/****************************************************************** * SymGetModuleInfoW64 (DBGHELP.@) * */ BOOL WINAPI SymGetModuleInfoW64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULEW64 ModuleInfo) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; IMAGEHLP_MODULEW64 miw64; TRACE("%p %s %p\n", hProcess, wine_dbgstr_longlong(dwAddr), ModuleInfo); if (!pcs) return FALSE; if (ModuleInfo->SizeOfStruct > sizeof(*ModuleInfo)) return FALSE; module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN); if (!module) return FALSE; miw64 = module->module; /* update debug information from container if any */ if (module->module.SymType == SymNone) { module = module_get_container(pcs, module); if (module && module->module.SymType != SymNone) { miw64.SymType = module->module.SymType; miw64.NumSyms = module->module.NumSyms; } } memcpy(ModuleInfo, &miw64, ModuleInfo->SizeOfStruct); return TRUE; }
/****************************************************************** * SymGetModuleInfo64 (DBGHELP.@) * */ BOOL WINAPI SymGetModuleInfo64(HANDLE hProcess, DWORD64 dwAddr, PIMAGEHLP_MODULE64 ModuleInfo) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; TRACE("%p %s %p\n", hProcess, wine_dbgstr_longlong(dwAddr), ModuleInfo); if (!pcs) return FALSE; if (ModuleInfo->SizeOfStruct > sizeof(*ModuleInfo)) return FALSE; module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN); if (!module) return FALSE; memcpy(ModuleInfo, &module->module, ModuleInfo->SizeOfStruct); if (module->module.SymType == SymNone) { module = module_get_container(pcs, module); if (module && module->module.SymType != SymNone) { ModuleInfo->SymType = module->module.SymType; ModuleInfo->NumSyms = module->module.NumSyms; } } return TRUE; }
/****************************************************************** * SymGetModuleInfo (DBGHELP.@) * */ BOOL WINAPI SymGetModuleInfo(HANDLE hProcess, DWORD dwAddr, PIMAGEHLP_MODULE ModuleInfo) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; IMAGEHLP_MODULE mod; if (!pcs) return FALSE; if (ModuleInfo->SizeOfStruct < sizeof(*ModuleInfo)) return FALSE; module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN); if (!module) return FALSE; mod.SizeOfStruct = ModuleInfo->SizeOfStruct; mod.BaseOfImage = module->module.BaseOfImage; mod.ImageSize = module->module.ImageSize; mod.TimeDateStamp = module->module.TimeDateStamp; mod.CheckSum = module->module.CheckSum; mod.NumSyms = module->module.NumSyms; mod.SymType = module->module.SymType; strcpy(mod.ModuleName, module->module.ModuleName); strcpy(mod.ImageName, module->module.ImageName); strcpy(mod.LoadedImageName, module->module.LoadedImageName); if (module->module.SymType == SymNone) { module = module_get_container(pcs, module); if (module && module->module.SymType != SymNone) { mod.SymType = module->module.SymType; mod.NumSyms = module->module.NumSyms; } } memcpy(ModuleInfo, &mod, ModuleInfo->SizeOfStruct); return TRUE; }
/*********************************************************************** * SymLoadModuleEx (DBGHELP.@) */ DWORD64 WINAPI SymLoadModuleEx(HANDLE hProcess, HANDLE hFile, PCSTR ImageName, PCSTR ModuleName, DWORD64 BaseOfDll, DWORD DllSize, PMODLOAD_DATA Data, DWORD Flags) { TRACE("(%p %p %s %s %s %08lx %p %08lx)\n", hProcess, hFile, debugstr_a(ImageName), debugstr_a(ModuleName), wine_dbgstr_longlong(BaseOfDll), DllSize, Data, Flags); if (Data) FIXME("Unsupported load data parameter %p for %s\n", Data, ImageName); if (!validate_addr64(BaseOfDll)) return FALSE; if (Flags & SLMFLAG_VIRTUAL) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; if (!pcs) return FALSE; module = module_new(pcs, ImageName, module_get_type_by_name(ImageName), TRUE, (DWORD)BaseOfDll, DllSize, 0, 0); if (!module) return FALSE; if (ModuleName) lstrcpynA(module->module.ModuleName, ModuleName, sizeof(module->module.ModuleName)); module->module.SymType = SymVirtual; return TRUE; } if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08lx for %s\n", Flags, ImageName); return SymLoadModule(hProcess, hFile, (char*)ImageName, (char*)ModuleName, (DWORD)BaseOfDll, DllSize); }
/****************************************************************** * SymFindFileInPathW (DBGHELP.@) * */ BOOL WINAPI SymFindFileInPathW(HANDLE hProcess, PCWSTR searchPath, PCWSTR full_path, PVOID id, DWORD two, DWORD three, DWORD flags, PWSTR buffer, PFINDFILEINPATHCALLBACKW cb, PVOID user) { struct sffip s; struct process* pcs = process_find_by_handle(hProcess); WCHAR tmp[MAX_PATH]; WCHAR* ptr; const WCHAR* filename; TRACE("(hProcess = %p, searchPath = %s, full_path = %s, id = %p, two = 0x%08x, three = 0x%08x, flags = 0x%08x, buffer = %p, cb = %p, user = %p)\n", hProcess, debugstr_w(searchPath), debugstr_w(full_path), id, two, three, flags, buffer, cb, user); if (!pcs) return FALSE; if (!searchPath) searchPath = pcs->search_path; s.id = id; s.two = two; s.three = three; s.flags = flags; s.cb = cb; s.user = user; filename = file_nameW(full_path); s.kind = module_get_type_by_name(filename); /* first check full path to file */ if (sffip_cb(full_path, &s)) { strcpyW(buffer, full_path); return TRUE; } while (searchPath) { ptr = strchrW(searchPath, ';'); if (ptr) { memcpy(tmp, searchPath, (ptr - searchPath) * sizeof(WCHAR)); tmp[ptr - searchPath] = 0; searchPath = ptr + 1; } else { strcpyW(tmp, searchPath); searchPath = NULL; } if (do_searchW(filename, tmp, FALSE, sffip_cb, &s)) { strcpyW(buffer, tmp); return TRUE; } } return FALSE; }
/****************************************************************** * SymRefreshModuleList (DBGHELP.@) */ BOOL WINAPI SymRefreshModuleList(HANDLE hProcess) { struct process* pcs; TRACE("(%p)\n", hProcess); if (!(pcs = process_find_by_handle(hProcess))) return FALSE; return refresh_module_list(pcs); }
/*********************************************************************** * SymGetModuleBase64 (DBGHELP.@) */ DWORD64 WINAPI SymGetModuleBase64(HANDLE hProcess, DWORD64 dwAddr) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; if (!pcs) return 0; module = module_find_by_addr(pcs, dwAddr, DMT_UNKNOWN); if (!module) return 0; return module->module.BaseOfImage; }
/****************************************************************** * SymUnloadModule (DBGHELP.@) * */ BOOL WINAPI SymUnloadModule(HANDLE hProcess, DWORD BaseOfDll) { struct process* pcs; struct module* module; pcs = process_find_by_handle(hProcess); if (!pcs) return FALSE; module = module_find_by_addr(pcs, BaseOfDll, DMT_UNKNOWN); if (!module) return FALSE; return module_remove(pcs, module); }
/*********************************************************************** * SymFunctionTableAccess64 (DBGHELP.@) */ PVOID WINAPI SymFunctionTableAccess64(HANDLE hProcess, DWORD64 AddrBase) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; if (!pcs || !dbghelp_current_cpu->find_runtime_function) return NULL; module = module_find_by_addr(pcs, AddrBase, DMT_UNKNOWN); if (!module) return NULL; return dbghelp_current_cpu->find_runtime_function(module, AddrBase); }
/*********************************************************************** * SymLoadModule (DBGHELP.@) */ DWORD WINAPI SymLoadModule(HANDLE hProcess, HANDLE hFile, const char* ImageName, const char* ModuleName, DWORD BaseOfDll, DWORD SizeOfDll) { struct process* pcs; struct module* module = NULL; TRACE("(%p %p %s %s %08lx %08lx)\n", hProcess, hFile, debugstr_a(ImageName), debugstr_a(ModuleName), BaseOfDll, SizeOfDll); pcs = process_find_by_handle(hProcess); if (!pcs) return FALSE; /* force transparent ELF loading / unloading */ elf_synchronize_module_list(pcs); /* this is a Wine extension to the API just to redo the synchronisation */ if (!ImageName && !hFile) return 0; if (module_is_elf_container_loaded(pcs, ImageName, ModuleName)) { /* force the loading of DLL as builtin */ if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName, BaseOfDll, SizeOfDll))) goto done; WARN("Couldn't locate %s\n", ImageName); return 0; } TRACE("Assuming %s as native DLL\n", ImageName); if (!(module = pe_load_module(pcs, ImageName, hFile, BaseOfDll, SizeOfDll))) { if (module_get_type_by_name(ImageName) == DMT_ELF && (module = elf_load_module(pcs, ImageName, BaseOfDll))) goto done; FIXME("Should have successfully loaded debug information for image %s\n", ImageName); if ((module = pe_load_module_from_pcs(pcs, ImageName, ModuleName, BaseOfDll, SizeOfDll))) goto done; WARN("Couldn't locate %s\n", ImageName); return 0; } module_compute_num_syms(module); done: /* by default pe_load_module fills module.ModuleName from a derivation * of ImageName. Overwrite it, if we have better information */ if (ModuleName) lstrcpynA(module->module.ModuleName, ModuleName, sizeof(module->module.ModuleName)); lstrcpynA(module->module.ImageName, ImageName, sizeof(module->module.ImageName)); return module->module.BaseOfImage; }
/****************************************************************** * SymRefreshModuleList (DBGHELP.@) */ BOOL WINAPI SymRefreshModuleList(HANDLE hProcess) { struct process* pcs; TRACE("(%p)\n", hProcess); if (!(pcs = process_find_by_handle(hProcess))) return FALSE; #ifndef DBGHELP_STATIC_LIB return refresh_module_list(pcs); #else return TRUE; #endif }
/****************************************************************** * SymEnumerateModules64 (DBGHELP.@) * */ BOOL WINAPI SymEnumerateModules64(HANDLE hProcess, PSYM_ENUMMODULES_CALLBACK64 EnumModulesCallback, PVOID UserContext) { struct process* pcs = process_find_by_handle(hProcess); struct module* module; if (!pcs) return FALSE; for (module = pcs->lmodules; module; module = module->next) { if (!(dbghelp_options & SYMOPT_WINE_WITH_ELF_MODULES) && module->type == DMT_ELF) continue; if (!EnumModulesCallback(module->module.ModuleName, module->module.BaseOfImage, UserContext)) break; } return TRUE; }
/****************************************************************** * SymEnumSourceFiles (DBGHELP.@) * */ BOOL WINAPI SymEnumSourceFiles(HANDLE hProcess, ULONG64 ModBase, PCSTR Mask, PSYM_ENUMSOURCEFILES_CALLBACK cbSrcFiles, PVOID UserContext) { struct module_pair pair; SOURCEFILE sf; char* ptr; if (!cbSrcFiles) return FALSE; pair.pcs = process_find_by_handle(hProcess); if (!pair.pcs) return FALSE; if (ModBase) { pair.requested = module_find_by_addr(pair.pcs, ModBase, DMT_UNKNOWN); if (!module_get_debug(&pair)) return FALSE; } else { if (Mask[0] == '!') { pair.requested = module_find_by_nameA(pair.pcs, Mask + 1); if (!module_get_debug(&pair)) return FALSE; } else { FIXME("Unsupported yet (should get info from current context)\n"); return FALSE; } } if (!pair.effective->sources) return FALSE; for (ptr = pair.effective->sources; *ptr; ptr += strlen(ptr) + 1) { /* FIXME: not using Mask */ sf.ModBase = ModBase; sf.FileName = ptr; if (!cbSrcFiles(&sf, UserContext)) break; } return TRUE; }
/****************************************************************** * SymFindFileInPath (DBGHELP.@) * */ BOOL WINAPI SymFindFileInPath(HANDLE hProcess, PCSTR inSearchPath, PCSTR full_path, PVOID id, DWORD two, DWORD three, DWORD flags, LPSTR buffer, PFINDFILEINPATHCALLBACK cb, PVOID user) { struct sffip s; struct process* pcs = process_find_by_handle(hProcess); char tmp[MAX_PATH]; char* ptr; const char* filename; const char* searchPath = inSearchPath; TRACE("(%p %s %s %p %08lx %08lx %08lx %p %p %p)\n", hProcess, searchPath, full_path, id, two, three, flags, buffer, cb, user); if (!pcs) return FALSE; if (!searchPath) { unsigned len = WideCharToMultiByte(CP_ACP, 0, pcs->search_path, -1, NULL, 0, NULL, NULL); char* buf; searchPath = buf = HeapAlloc(GetProcessHeap(), 0, len); if (!searchPath) return FALSE; WideCharToMultiByte(CP_ACP, 0, pcs->search_path, -1, buf, len, NULL, NULL); } s.id = id; s.two = two; s.three = three; s.flags = flags; s.cb = cb; s.user = user; filename = file_name(full_path); s.kind = module_get_type_by_name(filename); /* first check full path to file */ if (sffip_cb(full_path, &s)) { strcpy(buffer, full_path); if (searchPath != inSearchPath) HeapFree(GetProcessHeap(), 0, (char*)searchPath); return TRUE; } while (searchPath) { ptr = strchr(searchPath, ';'); if (ptr) { memcpy(tmp, searchPath, ptr - searchPath); tmp[ptr - searchPath] = 0; searchPath = ptr + 1; } else { strcpy(tmp, searchPath); searchPath = NULL; } if (do_search(filename, tmp, FALSE, sffip_cb, &s)) { strcpy(buffer, tmp); if (searchPath != inSearchPath) HeapFree(GetProcessHeap(), 0, (char*)searchPath); return TRUE; } } if (searchPath != inSearchPath) HeapFree(GetProcessHeap(), 0, (char*)searchPath); return FALSE; }
/*********************************************************************** * SymLoadModuleExW (DBGHELP.@) */ DWORD64 WINAPI SymLoadModuleExW(HANDLE hProcess, HANDLE hFile, PCWSTR wImageName, PCWSTR wModuleName, DWORD64 BaseOfDll, DWORD SizeOfDll, PMODLOAD_DATA Data, DWORD Flags) { struct process* pcs; struct module* module = NULL; TRACE("(%p %p %s %s %s %08x %p %08x)\n", hProcess, hFile, debugstr_w(wImageName), debugstr_w(wModuleName), wine_dbgstr_longlong(BaseOfDll), SizeOfDll, Data, Flags); if (Data) FIXME("Unsupported load data parameter %p for %s\n", Data, debugstr_w(wImageName)); if (!validate_addr64(BaseOfDll)) return FALSE; if (!(pcs = process_find_by_handle(hProcess))) return FALSE; if (Flags & SLMFLAG_VIRTUAL) { if (!wImageName) return FALSE; module = module_new(pcs, wImageName, module_get_type_by_name(wImageName), TRUE, BaseOfDll, SizeOfDll, 0, 0); if (!module) return FALSE; if (wModuleName) module_set_module(module, wModuleName); module->module.SymType = SymVirtual; return TRUE; } if (Flags & ~(SLMFLAG_VIRTUAL)) FIXME("Unsupported Flags %08x for %s\n", Flags, debugstr_w(wImageName)); refresh_module_list(pcs); /* this is a Wine extension to the API just to redo the synchronisation */ if (!wImageName && !hFile) return 0; /* check if the module is already loaded, or if it's a builtin PE module with * an containing ELF module */ if (wImageName) { module = module_is_already_loaded(pcs, wImageName); if (!module && module_is_container_loaded(pcs, wImageName, BaseOfDll)) { /* force the loading of DLL as builtin */ module = pe_load_builtin_module(pcs, wImageName, BaseOfDll, SizeOfDll); } } if (!module) { /* otherwise, try a regular PE module */ if (!(module = pe_load_native_module(pcs, wImageName, hFile, BaseOfDll, SizeOfDll)) && wImageName) { /* and finally an ELF or Mach-O module */ switch (module_get_type_by_name(wImageName)) { case DMT_ELF: module = elf_load_module(pcs, wImageName, BaseOfDll); break; case DMT_MACHO: module = macho_load_module(pcs, wImageName, BaseOfDll); break; default: /* Ignored */ break; } } } if (!module) { WARN("Couldn't locate %s\n", debugstr_w(wImageName)); return 0; } module->module.NumSyms = module->ht_symbols.num_elts; /* by default module_new fills module.ModuleName from a derivation * of LoadedImageName. Overwrite it, if we have better information */ if (wModuleName) module_set_module(module, wModuleName); if (wImageName) lstrcpynW(module->module.ImageName, wImageName, sizeof(module->module.ImageName) / sizeof(WCHAR)); return module->module.BaseOfImage; }