From: Hugh McMaster hugh.mcmaster@outlook.com
--- dlls/kernel32/tests/console.c | 6 +++--- dlls/kernelbase/console.c | 23 ++++++++++++++++------- include/wine/condrv.h | 10 ++++++++++ programs/conhost/conhost.c | 22 ++++++++++++++++------ 4 files changed, 45 insertions(+), 16 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index baab16f4b00..9c392fca2c5 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4272,12 +4272,12 @@ static void test_GetConsoleTitleW(void)
ret = GetConsoleTitleW(buf, ARRAY_SIZE(buf)); ok(ret, "GetConsoleTitleW failed: %lu\n", GetLastError()); - todo_wine ok(ret == wcslen(str), "Got string length %lu, expected %lu\n", ret, wcslen(str)); + ok(ret == wcslen(str), "Got string length %lu, expected %lu\n", ret, wcslen(str)); ok(!wcscmp(buf, str), "Title = %s\n", wine_dbgstr_w(buf));
ret = GetConsoleTitleW(buf, 2); ok(ret, "GetConsoleTitleW failed: %lu\n", GetLastError()); - todo_wine ok(ret == wcslen(str), "Got string length %lu, expected %lu\n", ret, wcslen(str)); + ok(ret == wcslen(str), "Got string length %lu, expected %lu\n", ret, wcslen(str)); if (!skip_nt) ok(!wcscmp(buf, L"t"), "Title = %s\n", wine_dbgstr_w(buf));
ret = GetConsoleTitleW(buf, 4); @@ -4289,7 +4289,7 @@ static void test_GetConsoleTitleW(void) ok(ret, "SetConsoleTitleW failed: %lu\n", GetLastError());
ret = GetConsoleTitleW(buf, ARRAY_SIZE(buf)); - todo_wine ok(!ret, "Unexpected string length; error %lu\n", GetLastError()); + ok(!ret, "Unexpected string length; error %lu\n", GetLastError()); }
static void test_file_info(HANDLE input, HANDLE output) diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 590198cf7bf..9d2a7ee5e69 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -1014,10 +1014,7 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleTitleA( LPSTR title, DWORD size ) if (!ptr) return 0; ret = GetConsoleTitleW( ptr, size ); if (ret) - { - WideCharToMultiByte( GetConsoleOutputCP(), 0, ptr, ret + 1, title, size, NULL, NULL); - ret = strlen(title); - } + WideCharToMultiByte( GetConsoleOutputCP(), 0, ptr, -1, title, size, NULL, NULL); HeapFree( GetProcessHeap(), 0, ptr ); return ret; } @@ -1028,15 +1025,27 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleTitleA( LPSTR title, DWORD size ) */ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleTitleW( LPWSTR title, DWORD size ) { - if (!size) return 0; + struct condrv_title_params params; + + if (!title || !size) return 0; + + params.mask = GET_CONSOLE_TITLE_LENGTH; + + if (!console_ioctl( RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle, IOCTL_CONDRV_GET_TITLE, + ¶ms, sizeof(params), ¶ms.title_len, sizeof(params.title_len), NULL )) + return 0; + + if (!params.title_len) return 0; + + params.mask = GET_CONSOLE_TITLE_STRING;
if (!console_ioctl( RtlGetCurrentPeb()->ProcessParameters->ConsoleHandle, IOCTL_CONDRV_GET_TITLE, - NULL, 0, title, (size - 1) * sizeof(WCHAR), &size )) + ¶ms, sizeof(params), title, (size - 1) * sizeof(WCHAR), &size )) return 0;
size /= sizeof(WCHAR); title[size] = 0; - return size + 1; + return params.title_len; }
diff --git a/include/wine/condrv.h b/include/wine/condrv.h index 3355d7177b0..d9231bfde0a 100644 --- a/include/wine/condrv.h +++ b/include/wine/condrv.h @@ -159,6 +159,16 @@ struct condrv_output_info_params #define SET_CONSOLE_OUTPUT_INFO_POPUP_ATTR 0x0040 #define SET_CONSOLE_OUTPUT_INFO_FONT 0x0080
+/* IOCTL_CONDRV_GET_TITLE params */ +struct condrv_title_params +{ + unsigned int mask; /* option mask */ + unsigned int title_len; /* title length (in characters) */ +}; + +#define GET_CONSOLE_TITLE_LENGTH 0x01 +#define GET_CONSOLE_TITLE_STRING 0x02 + /* IOCTL_CONDRV_FILL_OUTPUT params */ struct condrv_fill_output_params { diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 792daeb520f..c61d9920024 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2675,12 +2675,22 @@ static NTSTATUS console_input_ioctl( struct console *console, unsigned int code,
case IOCTL_CONDRV_GET_TITLE: { - WCHAR *result; - if (in_size) return STATUS_INVALID_PARAMETER; - TRACE( "returning title %s\n", debugstr_w(console->title) ); - *out_size = min( *out_size, console->title ? wcslen( console->title ) * sizeof(WCHAR) : 0 ); - if (!(result = alloc_ioctl_buffer( *out_size ))) return STATUS_NO_MEMORY; - if (*out_size) memcpy( result, console->title, *out_size ); + struct condrv_title_params *params = (struct condrv_title_params *)in_data; + if (params->mask == GET_CONSOLE_TITLE_LENGTH) + { + DWORD *title_len; + if (*out_size != sizeof(DWORD)) return STATUS_INVALID_PARAMETER; + if (!(title_len = alloc_ioctl_buffer( *out_size ))) return STATUS_NO_MEMORY; + *title_len = console->title ? wcslen( console-> title ) : 0; + } + else if (params->mask == GET_CONSOLE_TITLE_STRING) + { + WCHAR *result; + TRACE( "returning title %s\n", debugstr_w(console->title) ); + *out_size = min( *out_size, params->title_len * sizeof(WCHAR) ); + if (!(result = alloc_ioctl_buffer( *out_size ))) return STATUS_NO_MEMORY; + if (*out_size) memcpy( result, console->title, *out_size ); + } return STATUS_SUCCESS; }