https://git.reactos.org/?p=reactos.git;a=commitdiff;h=be0572902a33f8740e8dd2ccfff9f94f87ce6e82

commit be0572902a33f8740e8dd2ccfff9f94f87ce6e82
Author:     winesync <[email protected]>
AuthorDate: Fri Sep 11 19:12:15 2020 +0200
Commit:     Jérôme Gardou <[email protected]>
CommitDate: Wed Sep 16 10:36:00 2020 +0200

    [WINESYNC] dbghelp: Use debuggee environment variables in search_dll_path.
    
    This fixes searching wow32 binaries, where debuggee search path is
    different than debugger's.
    
    Signed-off-by: Jacek Caban <[email protected]>
    Signed-off-by: Alexandre Julliard <[email protected]>
    
    wine commit id 2b0977fc711e1faadfef69e3a46c2d1848b4826b by Jacek Caban 
<[email protected]>
---
 dll/win32/dbghelp/dbghelp.c         | 83 +++++++++++++++++++++++++++++++++----
 dll/win32/dbghelp/dbghelp_private.h |  5 ++-
 dll/win32/dbghelp/elf_module.c      |  2 +-
 dll/win32/dbghelp/macho_module.c    |  2 +-
 dll/win32/dbghelp/path.c            | 18 ++++----
 dll/win32/dbghelp/pe_module.c       |  2 +-
 sdk/tools/winesync/dbghelp.cfg      |  2 +-
 7 files changed, 93 insertions(+), 21 deletions(-)

diff --git a/dll/win32/dbghelp/dbghelp.c b/dll/win32/dbghelp/dbghelp.c
index 83c3a0ec10f..5a4f55f5470 100644
--- a/dll/win32/dbghelp/dbghelp.c
+++ b/dll/win32/dbghelp/dbghelp.c
@@ -284,6 +284,23 @@ static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 
base, ULONG size, PVOI
     return TRUE;
 }
 
