Eric Pouech : dbghelp: Implement SymEnumTypesByName(W).

Alexandre Julliard julliard at winehq.org
Fri Dec 10 15:07:52 CST 2021


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

Author: Eric Pouech <eric.pouech at gmail.com>
Date:   Wed Dec  8 14:45:02 2021 +0100

dbghelp: Implement SymEnumTypesByName(W).

Signed-off-by: Eric Pouech <eric.pouech at gmail.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 dlls/dbghelp/dbghelp.spec |   4 +-
 dlls/dbghelp/type.c       | 116 ++++++++++++++++++++++++++++++++++++++++++++++
 include/dbghelp.h         |   2 +
 3 files changed, 120 insertions(+), 2 deletions(-)

diff --git a/dlls/dbghelp/dbghelp.spec b/dlls/dbghelp/dbghelp.spec
index 471d9b6141c..87861cd87ce 100644
--- a/dlls/dbghelp/dbghelp.spec
+++ b/dlls/dbghelp/dbghelp.spec
@@ -57,8 +57,8 @@
 @ stub SymEnumSymbolsForAddrW
 @ stdcall SymEnumSymbolsW(ptr int64 wstr ptr ptr)
 @ stdcall SymEnumTypes(ptr int64 ptr ptr)
-@ stub SymEnumTypesByName
-@ stub SymEnumTypesByNameW
+@ stdcall SymEnumTypesByName(ptr int64 str ptr ptr)
+@ stdcall SymEnumTypesByNameW(ptr int64 wstr ptr ptr)
 @ stdcall SymEnumTypesW(ptr int64 ptr ptr)
 @ stdcall SymEnumerateModules(long ptr ptr)
 @ stdcall SymEnumerateModules64(long ptr ptr)
diff --git a/dlls/dbghelp/type.c b/dlls/dbghelp/type.c
index 3140d30e0bc..67f4265ddc9 100644
--- a/dlls/dbghelp/type.c
+++ b/dlls/dbghelp/type.c
@@ -544,6 +544,122 @@ BOOL WINAPI SymEnumTypesW(HANDLE hProcess, ULONG64 BaseOfDll,
     return SymEnumTypes(hProcess, BaseOfDll, enum_types_AtoW, &et);
 }
 
