mirror of
git://source.winehq.org/git/wine.git
synced 2024-09-15 05:09:47 +00:00
dbghelp: Implement SymSrvGetFileIndexInfo for PE modules.
Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
parent
4d32b2ee30
commit
5efe29edc0
|
@ -759,10 +759,12 @@ extern WCHAR* get_wine_loader_name(struct process *pcs) __WINE_DEALLOC(Hea
|
|||
|
||||
/* msc.c */
|
||||
extern BOOL pe_load_debug_directory(const struct process* pcs,
|
||||
struct module* module,
|
||||
struct module* module,
|
||||
const BYTE* mapping,
|
||||
const IMAGE_SECTION_HEADER* sectp, DWORD nsect,
|
||||
const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg) DECLSPEC_HIDDEN;
|
||||
extern DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* dbgdir, DWORD size,
|
||||
SYMSRV_INDEX_INFOW* info) DECLSPEC_HIDDEN;
|
||||
extern BOOL pdb_fetch_file_info(const struct pdb_lookup* pdb_lookup, unsigned* matched) DECLSPEC_HIDDEN;
|
||||
struct pdb_cmd_pair {
|
||||
const char* name;
|
||||
|
@ -793,6 +795,7 @@ extern struct module*
|
|||
extern BOOL pe_load_debug_info(const struct process* pcs,
|
||||
struct module* module) DECLSPEC_HIDDEN;
|
||||
extern const char* pe_map_directory(struct module* module, int dirno, DWORD* size) DECLSPEC_HIDDEN;
|
||||
extern DWORD pe_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info) DECLSPEC_HIDDEN;
|
||||
|
||||
/* source.c */
|
||||
extern unsigned source_new(struct module* module, const char* basedir, const char* source) DECLSPEC_HIDDEN;
|
||||
|
|
|
@ -4465,3 +4465,47 @@ typedef struct _FPO_DATA
|
|||
__ENDTRY
|
||||
return ret;
|
||||
}
|
||||
|
||||
DWORD msc_get_file_indexinfo(void* image, const IMAGE_DEBUG_DIRECTORY* debug_dir, DWORD num_dir, SYMSRV_INDEX_INFOW* info)
|
||||
{
|
||||
DWORD i;
|
||||
unsigned num_misc_records = 0;
|
||||
|
||||
info->age = 0;
|
||||
memset(&info->guid, 0, sizeof(info->guid));
|
||||
info->sig = 0;
|
||||
info->dbgfile[0] = L'\0';
|
||||
info->pdbfile[0] = L'\0';
|
||||
|
||||
for (i = 0; i < num_dir; i++)
|
||||
{
|
||||
if (debug_dir[i].Type == IMAGE_DEBUG_TYPE_CODEVIEW)
|
||||
{
|
||||
const CODEVIEW_PDB_DATA* data = (const CODEVIEW_PDB_DATA*)((char*)image + debug_dir[i].PointerToRawData);
|
||||
const OMFSignatureRSDS* rsds_data = (const OMFSignatureRSDS*)data;
|
||||
if (!memcmp(data->Signature, "NB10", 4))
|
||||
{
|
||||
info->age = data->age;
|
||||
info->sig = data->timestamp;
|
||||
MultiByteToWideChar(CP_ACP, 0, data->name, -1, info->pdbfile, ARRAY_SIZE(info->pdbfile));
|
||||
}
|
||||
if (!memcmp(rsds_data->Signature, "RSDS", 4))
|
||||
{
|
||||
info->age = rsds_data->age;
|
||||
info->guid = rsds_data->guid;
|
||||
MultiByteToWideChar(CP_ACP, 0, rsds_data->name, -1, info->pdbfile, ARRAY_SIZE(info->pdbfile));
|
||||
}
|
||||
}
|
||||
else if (debug_dir[i].Type == IMAGE_DEBUG_TYPE_MISC && info->stripped)
|
||||
{
|
||||
const IMAGE_DEBUG_MISC* misc = (const IMAGE_DEBUG_MISC*)
|
||||
((const char*)image + debug_dir[i].PointerToRawData);
|
||||
if (misc->Unicode)
|
||||
wcscpy(info->dbgfile, (WCHAR*)misc->Data);
|
||||
else
|
||||
MultiByteToWideChar(CP_ACP, 0, (const char*)misc->Data, -1, info->dbgfile, ARRAY_SIZE(info->dbgfile));
|
||||
num_misc_records++;
|
||||
}
|
||||
}
|
||||
return info->stripped && !num_misc_records ? ERROR_BAD_EXE_FORMAT : ERROR_SUCCESS;
|
||||
}
|
||||
|
|
|
@ -881,15 +881,42 @@ BOOL WINAPI SymSrvGetFileIndexInfo(const char *file, SYMSRV_INDEX_INFO* info, DW
|
|||
*/
|
||||
BOOL WINAPI SymSrvGetFileIndexInfoW(const WCHAR *file, SYMSRV_INDEX_INFOW* info, DWORD flags)
|
||||
{
|
||||
FIXME("(%s, %p, 0x%08lx): stub!\n", debugstr_w(file), info, flags);
|
||||
HANDLE hFile, hMap = NULL;
|
||||
void* image = NULL;
|
||||
DWORD fsize, ret;
|
||||
|
||||
TRACE("(%s, %p, 0x%08lx)\n", debugstr_w(file), info, flags);
|
||||
|
||||
if (info->sizeofstruct < sizeof(*info))
|
||||
{
|
||||
SetLastError(ERROR_INVALID_PARAMETER);
|
||||
return FALSE;
|
||||
}
|
||||
SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
|
||||
return FALSE;
|
||||
|
||||
if ((hFile = CreateFileW(file, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) != INVALID_HANDLE_VALUE &&
|
||||
((hMap = CreateFileMappingW(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) != NULL) &&
|
||||
((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) != NULL))
|
||||
{
|
||||
/* must handle PE, or .dbg or .pdb files. So each helper will return:
|
||||
* - ERROR_SUCCESS: if the file format is recognized and index info filled,
|
||||
* - ERROR_BAD_FORMAT: if the file doesn't match the expected format,
|
||||
* - any other error: if the file has expected format, but internal errors
|
||||
*/
|
||||
fsize = GetFileSize(hFile, NULL);
|
||||
/* try PE module first */
|
||||
ret = pe_get_file_indexinfo(image, fsize, info);
|
||||
/* handle (ret == ERROR_BAD_FORMAT) with .dbg and .pdb format */
|
||||
}
|
||||
else ret = ERROR_FILE_NOT_FOUND;
|
||||
|
||||
if (image) UnmapViewOfFile(image);
|
||||
if (hMap) CloseHandle(hMap);
|
||||
if (hFile != INVALID_HANDLE_VALUE) CloseHandle(hFile);
|
||||
|
||||
if (ret == ERROR_SUCCESS) wcscpy(info->file, file_name(file)); /* overflow? */
|
||||
SetLastError(ret);
|
||||
return ret == ERROR_SUCCESS;
|
||||
}
|
||||
|
||||
/******************************************************************
|
||||
|
|
|
@ -962,3 +962,30 @@ PVOID WINAPI ImageDirectoryEntryToData( PVOID base, BOOLEAN image, USHORT dir, P
|
|||
{
|
||||
return ImageDirectoryEntryToDataEx( base, image, dir, size, NULL );
|
||||
}
|
||||
|
||||
DWORD pe_get_file_indexinfo(void* image, DWORD size, SYMSRV_INDEX_INFOW* info)
|
||||
{
|
||||
const IMAGE_NT_HEADERS* nthdr;
|
||||
const IMAGE_DEBUG_DIRECTORY* dbg;
|
||||
ULONG dirsize;
|
||||
|
||||
if (!(nthdr = RtlImageNtHeader(image))) return ERROR_BAD_FORMAT;
|
||||
|
||||
dbg = RtlImageDirectoryEntryToData(image, FALSE, IMAGE_DIRECTORY_ENTRY_DEBUG, &dirsize);
|
||||
if (!dbg || dirsize < sizeof(dbg)) return ERROR_BAD_EXE_FORMAT;
|
||||
|
||||
/* fill in information from NT header */
|
||||
info->timestamp = nthdr->FileHeader.TimeDateStamp;
|
||||
info->stripped = (nthdr->FileHeader.Characteristics & IMAGE_FILE_DEBUG_STRIPPED) != 0;
|
||||
if (nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR64_MAGIC)
|
||||
{
|
||||
const IMAGE_NT_HEADERS64* nthdr64 = (const IMAGE_NT_HEADERS64*)nthdr;
|
||||
info->size = nthdr64->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
else if (nthdr->OptionalHeader.Magic == IMAGE_NT_OPTIONAL_HDR32_MAGIC)
|
||||
{
|
||||
const IMAGE_NT_HEADERS32* nthdr32 = (const IMAGE_NT_HEADERS32*)nthdr;
|
||||
info->size = nthdr32->OptionalHeader.SizeOfImage;
|
||||
}
|
||||
return msc_get_file_indexinfo(image, dbg, dirsize / sizeof(*dbg), info);
|
||||
}
|
||||
|
|
|
@ -442,10 +442,9 @@ static void test_srvgetindexes(void)
|
|||
if (indexes[i].in_error)
|
||||
{
|
||||
ok(!ret, "SymSrvGetFileIndexInfo should have failed\n");
|
||||
todo_wine
|
||||
ok(GetLastError() == ERROR_BAD_EXE_FORMAT, "Mismatch in GetLastError: %lu\n", GetLastError());
|
||||
}
|
||||
else todo_wine
|
||||
else
|
||||
{
|
||||
ok(ret, "SymSrvGetFileIndexInfo failed: %lu\n", GetLastError());
|
||||
|
||||
|
|
Loading…
Reference in a new issue