+const WCHAR *process_getenv(const struct process *process, const WCHAR *name)
+{
+    size_t name_len;
+    const WCHAR *iter;
+
+    if (!process->environment) return NULL;
+    name_len = lstrlenW(name);
+
+    for (iter = process->environment; *iter; iter += lstrlenW(iter) + 1)
+    {
+        if (!wcsnicmp(iter, name, name_len) && iter[name_len] == '=')
+            return iter + name_len + 1;
+    }
+
+    return NULL;
+}
+
 /******************************************************************
  *             check_live_target
  *
@@ -291,7 +308,7 @@ static BOOL WINAPI process_invade_cb(PCWSTR name, ULONG64 
base, ULONG size, PVOI
 static BOOL check_live_target(struct process* pcs)
 {
     PROCESS_BASIC_INFORMATION pbi;
-    ULONG_PTR base = 0;
+    ULONG_PTR base = 0, env = 0;
 
     if (!GetProcessId(pcs->handle)) return FALSE;
     if (GetEnvironmentVariableA("DBGHELP_NOLIVE", NULL, 0)) return FALSE;
@@ -302,18 +319,67 @@ static BOOL check_live_target(struct process* pcs)
 
     if (!pcs->is_64bit)
     {
-        PEB32 *peb32 = (PEB32 *)pbi.PebBaseAddress;
-        DWORD base32 = 0;
-        ReadProcessMemory(pcs->handle, &peb32->Reserved[0], &base32, 
sizeof(base32), NULL);
-        base = base32;
+        DWORD env32;
+        PEB32 peb32;
+        C_ASSERT(sizeof(void*) != 4 || 
FIELD_OFFSET(RTL_USER_PROCESS_PARAMETERS, Environment) == 0x48);
+        if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb32, 
sizeof(peb32), NULL)) return FALSE;
+        base = peb32.Reserved[0];
+        if (read_process_memory(pcs, peb32.ProcessParameters + 0x48, &env32, 
sizeof(env32))) env = env32;
     }
-    else ReadProcessMemory(pcs->handle, &pbi.PebBaseAddress->Reserved[0], 
&base, sizeof(base), NULL);
-#ifndef __REACTOS__
+    else
+    {
+        PEB peb;
+        if (!ReadProcessMemory(pcs->handle, pbi.PebBaseAddress, &peb, 
sizeof(peb), NULL)) return FALSE;
+        base = peb.Reserved[0];
+        ReadProcessMemory(pcs->handle, &peb.ProcessParameters->Environment, 
&env, sizeof(env), NULL);
+    }
+
+#ifdef __REACTOS__
     /* Wine store their loader base address in peb.reserved[0] and load its 
symbol from there.
-     * ReactOS does not care about it */
+     * ReactOS does not care about it, we are just happy if we managed to read 
the value */
+    base = 1;
+#endif
+
+    /* read debuggee environment block */
+    if (env)
+    {
+        size_t buf_size = 0, i, last_null = -1;
+        WCHAR *buf = NULL;
+
+        do
+        {
+            size_t read_size = sysinfo.dwAllocationGranularity - (env & 
(sysinfo.dwAllocationGranularity - 1));
+            if (buf)
+            {
+                WCHAR *new_buf;
+                if (!(new_buf = realloc(buf, buf_size + read_size))) break;
+                buf = new_buf;
+            }
+            else if(!(buf = malloc(read_size))) break;
+
+            if (!read_process_memory(pcs, env, (char*)buf + buf_size, 
read_size)) break;
+            for (i = buf_size / sizeof(WCHAR); i < (buf_size + read_size) / 
sizeof(WCHAR); i++)
+            {
+                if (buf[i]) continue;
+                if (last_null + 1 == i)
+                {
+                    pcs->environment = realloc(buf, (i + 1) * sizeof(WCHAR));
+                    buf = NULL;
+                    break;
+                }
+                last_null = i;
+            }
+            env += read_size;
+            buf_size += read_size;
+        }
+        while (buf);
+        free(buf);
+    }
+
     if (!base) return FALSE;
 
     TRACE("got debug info address %#lx from PEB %p\n", base, 
pbi.PebBaseAddress);
+#ifndef __REACTOS__
     return elf_read_wine_loader_dbg_info(pcs, base) || 
macho_read_wine_loader_dbg_info(pcs, base);
 #else
     return TRUE;
@@ -476,6 +542,7 @@ BOOL WINAPI SymCleanup(HANDLE hProcess)
             while ((*ppcs)->lmodules) module_remove(*ppcs, (*ppcs)->lmodules);
 
             HeapFree(GetProcessHeap(), 0, (*ppcs)->search_path);
+            free((*ppcs)->environment);
             next = (*ppcs)->next;
             HeapFree(GetProcessHeap(), 0, *ppcs);
             *ppcs = next;
diff --git a/dll/win32/dbghelp/dbghelp_private.h 
b/dll/win32/dbghelp/dbghelp_private.h
index 6faf8b8eb55..434e157c28f 100644
--- a/dll/win32/dbghelp/dbghelp_private.h
+++ b/dll/win32/dbghelp/dbghelp_private.h
@@ -430,6 +430,7 @@ struct process
     HANDLE                      handle;
     const struct loader_ops*    loader;
     WCHAR*                      search_path;
+    WCHAR*                      environment;
 
     PSYMBOL_REGISTERED_CALLBACK64       reg_cb;
     PSYMBOL_REGISTERED_CALLBACK reg_cb32;
