This series of patches implements GetConsoleOriginalTitleA/W().
We re-use the existing logic of GetConsoleTitle, as it is the same for GetConsoleOriginalTitle.
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 | 28 ++++++++++++++++++++++------ programs/conhost/conhost.h | 1 + 2 files changed, 23 insertions(+), 6 deletions(-)
diff --git a/programs/conhost/conhost.c b/programs/conhost/conhost.c index 1bed7b8a03c..747e43773ff 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2461,21 +2461,37 @@ 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 ); + 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 747e43773ff..c97e0c753f0 100644 --- a/programs/conhost/conhost.c +++ b/programs/conhost/conhost.c @@ -2725,15 +2725,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; }
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=131258
Your paranoid android.
=== w7pro64 (64 bit report) ===
kernel32: console.c:3303: Test failed: expected INVALID_FILE_SIZE, got 0x1000
On Wed Mar 29 11:29:53 2023 +0000, **** wrote:
Marvin replied on the mailing list:
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=131258 Your paranoid android. === w7pro64 (64 bit report) === kernel32: console.c:3303: Test failed: expected INVALID_FILE_SIZE, got 0x1000
This is unrelated.
hi - one general remark: could be interesting to check what is returned if no title has been set (not sure it's should be an error, or an empty string...) - nitpick: in the set console title path, you forgot to set console->title to NULL after freeing it in the case the dup for the original title fails