System.ConsolePal.WindowsConsoleStream.ReadFileNative C# (CSharp) Method

ReadFileNative() private static method

private static ReadFileNative ( IntPtr hFile, byte bytes, int offset, int count, bool isPipe, int &bytesRead, bool useFileAPIs ) : int
hFile IntPtr
bytes byte
offset int
count int
isPipe bool
bytesRead int
useFileAPIs bool
return int
            private unsafe static int ReadFileNative(IntPtr hFile, byte[] bytes, int offset, int count, bool isPipe, out int bytesRead, bool useFileAPIs)
            {
                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);
                Contract.EndContractBlock();

                // You can't use the fixed statement on an array of length 0.
                if (bytes.Length == 0)
                {
                    bytesRead = 0;
                    return Interop.Errors.ERROR_SUCCESS;
                }

                bool readSuccess;
                fixed (byte* p = bytes)
                {
                    if (useFileAPIs)
                    {
                        readSuccess = (0 != Interop.Kernel32.ReadFile(hFile, p + offset, count, out bytesRead, IntPtr.Zero));
                    }
                    else
                    {
                        // If the code page could be Unicode, we should use ReadConsole instead, e.g.
                        int charsRead;
                        readSuccess = Interop.Kernel32.ReadConsole(hFile, p + offset, count / BytesPerWChar, out charsRead, IntPtr.Zero);
                        bytesRead = charsRead * BytesPerWChar;
                    }
                }
                if (readSuccess)
                    return Interop.Errors.ERROR_SUCCESS;

                // For pipes that are closing or broken, just stop.
                // (E.g. ERROR_NO_DATA ("pipe is being closed") is returned when we write to a console that is closing;
                // ERROR_BROKEN_PIPE ("pipe was closed") is returned when stdin was closed, which is mot an error, but EOF.)
                int errorCode = Marshal.GetLastWin32Error();
                if (errorCode == Interop.Errors.ERROR_NO_DATA || errorCode == Interop.Errors.ERROR_BROKEN_PIPE)
                    return Interop.Errors.ERROR_SUCCESS;
                return errorCode;
            }