@@ -632,6 +633,7 @@ extern BOOL         pcs_callback(const struct process* pcs, 
ULONG action, void*
 extern void*        fetch_buffer(struct process* pcs, unsigned size) 
DECLSPEC_HIDDEN;
 extern const char*  wine_dbgstr_addr(const ADDRESS64* addr) DECLSPEC_HIDDEN;
 extern struct cpu*  cpu_find(DWORD) DECLSPEC_HIDDEN;
+extern const WCHAR *process_getenv(const struct process *process, const WCHAR 
*name);
 extern DWORD calc_crc32(HANDLE handle) DECLSPEC_HIDDEN;
 
 #ifndef __REACTOS__
@@ -703,7 +705,8 @@ extern BOOL         path_find_symbol_file(const struct 
process* pcs, const struc
                                           PCSTR full_path, enum module_type 
type, const GUID* guid, DWORD dw1, DWORD dw2,
                                           WCHAR *buffer, BOOL* is_unmatched) 
DECLSPEC_HIDDEN;
 extern WCHAR *get_dos_file_name(const WCHAR *filename) DECLSPEC_HIDDEN;
-extern BOOL search_dll_path(const WCHAR *name, BOOL (*match)(void*, HANDLE, 
const WCHAR*), void *param) DECLSPEC_HIDDEN;
+extern BOOL search_dll_path(const struct process* process, const WCHAR *name,
+                            BOOL (*match)(void*, HANDLE, const WCHAR*), void 
*param) DECLSPEC_HIDDEN;
 extern BOOL search_unix_path(const WCHAR *name, const char *path, BOOL 
(*match)(void*, HANDLE, const WCHAR*), void *param) DECLSPEC_HIDDEN;
 extern const WCHAR* file_name(const WCHAR* str) DECLSPEC_HIDDEN;
 extern const char* file_nameA(const char* str) DECLSPEC_HIDDEN;
diff --git a/dll/win32/dbghelp/elf_module.c b/dll/win32/dbghelp/elf_module.c
index 5f92432d0e8..ab2a693ecaf 100644
--- a/dll/win32/dbghelp/elf_module.c
+++ b/dll/win32/dbghelp/elf_module.c
@@ -1436,7 +1436,7 @@ static BOOL elf_search_and_load_file(struct process* pcs, 
const WCHAR* filename,
         load_elf.elf_info    = elf_info;
 
         ret = search_unix_path(filename, getenv("LD_LIBRARY_PATH"), 
elf_load_file_cb, &load_elf)
-            || search_dll_path(filename, elf_load_file_cb, &load_elf);
+            || search_dll_path(pcs, filename, elf_load_file_cb, &load_elf);
     }
 
     return ret;
diff --git a/dll/win32/dbghelp/macho_module.c b/dll/win32/dbghelp/macho_module.c
index 51119593770..05549571c5e 100644
--- a/dll/win32/dbghelp/macho_module.c
+++ b/dll/win32/dbghelp/macho_module.c
@@ -1588,7 +1588,7 @@ static BOOL macho_search_and_load_file(struct process* 
pcs, const WCHAR* filenam
         ret = search_unix_path(p, fallback, macho_load_file_cb, &load_params);
     }
     if (!ret && p == filename)
-        ret = search_dll_path(filename, macho_load_file_cb, &load_params);
+        ret = search_dll_path(pcs, filename, macho_load_file_cb, &load_params);
 
     return ret;
 }
diff --git a/dll/win32/dbghelp/path.c b/dll/win32/dbghelp/path.c
index d4e04ff1f40..87eeb93ae6d 100644
--- a/dll/win32/dbghelp/path.c
+++ b/dll/win32/dbghelp/path.c
@@ -692,19 +692,17 @@ WCHAR *get_dos_file_name(const WCHAR *filename)
 }
 
 #ifndef __REACTOS__
