dbghelp: Implement SymEnumSourceFilesW.
This commit is contained in:
parent
9edafeb742
commit
6ee16099a3
|
@ -45,7 +45,7 @@
|
||||||
@ stub SymEnumProcesses
|
@ stub SymEnumProcesses
|
||||||
@ stub SymEnumSourceFileTokens
|
@ stub SymEnumSourceFileTokens
|
||||||
@ stdcall SymEnumSourceFiles(ptr int64 str ptr ptr)
|
@ stdcall SymEnumSourceFiles(ptr int64 str ptr ptr)
|
||||||
@ stub SymEnumSourceFilesW
|
@ stdcall SymEnumSourceFilesW(ptr int64 wstr ptr ptr)
|
||||||
@ stub SymEnumSourceLines
|
@ stub SymEnumSourceLines
|
||||||
@ stub SymEnumSourceLinesW
|
@ stub SymEnumSourceLinesW
|
||||||
@ stub SymEnumSym
|
@ stub SymEnumSym
|
||||||
|
|
|
@ -537,6 +537,9 @@ extern const WCHAR S_SlashW[] DECLSPEC_HIDDEN;
|
||||||
extern struct module*
|
extern struct module*
|
||||||
module_find_by_addr(const struct process* pcs, unsigned long addr,
|
module_find_by_addr(const struct process* pcs, unsigned long addr,
|
||||||
enum module_type type) DECLSPEC_HIDDEN;
|
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*
|
extern struct module*
|
||||||
module_find_by_nameA(const struct process* pcs,
|
module_find_by_nameA(const struct process* pcs,
|
||||||
const char* name) DECLSPEC_HIDDEN;
|
const char* name) DECLSPEC_HIDDEN;
|
||||||
|
|
|
@ -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;
|
struct module* module;
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ struct module* module_find_by_nameA(const struct process* pcs, const char* name)
|
||||||
WCHAR wname[MAX_PATH];
|
WCHAR wname[MAX_PATH];
|
||||||
|
|
||||||
MultiByteToWideChar(CP_ACP, 0, name, -1, wname, sizeof(wname) / sizeof(WCHAR));
|
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);
|
||||||
}
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
|
|
|
@ -157,16 +157,18 @@ const char* source_get(const struct module* module, unsigned idx)
|
||||||
}
|
}
|
||||||
|
|
||||||
/******************************************************************
|
/******************************************************************
|
||||||
* SymEnumSourceFiles (DBGHELP.@)
|
* SymEnumSourceFilesW (DBGHELP.@)
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
|
BOOL WINAPI SymEnumSourceFilesW(HANDLE hProcess, ULONG64 ModBase, PCWSTR Mask,
|
||||||
PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles,
|
PSYM_ENUMSOURCEFILES_CALLBACKW cbSrcFiles,
|
||||||
PVOID UserContext)
|
PVOID UserContext)
|
||||||
{
|
{
|
||||||
struct module_pair pair;
|
struct module_pair pair;
|
||||||
SOURCEFILE sf;
|
SOURCEFILEW sf;
|
||||||
char* ptr;
|
char* ptr;
|
||||||
|
WCHAR* conversion_buffer = NULL;
|
||||||
|
DWORD conversion_buffer_len = 0;
|
||||||
|
|
||||||
if (!cbSrcFiles) return FALSE;
|
if (!cbSrcFiles) return FALSE;
|
||||||
pair.pcs = process_find_by_handle(hProcess);
|
pair.pcs = process_find_by_handle(hProcess);
|
||||||
|
@ -181,7 +183,7 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
|
||||||
{
|
{
|
||||||
if (Mask[0] == '!')
|
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;
|
if (!module_get_debug(&pair)) return FALSE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
@ -193,15 +195,119 @@ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask,
|
||||||
if (!pair.effective->sources) return FALSE;
|
if (!pair.effective->sources) return FALSE;
|
||||||
for (ptr = pair.effective->sources; *ptr; ptr += strlen(ptr) + 1)
|
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 */
|
/* FIXME: not using Mask */
|
||||||
sf.ModBase = ModBase;
|
sf.ModBase = ModBase;
|
||||||
sf.FileName = ptr;
|
sf.FileName = conversion_buffer;
|
||||||
if (!cbSrcFiles(&sf, UserContext)) break;
|
if (!cbSrcFiles(&sf, UserContext)) break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, conversion_buffer);
|
||||||
return TRUE;
|
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.@)
|
* SymGetSourceFileToken (DBGHELP.@)
|
||||||
*
|
*
|
||||||
|
|
Loading…
Reference in New Issue