Module: wine Branch: master Commit: 6ee16099a3b541c656b2146821fc6787aca6112b URL: http://source.winehq.org/git/wine.git/?a=commit;h=6ee16099a3b541c656b2146821...
Author: Andrew Nguyen anguyen@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.@) *