-BOOL search_dll_path(const WCHAR *name, BOOL (*match)(void*, HANDLE, const 
WCHAR*), void *param)
+BOOL search_dll_path(const struct process *process, const WCHAR *name, BOOL 
(*match)(void*, HANDLE, const WCHAR*), void *param)
 {
+    const WCHAR *env;
     size_t len, i;
     HANDLE file;
     WCHAR *buf;
     BOOL ret;
 
-    static const WCHAR winebuilddirW[] = 
{'W','I','N','E','B','U','I','L','D','D','I','R',0};
-    static const WCHAR winedlldirW[] = 
{'W','I','N','E','D','L','L','D','I','R','%','u',0};
-
     name = file_name(name);
 
-    if ((len = GetEnvironmentVariableW(winebuilddirW, NULL, 0)))
+    if ((env = process_getenv(process, L"WINEBUILDDIR")))
     {
         WCHAR *p, *end;
         const WCHAR dllsW[] = { '\\','d','l','l','s','\\' };
@@ -713,8 +711,11 @@ BOOL search_dll_path(const WCHAR *name, BOOL 
(*match)(void*, HANDLE, const WCHAR
         const WCHAR dot_exeW[] = {'.','e','x','e',0};
         const WCHAR dot_soW[] = {'.','s','o',0};
 
+
+        len = lstrlenW(env);
         if (!(buf = heap_alloc((len + 8 + 3 * lstrlenW(name)) * 
sizeof(WCHAR)))) return FALSE;
-        end = buf + GetEnvironmentVariableW(winebuilddirW, buf, len);
+        wcscpy(buf, env);
+        end = buf + len;
 
         memcpy(end, dllsW, sizeof(dllsW));
         lstrcpyW(end + ARRAY_SIZE(dllsW), name);
@@ -753,8 +754,9 @@ BOOL search_dll_path(const WCHAR *name, BOOL 
(*match)(void*, HANDLE, const WCHAR
     for (i = 0;; i++)
     {
         WCHAR env_name[64];
-        swprintf(env_name, ARRAY_SIZE(env_name), winedlldirW, i);
-        if (!(len = GetEnvironmentVariableW(env_name, NULL, 0))) break;
+        swprintf(env_name, ARRAY_SIZE(env_name), L"WINEDLLDIR%u", i);
+        if (!(env = process_getenv(process, env_name))) return FALSE;
+        len = lstrlenW(env);
         if (!(buf = heap_alloc((len + lstrlenW(name) + 2) * sizeof(WCHAR)))) 
return FALSE;
 
         len = GetEnvironmentVariableW(env_name, buf, len);
diff --git a/dll/win32/dbghelp/pe_module.c b/dll/win32/dbghelp/pe_module.c
index 9ea60ecade4..193876263ac 100644
--- a/dll/win32/dbghelp/pe_module.c
+++ b/dll/win32/dbghelp/pe_module.c
@@ -823,7 +823,7 @@ struct module* pe_load_native_module(struct process* pcs, 
const WCHAR* name,
     {
 #ifndef __REACTOS__
         struct builtin_search builtin = { NULL };
-        if (modfmt->u.pe_info->fmap.u.pe.builtin && 
search_dll_path(loaded_name, search_builtin_pe, &builtin))
+        if (modfmt->u.pe_info->fmap.u.pe.builtin && search_dll_path(pcs, 
loaded_name, search_builtin_pe, &builtin))
         {
             TRACE("reloaded %s from %s\n", debugstr_w(loaded_name), 
debugstr_w(builtin.path));
             image_unmap_file(&modfmt->u.pe_info->fmap);
diff --git a/sdk/tools/winesync/dbghelp.cfg b/sdk/tools/winesync/dbghelp.cfg
index d728bdefbc4..e8df9235796 100644
--- a/sdk/tools/winesync/dbghelp.cfg
+++ b/sdk/tools/winesync/dbghelp.cfg
@@ -4,4 +4,4 @@ files:
   include/dbghelp.h: sdk/include/psdk/dbghelp.h
   include/wine/mscvpdb.h: sdk/include/reactos/wine/mscvpdb.h
 tags:
-  wine: 341feeb10eddd3d139c4c206a43db80d0671ff3b
+  wine: 2b0977fc711e1faadfef69e3a46c2d1848b4826b

Reply via email to