Eric Pouech : dbghelp: Started implementation of the global callback mechanism.

Alexandre Julliard julliard at wine.codeweavers.com
Mon Jan 23 10:35:10 CST 2006


Module: wine
Branch: refs/heads/master
Commit: 418591c8ea512b68bcb6d4fdcdea41216e5560c0
URL:    http://source.winehq.org/git/?p=wine.git;a=commit;h=418591c8ea512b68bcb6d4fdcdea41216e5560c0

Author: Eric Pouech <eric.pouech at wanadoo.fr>
Date:   Mon Jan 23 16:29:21 2006 +0100

dbghelp: Started implementation of the global callback mechanism.

---

 dlls/dbghelp/dbghelp.c         |   79 ++++++++++++++++++++++++++++++++++++----
 dlls/dbghelp/dbghelp_private.h |    8 +++-
 dlls/dbghelp/module.c          |   29 +++++++++++++--
 include/dbghelp.h              |   12 ++++++
 4 files changed, 115 insertions(+), 13 deletions(-)

diff --git a/dlls/dbghelp/dbghelp.c b/dlls/dbghelp/dbghelp.c
index 94bb0e1..e0b9048 100644
--- a/dlls/dbghelp/dbghelp.c
+++ b/dlls/dbghelp/dbghelp.c
@@ -61,7 +61,6 @@ WINE_DEFAULT_DEBUG_CHANNEL(dbghelp);
  *        getting several of those while looking for a unique symbol. Part of the 
  *        issue is that we don't give a scope to a static variable inside a function
  *      + C++ management
- *  - implement the callback notification mechanism
  */
 
 unsigned   dbghelp_options = SYMOPT_UNDNAME;
@@ -284,6 +283,12 @@ BOOL WINAPI SymCleanup(HANDLE hProcess)
  */
 DWORD WINAPI SymSetOptions(DWORD opts)
 {
+    struct process* pcs;
+
+    for (pcs = process_first; pcs; pcs = pcs->next)
+    {
+        pcs_callback(pcs, CBA_SET_OPTIONS, &opts);
+    }
     return dbghelp_options = opts;
 }
 
@@ -322,6 +327,62 @@ BOOL WINAPI SymSetContext(HANDLE hProces
     return TRUE;
 }
 
+/******************************************************************
+ *		reg_cb64to32 (internal)
+ *
+ * Registered callback for converting information from 64 bit to 32 bit
+ */
+static BOOL CALLBACK reg_cb64to32(HANDLE hProcess, ULONG action, ULONG64 data, ULONG64 user)
+{
+    PSYMBOL_REGISTERED_CALLBACK         cb32 = (PSYMBOL_REGISTERED_CALLBACK)(DWORD)(user >> 32);
+    DWORD                               user32 = (DWORD)user;
+    void*                               data32;
+    IMAGEHLP_DEFERRED_SYMBOL_LOAD64*    idsl64;
+    IMAGEHLP_DEFERRED_SYMBOL_LOAD       idsl;
+
+    switch (action)
+    {
+    case CBA_DEBUG_INFO:
+    case CBA_DEFERRED_SYMBOL_LOAD_CANCEL:
+    case CBA_SET_OPTIONS:
+    case CBA_SYMBOLS_UNLOADED:
+        data32 = (void*)(DWORD)data;
+        break;
+    case CBA_DEFERRED_SYMBOL_LOAD_COMPLETE:
+    case CBA_DEFERRED_SYMBOL_LOAD_FAILURE:
+    case CBA_DEFERRED_SYMBOL_LOAD_PARTIAL:
+    case CBA_DEFERRED_SYMBOL_LOAD_START:
+        idsl64 = (IMAGEHLP_DEFERRED_SYMBOL_LOAD64*)(DWORD)data;
+        if (!validate_addr64(idsl64->BaseOfImage))
+            return FALSE;
+        idsl.SizeOfStruct = sizeof(idsl);
+        idsl.BaseOfImage = (DWORD)idsl64->BaseOfImage;
+        idsl.CheckSum = idsl64->CheckSum;
+        idsl.TimeDateStamp = idsl64->TimeDateStamp;
+        memcpy(idsl.FileName, idsl64->FileName, sizeof(idsl.FileName));
+        idsl.Reparse = idsl64->Reparse;
+        data32 = &idsl;
+        break;
+    case CBA_DUPLICATE_SYMBOL:
+    case CBA_EVENT:
+    case CBA_READ_MEMORY:
+    default:
+        FIXME("No mapping for action %lu\n", action);
+        return FALSE;
+    }
+    return cb32(hProcess, action, (PVOID)data32, (PVOID)user32);
+}
+
+/******************************************************************
+ *		pcs_callback (internal)
+ */
+BOOL pcs_callback(const struct process* pcs, ULONG action, void* data)
+{
+    TRACE("%p %lu %p\n", pcs, action, data);
+    if (!pcs->reg_cb) return FALSE;
+    return pcs->reg_cb(pcs->handle, action, (ULONG64)(DWORD_PTR)data, pcs->reg_user);
+}
+
 /***********************************************************************
  *		SymRegisterCallback (DBGHELP.@)
  */
