[PATCH v48 0/2] MR10291: Fix GetModuleFileName string termination
After Windows XP the string termination behavior of GetModuleFileName was changed to always terminate the path returned, even if the buffer is insufficient to contain the null terminator. -- v48: kernel32: Fix string termination of GetModuleFileName. https://gitlab.winehq.org/wine/wine/-/merge_requests/10291
From: Trent Waddington <trent.waddington@tensorworks.com.au> --- dlls/kernel32/tests/loader.c | 52 ++++++++++++++++++++++++++++++++++++ 1 file changed, 52 insertions(+) diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 529b9de870d..2d3934301b9 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -1552,6 +1552,56 @@ static void test_filenames(void) DeleteFileA( long_path ); } +static void test_getmodulefilenamew_string_termination(void) +{ + WCHAR dll_name[MAX_PATH]; + size_t dll_name_len, dll_name_term; + DWORD rv, err; + + SetLastError(0xdeadbeef); + GetModuleFileNameW(NULL, dll_name, MAX_PATH); + err = GetLastError(); + ok(err == ERROR_SUCCESS, "error getting path for NULL module: %lu\n", err); + dll_name_len = wcslen(dll_name); + ok(dll_name_len > 0, "can't get path for NULL module\n"); + + memset(dll_name, '*', sizeof(dll_name)); + SetLastError(0xdeadbeef); + rv = GetModuleFileNameW(NULL, dll_name, dll_name_len); + err = GetLastError(); + ok(err == ERROR_INSUFFICIENT_BUFFER, "didn't get expected error getting path for NULL module with short buffer: %lu\n", err); + dll_name_term = wcsnlen(dll_name, MAX_PATH); + ok(dll_name_term > 0, "can't get path for NULL module with short buffer, dll_name_term=%Iu\n", dll_name_term); + todo_wine { + ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %Iu got %Iu. rv=%lu\n", dll_name_len - 1, dll_name_term, rv); + } +} + +static void test_getmodulefilenamea_string_termination(void) +{ + char dll_name[MAX_PATH]; + size_t dll_name_len, dll_name_term; + DWORD rv, err; + + SetLastError(0xdeadbeef); + GetModuleFileNameA(NULL, dll_name, MAX_PATH); + err = GetLastError(); + ok(err == ERROR_SUCCESS, "error getting path for NULL module: %lu\n", err); + dll_name_len = strlen(dll_name); + ok(dll_name_len > 0, "can't get path for NULL module\n"); + + memset(dll_name, '*', sizeof(dll_name)); + SetLastError(0xdeadbeef); + rv = GetModuleFileNameA(NULL, dll_name, dll_name_len); + err = GetLastError(); + ok(err == ERROR_INSUFFICIENT_BUFFER, "didn't get expected error getting path for NULL module with short buffer: %lu\n", err); + dll_name_term = strnlen(dll_name, MAX_PATH); + ok(dll_name_term > 0, "can't get path for NULL module with short buffer, dll_name_term=%Iu\n", dll_name_term); + todo_wine { + ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %Iu got %Iu. rv=%lu\n", dll_name_len - 1, dll_name_term, rv); + } +} + /* Verify linking style of import descriptors */ static void test_ImportDescriptors(void) { @@ -4859,6 +4909,8 @@ START_TEST(loader) } test_filenames(); + test_getmodulefilenamew_string_termination(); + test_getmodulefilenamea_string_termination(); test_ResolveDelayLoadedAPI(); test_ImportDescriptors(); test_section_access(); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10291
From: Trent Waddington <trent.waddington@tensorworks.com.au> --- dlls/kernel32/tests/loader.c | 8 ++------ dlls/kernelbase/loader.c | 9 ++++++++- 2 files changed, 10 insertions(+), 7 deletions(-) diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 2d3934301b9..50b8e3d2750 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -1572,9 +1572,7 @@ static void test_getmodulefilenamew_string_termination(void) ok(err == ERROR_INSUFFICIENT_BUFFER, "didn't get expected error getting path for NULL module with short buffer: %lu\n", err); dll_name_term = wcsnlen(dll_name, MAX_PATH); ok(dll_name_term > 0, "can't get path for NULL module with short buffer, dll_name_term=%Iu\n", dll_name_term); - todo_wine { - ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %Iu got %Iu. rv=%lu\n", dll_name_len - 1, dll_name_term, rv); - } + ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %Iu got %Iu. rv=%lu\n", dll_name_len - 1, dll_name_term, rv); } static void test_getmodulefilenamea_string_termination(void) @@ -1597,9 +1595,7 @@ static void test_getmodulefilenamea_string_termination(void) ok(err == ERROR_INSUFFICIENT_BUFFER, "didn't get expected error getting path for NULL module with short buffer: %lu\n", err); dll_name_term = strnlen(dll_name, MAX_PATH); ok(dll_name_term > 0, "can't get path for NULL module with short buffer, dll_name_term=%Iu\n", dll_name_term); - todo_wine { - ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %Iu got %Iu. rv=%lu\n", dll_name_len - 1, dll_name_term, rv); - } + ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %Iu got %Iu. rv=%lu\n", dll_name_len - 1, dll_name_term, rv); } /* Verify linking style of import descriptors */ diff --git a/dlls/kernelbase/loader.c b/dlls/kernelbase/loader.c index f4e1ca2e23a..6c6f1f31881 100644 --- a/dlls/kernelbase/loader.c +++ b/dlls/kernelbase/loader.c @@ -315,7 +315,14 @@ DWORD WINAPI DECLSPEC_HOTPATCH GetModuleFileNameW( HMODULE module, LPWSTR filena name.Buffer = filename; name.MaximumLength = min( size, UNICODE_STRING_MAX_CHARS ) * sizeof(WCHAR); status = LdrGetDllFullName( module, &name ); - if (!status || status == STATUS_BUFFER_TOO_SMALL) len = name.Length / sizeof(WCHAR); + if (!status || status == STATUS_BUFFER_TOO_SMALL) + { + len = name.Length / sizeof(WCHAR); + /* LdrGetDllFullName calls RtlCopyUnicodeString which should terminate + if there's space, otherwise: */ + if (status == STATUS_BUFFER_TOO_SMALL && size > 0) + filename[size - 1] = 0; + } SetLastError( RtlNtStatusToDosError( status )); done: TRACE( "%s\n", debugstr_wn(filename, len) ); -- GitLab https://gitlab.winehq.org/wine/wine/-/merge_requests/10291
This merge request was approved by eric pouech. -- https://gitlab.winehq.org/wine/wine/-/merge_requests/10291
participants (3)
-
eric pouech (@epo) -
Trent Waddington -
Trent Waddington (@trent.waddington)