This series of patches implements GetConsoleOriginalTitleA/W().
We re-use the existing logic of GetConsoleTitle, as it is the same for GetConsoleOriginalTitle.
-- v4: kernel32/tests: Test GetConsoleOriginalTitleW() with an empty title
From: Hugh McMaster hugh.mcmaster@outlook.com
--- dlls/kernel32/tests/console.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index f8e39c164d2..0786a7813ee 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4227,9 +4227,9 @@ static void test_SetConsoleScreenBufferInfoEx(HANDLE std_output)
static void test_GetConsoleOriginalTitleA(void) { - char buf[64]; - DWORD ret; char title[] = "Original Console Title"; + char buf[64]; + DWORD ret, title_len = strlen(title);
ret = GetConsoleOriginalTitleA(NULL, 0); ok(!ret, "Unexpected string length; error %lu\n", GetLastError()); @@ -4240,6 +4240,7 @@ static void test_GetConsoleOriginalTitleA(void) ret = GetConsoleOriginalTitleA(buf, ARRAY_SIZE(buf)); todo_wine ok(ret, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError()); todo_wine ok(!strcmp(buf, title), "got %s, expected %s\n", wine_dbgstr_a(buf), wine_dbgstr_a(title)); + todo_wine ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len);
ret = SetConsoleTitleA("test"); ok(ret, "SetConsoleTitleA failed: %lu\n", GetLastError()); @@ -4247,13 +4248,14 @@ static void test_GetConsoleOriginalTitleA(void) ret = GetConsoleOriginalTitleA(buf, ARRAY_SIZE(buf)); todo_wine ok(ret, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError()); todo_wine ok(!strcmp(buf, title), "got %s, expected %s\n", wine_dbgstr_a(buf), wine_dbgstr_a(title)); + todo_wine ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); }
static void test_GetConsoleOriginalTitleW(void) { - WCHAR buf[64]; - DWORD ret; WCHAR title[] = L"Original Console Title"; + WCHAR buf[64]; + DWORD ret, title_len = lstrlenW(title);
ret = GetConsoleOriginalTitleW(NULL, 0); ok(!ret, "Unexpected string length; error %lu\n", GetLastError()); @@ -4265,6 +4267,7 @@ static void test_GetConsoleOriginalTitleW(void) todo_wine 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);
ret = SetConsoleTitleW(L"test"); ok(ret, "SetConsoleTitleW failed: %lu\n", GetLastError()); @@ -4272,10 +4275,12 @@ static void test_GetConsoleOriginalTitleW(void) 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);
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); }
static void test_GetConsoleOriginalTitle(void)
From: Hugh McMaster hugh.mcmaster@outlook.com
--- programs/conhost/conhost.c | 29 +++++++++++++++++++++++------ programs/conhost/conhost.h | 1 + 2 files changed, 24 insertions(+), 6 deletions(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 1bed7b8a03c..f07164c698e 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2461,21 +2461,38 @@ static NTSTATUS scroll_output( struct screen_buffer *screen_buffer, const struct return STATUS_SUCCESS; }
+static WCHAR *set_title( const WCHAR *in_title, size_t size ) +{ + WCHAR *title = NULL; + + title = malloc( size + sizeof(WCHAR) ); + if (!title) return NULL; + + memcpy( title, in_title, size ); + title[ size / sizeof(WCHAR) ] = 0; + + return title; +} + static NTSTATUS set_console_title( struct console *console, const WCHAR *in_title, size_t size ) { WCHAR *title = NULL;
TRACE( "%s\n", debugstr_wn(in_title, size / sizeof(WCHAR)) );
- if (size) - { - if (!(title = malloc( size + sizeof(WCHAR) ))) return STATUS_NO_MEMORY; - memcpy( title, in_title, size ); - title[size / sizeof(WCHAR)] = 0; - } + if (!(title = set_title( in_title, size ))) + return STATUS_NO_MEMORY; + free( console->title ); console->title = title;
+ if (!console->title_orig && !(console->title_orig = set_title( in_title, size ))) + { + free( console->title ); + console->title = NULL; + return STATUS_NO_MEMORY; + } + if (console->tty_output) { size_t len; diff --git a/programs/conhost/conhost.h b/programs/conhost/conhost.h index 4464f51032f..76d897e8800 100644 --- a/programs/conhost/conhost.h +++ b/programs/conhost/conhost.h @@ -93,6 +93,7 @@ struct console unsigned int key_state; struct console_window *window; WCHAR *title; /* console title */ + WCHAR *title_orig; /* original console title */ struct history_line **history; /* lines history */ unsigned int history_size; /* number of entries in history array */ unsigned int history_index; /* number of used entries in history array */
From: Hugh McMaster hugh.mcmaster@outlook.com
--- 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; }
From: Hugh McMaster hugh.mcmaster@outlook.com
--- dlls/kernel32/tests/console.c | 12 ++++++------ dlls/kernelbase/console.c | 14 +++++++++++--- 2 files changed, 17 insertions(+), 9 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index fbf773ec7d9..9e42c5b6c3b 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4238,17 +4238,17 @@ static void test_GetConsoleOriginalTitleA(void) ok(!ret, "Unexpected string length; error %lu\n", GetLastError());
ret = GetConsoleOriginalTitleA(buf, ARRAY_SIZE(buf)); - todo_wine ok(ret, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError()); - todo_wine ok(!strcmp(buf, title), "got %s, expected %s\n", wine_dbgstr_a(buf), wine_dbgstr_a(title)); - todo_wine ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); + ok(ret, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError()); + ok(!strcmp(buf, title), "got %s, expected %s\n", wine_dbgstr_a(buf), wine_dbgstr_a(title)); + ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len);
ret = SetConsoleTitleA("test"); ok(ret, "SetConsoleTitleA failed: %lu\n", GetLastError());
ret = GetConsoleOriginalTitleA(buf, ARRAY_SIZE(buf)); - todo_wine ok(ret, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError()); - todo_wine ok(!strcmp(buf, title), "got %s, expected %s\n", wine_dbgstr_a(buf), wine_dbgstr_a(title)); - todo_wine ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); + ok(ret, "GetConsoleOriginalTitleA failed: %lu\n", GetLastError()); + ok(!strcmp(buf, title), "got %s, expected %s\n", wine_dbgstr_a(buf), wine_dbgstr_a(title)); + ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); }
static void test_GetConsoleOriginalTitleW(void) diff --git a/dlls/kernelbase/console.c b/dlls/kernelbase/console.c index 0f72106e425..cd5fdb7d9f7 100644 --- a/dlls/kernelbase/console.c +++ b/dlls/kernelbase/console.c @@ -914,9 +914,17 @@ BOOL WINAPI DECLSPEC_HOTPATCH GetConsoleMode( HANDLE handle, DWORD *mode ) */ DWORD WINAPI DECLSPEC_HOTPATCH GetConsoleOriginalTitleA( LPSTR title, DWORD size ) { - FIXME( ": (%p, %lu) stub!\n", title, size ); - SetLastError( ERROR_CALL_NOT_IMPLEMENTED ); - return 0; + WCHAR *ptr = HeapAlloc( GetProcessHeap(), 0, size * sizeof(WCHAR) ); + DWORD ret; + + if (!ptr) return 0; + + ret = GetConsoleOriginalTitleW( ptr, size ); + if (ret) + WideCharToMultiByte( GetConsoleOutputCP(), 0, ptr, -1, title, size, NULL, NULL); + + HeapFree( GetProcessHeap(), 0, ptr ); + return ret; }
From: Hugh McMaster hugh.mcmaster@outlook.com
--- dlls/kernel32/tests/console.c | 28 +++++++++++++++++++++++++--- 1 file changed, 25 insertions(+), 3 deletions(-)
diff --git a/dlls/kernel32/tests/console.c b/dlls/kernel32/tests/console.c index 9e42c5b6c3b..8d569ad6410 100644 --- a/dlls/kernel32/tests/console.c +++ b/dlls/kernel32/tests/console.c @@ -4283,6 +4283,15 @@ static void test_GetConsoleOriginalTitleW(void) ok(ret == title_len, "got %lu, expected %lu\n", ret, title_len); }
+static void test_GetConsoleOriginalTitleW_empty(void) +{ + WCHAR buf[64]; + DWORD ret; + + ret = GetConsoleOriginalTitleW(buf, ARRAY_SIZE(buf)); + ok(!ret, "GetConsoleOriginalTitleW failed: %lu\n", GetLastError()); +} + static void test_GetConsoleOriginalTitle(void) { STARTUPINFOA si = { sizeof(si) }; @@ -4299,6 +4308,14 @@ static void test_GetConsoleOriginalTitle(void) CloseHandle(info.hThread); wait_child_process(info.hProcess); CloseHandle(info.hProcess); + + strcat(buf, " empty"); + title[0] = 0; + ret = CreateProcessA(NULL, buf, NULL, NULL, TRUE, CREATE_NEW_CONSOLE, NULL, NULL, &si, &info); + ok(ret, "CreateProcess failed: %lu\n", GetLastError()); + CloseHandle(info.hThread); + wait_child_process(info.hProcess); + CloseHandle(info.hProcess); }
static void test_GetConsoleTitleA(void) @@ -4944,10 +4961,15 @@ START_TEST(console) ExitProcess(exit_code); }
- if (argc == 3 && !strcmp(argv[2], "title_test")) + if (argc >= 3 && !strcmp(argv[2], "title_test")) { - test_GetConsoleOriginalTitleA(); - test_GetConsoleOriginalTitleW(); + if (argc == 3) + { + test_GetConsoleOriginalTitleA(); + test_GetConsoleOriginalTitleW(); + } + else + test_GetConsoleOriginalTitleW_empty(); return; }
Hi,
It looks like your patch introduced the new failures shown below. Please investigate and fix them before resubmitting your patch. If they are not new, fixing them anyway would help a lot. Otherwise please ask for the known failures list to be updated.
The tests also ran into some preexisting test failures. If you know how to fix them that would be helpful. See the TestBot job for the details:
The full results can be found at: https://testbot.winehq.org/JobDetails.pl?Key=131300
Your paranoid android.
=== w7pro64 (64 bit report) ===
kernel32: console.c:3303: Test failed: expected INVALID_FILE_SIZE, got 0x1000
Okay. Should be all done now.
This merge request was approved by eric pouech.
This merge request was approved by Jacek Caban.