Jacek Caban : dbghelp: Make dll builtin PE path search helper more generic.

Alexandre Julliard julliard at winehq.org
Mon Mar 23 15:47:11 CDT 2020


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

Author: Jacek Caban <jacek at codeweavers.com>
Date:   Mon Mar 23 16:15:58 2020 +0100

dbghelp: Make dll builtin PE path search helper more generic.

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/path.c            | 86 +++++++++++++++++++++++++++++++++++++++
 dlls/dbghelp/pe_module.c       | 91 ++++++++++--------------------------------
 3 files changed, 107 insertions(+), 71 deletions(-)

diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 81ae1507e0..e846d21054 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -670,6 +670,7 @@ extern BOOL         path_find_symbol_file(const struct process* pcs, const struc
                                           PCSTR full_path, 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 const WCHAR* file_name(const WCHAR* str) DECLSPEC_HIDDEN;
 extern const char* file_nameA(const char* str) DECLSPEC_HIDDEN;
 
diff --git a/dlls/dbghelp/path.c b/dlls/dbghelp/path.c
index 1b04d97e13..99f6d00395 100644
--- a/dlls/dbghelp/path.c
+++ b/dlls/dbghelp/path.c
@@ -720,3 +720,89 @@ WCHAR *get_dos_file_name(const WCHAR *filename)
     }
     return dos_path;
 }
+
+BOOL search_dll_path(const WCHAR *name, BOOL (*match)(void*, HANDLE, const WCHAR*), void *param)
+{
+    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)))
+    {
+        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};
+        const WCHAR dot_soW[] = {'.','s','o',0};
+
+        if (!(buf = heap_alloc((len + 8 + 3 * lstrlenW(name)) * sizeof(WCHAR)))) return FALSE;
+        end = buf + GetEnvironmentVariableW(winebuilddirW, buf, len);
+
+        memcpy(end, dllsW, sizeof(dllsW));
+        strcpyW(end + ARRAY_SIZE(dllsW), name);
+        if ((p = strrchrW(end, '.')) && !lstrcmpW(p, dot_soW)) *p = 0;
+        if ((p = strrchrW(end, '.')) && !lstrcmpW(p, dot_dllW)) *p = 0;
+        p = end + strlenW(end);
+        *p++ = '\\';
+        strcpyW(p, name);
+        file = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if (file != INVALID_HANDLE_VALUE)
+        {
+            ret = match(param, file, buf);
+            CloseHandle(file);
+            if (ret) goto found;
+        }
+
+        memcpy(end, programsW, sizeof(programsW));
+        end += ARRAY_SIZE(programsW);
+        strcpyW(end, name);
+        if ((p = strrchrW(end, '.')) && !lstrcmpW(p, dot_soW)) *p = 0;
+        if ((p = strrchrW(end, '.')) && !lstrcmpW(p, dot_exeW)) *p = 0;
+        p = end + strlenW(end);
+        *p++ = '\\';
+        strcpyW(p, name);
+        file = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if (file != INVALID_HANDLE_VALUE)
+        {
+            ret = match(param, file, buf);
+            CloseHandle(file);
+            if (ret) goto found;
+        }
+
+        heap_free(buf);
+    }
+
+    for (i = 0;; i++)
+    {
+        WCHAR env_name[64];
+        sprintfW(env_name, winedlldirW, i);
+        if (!(len = GetEnvironmentVariableW(env_name, NULL, 0))) break;
+        if (!(buf = heap_alloc((len + lstrlenW(name) + 2) * sizeof(WCHAR)))) return FALSE;
+
+        len = GetEnvironmentVariableW(env_name, buf, len);
+        buf[len++] = '\\';
+        strcpyW(buf + len, name);
+        file = CreateFileW(buf, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+        if (file != INVALID_HANDLE_VALUE)
+        {
+            ret = match(param, file, buf);
+            CloseHandle(file);
+            if (ret) goto found;
+        }
+        heap_free(buf);
+    }
+
+    return FALSE;
+
+found:
+    TRACE("found %s\n", debugstr_w(buf));
+    heap_free(buf);
+    return TRUE;
+}
diff --git a/dlls/dbghelp/pe_module.c b/dlls/dbghelp/pe_module.c
index 8c120e00dc..a9410fea58 100644
--- a/dlls/dbghelp/pe_module.c
+++ b/dlls/dbghelp/pe_module.c
@@ -740,68 +740,23 @@ BOOL pe_load_debug_info(const struct process* pcs, struct module* module)
     return ret;
 }
 
-static WCHAR *find_builtin_pe(const WCHAR *path, HANDLE *file)
+struct builtin_search
 {
-    const WCHAR *base_name;
-    size_t len, i;
-    WCHAR *buf;
+    WCHAR *path;
+    struct image_file_map fmap;
+};
 
-    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};
+static BOOL search_builtin_pe(void *param, HANDLE handle, const WCHAR *path)
+{
+    struct builtin_search *search = param;
+    size_t size;
 
-    if ((base_name = strrchrW(path, '\\'))) base_name++;
-    else base_name = path;
+    if (!pe_map_file(handle, &search->fmap, DMT_PE)) return FALSE;
 
-    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;
+    size = (lstrlenW(path) + 1) * sizeof(WCHAR);
+    if ((search->path = heap_alloc(size)))
+        memcpy(search->path, path, size);
+    return TRUE;
 }
 
 /******************************************************************
@@ -833,18 +788,12 @@ 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 builtin_search builtin = { NULL };
+        if (modfmt->u.pe_info->fmap.u.pe.builtin && search_dll_path(loaded_name, search_builtin_pe, &builtin))
         {
-            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));
-                image_unmap_file(&modfmt->u.pe_info->fmap);
-                modfmt->u.pe_info->fmap = builtin_fmap;
-            }
-            CloseHandle(builtin_module);
+            TRACE("reloaded %s from %s\n", debugstr_w(loaded_name), debugstr_w(builtin.path));
+            image_unmap_file(&modfmt->u.pe_info->fmap);
+            modfmt->u.pe_info->fmap = builtin.fmap;
         }
         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;
@@ -854,7 +803,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;
+            module->real_path = builtin.path;
             modfmt->module = module;
             modfmt->remove = pe_module_remove;
             modfmt->loc_compute = NULL;
@@ -869,7 +818,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);
+            heap_free(builtin.path);
             image_unmap_file(&modfmt->u.pe_info->fmap);
         }
     }




More information about the wine-cvs mailing list