From 887aa70e0884e78c7a97779200226e2f8566d29d Mon Sep 17 00:00:00 2001 From: Hugh McMaster Date: Wed, 29 Mar 2023 21:37:59 +1100 Subject: [PATCH] kernelbase: Implement GetConsoleOriginalTitleW(). --- dlls/kernel32/tests/console.c | 18 ++++++------ dlls/kernelbase/console.c | 52 +++++++++++++++++++---------------- programs/conhost/conhost.c | 12 +++++--- 3 files changed, 45 insertions(+), 37 deletions(-) diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 0786a7813ee..fbf773ec7d9 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4264,23 +4264,23 @@ static void test_GetConsoleOriginalTitleW(void) ok(!ret, "Unexpected string length; error %lu\n", GetLastError()); ret = GetConsoleOriginalTitleW(buf, ARRAY_SIZE(buf)); - todo_wine ok(ret, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError()); + ok(ret, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError()); buf[ret] = 0; - todo_wine ok(!wcscmp(buf, title), "got %s, expected %s\n", wine_dbgstr_w(buf), wine_dbgstr_w(title)); - todo_wine ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); + ok(!wcscmp(buf, title), "got %s, expected %s\n", wine_dbgstr_w(buf), wine_dbgstr_w(title)); + ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); ret = SetConsoleTitleW(L"test"); ok(ret, "SetConsoleTitleW failed: %lu\n", GetLastError()); ret = GetConsoleOriginalTitleW(buf, ARRAY_SIZE(buf)); - todo_wine ok(ret, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError()); - todo_wine ok(!wcscmp(buf, title), "got %s, expected %s\n", wine_dbgstr_w(buf), wine_dbgstr_w(title)); - todo_wine ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); + ok(ret, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError()); + ok(!wcscmp(buf, title), "got %s, expected %s\n", wine_dbgstr_w(buf), wine_dbgstr_w(title)); + ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); ret = GetConsoleOriginalTitleW(buf, 5); - todo_wine ok(ret, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError()); - todo_wine ok(!wcscmp(buf, L"Orig"), "got %s, expected 'Orig'\n", wine_dbgstr_w(buf)); - todo_wine ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); + ok(ret, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError()); + ok(!wcscmp(buf, L"Orig"), "got %s, expected 'Orig'\n", wine_dbgstr_w(buf)); + ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); } static void test_GetConsoleOriginalTitle(void) diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index fa143857bc2..0f72106e425 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -202,6 +202,32 @@ static COORD get_console_font_size( HANDLE handle, DWORD index ) return c; } +/* helper function for GetConsoleTitle and GetConsoleOriginalTitle */ +static DWORD get_console_title( WCHAR *title, DWORD size, BOOL current_title ) +{ + struct condrv_title_params *params; + size_t max_size = sizeof(*params) + (size - 1) * sizeof(WCHAR); + + if (!title || !size) return 0; + + if (!(params = HeapAlloc( GetProcessHeap(), 0, max_size ))) + return 0; + + if (console_ioctl( RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle, IOCTL_CONDRV_GET_TITLE, + ¤t_title, sizeof(current_title), params, max_size, &size ) && + size >= sizeof(*params)) + { + size -= sizeof(*params); + memcpy( title, params->buffer, size ); + title[ size / sizeof(WCHAR) ] = 0; + size = params->title_len; + } + else size = 0; + + HeapFree( GetProcessHeap(), 0, params ); + return size; +} + static HANDLE create_console_server( void ) { OBJECT_ATTRIBUTES attr = {sizeof(attr)}; @@ -899,9 +925,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleOriginalTitleA( LPSTR title, DWORD size */ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleOriginalTitleW( LPWSTR title, DWORD size ) { - FIXME( ": (%p, %lu) stub!\n", title, size ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return 0; + return get_console_title( title, size, FALSE ); } @@ -1046,27 +1070,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleTitleA( LPSTR title, DWORD size ) */ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleTitleW( LPWSTR title, DWORD size ) { - struct condrv_title_params *params; - size_t max_size = sizeof(*params) + (size - 1) * sizeof(WCHAR); - - if (!title || !size) return 0; - - if (!(params = HeapAlloc( GetProcessHeap(), 0, max_size ))) - return 0; - - if (console_ioctl( RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle, IOCTL_CONDRV_GET_TITLE, - NULL, 0, params, max_size, &size ) && - size >= sizeof(*params)) - { - size -= sizeof(*params); - memcpy( title, params->buffer, size ); - title[ size / sizeof(WCHAR) ] = 0; - size = params->title_len; - } - else size = 0; - - HeapFree( GetProcessHeap(), 0, params ); - return size; + return get_console_title( title, size, TRUE ); } diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index f07164c698e..04a294fc31f 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2726,15 +2726,19 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code, case IOCTL_CONDRV_GET_TITLE: { + BOOL current_title; + WCHAR *title; size_t title_len, str_size; struct condrv_title_params *params; - if (in_size) return STATUS_INVALID_PARAMETER; - title_len = console->title ? wcslen( console->title ) : 0; + if (in_size != sizeof(BOOL)) return STATUS_INVALID_PARAMETER; + current_title = *(BOOL *)in_data; + title = current_title ? console->title : console->title_orig; + title_len = title ? wcslen( title ) : 0; str_size = min( *out_size - sizeof(*params), title_len * sizeof(WCHAR) ); *out_size = sizeof(*params) + str_size; if (!(params = alloc_ioctl_buffer( *out_size ))) return STATUS_NO_MEMORY; - TRACE( "returning title %s\n", debugstr_w(console->title) ); - if (str_size) memcpy( params->buffer, console->title, str_size ); + TRACE( "returning %s %s\n", current_title ? "title" : "original title", debugstr_w(title) ); + if (str_size) memcpy( params->buffer, title, str_size ); params->title_len = title_len; return STATUS_SUCCESS; }