dbghelp: Implement SymSrvGetFileIndexInfo for PE modules.

Signed-off-by: Eric Pouech <eric.pouech@gmail.com>
This commit is contained in:
Eric Pouech 2023-06-20 17:01:18 +02:00 committed by Alexandre Julliard
parent 4d32b2ee30
commit 5efe29edc0
5 changed files with 106 additions and 6 deletions

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}
/******************************************************************

View file

@ -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);
}

View file

@ -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());