private unsafe int WriteFileNative(SafeFileHandle handle, byte[] bytes, int offset, int count, NativeOverlapped* overlapped, out int errorCode)
{
Debug.Assert(handle != null, "handle != null");
Debug.Assert(offset >= 0, "offset >= 0");
Debug.Assert(count >= 0, "count >= 0");
Debug.Assert(bytes != null, "bytes != null");
// Don't corrupt memory when multiple threads are erroneously writing
// to this stream simultaneously. (the OS is reading from
// the array we pass to WriteFile, but if we read beyond the end and
// that memory isn't allocated, we could get an AV.)
if (bytes.Length - offset < count)
throw new IndexOutOfRangeException(SR.IndexOutOfRange_IORaceCondition);
Debug.Assert((_useAsyncIO && overlapped != null) || (!_useAsyncIO && overlapped == null), "Async IO and overlapped parameters inconsistent in call to WriteFileNative.");
// You can't use the fixed statement on an array of length 0.
if (bytes.Length == 0)
{
errorCode = 0;
return 0;
}
int numBytesWritten = 0;
int r = 0;
fixed (byte* p = bytes)
{
if (_useAsyncIO)
r = Interop.Kernel32.WriteFile(handle, p + offset, count, IntPtr.Zero, overlapped);
else
r = Interop.Kernel32.WriteFile(handle, p + offset, count, out numBytesWritten, IntPtr.Zero);
}
if (r == 0)
{
errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
return -1;
}
else
{
errorCode = 0;
return numBytesWritten;
}
}