Leaked source code of windows server 2003
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2231 lines
61 KiB

  1. /*
  2. * symmod.c
  3. */
  4. #include <private.h>
  5. #include <symbols.h>
  6. #include <globals.h>
  7. #include <psapi.h>
  8. // this struct is used to initilaize the module data array for a new module
  9. static MODULE_DATA gmd[NUM_MODULE_DATA_ENTRIES] =
  10. {
  11. {mdHeader, dsNone, dsNone, false, NULL},
  12. {mdSecHdrs, dsNone, dsNone, false, NULL},
  13. {IMAGE_DEBUG_TYPE_UNKNOWN, dsNone, dsNone, false, NULL},
  14. {IMAGE_DEBUG_TYPE_COFF, dsNone, dsNone, false, NULL},
  15. {IMAGE_DEBUG_TYPE_CODEVIEW, dsNone, dsNone, false, NULL},
  16. {IMAGE_DEBUG_TYPE_FPO, dsNone, dsNone, false, NULL}, // true, mdfnGetExecutableImage},
  17. {IMAGE_DEBUG_TYPE_MISC, dsNone, dsNone, false, NULL},
  18. {IMAGE_DEBUG_TYPE_EXCEPTION, dsNone, dsNone, false, NULL},
  19. {IMAGE_DEBUG_TYPE_FIXUP, dsNone, dsNone, false, NULL},
  20. {IMAGE_DEBUG_TYPE_OMAP_TO_SRC, dsNone, dsNone, false, NULL},
  21. {IMAGE_DEBUG_TYPE_OMAP_FROM_SRC, dsNone, dsNone, false, NULL},
  22. {IMAGE_DEBUG_TYPE_BORLAND, dsNone, dsNone, false, NULL},
  23. {IMAGE_DEBUG_TYPE_RESERVED10, dsNone, dsNone, false, NULL},
  24. {IMAGE_DEBUG_TYPE_CLSID, dsNone, dsNone, false, NULL}
  25. };
  26. // prototypes - move them later
  27. BOOL
  28. modload(
  29. IN HANDLE hProcess,
  30. IN PMODULE_ENTRY mi
  31. );
  32. BOOL
  33. idd2mi(
  34. PPROCESS_ENTRY pe,
  35. PIMGHLP_DEBUG_DATA idd,
  36. PMODULE_ENTRY mi
  37. );
  38. BOOL
  39. imgReadLoaded(
  40. PIMGHLP_DEBUG_DATA idd
  41. );
  42. BOOL
  43. imgReadFromDisk(
  44. PIMGHLP_DEBUG_DATA idd
  45. );
  46. BOOL
  47. ReadHeader(
  48. PIMGHLP_DEBUG_DATA idd,
  49. DWORD datasrc
  50. );
  51. BOOL
  52. ReadCallerData(
  53. PIMGHLP_DEBUG_DATA idd
  54. );
  55. BOOL
  56. cbFindExe(
  57. HANDLE FileHandle,
  58. PSTR FileName,
  59. PVOID CallerData
  60. );
  61. BOOL
  62. cbFindDbg(
  63. HANDLE FileHandle,
  64. PSTR FileName,
  65. PVOID CallerData
  66. );
  67. BOOL
  68. ProcessCvForOmap(
  69. PIMGHLP_DEBUG_DATA idd
  70. );
  71. void
  72. RetrievePdbInfo(
  73. PIMGHLP_DEBUG_DATA idd
  74. );
  75. DWORD
  76. imgset(
  77. PMODULE_DATA md,
  78. DWORD id,
  79. DWORD hint,
  80. DWORD src
  81. );
  82. BOOL
  83. FakePdbName(
  84. PIMGHLP_DEBUG_DATA idd
  85. );
  86. // inline functions
  87. __inline
  88. DWORD
  89. SectionContains (
  90. HANDLE hp,
  91. PIMAGE_SECTION_HEADER pSH,
  92. PIMAGE_DATA_DIRECTORY ddir
  93. );
  94. // here's the real code
  95. BOOL
  96. LoadSymbols(
  97. HANDLE hp,
  98. PMODULE_ENTRY mi,
  99. DWORD flags
  100. )
  101. {
  102. BOOL rc;
  103. if (flags & LS_JUST_TEST) {
  104. if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS))
  105. return false;
  106. else
  107. return true;
  108. }
  109. if (flags & LS_QUALIFIED) {
  110. if (option(SYMOPT_NO_UNQUALIFIED_LOADS)) {
  111. if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS))
  112. return false;
  113. }
  114. }
  115. if ((mi->Flags & MIF_DEFERRED_LOAD) && !(mi->Flags & MIF_NO_SYMBOLS)) {
  116. rc = modload(hp, mi);
  117. if (rc)
  118. rc = mi->SymType != SymNone;
  119. return rc;
  120. } else if (flags & LS_FAIL_IF_LOADED)
  121. return false;
  122. return true;
  123. }
  124. // This function exists just to be called by MapDebugInfo legacy code.
  125. PIMGHLP_DEBUG_DATA
  126. GetIDD(
  127. HANDLE hFile,
  128. LPSTR FileName,
  129. LPSTR SymbolPath,
  130. ULONG64 ImageBase,
  131. DWORD dwFlags
  132. )
  133. {
  134. PIMGHLP_DEBUG_DATA idd;
  135. BOOL rc = true;
  136. SetLastError(NO_ERROR);
  137. idd = InitIDD(0,
  138. hFile,
  139. FileName,
  140. SymbolPath,
  141. ImageBase,
  142. 0,
  143. NULL,
  144. 0,
  145. dwFlags);
  146. if (!idd)
  147. return NULL;
  148. rc = imgReadLoaded(idd);
  149. if (idd->error) {
  150. SetLastError(idd->error);
  151. goto error;
  152. }
  153. if (!rc)
  154. rc = imgReadFromDisk(idd);
  155. if (idd->error) {
  156. SetLastError(idd->error);
  157. goto error;
  158. }
  159. if (rc)
  160. rc = GetDebugData(idd);
  161. if (rc)
  162. return idd;
  163. error:
  164. ReleaseDebugData(idd, IMGHLP_FREE_FPO | IMGHLP_FREE_SYMPATH | IMGHLP_FREE_PDATA | IMGHLP_FREE_XDATA);
  165. return NULL;
  166. }
  167. BOOL
  168. modload(
  169. IN HANDLE hp,
  170. IN PMODULE_ENTRY mi
  171. )
  172. {
  173. IMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl;
  174. PPROCESS_ENTRY pe;
  175. ULONG i;
  176. PIMGHLP_DEBUG_DATA idd;
  177. ULONG bias;
  178. PIMAGE_SYMBOL lpSymbolEntry;
  179. PUCHAR lpStringTable;
  180. PUCHAR p;
  181. BOOL SymbolsLoaded = false;
  182. PCHAR CallbackFileName, ImageName;
  183. ULONG Size;
  184. DWORD cba;
  185. BOOL bFixLoadFailure;
  186. BOOL bFixPartialLoad;
  187. BOOL rc = true;
  188. g.LastSymLoadError = SYMLOAD_DEFERRED;
  189. SetLastError(NO_ERROR);
  190. pe = FindProcessEntry(hp);
  191. if (!pe) {
  192. SetLastError(ERROR_INVALID_HANDLE);
  193. return false;
  194. }
  195. #ifdef DEBUG
  196. if (traceSubName(mi->ModuleName)) // for setting debug breakpoints from DBGHELP_TOKEN
  197. dtrace("debug(%s)\n", mi->ModuleName);
  198. #endif
  199. if (mi->SymType == SymNone)
  200. return error(ERROR_MOD_NOT_FOUND);
  201. CallbackFileName = mi->LoadedImageName ? mi->LoadedImageName :
  202. mi->ImageName ? mi->ImageName : mi->ModuleName;
  203. if (DoSymbolCallback(pe,
  204. CBA_DEFERRED_SYMBOL_LOAD_CANCEL,
  205. mi,
  206. &idsl,
  207. CallbackFileName))
  208. {
  209. pprint(pe, "Symbol loading cancelled\n");
  210. return error(ERROR_CANCELLED);
  211. }
  212. DoSymbolCallback(pe,
  213. CBA_DEFERRED_SYMBOL_LOAD_START,
  214. mi,
  215. &idsl,
  216. CallbackFileName);
  217. ImageName = mi->ImageName;
  218. bFixLoadFailure = false;
  219. bFixPartialLoad = false;
  220. load:
  221. idd = InitIDD(
  222. hp,
  223. mi->hFile,
  224. ImageName,
  225. pe->SymbolSearchPath,
  226. mi->BaseOfDll,
  227. mi->DllSize,
  228. &mi->mld,
  229. mi->CallerFlags,
  230. 0);
  231. if (!idd)
  232. return false;
  233. // First, try to load the image from the usual sources. If we fail,
  234. // allow the caller to fix up the image information and try again.
  235. rc = imgReadLoaded(idd);
  236. if (!rc && !bFixPartialLoad) {
  237. bFixPartialLoad = true;
  238. if (DoSymbolCallback(pe,
  239. CBA_DEFERRED_SYMBOL_LOAD_PARTIAL,
  240. mi,
  241. &idsl,
  242. CallbackFileName)
  243. && idsl.Reparse)
  244. {
  245. ImageName = idsl.FileName;
  246. mi->hFile = idsl.hFile;
  247. CallbackFileName = idsl.FileName;
  248. ReleaseDebugData(idd, IMGHLP_FREE_FPO | IMGHLP_FREE_SYMPATH | IMGHLP_FREE_PDATA | IMGHLP_FREE_XDATA);
  249. goto load;
  250. }
  251. }
  252. // get info from the caller's data struct
  253. if (!rc)
  254. rc = ReadCallerData(idd);
  255. // Okay. Let's try some of the less reliable methods, like searching
  256. // for images on disk, etc.
  257. if (!rc)
  258. rc = imgReadFromDisk(idd);
  259. // Load the symbolic information into temp storage.
  260. if (rc)
  261. rc = GetDebugData(idd);
  262. mi->SymLoadError = g.LastSymLoadError;
  263. if (idd->error)
  264. SetLastError(idd->error);
  265. // Load the debug info into the module info struct.
  266. __try {
  267. EnterCriticalSection(&g.threadlock);
  268. if (rc && (rc = idd2mi(pe, idd, mi))) {
  269. DoSymbolCallback(pe,
  270. CBA_DEFERRED_SYMBOL_LOAD_COMPLETE,
  271. mi,
  272. &idsl,
  273. CallbackFileName);
  274. }
  275. } __finally {
  276. ReleaseDebugData(idd, IMGHLP_FREE_STANDARD);
  277. LeaveCriticalSection(&g.threadlock);
  278. }
  279. // If at this point, we have failed. Let's tell the caller.
  280. // Try again, if it indicates we should. Otherwise, let's fail.
  281. if (!rc && !bFixLoadFailure) {
  282. bFixLoadFailure = true;
  283. if (DoSymbolCallback(pe,
  284. CBA_DEFERRED_SYMBOL_LOAD_FAILURE,
  285. mi,
  286. &idsl,
  287. CallbackFileName)
  288. && idsl.Reparse)
  289. {
  290. ImageName = idsl.FileName;
  291. mi->hFile = idsl.hFile;
  292. CallbackFileName = idsl.FileName;
  293. goto load;
  294. }
  295. mi->SymType = SymNone;
  296. mi->Flags |= MIF_NO_SYMBOLS;
  297. rc = false;
  298. }
  299. // SymbolStatus function is expensive - call only if needed.
  300. if (option(SYMOPT_DEBUG)) {
  301. pprint(pe, "%s - %s\n",
  302. *mi->AliasName ? mi->AliasName : mi->ModuleName,
  303. SymbolStatus(mi, 9));
  304. }
  305. return rc;
  306. }
  307. DWORD64
  308. LoadModule(
  309. IN HANDLE hp,
  310. IN PSTR ImageName,
  311. IN PSTR ModuleName,
  312. IN DWORD64 BaseOfDll,
  313. IN DWORD DllSize,
  314. IN HANDLE hFile,
  315. IN PMODLOAD_DATA data,
  316. IN DWORD flags
  317. )
  318. {
  319. IMAGEHLP_DEFERRED_SYMBOL_LOAD64 idsl;
  320. PPROCESS_ENTRY pe;
  321. PMODULE_ENTRY mi;
  322. LPSTR p;
  323. DWORD64 ip;
  324. #ifdef DEBUG
  325. if (traceSubName(ImageName)) // for setting debug breakpoints from DBGHELP_TOKEN
  326. dtrace("debug(%s)\n", ImageName);
  327. #endif
  328. if (BaseOfDll == (DWORD64)-1)
  329. return 0;
  330. __try {
  331. CHAR c;
  332. if (ImageName)
  333. c = *ImageName;
  334. if (ModuleName)
  335. c = *ModuleName;
  336. } __except(EXCEPTION_EXECUTE_HANDLER) {
  337. return error(ERROR_INVALID_PARAMETER);
  338. }
  339. // It is illegal to load pdb symbols without info to set the base address
  340. if (IsPdb(ImageName) && !BaseOfDll)
  341. return error(ERROR_INVALID_PARAMETER);
  342. // start loading
  343. pe = FindProcessEntry(hp);
  344. if (!pe) {
  345. return 0;
  346. }
  347. if (BaseOfDll)
  348. mi = GetModuleForPC(pe, BaseOfDll, true);
  349. else
  350. mi = NULL;
  351. if (mi) {
  352. //
  353. // in this case the symbols are already loaded
  354. // so the caller really wants the deferred
  355. // symbols to be loaded
  356. //
  357. if ((mi->Flags & MIF_DEFERRED_LOAD) && modload(hp, mi))
  358. return mi->BaseOfDll;
  359. else
  360. return 0;
  361. }
  362. //
  363. // look to see if there is an overlapping module entry
  364. //
  365. if (BaseOfDll) {
  366. do {
  367. mi = GetModuleForPC(pe, BaseOfDll, false);
  368. if (mi) {
  369. RemoveEntryList(&mi->ListEntry);
  370. DoSymbolCallback(
  371. pe,
  372. CBA_SYMBOLS_UNLOADED,
  373. mi,
  374. &idsl,
  375. mi->LoadedImageName ? mi->LoadedImageName : mi->ImageName ? mi->ImageName : mi->ModuleName
  376. );
  377. FreeModuleEntry(pe, mi);
  378. }
  379. } while(mi);
  380. }
  381. mi = (PMODULE_ENTRY)MemAlloc(sizeof(MODULE_ENTRY));
  382. if (!mi)
  383. return 0;
  384. InitModuleEntry(mi);
  385. mi->BaseOfDll = BaseOfDll;
  386. mi->DllSize = DllSize;
  387. mi->hFile = hFile;
  388. if (ImageName) {
  389. char SplitMod[_MAX_FNAME];
  390. mi->ImageName = StringDup(ImageName);
  391. _splitpath( ImageName, NULL, NULL, SplitMod, NULL );
  392. mi->ModuleName[0] = 0;
  393. CatString(mi->ModuleName, SplitMod, sizeof(mi->ModuleName));
  394. if (ModuleName && _stricmp( ModuleName, mi->ModuleName ) != 0) {
  395. mi->AliasName[0] = 0;
  396. CatString(mi->AliasName, ModuleName, sizeof(mi->AliasName));
  397. } else {
  398. mi->AliasName[0] = 0;
  399. }
  400. } else {
  401. if (ModuleName) {
  402. mi->AliasName[0] = 0;
  403. CatString( mi->AliasName, ModuleName, sizeof(mi->AliasName));
  404. }
  405. }
  406. mi->mod = NULL;
  407. mi->cbPdbSymbols = 0;
  408. mi->pPdbSymbols = NULL;
  409. mi->CallerFlags = flags;
  410. if (data) {
  411. if (data->ssize != sizeof(MODLOAD_DATA)) {
  412. SetLastError(ERROR_INVALID_PARAMETER);
  413. return 0;
  414. }
  415. memcpy(&mi->mld, data, data->ssize);
  416. mi->CallerData = MemAlloc(mi->mld.size);
  417. if (!mi->CallerData) {
  418. SetLastError(ERROR_NOT_ENOUGH_MEMORY);
  419. return 0;
  420. }
  421. mi->mld.data = mi->CallerData;
  422. memcpy(mi->mld.data, data->data, mi->mld.size);
  423. }
  424. if (option(SYMOPT_DEFERRED_LOADS) && BaseOfDll) {
  425. mi->Flags |= MIF_DEFERRED_LOAD;
  426. mi->SymType = SymDeferred;
  427. } else if (!modload( hp, mi )) {
  428. FreeModuleEntry(pe, mi);
  429. return 0;
  430. }
  431. InsertTailList( &pe->ModuleList, &mi->ListEntry);
  432. ip = GetIP(pe);
  433. if ((mi->BaseOfDll <= ip) && (mi->BaseOfDll + DllSize >= ip))
  434. diaSetModFromIP(pe);
  435. #if 0
  436. SrcSrvLoadModule(hp,
  437. (*mi->AliasName) ? mi->AliasName : mi->ModuleName,
  438. mi->BaseOfDll,
  439. mi->stSrcSrv,
  440. mi->cbSrcSrv);
  441. #else
  442. // char sz[MAX_PATH];
  443. // SymGetSourceFile(pe->hProcess, mi->BaseOfDll, "d:\\db\\symsrv\\symstore\\symstore.cpp", sz);
  444. #endif
  445. return mi->BaseOfDll;
  446. }
  447. BOOL
  448. GetModule(
  449. HANDLE hp,
  450. LPSTR ModuleName,
  451. DWORD64 ImageBase,
  452. DWORD ImageSize,
  453. PVOID Context
  454. )
  455. {
  456. LoadModule(
  457. hp,
  458. ModuleName,
  459. NULL,
  460. ImageBase,
  461. ImageSize,
  462. NULL,
  463. 0,
  464. NULL
  465. );
  466. return true;
  467. }
  468. BOOL
  469. idd2mi(
  470. PPROCESS_ENTRY pe,
  471. PIMGHLP_DEBUG_DATA idd,
  472. PMODULE_ENTRY mi
  473. )
  474. {
  475. ULONG i;
  476. idd->flags = mi->Flags;
  477. // The following code ONLY works if the dll wasn't rebased
  478. // during install. Is it really useful?
  479. if (!mi->BaseOfDll) {
  480. //
  481. // This case occurs when modules are loaded multiple times by
  482. // name with no explicit base address.
  483. //
  484. if (GetModuleForPC( pe, idd->ImageBaseFromImage, true )) {
  485. if (idd->ImageBaseFromImage) {
  486. pprint(pe, "GetModuleForPC(%p, %I64x, true) failed\n",
  487. pe,
  488. idd->ImageBaseFromImage,
  489. true
  490. );
  491. } else {
  492. pprint(pe, "No base address for %s: Please specify\n", mi->ImageName);
  493. }
  494. diaRelease(idd->dia);
  495. return false;
  496. }
  497. mi->BaseOfDll = idd->ImageBaseFromImage;
  498. }
  499. if (!mi->DllSize) {
  500. mi->DllSize = idd->SizeOfImage;
  501. }
  502. mi->hProcess = idd->hProcess;
  503. mi->InProcImageBase = idd->InProcImageBase;
  504. mi->CheckSum = idd->CheckSum;
  505. mi->TimeDateStamp = idd->TimeDateStamp;
  506. mi->MachineType = idd->Machine;
  507. mi->ImageType = idd->ImageType;
  508. mi->PdbSrc = idd->PdbSrc;
  509. mi->ImageSrc = idd->ImageSrc;
  510. if (!mi->MachineType && g.MachineType) {
  511. mi->MachineType = (USHORT) g.MachineType;
  512. }
  513. if (idd->dia) {
  514. mi->LoadedPdbName = StringDup(idd->PdbFileName);
  515. if (!mi->LoadedPdbName)
  516. return false;
  517. }
  518. if (idd->DbgFileMap) {
  519. mi->LoadedImageName = StringDup(idd->DbgFilePath);
  520. } else if (*idd->ImageFilePath) {
  521. mi->LoadedImageName = StringDup(idd->ImageFilePath);
  522. } else if (idd->dia) {
  523. mi->LoadedImageName = StringDup(idd->PdbFileName);
  524. } else {
  525. mi->LoadedImageName = StringDup("");
  526. }
  527. if (!mi->LoadedImageName)
  528. return false;
  529. if (idd->fROM) {
  530. mi->Flags |= MIF_ROM_IMAGE;
  531. }
  532. if (!mi->ImageName) {
  533. mi->ImageName = StringDup(idd->OriginalImageFileName);
  534. if (!mi->ImageName)
  535. return false;
  536. _splitpath( mi->ImageName, NULL, NULL, mi->ModuleName, NULL );
  537. if (*mi->ImageName)
  538. mi->AliasName[0] = 0;
  539. }
  540. mi->dsExceptions = idd->dsExceptions;
  541. if (idd->cFpo) {
  542. //
  543. // use virtualalloc() because the rtf search function
  544. // return a pointer into this memory. we want to make
  545. // all of this memory read only so that callers cannot
  546. // stomp on imagehlp's data
  547. //
  548. mi->pFpoData = (PFPO_DATA)VirtualAlloc(
  549. NULL,
  550. sizeof(FPO_DATA) * idd->cFpo,
  551. MEM_COMMIT,
  552. PAGE_READWRITE
  553. );
  554. if (mi->pFpoData) {
  555. mi->dwEntries = idd->cFpo;
  556. CopyMemory(
  557. mi->pFpoData,
  558. idd->pFpo,
  559. sizeof(FPO_DATA) * mi->dwEntries
  560. );
  561. VirtualProtect(
  562. mi->pFpoData,
  563. sizeof(FPO_DATA) * mi->dwEntries,
  564. PAGE_READONLY,
  565. &i
  566. );
  567. }
  568. }
  569. // copy the pdata block from the pdb
  570. if (idd->pPData) {
  571. mi->pPData = MemAlloc(idd->cbPData);
  572. if (mi->pPData) {
  573. mi->cPData = idd->cPData;
  574. mi->cbPData = idd->cbPData;
  575. CopyMemory(mi->pPData, idd->pPData, idd->cbPData);
  576. }
  577. }
  578. if (idd->pXData) {
  579. mi->pXData = MemAlloc(idd->cbXData);
  580. if (mi->pXData) {
  581. mi->cXData = idd->cXData;
  582. mi->cbXData = idd->cbXData;
  583. CopyMemory(mi->pXData, idd->pXData, idd->cbXData);
  584. }
  585. }
  586. // now the sections
  587. mi->NumSections = idd->cCurrentSections;
  588. if (idd->fCurrentSectionsMapped) {
  589. mi->SectionHdrs = (PIMAGE_SECTION_HEADER) MemAlloc(
  590. sizeof(IMAGE_SECTION_HEADER) * mi->NumSections
  591. );
  592. if (mi->SectionHdrs) {
  593. CopyMemory(
  594. mi->SectionHdrs,
  595. idd->pCurrentSections,
  596. sizeof(IMAGE_SECTION_HEADER) * mi->NumSections
  597. );
  598. }
  599. } else {
  600. mi->SectionHdrs = idd->pCurrentSections;
  601. }
  602. if (idd->pOriginalSections) {
  603. mi->OriginalNumSections = idd->cOriginalSections;
  604. mi->OriginalSectionHdrs = idd->pOriginalSections;
  605. } else {
  606. mi->OriginalNumSections = mi->NumSections;
  607. mi->OriginalSectionHdrs = (PIMAGE_SECTION_HEADER) MemAlloc(
  608. sizeof(IMAGE_SECTION_HEADER) * mi->NumSections
  609. );
  610. if (mi->OriginalSectionHdrs) {
  611. CopyMemory(
  612. mi->OriginalSectionHdrs,
  613. idd->pCurrentSections,
  614. sizeof(IMAGE_SECTION_HEADER) * mi->NumSections
  615. );
  616. }
  617. }
  618. // symbols
  619. mi->TmpSym.Name = (LPSTR) MemAlloc( TMP_SYM_LEN );
  620. mi->vsTmpSym.Name = (LPSTR) MemAlloc( TMP_SYM_LEN );
  621. if (idd->dia) {
  622. mi->SymType = SymPdb;
  623. mi->lSymType = SymPdb;
  624. mi->loaded = true;
  625. } else {
  626. if (idd->pMappedCv) {
  627. mi->loaded = LoadCodeViewSymbols(
  628. mi->hProcess,
  629. mi,
  630. idd
  631. );
  632. }
  633. if (!mi->loaded && idd->pMappedCoff) {
  634. mi->loaded = LoadCoffSymbols(mi->hProcess, mi, idd);
  635. }
  636. if (!mi->loaded && idd->cExports) {
  637. mi->loaded = LoadExportSymbols( mi, idd );
  638. if (mi->loaded) {
  639. mi->PdbSrc = srcNone;
  640. }
  641. }
  642. if (idd->ImageType == dsVirtual) {
  643. mi->SymType = SymVirtual;
  644. mi->loaded = true;
  645. }
  646. mi->lSymType = mi->SymType;
  647. if (!mi->loaded) {
  648. mi->SymType = SymNone;
  649. if (mi->lSymType == SymDeferred)
  650. mi->lSymType = SymNone;
  651. }
  652. }
  653. mi->dia = idd->dia;
  654. mi->pdbdataSig = idd->pdbdataSig;
  655. mi->pdbdataAge = idd->pdbdataAge;
  656. memcpy(&mi->pdbdataGuid, &idd->pdbdataGuid, sizeof(GUID));
  657. if (idd->pMappedCv) {
  658. PSTR pszPdb;
  659. ULONG cbLeft;
  660. memcpy(&mi->CVRec, idd->pMappedCv, sizeof(mi->CVRec.dwSig));
  661. mi->cvSig = mi->CVRec.dwSig;
  662. if (mi->cvSig == NB10_SIG)
  663. {
  664. memcpy(&mi->CVRec, idd->pMappedCv, sizeof(mi->CVRec.nb10ih));
  665. pszPdb = (PSTR) &mi->CVRec + sizeof(mi->CVRec.nb10ih);
  666. cbLeft = sizeof(mi->CVRec) - sizeof(mi->CVRec.nb10ih);
  667. CopyString(pszPdb, (PSTR) idd->pMappedCv + sizeof(mi->CVRec.nb10ih), cbLeft);
  668. } else
  669. {
  670. memcpy(&mi->CVRec, idd->pMappedCv, sizeof(mi->CVRec.rsdsih));
  671. pszPdb = (PSTR) &mi->CVRec + sizeof(mi->CVRec.rsdsih);
  672. cbLeft = sizeof(mi->CVRec) - sizeof(mi->CVRec.rsdsih);
  673. CopyString(pszPdb, (PSTR) idd->pMappedCv + sizeof(mi->CVRec.rsdsih), cbLeft);
  674. }
  675. }
  676. mi->fTypes = idd->fTypes;
  677. mi->fLines = idd->fLines;
  678. mi->fSymbols = idd->fSymbols;
  679. mi->fTypes = idd->fTypes;
  680. mi->fPdbUnmatched = idd->fPdbUnmatched;
  681. mi->fDbgUnmatched = idd->fDbgUnmatched;
  682. ProcessOmapForModule( mi, idd );
  683. mi->Flags &= ~MIF_DEFERRED_LOAD;
  684. return true;
  685. }
  686. PIMGHLP_DEBUG_DATA
  687. InitIDD(
  688. HANDLE hProcess,
  689. HANDLE FileHandle,
  690. LPSTR FileName,
  691. LPSTR SymbolPath,
  692. ULONG64 ImageBase,
  693. DWORD SizeOfImage,
  694. PMODLOAD_DATA mld,
  695. DWORD CallerFlags,
  696. ULONG dwFlags
  697. )
  698. {
  699. PIMGHLP_DEBUG_DATA idd;
  700. int len;
  701. #ifdef DEBUG
  702. if (traceSubName(FileName)) // for setting debug breakpoints from DBGHELP_TOKEN
  703. dtrace("debug(%s)\n", FileName);
  704. #endif
  705. // No File handle and no file name. Bail
  706. if (!(CallerFlags & SLMFLAG_VIRTUAL)) {
  707. if (!FileHandle && (!FileName || !*FileName))
  708. return NULL;
  709. }
  710. SetLastError(NO_ERROR);
  711. idd = (PIMGHLP_DEBUG_DATA)MemAlloc(sizeof(IMGHLP_DEBUG_DATA));
  712. if (!idd) {
  713. SetLastError(ERROR_OUTOFMEMORY);
  714. g.LastSymLoadError = SYMLOAD_OUTOFMEMORY;
  715. return NULL;
  716. }
  717. ZeroMemory(idd, sizeof(IMGHLP_DEBUG_DATA));
  718. idd->SizeOfStruct = sizeof(IMGHLP_DEBUG_DATA);
  719. idd->md = (PMODULE_DATA)MemAlloc(sizeof(gmd));
  720. if (!idd->md) {
  721. SetLastError(ERROR_OUTOFMEMORY);
  722. g.LastSymLoadError = SYMLOAD_OUTOFMEMORY;
  723. MemFree(idd);
  724. return NULL;
  725. }
  726. memcpy(idd->md, gmd, sizeof(gmd));
  727. // store off parameters
  728. idd->pe = FindProcessEntry(hProcess);
  729. idd->flags = dwFlags;
  730. idd->ImageFileHandle = FileHandle;
  731. idd->SizeOfImage = SizeOfImage;
  732. idd->CallerFlags = CallerFlags;
  733. if (FileName)
  734. CopyStrArray(idd->ImageFilePath, FileName);
  735. __try {
  736. idd->InProcImageBase = ImageBase;
  737. idd->hProcess = hProcess;
  738. idd->mld = mld;
  739. if (FileName)
  740. CopyStrArray(idd->ImageName, FileName);
  741. if (SymbolPath) {
  742. len = strlen(SymbolPath) + 1;
  743. idd->SymbolPath = (PCHAR)MemAlloc(len);
  744. if (idd->SymbolPath)
  745. CopyString(idd->SymbolPath, SymbolPath, len);
  746. }
  747. } __except (EXCEPTION_EXECUTE_HANDLER) {
  748. if (idd) {
  749. ReleaseDebugData(idd, IMGHLP_FREE_ALL);
  750. idd = NULL;
  751. }
  752. }
  753. return idd;
  754. }
  755. typedef BOOL (WINAPI *PENUMPROCESSMODULES)(HANDLE, HMODULE *, DWORD, LPDWORD);
  756. typedef DWORD (WINAPI *PGETMODULEFILENAMEEXA)(HANDLE, HMODULE, LPSTR, DWORD);
  757. typedef BOOL (WINAPI *PGETMODULEINFORMATION)(HANDLE, HMODULE, LPMODULEINFO, DWORD);
  758. BOOL GetFileNameFromBase(HANDLE hp, ULONG64 base, char *name, DWORD cbname)
  759. {
  760. HMODULE hmods[1024];
  761. DWORD cb;
  762. unsigned int i;
  763. char modname[MAX_PATH];
  764. MODULEINFO mi;
  765. static PENUMPROCESSMODULES fnEnumProcessModules = NULL;
  766. static PGETMODULEFILENAMEEXA fnGetModuleFileNameEx = NULL;
  767. static PGETMODULEINFORMATION fnGetModuleInformation = NULL;
  768. if (!hp || hp == INVALID_HANDLE_VALUE || !base || !name || !cbname)
  769. return false;
  770. // Get the functions from psapi...
  771. if (fnEnumProcessModules == (PENUMPROCESSMODULES)-1)
  772. return false;
  773. if (!fnEnumProcessModules) {
  774. HMODULE hmod = LoadLibrary("psapi.dll");
  775. if (!hmod || hmod == INVALID_HANDLE_VALUE) {
  776. fnEnumProcessModules = (PENUMPROCESSMODULES)-1;
  777. return false;
  778. }
  779. fnEnumProcessModules = (PENUMPROCESSMODULES)GetProcAddress(hmod, "EnumProcessModules");
  780. if (!fnEnumProcessModules) {
  781. fnEnumProcessModules = (PENUMPROCESSMODULES)-1;
  782. return false;
  783. }
  784. fnGetModuleFileNameEx = (PGETMODULEFILENAMEEXA)GetProcAddress(hmod, "GetModuleFileNameExA");
  785. if (!fnGetModuleFileNameEx) {
  786. fnGetModuleFileNameEx = (PGETMODULEFILENAMEEXA)-1;
  787. return false;
  788. }
  789. fnGetModuleInformation = (PGETMODULEINFORMATION)GetProcAddress(hmod, "GetModuleInformation");
  790. if (!fnGetModuleInformation) {
  791. fnGetModuleInformation = (PGETMODULEINFORMATION)-1;
  792. return false;
  793. }
  794. }
  795. // Get a list of all the modules in this process
  796. // and the full path to each.
  797. if(fnEnumProcessModules(hp, hmods, sizeof(hmods), &cb))
  798. {
  799. for (i = 0; i < (cb / sizeof(HMODULE)); i++) {
  800. if (!fnGetModuleFileNameEx(hp, hmods[i], modname, sizeof(modname)))
  801. continue;
  802. if (!fnGetModuleInformation(hp, hmods[i], &mi, sizeof(mi)))
  803. continue;
  804. if ((ULONG64)mi.lpBaseOfDll != base)
  805. continue;
  806. CopyString(name, modname, cbname);
  807. return true;
  808. }
  809. }
  810. return false;
  811. }
  812. BOOL
  813. imgReadLoaded(
  814. PIMGHLP_DEBUG_DATA idd
  815. )
  816. {
  817. #ifdef DEBUG
  818. if (traceSubName(idd->ImageFilePath)) // for setting debug breakpoints from DBGHELP_TOKEN
  819. dtrace("debug(%s)\n", idd->ImageFilePath);
  820. #endif
  821. __try {
  822. // if this is a virtual module, we're done
  823. if (idd->CallerFlags & SLMFLAG_VIRTUAL) {
  824. idd->ImageType = dsVirtual;
  825. return true;
  826. }
  827. // if we were passed a file handle, use it
  828. if (idd->ImageFileHandle) {
  829. HANDLE fh;
  830. if (!DuplicateHandle(GetCurrentProcess(),
  831. idd->ImageFileHandle,
  832. GetCurrentProcess(),
  833. &fh,
  834. GENERIC_READ,
  835. false,
  836. DUPLICATE_SAME_ACCESS
  837. ))
  838. {
  839. return false;
  840. }
  841. GetFileNameFromBase(idd->hProcess, idd->InProcImageBase, idd->ImageFilePath, sizeof(idd->ImageFilePath));
  842. idd->ImageFileHandle = fh;
  843. idd->ImageSrc = srcHandle;
  844. if (ReadHeader(idd, dsImage))
  845. return true;
  846. }
  847. // if we have a base pointer into process memory. See what we can get here.
  848. if (idd->InProcImageBase) {
  849. if (ReadHeader(idd, dsInProc)) {
  850. idd->ImageSrc = srcMemory;
  851. return true;
  852. }
  853. }
  854. return false;
  855. } __except (EXCEPTION_EXECUTE_HANDLER) {
  856. return false;
  857. }
  858. return true;
  859. }
  860. BOOL
  861. imgReadFromDisk(
  862. PIMGHLP_DEBUG_DATA idd
  863. )
  864. /*
  865. Given:
  866. ImageFileHandle - Map the thing. The only time FileHandle s/b non-null
  867. is if we're given an image handle. If this is not
  868. true, ignore the handle.
  869. !ImageFileHandle - Use the filename and search for first the image name,
  870. then the .dbg file, and finally a .pdb file.
  871. dwFlags: NO_PE64_IMAGES - Return failure if only image is PE64.
  872. Used to implement MapDebugInformation()
  873. */
  874. {
  875. int len;
  876. // If the file name is a pdb, let's just store it and move on.
  877. if (IsPdb(idd->ImageFilePath)) {
  878. CopyStrArray(idd->PdbFileName, idd->ImageFilePath);
  879. return true;
  880. }
  881. // Let's look for the image on disk.
  882. if (!option(SYMOPT_NO_IMAGE_SEARCH)) {
  883. // otherwise use the file name to open the disk image
  884. // only if we didn't have access to in-proc headers
  885. pprint(idd->pe, "No header for %s. Searching for image on disk\n", idd->ImageName);
  886. idd->ImageFileHandle = FindExecutableImageEx(idd->ImageName,
  887. idd->SymbolPath,
  888. idd->ImageFilePath,
  889. cbFindExe,
  890. idd);
  891. if (idd->ImageFileHandle) {
  892. if (!idd->SizeOfImage)
  893. GetFileSize(idd->ImageFileHandle, &idd->SizeOfImage);
  894. ReadHeader(idd, dsImage);
  895. }
  896. }
  897. return true;
  898. }
  899. BOOL
  900. NoSymbols(
  901. PIMGHLP_DEBUG_DATA idd
  902. )
  903. {
  904. return (!*idd->PdbFileName && !idd->pMappedCoff && !idd->pMappedCv);
  905. }
  906. BOOL
  907. GetDebugData(
  908. PIMGHLP_DEBUG_DATA idd
  909. )
  910. {
  911. char dbgfile[MAX_PATH + 1];
  912. BOOL rc;
  913. // If this is a virtual module, we are done.
  914. if (idd->ImageType == dsVirtual)
  915. return true;
  916. *dbgfile = 0;
  917. // Now we look for dbg files on all stripped images and unread headers.
  918. if (idd->Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
  919. if (*idd->OriginalDbgFileName)
  920. CopyStrArray(dbgfile, idd->OriginalDbgFileName);
  921. else
  922. CopyStrArray(dbgfile, idd->ImageName);
  923. pprint(idd->pe, "%s is stripped. Searching for dbg file\n", dbgfile);
  924. } else if (!option(SYMOPT_EXACT_SYMBOLS) || option(SYMOPT_LOAD_ANYTHING)) {
  925. if (NoSymbols(idd)) {
  926. CopyStrArray(dbgfile, idd->ImageName);
  927. if (!idd->Characteristics)
  928. pprint(idd->pe, "No header for %s. Searching for dbg file\n", dbgfile);
  929. else
  930. pprint(idd->pe, "No debug info for %s. Searching for dbg file\n", dbgfile);
  931. }
  932. }
  933. if (*dbgfile) {
  934. idd->DbgFileHandle = FindDebugInfoFileEx(
  935. dbgfile,
  936. idd->SymbolPath,
  937. idd->DbgFilePath,
  938. cbFindDbg,
  939. idd);
  940. if (!idd->DbgFileHandle)
  941. g.LastSymLoadError = SYMLOAD_DBGNOTFOUND;
  942. else
  943. ReadHeader(idd, dsDbg);
  944. }
  945. // We don't have an image, dbg, or pdb. Let's just look for any old PDB.
  946. if (NoSymbols(idd) && (!option(SYMOPT_EXACT_SYMBOLS) || option(SYMOPT_LOAD_ANYTHING)))
  947. {
  948. if (FakePdbName(idd))
  949. pprint(idd->pe, "%s missing debug info. Searching for pdb anyway\n", idd->ImageName);
  950. }
  951. // Get codeview information, either from pdb or within the image.
  952. if (*idd->PdbFileName) {
  953. rc = diaGetPdb(idd);
  954. if (!rc && IsPdb(idd->ImageFilePath))
  955. return false;
  956. } else if (idd->pMappedCv)
  957. ProcessCvForOmap(idd);
  958. return true;
  959. }
  960. PIMGHLP_DEBUG_DATA
  961. InitDebugData(
  962. VOID
  963. )
  964. {
  965. PIMGHLP_DEBUG_DATA idd;
  966. idd = (PIMGHLP_DEBUG_DATA)MemAlloc(sizeof(IMGHLP_DEBUG_DATA));
  967. if (!idd) {
  968. SetLastError(ERROR_OUTOFMEMORY);
  969. g.LastSymLoadError = SYMLOAD_OUTOFMEMORY;
  970. return NULL;
  971. }
  972. ZeroMemory(idd, sizeof(IMGHLP_DEBUG_DATA));
  973. idd->md = (PMODULE_DATA)MemAlloc(sizeof(gmd));
  974. if (!idd->md) {
  975. SetLastError(ERROR_OUTOFMEMORY);
  976. g.LastSymLoadError = SYMLOAD_OUTOFMEMORY;
  977. MemFree(idd);
  978. return NULL;
  979. }
  980. memcpy(idd->md, gmd, sizeof(gmd));
  981. return idd;
  982. }
  983. void
  984. ReleaseDebugData(
  985. PIMGHLP_DEBUG_DATA idd,
  986. DWORD dwFlags
  987. )
  988. {
  989. if (!idd)
  990. return;
  991. if (idd->ImageMap) {
  992. UnmapViewOfFile(idd->ImageMap);
  993. }
  994. if (idd->ImageFileHandle) {
  995. CloseHandle(idd->ImageFileHandle);
  996. }
  997. if (idd->DbgFileMap) {
  998. UnmapViewOfFile(idd->DbgFileMap);
  999. }
  1000. if (idd->DbgFileHandle) {
  1001. CloseHandle(idd->DbgFileHandle);
  1002. }
  1003. if ((dwFlags & IMGHLP_FREE_FPO) &&
  1004. idd->pFpo &&
  1005. !idd->fFpoMapped
  1006. )
  1007. {
  1008. MemFree(idd->pFpo);
  1009. }
  1010. if ((dwFlags & IMGHLP_FREE_PDATA) &&
  1011. idd->pPData &&
  1012. !idd->fPDataMapped
  1013. )
  1014. {
  1015. MemFree(idd->pPData);
  1016. }
  1017. if ((dwFlags & IMGHLP_FREE_XDATA) &&
  1018. idd->pXData &&
  1019. !idd->fXDataMapped
  1020. )
  1021. {
  1022. MemFree(idd->pXData);
  1023. }
  1024. if ((dwFlags & IMGHLP_FREE_PDATA) &&
  1025. idd->pMappedCoff &&
  1026. !idd->fCoffMapped
  1027. )
  1028. {
  1029. MemFree(idd->pMappedCoff);
  1030. }
  1031. if ((dwFlags & IMGHLP_FREE_PDATA) &&
  1032. idd->pMappedCv &&
  1033. !idd->fCvMapped
  1034. )
  1035. {
  1036. MemFree(idd->pMappedCv);
  1037. }
  1038. if ((dwFlags & IMGHLP_FREE_OMAPT)
  1039. && idd->pOmapTo
  1040. && !idd->fOmapToMapped)
  1041. {
  1042. MemFree(idd->pOmapTo);
  1043. }
  1044. if ((dwFlags & IMGHLP_FREE_OMAPF)
  1045. && idd->pOmapFrom
  1046. && !idd->fOmapFromMapped)
  1047. {
  1048. MemFree(idd->pOmapFrom);
  1049. }
  1050. if ((dwFlags & IMGHLP_FREE_OSECT) &&
  1051. idd->pOriginalSections
  1052. )
  1053. {
  1054. MemFree(idd->pOriginalSections);
  1055. }
  1056. if ((dwFlags & IMGHLP_FREE_CSECT) &&
  1057. idd->pCurrentSections &&
  1058. !idd->fCurrentSectionsMapped
  1059. )
  1060. {
  1061. MemFree(idd->pCurrentSections);
  1062. }
  1063. if (idd->SymbolPath) {
  1064. MemFree(idd->SymbolPath);
  1065. }
  1066. MemFree(idd->md);
  1067. MemFree(idd);
  1068. return;
  1069. }
  1070. BOOL
  1071. ExtMatch(
  1072. char *fname,
  1073. char *ext
  1074. )
  1075. {
  1076. char fext[_MAX_EXT + 1];
  1077. if (!fname)
  1078. return false;
  1079. _splitpath(fname, NULL, NULL, NULL, fext);
  1080. if (_strcmpi(fext, ext))
  1081. return false;
  1082. return true;
  1083. }
  1084. BOOL
  1085. ReadHeader(
  1086. PIMGHLP_DEBUG_DATA idd,
  1087. DWORD datasrc
  1088. )
  1089. {
  1090. BOOL status;
  1091. ULONG cb;
  1092. IMAGE_DOS_HEADER dh;
  1093. IMAGE_NT_HEADERS32 nh32;
  1094. IMAGE_NT_HEADERS64 nh64;
  1095. PIMAGE_ROM_OPTIONAL_HEADER rom = NULL;
  1096. IMAGE_SEPARATE_DEBUG_HEADER sdh;
  1097. PIMAGE_FILE_HEADER fh;
  1098. PIMAGE_DEBUG_MISC md;
  1099. ULONG ddva;
  1100. ULONG shva;
  1101. ULONG nSections;
  1102. PIMAGE_SECTION_HEADER psh;
  1103. IMAGE_DEBUG_DIRECTORY dd;
  1104. PIMAGE_DATA_DIRECTORY datadir;
  1105. PCHAR pCV;
  1106. ULONG i;
  1107. int nDebugDirs = 0;
  1108. HANDLE hp;
  1109. ULONG64 base;
  1110. IMAGE_ROM_HEADERS ROMImage;
  1111. DWORD rva;
  1112. PCHAR filepath;
  1113. IMAGE_EXPORT_DIRECTORY expdir;
  1114. DWORD fsize;
  1115. BOOL rc;
  1116. USHORT filetype;
  1117. #ifdef DO_NBO9
  1118. ULONG hdrsig;
  1119. char cvsig[5];
  1120. char cvsig2[5];
  1121. long cvpos;
  1122. #endif
  1123. // setup pointers for grabing data
  1124. switch (datasrc) {
  1125. case dsInProc:
  1126. hp = idd->hProcess;
  1127. base = idd->InProcImageBase;
  1128. fsize = 0;
  1129. filepath = idd->ImageFilePath;
  1130. idd->PdbSrc = srcCVRec;
  1131. break;
  1132. case dsImage:
  1133. hp = NULL;
  1134. idd->ImageMap = MapItRO(idd->ImageFileHandle);
  1135. base = (ULONG64)idd->ImageMap;
  1136. fsize = GetFileSize(idd->ImageFileHandle, NULL);
  1137. filepath = idd->ImageFilePath;
  1138. idd->PdbSrc = srcImagePath;
  1139. break;
  1140. case dsDbg:
  1141. hp = NULL;
  1142. idd->DbgFileMap = MapItRO(idd->DbgFileHandle);
  1143. base = (ULONG64)idd->DbgFileMap;
  1144. fsize = GetFileSize(idd->DbgFileHandle, NULL);
  1145. filepath = idd->DbgFilePath;
  1146. idd->PdbSrc = srcDbgPath;
  1147. break;
  1148. default:
  1149. return false;
  1150. }
  1151. // some initialization
  1152. idd->fNeedImage = false;
  1153. rc = false;
  1154. ddva = 0;
  1155. __try {
  1156. // test the file type
  1157. status = ReadImageData(hp, base, 0, &filetype, sizeof(filetype));
  1158. if (!status) {
  1159. g.LastSymLoadError = SYMLOAD_HEADERPAGEDOUT;
  1160. return false;
  1161. }
  1162. idd->ImageType = datasrc;
  1163. if (filetype == IMAGE_SEPARATE_DEBUG_SIGNATURE)
  1164. goto dbg;
  1165. if (filetype == IMAGE_DOS_SIGNATURE)
  1166. {
  1167. // grab the dos header
  1168. status = ReadImageData(hp, base, 0, &dh, sizeof(dh));
  1169. if (!status) {
  1170. g.LastSymLoadError = SYMLOAD_HEADERPAGEDOUT;
  1171. return false;
  1172. }
  1173. #ifdef DO_NB09
  1174. // test 16 bit image...
  1175. if (idd->SizeOfImage) {
  1176. ZeroMemory(cvsig, 5);
  1177. ZeroMemory(cvsig2, 5);
  1178. cvpos = 0;
  1179. status = ReadImageData(hp, base, idd->SizeOfImage - 8, cvsig, 4);
  1180. status = ReadImageData(hp, base, idd->SizeOfImage - 4, &cvpos, sizeof(cvpos));
  1181. status = ReadImageData(hp, base, idd->SizeOfImage - cvpos, cvsig2, 4);
  1182. if (*cvsig && !strcmp(cvsig, cvsig2)) {
  1183. pCV = (PCHAR)MemAlloc(cvpos);
  1184. if (!pCV)
  1185. return false;
  1186. status = ReadImageData(hp, base, idd->SizeOfImage - cvpos, pCV, cvpos);
  1187. idd->pMappedCv = (PCHAR)pCV;
  1188. idd->cMappedCv = cvpos;
  1189. return true;
  1190. }
  1191. }
  1192. #endif
  1193. // grab the pe header
  1194. #ifdef DO_NB09
  1195. status = ReadImageData(hp, base, dh.e_lfanew, &hdrsig, sizeof(hdrsig));
  1196. if (!status) {
  1197. g.LastSymLoadError = SYMLOAD_HEADERPAGEDOUT;
  1198. return false;
  1199. }
  1200. #endif
  1201. status = ReadImageData(hp, base, dh.e_lfanew, &nh32, sizeof(nh32));
  1202. if (!status) {
  1203. g.LastSymLoadError = SYMLOAD_HEADERPAGEDOUT;
  1204. return false;
  1205. }
  1206. // read header info
  1207. if (nh32.Signature != IMAGE_NT_SIGNATURE) {
  1208. // if header is not NT sig, this is a ROM image
  1209. rom = (PIMAGE_ROM_OPTIONAL_HEADER)&nh32.OptionalHeader;
  1210. fh = &nh32.FileHeader;
  1211. shva = dh.e_lfanew + sizeof(DWORD) +
  1212. sizeof(IMAGE_FILE_HEADER) + fh->SizeOfOptionalHeader;
  1213. }
  1214. } else if (filetype == IMAGE_FILE_MACHINE_I386) {
  1215. // This is an X86 ROM image
  1216. status = ReadImageData(hp, base, 0, &nh32.FileHeader, sizeof(nh32.FileHeader)+sizeof(nh32.OptionalHeader));
  1217. if (!status)
  1218. return false;
  1219. nh32.Signature = 'ROM ';
  1220. } else {
  1221. // This may be a ROM image
  1222. status = ReadImageData(hp, base, 0, &ROMImage, sizeof(ROMImage));
  1223. if (!status) {
  1224. g.LastSymLoadError = SYMLOAD_HEADERPAGEDOUT;
  1225. return false;
  1226. }
  1227. if ((ROMImage.FileHeader.Machine == IMAGE_FILE_MACHINE_I386) ||
  1228. (ROMImage.FileHeader.Machine == IMAGE_FILE_MACHINE_ALPHA) ||
  1229. (ROMImage.FileHeader.Machine == IMAGE_FILE_MACHINE_ALPHA64))
  1230. {
  1231. rom = (PIMAGE_ROM_OPTIONAL_HEADER)&ROMImage.OptionalHeader;
  1232. fh = &ROMImage.FileHeader;
  1233. shva = sizeof(IMAGE_FILE_HEADER) + fh->SizeOfOptionalHeader;
  1234. } else {
  1235. return false;
  1236. }
  1237. }
  1238. if (rom) {
  1239. if (rom->Magic == IMAGE_ROM_OPTIONAL_HDR_MAGIC) {
  1240. idd->fROM = true;
  1241. idd->iohMagic = rom->Magic;
  1242. idd->ImageBaseFromImage = rom->BaseOfCode;
  1243. idd->SizeOfImage = rom->SizeOfCode;
  1244. idd->CheckSum = 0;
  1245. } else {
  1246. idd->error = ERROR_BAD_FORMAT;
  1247. return false;
  1248. }
  1249. } else {
  1250. // otherwise, get info from appropriate header type for 32 or 64 bit
  1251. if (IsImageMachineType64(nh32.FileHeader.Machine)) {
  1252. // Reread the header as a 64bit header.
  1253. status = ReadImageData(hp, base, dh.e_lfanew, &nh64, sizeof(nh64));
  1254. if (!status) {
  1255. g.LastSymLoadError = SYMLOAD_HEADERPAGEDOUT;
  1256. return false;
  1257. }
  1258. fh = &nh64.FileHeader;
  1259. datadir = nh64.OptionalHeader.DataDirectory;
  1260. shva = dh.e_lfanew + sizeof(nh64);
  1261. idd->iohMagic = nh64.OptionalHeader.Magic;
  1262. idd->fPE64 = true; // seems to be unused
  1263. if (datasrc == dsImage || datasrc == dsInProc) {
  1264. idd->ImageBaseFromImage = nh64.OptionalHeader.ImageBase;
  1265. idd->ImageAlign = nh64.OptionalHeader.SectionAlignment;
  1266. idd->CheckSum = nh64.OptionalHeader.CheckSum;
  1267. }
  1268. idd->SizeOfImage = nh64.OptionalHeader.SizeOfImage;
  1269. }
  1270. else {
  1271. fh = &nh32.FileHeader;
  1272. datadir = nh32.OptionalHeader.DataDirectory;
  1273. idd->iohMagic = nh32.OptionalHeader.Magic;
  1274. if (nh32.Signature == 'ROM ') {
  1275. shva = sizeof(nh32.FileHeader)+sizeof(nh32.OptionalHeader);
  1276. } else {
  1277. shva = dh.e_lfanew + sizeof(nh32);
  1278. }
  1279. if (datasrc == dsImage || datasrc == dsInProc) {
  1280. idd->ImageBaseFromImage = nh32.OptionalHeader.ImageBase;
  1281. idd->ImageAlign = nh32.OptionalHeader.SectionAlignment;
  1282. idd->CheckSum = nh32.OptionalHeader.CheckSum;
  1283. }
  1284. idd->SizeOfImage = nh32.OptionalHeader.SizeOfImage;
  1285. }
  1286. }
  1287. imgset(idd->md, mdHeader, datasrc, datasrc);
  1288. // read the section headers
  1289. nSections = fh->NumberOfSections;
  1290. psh = (PIMAGE_SECTION_HEADER) MemAlloc(nSections * sizeof(IMAGE_SECTION_HEADER));
  1291. if (!psh)
  1292. goto debugdirs;
  1293. status = ReadImageData(hp, base, shva, psh, nSections * sizeof(IMAGE_SECTION_HEADER));
  1294. if (!status)
  1295. goto debugdirs;
  1296. // store off info to return struct
  1297. idd->pCurrentSections = psh;
  1298. idd->cCurrentSections = nSections;
  1299. idd->pImageSections = psh;
  1300. idd->cImageSections = nSections;
  1301. idd->Machine = fh->Machine;
  1302. idd->TimeDateStamp = fh->TimeDateStamp;
  1303. idd->Characteristics = fh->Characteristics;
  1304. imgset(idd->md, mdSecHdrs, datasrc, datasrc);
  1305. // get information from the sections
  1306. for (i = 0; i < nSections; i++, psh++) {
  1307. DWORD offset;
  1308. if (idd->fROM &&
  1309. ((fh->Characteristics & IMAGE_FILE_DEBUG_STRIPPED) == 0) &&
  1310. (!strcmp((LPSTR)psh->Name, ".rdata")))
  1311. {
  1312. nDebugDirs = 1;
  1313. ddva = psh->VirtualAddress;
  1314. break;
  1315. }
  1316. if (offset = SectionContains(hp, psh, &datadir[IMAGE_DIRECTORY_ENTRY_EXPORT]))
  1317. {
  1318. idd->dsExports = datasrc;
  1319. idd->cExports = datadir[IMAGE_DIRECTORY_ENTRY_EXPORT].Size;
  1320. idd->oExports = offset;
  1321. ReadImageData(hp, base, offset, &idd->expdir, sizeof(idd->expdir));
  1322. }
  1323. if (offset = SectionContains(hp, psh, &datadir[IMAGE_DIRECTORY_ENTRY_DEBUG]))
  1324. {
  1325. ddva = offset;
  1326. nDebugDirs = datadir[IMAGE_DIRECTORY_ENTRY_DEBUG].Size / sizeof(IMAGE_DEBUG_DIRECTORY);
  1327. }
  1328. }
  1329. goto debugdirs;
  1330. dbg:
  1331. // grab the dbg header
  1332. status = ReadImageData(hp, base, 0, &sdh, sizeof(sdh));
  1333. if (!status)
  1334. return false;
  1335. // Only support .dbg files for X86 and Alpha (32 bit).
  1336. if ((sdh.Machine != IMAGE_FILE_MACHINE_I386)
  1337. && (sdh.Machine != IMAGE_FILE_MACHINE_ALPHA))
  1338. {
  1339. UnmapViewOfFile(idd->DbgFileMap);
  1340. idd->DbgFileMap = 0;
  1341. return false;
  1342. }
  1343. idd->ImageAlign = sdh.SectionAlignment;
  1344. idd->CheckSum = sdh.CheckSum;
  1345. idd->Machine = sdh.Machine;
  1346. idd->TimeDateStamp = sdh.TimeDateStamp;
  1347. idd->Characteristics = sdh.Characteristics;
  1348. if (!idd->ImageBaseFromImage) {
  1349. idd->ImageBaseFromImage = sdh.ImageBase;
  1350. }
  1351. if (!idd->SizeOfImage) {
  1352. idd->SizeOfImage = sdh.SizeOfImage;
  1353. }
  1354. nSections = sdh.NumberOfSections;
  1355. psh = (PIMAGE_SECTION_HEADER) MemAlloc(nSections * sizeof(IMAGE_SECTION_HEADER));
  1356. if (!psh)
  1357. goto debugdirs;
  1358. status = ReadImageData(hp,
  1359. base,
  1360. sizeof(IMAGE_SEPARATE_DEBUG_HEADER),
  1361. psh,
  1362. nSections * sizeof(IMAGE_SECTION_HEADER));
  1363. if (!status)
  1364. goto debugdirs;
  1365. idd->pCurrentSections = psh;
  1366. idd->cCurrentSections = nSections;
  1367. idd->pDbgSections = psh;
  1368. idd->cDbgSections = nSections;
  1369. // idd->ExportedNamesSize = sdh.ExportedNamesSize;
  1370. if (sdh.DebugDirectorySize) {
  1371. nDebugDirs = (int)(sdh.DebugDirectorySize / sizeof(IMAGE_DEBUG_DIRECTORY));
  1372. ddva = sizeof(IMAGE_SEPARATE_DEBUG_HEADER)
  1373. + (sdh.NumberOfSections * sizeof(IMAGE_SECTION_HEADER))
  1374. + sdh.ExportedNamesSize;
  1375. }
  1376. debugdirs:
  1377. rc = true;
  1378. // copy the virtual addr of the debug directories over for MapDebugInformation
  1379. if (datasrc == dsImage) {
  1380. idd->ddva = ddva;
  1381. idd->cdd = nDebugDirs;
  1382. }
  1383. // read the debug directories
  1384. while (nDebugDirs) {
  1385. status = ReadImageData(hp, base, (ULONG_PTR)ddva, &dd, sizeof(dd));
  1386. if (!status)
  1387. return false;
  1388. if (!dd.SizeOfData)
  1389. goto nextdebugdir;
  1390. // indicate that we found the debug directory
  1391. imgset(idd->md, dd.Type, datasrc, dsNone);
  1392. // these debug directories are processed both in-proc and from file
  1393. switch (dd.Type)
  1394. {
  1395. case IMAGE_DEBUG_TYPE_CODEVIEW:
  1396. // get info on pdb file
  1397. if (hp) { // in-proc image
  1398. if (!dd.AddressOfRawData)
  1399. return false;
  1400. if (!(pCV = (PCHAR)MemAlloc(dd.SizeOfData)))
  1401. break;
  1402. status = ReadImageData(hp, base, dd.AddressOfRawData, pCV, dd.SizeOfData);
  1403. if (!status) {
  1404. MemFree(pCV);
  1405. return false;
  1406. }
  1407. } else { // file-base image
  1408. if (dd.PointerToRawData >= fsize)
  1409. break;
  1410. pCV = (PCHAR)base + dd.PointerToRawData;
  1411. idd->fCvMapped = true;
  1412. }
  1413. idd->pMappedCv = (PCHAR)pCV;
  1414. idd->cMappedCv = dd.SizeOfData;
  1415. idd->dsCV = datasrc;
  1416. RetrievePdbInfo(idd);
  1417. imgset(idd->md, dd.Type, dsNone, datasrc);
  1418. break;
  1419. case IMAGE_DEBUG_TYPE_MISC:
  1420. // on stripped files, find the dbg file
  1421. // on dbg file, find the original file name
  1422. if (dd.PointerToRawData < fsize) {
  1423. md = (PIMAGE_DEBUG_MISC)((PCHAR)base + dd.PointerToRawData);
  1424. if (md->DataType != IMAGE_DEBUG_MISC_EXENAME)
  1425. break;
  1426. if (datasrc == dsDbg) {
  1427. if (!*idd->OriginalImageFileName)
  1428. CopyStrArray(idd->OriginalImageFileName, (LPSTR)md->Data);
  1429. break;
  1430. }
  1431. if (fh->Characteristics & IMAGE_FILE_DEBUG_STRIPPED) {
  1432. CopyStrArray(idd->OriginalDbgFileName, (LPSTR)md->Data);
  1433. idd->DbgTimeDateStamp = dd.TimeDateStamp;
  1434. } else {
  1435. CopyStrArray(idd->OriginalImageFileName, (LPSTR)md->Data);
  1436. }
  1437. }
  1438. imgset(idd->md, dd.Type, dsNone, datasrc);
  1439. break;
  1440. case IMAGE_DEBUG_TYPE_COFF:
  1441. if (dd.PointerToRawData < fsize) {
  1442. // idd->fNeedImage = true;
  1443. idd->pMappedCoff = (PCHAR)base + dd.PointerToRawData;
  1444. idd->cMappedCoff = dd.SizeOfData;
  1445. idd->fCoffMapped = true;
  1446. idd->dsCoff = datasrc;
  1447. imgset(idd->md, dd.Type, dsNone, datasrc);
  1448. } else {
  1449. idd->fNeedImage = true;
  1450. }
  1451. break;
  1452. }
  1453. // these debug directories are only processed for disk-based images
  1454. if (dd.PointerToRawData < fsize) {
  1455. switch (dd.Type)
  1456. {
  1457. case IMAGE_DEBUG_TYPE_FPO:
  1458. idd->pFpo = (PCHAR)base + dd.PointerToRawData;
  1459. idd->cFpo = dd.SizeOfData / SIZEOF_RFPO_DATA;
  1460. idd->fFpoMapped = true;
  1461. idd->dsFPO = datasrc;
  1462. imgset(idd->md, dd.Type, dsNone, datasrc);
  1463. break;
  1464. case IMAGE_DEBUG_TYPE_OMAP_TO_SRC:
  1465. idd->pOmapTo = (POMAP)((PCHAR)base + dd.PointerToRawData);
  1466. idd->cOmapTo = dd.SizeOfData / sizeof(OMAP);
  1467. idd->fOmapToMapped = true;
  1468. idd->dsOmapTo = datasrc;
  1469. imgset(idd->md, dd.Type, dsNone, datasrc);
  1470. break;
  1471. case IMAGE_DEBUG_TYPE_OMAP_FROM_SRC:
  1472. idd->pOmapFrom = (POMAP)((PCHAR)base + dd.PointerToRawData);
  1473. idd->cOmapFrom = dd.SizeOfData / sizeof(OMAP);
  1474. idd->fOmapFromMapped = true;
  1475. idd->dsOmapFrom = datasrc;
  1476. imgset(idd->md, dd.Type, dsNone, datasrc);
  1477. break;
  1478. case IMAGE_DEBUG_TYPE_EXCEPTION:
  1479. idd->dsExceptions = datasrc;
  1480. imgset(idd->md, dd.Type, dsNone, datasrc);
  1481. break;
  1482. }
  1483. }
  1484. nextdebugdir:
  1485. ddva += sizeof(IMAGE_DEBUG_DIRECTORY);
  1486. nDebugDirs--;
  1487. }
  1488. } __except (EXCEPTION_EXECUTE_HANDLER) {
  1489. // We might have gotten enough information
  1490. // to be okay. So don't indicate error.
  1491. }
  1492. return rc;
  1493. }
  1494. BOOL
  1495. ReadCallerData(
  1496. PIMGHLP_DEBUG_DATA idd
  1497. )
  1498. {
  1499. PMODLOAD_DATA mld = idd->mld;
  1500. PIMAGE_DEBUG_DIRECTORY dd;
  1501. PCHAR pCV;
  1502. DWORD cdd;
  1503. DWORD i;
  1504. if (!mld)
  1505. return false;
  1506. if (!mld->ssize
  1507. || !mld->size
  1508. || !mld->data)
  1509. return false;
  1510. switch (mld->ssig)
  1511. {
  1512. case DBHHEADER_DEBUGDIRS:
  1513. cdd = mld->size / sizeof(IMAGE_DEBUG_DIRECTORY);
  1514. dd = (PIMAGE_DEBUG_DIRECTORY)mld->data;
  1515. for (i = 0; i < cdd; i++, dd++) {
  1516. if (dd->Type != IMAGE_DEBUG_TYPE_CODEVIEW)
  1517. continue;
  1518. pCV = (PCHAR)mld->data + dd->PointerToRawData;
  1519. idd->fCvMapped = true;
  1520. idd->pMappedCv = (PCHAR)pCV;
  1521. idd->cMappedCv = dd->SizeOfData;
  1522. idd->dsCV = dsCallerData;
  1523. idd->PdbSignature = 0;
  1524. idd->PdbAge = 0;
  1525. RetrievePdbInfo(idd);
  1526. imgset(idd->md, dd->Type, dsNone, dsCallerData);
  1527. break;
  1528. }
  1529. return true;
  1530. }
  1531. return false;
  1532. }
  1533. BOOL
  1534. cbFindExe(
  1535. HANDLE FileHandle,
  1536. PSTR FileName,
  1537. PVOID CallerData
  1538. )
  1539. {
  1540. PIMGHLP_DEBUG_DATA idd;
  1541. PIMAGE_FILE_HEADER FileHeader = NULL;
  1542. PVOID ImageMap = NULL;
  1543. BOOL rc;
  1544. if (!CallerData)
  1545. return true;
  1546. idd = (PIMGHLP_DEBUG_DATA)CallerData;
  1547. if (!idd->TimeDateStamp)
  1548. return true;
  1549. // Crack the image and let's see what we're working with
  1550. ImageMap = MapItRO(FileHandle);
  1551. if (!ImageMap)
  1552. return true;
  1553. // Check the first word. We're either looking at a normal PE32/PE64 image, or it's
  1554. // a ROM image (no DOS stub) or it's a random file.
  1555. switch (*(PUSHORT)ImageMap) {
  1556. case IMAGE_FILE_MACHINE_I386:
  1557. // Must be an X86 ROM image (ie: ntldr)
  1558. FileHeader = &((PIMAGE_ROM_HEADERS)ImageMap)->FileHeader;
  1559. // Make sure
  1560. if (!(FileHeader->SizeOfOptionalHeader == sizeof(IMAGE_OPTIONAL_HEADER32) &&
  1561. idd->iohMagic == IMAGE_NT_OPTIONAL_HDR32_MAGIC))
  1562. {
  1563. FileHeader = NULL;
  1564. }
  1565. break;
  1566. case IMAGE_FILE_MACHINE_ALPHA:
  1567. case IMAGE_FILE_MACHINE_ALPHA64:
  1568. case IMAGE_FILE_MACHINE_IA64:
  1569. case IMAGE_FILE_MACHINE_AMD64:
  1570. // Should be an Alpha/IA64 ROM image (ie: osloader.exe)
  1571. FileHeader = &((PIMAGE_ROM_HEADERS)ImageMap)->FileHeader;
  1572. // Make sure
  1573. if (!(FileHeader->SizeOfOptionalHeader == sizeof(IMAGE_ROM_OPTIONAL_HEADER) &&
  1574. idd->iohMagic == IMAGE_ROM_OPTIONAL_HDR_MAGIC))
  1575. {
  1576. FileHeader = NULL;
  1577. }
  1578. break;
  1579. case IMAGE_DOS_SIGNATURE:
  1580. {
  1581. PIMAGE_NT_HEADERS NtHeaders = ImageNtHeader(ImageMap);
  1582. if (NtHeaders) {
  1583. FileHeader = &NtHeaders->FileHeader;
  1584. }
  1585. }
  1586. break;
  1587. default:
  1588. break;
  1589. }
  1590. // default return is a match
  1591. rc = true;
  1592. // compare timestamps
  1593. if (FileHeader && FileHeader->TimeDateStamp != idd->TimeDateStamp)
  1594. rc = false;
  1595. idd->ImageSrc = srcSearchPath;
  1596. // cleanup
  1597. if (ImageMap)
  1598. UnmapViewOfFile(ImageMap);
  1599. return rc;
  1600. }
  1601. BOOL
  1602. cbFindDbg(
  1603. HANDLE FileHandle,
  1604. PSTR FileName,
  1605. PVOID CallerData
  1606. )
  1607. {
  1608. PIMGHLP_DEBUG_DATA idd;
  1609. PIMAGE_SEPARATE_DEBUG_HEADER DbgHeader;
  1610. PVOID FileMap;
  1611. BOOL rc;
  1612. rc = true;
  1613. if (!CallerData)
  1614. return true;
  1615. idd = (PIMGHLP_DEBUG_DATA)CallerData;
  1616. FileMap = MapItRO(FileHandle);
  1617. if (!FileMap) {
  1618. return false;
  1619. }
  1620. DbgHeader = (PIMAGE_SEPARATE_DEBUG_HEADER)FileMap;
  1621. // Only support .dbg files for X86 and Alpha (32 bit).
  1622. if ((DbgHeader->Signature != IMAGE_SEPARATE_DEBUG_SIGNATURE) ||
  1623. ((DbgHeader->Machine != IMAGE_FILE_MACHINE_I386) &&
  1624. (DbgHeader->Machine != IMAGE_FILE_MACHINE_ALPHA)))
  1625. {
  1626. rc = false;
  1627. goto cleanup;
  1628. }
  1629. if (idd->DbgTimeDateStamp)
  1630. rc = (idd->DbgTimeDateStamp == DbgHeader->TimeDateStamp) ? true : false;
  1631. if (!rc && idd->TimeDateStamp)
  1632. rc = (idd->TimeDateStamp == DbgHeader->TimeDateStamp) ? true : false;
  1633. cleanup:
  1634. if (FileMap)
  1635. UnmapViewOfFile(FileMap);
  1636. return rc;
  1637. }
  1638. BOOL
  1639. ProcessCvForOmap(
  1640. PIMGHLP_DEBUG_DATA idd
  1641. )
  1642. {
  1643. OMFSignature *omfSig;
  1644. OMFDirHeader *omfDirHdr;
  1645. OMFDirEntry *omfDirEntry;
  1646. OMFSegMap *omfSegMap;
  1647. OMFSegMapDesc *omfSegMapDesc;
  1648. DWORD i, j, k, SectionSize;
  1649. DWORD SectionStart;
  1650. PIMAGE_SECTION_HEADER Section;
  1651. if (idd->cOmapFrom) {
  1652. // If there's omap, we need to generate the original section map
  1653. omfSig = (OMFSignature *)idd->pMappedCv;
  1654. omfDirHdr = (OMFDirHeader*) ((PCHAR)idd->pMappedCv + (DWORD)omfSig->filepos);
  1655. omfDirEntry = (OMFDirEntry*) ((PCHAR)omfDirHdr + sizeof(OMFDirHeader));
  1656. if (!omfDirHdr->cDir) {
  1657. idd->cOmapFrom = 0;
  1658. idd->cOmapTo = 0;
  1659. }
  1660. for (i=0; i<omfDirHdr->cDir; i++,omfDirEntry++) {
  1661. if (omfDirEntry->SubSection == sstSegMap) {
  1662. omfSegMap = (OMFSegMap*) ((PCHAR)idd->pMappedCv + omfDirEntry->lfo);
  1663. omfSegMapDesc = (OMFSegMapDesc*)&omfSegMap->rgDesc[0];
  1664. SectionStart = *(DWORD *)idd->pOmapFrom;
  1665. SectionSize = 0;
  1666. Section = (PIMAGE_SECTION_HEADER) MemAlloc(omfSegMap->cSeg * sizeof(IMAGE_SECTION_HEADER));
  1667. if (Section) {
  1668. for (j=0, k=0; j < omfSegMap->cSeg; j++) {
  1669. if (omfSegMapDesc[j].frame) {
  1670. // The linker sets the frame field to the actual section header number. Zero is
  1671. // used to track absolute symbols that don't exist in a real sections.
  1672. Section[k].VirtualAddress =
  1673. SectionStart =
  1674. SectionStart + ((SectionSize + (idd->ImageAlign-1)) & ~(idd->ImageAlign-1));
  1675. Section[k].Misc.VirtualSize =
  1676. SectionSize = omfSegMapDesc[j].cbSeg;
  1677. k++;
  1678. }
  1679. }
  1680. idd->pOriginalSections = Section;
  1681. idd->cOriginalSections = k;
  1682. }
  1683. }
  1684. }
  1685. }
  1686. return true;
  1687. }
  1688. __inline
  1689. DWORD
  1690. SectionContains (
  1691. HANDLE hp,
  1692. PIMAGE_SECTION_HEADER pSH,
  1693. PIMAGE_DATA_DIRECTORY ddir
  1694. )
  1695. {
  1696. DWORD rva = 0;
  1697. if (!ddir->VirtualAddress)
  1698. return 0;
  1699. if (ddir->VirtualAddress >= pSH->VirtualAddress) {
  1700. if ((ddir->VirtualAddress + ddir->Size) <= (pSH->VirtualAddress + pSH->SizeOfRawData)) {
  1701. rva = ddir->VirtualAddress;
  1702. if (!hp)
  1703. rva = rva - pSH->VirtualAddress + pSH->PointerToRawData;
  1704. }
  1705. }
  1706. return rva;
  1707. }
  1708. void
  1709. RetrievePdbInfo(
  1710. PIMGHLP_DEBUG_DATA idd
  1711. )
  1712. {
  1713. CHAR szRefDrive[_MAX_DRIVE];
  1714. CHAR szRefPath[_MAX_DIR];
  1715. PCVDD pcv = (PCVDD)idd->pMappedCv;
  1716. if (idd->PdbSignature)
  1717. return;
  1718. switch (pcv->dwSig)
  1719. {
  1720. case '01BN':
  1721. idd->PdbAge = pcv->nb10i.age;
  1722. idd->PdbSignature = pcv->nb10i.sig;
  1723. CopyStrArray(idd->PdbFileName, pcv->nb10i.szPdb);
  1724. break;
  1725. case 'SDSR':
  1726. idd->PdbRSDS = true;
  1727. idd->PdbAge = pcv->rsdsi.age;
  1728. memcpy(&idd->PdbGUID, &pcv->rsdsi.guidSig, sizeof(GUID));
  1729. CopyStrArray(idd->PdbFileName, pcv->rsdsi.szPdb);
  1730. break;
  1731. default:
  1732. return;
  1733. }
  1734. // XXX: get rid of this variable
  1735. CopyStrArray(idd->PdbReferencePath, "");
  1736. }
  1737. DWORD
  1738. imgset(
  1739. PMODULE_DATA md,
  1740. DWORD id,
  1741. DWORD hint,
  1742. DWORD src
  1743. )
  1744. {
  1745. DWORD i;
  1746. for (i = 0; i < NUM_MODULE_DATA_ENTRIES; md++, i++) {
  1747. if (md->id == id) {
  1748. if (hint != dsNone)
  1749. md->hint = hint;
  1750. if (src != dsNone)
  1751. md->src = src;
  1752. return i;
  1753. }
  1754. }
  1755. return 0;
  1756. }
  1757. BOOL
  1758. FakePdbName(
  1759. PIMGHLP_DEBUG_DATA idd
  1760. )
  1761. {
  1762. CHAR szName[_MAX_FNAME];
  1763. // nothing to do
  1764. if (*idd->PdbFileName)
  1765. return false;
  1766. if (idd->PdbSignature)
  1767. return false;
  1768. // nothing to work with
  1769. if (!idd->ImageName)
  1770. return false;
  1771. // generate pdb name from image
  1772. _splitpath(idd->ImageName, NULL, NULL, szName, NULL);
  1773. if (!*szName)
  1774. return false;
  1775. CopyStrArray(idd->PdbFileName, szName);
  1776. CatStrArray(idd->PdbFileName, ".pdb");
  1777. return true;
  1778. }
  1779. BOOL
  1780. IsImageMachineType64(
  1781. DWORD MachineType
  1782. )
  1783. {
  1784. switch(MachineType) {
  1785. case IMAGE_FILE_MACHINE_AXP64:
  1786. case IMAGE_FILE_MACHINE_IA64:
  1787. case IMAGE_FILE_MACHINE_AMD64:
  1788. return true;
  1789. default:
  1790. return false;
  1791. }
  1792. }
  1793. ULONG
  1794. ReadImageData(
  1795. IN HANDLE hprocess,
  1796. IN ULONG64 ul,
  1797. IN ULONG64 addr,
  1798. OUT LPVOID buffer,
  1799. IN ULONG size
  1800. )
  1801. {
  1802. ULONG bytesread;
  1803. if (hprocess) {
  1804. ULONG64 base = ul;
  1805. BOOL rc;
  1806. rc = ReadInProcMemory(hprocess,
  1807. base + addr,
  1808. buffer,
  1809. size,
  1810. &bytesread);
  1811. if (!rc || (bytesread < (ULONG)size))
  1812. return 0;
  1813. } else {
  1814. PCHAR p = (PCHAR)ul + addr;
  1815. memcpy(buffer, p, size);
  1816. }
  1817. return size;
  1818. }
  1819. PVOID
  1820. MapItRO(
  1821. HANDLE FileHandle
  1822. )
  1823. {
  1824. PVOID MappedBase = NULL;
  1825. if (FileHandle) {
  1826. HANDLE MappingHandle = CreateFileMapping( FileHandle, NULL, PAGE_READONLY, 0, 0, NULL );
  1827. if (MappingHandle) {
  1828. MappedBase = MapViewOfFile( MappingHandle, FILE_MAP_READ, 0, 0, 0 );
  1829. CloseHandle(MappingHandle);
  1830. }
  1831. }
  1832. return MappedBase;
  1833. }