dotnet / pinvoke

A library containing all P/Invoke code so you don't have to import it every time. Maintained and updated to support the latest Windows OS.
MIT License
2.12k stars 222 forks source link

ReadConsole signature has wrong parameter mode #523

Closed Entomy closed 4 years ago

Entomy commented 4 years ago

ReadConsole() has an incorrect parameter mode, specifically on int lpNumberOfCharsRead, which is defined as an normal input parameter, but is supposed to be an output parameter, per the WinAPI docs.

Despite the clear intentions to do this (the [Friendly(FriendlyFlags.Out)] attribute), the actual parameter is not defined this way. This causes the following exception:

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at PInvoke.Kernel32.ReadConsole(IntPtr, Void*, Int32, Int32, IntPtr)
   at PInvoke.Kernel32.ReadConsole(IntPtr, Void*, Int32, Int32, IntPtr)
   at Consolator.Console.Read()
   at Tester.Program.Main()

Creating my own import as follows:

[DllImport(nameof(Kernel32), CharSet = CharSet.Unicode, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static unsafe extern Boolean ReadConsole(IntPtr hConsoleInput, void* lpBuffer, Int32 nNumberOfCharsToRead, out Int32 lpNumberOfCharsRead, IntPtr lpReserved);

Does not throw an exception, and operates as expected.