Module: wine
Branch: master
Commit: 7b0d974439ed69f2323cd64685bc96d370ec6531
URL: https://gitlab.winehq.org/wine/wine/-/commit/7b0d974439ed69f2323cd64685bc96…
Author: Eric Pouech <epouech(a)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(a)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)),