Module: wine Branch: master Commit: 7b0d974439ed69f2323cd64685bc96d370ec6531 URL: https://gitlab.winehq.org/wine/wine/-/commit/7b0d974439ed69f2323cd64685bc96d...
Author: Eric Pouech epouech@codeweavers.com Date: Sat Dec 16 15:25:51 2023 +0100
dbghelp: Fix some tests for SymLoadModule*().
On top of being closer to native behavior, this helps some games where: - they use dbghelp to gather information of where they generate exceptions, - they generate exception in the game play, - and refresh their list of loaded modules in dbghelp.
This can generate some delays (~2ms per module), which affects game play (freeze, slugginess...).
Credit to Paul Gofman for triaging this.
Signed-off-by: Eric Pouech epouech@codeweavers.com
---
dlls/dbghelp/module.c | 18 ++++++++++++++++-- dlls/dbghelp/tests/dbghelp.c | 1 - 2 files changed, 16 insertions(+), 3 deletions(-)
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c index b12007d270e..f21733c7be9 100644 --- a/dlls/dbghelp/module.c +++ b/dlls/dbghelp/module.c @@ -943,6 +943,19 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08lx for %s\n", Flags, debugstr_w(wImageName));
+ /* Trying to load a new module at the same address of an existing one, + * native simply keeps the old one in place. + */ + if (BaseOfDll) + for (altmodule = pcs->lmodules; altmodule; altmodule = altmodule->next) + { + if (altmodule->type == DMT_PE && BaseOfDll == altmodule->module.BaseOfImage) + { + SetLastError(ERROR_SUCCESS); + return 0; + } + } + pcs->loader->synchronize_module_list(pcs);
/* this is a Wine extension to the API just to redo the synchronisation */ @@ -974,6 +987,7 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam if (!module) { WARN("Couldn't locate %s\n", debugstr_w(wImageName)); + SetLastError(ERROR_NO_MORE_FILES); return 0; } /* by default module_new fills module.ModuleName from a derivation @@ -997,11 +1011,11 @@ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageNam * (it's hidden by altmodule). * We need to decide which one the two modules we need to get rid of. */ - /* loading same module at same address... don't change anything */ + /* loading same module at same address... we can only get here when BaseOfDll is 0 */ if (module->module.BaseOfImage == altmodule->module.BaseOfImage) { module_remove(pcs, module); - SetLastError(ERROR_SUCCESS); + SetLastError(ERROR_INVALID_ADDRESS); return 0; } /* replace old module with new one */ diff --git a/dlls/dbghelp/tests/dbghelp.c b/dlls/dbghelp/tests/dbghelp.c index 0259aaac81a..13cd173e761 100644 --- a/dlls/dbghelp/tests/dbghelp.c +++ b/dlls/dbghelp/tests/dbghelp.c @@ -605,7 +605,6 @@ static void test_modules_overlap(void) if (tests[i].error_code != ~0) { ok(base[1] == 0, "SymLoadModuleEx should have failed\n"); - todo_wine_if((i >= 8 && i < 12) || (i >= 20 && i < 32)) ok(GetLastError() == tests[i].error_code || /* Win8 returns this */ (tests[i].error_code == ERROR_NO_MORE_FILES && broken(GetLastError() == ERROR_INVALID_HANDLE)),