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