kernelbase: Move some console support back to kernel32.

That's where the bulk of the console code still resides.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
stable
Alexandre Julliard 2019-12-12 12:03:47 +01:00
parent 1ec0769cf6
commit 207c558003
6 changed files with 138 additions and 93 deletions

View File

@ -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.@)
*/

View File

@ -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 *
**************************************************************************/

View File

@ -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)

View File

@ -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.@)
*/

View File

@ -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;

View File

@ -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)