[PATCH v45 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. -- v45: kernel32: Fix string termination of GetModuleFileName Add tests for GetModuleFileName string termination. https://gitlab.winehq.org/wine/wine/-/merge_requests/10291
From: Trent Waddington <trent.waddington@tensorworks.com.au> --- dlls/kernel32/tests/loader.c | 48 ++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 529b9de870d..2ea83147296 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -1552,6 +1552,52 @@ 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; + + 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)); + 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=%llu\n", dll_name_term); + todo_wine { + ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %llu got %llu. 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; + + GetModuleFileNameA(NULL, dll_name, MAX_PATH); + err = GetLastError(); + ok(err == ERROR_SUCCESS, "error getting path for NULL module: %d\n", (int)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)); + 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=%llu\n", dll_name_term); + todo_wine { + ok(dll_name_term == dll_name_len - 1, "incorrect path termination for NULL module with short buffer. Expected %llu got %llu. rv=%lu\n", dll_name_len - 1, dll_name_term, rv); + } +} + /* Verify linking style of import descriptors */ static void test_ImportDescriptors(void) { @@ -4859,6 +4905,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/kernelbase/loader.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/dlls/kernelbase/loader.c b/dlls/kernelbase/loader.c index f4e1ca2e23a..aeac1c3ec77 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); + if (len < size) + filename[len] = 0; + else if (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
participants (2)
-
Trent Waddington -
Trent Waddington (@trent.waddington)