+static void enum_types_of_module(struct module_pair* pair, const char* name, PSYM_ENUMERATESYMBOLS_CALLBACK cb, PVOID user)
+{
+    char                buffer[sizeof(SYMBOL_INFO) + 256];
+    SYMBOL_INFO*        sym_info = (SYMBOL_INFO*)buffer;
+    struct symt*        type;
+    DWORD64             size;
+    unsigned            i;
+    const char*         tname;
+
+    sym_info->SizeOfStruct = sizeof(SYMBOL_INFO);
+    sym_info->MaxNameLen = sizeof(buffer) - sizeof(SYMBOL_INFO);
+
+    for (i = 0; i < vector_length(&pair->effective->vtypes); i++)
+    {
+        type = *(struct symt**)vector_at(&pair->effective->vtypes, i);
+        tname = symt_get_name(type);
+        if (tname && SymMatchStringA(tname, name, TRUE))
+        {
+            sym_info->TypeIndex = symt_ptr2index(pair->effective, type);
+            sym_info->Index = 0; /* FIXME */
+            symt_get_info(pair->effective, type, TI_GET_LENGTH, &size);
+            sym_info->Size = size;
+            sym_info->ModBase = pair->requested->module.BaseOfImage;
+            sym_info->Flags = 0; /* FIXME */
+            sym_info->Value = 0; /* FIXME */
+            sym_info->Address = 0; /* FIXME */
+            sym_info->Register = 0; /* FIXME */
+            sym_info->Scope = 0; /* FIXME */
+            sym_info->Tag = type->tag;
+            symbol_setname(sym_info, tname);
+            if (!cb(sym_info, sym_info->Size, user)) break;
+        }
+    }
+}
+
+static BOOL walk_modules(struct module_pair* pair)
+{
+    /* first walk PE only modules */
+    if (!pair->requested || pair->requested->type == DMT_PE)
+    {
+        while ((pair->requested = pair->requested ? pair->requested->next : pair->pcs->lmodules) != NULL)
+        {
+            if (pair->requested->type == DMT_PE && module_get_debug(pair)) return TRUE;
+        }
+    }
+    /* then walk ELF or Mach-O modules, not containing PE modules */
+    while ((pair->requested = pair->requested ? pair->requested->next : pair->pcs->lmodules) != NULL)
+    {
+        if ((pair->requested->type == DMT_ELF || pair->requested->type == DMT_MACHO) &&
+            !module_get_containee(pair->pcs, pair->requested) &&
+            module_get_debug(pair))
+            return TRUE;
+    }
+    return FALSE;
+}
+
+BOOL WINAPI SymEnumTypesByName(HANDLE proc, ULONG64 base, PCSTR name, PSYM_ENUMERATESYMBOLS_CALLBACK cb, PVOID user)
+{
+    struct module_pair  pair;
+    const char*         bang;
+
+    TRACE("(%p %I64x %s %p %p)\n", proc, base, wine_dbgstr_a(name), cb, user);
+
+    if (!name) return SymEnumTypes(proc, base, cb, user);
+    bang = strchr(name, '!');
+    if (bang)
+    {
+        DWORD sz;
+        WCHAR* modW;
+        pair.pcs = process_find_by_handle(proc);
+        if (bang == name) return FALSE;
+        if (!pair.pcs) return FALSE;
+        sz = MultiByteToWideChar(CP_ACP, 0, name, bang - name, NULL, 0) + 1;
+        if ((modW = malloc(sz * sizeof(WCHAR))) == NULL) return FALSE;
+        MultiByteToWideChar(CP_ACP, 0, name, bang - name, modW, sz);
+        modW[sz - 1] = L'\0';
+        pair.requested = NULL;
+        while (walk_modules(&pair))
+        {
+            if (SymMatchStringW(pair.requested->modulename, modW, FALSE))
+                enum_types_of_module(&pair, bang + 1, cb, user);
+        }
+        free(modW);
+    }
+    else
+    {
+        if (!module_init_pair(&pair, proc, base) || !module_get_debug(&pair)) return FALSE;
+        enum_types_of_module(&pair, name, cb, user);
+    }
+    return TRUE;
+}
+
+BOOL WINAPI SymEnumTypesByNameW(HANDLE proc, ULONG64 base, PCWSTR nameW, PSYM_ENUMERATESYMBOLS_CALLBACKW cb, PVOID user)
+{
+    struct enum_types_AtoW     et;
+    DWORD len = nameW ? WideCharToMultiByte(CP_ACP, 0, nameW, -1, NULL, 0, NULL, NULL) : 0;
+    char* name;
+    BOOL ret;
+
+    TRACE("(%p %I64x %s %p %p)\n", proc, base, wine_dbgstr_w(nameW), cb, user);
+
+    if (len)
+    {
+        if (!(name = malloc(len))) return FALSE;
+        WideCharToMultiByte(CP_ACP, 0, nameW, -1, name, len, NULL, NULL);
+    }
+    else name = NULL;
+
+    et.callback = cb;
+    et.user = user;
+
+    ret = SymEnumTypesByName(proc, base, name, enum_types_AtoW, &et);
+    free(name);
+    return ret;
+}
+
 /******************************************************************
  *		symt_get_info
  *
diff --git a/include/dbghelp.h b/include/dbghelp.h
index 248b3ab418d..07fa429809a 100644
--- a/include/dbghelp.h
+++ b/include/dbghelp.h
@@ -1081,6 +1081,8 @@ typedef BOOL (CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACK)(PSYMBOL_INFO, ULONG, PVO
 typedef BOOL (CALLBACK *PSYM_ENUMERATESYMBOLS_CALLBACKW)(PSYMBOL_INFOW, ULONG, PVOID);
 BOOL WINAPI SymEnumTypes(HANDLE, ULONG64, PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID);
 BOOL WINAPI SymEnumTypesW(HANDLE, ULONG64, PSYM_ENUMERATESYMBOLS_CALLBACKW, PVOID);
+BOOL WINAPI SymEnumTypesByName(HANDLE, ULONG64, PCSTR, PSYM_ENUMERATESYMBOLS_CALLBACK, PVOID);
+BOOL WINAPI SymEnumTypesByNameW(HANDLE, ULONG64, PCWSTR, PSYM_ENUMERATESYMBOLS_CALLBACKW, PVOID);
 BOOL WINAPI SymFromAddr(HANDLE, DWORD64, DWORD64*, SYMBOL_INFO*);
 BOOL WINAPI SymFromAddrW(HANDLE, DWORD64, DWORD64*, SYMBOL_INFOW*);
 BOOL WINAPI SymFromInlineContext(HANDLE, DWORD64, ULONG, PDWORD64, PSYMBOL_INFO);




More information about the wine-cvs mailing list