The serie intent is to fix unexpected paths in module's list: This happens: - when running under old / (new) wow64 - when main module is located under the syswow64 directory - the 32 bit modules are stored in LdrData (and then exposed through a couple of ways) under syswow64 (they are normally stored under system32, letting the redirection come into play when needed)
This triggers a couple of errors in winetest (as we're using c:\windows\syswow64\msinfo32.exe in many tests to trigger a wow64 process from a winetest program).
This is the fix awaited in MR!2497.
@julliard: I'm not 100% happy with the fix itself by reintroducting ref to the redirected DLLs in ntdll/PE but couldn't find a better idea.
-- v3: ntdll,wow64: Unredirect DLLs filename before storing them into LdrData. kernel32: Harden some wow64 module tests.
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/kernel32/tests/loader.c | 30 ++++++++++++++++++++++++++---- 1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index 19f112efcd8..c354ba8f24d 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -4047,10 +4047,15 @@ static void test_InMemoryOrderModuleList(void) ok(entry2 == mark2, "expected entry2 == mark2, got %p and %p\n", entry2, mark2); }
-static void test_wow64_redirection_for_dll(const char *libname) +static void test_wow64_redirection_for_dll(const char *libname, BOOL will_fail) { HMODULE lib; char buf[256]; + static const char *system32dir = "c:\windows\system32\"; + static const char *syswow64dir = "c:\windows\syswow64\"; + const size_t sysdirlen = strlen(system32dir); + const size_t syswowlen = strlen(syswow64dir); + const char *modname;
if (!GetModuleHandleA(libname)) { @@ -4066,6 +4071,13 @@ static void test_wow64_redirection_for_dll(const char *libname) ok(lib != NULL, "Loading %s from full path should succeed with WOW64 redirection disabled\n", libname); if (lib) FreeLibrary(lib); + modname = strrchr(libname, '\'); + modname = modname ? modname + 1 : libname; + todo_wine_if(will_fail) + ok((!strncasecmp(buf, system32dir, sysdirlen) && !strcasecmp(buf + sysdirlen, modname)) || + /* Win7 report from syswow64 */ + broken(!strncasecmp(buf, syswow64dir, syswowlen) && !strcasecmp(buf + syswowlen, modname)), + "Unexpected loaded DLL name %s for %s\n", buf, libname); } } else @@ -4085,10 +4097,20 @@ static void test_wow64_redirection(void) * already be loaded in this process). */ ok(pWow64DisableWow64FsRedirection(&OldValue), "Disabling FS redirection failed\n"); - test_wow64_redirection_for_dll("wlanapi.dll"); - test_wow64_redirection_for_dll("dxgi.dll"); - test_wow64_redirection_for_dll("dwrite.dll"); + test_wow64_redirection_for_dll("wlanapi.dll", FALSE); + test_wow64_redirection_for_dll("dxgi.dll", FALSE); + test_wow64_redirection_for_dll("dwrite.dll", FALSE); + test_wow64_redirection_for_dll("c:\windows\syswow64\wlanapi.dll", TRUE); + test_wow64_redirection_for_dll("c:\windows\syswow64\dxgi.dll", TRUE); + test_wow64_redirection_for_dll("c:\windows\syswow64\dwrite.dll", TRUE); ok(pWow64RevertWow64FsRedirection(OldValue), "Re-enabling FS redirection failed\n"); + /* and results don't depend whether redirection is enabled or not */ + test_wow64_redirection_for_dll("wlanapi.dll", FALSE); + test_wow64_redirection_for_dll("dxgi.dll", FALSE); + test_wow64_redirection_for_dll("dwrite.dll", FALSE); + test_wow64_redirection_for_dll("c:\windows\syswow64\wlanapi.dll", TRUE); + test_wow64_redirection_for_dll("c:\windows\syswow64\dxgi.dll", TRUE); + test_wow64_redirection_for_dll("c:\windows\syswow64\dwrite.dll", TRUE); }
static void test_dll_file( const char *name )
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/tests/dbghelp.c | 7 +------ dlls/kernel32/tests/loader.c | 27 +++++++++++++-------------- dlls/ntdll/loader.c | 23 +++++++++++++++++++++++ dlls/psapi/tests/psapi_main.c | 2 -- 4 files changed, 37 insertions(+), 22 deletions(-)
diff --git a/dlls/dbghelp/tests/dbghelp.c b/dlls/dbghelp/tests/dbghelp.c index 276faf0101a..d6cd1c9da70 100644 --- a/dlls/dbghelp/tests/dbghelp.c +++ b/dlls/dbghelp/tests/dbghelp.c @@ -719,7 +719,7 @@ static void test_loaded_modules(void) break; case PCSKIND_64BIT: case PCSKIND_WOW64: - todo_wine + case PCSKIND_WINE_OLD_WOW64: ok(aggregation.count_systemdir > 2 && aggregation.count_wowdir == 1, "Wrong directory aggregation count %u %u\n", aggregation.count_systemdir, aggregation.count_wowdir); break; @@ -727,10 +727,6 @@ static void test_loaded_modules(void) ok(aggregation.count_systemdir > 2 && aggregation.count_wowdir == 0, "Wrong directory aggregation count %u %u\n", aggregation.count_systemdir, aggregation.count_wowdir); break; - case PCSKIND_WINE_OLD_WOW64: - ok(aggregation.count_systemdir == 1 && aggregation.count_wowdir > 2, "Wrong directory aggregation count %u %u\n", - aggregation.count_systemdir, aggregation.count_wowdir); - break; } }
@@ -767,7 +763,6 @@ static void test_loaded_modules(void) aggregation.count_32bit, aggregation.count_64bit); ok(aggregation.count_exe == 1 && aggregation.count_ntdll == 1, "Wrong kind aggregation count %u %u\n", aggregation.count_exe, aggregation.count_ntdll); - todo_wine ok(aggregation.count_systemdir > 2 && aggregation.count_64bit == aggregation.count_systemdir && aggregation.count_wowdir == 1, "Wrong directory aggregation count %u %u\n", aggregation.count_systemdir, aggregation.count_wowdir); diff --git a/dlls/kernel32/tests/loader.c b/dlls/kernel32/tests/loader.c index c354ba8f24d..76d6951fff1 100644 --- a/dlls/kernel32/tests/loader.c +++ b/dlls/kernel32/tests/loader.c @@ -4047,7 +4047,7 @@ static void test_InMemoryOrderModuleList(void) ok(entry2 == mark2, "expected entry2 == mark2, got %p and %p\n", entry2, mark2); }
-static void test_wow64_redirection_for_dll(const char *libname, BOOL will_fail) +static void test_wow64_redirection_for_dll(const char *libname) { HMODULE lib; char buf[256]; @@ -4073,7 +4073,6 @@ static void test_wow64_redirection_for_dll(const char *libname, BOOL will_fail) FreeLibrary(lib); modname = strrchr(libname, '\'); modname = modname ? modname + 1 : libname; - todo_wine_if(will_fail) ok((!strncasecmp(buf, system32dir, sysdirlen) && !strcasecmp(buf + sysdirlen, modname)) || /* Win7 report from syswow64 */ broken(!strncasecmp(buf, syswow64dir, syswowlen) && !strcasecmp(buf + syswowlen, modname)), @@ -4097,20 +4096,20 @@ static void test_wow64_redirection(void) * already be loaded in this process). */ ok(pWow64DisableWow64FsRedirection(&OldValue), "Disabling FS redirection failed\n"); - test_wow64_redirection_for_dll("wlanapi.dll", FALSE); - test_wow64_redirection_for_dll("dxgi.dll", FALSE); - test_wow64_redirection_for_dll("dwrite.dll", FALSE); - test_wow64_redirection_for_dll("c:\windows\syswow64\wlanapi.dll", TRUE); - test_wow64_redirection_for_dll("c:\windows\syswow64\dxgi.dll", TRUE); - test_wow64_redirection_for_dll("c:\windows\syswow64\dwrite.dll", TRUE); + test_wow64_redirection_for_dll("wlanapi.dll"); + test_wow64_redirection_for_dll("dxgi.dll"); + test_wow64_redirection_for_dll("dwrite.dll"); + test_wow64_redirection_for_dll("c:\windows\syswow64\wlanapi.dll"); + test_wow64_redirection_for_dll("c:\windows\syswow64\dxgi.dll"); + test_wow64_redirection_for_dll("c:\windows\syswow64\dwrite.dll"); ok(pWow64RevertWow64FsRedirection(OldValue), "Re-enabling FS redirection failed\n"); /* and results don't depend whether redirection is enabled or not */ - test_wow64_redirection_for_dll("wlanapi.dll", FALSE); - test_wow64_redirection_for_dll("dxgi.dll", FALSE); - test_wow64_redirection_for_dll("dwrite.dll", FALSE); - test_wow64_redirection_for_dll("c:\windows\syswow64\wlanapi.dll", TRUE); - test_wow64_redirection_for_dll("c:\windows\syswow64\dxgi.dll", TRUE); - test_wow64_redirection_for_dll("c:\windows\syswow64\dwrite.dll", TRUE); + test_wow64_redirection_for_dll("wlanapi.dll"); + test_wow64_redirection_for_dll("dxgi.dll"); + test_wow64_redirection_for_dll("dwrite.dll"); + test_wow64_redirection_for_dll("c:\windows\syswow64\wlanapi.dll"); + test_wow64_redirection_for_dll("c:\windows\syswow64\dxgi.dll"); + test_wow64_redirection_for_dll("c:\windows\syswow64\dwrite.dll"); }
static void test_dll_file( const char *name ) diff --git a/dlls/ntdll/loader.c b/dlls/ntdll/loader.c index 7eb8e9ee8f1..3403369031b 100644 --- a/dlls/ntdll/loader.c +++ b/dlls/ntdll/loader.c @@ -1413,6 +1413,24 @@ static NTSTATUS fixup_imports( WINE_MODREF *wm, LPCWSTR load_path ) return status; }
+static NTSTATUS WINAPI wine_unredirect_file_name( WCHAR *filename ) +{ + static const WCHAR *redirected[] = {L"syswow64\", L"sysarm32\", L"sysx8664\", L"sysarm64\"}; + static const size_t windir_len = 11; /* C:\windows\ */ + static const size_t redir_len = 9; /* all have same len */ + int i; + + for (i = 0; i < ARRAY_SIZE(redirected); i++) + { + if (!wcsnicmp( filename, L"C:\windows\", windir_len ) && + !wcsnicmp( filename + windir_len, redirected[i], redir_len )) + { + memcpy( filename + windir_len, L"system32\", redir_len * sizeof(WCHAR) ); + return STATUS_SUCCESS; + } + } + return STATUS_NOT_FOUND; +}
/************************************************************************* * alloc_module @@ -1454,6 +1472,11 @@ static WINE_MODREF *alloc_module( HMODULE hModule, const UNICODE_STRING *nt_name
memcpy( buffer, nt_name->Buffer + 4 /* ??\ prefix */, nt_name->Length - 4 * sizeof(WCHAR) ); buffer[nt_name->Length/sizeof(WCHAR) - 4] = 0; + /* main module is not unredirected, while other modules are */ + if (NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList.Flink != &NtCurrentTeb()->Peb->LdrData->InLoadOrderModuleList) + { + wine_unredirect_file_name( buffer ); + } if ((p = wcsrchr( buffer, '\' ))) p++; else p = buffer; RtlInitUnicodeString( &wm->ldr.FullDllName, buffer ); diff --git a/dlls/psapi/tests/psapi_main.c b/dlls/psapi/tests/psapi_main.c index 8d7b169703a..e1028d805ae 100644 --- a/dlls/psapi/tests/psapi_main.c +++ b/dlls/psapi/tests/psapi_main.c @@ -525,12 +525,10 @@ static void test_EnumProcessModulesEx(void) ret = GetSystemWow64DirectoryA(buffer, sizeof(buffer)); ok(ret, "GetSystemWow64DirectoryA failed: %lu\n", GetLastError()); count = snapshot_count_in_dir(snap, pi.hProcess, buffer); - todo_wine ok(count <= 1, "Wrong count %u in %s\n", count, buffer); /* msinfo32 can be from system wow64 */ ret = GetSystemDirectoryA(buffer, sizeof(buffer)); ok(ret, "GetSystemDirectoryA failed: %lu\n", GetLastError()); count = snapshot_count_in_dir(snap, pi.hProcess, buffer); - todo_wine ok(count > 2, "Wrong count %u in %s\n", count, buffer);
/* in fact, this error is only returned when (list & 3 == 0), otherwise the corresponding
On Thu Apr 27 18:29:29 2023 +0000, Alexandre Julliard wrote:
Why are you adding a Unix call for this? That doesn't seem necessary.
Did it not to use the system directory names in PE ntdll. Redone without.
This merge request was closed by eric pouech.