@@ -329,9 +390,8 @@ BOOL WINAPI SymRegisterCallback(HANDLE h
                                 PSYMBOL_REGISTERED_CALLBACK CallbackFunction,
                                 PVOID UserContext)
 {
-    FIXME("(%p, %p, %p): stub\n", hProcess, CallbackFunction, UserContext);
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    DWORD64 tmp = ((ULONGLONG)(DWORD)CallbackFunction << 32) | (DWORD)UserContext;
+    return SymRegisterCallback64(hProcess, reg_cb64to32, tmp);
 }
 
 /***********************************************************************
@@ -341,10 +401,15 @@ BOOL WINAPI SymRegisterCallback64(HANDLE
                                   PSYMBOL_REGISTERED_CALLBACK64 CallbackFunction,
                                   ULONG64 UserContext)
 {
-    FIXME("(%p, %p, %s): stub\n", 
+    struct process* pcs = process_find_by_handle(hProcess);
+
+    TRACE("(%p, %p, %s)\n", 
           hProcess, CallbackFunction, wine_dbgstr_longlong(UserContext));
-    SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
-    return FALSE;
+    if (!pcs) return FALSE;
+    pcs->reg_cb = CallbackFunction;
+    pcs->reg_user = UserContext;
+
+    return TRUE;
 }
 
 /* This is imagehlp version not dbghelp !! */
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 8d8cb70..c3e3676 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -291,6 +291,9 @@ struct process 
     struct process*             next;
     HANDLE                      handle;
     char*                       search_path;
+    
+    PSYMBOL_REGISTERED_CALLBACK64       reg_cb;
+    DWORD64                     reg_user;
 
     struct module*              lmodules;
     unsigned long               dbg_hdr_addr;
@@ -314,8 +317,9 @@ struct line_info
 /* dbghelp.c */
 extern struct process* process_find_by_handle(HANDLE hProcess);
 extern HANDLE hMsvcrt;
