From 207c55800319da0ad917cc818c3f56ab52f49715 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 12 Dec 2019 12:03:47 +0100 Subject: [PATCH] kernelbase: Move some console support back to kernel32. That's where the bulk of the console code still resides. Signed-off-by: Alexandre Julliard --- dlls/kernel32/console.c | 75 +++++++++++++++++++++++++++++++++ dlls/kernel32/file.c | 55 ++++++++++++++++++++++++ dlls/kernel32/kernel32.spec | 10 ++--- dlls/kernelbase/console.c | 61 --------------------------- dlls/kernelbase/file.c | 24 ----------- dlls/kernelbase/kernelbase.spec | 6 +-- 6 files changed, 138 insertions(+), 93 deletions(-) diff --git a/dlls/kernel32/console.c b/dlls/kernel32/console.c index 86fdae0ecb8..472d5139901 100644 --- a/dlls/kernel32/console.c +++ b/dlls/kernel32/console.c @@ -79,6 +79,21 @@ static const WCHAR conoutW[] = {'C','O','N','O','U','T','$',0}; /* FIXME: this is not thread safe */ static HANDLE console_wait_event; +/* map input records to ASCII */ +static void input_records_WtoA( INPUT_RECORD *buffer, int count ) +{ + UINT cp = GetConsoleCP(); + int i; + char ch; + + for (i = 0; i < count; i++) + { + if (buffer[i].EventType != KEY_EVENT) continue; + WideCharToMultiByte( cp, 0, &buffer[i].Event.KeyEvent.uChar.UnicodeChar, 1, &ch, 1, NULL, NULL ); + buffer[i].Event.KeyEvent.uChar.AsciiChar = ch; + } +} + static struct termios S_termios; /* saved termios for bare consoles */ static BOOL S_termios_raw /* = FALSE */; @@ -726,6 +741,30 @@ BOOL WINAPI AllocConsole(void) } +/*********************************************************************** + * ReadConsoleA (KERNEL32.@) + */ +BOOL WINAPI ReadConsoleA( HANDLE handle, LPVOID buffer, DWORD length, DWORD *ret_count, void *reserved ) +{ + LPWSTR strW = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) ); + DWORD count = 0; + BOOL ret; + + if (!strW) + { + SetLastError( ERROR_NOT_ENOUGH_MEMORY ); + return FALSE; + } + if ((ret = ReadConsoleW( handle, strW, length, &count, NULL ))) + { + count = WideCharToMultiByte( GetConsoleCP(), 0, strW, count, buffer, length, NULL, NULL ); + if (ret_count) *ret_count = count; + } + HeapFree( GetProcessHeap(), 0, strW ); + return ret; +} + + /*********************************************************************** * ReadConsoleW (KERNEL32.@) */ @@ -801,6 +840,20 @@ BOOL WINAPI ReadConsoleW(HANDLE hConsoleInput, LPVOID lpBuffer, } +/*********************************************************************** + * ReadConsoleInputA (KERNEL32.@) + */ +BOOL WINAPI ReadConsoleInputA( HANDLE handle, INPUT_RECORD *buffer, DWORD length, DWORD *count ) +{ + DWORD read; + + if (!ReadConsoleInputW( handle, buffer, length, &read )) return FALSE; + input_records_WtoA( buffer, read ); + if (count) *count = read; + return TRUE; +} + + /*********************************************************************** * ReadConsoleInputW (KERNEL32.@) */ @@ -1126,6 +1179,28 @@ static BOOL write_block(HANDLE hCon, CONSOLE_SCREEN_BUFFER_INFO* csbi, return TRUE; } + +/*********************************************************************** + * WriteConsoleA (KERNEL32.@) + */ +BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleA( HANDLE handle, LPCVOID buffer, DWORD length, + DWORD *written, void *reserved ) +{ + UINT cp = GetConsoleOutputCP(); + LPWSTR strW; + DWORD lenW; + BOOL ret; + + if (written) *written = 0; + lenW = MultiByteToWideChar( cp, 0, buffer, length, NULL, 0 ); + if (!(strW = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) ))) return FALSE; + MultiByteToWideChar( cp, 0, buffer, length, strW, lenW ); + ret = WriteConsoleW( handle, strW, lenW, written, 0 ); + HeapFree( GetProcessHeap(), 0, strW ); + return ret; +} + + /*********************************************************************** * WriteConsoleW (KERNEL32.@) */ diff --git a/dlls/kernel32/file.c b/dlls/kernel32/file.c index ff65aa75f5f..b2979f96222 100644 --- a/dlls/kernel32/file.c +++ b/dlls/kernel32/file.c @@ -354,6 +354,61 @@ UINT WINAPI SetHandleCount( UINT count ) } +/************************************************************************* + * ReadFile (KERNEL32.@) + */ +BOOL WINAPI KERNEL32_ReadFile( HANDLE file, LPVOID buffer, DWORD count, + LPDWORD result, LPOVERLAPPED overlapped ) +{ + if (result) *result = 0; + + if (is_console_handle( file )) + { + DWORD conread, mode; + + if (!ReadConsoleA( file, buffer, count, &conread, NULL) || !GetConsoleMode( file, &mode )) + return FALSE; + /* ctrl-Z (26) means end of file on window (if at beginning of buffer) + * but Unix uses ctrl-D (4), and ctrl-Z is a bad idea on Unix :-/ + * So map both ctrl-D ctrl-Z to EOF. + */ + if ((mode & ENABLE_PROCESSED_INPUT) && conread > 0 && + (((char *)buffer)[0] == 26 || ((char *)buffer)[0] == 4)) + { + conread = 0; + } + if (result) *result = conread; + return TRUE; + } + return ReadFile( file, buffer, count, result, overlapped ); +} + + +/************************************************************************* + * WriteFile (KERNEL32.@) + */ +BOOL WINAPI KERNEL32_WriteFile( HANDLE file, LPCVOID buffer, DWORD count, + LPDWORD result, LPOVERLAPPED overlapped ) +{ + if (is_console_handle( file )) return WriteConsoleA( file, buffer, count, result, NULL ); + return WriteFile( file, buffer, count, result, overlapped ); +} + + +/************************************************************************* + * FlushFileBuffers (KERNEL32.@) + */ +BOOL WINAPI KERNEL32_FlushFileBuffers( HANDLE file ) +{ + IO_STATUS_BLOCK iosb; + + /* this will fail (as expected) for an output handle */ + if (is_console_handle( file )) return FlushConsoleInputBuffer( file ); + + return set_ntstatus( NtFlushBuffersFile( file, &iosb )); +} + + /************************************************************************** * Operations on file names * **************************************************************************/ diff --git a/dlls/kernel32/kernel32.spec b/dlls/kernel32/kernel32.spec index d8b50426238..6296bab4b4e 100644 --- a/dlls/kernel32/kernel32.spec +++ b/dlls/kernel32/kernel32.spec @@ -1185,8 +1185,8 @@ @ stdcall -import QueueUserWorkItem(ptr ptr long) @ stdcall -import RaiseException(long long long ptr) # @ stub RaiseFailFastException -@ stdcall -import ReadConsoleA(long ptr long ptr ptr) -@ stdcall -import ReadConsoleInputA(long ptr long ptr) +@ stdcall ReadConsoleA(long ptr long ptr ptr) +@ stdcall ReadConsoleInputA(long ptr long ptr) @ stub ReadConsoleInputExA @ stub ReadConsoleInputExW @ stdcall ReadConsoleInputW(long ptr long ptr) @@ -1197,7 +1197,7 @@ @ stdcall -import ReadConsoleOutputW(long ptr long long ptr) @ stdcall ReadConsoleW(long ptr long ptr ptr) @ stdcall -import ReadDirectoryChangesW(long ptr long long long ptr ptr ptr) -@ stdcall -import ReadFile(long ptr long ptr ptr) +@ stdcall ReadFile(long ptr long ptr ptr) KERNEL32_ReadFile @ stdcall -import ReadFileEx(long ptr long ptr ptr) @ stdcall -import ReadFileScatter(long ptr long ptr ptr) @ stdcall -import ReadProcessMemory(long ptr ptr long ptr) @@ -1610,7 +1610,7 @@ @ stdcall -import Wow64RevertWow64FsRedirection(ptr) @ stdcall Wow64SetThreadContext(long ptr) # @ stub Wow64SuspendThread -@ stdcall -import WriteConsoleA(long ptr long ptr ptr) +@ stdcall WriteConsoleA(long ptr long ptr ptr) @ stdcall -import WriteConsoleInputA(long ptr long ptr) @ stub WriteConsoleInputVDMA @ stub WriteConsoleInputVDMW @@ -1621,7 +1621,7 @@ @ stdcall -import WriteConsoleOutputCharacterW(long ptr long long ptr) @ stdcall -import WriteConsoleOutputW(long ptr long long ptr) @ stdcall WriteConsoleW(long ptr long ptr ptr) -@ stdcall -import WriteFile(long ptr long ptr ptr) +@ stdcall WriteFile(long ptr long ptr ptr) KERNEL32_WriteFile @ stdcall -import WriteFileEx(long ptr long ptr ptr) @ stdcall -import WriteFileGather(long ptr long ptr ptr) @ stdcall WritePrivateProfileSectionA(str str str) diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 0729e578e44..91e8129fbe2 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -663,46 +663,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH PeekConsoleInputW( HANDLE handle, INPUT_RECORD *bu } -/*********************************************************************** - * ReadConsoleA (kernelbase.@) - */ -BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleA( HANDLE handle, LPVOID buffer, DWORD length, - DWORD *ret_count, void *reserved ) -{ - LPWSTR strW = HeapAlloc( GetProcessHeap(), 0, length * sizeof(WCHAR) ); - DWORD count = 0; - BOOL ret; - - if (!strW) - { - SetLastError( ERROR_NOT_ENOUGH_MEMORY ); - return FALSE; - } - if ((ret = ReadConsoleW( handle, strW, length, &count, NULL ))) - { - count = WideCharToMultiByte( GetConsoleCP(), 0, strW, count, buffer, length, NULL, NULL ); - if (ret_count) *ret_count = count; - } - HeapFree( GetProcessHeap(), 0, strW ); - return ret; -} - - -/****************************************************************************** - * ReadConsoleInputA (kernelbase.@) - */ -BOOL WINAPI DECLSPEC_HOTPATCH ReadConsoleInputA( HANDLE handle, INPUT_RECORD *buffer, - DWORD length, DWORD *count ) -{ - DWORD read; - - if (!ReadConsoleInputW( handle, buffer, length, &read )) return FALSE; - input_records_WtoA( buffer, read ); - if (count) *count = read; - return TRUE; -} - - /****************************************************************************** * ReadConsoleOutputAttribute (kernelbase.@) */ @@ -1289,27 +1249,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH SetConsoleWindowInfo( HANDLE handle, BOOL absolute } -/*********************************************************************** - * WriteConsoleA (kernelbase.@) - */ -BOOL WINAPI DECLSPEC_HOTPATCH WriteConsoleA( HANDLE handle, LPCVOID buffer, DWORD length, - DWORD *written, void *reserved ) -{ - UINT cp = GetConsoleOutputCP(); - LPWSTR strW; - DWORD lenW; - BOOL ret; - - if (written) *written = 0; - lenW = MultiByteToWideChar( cp, 0, buffer, length, NULL, 0 ); - if (!(strW = HeapAlloc( GetProcessHeap(), 0, lenW * sizeof(WCHAR) ))) return FALSE; - MultiByteToWideChar( cp, 0, buffer, length, strW, lenW ); - ret = WriteConsoleW( handle, strW, lenW, written, 0 ); - HeapFree( GetProcessHeap(), 0, strW ); - return ret; -} - - /****************************************************************************** * WriteConsoleInputA (kernelbase.@) */ diff --git a/dlls/kernelbase/file.c b/dlls/kernelbase/file.c index 89c5f85cb20..eb2ef57c7d6 100644 --- a/dlls/kernelbase/file.c +++ b/dlls/kernelbase/file.c @@ -2205,9 +2205,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH FlushFileBuffers( HANDLE file ) { IO_STATUS_BLOCK iosb; - /* this will fail (as expected) for an output handle */ - if (is_console_handle( file )) return FlushConsoleInputBuffer( file ); - return set_ntstatus( NtFlushBuffersFile( file, &iosb )); } @@ -2631,25 +2628,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH ReadFile( HANDLE file, LPVOID buffer, DWORD count, if (result) *result = 0; - if (is_console_handle( file )) - { - DWORD conread, mode; - - if (!ReadConsoleA( file, buffer, count, &conread, NULL) || !GetConsoleMode( file, &mode )) - return FALSE; - /* ctrl-Z (26) means end of file on window (if at beginning of buffer) - * but Unix uses ctrl-D (4), and ctrl-Z is a bad idea on Unix :-/ - * So map both ctrl-D ctrl-Z to EOF. - */ - if ((mode & ENABLE_PROCESSED_INPUT) && conread > 0 && - (((char *)buffer)[0] == 26 || ((char *)buffer)[0] == 4)) - { - conread = 0; - } - if (result) *result = conread; - return TRUE; - } - if (overlapped) { offset.u.LowPart = overlapped->u.s.Offset; @@ -2978,8 +2956,6 @@ BOOL WINAPI DECLSPEC_HOTPATCH WriteFile( HANDLE file, LPCVOID buffer, DWORD coun TRACE( "%p %p %d %p %p\n", file, buffer, count, result, overlapped ); - if (is_console_handle( file )) return WriteConsoleA( file, buffer, count, result, NULL); - if (overlapped) { offset.u.LowPart = overlapped->u.s.Offset; diff --git a/dlls/kernelbase/kernelbase.spec b/dlls/kernelbase/kernelbase.spec index 8e5e81d5643..a9ef04aa176 100644 --- a/dlls/kernelbase/kernelbase.spec +++ b/dlls/kernelbase/kernelbase.spec @@ -1234,8 +1234,8 @@ @ stdcall RaiseException(long long long ptr) # @ stub RaiseFailFastException @ stdcall ReOpenFile(ptr long long long) -@ stdcall ReadConsoleA(long ptr long ptr ptr) -@ stdcall ReadConsoleInputA(long ptr long ptr) +@ stdcall ReadConsoleA(long ptr long ptr ptr) kernel32.ReadConsoleA +@ stdcall ReadConsoleInputA(long ptr long ptr) kernel32.ReadConsoleInputA @ stub ReadConsoleInputExA @ stub ReadConsoleInputExW @ stdcall ReadConsoleInputW(long ptr long ptr) kernel32.ReadConsoleInputW @@ -1716,7 +1716,7 @@ @ stdcall Wow64RevertWow64FsRedirection(ptr) # @ stub Wow64SetThreadDefaultGuestMachine # @ stub -arch=i386 Wow64Transition -@ stdcall WriteConsoleA(long ptr long ptr ptr) +@ stdcall WriteConsoleA(long ptr long ptr ptr) kernel32.WriteConsoleA @ stdcall WriteConsoleInputA(long ptr long ptr) @ stdcall WriteConsoleInputW(long ptr long ptr) @ stdcall WriteConsoleOutputA(long ptr long long ptr)