The aim of this serie is to (re)implement dbghelp.EnumerateLoadedModules in order to return correct 32bit & 64bit modules information for a 32bit debuggee from a 64bit debugger. - In this case, Wine ntdll (incorrectly) stores the paths in LdrData (for system modules) within the syswow64 directory while native stores them within the system32 directory (except for 32bit ntdll which Wine correctly stores within system32). - So now dbghelp implements the system32 => syswow64 path rewrite (for the relevant cases), which is currently used only for ntdll. - This allows: - to be transparent in dbghelp if ntdll is fixed to store the same path as native - the paths returned by dbghelp are consistent with native (in the 64bit debugger / 32bit debuggee case mentionned above)
It must be noted that the remaining todo:s in tests are only for the case of a 32bit debugger / 32bit debuggee in (old|new) wow setup, where the returned paths are the (untouched from ntdll) paths, hence in syswow64 when native reports them from system32. - this patch doesn't modify the returned path, and we haven't noticed any issue so far - with redirection in place, access to the image files should be tranparent - so we can keep it as is (not fixing ntdll).
-- v2: dbghelp: Reimplement EnumerateLoadedModules(). dbghelp/tests: Add more test wrt. modules's imagename handling. dbghelp/test: Review old-wow64 expected values. dbghelp/tests: Fix process kind detection on old Windows machines.
From: Eric Pouech epouech@codeweavers.com
Signed-off-by: Eric Pouech epouech@codeweavers.com --- dlls/dbghelp/tests/dbghelp.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/dlls/dbghelp/tests/dbghelp.c b/dlls/dbghelp/tests/dbghelp.c index 276faf0101a..f45516c2882 100644 --- a/dlls/dbghelp/tests/dbghelp.c +++ b/dlls/dbghelp/tests/dbghelp.c @@ -571,12 +571,14 @@ static enum process_kind get_process_kind_internal(HANDLE process) { USHORT m1, m2;
- if (!pIsWow64Process2) + if (!pIsWow64Process2) /* only happens on old Win 8 and early win 1064v1507 */ { BOOL is_wow64; - return is_win64 ? PCSKIND_64BIT : - IsWow64Process(process, &is_wow64) && is_wow64 ? PCSKIND_WOW64 : - PCSKIND_32BIT; + + if (!strcmp(winetest_platform, "wine") || !IsWow64Process(process, &is_wow64)) + return PCSKIND_ERROR; + if (is_wow64) return PCSKIND_WOW64; + return is_win64 ? PCSKIND_64BIT : PCSKIND_32BIT; } if (!pIsWow64Process2(process, &m1, &m2)) return PCSKIND_ERROR; if (m1 == IMAGE_FILE_MACHINE_UNKNOWN && get_machine_bitness(m2) == 32) return PCSKIND_32BIT;
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/tests/dbghelp.c | 75 +++++++++++++++++++++++++++--------- 1 file changed, 56 insertions(+), 19 deletions(-)
diff --git a/dlls/dbghelp/tests/dbghelp.c b/dlls/dbghelp/tests/dbghelp.c index f45516c2882..cec462ee2f0 100644 --- a/dlls/dbghelp/tests/dbghelp.c +++ b/dlls/dbghelp/tests/dbghelp.c @@ -764,16 +764,34 @@ static void test_loaded_modules(void) ret = wrapper_EnumerateLoadedModulesW64(pi.hProcess, aggregate_cb, &aggregation); ok(ret, "EnumerateLoadedModulesW64 failed: %lu\n", GetLastError());
- todo_wine - ok(aggregation.count_32bit == 1 && aggregation.count_64bit, "Wrong bitness aggregation count %u %u\n", - 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); - + switch (get_process_kind(pi.hProcess)) + { + default: + ok(0, "Unknown process kind\n"); + break; + case PCSKIND_WINE_OLD_WOW64: + todo_wine + ok(aggregation.count_32bit == 1 && !aggregation.count_64bit, "Wrong bitness aggregation count %u %u\n", + aggregation.count_32bit, aggregation.count_64bit); + todo_wine + ok(aggregation.count_exe == 1 && aggregation.count_ntdll == 0, "Wrong kind aggregation count %u %u\n", + aggregation.count_exe, aggregation.count_ntdll); + todo_wine + ok(aggregation.count_systemdir == 0 && aggregation.count_wowdir == 1, + "Wrong directory aggregation count %u %u\n", + aggregation.count_systemdir, aggregation.count_wowdir); + break; + case PCSKIND_WOW64: + todo_wine + ok(aggregation.count_32bit == 1 && aggregation.count_64bit, "Wrong bitness aggregation count %u %u\n", + 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); + } ret = SymRefreshModuleList(pi.hProcess); ok(ret, "SymRefreshModuleList failed: %lu\n", GetLastError());
@@ -805,15 +823,34 @@ static void test_loaded_modules(void) ret = wrapper_EnumerateLoadedModulesW64(pi.hProcess, aggregate_cb, &aggregation2); ok(ret, "EnumerateLoadedModulesW64 failed: %lu\n", GetLastError());
- ok(aggregation2.count_32bit && aggregation2.count_64bit, "Wrong bitness aggregation count %u %u\n", - aggregation2.count_32bit, aggregation2.count_64bit); - todo_wine - ok(aggregation2.count_exe == 2 && aggregation2.count_ntdll == 2, "Wrong kind aggregation count %u %u\n", - aggregation2.count_exe, aggregation2.count_ntdll); - todo_wine - ok(aggregation2.count_systemdir > 2 && aggregation2.count_64bit == aggregation2.count_systemdir && aggregation2.count_wowdir > 2, - "Wrong directory aggregation count %u %u\n", - aggregation2.count_systemdir, aggregation2.count_wowdir); + switch (get_process_kind(pi.hProcess)) + { + case PCSKIND_ERROR: + break; + case PCSKIND_WINE_OLD_WOW64: + todo_wine + ok(aggregation2.count_32bit && !aggregation2.count_64bit, "Wrong bitness aggregation count %u %u\n", + aggregation2.count_32bit, aggregation2.count_64bit); + todo_wine + ok(aggregation2.count_exe == 2 && aggregation2.count_ntdll == 1, "Wrong kind aggregation count %u %u\n", + aggregation2.count_exe, aggregation2.count_ntdll); + todo_wine + ok(aggregation2.count_systemdir == 0 && aggregation2.count_32bit == aggregation2.count_wowdir + 1 && aggregation2.count_wowdir > 2, + "Wrong directory aggregation count %u %u\n", + aggregation2.count_systemdir, aggregation2.count_wowdir); + break; + default: + ok(aggregation2.count_32bit && aggregation2.count_64bit, "Wrong bitness aggregation count %u %u\n", + aggregation2.count_32bit, aggregation2.count_64bit); + todo_wine + ok(aggregation2.count_exe == 2 && aggregation2.count_ntdll == 2, "Wrong kind aggregation count %u %u\n", + aggregation2.count_exe, aggregation2.count_ntdll); + todo_wine + ok(aggregation2.count_systemdir > 2 && aggregation2.count_64bit == aggregation2.count_systemdir && aggregation2.count_wowdir > 2, + "Wrong directory aggregation count %u %u\n", + aggregation2.count_systemdir, aggregation2.count_wowdir); + break; + }
ret = SymRefreshModuleList(pi.hProcess); ok(ret, "SymRefreshModuleList failed: %lu\n", GetLastError());
From: Eric Pouech eric.pouech@gmail.com
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/tests/dbghelp.c | 493 +++++++++++++++++++++++++++++++++++ 1 file changed, 493 insertions(+)
diff --git a/dlls/dbghelp/tests/dbghelp.c b/dlls/dbghelp/tests/dbghelp.c index cec462ee2f0..211843dfd37 100644 --- a/dlls/dbghelp/tests/dbghelp.c +++ b/dlls/dbghelp/tests/dbghelp.c @@ -614,6 +614,12 @@ static enum process_kind get_process_kind(HANDLE process) return pcskind; }
+static const char* process_kind2string(enum process_kind pcskind) +{ + static const char* str[] = {"error", "64bit", "32bit", "wine_old_wow64", "wow64"}; + return (pcskind >= ARRAY_SIZE(str)) ? str[0] : str[pcskind]; +} + struct loaded_module_aggregation { HANDLE proc; @@ -868,6 +874,492 @@ static void test_loaded_modules(void) } }
+static USHORT pcs_get_loaded_module_machine(HANDLE hProc, DWORD64 base) +{ + IMAGE_DOS_HEADER dos; + DWORD signature; + IMAGE_FILE_HEADER fh; + BOOL ret; + + ret = ReadProcessMemory(hProc, (char*)(DWORD_PTR)base, &dos, sizeof(dos), NULL); + ok(ret, "ReadProcessMemory failed: %lu\n", GetLastError()); + ok(dos.e_magic == IMAGE_DOS_SIGNATURE, "Unexpected signature %x\n", dos.e_magic); + ret = ReadProcessMemory(hProc, (char*)(DWORD_PTR)(base + dos.e_lfanew), &signature, sizeof(signature), NULL); + ok(ret, "ReadProcessMemory failed: %lu\n", GetLastError()); + ok(signature == IMAGE_NT_SIGNATURE, "Unexpected signature %lx\n", signature); + ret = ReadProcessMemory(hProc, (char*)(DWORD_PTR)(base + dos.e_lfanew + sizeof(signature) ), &fh, sizeof(fh), NULL); + ok(ret, "ReadProcessMemory failed: %lu\n", GetLastError()); + return fh.Machine; +} + +static void aggregation_push(struct loaded_module_aggregation* aggregation, DWORD64 base, const WCHAR* name, USHORT machine) +{ + BOOL wow64; + + switch (get_machine_bitness(machine)) + { + case 32: aggregation->count_32bit++; break; + case 64: aggregation->count_64bit++; break; + default: break; + } + if (ends_withW(name, L".exe")) + aggregation->count_exe++; + if (ends_withW(name, L"ntdll.dll")) + aggregation->count_ntdll++; + if (!wcsnicmp(name, system_directory, wcslen(system_directory))) + aggregation->count_systemdir++; + if (IsWow64Process(aggregation->proc, &wow64) && wow64 && + !wcsnicmp(name, wow64_directory, wcslen(wow64_directory))) + aggregation->count_wowdir++; +} + +static BOOL CALLBACK aggregation_sym_cb(const WCHAR* name, DWORD64 base, void* usr) +{ + struct loaded_module_aggregation* aggregation = usr; + IMAGEHLP_MODULEW64 module; + BOOL ret; + + module.SizeOfStruct = sizeof(module); + ret = SymGetModuleInfoW64(aggregation->proc, base, &module); + ok(ret, "SymGetModuleInfoW64 failed: %lu\n", GetLastError()); + + aggregation_push(aggregation, base, module.LoadedImageName, module.MachineType); + + return TRUE; +} + +static BOOL CALLBACK aggregate_enum_cb(PCWSTR imagename, DWORD64 base, ULONG sz, PVOID usr) +{ + struct loaded_module_aggregation* aggregation = usr; + + aggregation_push(aggregation, base, imagename, pcs_get_loaded_module_machine(aggregation->proc, base)); + + return TRUE; +} + +static BOOL pcs_fetch_module_name(HANDLE proc, void* str_addr, void* module_base, WCHAR* buffer, unsigned bufsize, BOOL unicode) +{ + BOOL ret = FALSE; + + if (str_addr) + { + void* tgt = NULL; + SIZE_T addr_size; + SIZE_T r; + BOOL is_wow64; + + ret = IsWow64Process(proc, &is_wow64); + ok(ret, "IsWow64Process failed: %lu\n", GetLastError()); + addr_size = is_win64 && is_wow64 ? 4 : sizeof(void*); + + /* note: string is not always present */ + /* assuming little endian CPU */ + ret = ReadProcessMemory(proc, str_addr, &tgt, addr_size, &r) && r == addr_size; + if (ret) + { + if (unicode) + { + ret = ReadProcessMemory(proc, tgt, buffer, bufsize, &r); + if (ret) + buffer[r / sizeof(WCHAR)] = '\0'; + /* Win11 starts exposing ntdll from the string indirection in DLL load event. + * So we won't fall back to the mapping's filename below, good! + * But the sent DLL name for the 32bit ntdll is now "ntdll32.dll" instead of "ntdll.dll". + * Replace it by "ntdll.dll" so we won't have to worry about it in the rest of the code. + */ + if (broken(!wcscmp(buffer, L"ntdll32.dll"))) + wcscpy(buffer, L"ntdll.dll"); + } + else + { + char *tmp = malloc(bufsize); + if (tmp) + { + ret = ReadProcessMemory(proc, tgt, tmp, bufsize, &r); + if (ret) + { + if (!r) tmp[0] = '\0'; + else if (!memchr(tmp, '\0', r)) tmp[r - 1] = '\0'; + MultiByteToWideChar(CP_ACP, 0, tmp, -1, buffer, bufsize); + buffer[bufsize - 1] = '\0'; + } + free(tmp); + } + else ret = FALSE; + } + } + } + if (!ret) + { + WCHAR tmp[128]; + WCHAR drv[3] = {L'A', L':', L'\0'}; + + ret = GetMappedFileNameW(proc, module_base, buffer, bufsize); + /* Win8 returns this error */ + if (!broken(!ret && GetLastError() == ERROR_FILE_INVALID)) + { + ok(ret, "GetMappedFileNameW failed: %lu\n", GetLastError()); + if (!wcsncmp(buffer, L"\??\", 4)) + memmove(buffer, buffer + 4, (wcslen(buffer) + 1 - 4) * sizeof(WCHAR)); + while (drv[0] <= L'Z') + { + if (QueryDosDeviceW(drv, tmp, ARRAY_SIZE(tmp))) + { + size_t len = wcslen(tmp); + if (len >= 2 && !wcsnicmp(buffer, tmp, len)) + { + memmove(buffer + 2, buffer + len, (wcslen(buffer) + 1 - len) * sizeof(WCHAR)); + buffer[0] = drv[0]; + buffer[1] = drv[1]; + break; + } + } + drv[0]++; + } + } + } + return ret; +} + +static void test_live_modules_proc(WCHAR* exename, BOOL with_32) +{ + WCHAR buffer[MAX_PATH]; + PROCESS_INFORMATION pi = {0}; + STARTUPINFOW si = {0}; + DEBUG_EVENT de; + BOOL ret; + BOOL is_wow64 = FALSE; + struct loaded_module_aggregation aggregation_event = {}; + struct loaded_module_aggregation aggregation_enum = {}; + struct loaded_module_aggregation aggregation_sym = {}; + DWORD old_options = SymGetOptions(); + enum process_kind pcskind; + + ret = CreateProcessW(NULL, exename, NULL, NULL, FALSE, DEBUG_PROCESS, NULL, NULL, &si, &pi); + if (!ret) + { + if (GetLastError() == ERROR_FILE_NOT_FOUND) + skip("Skip wow64 test on non compatible platform\n"); + else + ok(ret, "CreateProcess failed: %lu\n", GetLastError()); + return; + } + + ret = IsWow64Process(pi.hProcess, &is_wow64); + ok(ret, "IsWow64Process failed: %lu\n", GetLastError()); + pcskind = get_process_kind(pi.hProcess); + ok(pcskind != PCSKIND_ERROR, "Unexpected error\n"); + + winetest_push_context("[%u/%u enum:%s %s]", + is_win64 ? 64 : 32, is_wow64 ? 32 : 64, with_32 ? "+32bit" : "default", + process_kind2string(pcskind)); + + memset(&aggregation_event, 0, sizeof(aggregation_event)); + aggregation_event.proc = pi.hProcess; + while (WaitForDebugEvent(&de, 2000)) + { + switch (de.dwDebugEventCode) + { + case CREATE_PROCESS_DEBUG_EVENT: + if (pcs_fetch_module_name(pi.hProcess, de.u.CreateProcessInfo.lpImageName, de.u.CreateProcessInfo.lpBaseOfImage, + buffer, ARRAY_SIZE(buffer), de.u.CreateProcessInfo.fUnicode)) + aggregation_push(&aggregation_event, (ULONG_PTR)de.u.CreateProcessInfo.lpBaseOfImage, buffer, + pcs_get_loaded_module_machine(pi.hProcess, (ULONG_PTR)de.u.CreateProcessInfo.lpBaseOfImage)); + break; + case LOAD_DLL_DEBUG_EVENT: + if (pcs_fetch_module_name(pi.hProcess, de.u.LoadDll.lpImageName, de.u.LoadDll.lpBaseOfDll, buffer, ARRAY_SIZE(buffer), de.u.LoadDll.fUnicode)) + aggregation_push(&aggregation_event, (ULONG_PTR)de.u.LoadDll.lpBaseOfDll, buffer, + pcs_get_loaded_module_machine(pi.hProcess, (ULONG_PTR)de.u.LoadDll.lpBaseOfDll)); + break; + case UNLOAD_DLL_DEBUG_EVENT: + /* FIXME: we should take of updating aggregation_event; as of today, doesn't trigger issue */ + break; + case EXCEPTION_DEBUG_EVENT: + break; + } + ret = ContinueDebugEvent(de.dwProcessId, de.dwThreadId, DBG_CONTINUE); + ok(ret, "ContinueDebugEvent failed: %lu\n", GetLastError()); + } + + if (with_32) + SymSetOptions(old_options | SYMOPT_INCLUDE_32BIT_MODULES); + else + SymSetOptions(old_options & ~SYMOPT_INCLUDE_32BIT_MODULES); + + memset(&aggregation_enum, 0, sizeof(aggregation_enum)); + aggregation_enum.proc = pi.hProcess; + ret = wrapper_EnumerateLoadedModulesW64(pi.hProcess, aggregate_enum_cb, &aggregation_enum); + ok(ret, "SymEnumerateModulesW64 failed: %lu\n", GetLastError()); + + ret = SymInitialize(pi.hProcess, NULL, TRUE); + ok(ret, "SymInitialize failed: %lu\n", GetLastError()); + +/* .exe ntdll kernel32 kernelbase user32 gdi32 (all are in system or wow64 directory) */ +#define MODCOUNT 6 +/* when in wow64: wow64 wow64cpu wow64win ntdll (64bit) */ +#define MODWOWCOUNT 4 +/* .exe is reported twice in enum */ +#define XTRAEXE (!!with_32) +/* ntdll is reported twice in enum */ +#define XTRANTDLL (is_win64 && is_wow64 && (!!with_32)) + + memset(&aggregation_sym, 0, sizeof(aggregation_sym)); + aggregation_sym.proc = pi.hProcess; + ret = SymEnumerateModulesW64(pi.hProcess, aggregation_sym_cb, &aggregation_sym); + ok(ret, "SymEnumerateModulesW64 failed: %lu\n", GetLastError()); + + if (pcskind == PCSKIND_64BIT) /* 64/64 */ + { + ok(is_win64, "How come?\n"); + ok(aggregation_event.count_exe == 1, "Unexpected event.count_exe %u\n", aggregation_event.count_exe); + ok(aggregation_event.count_32bit == 0, "Unexpected event.count_32bit %u\n", aggregation_event.count_32bit); + ok(aggregation_event.count_64bit >= MODCOUNT, "Unexpected event.count_64bit %u\n", aggregation_event.count_64bit); + ok(aggregation_event.count_systemdir >= MODCOUNT, "Unexpected event.count_systemdir %u\n", aggregation_event.count_systemdir); + ok(aggregation_event.count_wowdir == 0, "Unexpected event.count_wowdir %u\n", aggregation_event.count_wowdir); + ok(aggregation_event.count_ntdll == 1, "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll); + + ok(aggregation_enum.count_exe == 1, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); + ok(aggregation_enum.count_32bit == 0, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + ok(aggregation_enum.count_64bit >= MODCOUNT, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); + ok(aggregation_enum.count_systemdir >= MODCOUNT, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); + ok(aggregation_enum.count_wowdir == 0, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + ok(aggregation_enum.count_ntdll == 1, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll); + + ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); + ok(aggregation_sym.count_32bit == 0, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + ok(aggregation_sym.count_64bit >= MODCOUNT, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); + ok(aggregation_sym.count_systemdir >= MODCOUNT, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); + ok(aggregation_sym.count_wowdir == 0, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + ok(aggregation_sym.count_ntdll == 1, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); + } + else if (pcskind == PCSKIND_32BIT) /* 32/32 */ + { + ok(!is_win64, "How come?\n"); + ok(aggregation_event.count_exe == 1, "Unexpected event.count_exe %u\n", aggregation_event.count_exe); + ok(aggregation_event.count_32bit >= MODCOUNT, "Unexpected event.count_32bit %u\n", aggregation_event.count_32bit); + ok(aggregation_event.count_64bit == 0, "Unexpected event.count_64bit %u\n", aggregation_event.count_64bit); + ok(aggregation_event.count_systemdir >= MODCOUNT, "Unexpected event.count_systemdir %u\n", aggregation_event.count_systemdir); + ok(aggregation_event.count_wowdir == 0, "Unexpected event.count_wowdir %u\n", aggregation_event.count_wowdir); + ok(aggregation_event.count_ntdll == 1, "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll); + + ok(aggregation_enum.count_exe == 1, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); + ok(aggregation_enum.count_32bit >= MODCOUNT, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + ok(aggregation_enum.count_64bit == 0, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); + ok(aggregation_enum.count_systemdir >= MODCOUNT, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); + ok(aggregation_enum.count_wowdir == 0, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + ok(aggregation_enum.count_ntdll == 1, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll); + + ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); + ok(aggregation_sym.count_32bit >= MODCOUNT, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + ok(aggregation_sym.count_64bit == 0, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); + ok(aggregation_sym.count_systemdir >= MODCOUNT, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); + ok(aggregation_sym.count_wowdir == 0, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + ok(aggregation_sym.count_ntdll == 1, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); + } + else if (is_win64 && pcskind == PCSKIND_WOW64) /* 64/32 */ + { + ok(aggregation_event.count_exe == 1, "Unexpected event.count_exe %u\n", aggregation_event.count_exe); + ok(aggregation_event.count_32bit >= MODCOUNT, "Unexpected event.count_32bit %u\n", aggregation_event.count_32bit); + ok(aggregation_event.count_64bit >= MODWOWCOUNT, "Unexpected event.count_64bit %u\n", aggregation_event.count_64bit); + ok(aggregation_event.count_systemdir >= MODWOWCOUNT, "Unexpected event.count_systemdir %u\n", aggregation_event.count_systemdir); + ok(aggregation_event.count_wowdir >= MODCOUNT, "Unexpected event.count_wowdir %u\n", aggregation_event.count_wowdir); + ok(aggregation_event.count_ntdll == 2 || broken(aggregation_event.count_ntdll == 3), + /* yes! with Win 864 and Win1064 v 1507... 2 ntdll:s ain't enuff <g>, 3 are reported! */ + /* in fact the first ntdll is reported twice (at same address) in two consecutive events */ + "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll); + + todo_wine_if(with_32) + ok(aggregation_enum.count_exe == 1 + XTRAEXE, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); + if (with_32) + ok(aggregation_enum.count_32bit >= MODCOUNT, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + else + todo_wine + ok(aggregation_enum.count_32bit == 1, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + todo_wine + ok(aggregation_enum.count_64bit >= MODWOWCOUNT, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); + todo_wine + ok(aggregation_enum.count_systemdir >= MODWOWCOUNT, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); + if (with_32) + ok(aggregation_enum.count_wowdir >= MODCOUNT, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + else + todo_wine + ok(aggregation_enum.count_wowdir == 1, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + todo_wine_if(with_32) + ok(aggregation_enum.count_ntdll == 1 + XTRANTDLL, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll); + + ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); + if (with_32) + ok(aggregation_sym.count_32bit >= MODCOUNT, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + else + todo_wine + ok(aggregation_sym.count_32bit == 1, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + todo_wine + ok(aggregation_sym.count_64bit >= MODWOWCOUNT, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); + todo_wine + ok(aggregation_sym.count_systemdir >= MODWOWCOUNT, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); + if (with_32) + ok(aggregation_sym.count_wowdir >= MODCOUNT, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + else + todo_wine + ok(aggregation_sym.count_wowdir == 1, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + todo_wine_if(with_32) + ok(aggregation_sym.count_ntdll == 1 + XTRANTDLL, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); + } + else if (!is_win64 && pcskind == PCSKIND_WOW64) /* 32/32 */ + { + ok(aggregation_event.count_exe == 1, "Unexpected event.count_exe %u\n", aggregation_event.count_exe); + ok(aggregation_event.count_32bit >= MODCOUNT, "Unexpected event.count_32bit %u\n", aggregation_event.count_32bit); + ok(aggregation_event.count_64bit == 0, "Unexpected event.count_64bit %u\n", aggregation_event.count_64bit); + ok(aggregation_event.count_systemdir == 0, "Unexpected event.count_systemdir %u\n", aggregation_event.count_systemdir); + ok(aggregation_event.count_wowdir >= MODCOUNT, "Unexpected event.count_wowdir %u\n", aggregation_event.count_wowdir); + ok(aggregation_event.count_ntdll == 1, "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll); + + ok(aggregation_enum.count_exe == 1 + XTRAEXE, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); + ok(aggregation_enum.count_32bit >= MODCOUNT, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + ok(aggregation_enum.count_64bit == 0, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); + /* yes that's different from event! */ + todo_wine + ok(aggregation_enum.count_systemdir >= MODCOUNT - 1, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); + /* .exe */ + todo_wine + ok(aggregation_enum.count_wowdir == 1, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + ok(aggregation_enum.count_ntdll == 1, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll); + + ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); + ok(aggregation_sym.count_32bit >= MODCOUNT, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + ok(aggregation_sym.count_64bit == 0, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); + todo_wine + ok(aggregation_sym.count_systemdir >= MODCOUNT - 1, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); + /* .exe */ + todo_wine + ok(aggregation_sym.count_wowdir == 1, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + ok(aggregation_sym.count_ntdll == 1 + XTRANTDLL, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); + } + else if (is_win64 && pcskind == PCSKIND_WINE_OLD_WOW64) /* 64/32 */ + { + ok(aggregation_event.count_exe == 1, "Unexpected event.count_exe %u\n", aggregation_event.count_exe); + ok(aggregation_event.count_32bit >= MODCOUNT, "Unexpected event.count_32bit %u\n", aggregation_event.count_32bit); + ok(aggregation_event.count_64bit == 0, "Unexpected event.count_64bit %u\n", aggregation_event.count_64bit); + ok(aggregation_event.count_systemdir >= 1, "Unexpected event.count_systemdir %u\n", aggregation_event.count_systemdir); + ok(aggregation_event.count_wowdir >= MODCOUNT - 1, "Unexpected event.count_wowdir %u\n", aggregation_event.count_wowdir); + ok(aggregation_event.count_ntdll == 1, "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll); + + todo_wine_if(with_32) + ok(aggregation_enum.count_exe == 1 + XTRAEXE, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); + if (with_32) + ok(aggregation_enum.count_32bit >= MODCOUNT, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + else + todo_wine + ok(aggregation_enum.count_32bit <= 1, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + ok(aggregation_enum.count_64bit == 0, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); + todo_wine + ok(aggregation_enum.count_systemdir == 0, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); + if (with_32) + ok(aggregation_enum.count_wowdir >= MODCOUNT, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + else + todo_wine + ok(aggregation_enum.count_wowdir <= 1, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + todo_wine_if(!with_32) + ok(aggregation_enum.count_ntdll == XTRANTDLL, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll); + + ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); + if (with_32) + ok(aggregation_sym.count_32bit >= MODCOUNT, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + else + todo_wine + ok(aggregation_sym.count_wowdir <= 1, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + todo_wine + ok(aggregation_sym.count_64bit == 0, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); + todo_wine + ok(aggregation_sym.count_systemdir == 0, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); + if (with_32) + ok(aggregation_sym.count_wowdir >= MODCOUNT, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + else + todo_wine + ok(aggregation_sym.count_wowdir <= 1, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + todo_wine_if(!with_32) + ok(aggregation_sym.count_ntdll == XTRANTDLL, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); + } + else if (!is_win64 && pcskind == PCSKIND_WINE_OLD_WOW64) /* 32/32 */ + { + ok(aggregation_event.count_exe == 1, "Unexpected event.count_exe %u\n", aggregation_event.count_exe); + ok(aggregation_event.count_32bit >= MODCOUNT, "Unexpected event.count_32bit %u\n", aggregation_event.count_32bit); + ok(aggregation_event.count_64bit == 0, "Unexpected event.count_64bit %u\n", aggregation_event.count_64bit); + ok(aggregation_event.count_systemdir == 1, "Unexpected event.count_systemdir %u\n", aggregation_event.count_systemdir); + ok(aggregation_event.count_wowdir >= MODCOUNT, "Unexpected event.count_wowdir %u\n", aggregation_event.count_wowdir); + ok(aggregation_event.count_ntdll == 1, "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll); + + ok(aggregation_enum.count_exe == 1 + XTRAEXE, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); + ok(aggregation_enum.count_32bit >= MODCOUNT, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); + ok(aggregation_enum.count_64bit == 0, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); + todo_wine + ok(aggregation_enum.count_systemdir >= MODCOUNT, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); + /* .exe */ + todo_wine + ok(aggregation_enum.count_wowdir == 1, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); + ok(aggregation_enum.count_ntdll == 1 + XTRANTDLL, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll); + + ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); + ok(aggregation_sym.count_32bit >= MODCOUNT, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); + ok(aggregation_sym.count_64bit == 0, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); + todo_wine + ok(aggregation_sym.count_systemdir >= MODCOUNT, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); + /* .exe */ + todo_wine + ok(aggregation_sym.count_wowdir == 1, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); + ok(aggregation_sym.count_ntdll == 1 + XTRANTDLL, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); + } + else + ok(0, "Unexpected process kind %u\n", pcskind); + + /* main module is enumerated twice in enum when including 32bit modules */ + todo_wine_if(is_win64 && (pcskind == PCSKIND_WOW64 || pcskind == PCSKIND_WINE_OLD_WOW64) && !with_32) + ok(aggregation_sym.count_32bit + XTRAEXE == aggregation_enum.count_32bit, "Different sym/enum count32_bit (%u/%u)\n", + aggregation_sym.count_32bit, aggregation_enum.count_32bit); + todo_wine_if(is_win64 && (pcskind == PCSKIND_WOW64 || pcskind == PCSKIND_WINE_OLD_WOW64)) + ok(aggregation_sym.count_64bit == aggregation_enum.count_64bit, "Different sym/enum count64_bit (%u/%u)\n", + aggregation_sym.count_64bit, aggregation_enum.count_64bit); + ok(aggregation_sym.count_systemdir == aggregation_enum.count_systemdir, "Different sym/enum systemdir (%u/%u)\n", + aggregation_sym.count_systemdir, aggregation_enum.count_systemdir); + todo_wine_if(with_32) + ok(aggregation_sym.count_wowdir + XTRAEXE == aggregation_enum.count_wowdir, "Different sym/enum wowdir (%u/%u)\n", + aggregation_sym.count_wowdir, aggregation_enum.count_wowdir); + todo_wine_if(with_32) + ok(aggregation_sym.count_exe + XTRAEXE == aggregation_enum.count_exe, "Different sym/enum exe (%u/%u)\n", + aggregation_sym.count_exe, aggregation_enum.count_exe); + ok(aggregation_sym.count_ntdll == aggregation_enum.count_ntdll, "Different sym/enum exe (%u/%u)\n", + aggregation_sym.count_ntdll, aggregation_enum.count_ntdll); + +#undef MODCOUNT +#undef MODWOWCOUNT +#undef XTRAEXE +#undef XTRANTDLL + + TerminateProcess(pi.hProcess, 0); + + winetest_pop_context(); + SymSetOptions(old_options); +} + +static void test_live_modules(void) +{ + WCHAR buffer[200]; + + wcscpy(buffer, system_directory); + wcscat(buffer, L"\msinfo32.exe"); + + test_live_modules_proc(buffer, FALSE); + + if (is_win64) + { + wcscpy(buffer, wow64_directory); + wcscat(buffer, L"\msinfo32.exe"); + + test_live_modules_proc(buffer, TRUE); + test_live_modules_proc(buffer, FALSE); + } +} + START_TEST(dbghelp) { BOOL ret; @@ -897,5 +1389,6 @@ START_TEST(dbghelp) { test_modules_overlap(); test_loaded_modules(); + test_live_modules(); } }
From: Eric Pouech eric.pouech@gmail.com
- correctly taking into accoung SYMOPT_INCLUDE_32BIT_MODULES option - converting, for 32bit modules requested from a 64bit module, the system32 paths into syswow64
Signed-off-by: Eric Pouech eric.pouech@gmail.com --- dlls/dbghelp/Makefile.in | 2 +- dlls/dbghelp/module.c | 139 +++++++++++++++++++++++++---------- dlls/dbghelp/tests/dbghelp.c | 35 --------- 3 files changed, 103 insertions(+), 73 deletions(-)
diff --git a/dlls/dbghelp/Makefile.in b/dlls/dbghelp/Makefile.in index 22be2612eeb..74647820126 100644 --- a/dlls/dbghelp/Makefile.in +++ b/dlls/dbghelp/Makefile.in @@ -1,6 +1,6 @@ MODULE = dbghelp.dll IMPORTLIB = dbghelp -IMPORTS = $(ZLIB_PE_LIBS) +IMPORTS = kernelbase $(ZLIB_PE_LIBS) EXTRAINCL = $(ZLIB_PE_CFLAGS) EXTRADEFS = -D_IMAGEHLP_SOURCE_ DELAYIMPORTS = version diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index ee559cfd99e..bae4a77f16e 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -1262,53 +1262,118 @@ BOOL WINAPI EnumerateLoadedModules(HANDLE hProcess, return EnumerateLoadedModulesW64(hProcess, enum_load_modW64_32, &x); }
+static unsigned int load_and_grow_modules(HANDLE process, HMODULE** hmods, unsigned start, unsigned* alloc, DWORD filter) +{ + DWORD needed; + BOOL ret; + + while ((ret = EnumProcessModulesEx(process, *hmods + start, (*alloc - start) * sizeof(HMODULE), + &needed, filter)) && + needed > (*alloc - start) * sizeof(HMODULE)) + { + HMODULE* new = HeapReAlloc(GetProcessHeap(), 0, *hmods, (*alloc) * 2 * sizeof(HMODULE)); + if (!new) return 0; + *hmods = new; + *alloc *= 2; + } + return ret ? needed / sizeof(HMODULE) : 0; +} + /****************************************************************** * EnumerateLoadedModulesW64 (DBGHELP.@) * */ -BOOL WINAPI EnumerateLoadedModulesW64(HANDLE hProcess, - PENUMLOADED_MODULES_CALLBACKW64 EnumLoadedModulesCallback, - PVOID UserContext) -{ - HMODULE* hMods; - WCHAR imagenameW[MAX_PATH]; - DWORD i, sz; - MODULEINFO mi; - BOOL wow64; - DWORD filter = LIST_MODULES_DEFAULT; - - hMods = HeapAlloc(GetProcessHeap(), 0, 256 * sizeof(hMods[0])); - if (!hMods) return FALSE; - - if (sizeof(void*) > sizeof(int) && - IsWow64Process(hProcess, &wow64) && - wow64) - filter = LIST_MODULES_32BIT; - - if (!EnumProcessModulesEx(hProcess, hMods, 256 * sizeof(hMods[0]), &sz, filter)) - { - /* hProcess should also be a valid process handle !! */ - HeapFree(GetProcessHeap(), 0, hMods); +BOOL WINAPI EnumerateLoadedModulesW64(HANDLE process, + PENUMLOADED_MODULES_CALLBACKW64 enum_cb, + PVOID user) +{ + HMODULE* hmods; + unsigned alloc = 256, count, count32, i; + USHORT pcs_machine, native_machine; + BOOL with_32bit_modules; + WCHAR imagenameW[MAX_PATH]; + MODULEINFO mi; + WCHAR* sysdir = NULL; + WCHAR* wowdir = NULL; + size_t sysdir_len = 0, wowdir_len = 0; + + /* process might not be a handle to a live process */ + if (!IsWow64Process2(process, &pcs_machine, &native_machine)) return FALSE; + with_32bit_modules = sizeof(void*) > sizeof(int) && + pcs_machine != IMAGE_FILE_MACHINE_UNKNOWN && + (dbghelp_options & SYMOPT_INCLUDE_32BIT_MODULES); + + if (!(hmods = HeapAlloc(GetProcessHeap(), 0, alloc * sizeof(hmods[0])))) return FALSE; - } - if (sz > 256 * sizeof(hMods[0])) + + /* Note: + * - we report modules returned from kernelbase.EnumProcessModulesEx + * - appending 32bit modules when possible and requested + * + * When considering 32bit modules in a wow64 child process, required from + * a 64bit process: + * - native returns from kernelbase.EnumProcessModulesEx + * redirected paths (that is in system32 directory), while + * dbghelp.EnumerateLoadedModulesWine returns the effective path + * (eg. syswow64 for x86_64). + * - (Except for the main module, if gotten from syswow64, where kernelbase + * will return the effective path) + * - Wine kernelbase (and ntdll) incorrectly return these modules from + * syswow64 (except for ntdll which is returned from system32). + * => for these modules, always perform a system32 => syswow64 path + * conversion (it'll work even if ntdll/kernelbase is fixed). + */ + if ((count = load_and_grow_modules(process, &hmods, 0, &alloc, LIST_MODULES_DEFAULT)) && with_32bit_modules) { - hMods = HeapReAlloc(GetProcessHeap(), 0, hMods, sz); - if (!hMods || !EnumProcessModulesEx(hProcess, hMods, sz, &sz, filter)) - return FALSE; + /* append 32bit modules when required */ + if ((count32 = load_and_grow_modules(process, &hmods, count, &alloc, LIST_MODULES_32BIT))) + { + sysdir_len = GetSystemDirectoryW(NULL, 0); + wowdir_len = GetSystemWow64Directory2W(NULL, 0, pcs_machine); + + if (!sysdir_len || !wowdir_len || + !(sysdir = HeapAlloc(GetProcessHeap(), 0, (sysdir_len + 1 + wowdir_len + 1) * sizeof(WCHAR)))) + { + HeapFree(GetProcessHeap(), 0, hmods); + return FALSE; + } + wowdir = sysdir + sysdir_len + 1; + if (GetSystemDirectoryW(sysdir, sysdir_len) >= sysdir_len) + FIXME("shouldn't happen\n"); + if (GetSystemWow64Directory2W(wowdir, wowdir_len, pcs_machine) >= wowdir_len) + FIXME("shouldn't happen\n"); + wcscat(sysdir, L"\"); + wcscat(wowdir, L"\"); + } } - sz /= sizeof(HMODULE); - for (i = 0; i < sz; i++) + else count32 = 0; + + for (i = 0; i < count + count32; i++) { - if (!GetModuleInformation(hProcess, hMods[i], &mi, sizeof(mi)) || - !GetModuleFileNameExW(hProcess, hMods[i], imagenameW, ARRAY_SIZE(imagenameW))) - continue; - EnumLoadedModulesCallback(imagenameW, (DWORD_PTR)mi.lpBaseOfDll, mi.SizeOfImage, - UserContext); + if (GetModuleInformation(process, hmods[i], &mi, sizeof(mi)) && + GetModuleFileNameExW(process, hmods[i], imagenameW, ARRAY_SIZE(imagenameW))) + { + /* rewrite path in system32 into syswow64 for 32bit modules */ + if (i >= count) + { + size_t len = wcslen(imagenameW); + + if (!wcsnicmp(imagenameW, sysdir, sysdir_len) && + (len - sysdir_len + wowdir_len) + 1 <= ARRAY_SIZE(imagenameW)) + { + memmove(&imagenameW[wowdir_len], &imagenameW[sysdir_len], (len - sysdir_len) * sizeof(WCHAR)); + memcpy(imagenameW, wowdir, wowdir_len * sizeof(WCHAR)); + } + } + if (!enum_cb(imagenameW, (DWORD_PTR)mi.lpBaseOfDll, mi.SizeOfImage, user)) + break; + } } - HeapFree(GetProcessHeap(), 0, hMods);
- return sz != 0 && i == sz; + HeapFree(GetProcessHeap(), 0, hmods); + HeapFree(GetProcessHeap(), 0, sysdir); + + return count != 0; }
static void dbghelp_str_WtoA(const WCHAR *src, char *dst, int dst_len) diff --git a/dlls/dbghelp/tests/dbghelp.c b/dlls/dbghelp/tests/dbghelp.c index 211843dfd37..6e3edc7c952 100644 --- a/dlls/dbghelp/tests/dbghelp.c +++ b/dlls/dbghelp/tests/dbghelp.c @@ -776,24 +776,19 @@ static void test_loaded_modules(void) ok(0, "Unknown process kind\n"); break; case PCSKIND_WINE_OLD_WOW64: - todo_wine ok(aggregation.count_32bit == 1 && !aggregation.count_64bit, "Wrong bitness aggregation count %u %u\n", aggregation.count_32bit, aggregation.count_64bit); - todo_wine ok(aggregation.count_exe == 1 && aggregation.count_ntdll == 0, "Wrong kind aggregation count %u %u\n", aggregation.count_exe, aggregation.count_ntdll); - todo_wine ok(aggregation.count_systemdir == 0 && aggregation.count_wowdir == 1, "Wrong directory aggregation count %u %u\n", aggregation.count_systemdir, aggregation.count_wowdir); break; case PCSKIND_WOW64: - todo_wine ok(aggregation.count_32bit == 1 && aggregation.count_64bit, "Wrong bitness aggregation count %u %u\n", 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); @@ -834,13 +829,10 @@ static void test_loaded_modules(void) case PCSKIND_ERROR: break; case PCSKIND_WINE_OLD_WOW64: - todo_wine ok(aggregation2.count_32bit && !aggregation2.count_64bit, "Wrong bitness aggregation count %u %u\n", aggregation2.count_32bit, aggregation2.count_64bit); - todo_wine ok(aggregation2.count_exe == 2 && aggregation2.count_ntdll == 1, "Wrong kind aggregation count %u %u\n", aggregation2.count_exe, aggregation2.count_ntdll); - todo_wine ok(aggregation2.count_systemdir == 0 && aggregation2.count_32bit == aggregation2.count_wowdir + 1 && aggregation2.count_wowdir > 2, "Wrong directory aggregation count %u %u\n", aggregation2.count_systemdir, aggregation2.count_wowdir); @@ -848,10 +840,8 @@ static void test_loaded_modules(void) default: ok(aggregation2.count_32bit && aggregation2.count_64bit, "Wrong bitness aggregation count %u %u\n", aggregation2.count_32bit, aggregation2.count_64bit); - todo_wine ok(aggregation2.count_exe == 2 && aggregation2.count_ntdll == 2, "Wrong kind aggregation count %u %u\n", aggregation2.count_exe, aggregation2.count_ntdll); - todo_wine ok(aggregation2.count_systemdir > 2 && aggregation2.count_64bit == aggregation2.count_systemdir && aggregation2.count_wowdir > 2, "Wrong directory aggregation count %u %u\n", aggregation2.count_systemdir, aggregation2.count_wowdir); @@ -1168,41 +1158,30 @@ static void test_live_modules_proc(WCHAR* exename, BOOL with_32) /* in fact the first ntdll is reported twice (at same address) in two consecutive events */ "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll);
- todo_wine_if(with_32) ok(aggregation_enum.count_exe == 1 + XTRAEXE, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); if (with_32) ok(aggregation_enum.count_32bit >= MODCOUNT, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); else - todo_wine ok(aggregation_enum.count_32bit == 1, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); - todo_wine ok(aggregation_enum.count_64bit >= MODWOWCOUNT, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); - todo_wine ok(aggregation_enum.count_systemdir >= MODWOWCOUNT, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); if (with_32) ok(aggregation_enum.count_wowdir >= MODCOUNT, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); else - todo_wine ok(aggregation_enum.count_wowdir == 1, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); - todo_wine_if(with_32) ok(aggregation_enum.count_ntdll == 1 + XTRANTDLL, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll);
ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); if (with_32) ok(aggregation_sym.count_32bit >= MODCOUNT, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); else - todo_wine ok(aggregation_sym.count_32bit == 1, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); - todo_wine ok(aggregation_sym.count_64bit >= MODWOWCOUNT, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); - todo_wine ok(aggregation_sym.count_systemdir >= MODWOWCOUNT, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); if (with_32) ok(aggregation_sym.count_wowdir >= MODCOUNT, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); else - todo_wine ok(aggregation_sym.count_wowdir == 1, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); - todo_wine_if(with_32) ok(aggregation_sym.count_ntdll == 1 + XTRANTDLL, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); } else if (!is_win64 && pcskind == PCSKIND_WOW64) /* 32/32 */ @@ -1244,40 +1223,30 @@ static void test_live_modules_proc(WCHAR* exename, BOOL with_32) ok(aggregation_event.count_wowdir >= MODCOUNT - 1, "Unexpected event.count_wowdir %u\n", aggregation_event.count_wowdir); ok(aggregation_event.count_ntdll == 1, "Unexpected event.count_ntdll %u\n", aggregation_event.count_ntdll);
- todo_wine_if(with_32) ok(aggregation_enum.count_exe == 1 + XTRAEXE, "Unexpected enum.count_exe %u\n", aggregation_enum.count_exe); if (with_32) ok(aggregation_enum.count_32bit >= MODCOUNT, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); else - todo_wine ok(aggregation_enum.count_32bit <= 1, "Unexpected enum.count_32bit %u\n", aggregation_enum.count_32bit); ok(aggregation_enum.count_64bit == 0, "Unexpected enum.count_64bit %u\n", aggregation_enum.count_64bit); - todo_wine ok(aggregation_enum.count_systemdir == 0, "Unexpected enum.count_systemdir %u\n", aggregation_enum.count_systemdir); if (with_32) ok(aggregation_enum.count_wowdir >= MODCOUNT, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); else - todo_wine ok(aggregation_enum.count_wowdir <= 1, "Unexpected enum.count_wowdir %u\n", aggregation_enum.count_wowdir); - todo_wine_if(!with_32) ok(aggregation_enum.count_ntdll == XTRANTDLL, "Unexpected enum.count_ntdll %u\n", aggregation_enum.count_ntdll);
ok(aggregation_sym.count_exe == 1, "Unexpected sym.count_exe %u\n", aggregation_sym.count_exe); if (with_32) ok(aggregation_sym.count_32bit >= MODCOUNT, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); else - todo_wine ok(aggregation_sym.count_wowdir <= 1, "Unexpected sym.count_32bit %u\n", aggregation_sym.count_32bit); - todo_wine ok(aggregation_sym.count_64bit == 0, "Unexpected sym.count_64bit %u\n", aggregation_sym.count_64bit); - todo_wine ok(aggregation_sym.count_systemdir == 0, "Unexpected sym.count_systemdir %u\n", aggregation_sym.count_systemdir); if (with_32) ok(aggregation_sym.count_wowdir >= MODCOUNT, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); else - todo_wine ok(aggregation_sym.count_wowdir <= 1, "Unexpected sym.count_wowdir %u\n", aggregation_sym.count_wowdir); - todo_wine_if(!with_32) ok(aggregation_sym.count_ntdll == XTRANTDLL, "Unexpected sym.count_ntdll %u\n", aggregation_sym.count_ntdll); } else if (!is_win64 && pcskind == PCSKIND_WINE_OLD_WOW64) /* 32/32 */ @@ -1313,18 +1282,14 @@ static void test_live_modules_proc(WCHAR* exename, BOOL with_32) ok(0, "Unexpected process kind %u\n", pcskind);
/* main module is enumerated twice in enum when including 32bit modules */ - todo_wine_if(is_win64 && (pcskind == PCSKIND_WOW64 || pcskind == PCSKIND_WINE_OLD_WOW64) && !with_32) ok(aggregation_sym.count_32bit + XTRAEXE == aggregation_enum.count_32bit, "Different sym/enum count32_bit (%u/%u)\n", aggregation_sym.count_32bit, aggregation_enum.count_32bit); - todo_wine_if(is_win64 && (pcskind == PCSKIND_WOW64 || pcskind == PCSKIND_WINE_OLD_WOW64)) ok(aggregation_sym.count_64bit == aggregation_enum.count_64bit, "Different sym/enum count64_bit (%u/%u)\n", aggregation_sym.count_64bit, aggregation_enum.count_64bit); ok(aggregation_sym.count_systemdir == aggregation_enum.count_systemdir, "Different sym/enum systemdir (%u/%u)\n", aggregation_sym.count_systemdir, aggregation_enum.count_systemdir); - todo_wine_if(with_32) ok(aggregation_sym.count_wowdir + XTRAEXE == aggregation_enum.count_wowdir, "Different sym/enum wowdir (%u/%u)\n", aggregation_sym.count_wowdir, aggregation_enum.count_wowdir); - todo_wine_if(with_32) ok(aggregation_sym.count_exe + XTRAEXE == aggregation_enum.count_exe, "Different sym/enum exe (%u/%u)\n", aggregation_sym.count_exe, aggregation_enum.count_exe); ok(aggregation_sym.count_ntdll == aggregation_enum.count_ntdll, "Different sym/enum exe (%u/%u)\n",
V2: with proper import of kernelbase
@julliard: something's to be changed for this one?