-extern BOOL validate_addr64(DWORD64 addr);
-	
+extern BOOL         validate_addr64(DWORD64 addr);
+extern BOOL         pcs_callback(const struct process* pcs, ULONG action, void* data);
+
 /* elf_module.c */
 typedef BOOL (*elf_enum_modules_cb)(const char*, unsigned long addr, void* user);
 extern BOOL         elf_enum_modules(HANDLE hProc, elf_enum_modules_cb, void*);
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 3c0c5d4..afd33fd 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -232,7 +232,8 @@ struct module* module_get_containee(cons
  */
 struct module* module_get_debug(const struct process* pcs, struct module* module)
 {
-    struct module*      parent;
+    struct module*                      parent;
+    IMAGEHLP_DEFERRED_SYMBOL_LOAD64     idsl64;
 
     if (!module) return NULL;
     /* for a PE builtin, always get info from parent */
@@ -245,10 +246,28 @@ struct module* module_get_debug(const st
 
         switch (module->type)
         {
-        case DMT_ELF: ret = elf_load_debug_info(module, NULL);  break;
-        case DMT_PE:  ret = pe_load_debug_info(pcs, module);    break;
+        case DMT_ELF:
+            ret = elf_load_debug_info(module, NULL);
+            break;
+        case DMT_PE:
+            idsl64.SizeOfStruct = sizeof(idsl64);
+            idsl64.BaseOfImage = module->module.BaseOfImage;
+            idsl64.CheckSum = module->module.CheckSum;
+            idsl64.TimeDateStamp = module->module.TimeDateStamp;
+            strcpy(idsl64.FileName, module->module.ImageName);
+            idsl64.Reparse = FALSE;
+            idsl64.hFile = INVALID_HANDLE_VALUE;
+
+            pcs_callback(pcs, CBA_DEFERRED_SYMBOL_LOAD_START, &idsl64);
+            ret = pe_load_debug_info(pcs, module);
+            pcs_callback(pcs,
+                         ret ? CBA_DEFERRED_SYMBOL_LOAD_COMPLETE : CBA_DEFERRED_SYMBOL_LOAD_FAILURE,
+                         &idsl64);
+            break;
         case DMT_VIRTUAL: /* fall through */
-        default:      ret = FALSE;                              break;
+        default:
+            ret = FALSE;
+            break;
         }
         if (!ret) module->module.SymType = SymNone;
         assert(module->module.SymType != SymDeferred);
@@ -451,6 +470,8 @@ BOOL module_remove(struct process* pcs, 
     HeapFree(GetProcessHeap(), 0, (char*)module->sources);
     HeapFree(GetProcessHeap(), 0, module->addr_sorttab);
     pool_destroy(&module->pool);
+    if (module->module.SymType != SymNone)
+        pcs_callback(pcs, CBA_SYMBOLS_UNLOADED, NULL);
 
     for (p = &pcs->lmodules; *p; p = &(*p)->next)
     {
diff --git a/include/dbghelp.h b/include/dbghelp.h
index 9ef700c..e53b324 100644
--- a/include/dbghelp.h
+++ b/include/dbghelp.h
@@ -221,6 +221,7 @@ typedef struct _SOURCEFILE
 #define CBA_DEFERRED_SYMBOL_LOAD_CANCEL         0x00000007
 #define CBA_SET_OPTIONS                         0x00000008
 #define CBA_EVENT                               0x00000010
+#define CBA_DEFERRED_SYMBOL_LOAD_PARTIAL        0x00000020
 #define CBA_DEBUG_INFO                          0x10000000
 
 typedef struct _IMAGEHLP_CBA_READ_MEMORY
@@ -258,6 +259,17 @@ typedef struct _IMAGEHLP_DEFERRED_SYMBOL
     BOOLEAN                     Reparse;
 } IMAGEHLP_DEFERRED_SYMBOL_LOAD, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD;
 
+typedef struct _IMAGEHLP_DEFERRED_SYMBOL_LOAD64
+{
+    DWORD                       SizeOfStruct;
+    DWORD64                     BaseOfImage;
+    DWORD                       CheckSum;
+    DWORD                       TimeDateStamp;
+    CHAR                        FileName[MAX_PATH];
+    BOOLEAN                     Reparse;
+    HANDLE                      hFile;
+} IMAGEHLP_DEFERRED_SYMBOL_LOAD64, *PIMAGEHLP_DEFERRED_SYMBOL_LOAD64;
+
 typedef struct _IMAGEHLP_DUPLICATE_SYMBOL
 {
     DWORD                       SizeOfStruct;




More information about the wine-cvs mailing list