Andrew Nguyen : dbghelp: Implement SymEnumSourceFilesW.

Alexandre Julliard julliard at winehq.org
Wed Jun 1 12:11:09 CDT 2011


Module: wine
Branch: master
Commit: 6ee16099a3b541c656b2146821fc6787aca6112b
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=6ee16099a3b541c656b2146821fc6787aca6112b

Author: Andrew Nguyen <anguyen at codeweavers.com>
Date:   Tue May 31 06:12:44 2011 -0500

dbghelp: Implement SymEnumSourceFilesW.

---

 dlls/dbghelp/dbghelp.spec      |    2 +-
 dlls/dbghelp/dbghelp_private.h |    3 +
 dlls/dbghelp/module.c          |    6 +-
 dlls/dbghelp/source.c          |  122 +++++++++++++++++++++++++++++++++++++---
 4 files changed, 121 insertions(+), 12 deletions(-)

diff --git a/dlls/dbghelp/dbghelp.spec b/dlls/dbghelp/dbghelp.spec
index c50ab22..ddb9d33 100644
--- a/dlls/dbghelp/dbghelp.spec
+++ b/dlls/dbghelp/dbghelp.spec
@@ -45,7 +45,7 @@
 @ stub SymEnumProcesses
 @ stub SymEnumSourceFileTokens
 @ stdcall SymEnumSourceFiles(ptr int64 str ptr ptr)
-@ stub SymEnumSourceFilesW
+@ stdcall SymEnumSourceFilesW(ptr int64 wstr ptr ptr)
 @ stub SymEnumSourceLines
 @ stub SymEnumSourceLinesW
 @ stub SymEnumSym
diff --git a/dlls/dbghelp/dbghelp_private.h b/dlls/dbghelp/dbghelp_private.h
index 4a64253..43aca49 100644
--- a/dlls/dbghelp/dbghelp_private.h
+++ b/dlls/dbghelp/dbghelp_private.h
@@ -538,6 +538,9 @@ extern struct module*
                     module_find_by_addr(const struct process* pcs, unsigned long addr,
                                         enum module_type type) DECLSPEC_HIDDEN;
 extern struct module*
+                    module_find_by_nameW(const struct process* pcs,
+                                         const WCHAR* name) DECLSPEC_HIDDEN;
+extern struct module*
                     module_find_by_nameA(const struct process* pcs,
                                          const char* name) DECLSPEC_HIDDEN;
 extern struct module*
diff --git a/dlls/dbghelp/module.c b/dlls/dbghelp/module.c
index 7f75cc2..2a1471f 100644
--- a/dlls/dbghelp/module.c
+++ b/dlls/dbghelp/module.c
@@ -234,10 +234,10 @@ struct module* module_new(struct process* pcs, const WCHAR* name,
 }
 
 /***********************************************************************
- *	module_find_by_name
+ *	module_find_by_nameW
  *
  */
-static struct module* module_find_by_name(const struct process* pcs, const WCHAR* name)
+struct module* module_find_by_nameW(const struct process* pcs, const WCHAR* name)
 {
     struct module*      module;
 
@@ -254,7 +254,7 @@ struct module* module_find_by_nameA(const struct process* pcs, const char* name)
     WCHAR wname[MAX_PATH];
 
     MultiByteToWideChar(CP_ACP, 0, name, -1, wname, sizeof(wname) / sizeof(WCHAR));
-    return module_find_by_name(pcs, wname);
+    return module_find_by_nameW(pcs, wname);
 }
 
 /***********************************************************************
diff --git a/dlls/dbghelp/source.c b/dlls/dbghelp/source.c
index 5f12b9f..3bed023 100644
--- a/dlls/dbghelp/source.c
+++ b/dlls/dbghelp/source.c
@@ -157,17 +157,19 @@ const char* source_get(const struct module* module, unsigned idx)
 }
 
 /******************************************************************
- *		SymEnumSourceFiles (DBGHELP.@)
+ *		SymEnumSourceFilesW (DBGHELP.@)
  *
  */
-BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
-                               PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles,
-                               PVOID UserContext)
+BOOL WINAPI SymEnumSourceFilesW(HANDLE hProcess, ULONG64 ModBase, PCWSTR Mask,
+                                PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles,
+                                PVOID UserContext)
 {
     struct module_pair  pair;
-    SOURCEFILE          sf;
+    SOURCEFILEW         sf;
     char*               ptr;
-    
+    WCHAR*              conversion_buffer = NULL;
+    DWORD               conversion_buffer_len = 0;
+
     if (!cbSrcFiles) return FALSE;
     pair.pcs = process_find_by_handle(hProcess);
     if (!pair.pcs) return FALSE;
@@ -181,7 +183,7 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
     {
         if (Mask[0] == '!')
         {
-            pair.requested = module_find_by_nameA(pair.pcs, Mask + 1);
+            pair.requested = module_find_by_nameW(pair.pcs, Mask + 1);
             if (!module_get_debug(&pair)) return FALSE;
         }
         else
@@ -193,15 +195,119 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
     if (!pair.effective->sources) return FALSE;
     for (ptr = pair.effective->sources; *ptr; ptr += strlen(ptr) + 1)
     {
+        DWORD len = MultiByteToWideChar(CP_ACP, 0, ptr, -1, NULL, 0);
+
+        if (len > conversion_buffer_len)
+        {
+            HeapFree(GetProcessHeap(), 0, conversion_buffer);
+            conversion_buffer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+            if (!conversion_buffer) return FALSE;
+            conversion_buffer_len = len;
+        }
+
+        MultiByteToWideChar(CP_ACP, 0, ptr, -1, conversion_buffer, len);
+
         /* FIXME: not using Mask */
         sf.ModBase = ModBase;
-        sf.FileName = ptr;
+        sf.FileName = conversion_buffer;
         if (!cbSrcFiles(&sf, UserContext)) break;
     }
 
+    HeapFree(GetProcessHeap(), 0, conversion_buffer);
     return TRUE;
 }
 
+struct enum_sources_files_context
+{
+    PSYM_ENUMSOURCEFILES_CALLBACK callbackA;
+    PVOID caller_context;
+    char *conversion_buffer;
+    DWORD conversion_buffer_len;
+    DWORD callback_error;
+};
+
+static BOOL CALLBACK enum_source_files_W_to_A(PSOURCEFILEW source_file, PVOID context)
+{
+    struct enum_sources_files_context *ctx = context;
+    SOURCEFILE source_fileA;
+    DWORD len;
+
+    len = WideCharToMultiByte(CP_ACP, 0, source_file->FileName, -1, NULL, 0, NULL, NULL);
+    if (len > ctx->conversion_buffer_len)
+    {
+        char *ptr = ctx->conversion_buffer ? HeapReAlloc(GetProcessHeap(), 0, ctx->conversion_buffer, len) :
+                                             HeapAlloc(GetProcessHeap(), 0, len);
+
+        if (!ptr)
+        {
+            ctx->callback_error = ERROR_OUTOFMEMORY;
+            return FALSE;
+        }
+
+        ctx->conversion_buffer = ptr;
+        ctx->conversion_buffer_len = len;
+    }
+
+    WideCharToMultiByte(CP_ACP, 0, source_file->FileName, -1, ctx->conversion_buffer, len, NULL, NULL);
+
+    source_fileA.ModBase = source_file->ModBase;
+    source_fileA.FileName = ctx->conversion_buffer;
+    return ctx->callbackA(&source_fileA, ctx->caller_context);
+}
+
+/******************************************************************
+ *		SymEnumSourceFiles (DBGHELP.@)
+ *
+ */
+BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
+                               PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles,
+                               PVOID UserContext)
+{
+    WCHAR *maskW = NULL;
+    PSYM_ENUMSOURCEFILES_CALLBACKW callbackW;
+    PVOID context;
+    struct enum_sources_files_context callback_context = {cbSrcFiles, UserContext};
+    BOOL ret;
+
+    if (Mask)
+    {
+        DWORD len = MultiByteToWideChar(CP_ACP, 0, Mask, -1, NULL, 0);
+
+        maskW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+        if (!maskW)
+        {
+            SetLastError(ERROR_OUTOFMEMORY);
+            return FALSE;
+        }
+
+        MultiByteToWideChar(CP_ACP, 0, Mask, -1, maskW, len);
+    }
+
+    if (cbSrcFiles)
+    {
+        callbackW = enum_source_files_W_to_A;
+        context = &callback_context;
+    }
+    else
+    {
+        callbackW = NULL;
+        context = UserContext;
+    }
+
+    ret = SymEnumSourceFilesW(hProcess, ModBase, maskW, callbackW, context);
+
+    if (callback_context.callback_error)
+    {
+        SetLastError(callback_context.callback_error);
+        ret = FALSE;
+    }
+
+    HeapFree(GetProcessHeap(), 0, callback_context.conversion_buffer);
+    HeapFree(GetProcessHeap(), 0, maskW);
+
+    return ret;
+}
+
 /******************************************************************
  *		SymGetSourceFileToken (DBGHELP.@)
  *




More information about the wine-cvs mailing list