Jacek Caban : dbghelp: Try loading builtin modules from unix installation.

Alexandre Julliard julliard at winehq.org
Tue Mar 10 16:24:59 CDT 2020


Module: wine
Branch: master
Commit: e21b61392cbc3a4879f837316c869c44b8dcf685
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=e21b61392cbc3a4879f837316c869c44b8dcf685

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Tue Mar 10 14:54:31 2020 +0100

dbghelp: Try loading builtin modules from unix installation.

Signed-off-by: Jacek Caban <jacek at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dbghelp/dbghelp_private.h |  1 +
 dlls/dbghelp/image_private.h   |  1 +
 dlls/dbghelp/module.c          |  1 +
 dlls/dbghelp/pe_module.c       | 84 ++++++++++++++++++++++++++++++++++++++++++
 4 files changed, 87 insertions(+)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index b52392aece..eea966d6b3 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -358,6 +358,7 @@ struct module
     enum module_type		type : 16;
     unsigned short              is_virtual : 1;
     DWORD64                     reloc_delta;
+    WCHAR*                      real_path;
 
     /* specific information for debug types */
     struct module_format*       format_info[DFI_LAST];
diff --git a/dlls/dbghelp/image_private.h b/dlls/dbghelp/image_private.h
index a29794ef58..b6c7a0728f 100644
--- a/dlls/dbghelp/image_private.h
+++ b/dlls/dbghelp/image_private.h
@@ -110,6 +110,7 @@ struct image_file_map
         {
             HANDLE                      hMap;
             IMAGE_NT_HEADERS            ntheader;
+            BOOL                        builtin;
             unsigned                    full_count;
             void*                       full_map;
             struct
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index fe8ed35108..ef68a15700 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -705,6 +705,7 @@ BOOL module_remove(struct process* pcs, struct module* module)
     hash_table_destroy(&module->ht_types);
     HeapFree(GetProcessHeap(), 0, module->sources);
     HeapFree(GetProcessHeap(), 0, module->addr_sorttab);
+    HeapFree(GetProcessHeap(), 0, module->real_path);
     pool_destroy(&module->pool);
     /* native dbghelp doesn't invoke registered callback(,CBA_SYMBOLS_UNLOADED,) here
      * so do we
diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c
index 0f00b684ba..d0dca134d7 100644
--- a/dlls/dbghelp/pe_module.c
+++ b/dlls/dbghelp/pe_module.c
@@ -33,6 +33,7 @@
 #include "image_private.h"
 #include "winternl.h"
 #include "wine/debug.h"
+#include "wine/heap.h"
 
 WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
 
@@ -41,6 +42,8 @@ struct pe_module_info
     struct image_file_map       fmap;
 };
 
+static const char builtin_signature[] = "Wine builtin DLL";
+
 static void* pe_map_full(struct image_file_map* fmap, IMAGE_NT_HEADERS** nth)
 {
     if (!fmap->u.pe.full_map)
@@ -230,6 +233,8 @@ static BOOL pe_map_file(HANDLE file, struct image_file_map* fmap, enum module_ty
             case 0x20b: fmap->addr_size = 64; break;
             default: return FALSE;
             }
+
+            fmap->u.pe.builtin = !memcmp((const IMAGE_DOS_HEADER*)mapping + 1, builtin_signature, sizeof(builtin_signature));
             section = (IMAGE_SECTION_HEADER*)
                 ((char*)&nthdr->OptionalHeader + nthdr->FileHeader.SizeOfOptionalHeader);
             fmap->u.pe.sect = HeapAlloc(GetProcessHeap(), 0,
@@ -722,6 +727,70 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
     return ret;
 }
 
+static WCHAR *find_builtin_pe(const WCHAR *path, HANDLE *file)
+{
+    const WCHAR *base_name;
+    size_t len, i;
+    WCHAR *buf;
+
+    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};
+
+    if ((base_name = strrchrW(path, '\\'))) base_name++;
+    else base_name = path;
+
+    if ((len = GetEnvironmentVariableW(winebuilddirW, NULL, 0)))
+    {
+        WCHAR *p, *end;
+        const WCHAR dllsW[] = { '\\','d','l','l','s','\\' };
+        const WCHAR programsW[] = { '\\','p','r','o','g','r','a','m','s','\\' };
+        const WCHAR dot_dllW[] = {'.','d','l','l',0};
+        const WCHAR dot_exeW[] = {'.','e','x','e',0};
+
+        if (!(buf = heap_alloc((len + 8 + 2 * lstrlenW(base_name)) * sizeof(WCHAR)))) return NULL;
+        end = buf + GetEnvironmentVariableW(winebuilddirW, buf, len);
+
+        memcpy(end, dllsW, sizeof(dllsW));
+        strcpyW(end + ARRAY_SIZE(dllsW), base_name);
+        if ((p = strchrW(end, '.')) && !lstrcmpW(p, dot_dllW)) *p = 0;
+        p = end + strlenW(end);
+        *p++ = '\\';
+        strcpyW(p, base_name);
+        *file = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if (*file != INVALID_HANDLE_VALUE) return buf;
+
+        memcpy(end, programsW, sizeof(programsW));
+        end += ARRAY_SIZE(programsW);
+        strcpyW(end, base_name);
+        if ((p = strchrW(end, '.')) && !lstrcmpW(p, dot_exeW)) *p = 0;
+        p = end + strlenW(end);
+        *p++ = '\\';
+        strcpyW(p, base_name);
+        *file = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if (*file != INVALID_HANDLE_VALUE) return buf;
+
+        heap_free(buf);
+    }
+
+    for (i = 0;; i++)
+    {
+        WCHAR name[64];
+        sprintfW(name, winedlldirW, i);
+        if (!(len = GetEnvironmentVariableW(name, NULL, 0))) break;
+        if (!(buf = heap_alloc((len + lstrlenW(base_name) + 2) * sizeof(WCHAR)))) return NULL;
+
+        GetEnvironmentVariableW(name, buf, len);
+        buf[len++] = '\\';
+        strcpyW(buf + len, base_name);
+        *file = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if (*file != INVALID_HANDLE_VALUE) return buf;
+
+        heap_free(buf);
+    }
+
+    return NULL;
+}
+
 /******************************************************************
  *		pe_load_native_module
  *
@@ -751,6 +820,19 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
     modfmt->u.pe_info = (struct pe_module_info*)(modfmt + 1);
     if (pe_map_file(hFile, &modfmt->u.pe_info->fmap, DMT_PE))
     {
+        WCHAR *builtin_path = NULL;
+        HANDLE builtin_module;
+        if (modfmt->u.pe_info->fmap.u.pe.builtin && (builtin_path = find_builtin_pe(loaded_name, &builtin_module)))
+        {
+            struct image_file_map builtin_fmap;
+            if (pe_map_file(builtin_module, &builtin_fmap, DMT_PE))
+            {
+                TRACE("reloaded %s from %s\n", debugstr_w(loaded_name), debugstr_w(builtin_path));
+                pe_unmap_file(&modfmt->u.pe_info->fmap);
+                modfmt->u.pe_info->fmap = builtin_fmap;
+            }
+            CloseHandle(builtin_module);
+        }
         if (!base) base = modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.ImageBase;
         if (!size) size = modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.SizeOfImage;
 
@@ -759,6 +841,7 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
                             modfmt->u.pe_info->fmap.u.pe.ntheader.OptionalHeader.CheckSum);
         if (module)
         {
+            module->real_path = builtin_path;
             modfmt->module = module;
             modfmt->remove = pe_module_remove;
             modfmt->loc_compute = NULL;
@@ -773,6 +856,7 @@ struct module* pe_load_native_module(struct process* pcs, const WCHAR* name,
         else
         {
             ERR("could not load the module '%s'\n", debugstr_w(loaded_name));
+            heap_free(module->real_path);
             pe_unmap_file(&modfmt->u.pe_info->fmap);
         }
     }




More information about the wine-cvs mailing list