forked from Mirrors/wine-wine
dbghelp: SymFindFileInPath and PDB
- implemented correct lookup when SymFindFileInPath is called to find a PDB file - added pdb_fetch_file_info to gather relevant information - when looking for a PDB file (from a .EXE or a .DLL), now using SymFindFileInPath to locate the PDB file with the correct informationoldstable
parent
2a1d8efde4
commit
a5b1581e48
|
@ -325,6 +325,28 @@ struct module_pair
|
||||||
struct module* effective; /* out: module with debug info */
|
struct module* effective; /* out: module with debug info */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
enum pdb_kind {PDB_JG, PDB_DS};
|
||||||
|
|
||||||
|
struct pdb_lookup
|
||||||
|
{
|
||||||
|
const char* filename;
|
||||||
|
DWORD age;
|
||||||
|
enum pdb_kind kind;
|
||||||
|
union
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
DWORD timestamp;
|
||||||
|
struct PDB_JG_TOC* toc;
|
||||||
|
} jg;
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
GUID guid;
|
||||||
|
struct PDB_DS_TOC* toc;
|
||||||
|
} ds;
|
||||||
|
} u;
|
||||||
|
};
|
||||||
|
|
||||||
/* dbghelp.c */
|
/* dbghelp.c */
|
||||||
extern struct process* process_find_by_handle(HANDLE hProcess);
|
extern struct process* process_find_by_handle(HANDLE hProcess);
|
||||||
extern HANDLE hMsvcrt;
|
extern HANDLE hMsvcrt;
|
||||||
|
@ -376,6 +398,8 @@ extern BOOL pe_load_debug_directory(const struct process* pcs,
|
||||||
const BYTE* mapping,
|
const BYTE* mapping,
|
||||||
const IMAGE_SECTION_HEADER* sectp, DWORD nsect,
|
const IMAGE_SECTION_HEADER* sectp, DWORD nsect,
|
||||||
const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg);
|
const IMAGE_DEBUG_DIRECTORY* dbg, int nDbg);
|
||||||
|
extern BOOL pdb_fetch_file_info(struct pdb_lookup* pdb_lookup);
|
||||||
|
|
||||||
/* pe_module.c */
|
/* pe_module.c */
|
||||||
extern BOOL pe_load_nt_header(HANDLE hProc, DWORD base, IMAGE_NT_HEADERS* nth);
|
extern BOOL pe_load_nt_header(HANDLE hProc, DWORD base, IMAGE_NT_HEADERS* nth);
|
||||||
extern struct module*
|
extern struct module*
|
||||||
|
|
|
@ -1630,25 +1630,6 @@ static int codeview_snarf(const struct msc_debug_info* msc_dbg, const BYTE* root
|
||||||
* Process PDB file.
|
* Process PDB file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
struct pdb_lookup
|
|
||||||
{
|
|
||||||
const char* filename;
|
|
||||||
enum {PDB_JG, PDB_DS} kind;
|
|
||||||
union
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
DWORD timestamp;
|
|
||||||
struct PDB_JG_TOC* toc;
|
|
||||||
} jg;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
GUID guid;
|
|
||||||
struct PDB_DS_TOC* toc;
|
|
||||||
} ds;
|
|
||||||
} u;
|
|
||||||
};
|
|
||||||
|
|
||||||
static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list,
|
static void* pdb_jg_read(const struct PDB_JG_HEADER* pdb, const WORD* block_list,
|
||||||
int size)
|
int size)
|
||||||
{
|
{
|
||||||
|
@ -1850,22 +1831,35 @@ static BOOL CALLBACK pdb_match(char* file, void* user)
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static HANDLE open_pdb_file(const struct process* pcs, const char* filename)
|
static HANDLE open_pdb_file(const struct process* pcs,
|
||||||
|
const struct pdb_lookup* lookup)
|
||||||
{
|
{
|
||||||
HANDLE h;
|
HANDLE h;
|
||||||
char dbg_file_path[MAX_PATH];
|
char dbg_file_path[MAX_PATH];
|
||||||
|
BOOL ret = FALSE;
|
||||||
|
|
||||||
h = CreateFileA(filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
switch (lookup->kind)
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
|
||||||
/* FIXME: should give more bits on the file to look at */
|
|
||||||
if (h == INVALID_HANDLE_VALUE &&
|
|
||||||
SymFindFileInPath(pcs->handle, NULL, (char*)filename, NULL, 0, 0, 0,
|
|
||||||
dbg_file_path, pdb_match, NULL))
|
|
||||||
{
|
{
|
||||||
h = CreateFileA(dbg_file_path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
case PDB_JG:
|
||||||
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
ret = SymFindFileInPath(pcs->handle, NULL, lookup->filename,
|
||||||
TRACE("with %s returns %p\n", dbg_file_path, h);
|
(PVOID)(DWORD_PTR)lookup->u.jg.timestamp,
|
||||||
|
lookup->age, 0, SSRVOPT_DWORD,
|
||||||
|
dbg_file_path, pdb_match, NULL);
|
||||||
|
break;
|
||||||
|
case PDB_DS:
|
||||||
|
ret = SymFindFileInPath(pcs->handle, NULL, lookup->filename,
|
||||||
|
(PVOID)&lookup->u.ds.guid, lookup->age, 0,
|
||||||
|
SSRVOPT_GUIDPTR, dbg_file_path, pdb_match, NULL);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
if (!ret)
|
||||||
|
{
|
||||||
|
WARN("\tCouldn't find %s\n", lookup->filename);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
h = CreateFileA(dbg_file_path, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||||
|
TRACE("%s: %s returns %p\n", lookup->filename, dbg_file_path, h);
|
||||||
return (h == INVALID_HANDLE_VALUE) ? NULL : h;
|
return (h == INVALID_HANDLE_VALUE) ? NULL : h;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1922,91 +1916,95 @@ static void pdb_process_types(const struct msc_debug_info* msc_dbg,
|
||||||
static const char PDB_JG_IDENT[] = "Microsoft C/C++ program database 2.00\r\n\032JG\0";
|
static const char PDB_JG_IDENT[] = "Microsoft C/C++ program database 2.00\r\n\032JG\0";
|
||||||
static const char PDB_DS_IDENT[] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0";
|
static const char PDB_DS_IDENT[] = "Microsoft C/C++ MSF 7.00\r\n\032DS\0";
|
||||||
|
|
||||||
static BOOL pdb_init(struct pdb_lookup* pdb_lookup, const char* image)
|
/******************************************************************
|
||||||
|
* pdb_init
|
||||||
|
*
|
||||||
|
* Tries to load a pdb file
|
||||||
|
* if do_fill is TRUE, then it just fills pdb_lookup with the information of the
|
||||||
|
* file
|
||||||
|
* if do_fill is FALSE, then it just checks that the kind of PDB (stored in
|
||||||
|
* pdb_lookup) matches what's really in the file
|
||||||
|
*/
|
||||||
|
static BOOL pdb_init(struct pdb_lookup* pdb_lookup, const char* image, BOOL do_fill)
|
||||||
{
|
{
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
/* check the file header, and if ok, load the TOC */
|
/* check the file header, and if ok, load the TOC */
|
||||||
TRACE("PDB(%s): %.40s\n", pdb_lookup->filename, debugstr_an(image, 40));
|
TRACE("PDB(%s): %.40s\n", pdb_lookup->filename, debugstr_an(image, 40));
|
||||||
switch (pdb_lookup->kind)
|
|
||||||
|
if (!memcmp(image, PDB_JG_IDENT, sizeof(PDB_JG_IDENT)))
|
||||||
{
|
{
|
||||||
case PDB_JG:
|
const struct PDB_JG_HEADER* pdb = (const struct PDB_JG_HEADER*)image;
|
||||||
pdb_lookup->u.jg.toc = NULL;
|
struct PDB_JG_ROOT* root;
|
||||||
if (memcmp(image, PDB_JG_IDENT, sizeof(PDB_JG_IDENT)))
|
|
||||||
|
pdb_lookup->u.jg.toc = pdb_jg_read(pdb, pdb->toc_block, pdb->toc.size);
|
||||||
|
root = pdb_read_jg_file(pdb, pdb_lookup->u.jg.toc, 1);
|
||||||
|
if (!root)
|
||||||
{
|
{
|
||||||
FIXME("Couldn't match JG header\n");
|
ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
switch (root->Version)
|
||||||
{
|
{
|
||||||
const struct PDB_JG_HEADER* pdb = (const struct PDB_JG_HEADER*)image;
|
case 19950623: /* VC 4.0 */
|
||||||
struct PDB_JG_ROOT* root;
|
case 19950814:
|
||||||
|
case 19960307: /* VC 5.0 */
|
||||||
pdb_lookup->u.jg.toc = pdb_jg_read(pdb, pdb->toc_block, pdb->toc.size);
|
case 19970604: /* VC 6.0 */
|
||||||
root = pdb_read_jg_file(pdb, pdb_lookup->u.jg.toc, 1);
|
break;
|
||||||
if (!root)
|
default:
|
||||||
{
|
ERR("-Unknown root block version %ld\n", root->Version);
|
||||||
ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
switch (root->Version)
|
|
||||||
{
|
|
||||||
case 19950623: /* VC 4.0 */
|
|
||||||
case 19950814:
|
|
||||||
case 19960307: /* VC 5.0 */
|
|
||||||
case 19970604: /* VC 6.0 */
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERR("-Unknown root block version %ld\n", root->Version);
|
|
||||||
}
|
|
||||||
/* Check .PDB time stamp */
|
|
||||||
if (root->TimeDateStamp != pdb_lookup->u.jg.timestamp)
|
|
||||||
{
|
|
||||||
ERR("-Wrong time stamp of .PDB file %s (0x%08lx, 0x%08lx)\n",
|
|
||||||
pdb_lookup->filename, root->TimeDateStamp,
|
|
||||||
pdb_lookup->u.jg.timestamp);
|
|
||||||
}
|
|
||||||
pdb_free(root);
|
|
||||||
}
|
}
|
||||||
break;
|
if (do_fill)
|
||||||
case PDB_DS:
|
|
||||||
pdb_lookup->u.ds.toc = NULL;
|
|
||||||
if (memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
|
|
||||||
{
|
{
|
||||||
FIXME("Couldn't match DS header\n");
|
pdb_lookup->kind = PDB_JG;
|
||||||
|
pdb_lookup->u.jg.timestamp = root->TimeDateStamp;
|
||||||
|
pdb_lookup->age = root->Age;
|
||||||
|
}
|
||||||
|
else if (pdb_lookup->kind != PDB_JG ||
|
||||||
|
pdb_lookup->u.jg.timestamp != root->TimeDateStamp ||
|
||||||
|
pdb_lookup->age != root->Age)
|
||||||
|
ret = FALSE;
|
||||||
|
TRACE("found JG/%c for %s: age=%lx timestamp=%lx\n",
|
||||||
|
do_fill ? 'f' : '-', pdb_lookup->filename, root->Age,
|
||||||
|
root->TimeDateStamp);
|
||||||
|
pdb_free(root);
|
||||||
|
}
|
||||||
|
else if (!memcmp(image, PDB_DS_IDENT, sizeof(PDB_DS_IDENT)))
|
||||||
|
{
|
||||||
|
const struct PDB_DS_HEADER* pdb = (const struct PDB_DS_HEADER*)image;
|
||||||
|
struct PDB_DS_ROOT* root;
|
||||||
|
|
||||||
|
pdb_lookup->u.ds.toc =
|
||||||
|
pdb_ds_read(pdb,
|
||||||
|
(const DWORD*)((const char*)pdb + pdb->toc_page * pdb->block_size),
|
||||||
|
pdb->toc_size);
|
||||||
|
root = pdb_read_ds_file(pdb, pdb_lookup->u.ds.toc, 1);
|
||||||
|
if (!root)
|
||||||
|
{
|
||||||
|
ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
else
|
switch (root->Version)
|
||||||
{
|
{
|
||||||
const struct PDB_DS_HEADER* pdb = (const struct PDB_DS_HEADER*)image;
|
case 20000404:
|
||||||
struct PDB_DS_ROOT* root;
|
break;
|
||||||
|
default:
|
||||||
pdb_lookup->u.ds.toc =
|
ERR("-Unknown root block version %ld\n", root->Version);
|
||||||
pdb_ds_read(pdb,
|
|
||||||
(const DWORD*)((const char*)pdb + pdb->toc_page * pdb->block_size),
|
|
||||||
pdb->toc_size);
|
|
||||||
root = pdb_read_ds_file(pdb, pdb_lookup->u.ds.toc, 1);
|
|
||||||
if (!root)
|
|
||||||
{
|
|
||||||
ERR("-Unable to get root from .PDB in %s\n", pdb_lookup->filename);
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
switch (root->Version)
|
|
||||||
{
|
|
||||||
case 20000404:
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
ERR("-Unknown root block version %ld\n", root->Version);
|
|
||||||
}
|
|
||||||
/* Check .PDB time stamp */
|
|
||||||
if (memcmp(&root->guid, &pdb_lookup->u.ds.guid, sizeof(GUID)))
|
|
||||||
{
|
|
||||||
ERR("-Wrong GUID of .PDB file %s (%s, %s)\n",
|
|
||||||
pdb_lookup->filename,
|
|
||||||
wine_dbgstr_guid(&root->guid),
|
|
||||||
wine_dbgstr_guid(&pdb_lookup->u.ds.guid));
|
|
||||||
}
|
|
||||||
pdb_free(root);
|
|
||||||
}
|
}
|
||||||
break;
|
if (do_fill)
|
||||||
|
{
|
||||||
|
pdb_lookup->kind = PDB_DS;
|
||||||
|
pdb_lookup->u.ds.guid = root->guid;
|
||||||
|
pdb_lookup->age = root->Age;
|
||||||
|
}
|
||||||
|
else if (pdb_lookup->kind != PDB_DS ||
|
||||||
|
memcmp(&pdb_lookup->u.ds.guid, &root->guid, sizeof(GUID)) ||
|
||||||
|
pdb_lookup->age != root->Age)
|
||||||
|
ret = FALSE;
|
||||||
|
TRACE("found DS/%c for %s: age=%lx guid=%s\n",
|
||||||
|
do_fill ? 'f' : '-', pdb_lookup->filename, root->Age,
|
||||||
|
debugstr_guid(&root->guid));
|
||||||
|
pdb_free(root);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (0) /* some tool to dump the internal files from a PDB file */
|
if (0) /* some tool to dump the internal files from a PDB file */
|
||||||
|
@ -2028,7 +2026,7 @@ static BOOL pdb_init(struct pdb_lookup* pdb_lookup, const char* image)
|
||||||
pdb_free(x);
|
pdb_free(x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return TRUE;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static BOOL pdb_process_internal(const struct process* pcs,
|
static BOOL pdb_process_internal(const struct process* pcs,
|
||||||
|
@ -2069,9 +2067,15 @@ static void pdb_process_symbol_imports(const struct process* pcs,
|
||||||
{
|
{
|
||||||
struct pdb_lookup imp_pdb_lookup;
|
struct pdb_lookup imp_pdb_lookup;
|
||||||
|
|
||||||
|
/* FIXME: this is an import of a JG PDB file
|
||||||
|
* how's a DS PDB handled ?
|
||||||
|
*/
|
||||||
imp_pdb_lookup.filename = imp->filename;
|
imp_pdb_lookup.filename = imp->filename;
|
||||||
imp_pdb_lookup.kind = PDB_JG;
|
imp_pdb_lookup.kind = PDB_JG;
|
||||||
imp_pdb_lookup.u.jg.timestamp = imp->TimeDateStamp;
|
imp_pdb_lookup.u.jg.timestamp = imp->TimeDateStamp;
|
||||||
|
imp_pdb_lookup.age = imp->Age;
|
||||||
|
TRACE("got for %s: age=%lu ts=%lx\n",
|
||||||
|
imp->filename, imp->Age, imp->TimeDateStamp);
|
||||||
pdb_process_internal(pcs, msc_dbg, &imp_pdb_lookup, i);
|
pdb_process_internal(pcs, msc_dbg, &imp_pdb_lookup, i);
|
||||||
}
|
}
|
||||||
i++;
|
i++;
|
||||||
|
@ -2097,14 +2101,14 @@ static BOOL pdb_process_internal(const struct process* pcs,
|
||||||
TRACE("Processing PDB file %s\n", pdb_lookup->filename);
|
TRACE("Processing PDB file %s\n", pdb_lookup->filename);
|
||||||
|
|
||||||
/* Open and map() .PDB file */
|
/* Open and map() .PDB file */
|
||||||
if ((hFile = open_pdb_file(pcs, pdb_lookup->filename)) == NULL ||
|
if ((hFile = open_pdb_file(pcs, pdb_lookup)) == NULL ||
|
||||||
((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) ||
|
((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) ||
|
||||||
((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
|
((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
|
||||||
{
|
{
|
||||||
WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
|
WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
|
||||||
goto leave;
|
goto leave;
|
||||||
}
|
}
|
||||||
pdb_init(pdb_lookup, image);
|
pdb_init(pdb_lookup, image, FALSE);
|
||||||
|
|
||||||
symbols_image = pdb_read_file(image, pdb_lookup, 3);
|
symbols_image = pdb_read_file(image, pdb_lookup, 3);
|
||||||
if (symbols_image)
|
if (symbols_image)
|
||||||
|
@ -2203,6 +2207,33 @@ static BOOL pdb_process_file(const struct process* pcs,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
BOOL pdb_fetch_file_info(struct pdb_lookup* pdb_lookup)
|
||||||
|
{
|
||||||
|
HANDLE hFile, hMap = NULL;
|
||||||
|
char* image = NULL;
|
||||||
|
BOOL ret = TRUE;
|
||||||
|
|
||||||
|
if ((hFile = CreateFileA(pdb_lookup->filename, GENERIC_READ, FILE_SHARE_READ, NULL,
|
||||||
|
OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL)) == INVALID_HANDLE_VALUE ||
|
||||||
|
((hMap = CreateFileMappingA(hFile, NULL, PAGE_READONLY, 0, 0, NULL)) == NULL) ||
|
||||||
|
((image = MapViewOfFile(hMap, FILE_MAP_READ, 0, 0, 0)) == NULL))
|
||||||
|
{
|
||||||
|
WARN("Unable to open .PDB file: %s\n", pdb_lookup->filename);
|
||||||
|
ret = FALSE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
pdb_init(pdb_lookup, image, TRUE);
|
||||||
|
pdb_free_lookup(pdb_lookup);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (image) UnmapViewOfFile(image);
|
||||||
|
if (hMap) CloseHandle(hMap);
|
||||||
|
if (hFile) CloseHandle(hFile);
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
/*========================================================================
|
/*========================================================================
|
||||||
* Process CodeView debug information.
|
* Process CodeView debug information.
|
||||||
*/
|
*/
|
||||||
|
@ -2307,6 +2338,7 @@ static BOOL codeview_process_info(const struct process* pcs,
|
||||||
pdb_lookup.kind = PDB_JG;
|
pdb_lookup.kind = PDB_JG;
|
||||||
pdb_lookup.u.jg.timestamp = pdb->timestamp;
|
pdb_lookup.u.jg.timestamp = pdb->timestamp;
|
||||||
pdb_lookup.u.jg.toc = NULL;
|
pdb_lookup.u.jg.toc = NULL;
|
||||||
|
pdb_lookup.age = pdb->unknown;
|
||||||
ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
|
ret = pdb_process_file(pcs, msc_dbg, &pdb_lookup);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1300,7 +1300,7 @@ struct PDB_JG_ROOT
|
||||||
{
|
{
|
||||||
DWORD Version;
|
DWORD Version;
|
||||||
DWORD TimeDateStamp;
|
DWORD TimeDateStamp;
|
||||||
DWORD unknown;
|
DWORD Age;
|
||||||
DWORD cbNames;
|
DWORD cbNames;
|
||||||
CHAR names[1];
|
CHAR names[1];
|
||||||
};
|
};
|
||||||
|
@ -1309,7 +1309,7 @@ struct PDB_DS_ROOT
|
||||||
{
|
{
|
||||||
DWORD Version;
|
DWORD Version;
|
||||||
DWORD TimeDateStamp;
|
DWORD TimeDateStamp;
|
||||||
DWORD unknown;
|
DWORD Age;
|
||||||
GUID guid;
|
GUID guid;
|
||||||
DWORD cbNames;
|
DWORD cbNames;
|
||||||
CHAR names[1];
|
CHAR names[1];
|
||||||
|
@ -1409,7 +1409,7 @@ typedef struct _PDB_SYMBOL_IMPORT
|
||||||
DWORD unknown1;
|
DWORD unknown1;
|
||||||
DWORD unknown2;
|
DWORD unknown2;
|
||||||
DWORD TimeDateStamp;
|
DWORD TimeDateStamp;
|
||||||
DWORD nRequests;
|
DWORD Age;
|
||||||
CHAR filename[1];
|
CHAR filename[1];
|
||||||
} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
|
} PDB_SYMBOL_IMPORT, *PPDB_SYMBOL_IMPORT;
|
||||||
|
|
||||||
|
@ -1556,5 +1556,3 @@ typedef struct _CV_ENTRY_GLOBAL_TYPES
|
||||||
types_record[];
|
types_record[];
|
||||||
*/
|
*/
|
||||||
} CV_ENTRY_GLOBAL_TYPES;
|
} CV_ENTRY_GLOBAL_TYPES;
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -229,7 +229,6 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
|
||||||
{
|
{
|
||||||
struct sffip* s = (struct sffip*)user;
|
struct sffip* s = (struct sffip*)user;
|
||||||
DWORD size, checksum;
|
DWORD size, checksum;
|
||||||
DWORD_PTR timestamp;
|
|
||||||
|
|
||||||
/* FIXME: should check that id/two/three match the file pointed
|
/* FIXME: should check that id/two/three match the file pointed
|
||||||
* by buffer
|
* by buffer
|
||||||
|
@ -240,6 +239,7 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
|
||||||
{
|
{
|
||||||
HANDLE hFile, hMap;
|
HANDLE hFile, hMap;
|
||||||
void* mapping;
|
void* mapping;
|
||||||
|
DWORD timestamp;
|
||||||
|
|
||||||
timestamp = ~(DWORD_PTR)s->id;
|
timestamp = ~(DWORD_PTR)s->id;
|
||||||
size = ~s->two;
|
size = ~s->two;
|
||||||
|
@ -282,7 +282,49 @@ static BOOL CALLBACK sffip_cb(LPCSTR buffer, void* user)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case DMT_PDB:
|
case DMT_PDB:
|
||||||
FIXME("NIY on '%s'\n", buffer);
|
{
|
||||||
|
struct pdb_lookup pdb_lookup;
|
||||||
|
|
||||||
|
pdb_lookup.filename = buffer;
|
||||||
|
|
||||||
|
if (!pdb_fetch_file_info(&pdb_lookup)) return FALSE;
|
||||||
|
switch (pdb_lookup.kind)
|
||||||
|
{
|
||||||
|
case PDB_JG:
|
||||||
|
if (s->flags & SSRVOPT_GUIDPTR)
|
||||||
|
{
|
||||||
|
WARN("Found %s, but wrong PDB version\n", buffer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (pdb_lookup.u.jg.timestamp != (DWORD_PTR)s->id)
|
||||||
|
{
|
||||||
|
WARN("Found %s, but wrong signature: %08lx %08lx\n",
|
||||||
|
buffer, pdb_lookup.u.jg.timestamp, (DWORD_PTR)s->id);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case PDB_DS:
|
||||||
|
if (!(s->flags & SSRVOPT_GUIDPTR))
|
||||||
|
{
|
||||||
|
WARN("Found %s, but wrong PDB version\n", buffer);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
if (!(memcmp(&pdb_lookup.u.ds.guid, (GUID*)s->id, sizeof(GUID))))
|
||||||
|
{
|
||||||
|
WARN("Found %s, but wrong GUID: %s %s\n",
|
||||||
|
buffer, debugstr_guid(&pdb_lookup.u.ds.guid),
|
||||||
|
debugstr_guid((GUID*)s->id));
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (pdb_lookup.age != s->two)
|
||||||
|
{
|
||||||
|
WARN("Found %s, but wrong age: %08lx %08lx\n",
|
||||||
|
buffer, pdb_lookup.age, s->two);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
FIXME("What the heck??\n");
|
FIXME("What the heck??\n");
|
||||||
|
|
Loading…
Reference in New Issue