private unsafe int ReadFileNative(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.
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 ReadFileNative.");
// You can't use the fixed statement on an array of length 0.
if (bytes.Length == 0)
{
errorCode = 0;
return 0;
}
int r = 0;
int numBytesRead = 0;
fixed (byte* p = bytes)
{
if (_useAsyncIO)
r = Interop.Kernel32.ReadFile(handle, p + offset, count, IntPtr.Zero, overlapped);
else
r = Interop.Kernel32.ReadFile(handle, p + offset, count, out numBytesRead, IntPtr.Zero);
}
if (r == 0)
{
errorCode = GetLastWin32ErrorAndDisposeHandleIfInvalid();
return -1;
}
else
{
errorCode = 0;
return numBytesRead;
}
}