Source code of Windows XP (NT5)
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.

3196 lines
84 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Abstraction of target-specific information.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2001.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. //
  10. // Note by olegk
  11. // We using KLDR_DATA_TABLE_ENTRY64 in some places like
  12. // GetModNameFromLoaderList) instead of LDR_DATA_TABLE_ENTRY assuming that
  13. // most important fields are the same in these structures.
  14. // So I add some asserts for quick notification if anything will change
  15. // (these are not fullproof checks just a basics)
  16. //
  17. C_ASSERT(&(((PLDR_DATA_TABLE_ENTRY64)0)->InLoadOrderLinks) ==
  18. &(((PKLDR_DATA_TABLE_ENTRY64)0)->InLoadOrderLinks));
  19. C_ASSERT(&(((PLDR_DATA_TABLE_ENTRY64)0)->DllBase) ==
  20. &(((PKLDR_DATA_TABLE_ENTRY64)0)->DllBase));
  21. C_ASSERT(&(((PLDR_DATA_TABLE_ENTRY64)0)->FullDllName) ==
  22. &(((PKLDR_DATA_TABLE_ENTRY64)0)->FullDllName));
  23. DBGKD_GET_VERSION64 g_KdVersion;
  24. PCSTR g_NtSverNames[] =
  25. {
  26. "Windows NT 4", "Windows 2000 RC3", "Windows 2000", "Windows XP",
  27. };
  28. PCSTR g_W9xSverNames[] =
  29. {
  30. "Windows 95", "Windows 98", "Windows 98 SE", "Windows ME",
  31. };
  32. PCSTR g_XBoxSverNames[] =
  33. {
  34. "XBox",
  35. };
  36. PCSTR g_BigSverNames[] =
  37. {
  38. "BIG KD Emulation",
  39. };
  40. PCSTR g_ExdiSverNames[] =
  41. {
  42. "eXDI Device",
  43. };
  44. PCSTR g_NtBdSverNames[] =
  45. {
  46. "Windows Boot Debugger",
  47. };
  48. PCSTR g_EfiSverNames[] =
  49. {
  50. "EFI KD Emulation",
  51. };
  52. //----------------------------------------------------------------------------
  53. //
  54. // Support functions.
  55. //
  56. //----------------------------------------------------------------------------
  57. ULONG
  58. NtBuildToSystemVersion(ULONG Build)
  59. {
  60. if (Build > 2195)
  61. {
  62. return NT_SVER_W2K_WHISTLER;
  63. }
  64. else if (Build > 2183)
  65. {
  66. return NT_SVER_W2K;
  67. }
  68. else if (Build > 1381)
  69. {
  70. return NT_SVER_W2K_RC3;
  71. }
  72. else
  73. {
  74. return NT_SVER_NT4;
  75. }
  76. }
  77. // Taken from http://kbinternal/kb/articles/q158/2/38.htm
  78. //
  79. // Release Version File dates
  80. // ---------------------------------------------------------------------
  81. // Windows 95 retail, OEM 4.00.950 7/11/95
  82. // Windows 95 retail SP1 4.00.950A 7/11/95
  83. // OEM Service Release 1 4.00.950A 7/11/95
  84. // OEM Service Release 2 4.00.1111* (4.00.950B) 8/24/96
  85. // OEM Service Release 2.1 4.03.1212-1214* (4.00.950B) 8/24/96-8/27/97
  86. // OEM Service Release 2.5 4.03.1214* (4.00.950C) 8/24/96-11/18/97
  87. // Windows 98 retail, OEM 4.10.1998 5/11/98
  88. // Windows 98 Second Edition 4.10.2222A 4/23/99
  89. ULONG
  90. Win9xBuildToSystemVersion(ULONG Build)
  91. {
  92. if (Build > 2222)
  93. {
  94. return W9X_SVER_WME;
  95. }
  96. else if (Build > 1998)
  97. {
  98. return W9X_SVER_W98SE;
  99. }
  100. else if (Build > 950)
  101. {
  102. return W9X_SVER_W98;
  103. }
  104. else
  105. {
  106. return W9X_SVER_W95;
  107. }
  108. }
  109. void
  110. SetTargetSystemVersionAndBuild(ULONG Build, ULONG PlatformId)
  111. {
  112. if (PlatformId == VER_PLATFORM_WIN32_NT)
  113. {
  114. g_ActualSystemVersion = NtBuildToSystemVersion(Build);
  115. g_SystemVersion = g_ActualSystemVersion;
  116. }
  117. else
  118. {
  119. // Win9x puts the major and minor versions in the high word
  120. // of the build number so mask them off.
  121. Build &= 0xffff;
  122. g_ActualSystemVersion = Win9xBuildToSystemVersion(Build);
  123. // Win98SE was the first Win9x version to support
  124. // the extended registers thread context flag.
  125. if (g_ActualSystemVersion >= W9X_SVER_W98SE)
  126. {
  127. g_SystemVersion = NT_SVER_W2K;
  128. }
  129. else
  130. {
  131. g_SystemVersion = NT_SVER_NT4;
  132. }
  133. }
  134. g_TargetBuildNumber = Build;
  135. }
  136. PCSTR
  137. SystemVersionName(ULONG Sver)
  138. {
  139. if (Sver > NT_SVER_START && Sver < NT_SVER_END)
  140. {
  141. return g_NtSverNames[Sver - NT_SVER_START - 1];
  142. }
  143. else if (Sver > W9X_SVER_START && Sver < W9X_SVER_END)
  144. {
  145. return g_W9xSverNames[Sver - W9X_SVER_START - 1];
  146. }
  147. else if (Sver > XBOX_SVER_START && Sver < XBOX_SVER_END)
  148. {
  149. return g_XBoxSverNames[Sver - XBOX_SVER_START - 1];
  150. }
  151. else if (Sver > BIG_SVER_START && Sver < BIG_SVER_END)
  152. {
  153. return g_BigSverNames[Sver - BIG_SVER_START - 1];
  154. }
  155. else if (Sver > EXDI_SVER_START && Sver < EXDI_SVER_END)
  156. {
  157. return g_ExdiSverNames[Sver - EXDI_SVER_START - 1];
  158. }
  159. else if (Sver > NTBD_SVER_START && Sver < NTBD_SVER_END)
  160. {
  161. return g_NtBdSverNames[Sver - NTBD_SVER_START - 1];
  162. }
  163. else if (Sver > EFI_SVER_START && Sver < EFI_SVER_END)
  164. {
  165. return g_EfiSverNames[Sver - EFI_SVER_START - 1];
  166. }
  167. return "Unknown System";
  168. }
  169. BOOL
  170. GetUserModuleListAddress(
  171. MachineInfo* Machine,
  172. ULONG64 Peb,
  173. BOOL Quiet,
  174. PULONG64 OrderModuleListStart,
  175. PULONG64 FirstEntry
  176. )
  177. {
  178. ULONG64 PebLdrOffset;
  179. ULONG64 ModuleListOffset;
  180. ULONG64 PebAddr;
  181. ULONG64 PebLdr = 0;
  182. *OrderModuleListStart = 0;
  183. *FirstEntry = 0;
  184. //
  185. // Triage dumps have no user mode information.
  186. // User-mode minidumps don't have a loader list.
  187. //
  188. if (IS_KERNEL_TRIAGE_DUMP() || IS_USER_MINI_DUMP())
  189. {
  190. return FALSE;
  191. }
  192. if (Machine->m_Ptr64)
  193. {
  194. PebLdrOffset = PEBLDR_FROM_PEB64;
  195. ModuleListOffset = MODULE_LIST_FROM_PEBLDR64;
  196. }
  197. else
  198. {
  199. PebLdrOffset = PEBLDR_FROM_PEB32;
  200. ModuleListOffset = MODULE_LIST_FROM_PEBLDR32;
  201. }
  202. if (!Peb)
  203. {
  204. if (GetImplicitProcessDataPeb(&Peb) != S_OK)
  205. {
  206. if (!Quiet)
  207. {
  208. ErrOut("Unable to read KPROCESS\n");
  209. }
  210. return FALSE;
  211. }
  212. if ( (Peb == 0) )
  213. {
  214. // This is a common error as the system process has no
  215. // user address space.
  216. if (!Quiet)
  217. {
  218. ErrOut("Unable to retrieve the PEB address. "
  219. "This is usually caused\n");
  220. ErrOut("by being in the wrong process context or by paging\n");
  221. }
  222. return FALSE;
  223. }
  224. }
  225. //
  226. // Read address the PEB Ldr data from the PEB structure
  227. //
  228. Peb += PebLdrOffset;
  229. if ( (g_Target->ReadPointer(Machine, Peb, &PebLdr) != S_OK) ||
  230. (PebLdr == 0) )
  231. {
  232. if (!Quiet)
  233. {
  234. ErrOut("PPEB_LDR_DATA is NULL (Peb = %s)\n",
  235. FormatMachineAddr64(Machine, Peb));
  236. ErrOut("This is usually caused by being in the wrong process\n");
  237. ErrOut("context or by paging\n");
  238. }
  239. return FALSE;
  240. }
  241. //
  242. // Read address of the user mode module list from the PEB Ldr Data.
  243. //
  244. PebLdr += ModuleListOffset;
  245. *OrderModuleListStart = PebLdr;
  246. if ( (g_Target->ReadPointer(Machine, PebLdr, FirstEntry) != S_OK) ||
  247. (*FirstEntry == 0) )
  248. {
  249. if (!Quiet)
  250. {
  251. ErrOut("UserMode Module List Address is NULL (Addr= %s)\n",
  252. FormatMachineAddr64(Machine, PebLdr));
  253. ErrOut("This is usually caused by being in the wrong process\n");
  254. ErrOut("context or by paging\n");
  255. }
  256. return FALSE;
  257. }
  258. return TRUE;
  259. }
  260. BOOL
  261. GetModNameFromLoaderList(
  262. MachineInfo* Machine,
  263. ULONG64 Peb,
  264. ULONG64 ModuleBase,
  265. PSTR NameBuffer,
  266. ULONG BufferSize,
  267. BOOL FullPath
  268. )
  269. {
  270. ULONG64 ModList;
  271. ULONG64 List;
  272. HRESULT Status;
  273. KLDR_DATA_TABLE_ENTRY64 Entry;
  274. WCHAR UnicodeBuffer[MAX_IMAGE_PATH];
  275. ULONG Read;
  276. if (!GetUserModuleListAddress(Machine, Peb, TRUE, &ModList, &List))
  277. {
  278. return FALSE;
  279. }
  280. while (List != ModList)
  281. {
  282. Status = g_Target->ReadLoaderEntry(Machine, List, &Entry);
  283. if (Status != S_OK)
  284. {
  285. ErrOut("Unable to read LDR_DATA_TABLE_ENTRY at %s - %s\n",
  286. FormatMachineAddr64(Machine, List),
  287. FormatStatusCode(Status));
  288. return FALSE;
  289. }
  290. List = Entry.InLoadOrderLinks.Flink;
  291. if (Entry.DllBase == ModuleBase)
  292. {
  293. UNICODE_STRING64 Name;
  294. //
  295. // We found a matching entry. Try to get the name.
  296. //
  297. if (FullPath)
  298. {
  299. Name = Entry.FullDllName;
  300. }
  301. else
  302. {
  303. Name = Entry.BaseDllName;
  304. }
  305. if (Name.Length == 0 ||
  306. Name.Buffer == 0 ||
  307. Name.Length >= sizeof(UnicodeBuffer) - sizeof(WCHAR))
  308. {
  309. return FALSE;
  310. }
  311. Status = g_Target->ReadVirtual(Name.Buffer, UnicodeBuffer,
  312. Name.Length, &Read);
  313. if (Status != S_OK || Read < Name.Length)
  314. {
  315. ErrOut("Unable to read name string at %s - %s\n",
  316. FormatMachineAddr64(Machine, Name.Buffer),
  317. FormatStatusCode(Status));
  318. return FALSE;
  319. }
  320. UnicodeBuffer[Name.Length / sizeof(WCHAR)] = UNICODE_NULL;
  321. if (!WideCharToMultiByte(CP_ACP, 0, UnicodeBuffer,
  322. Name.Length / sizeof(WCHAR) + 1,
  323. NameBuffer, BufferSize,
  324. NULL, NULL))
  325. {
  326. ErrOut("Unable to convert Unicode string %ls to ANSI\n",
  327. UnicodeBuffer);
  328. return FALSE;
  329. }
  330. return TRUE;
  331. }
  332. }
  333. return FALSE;
  334. }
  335. void
  336. SetTargetNtCsdVersion(ULONG CsdVersion)
  337. {
  338. g_TargetServicePackNumber = CsdVersion;
  339. if (CsdVersion == 0)
  340. {
  341. g_TargetServicePackString[0] = 0;
  342. return;
  343. }
  344. PSTR Str = g_TargetServicePackString;
  345. *Str = 0;
  346. if (CsdVersion & 0xFFFF)
  347. {
  348. sprintf(Str, "Service Pack %u", (CsdVersion & 0xFF00) >> 8);
  349. Str += strlen(Str);
  350. if (CsdVersion & 0xFF)
  351. {
  352. *Str++ = 'A' + (char)(CsdVersion & 0xFF) - 1;
  353. *Str = 0;
  354. }
  355. }
  356. if (CsdVersion & 0xFFFF0000)
  357. {
  358. if (CsdVersion & 0xFFFF)
  359. {
  360. strcpy(Str, ", ");
  361. Str += strlen(Str);
  362. }
  363. sprintf(Str, "RC %u", (CsdVersion >> 24) & 0xFF);
  364. Str += strlen(Str);
  365. if (CsdVersion & 0x00FF0000)
  366. {
  367. sprintf(Str, ".%u", (CsdVersion >> 16) & 0xFF);
  368. Str += strlen(Str);
  369. }
  370. }
  371. }
  372. //----------------------------------------------------------------------------
  373. //
  374. // Module list abstraction.
  375. //
  376. //----------------------------------------------------------------------------
  377. void
  378. ModuleInfo::ReadImageHeaderInfo(PMODULE_INFO_ENTRY Entry)
  379. {
  380. HRESULT Status;
  381. UCHAR SectorBuffer[ 512 ];
  382. PIMAGE_NT_HEADERS64 NtHeaders;
  383. ULONG Result;
  384. if (Entry->ImageInfoValid)
  385. {
  386. return;
  387. }
  388. //
  389. // For live debugging of both user mode and kernel mode, we have
  390. // to go load the checksum timestamp directly out of the image header
  391. // because someone decided to overwrite these fields in the OS
  392. // module list - Argh !
  393. //
  394. Entry->CheckSum = UNKNOWN_CHECKSUM;
  395. Entry->TimeDateStamp = UNKNOWN_TIMESTAMP;
  396. Status = g_Target->ReadVirtual(Entry->Base, SectorBuffer,
  397. sizeof(SectorBuffer), &Result);
  398. if (Status == S_OK && Result >= sizeof(SectorBuffer))
  399. {
  400. NtHeaders = (PIMAGE_NT_HEADERS64)ImageNtHeader(SectorBuffer);
  401. if (NtHeaders != NULL)
  402. {
  403. switch (NtHeaders->OptionalHeader.Magic)
  404. {
  405. case IMAGE_NT_OPTIONAL_HDR32_MAGIC:
  406. Entry->CheckSum = ((PIMAGE_NT_HEADERS32)NtHeaders)->
  407. OptionalHeader.CheckSum;
  408. Entry->Size = ((PIMAGE_NT_HEADERS32)NtHeaders)->
  409. OptionalHeader.SizeOfImage;
  410. Entry->SizeOfCode = ((PIMAGE_NT_HEADERS32)NtHeaders)->
  411. OptionalHeader.SizeOfCode;
  412. Entry->SizeOfData = ((PIMAGE_NT_HEADERS32)NtHeaders)->
  413. OptionalHeader.SizeOfInitializedData;
  414. break;
  415. case IMAGE_NT_OPTIONAL_HDR64_MAGIC:
  416. Entry->CheckSum = NtHeaders->OptionalHeader.CheckSum;
  417. Entry->Size = NtHeaders->OptionalHeader.SizeOfImage;
  418. Entry->SizeOfCode = NtHeaders->OptionalHeader.SizeOfCode;
  419. Entry->SizeOfData =
  420. NtHeaders->OptionalHeader.SizeOfInitializedData;
  421. break;
  422. }
  423. Entry->TimeDateStamp = NtHeaders->FileHeader.TimeDateStamp;
  424. Entry->ImageInfoValid = 1;
  425. }
  426. }
  427. }
  428. HRESULT
  429. NtModuleInfo::GetEntry(PMODULE_INFO_ENTRY Entry)
  430. {
  431. HRESULT Status;
  432. ULONG Result = 0;
  433. ULONG Length;
  434. ULONG64 Buffer;
  435. if (m_Cur == m_Head)
  436. {
  437. return S_FALSE;
  438. }
  439. KLDR_DATA_TABLE_ENTRY64 LdrEntry;
  440. Status = g_Target->ReadLoaderEntry(m_Machine, m_Cur, &LdrEntry);
  441. if (Status != S_OK)
  442. {
  443. ErrOut("Unable to read KLDR_DATA_TABLE_ENTRY at %s - %s\n",
  444. FormatAddr64(m_Cur), FormatStatusCode(Status));
  445. return Status;
  446. }
  447. m_Cur = LdrEntry.InLoadOrderLinks.Flink;
  448. //
  449. // Get the image path if possible, otherwise
  450. // just use the image base name.
  451. //
  452. Entry->NamePtr = NULL;
  453. Entry->NameLength = 0;
  454. Length = (ULONG)(ULONG_PTR) LdrEntry.FullDllName.Length;
  455. Buffer = LdrEntry.FullDllName.Buffer;
  456. // In the NT4 dumps that we have the long name may
  457. // point to valid memory but the memory content is
  458. // rarely the correct name, so just don't bother
  459. // trying to read the long name on NT4.
  460. if (g_SystemVersion >= NT_SVER_W2K &&
  461. Length != 0 && Buffer != 0 &&
  462. Length < (MAX_IMAGE_PATH * sizeof(WCHAR)))
  463. {
  464. Status = g_Target->ReadVirtual(Buffer,
  465. Entry->Buffer,
  466. Length,
  467. &Result);
  468. if (Status != S_OK || (Result < Length))
  469. {
  470. // Make this a verbose message since it's possible the
  471. // name is simply paged out.
  472. VerbOut("Unable to read NT module Full Name string at %s - %s\n",
  473. FormatAddr64(Buffer), FormatStatusCode(Status));
  474. Result = 0;
  475. }
  476. }
  477. if (!Result)
  478. {
  479. Length = (ULONG)(ULONG_PTR) LdrEntry.BaseDllName.Length;
  480. Buffer = LdrEntry.BaseDllName.Buffer;
  481. if (Length != 0 && Buffer != 0 &&
  482. Length < (MAX_IMAGE_PATH * sizeof(WCHAR)))
  483. {
  484. Status = g_Target->ReadVirtual(Buffer,
  485. Entry->Buffer,
  486. Length,
  487. &Result);
  488. if (Status != S_OK || (Result < Length))
  489. {
  490. WarnOut("Unable to read NT module Base Name "
  491. "string at %s - %s\n",
  492. FormatAddr64(Buffer), FormatStatusCode(Status));
  493. Result = 0;
  494. }
  495. }
  496. }
  497. if (!Result)
  498. {
  499. // We did not get any name - just return.
  500. return S_OK;
  501. }
  502. *(PWCHAR)(Entry->Buffer + Length) = UNICODE_NULL;
  503. Entry->NamePtr = &(Entry->Buffer[0]);
  504. Entry->NameLength = Length;
  505. Entry->UnicodeNamePtr = 1;
  506. Entry->Base = LdrEntry.DllBase;
  507. Entry->Size = LdrEntry.SizeOfImage;
  508. Entry->CheckSum = LdrEntry.CheckSum;
  509. Entry->TimeDateStamp = LdrEntry.TimeDateStamp;
  510. //
  511. // Update the image informaion, such as timestamp and real image size,
  512. // Directly from the image header
  513. //
  514. ReadImageHeaderInfo(Entry);
  515. //
  516. // For newer NT builds, we also have an alternate entry in the
  517. // LdrDataTable to store image information in case the actual header
  518. // is paged out. We do this for session space images only right now.
  519. //
  520. if (LdrEntry.Flags & LDRP_NON_PAGED_DEBUG_INFO)
  521. {
  522. NON_PAGED_DEBUG_INFO di;
  523. Status = g_Target->ReadVirtual(LdrEntry.NonPagedDebugInfo,
  524. &di,
  525. sizeof(di), // Only read the base struct
  526. &Result);
  527. if (Status != S_OK || (Result < sizeof(di)))
  528. {
  529. WarnOut("Unable to read NonPagedDebugInfo at %s - %s\n",
  530. FormatAddr64(LdrEntry.NonPagedDebugInfo),
  531. FormatStatusCode(Status));
  532. return S_OK;
  533. }
  534. Entry->TimeDateStamp = di.TimeDateStamp;
  535. Entry->CheckSum = di.CheckSum;
  536. Entry->Size = di.SizeOfImage;
  537. Entry->ImageInfoPartial = 1;
  538. Entry->ImageInfoValid = 1;
  539. if (di.Flags == 1)
  540. {
  541. Entry->DebugHeader = malloc(di.Size - sizeof(di));
  542. if (Entry->DebugHeader)
  543. {
  544. Status = g_Target->ReadVirtual(LdrEntry.NonPagedDebugInfo +
  545. sizeof(di),
  546. Entry->DebugHeader,
  547. di.Size - sizeof(di),
  548. &Result);
  549. if (Status != S_OK || (Result < di.Size - sizeof(di)))
  550. {
  551. WarnOut("Unable to read NonPagedDebugInfo data at %s - %s\n",
  552. FormatAddr64(LdrEntry.NonPagedDebugInfo + sizeof(di)),
  553. FormatStatusCode(Status));
  554. return S_OK;
  555. }
  556. Entry->ImageDebugHeader = 1;
  557. Entry->SizeOfDebugHeader = di.Size - sizeof(di);
  558. }
  559. }
  560. }
  561. return S_OK;
  562. }
  563. HRESULT
  564. NtKernelModuleInfo::Initialize(void)
  565. {
  566. HRESULT Status;
  567. LIST_ENTRY64 List64;
  568. m_Machine = g_TargetMachine;
  569. if ((m_Head = KdDebuggerData.PsLoadedModuleList) == 0)
  570. {
  571. //
  572. // This field is ALWAYS set in NT 5 targets.
  573. //
  574. // We will only fail here if someone changed the debugger code
  575. // and did not "make up" this structure properly for NT 4 or
  576. // dump targets..
  577. //
  578. ErrOut("Module List address is NULL - "
  579. "debugger not initialized properly.\n");
  580. return E_FAIL;
  581. }
  582. Status = g_Target->ReadListEntry(m_Machine, m_Head, &List64);
  583. //
  584. // In live debug sessions, the debugger connects before Mm creates
  585. // the actual module list.
  586. // If we are this early on, try to load symbols from the loader
  587. // block module list (NT 6). Otherwise, just fail and we will
  588. // get called back later by the ntoskrnl.exe module load call.
  589. //
  590. // For dumps, (not user mode or triage) the data should always
  591. // be initialized.
  592. //
  593. if ( (Status == S_OK) && (List64.Flink) )
  594. {
  595. m_Cur = List64.Flink;
  596. }
  597. else
  598. {
  599. dprintf("PsLoadedModuleList not initialized yet. "
  600. "Delay kernel load.\n");
  601. return S_FALSE;
  602. }
  603. return S_OK;
  604. }
  605. NtKernelModuleInfo g_NtKernelModuleIterator;
  606. HRESULT
  607. NtUserModuleInfo::Initialize(void)
  608. {
  609. return GetUserModuleListAddress(m_Machine, m_Peb, FALSE, &m_Head, &m_Cur) ?
  610. S_OK : S_FALSE;
  611. }
  612. HRESULT
  613. NtTargetUserModuleInfo::Initialize(void)
  614. {
  615. m_Machine = g_TargetMachine;
  616. m_Peb = 0;
  617. return NtUserModuleInfo::Initialize();
  618. }
  619. NtTargetUserModuleInfo g_NtTargetUserModuleIterator;
  620. HRESULT
  621. NtWow64UserModuleInfo::Initialize(void)
  622. {
  623. HRESULT Status;
  624. if (g_TargetMachine->m_NumExecTypes < 2)
  625. {
  626. return E_UNEXPECTED;
  627. }
  628. m_Machine = MachineTypeInfo(g_TargetMachine->m_ExecTypes[1]);
  629. if ((Status = GetPeb32(&m_Peb)) != S_OK)
  630. {
  631. return Status;
  632. }
  633. return NtUserModuleInfo::Initialize();
  634. }
  635. HRESULT
  636. NtWow64UserModuleInfo::GetPeb32(PULONG64 Peb32)
  637. {
  638. ULONG64 Teb;
  639. ULONG64 Teb32;
  640. ULONG Result;
  641. HRESULT Status;
  642. if ((Status = GetImplicitThreadDataTeb(&Teb)) == S_OK)
  643. {
  644. if ((Status = g_Target->ReadPointer(g_TargetMachine,
  645. Teb, &Teb32)) == S_OK)
  646. {
  647. if (!Teb32)
  648. {
  649. return E_UNEXPECTED;
  650. }
  651. ULONG RawPeb32;
  652. Status = g_Target->
  653. ReadAllVirtual(Teb32 + PEB_FROM_TEB32, &RawPeb32,
  654. sizeof(RawPeb32));
  655. if (Status != S_OK)
  656. {
  657. ErrOut("Cannot read PEB32 from WOW64 TEB32 %s - %s\n",
  658. FormatAddr64(Teb32), FormatStatusCode(Status));
  659. return Status;
  660. }
  661. *Peb32 = EXTEND64(RawPeb32);
  662. }
  663. }
  664. return Status;
  665. }
  666. NtWow64UserModuleInfo g_NtWow64UserModuleIterator;
  667. HRESULT
  668. DebuggerModuleInfo::Initialize(void)
  669. {
  670. m_Image = g_CurrentProcess->ImageHead;
  671. return S_OK;
  672. }
  673. HRESULT
  674. DebuggerModuleInfo::GetEntry(PMODULE_INFO_ENTRY Entry)
  675. {
  676. if (m_Image == NULL)
  677. {
  678. return S_FALSE;
  679. }
  680. Entry->NamePtr = m_Image->ImagePath;
  681. Entry->UnicodeNamePtr = 0;
  682. Entry->ModuleName = m_Image->ModuleName;
  683. Entry->File = m_Image->File;
  684. Entry->Base = m_Image->BaseOfImage;
  685. Entry->Size = m_Image->SizeOfImage;
  686. Entry->CheckSum = m_Image->CheckSum;
  687. Entry->TimeDateStamp = m_Image->TimeDateStamp;
  688. Entry->ImageInfoValid = 1;
  689. m_Image = m_Image->Next;
  690. return S_OK;
  691. }
  692. DebuggerModuleInfo g_DebuggerModuleIterator;
  693. HRESULT
  694. NtKernelUnloadedModuleInfo::Initialize(void)
  695. {
  696. if (KdDebuggerData.MmUnloadedDrivers == 0 ||
  697. KdDebuggerData.MmLastUnloadedDriver == 0)
  698. {
  699. return E_FAIL;
  700. }
  701. // If this is the initial module load we need to be
  702. // careful because much of the system isn't initialized
  703. // yet. Some versions of the OS can crash when scanning
  704. // the unloaded module list, plus at this point we can
  705. // safely assume there are no unloaded modules, so just
  706. // don't enumerate anything.
  707. if (g_EngStatus & ENG_STATUS_AT_INITIAL_MODULE_LOAD)
  708. {
  709. return E_FAIL;
  710. }
  711. HRESULT Status;
  712. ULONG Read;
  713. if ((Status = g_Target->ReadPointer(g_TargetMachine,
  714. KdDebuggerData.MmUnloadedDrivers,
  715. &m_Base)) != S_OK ||
  716. (Status = g_Target->ReadVirtual(KdDebuggerData.MmLastUnloadedDriver,
  717. &m_Index, sizeof(m_Index),
  718. &Read)) != S_OK)
  719. {
  720. return Status;
  721. }
  722. if (Read != sizeof(m_Index))
  723. {
  724. return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
  725. }
  726. m_Count = 0;
  727. return S_OK;
  728. }
  729. HRESULT
  730. NtKernelUnloadedModuleInfo::GetEntry(PSTR Name,
  731. PDEBUG_MODULE_PARAMETERS Params)
  732. {
  733. if (m_Count == MI_UNLOADED_DRIVERS)
  734. {
  735. return S_FALSE;
  736. }
  737. if (m_Index == 0)
  738. {
  739. m_Index = MI_UNLOADED_DRIVERS - 1;
  740. }
  741. else
  742. {
  743. m_Index--;
  744. }
  745. ULONG64 Offset;
  746. ULONG Read;
  747. HRESULT Status;
  748. ULONG64 WideName;
  749. ULONG NameLen;
  750. ZeroMemory(Params, sizeof(*Params));
  751. Params->Flags |= DEBUG_MODULE_UNLOADED;
  752. if (g_TargetMachine->m_Ptr64)
  753. {
  754. UNLOADED_DRIVERS64 Entry;
  755. Offset = m_Base + m_Index * sizeof(Entry);
  756. if ((Status = g_Target->ReadVirtual(Offset, &Entry, sizeof(Entry),
  757. &Read)) != S_OK)
  758. {
  759. return Status;
  760. }
  761. if (Read != sizeof(Entry))
  762. {
  763. return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
  764. }
  765. if (Entry.Name.Buffer == 0)
  766. {
  767. m_Count = MI_UNLOADED_DRIVERS;
  768. return S_FALSE;
  769. }
  770. Params->Base = Entry.StartAddress;
  771. Params->Size = (ULONG)(Entry.EndAddress - Entry.StartAddress);
  772. Params->TimeDateStamp =
  773. FileTimeToTimeDateStamp(Entry.CurrentTime.QuadPart);
  774. WideName = Entry.Name.Buffer;
  775. NameLen = Entry.Name.Length;
  776. }
  777. else
  778. {
  779. UNLOADED_DRIVERS32 Entry;
  780. Offset = m_Base + m_Index * sizeof(Entry);
  781. if ((Status = g_Target->ReadVirtual(Offset, &Entry, sizeof(Entry),
  782. &Read)) != S_OK)
  783. {
  784. return Status;
  785. }
  786. if (Read != sizeof(Entry))
  787. {
  788. return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
  789. }
  790. if (Entry.Name.Buffer == 0)
  791. {
  792. m_Count = MI_UNLOADED_DRIVERS;
  793. return S_FALSE;
  794. }
  795. Params->Base = EXTEND64(Entry.StartAddress);
  796. Params->Size = Entry.EndAddress - Entry.StartAddress;
  797. Params->TimeDateStamp =
  798. FileTimeToTimeDateStamp(Entry.CurrentTime.QuadPart);
  799. WideName = EXTEND64(Entry.Name.Buffer);
  800. NameLen = Entry.Name.Length;
  801. }
  802. if (Name != NULL)
  803. {
  804. //
  805. // This size restriction is in force for minidumps only.
  806. // For kernel dumps, just truncate the name for now ...
  807. //
  808. if (NameLen > MAX_UNLOADED_NAME_LENGTH)
  809. {
  810. NameLen = MAX_UNLOADED_NAME_LENGTH;
  811. }
  812. WCHAR WideBuf[MAX_UNLOADED_NAME_LENGTH / sizeof(WCHAR) + 1];
  813. if ((Status = g_Target->ReadVirtual(WideName, WideBuf, NameLen,
  814. &Read)) != S_OK)
  815. {
  816. return Status;
  817. }
  818. WideBuf[NameLen / sizeof(WCHAR)] = 0;
  819. if (WideCharToMultiByte(CP_ACP, 0,
  820. WideBuf, NameLen / sizeof(WCHAR) + 1,
  821. Name,
  822. MAX_UNLOADED_NAME_LENGTH / sizeof(WCHAR) + 1,
  823. NULL, NULL) == 0)
  824. {
  825. return WIN32_LAST_STATUS();
  826. }
  827. Name[MAX_UNLOADED_NAME_LENGTH / sizeof(WCHAR)] = 0;
  828. }
  829. m_Count++;
  830. return S_OK;
  831. }
  832. NtKernelUnloadedModuleInfo g_NtKernelUnloadedModuleIterator;
  833. HRESULT
  834. W9xModuleInfo::Initialize(void)
  835. {
  836. m_Snap = g_Kernel32Calls.
  837. CreateToolhelp32Snapshot(TH32CS_SNAPMODULE,
  838. g_CurrentProcess->SystemId);
  839. if (m_Snap == INVALID_HANDLE_VALUE)
  840. {
  841. m_Snap = NULL;
  842. ErrOut("Can't create snapshot\n");
  843. return WIN32_LAST_STATUS();
  844. }
  845. m_First = TRUE;
  846. m_LastId = 0;
  847. return S_OK;
  848. }
  849. HRESULT
  850. W9xModuleInfo::GetEntry(PMODULE_INFO_ENTRY Entry)
  851. {
  852. if (m_Snap == NULL)
  853. {
  854. return S_FALSE;
  855. }
  856. BOOL Succ;
  857. MODULEENTRY32 Mod;
  858. Mod.dwSize = sizeof(Mod);
  859. if (m_First)
  860. {
  861. Succ = g_Kernel32Calls.Module32First(m_Snap, &Mod);
  862. m_First = FALSE;
  863. }
  864. else
  865. {
  866. // Win9x seems to require that this module ID be saved
  867. // between calls so stick it back in to keep Win9x happy.
  868. Mod.th32ModuleID = m_LastId;
  869. Succ = g_Kernel32Calls.Module32Next(m_Snap, &Mod);
  870. }
  871. if (!Succ)
  872. {
  873. CloseHandle(m_Snap);
  874. m_Snap = NULL;
  875. return S_FALSE;
  876. }
  877. m_LastId = Mod.th32ModuleID;
  878. strncat(Entry->Buffer, Mod.szModule, sizeof(Entry->Buffer) - 1);
  879. Entry->NamePtr = Entry->Buffer;
  880. Entry->UnicodeNamePtr = 0;
  881. Entry->Base = EXTEND64((ULONG_PTR)Mod.modBaseAddr);
  882. Entry->Size = Mod.modBaseSize;
  883. //
  884. // Update the image informaion, such as timestamp and real image size,
  885. // Directly from the image header
  886. //
  887. ReadImageHeaderInfo(Entry);
  888. return S_OK;
  889. }
  890. W9xModuleInfo g_W9xModuleIterator;
  891. //----------------------------------------------------------------------------
  892. //
  893. // Target configuration information.
  894. //
  895. //----------------------------------------------------------------------------
  896. ULONG g_SystemVersion;
  897. ULONG g_ActualSystemVersion;
  898. ULONG g_TargetCheckedBuild;
  899. ULONG g_TargetBuildNumber;
  900. BOOL g_MachineInitialized;
  901. ULONG g_TargetMachineType = IMAGE_FILE_MACHINE_UNKNOWN;
  902. ULONG g_TargetExecMachine = IMAGE_FILE_MACHINE_UNKNOWN;
  903. ULONG g_TargetPlatformId;
  904. char g_TargetServicePackString[_MAX_PATH];
  905. ULONG g_TargetServicePackNumber;
  906. char g_TargetBuildLabName[272];
  907. ULONG g_TargetNumberProcessors;
  908. ULONG g_TargetClass = DEBUG_CLASS_UNINITIALIZED;
  909. ULONG g_TargetClassQualifier;
  910. ConnLiveKernelTargetInfo g_ConnLiveKernelTarget;
  911. LocalLiveKernelTargetInfo g_LocalLiveKernelTarget;
  912. ExdiLiveKernelTargetInfo g_ExdiLiveKernelTarget;
  913. LocalUserTargetInfo g_LocalUserTarget;
  914. RemoteUserTargetInfo g_RemoteUserTarget;
  915. //----------------------------------------------------------------------------
  916. //
  917. // TargetInfo.
  918. //
  919. //----------------------------------------------------------------------------
  920. // Used in convenience macros.
  921. ULONG g_TmpCount;
  922. TargetInfo* g_Target = &g_UnexpectedTarget;
  923. void
  924. TargetInfo::Uninitialize(void)
  925. {
  926. // Placeholder.
  927. }
  928. HRESULT
  929. TargetInfo::ThreadInitialize(void)
  930. {
  931. // Placeholder.
  932. return S_OK;
  933. }
  934. void
  935. TargetInfo::ThreadUninitialize(void)
  936. {
  937. // Placeholder.
  938. }
  939. HRESULT
  940. TargetInfo::OutputTime(void)
  941. {
  942. ULONG64 TimeDateN = GetCurrentTimeDateN();
  943. if (TimeDateN)
  944. {
  945. dprintf("Debug session time: %s\n",
  946. TimeToStr(FileTimeToTimeDateStamp(TimeDateN)));
  947. }
  948. ULONG64 UpTimeN = GetCurrentSystemUpTimeN();
  949. if (UpTimeN)
  950. {
  951. ULONG seconds = FileTimeToTime(UpTimeN);
  952. ULONG minutes = seconds / 60;
  953. ULONG hours = minutes / 60;
  954. ULONG days = hours / 24;
  955. dprintf("System Uptime: %d days %d:%02d:%02d \n",
  956. days, hours%24, minutes%60, seconds%60);
  957. }
  958. else
  959. {
  960. dprintf("System Uptime: not available\n");
  961. }
  962. if (IS_LIVE_USER_TARGET())
  963. {
  964. ULONG64 UpTimeProcessN = GetProcessUpTimeN(g_CurrentProcess->FullHandle);
  965. if (UpTimeN)
  966. {
  967. ULONG seconds = FileTimeToTime(UpTimeProcessN);
  968. ULONG minutes = seconds / 60;
  969. ULONG hours = minutes / 60;
  970. ULONG days = hours / 24;
  971. dprintf("Process Uptime: %d days %d:%02d:%02d \n",
  972. days, hours%24, minutes%60, seconds%60);
  973. }
  974. else
  975. {
  976. dprintf("Process Uptime: not available\n");
  977. }
  978. }
  979. return (TimeDateN && UpTimeN) ? S_OK : E_FAIL;
  980. }
  981. HRESULT
  982. TargetInfo::OutputVersion(void)
  983. {
  984. BOOL MpMachine;
  985. if (!IS_TARGET_SET())
  986. {
  987. return E_UNEXPECTED;
  988. }
  989. else if (IS_USER_TARGET())
  990. {
  991. dprintf("%s ", SystemVersionName(g_ActualSystemVersion));
  992. }
  993. else
  994. {
  995. dprintf("%s Kernel ", SystemVersionName(g_ActualSystemVersion));
  996. }
  997. dprintf("Version %u", g_TargetBuildNumber);
  998. // Win9x seems to set the CSD string to a space which isn't
  999. // very interesting so ignore it.
  1000. if (g_TargetServicePackString[0] &&
  1001. strcmp(g_TargetServicePackString, " ") != 0)
  1002. {
  1003. dprintf(" (%s)", g_TargetServicePackString);
  1004. }
  1005. MpMachine = IS_LIVE_KERNEL_TARGET() ?
  1006. ((g_KdVersion.Flags & DBGKD_VERS_FLAG_MP) ? 1 : 0) :
  1007. (g_TargetNumberProcessors > 1);
  1008. dprintf(" %s ", MpMachine ? "MP" : "UP");
  1009. if (MpMachine)
  1010. {
  1011. dprintf("(%d procs) ", g_TargetNumberProcessors);
  1012. }
  1013. dprintf("%s %s\n",
  1014. g_TargetCheckedBuild == 0xC ? "Checked" : "Free",
  1015. g_TargetMachine != NULL ? g_TargetMachine->m_FullName : "");
  1016. if (g_Wow64exts != NULL)
  1017. {
  1018. dprintf("WOW64 extensions loaded\n");
  1019. }
  1020. if (g_TargetBuildLabName[0])
  1021. {
  1022. dprintf("%s\n", g_TargetBuildLabName);
  1023. }
  1024. if (IS_KERNEL_TARGET())
  1025. {
  1026. dprintf("Kernel base = 0x%s PsLoadedModuleList = 0x%s\n",
  1027. FormatAddr64(KdDebuggerData.KernBase),
  1028. FormatAddr64(KdDebuggerData.PsLoadedModuleList));
  1029. }
  1030. OutputTime();
  1031. return S_OK;
  1032. }
  1033. ModuleInfo*
  1034. TargetInfo::GetModuleInfo(BOOL UserMode)
  1035. {
  1036. if (UserMode)
  1037. {
  1038. switch(g_TargetPlatformId)
  1039. {
  1040. case VER_PLATFORM_WIN32_NT:
  1041. return &g_NtTargetUserModuleIterator;
  1042. case VER_PLATFORM_WIN32_WINDOWS:
  1043. return &g_W9xModuleIterator;
  1044. default:
  1045. ErrOut("System module info not available\n");
  1046. return NULL;
  1047. }
  1048. }
  1049. else
  1050. {
  1051. if (g_TargetPlatformId != VER_PLATFORM_WIN32_NT)
  1052. {
  1053. ErrOut("System module info only available on Windows NT/2000\n");
  1054. return NULL;
  1055. }
  1056. DBG_ASSERT(IS_KERNEL_TARGET());
  1057. return &g_NtKernelModuleIterator;
  1058. }
  1059. }
  1060. UnloadedModuleInfo*
  1061. TargetInfo::GetUnloadedModuleInfo(void)
  1062. {
  1063. if (g_TargetPlatformId != VER_PLATFORM_WIN32_NT)
  1064. {
  1065. ErrOut("System unloaded module info only available on "
  1066. "Windows NT/2000\n");
  1067. return NULL;
  1068. }
  1069. if (IS_KERNEL_TARGET())
  1070. {
  1071. return &g_NtKernelUnloadedModuleIterator;
  1072. }
  1073. else
  1074. {
  1075. return NULL;
  1076. }
  1077. }
  1078. HRESULT
  1079. TargetInfo::GetImageVersionInformation(PCSTR ImagePath,
  1080. ULONG64 ImageBase,
  1081. PCSTR Item,
  1082. PVOID Buffer, ULONG BufferSize,
  1083. PULONG VerInfoSize)
  1084. {
  1085. return E_NOINTERFACE;
  1086. }
  1087. HRESULT
  1088. TargetInfo::Reload(
  1089. IN PCSTR args
  1090. )
  1091. {
  1092. HRESULT Status;
  1093. CHAR AnsiString[MAX_IMAGE_PATH];
  1094. LPSTR SpecificModule = NULL;
  1095. ULONG64 Address = 0;
  1096. ULONG ImageSize = 0;
  1097. PCHAR p;
  1098. ULONG ModCount;
  1099. BOOL IgnoreSignature = FALSE;
  1100. ULONG ReloadSymOptions;
  1101. BOOL UnloadOnly = FALSE;
  1102. BOOL ReallyVerbose = FALSE;
  1103. BOOL LoadUserSymbols = TRUE;
  1104. BOOL UserModeList = IS_USER_TARGET();
  1105. BOOL ForceSymbolLoad = FALSE;
  1106. BOOL PrintImageListOnly = FALSE;
  1107. BOOL rc;
  1108. BOOL AddrLoad = FALSE;
  1109. BOOL UseDebuggerModuleList;
  1110. BOOL SkipPathChecks = FALSE;
  1111. ModuleInfo* ModIter;
  1112. BOOL Wow64ModLoaded = FALSE;
  1113. HRESULT RetStatus = S_OK;
  1114. MODULE_INFO_ENTRY ModEntry = {0};
  1115. if (!IS_TARGET_SET() ||
  1116. g_CurrentProcess == NULL)
  1117. {
  1118. return E_UNEXPECTED;
  1119. }
  1120. // Historically, live user-mode reload has always
  1121. // just used the internal module list so preserve that.
  1122. UseDebuggerModuleList = IS_USER_TARGET() && !IS_DUMP_TARGET();
  1123. while (*args)
  1124. {
  1125. while (*args && *args <= ' ')
  1126. {
  1127. args++;
  1128. }
  1129. if (*args == '/' || *args == '-')
  1130. {
  1131. args++;
  1132. while (*args > ' ')
  1133. {
  1134. switch (*args++)
  1135. {
  1136. case 'a':
  1137. // for internal use only: loads whatever is found at the
  1138. // passed address
  1139. AddrLoad = TRUE;
  1140. break;
  1141. case 'd':
  1142. UseDebuggerModuleList = TRUE;
  1143. break;
  1144. case 'f':
  1145. ForceSymbolLoad = TRUE;
  1146. break;
  1147. case 'i':
  1148. IgnoreSignature = TRUE;
  1149. break;
  1150. case 'l':
  1151. PrintImageListOnly = TRUE;
  1152. break;
  1153. case 'n':
  1154. LoadUserSymbols = FALSE;
  1155. break;
  1156. case 'P':
  1157. // Internal-only switch.
  1158. SkipPathChecks = TRUE;
  1159. break;
  1160. case 's':
  1161. UseDebuggerModuleList = FALSE;
  1162. break;
  1163. case 'u':
  1164. if (!_strcmpi(args, "ser"))
  1165. {
  1166. UserModeList = TRUE;
  1167. args += 3;
  1168. }
  1169. else
  1170. {
  1171. UnloadOnly = TRUE;
  1172. }
  1173. break;
  1174. case 'v':
  1175. ReallyVerbose = TRUE;
  1176. break;
  1177. default:
  1178. dprintf("Reload: Unknown option '%c'\n", args[-1]);
  1179. dprintf("Usage: .reload [flags] [module] ...\n");
  1180. dprintf(" Flags: /d Use the debugger's module list\n");
  1181. dprintf(" Default for live user-mode "
  1182. "sessions\n");
  1183. dprintf(" /f Force immediate symbol load "
  1184. "instead of deferred\n");
  1185. dprintf(" /i Force symbol load by ignoring "
  1186. "mismatches in the pdb signature (requires /f as well)\n");
  1187. dprintf(" /l Just list the modules. "
  1188. "Kernel output same as !drivers\n");
  1189. dprintf(" /n Do not load from user-mode list "
  1190. "in kernel sessions\n");
  1191. dprintf(" /s Use the system's module list\n");
  1192. dprintf(" Default for dump and kernel sessions\n");
  1193. dprintf(" /u Unload symbols, no reload\n");
  1194. dprintf(" /user Load only user-mode symbols "
  1195. "in kernel sessions\n");
  1196. dprintf(" /v Verbose\n");
  1197. return E_INVALIDARG;
  1198. }
  1199. }
  1200. }
  1201. while (*args && *args <= ' ')
  1202. {
  1203. args++;
  1204. }
  1205. if (!(*args == '/' || *args == '-') || AddrLoad)
  1206. {
  1207. AnsiString[ 0 ] = '\0';
  1208. Address = 0;
  1209. if (!sscanf(args, "%s", AnsiString) ||
  1210. !strlen(AnsiString))
  1211. {
  1212. AddrLoad = FALSE;
  1213. break;
  1214. }
  1215. else
  1216. {
  1217. p = 0;
  1218. args += strlen( AnsiString );
  1219. //
  1220. // Support !reload pri_kern.exe=0x80400000,size
  1221. //
  1222. if (p = strchr(AnsiString, '='))
  1223. {
  1224. *p++ = 0;
  1225. if (sscanf(p, "%I64x", &Address) != 1)
  1226. {
  1227. ErrOut("Invalid address %s\n", p);
  1228. return E_INVALIDARG;
  1229. }
  1230. if (!g_TargetMachine->m_Ptr64)
  1231. {
  1232. Address = EXTEND64(Address);
  1233. }
  1234. if (p = strchr(p, ','))
  1235. {
  1236. p++;
  1237. if (sscanf(p, "%x", &ImageSize) != 1)
  1238. {
  1239. ErrOut("Invalid ImageSize %s\n", p);
  1240. return E_INVALIDARG;
  1241. }
  1242. }
  1243. }
  1244. if (UnloadOnly)
  1245. {
  1246. BOOL Deleted;
  1247. Deleted = DelImageByName(g_CurrentProcess, AnsiString,
  1248. INAME_MODULE);
  1249. if (!Deleted)
  1250. {
  1251. // The user might have given an image name
  1252. // instead of a module name so try that.
  1253. Deleted = DelImageByName(g_CurrentProcess,
  1254. PathTail(AnsiString),
  1255. INAME_IMAGE_PATH_TAIL);
  1256. }
  1257. if (Deleted)
  1258. {
  1259. dprintf("Unloaded %s\n", AnsiString);
  1260. return S_OK;
  1261. }
  1262. else
  1263. {
  1264. dprintf("Unable to find module '%s'\n", AnsiString);
  1265. return E_NOINTERFACE;
  1266. }
  1267. }
  1268. //
  1269. // NOTE: This seems unnecessary as AddImage is going to
  1270. // check for the renamed image anyway.
  1271. //
  1272. SpecificModule = _strdup( AnsiString );
  1273. if (!SpecificModule)
  1274. {
  1275. return S_OK;
  1276. }
  1277. if (IS_KERNEL_TARGET() &&
  1278. _stricmp( AnsiString, KERNEL_MODULE_NAME ) == 0)
  1279. {
  1280. ForceSymbolLoad = TRUE;
  1281. }
  1282. else
  1283. {
  1284. if (AddrLoad)
  1285. {
  1286. free(SpecificModule);
  1287. SpecificModule = NULL;
  1288. }
  1289. }
  1290. }
  1291. }
  1292. }
  1293. // Ignore signature will only work if we load the symbols imediately.
  1294. if (ForceSymbolLoad == FALSE)
  1295. {
  1296. IgnoreSignature = FALSE;
  1297. }
  1298. if (!PrintImageListOnly && !SkipPathChecks)
  1299. {
  1300. if (g_SymbolSearchPath == NULL ||
  1301. *g_SymbolSearchPath == NULL)
  1302. {
  1303. dprintf("*********************************************************************\n");
  1304. dprintf("* Symbols can not be loaded because symbol path is not initialized. *\n");
  1305. dprintf("* *\n");
  1306. dprintf("* The Symbol Path can be set by: *\n");
  1307. dprintf("* using the _NT_SYMBOL_PATH environment variable. *\n");
  1308. dprintf("* using the -y <symbol_path> argument when starting the debugger. *\n");
  1309. dprintf("* using .sympath and .sympath+ *\n");
  1310. dprintf("*********************************************************************\n");
  1311. RetStatus = E_INVALIDARG;
  1312. goto FreeSpecMod;
  1313. }
  1314. if (IS_DUMP_WITH_MAPPED_IMAGES() &&
  1315. (g_ExecutableImageSearchPath == NULL ||
  1316. *g_ExecutableImageSearchPath == NULL))
  1317. {
  1318. dprintf("*********************************************************************\n");
  1319. dprintf("* Analyzing Minidumps requires access to the actual executable *\n");
  1320. dprintf("* images for the crashed system *\n");
  1321. dprintf("* *\n");
  1322. dprintf("* The Executable Image Path can be set by: *\n");
  1323. dprintf("* using the _NT_EXECUTABLE_IMAGE_PATH environment variable. *\n");
  1324. dprintf("* using the -i <image_path> argument when starting the debugger. *\n");
  1325. dprintf("* using .exepath and .exepath+ *\n");
  1326. dprintf("*********************************************************************\n");
  1327. RetStatus = E_INVALIDARG;
  1328. goto FreeSpecMod;
  1329. }
  1330. }
  1331. //
  1332. // If both the module name and the address are specified, then just load
  1333. // the module right now, as this is only used when normal symbol loading
  1334. // would have failed in the first place.
  1335. //
  1336. if (SpecificModule && Address)
  1337. {
  1338. if (IgnoreSignature)
  1339. {
  1340. ReloadSymOptions = SymGetOptions();
  1341. SymSetOptions(ReloadSymOptions | SYMOPT_LOAD_ANYTHING);
  1342. }
  1343. ModEntry.NamePtr = SpecificModule,
  1344. ModEntry.Base = Address;
  1345. ModEntry.Size = ImageSize;
  1346. ModEntry.CheckSum = -1;
  1347. if (AddImage(&ModEntry, TRUE) == NULL)
  1348. {
  1349. ErrOut("Unable to add module at %s\n", FormatAddr64(Address));
  1350. RetStatus = E_FAIL;
  1351. }
  1352. if (IgnoreSignature)
  1353. {
  1354. SymSetOptions(ReloadSymOptions);
  1355. }
  1356. goto FreeSpecMod;
  1357. }
  1358. //
  1359. // Don't unload and reset things if we are looking for a specific module
  1360. // or if we're going to use the existing module list.
  1361. //
  1362. if (SpecificModule == NULL)
  1363. {
  1364. if (!PrintImageListOnly &&
  1365. (!UseDebuggerModuleList || UnloadOnly))
  1366. {
  1367. DelImages(g_CurrentProcess);
  1368. }
  1369. if (UnloadOnly)
  1370. {
  1371. dprintf("Unloaded all modules\n");
  1372. return S_OK;
  1373. }
  1374. if (!IS_USER_TARGET() && !UseDebuggerModuleList)
  1375. {
  1376. if (!IS_DUMP_TARGET())
  1377. {
  1378. GetKdVersion();
  1379. }
  1380. VerifyKernelBase(TRUE);
  1381. }
  1382. //
  1383. // Print out the correct statement based on the type of output we
  1384. // want to provide
  1385. //
  1386. if (PrintImageListOnly)
  1387. {
  1388. if (UseDebuggerModuleList)
  1389. {
  1390. dprintf("Debugger Module List Summary\n");
  1391. }
  1392. else
  1393. {
  1394. dprintf("System %s Summary\n",
  1395. IS_USER_TARGET() ? "Image" : "Driver and Image");
  1396. }
  1397. dprintf("Base ");
  1398. if (g_TargetMachine->m_Ptr64)
  1399. {
  1400. dprintf(" ");
  1401. }
  1402. #if 0
  1403. if (Flags & 1)
  1404. {
  1405. dprintf("Code Size Data Size Resident "
  1406. "Standby Driver Name\n");
  1407. }
  1408. else if (Flags & 2)
  1409. {
  1410. dprintf("Code Data Locked Resident Standby "
  1411. "Loader Entry Driver Name\n");
  1412. }
  1413. else
  1414. {
  1415. #endif
  1416. if (UseDebuggerModuleList)
  1417. {
  1418. dprintf("Image Size "
  1419. "Image Name Creation Time\n");
  1420. }
  1421. else
  1422. {
  1423. dprintf("Code Size Data Size "
  1424. "Image Name Creation Time\n");
  1425. }
  1426. }
  1427. else if (UseDebuggerModuleList)
  1428. {
  1429. dprintf("Reloading current modules\n");
  1430. }
  1431. else if (!IS_USER_TARGET())
  1432. {
  1433. dprintf("Loading %s Symbols\n",
  1434. UserModeList ? "User" : "Kernel");
  1435. }
  1436. }
  1437. //
  1438. // Get the beginning of the module list.
  1439. //
  1440. if (UseDebuggerModuleList)
  1441. {
  1442. ModIter = &g_DebuggerModuleIterator;
  1443. }
  1444. else
  1445. {
  1446. ModIter = GetModuleInfo(UserModeList);
  1447. }
  1448. if (ModIter == NULL)
  1449. {
  1450. // Error messages already printed.
  1451. RetStatus = E_UNEXPECTED;
  1452. goto FreeSpecMod;
  1453. }
  1454. if ((Status = ModIter->Initialize()) != S_OK)
  1455. {
  1456. // Error messages already printed.
  1457. // Fold unprepared-to-reload S_FALSE into S_OK.
  1458. RetStatus = SUCCEEDED(Status) ? S_OK : Status;
  1459. goto FreeSpecMod;
  1460. }
  1461. if (IgnoreSignature)
  1462. {
  1463. ReloadSymOptions = SymGetOptions();
  1464. SymSetOptions(ReloadSymOptions | SYMOPT_LOAD_ANYTHING);
  1465. }
  1466. // Suppress notifications until everything is done.
  1467. g_EngNotify++;
  1468. LoadLoop:
  1469. for (ModCount=0; ; ModCount++)
  1470. {
  1471. // Flush regularly so the user knows something is
  1472. // happening during the reload.
  1473. FlushCallbacks();
  1474. if (CheckUserInterrupt())
  1475. {
  1476. break;
  1477. }
  1478. if (ModCount > 1000)
  1479. {
  1480. ErrOut("ModuleList is corrupt - walked over 1000 module entries\n");
  1481. break;
  1482. }
  1483. if (ModEntry.DebugHeader)
  1484. {
  1485. free(ModEntry.DebugHeader);
  1486. }
  1487. ZeroMemory(&ModEntry, sizeof(ModEntry));
  1488. if ((Status = ModIter->GetEntry(&ModEntry)) != S_OK)
  1489. {
  1490. // Error message already printed in error case.
  1491. // Works for end-of-list case also.
  1492. break;
  1493. }
  1494. //
  1495. // Warn if not all the information was gathered
  1496. //
  1497. if (!ModEntry.ImageInfoValid)
  1498. {
  1499. VerbOut("Unable to read image header for");
  1500. if (ModEntry.UnicodeNamePtr)
  1501. {
  1502. VerbOut(" %ls", ModEntry.NamePtr);
  1503. }
  1504. else
  1505. {
  1506. VerbOut(" %s", ModEntry.NamePtr);
  1507. }
  1508. VerbOut(" at %s\n",
  1509. FormatAddr64(ModEntry.Base));
  1510. }
  1511. if (ModEntry.NameLength > (MAX_IMAGE_PATH - 1) *
  1512. (ModEntry.UnicodeNamePtr ? sizeof(WCHAR) : sizeof(CHAR)))
  1513. {
  1514. ErrOut("Module list is corrupt.");
  1515. if (IS_KERNEL_TARGET())
  1516. {
  1517. ErrOut(" Check your kernel symbols.\n");
  1518. }
  1519. else
  1520. {
  1521. ErrOut(" Loader list may be invalid\n");
  1522. }
  1523. break;
  1524. }
  1525. // If this entry has no name just skip it.
  1526. if ((ModEntry.NamePtr == NULL) ||
  1527. (ModEntry.UnicodeNamePtr && ModEntry.NameLength == 0))
  1528. {
  1529. ErrOut(" Module List has empty entry in it - skipping\n");
  1530. continue;
  1531. }
  1532. //
  1533. // Are we looking for a module at a specific address ?
  1534. //
  1535. if (AddrLoad)
  1536. {
  1537. if (Address < ModEntry.Base ||
  1538. Address >= ModEntry.Base + ModEntry.Size)
  1539. {
  1540. continue;
  1541. }
  1542. }
  1543. if (ModEntry.UnicodeNamePtr)
  1544. {
  1545. if (!WideCharToMultiByte(CP_ACP,
  1546. 0,
  1547. (PWSTR)ModEntry.NamePtr,
  1548. ModEntry.NameLength / sizeof(WCHAR),
  1549. AnsiString,
  1550. sizeof(AnsiString),
  1551. NULL,
  1552. NULL))
  1553. {
  1554. WarnOut("Unable to convert Unicode string %ls to Ansi\n",
  1555. ModEntry.NamePtr);
  1556. continue;
  1557. }
  1558. ModEntry.NamePtr = AnsiString;
  1559. ModEntry.UnicodeNamePtr = 0;
  1560. AnsiString[ModEntry.NameLength / sizeof(WCHAR)] = 0;
  1561. }
  1562. //
  1563. // If we are loading a specific module:
  1564. //
  1565. // If the Module is NT, we take the first module in the list as it is
  1566. // guaranteed to be the kernel. Reset the Base address if it was
  1567. // not set.
  1568. //
  1569. // Otherwise, actually compare the strings and continue if they don't
  1570. // match
  1571. //
  1572. if (SpecificModule)
  1573. {
  1574. if (!UserModeList && _stricmp( SpecificModule, KERNEL_MODULE_NAME ) == 0)
  1575. {
  1576. if (!KdDebuggerData.KernBase)
  1577. {
  1578. KdDebuggerData.KernBase = ModEntry.Base;
  1579. }
  1580. }
  1581. else
  1582. {
  1583. if (!MatchPathTails(SpecificModule, ModEntry.NamePtr))
  1584. {
  1585. continue;
  1586. }
  1587. }
  1588. }
  1589. PCSTR NamePtrTail = PathTail(ModEntry.NamePtr);
  1590. if (PrintImageListOnly)
  1591. {
  1592. PCHAR Time;
  1593. //
  1594. // The timestamp in minidumps was corrupt until NT5 RC3
  1595. // The timestamp could also be invalid because it was paged out
  1596. // in which case it's value is UNKNOWN_TIMESTAMP.
  1597. if (IS_KERNEL_TRIAGE_DUMP() &&
  1598. (g_ActualSystemVersion > NT_SVER_START &&
  1599. g_ActualSystemVersion <= NT_SVER_W2K_RC3))
  1600. {
  1601. Time = "";
  1602. }
  1603. Time = TimeToStr(ModEntry.TimeDateStamp);
  1604. if (UseDebuggerModuleList)
  1605. {
  1606. dprintf("%s %6lx (%4ld k) %12s %s\n",
  1607. FormatAddr64(ModEntry.Base), ModEntry.Size,
  1608. KBYTES(ModEntry.Size), NamePtrTail,
  1609. Time);
  1610. }
  1611. else
  1612. {
  1613. dprintf("%s %6lx (%4ld k) %5lx (%3ld k) %12s %s\n",
  1614. FormatAddr64(ModEntry.Base),
  1615. ModEntry.SizeOfCode, KBYTES(ModEntry.SizeOfCode),
  1616. ModEntry.SizeOfData, KBYTES(ModEntry.SizeOfData),
  1617. NamePtrTail, Time);
  1618. }
  1619. }
  1620. else
  1621. {
  1622. //
  1623. // Don't bother reloading the kernel if we are not specifically
  1624. // asked since we know those symbols we reloaded by the
  1625. // VerifyKernel call.
  1626. //
  1627. if (!SpecificModule && !UserModeList &&
  1628. KdDebuggerData.KernBase == ModEntry.Base)
  1629. {
  1630. continue;
  1631. }
  1632. if (ReallyVerbose)
  1633. {
  1634. dprintf("AddImage: %s\n DllBase = %s\n Size = %08x\n "
  1635. "Checksum = %08x\n TimeDateStamp = %08x\n",
  1636. ModEntry.NamePtr, FormatAddr64(ModEntry.Base),
  1637. ModEntry.Size, ModEntry.CheckSum,
  1638. ModEntry.TimeDateStamp);
  1639. }
  1640. else
  1641. {
  1642. if (!SpecificModule)
  1643. {
  1644. dprintf(".");
  1645. }
  1646. }
  1647. if (Address)
  1648. {
  1649. ModEntry.Base = Address;
  1650. }
  1651. if (AddImage(&ModEntry, ForceSymbolLoad) == NULL)
  1652. {
  1653. RetStatus = E_FAIL;
  1654. }
  1655. }
  1656. if (SpecificModule)
  1657. {
  1658. free( SpecificModule );
  1659. goto Notify;
  1660. }
  1661. if (AddrLoad)
  1662. {
  1663. goto Notify;
  1664. }
  1665. }
  1666. if (UseDebuggerModuleList || IS_KERNEL_TARGET() || UserModeList)
  1667. {
  1668. // print newline after all the '.'
  1669. dprintf("\n");
  1670. }
  1671. if (!UseDebuggerModuleList && !UserModeList && SpecificModule == NULL)
  1672. {
  1673. // If we just reloaded the kernel modules
  1674. // go through the unloaded module list.
  1675. if (!PrintImageListOnly)
  1676. {
  1677. dprintf("Loading unloaded module list\n");
  1678. }
  1679. ListUnloadedModules(PrintImageListOnly ?
  1680. LUM_OUTPUT : LUM_OUTPUT_TERSE, NULL);
  1681. }
  1682. //
  1683. // If we got to the end of the kernel symbols, try to load the
  1684. // user mode symbols for the current process.
  1685. //
  1686. if (!UseDebuggerModuleList &&
  1687. (UserModeList == FALSE) &&
  1688. (LoadUserSymbols == TRUE) &&
  1689. SUCCEEDED(Status))
  1690. {
  1691. if (!AddrLoad && !SpecificModule)
  1692. {
  1693. dprintf("Loading User Symbols\n");
  1694. }
  1695. UserModeList = TRUE;
  1696. ModIter = GetModuleInfo(UserModeList);
  1697. if (ModIter != NULL && ModIter->Initialize() == S_OK)
  1698. {
  1699. goto LoadLoop;
  1700. }
  1701. }
  1702. if (!SpecificModule && !Wow64ModLoaded)
  1703. {
  1704. ModIter = &g_NtWow64UserModuleIterator;
  1705. Wow64ModLoaded = TRUE;
  1706. if (ModIter->Initialize() == S_OK)
  1707. {
  1708. dprintf("Loading Wow64 Symbols\n");
  1709. goto LoadLoop;
  1710. }
  1711. }
  1712. // In the multiple load situation we always return OK
  1713. // since an error wouldn't tell you much about what
  1714. // actually occurred.
  1715. // Specific loads that haven't already been handled are checked
  1716. // right after this.
  1717. RetStatus = S_OK;
  1718. //
  1719. // If we still have not managed to load a named file, just pass the name
  1720. // and the address and hope for the best.
  1721. //
  1722. if (SpecificModule)
  1723. {
  1724. WarnOut("\nModule \"%s\" was not found in the module list.\n",
  1725. SpecificModule);
  1726. WarnOut("Debugger will attempt to load module \"%s\" "
  1727. "by guessing the base address.\n\n", SpecificModule);
  1728. WarnOut("Please provide the full image name, including the "
  1729. "extension (i.e. kernel32.dll) for more reliable results.\n");
  1730. ZeroMemory(&ModEntry, sizeof(ModEntry));
  1731. ModEntry.NamePtr = SpecificModule,
  1732. ModEntry.Base = Address;
  1733. ModEntry.Size = ImageSize;
  1734. if (AddImage(&ModEntry, TRUE) == NULL)
  1735. {
  1736. ErrOut("Unable to load module at %s\n", FormatAddr64(Address));
  1737. RetStatus = E_FAIL;
  1738. }
  1739. free(SpecificModule);
  1740. }
  1741. Notify:
  1742. // If we've gotten this far we've done one or more reloads
  1743. // and postponed notifications. Do them now that all the work
  1744. // has been done.
  1745. g_EngNotify--;
  1746. if (SUCCEEDED(RetStatus))
  1747. {
  1748. NotifyChangeSymbolState(DEBUG_CSS_LOADS | DEBUG_CSS_UNLOADS, 0,
  1749. g_CurrentProcess);
  1750. }
  1751. if (IgnoreSignature)
  1752. {
  1753. SymSetOptions(ReloadSymOptions);
  1754. }
  1755. if (ModEntry.DebugHeader)
  1756. {
  1757. free(ModEntry.DebugHeader);
  1758. }
  1759. return RetStatus;
  1760. FreeSpecMod:
  1761. free(SpecificModule);
  1762. return RetStatus;
  1763. }
  1764. ULONG64
  1765. TargetInfo::GetCurrentTimeDateN(void)
  1766. {
  1767. // No information.
  1768. return 0;
  1769. }
  1770. ULONG64
  1771. TargetInfo::GetCurrentSystemUpTimeN(void)
  1772. {
  1773. // No information.
  1774. return 0;
  1775. }
  1776. ULONG64
  1777. TargetInfo::GetProcessUpTimeN(ULONG64 Process)
  1778. {
  1779. // No information.
  1780. return 0;
  1781. }
  1782. void
  1783. TargetInfo::GetKdVersion(void)
  1784. {
  1785. BOOL Ptr64;
  1786. if (GetTargetKdVersion(&g_KdVersion) != S_OK)
  1787. {
  1788. ErrOut("Debugger can't get KD version information\n");
  1789. memset(&g_KdVersion, 0, sizeof(g_KdVersion));
  1790. return;
  1791. }
  1792. if ((g_KdVersion.MajorVersion >> 8) >= KD_MAJOR_COUNT)
  1793. {
  1794. ErrOut("KD version has unknown kernel type\n");
  1795. memset(&g_KdVersion, 0, sizeof(g_KdVersion));
  1796. return;
  1797. }
  1798. if (MachineTypeIndex(g_KdVersion.MachineType) == MACHIDX_COUNT)
  1799. {
  1800. ErrOut("KD version has unknown processor architecture\n");
  1801. memset(&g_KdVersion, 0, sizeof(g_KdVersion));
  1802. return;
  1803. }
  1804. Ptr64 =
  1805. ((g_KdVersion.Flags & DBGKD_VERS_FLAG_PTR64) == DBGKD_VERS_FLAG_PTR64);
  1806. if (g_KdVersion.Flags & DBGKD_VERS_FLAG_NOMM)
  1807. {
  1808. g_VirtualCache.m_DecodePTEs = FALSE;
  1809. }
  1810. // Reloads cause the version to be retrieved but
  1811. // we don't want to completely reinitialize machines
  1812. // in that case as some settings can be lost. Only
  1813. // reinitialize if there's a need to do so.
  1814. BOOL MustInitializeMachines =
  1815. g_TargetMachineType != g_KdVersion.MachineType ||
  1816. g_TargetMachine == NULL;
  1817. g_TargetMachineType = g_KdVersion.MachineType;
  1818. g_TargetBuildNumber = g_KdVersion.MinorVersion;
  1819. g_TargetCheckedBuild = g_KdVersion.MajorVersion & 0xFF;
  1820. if ((g_TargetMachineType == IMAGE_FILE_MACHINE_ALPHA) && Ptr64)
  1821. {
  1822. g_TargetMachineType = IMAGE_FILE_MACHINE_AXP64;
  1823. g_KdVersion.MachineType = IMAGE_FILE_MACHINE_AXP64;
  1824. }
  1825. //
  1826. // Determine the OS running.
  1827. //
  1828. switch(g_KdVersion.MajorVersion >> 8)
  1829. {
  1830. case KD_MAJOR_NT:
  1831. g_TargetPlatformId = VER_PLATFORM_WIN32_NT;
  1832. g_ActualSystemVersion = NtBuildToSystemVersion(g_TargetBuildNumber);
  1833. g_SystemVersion = g_ActualSystemVersion;
  1834. break;
  1835. case KD_MAJOR_XBOX:
  1836. g_TargetPlatformId = VER_PLATFORM_WIN32_NT;
  1837. g_ActualSystemVersion = XBOX_SVER_1;
  1838. g_SystemVersion = NT_SVER_W2K;
  1839. break;
  1840. case KD_MAJOR_BIG:
  1841. g_TargetPlatformId = VER_PLATFORM_WIN32_NT;
  1842. g_ActualSystemVersion = BIG_SVER_1;
  1843. g_SystemVersion = NT_SVER_W2K;
  1844. break;
  1845. case KD_MAJOR_EXDI:
  1846. g_TargetPlatformId = VER_PLATFORM_WIN32_NT;
  1847. g_ActualSystemVersion = EXDI_SVER_1;
  1848. g_SystemVersion = NT_SVER_W2K;
  1849. break;
  1850. case KD_MAJOR_NTBD:
  1851. // Special mode for the NT boot debugger where
  1852. // the full system hasn't started yet.
  1853. g_TargetPlatformId = VER_PLATFORM_WIN32_NT;
  1854. g_ActualSystemVersion = NTBD_SVER_W2K_WHISTLER;
  1855. g_SystemVersion = NtBuildToSystemVersion(g_TargetBuildNumber);
  1856. break;
  1857. case KD_MAJOR_EFI:
  1858. g_TargetPlatformId = VER_PLATFORM_WIN32_NT;
  1859. g_ActualSystemVersion = EFI_SVER_1;
  1860. g_SystemVersion = NT_SVER_W2K_WHISTLER;
  1861. break;
  1862. }
  1863. //
  1864. // Pre-Whistler kernels didn't set these values so
  1865. // default them appropriately.
  1866. //
  1867. g_KdMaxPacketType = g_KdVersion.MaxPacketType;
  1868. if (g_SystemVersion < NT_SVER_W2K_WHISTLER ||
  1869. g_KdMaxPacketType == 0 ||
  1870. g_KdMaxPacketType > PACKET_TYPE_MAX)
  1871. {
  1872. g_KdMaxPacketType = PACKET_TYPE_KD_CONTROL_REQUEST + 1;
  1873. }
  1874. g_KdMaxStateChange = g_KdVersion.MaxStateChange +
  1875. DbgKdMinimumStateChange;
  1876. if (g_SystemVersion < NT_SVER_W2K_WHISTLER ||
  1877. g_KdMaxStateChange == DbgKdMinimumStateChange ||
  1878. g_KdMaxStateChange > DbgKdMaximumStateChange)
  1879. {
  1880. g_KdMaxStateChange = DbgKdLoadSymbolsStateChange + 1;
  1881. }
  1882. g_KdMaxManipulate = g_KdVersion.MaxManipulate +
  1883. DbgKdMinimumManipulate;
  1884. if (g_SystemVersion < NT_SVER_W2K_WHISTLER ||
  1885. g_KdMaxManipulate == DbgKdMinimumManipulate ||
  1886. g_KdMaxManipulate > DbgKdMaximumManipulate)
  1887. {
  1888. g_KdMaxManipulate = DbgKdCheckLowMemoryApi + 1;
  1889. }
  1890. if (MustInitializeMachines)
  1891. {
  1892. InitializeMachines(g_TargetMachineType);
  1893. }
  1894. KdOut("Target MajorVersion %08lx\n", g_KdVersion.MajorVersion);
  1895. KdOut("Target MinorVersion %08lx\n", g_KdVersion.MinorVersion);
  1896. KdOut("Target ProtocolVersion %08lx\n", g_KdVersion.ProtocolVersion);
  1897. KdOut("Target Flags %08lx\n", g_KdVersion.Flags);
  1898. KdOut("Target MachineType %08lx\n", g_KdVersion.MachineType);
  1899. KdOut("Target MaxPacketType %x\n", g_KdVersion.MaxPacketType);
  1900. KdOut("Target MaxStateChange %x\n", g_KdVersion.MaxStateChange);
  1901. KdOut("Target MaxManipulate %x\n", g_KdVersion.MaxManipulate);
  1902. KdOut("Target KernBase %s\n",
  1903. FormatAddr64(g_KdVersion.KernBase));
  1904. KdOut("Target PsLoadedModuleList %s\n",
  1905. FormatAddr64(g_KdVersion.PsLoadedModuleList));
  1906. KdOut("Target DebuggerDataList %s\n",
  1907. FormatAddr64(g_KdVersion.DebuggerDataList));
  1908. dprintf("Connected to %s %d %s target, ptr64 %s\n",
  1909. SystemVersionName(g_ActualSystemVersion), g_TargetBuildNumber,
  1910. g_TargetMachine->m_FullName,
  1911. g_TargetMachine->m_Ptr64 ? "TRUE" : "FALSE");
  1912. }
  1913. //----------------------------------------------------------------------------
  1914. //
  1915. // LiveKernelTargetInfo miscellaneous methods.
  1916. //
  1917. // Data space methods and system objects methods are elsewhere.
  1918. //
  1919. //----------------------------------------------------------------------------
  1920. HRESULT
  1921. LiveKernelTargetInfo::Initialize(void)
  1922. {
  1923. InitSelCache();
  1924. return S_OK;
  1925. }
  1926. HRESULT
  1927. LiveKernelTargetInfo::ReadBugCheckData(PULONG Code, ULONG64 Args[4])
  1928. {
  1929. ULONG64 BugCheckData;
  1930. ULONG64 Data[5];
  1931. HRESULT Status;
  1932. ULONG Read;
  1933. if (!(BugCheckData = KdDebuggerData.KiBugcheckData))
  1934. {
  1935. if (!GetOffsetFromSym("nt!KiBugCheckData", &BugCheckData, NULL) ||
  1936. !BugCheckData)
  1937. {
  1938. ErrOut("Unable to resolve nt!KiBugCheckData\n");
  1939. return E_NOINTERFACE;
  1940. }
  1941. }
  1942. if (g_TargetMachine->m_Ptr64)
  1943. {
  1944. Status = ReadVirtual(BugCheckData, Data, sizeof(Data), &Read);
  1945. }
  1946. else
  1947. {
  1948. ULONG i;
  1949. ULONG Data32[5];
  1950. Status = ReadVirtual(BugCheckData, Data32, sizeof(Data32), &Read);
  1951. Read *= 2;
  1952. for (i = 0; i < DIMA(Data); i++)
  1953. {
  1954. Data[i] = EXTEND64(Data32[i]);
  1955. }
  1956. }
  1957. if (Status != S_OK || Read != sizeof(Data))
  1958. {
  1959. ErrOut("Unable to read KiBugCheckData\n");
  1960. return Status == S_OK ? E_FAIL : Status;
  1961. }
  1962. *Code = (ULONG)Data[0];
  1963. memcpy(Args, Data + 1, sizeof(Data) - sizeof(ULONG64));
  1964. return S_OK;
  1965. }
  1966. ULONG64
  1967. LiveKernelTargetInfo::GetCurrentTimeDateN(void)
  1968. {
  1969. ULONG64 TimeDate;
  1970. if (ReadSharedUserTimeDateN(&TimeDate) == S_OK)
  1971. {
  1972. return TimeDate;
  1973. }
  1974. else
  1975. {
  1976. return 0;
  1977. }
  1978. }
  1979. ULONG64
  1980. LiveKernelTargetInfo::GetCurrentSystemUpTimeN(void)
  1981. {
  1982. ULONG64 UpTime;
  1983. if (ReadSharedUserUpTimeN(&UpTime) == S_OK)
  1984. {
  1985. return UpTime;
  1986. }
  1987. else
  1988. {
  1989. return 0;
  1990. }
  1991. }
  1992. //----------------------------------------------------------------------------
  1993. //
  1994. // ConnLiveKernelTargetInfo miscellaneous methods.
  1995. //
  1996. // Data space methods and system objects methods are elsewhere.
  1997. //
  1998. //----------------------------------------------------------------------------
  1999. HRESULT
  2000. ConnLiveKernelTargetInfo::Initialize(void)
  2001. {
  2002. HRESULT Status = DbgKdConnectAndInitialize(m_ConnectOptions);
  2003. if (Status == S_OK)
  2004. {
  2005. Status = LiveKernelTargetInfo::Initialize();
  2006. }
  2007. return Status;
  2008. }
  2009. void
  2010. ConnLiveKernelTargetInfo::Uninitialize(void)
  2011. {
  2012. if (g_DbgKdTransport != NULL)
  2013. {
  2014. g_DbgKdTransport->Uninitialize();
  2015. g_DbgKdTransport = NULL;
  2016. }
  2017. LiveKernelTargetInfo::Uninitialize();
  2018. }
  2019. HRESULT
  2020. ConnLiveKernelTargetInfo::GetTargetKdVersion(PDBGKD_GET_VERSION64 Version)
  2021. {
  2022. NTSTATUS Status = DbgKdGetVersion(Version);
  2023. return CONV_NT_STATUS(Status);
  2024. }
  2025. HRESULT
  2026. ConnLiveKernelTargetInfo::RequestBreakIn(void)
  2027. {
  2028. // Tell the waiting thread to break in.
  2029. g_DbgKdTransport->m_BreakIn = TRUE;
  2030. return S_OK;
  2031. }
  2032. HRESULT
  2033. ConnLiveKernelTargetInfo::Reboot(void)
  2034. {
  2035. DbgKdReboot();
  2036. ResetConnection(DEBUG_SESSION_REBOOT);
  2037. return S_OK;
  2038. }
  2039. //----------------------------------------------------------------------------
  2040. //
  2041. // LocalLiveKernelTargetInfo miscellaneous methods.
  2042. //
  2043. // Data space methods and system objects methods are elsewhere.
  2044. //
  2045. //----------------------------------------------------------------------------
  2046. HRESULT
  2047. LocalLiveKernelTargetInfo::Initialize(void)
  2048. {
  2049. DBGKD_GET_VERSION64 Version;
  2050. // Do a quick check to see if this kernel even
  2051. // supports the necessary debug services.
  2052. if (!NT_SUCCESS(g_NtDllCalls.
  2053. NtSystemDebugControl(SysDbgQueryVersion, NULL, 0,
  2054. &Version, sizeof(Version), NULL)))
  2055. {
  2056. ErrOut("The system does not support local kernel debugging.\n");
  2057. ErrOut("Local kernel debugging requires Windows XP, Administrative\n"
  2058. "privileges, and is not supported by WOW64.\n");
  2059. return E_NOTIMPL;
  2060. }
  2061. //
  2062. // Set this right here since we know kernel debugging only works on
  2063. // recent systems using the 64 bit protocol.
  2064. //
  2065. DbgKdApi64 = TRUE;
  2066. return LiveKernelTargetInfo::Initialize();
  2067. }
  2068. HRESULT
  2069. LocalLiveKernelTargetInfo::GetTargetKdVersion(PDBGKD_GET_VERSION64 Version)
  2070. {
  2071. NTSTATUS Status = g_NtDllCalls.
  2072. NtSystemDebugControl(SysDbgQueryVersion, NULL, 0,
  2073. Version, sizeof(*Version), NULL);
  2074. return CONV_NT_STATUS(Status);
  2075. }
  2076. //----------------------------------------------------------------------------
  2077. //
  2078. // ExdiLiveKernelTargetInfo miscellaneous methods.
  2079. //
  2080. // Data space methods and system objects methods are elsewhere.
  2081. //
  2082. //----------------------------------------------------------------------------
  2083. HRESULT
  2084. ExdiNotifyRunChange::Initialize(void)
  2085. {
  2086. m_Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  2087. if (m_Event == NULL)
  2088. {
  2089. return WIN32_LAST_STATUS();
  2090. }
  2091. return S_OK;
  2092. }
  2093. void
  2094. ExdiNotifyRunChange::Uninitialize(void)
  2095. {
  2096. if (m_Event != NULL)
  2097. {
  2098. CloseHandle(m_Event);
  2099. m_Event = NULL;
  2100. }
  2101. }
  2102. STDMETHODIMP
  2103. ExdiNotifyRunChange::QueryInterface(
  2104. THIS_
  2105. IN REFIID InterfaceId,
  2106. OUT PVOID* Interface
  2107. )
  2108. {
  2109. if (DbgIsEqualIID(IID_IUnknown, InterfaceId) ||
  2110. DbgIsEqualIID(__uuidof(IeXdiClientNotifyRunChg), InterfaceId))
  2111. {
  2112. *Interface = this;
  2113. return S_OK;
  2114. }
  2115. *Interface = NULL;
  2116. return E_NOINTERFACE;
  2117. }
  2118. STDMETHODIMP_(ULONG)
  2119. ExdiNotifyRunChange::AddRef(
  2120. THIS
  2121. )
  2122. {
  2123. return 1;
  2124. }
  2125. STDMETHODIMP_(ULONG)
  2126. ExdiNotifyRunChange::Release(
  2127. THIS
  2128. )
  2129. {
  2130. return 0;
  2131. }
  2132. STDMETHODIMP
  2133. ExdiNotifyRunChange::NotifyRunStateChange(RUN_STATUS_TYPE ersCurrent,
  2134. HALT_REASON_TYPE ehrCurrent,
  2135. ADDRESS_TYPE CurrentExecAddress,
  2136. DWORD dwExceptionCode)
  2137. {
  2138. if (ersCurrent == rsRunning)
  2139. {
  2140. // We're waiting for things to stop so ignore this.
  2141. return S_OK;
  2142. }
  2143. m_HaltReason = ehrCurrent;
  2144. m_ExecAddress = CurrentExecAddress;
  2145. m_ExceptionCode = dwExceptionCode;
  2146. SetEvent(m_Event);
  2147. return S_OK;
  2148. }
  2149. class ExdiParams : public ParameterStringParser
  2150. {
  2151. public:
  2152. virtual ULONG GetNumberParameters(void)
  2153. {
  2154. // No need to get.
  2155. return 0;
  2156. }
  2157. virtual void GetParameter(ULONG Index, PSTR Name, PSTR Value)
  2158. {
  2159. }
  2160. virtual void ResetParameters(void);
  2161. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  2162. CLSID m_Clsid;
  2163. EXDI_KD_SUPPORT m_KdSupport;
  2164. BOOL m_ForceX86;
  2165. };
  2166. void
  2167. ExdiParams::ResetParameters(void)
  2168. {
  2169. ZeroMemory(&m_Clsid, sizeof(m_Clsid));
  2170. m_KdSupport = EXDI_KD_NONE;
  2171. m_ForceX86 = FALSE;
  2172. }
  2173. BOOL
  2174. ScanExdiDriverList(PCSTR Name, LPCLSID Clsid)
  2175. {
  2176. char Pattern[MAX_PARAM_VALUE];
  2177. strncpy(Pattern, Name, sizeof(Pattern));
  2178. Pattern[MAX_PARAM_VALUE-1] = 0;
  2179. _strupr(Pattern);
  2180. HKEY ListKey;
  2181. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  2182. "Software\\Microsoft\\eXdi\\DriverList", 0,
  2183. KEY_ALL_ACCESS, &ListKey) != ERROR_SUCCESS)
  2184. {
  2185. return FALSE;
  2186. }
  2187. ULONG Index = 0;
  2188. BOOL Status = FALSE;
  2189. char ValName[MAX_PARAM_VALUE];
  2190. WCHAR WideValName[MAX_PARAM_VALUE];
  2191. ULONG NameLen, ValLen;
  2192. ULONG Type;
  2193. char Value[MAX_PARAM_VALUE];
  2194. for (;;)
  2195. {
  2196. NameLen = sizeof(ValName);
  2197. ValLen = sizeof(Value);
  2198. if (RegEnumValue(ListKey, Index, ValName, &NameLen, NULL,
  2199. &Type, (PBYTE)Value, &ValLen) != ERROR_SUCCESS)
  2200. {
  2201. break;
  2202. }
  2203. if (Type == REG_SZ &&
  2204. MatchPattern(Value, Pattern) &&
  2205. MultiByteToWideChar(CP_ACP, 0, ValName, -1, WideValName,
  2206. sizeof(WideValName) / sizeof(WCHAR)) > 0 &&
  2207. g_Ole32Calls.CLSIDFromString(WideValName, Clsid) == S_OK)
  2208. {
  2209. Status = TRUE;
  2210. break;
  2211. }
  2212. Index++;
  2213. }
  2214. RegCloseKey(ListKey);
  2215. return Status;
  2216. }
  2217. BOOL
  2218. ExdiParams::SetParameter(PCSTR Name, PCSTR Value)
  2219. {
  2220. if (!_strcmpi(Name, "CLSID"))
  2221. {
  2222. WCHAR WideValue[MAX_PARAM_VALUE];
  2223. if (MultiByteToWideChar(CP_ACP, 0, Value, -1, WideValue,
  2224. sizeof(WideValue) / sizeof(WCHAR)) == 0)
  2225. {
  2226. return FALSE;
  2227. }
  2228. return g_Ole32Calls.CLSIDFromString(WideValue, &m_Clsid) == S_OK;
  2229. }
  2230. else if (!_strcmpi(Name, "Desc"))
  2231. {
  2232. return ScanExdiDriverList(Value, &m_Clsid);
  2233. }
  2234. else if (!_strcmpi(Name, "ForceX86"))
  2235. {
  2236. m_ForceX86 = TRUE;
  2237. }
  2238. else if (!_strcmpi(Name, "Kd"))
  2239. {
  2240. if (!Value)
  2241. {
  2242. return FALSE;
  2243. }
  2244. if (!_strcmpi(Value, "Ioctl"))
  2245. {
  2246. m_KdSupport = EXDI_KD_IOCTL;
  2247. }
  2248. else if (!_strcmpi(Value, "GsPcr"))
  2249. {
  2250. m_KdSupport = EXDI_KD_GS_PCR;
  2251. }
  2252. else
  2253. {
  2254. return FALSE;
  2255. }
  2256. }
  2257. else
  2258. {
  2259. return FALSE;
  2260. }
  2261. return TRUE;
  2262. }
  2263. PCSTR g_ExdiGroupNames[] =
  2264. {
  2265. "exdi",
  2266. };
  2267. HRESULT
  2268. ExdiLiveKernelTargetInfo::Initialize(void)
  2269. {
  2270. HRESULT Status;
  2271. // Load ole32.dll so we can call CoCreateInstance.
  2272. if ((Status = InitDynamicCalls(&g_Ole32CallsDesc)) != S_OK)
  2273. {
  2274. return Status;
  2275. }
  2276. ULONG Group;
  2277. Group = ParameterStringParser::
  2278. GetParser(m_ConnectOptions, DIMA(g_ExdiGroupNames), g_ExdiGroupNames);
  2279. if (Group == PARSER_INVALID)
  2280. {
  2281. return E_INVALIDARG;
  2282. }
  2283. ExdiParams Params;
  2284. Params.ResetParameters();
  2285. if (!Params.ParseParameters(m_ConnectOptions))
  2286. {
  2287. return E_INVALIDARG;
  2288. }
  2289. m_KdSupport = Params.m_KdSupport;
  2290. if ((Status = g_Ole32Calls.
  2291. CoInitializeEx(NULL, COINIT_MULTITHREADED)) != S_OK)
  2292. {
  2293. return Status;
  2294. }
  2295. if ((Status = g_Ole32Calls.CoCreateInstance(Params.m_Clsid, NULL,
  2296. CLSCTX_LOCAL_SERVER,
  2297. __uuidof(IeXdiServer),
  2298. (PVOID*)&m_Server)) != S_OK)
  2299. {
  2300. goto EH_CoInit;
  2301. }
  2302. if ((Status = m_Server->GetTargetInfo(&m_GlobalInfo)) != S_OK)
  2303. {
  2304. goto EH_Server;
  2305. }
  2306. if (Params.m_ForceX86 ||
  2307. m_GlobalInfo.TargetProcessorFamily == PROCESSOR_FAMILY_X86)
  2308. {
  2309. if (!Params.m_ForceX86 &&
  2310. (Status = m_Server->
  2311. QueryInterface(__uuidof(IeXdiX86_64Context),
  2312. (PVOID*)&m_Context)) == S_OK)
  2313. {
  2314. m_ExpectedMachine = IMAGE_FILE_MACHINE_AMD64;
  2315. }
  2316. else if ((Status = m_Server->
  2317. QueryInterface(__uuidof(IeXdiX86Context),
  2318. (PVOID*)&m_Context)) == S_OK)
  2319. {
  2320. m_ExpectedMachine = IMAGE_FILE_MACHINE_I386;
  2321. }
  2322. else
  2323. {
  2324. goto EH_Server;
  2325. }
  2326. }
  2327. else
  2328. {
  2329. Status = E_NOINTERFACE;
  2330. goto EH_Server;
  2331. }
  2332. DWORD HwCode, SwCode;
  2333. if ((Status = m_Server->GetNbCodeBpAvail(&HwCode, &SwCode)) != S_OK)
  2334. {
  2335. goto EH_Context;
  2336. }
  2337. // We'd prefer to use software code breakpoints for our
  2338. // software code breakpoints so that hardware resources
  2339. // aren't consumed for a breakpoint we don't need to
  2340. // use hardware for. However, some servers, such as
  2341. // the x86-64 SimNow implementation, do not support
  2342. // software breakpoints.
  2343. // Also, if the number of hardware breakpoints is
  2344. // unbounded, go ahead and let the server choose.
  2345. // SimNow advertises -1 -1 for some reason and
  2346. // this is necessary to get things to work.
  2347. if (SwCode > 0 && HwCode != (DWORD)-1)
  2348. {
  2349. m_CodeBpType = cbptSW;
  2350. }
  2351. else
  2352. {
  2353. m_CodeBpType = cbptAlgo;
  2354. }
  2355. if ((Status = m_RunChange.Initialize()) != S_OK)
  2356. {
  2357. goto EH_Context;
  2358. }
  2359. if ((Status = LiveKernelTargetInfo::Initialize()) != S_OK)
  2360. {
  2361. goto EH_RunChange;
  2362. }
  2363. m_ContextValid = 0;
  2364. return S_OK;
  2365. EH_RunChange:
  2366. m_RunChange.Uninitialize();
  2367. EH_Context:
  2368. RELEASE(m_Context);
  2369. EH_Server:
  2370. RELEASE(m_Server);
  2371. EH_CoInit:
  2372. g_Ole32Calls.CoUninitialize();
  2373. return Status;
  2374. }
  2375. HRESULT
  2376. ExdiLiveKernelTargetInfo::ThreadInitialize(void)
  2377. {
  2378. return g_Ole32Calls.CoInitializeEx(NULL, COINIT_MULTITHREADED);
  2379. }
  2380. void
  2381. ExdiLiveKernelTargetInfo::ThreadUninitialize(void)
  2382. {
  2383. g_Ole32Calls.CoUninitialize();
  2384. }
  2385. void
  2386. ExdiLiveKernelTargetInfo::Uninitialize(void)
  2387. {
  2388. m_RunChange.Uninitialize();
  2389. RELEASE(m_Context);
  2390. RELEASE(m_Server);
  2391. g_Ole32Calls.CoUninitialize();
  2392. }
  2393. #define EXDI_IOCTL_GET_KD_VERSION ((ULONG)'VDKG')
  2394. HRESULT
  2395. ExdiLiveKernelTargetInfo::GetTargetKdVersion(PDBGKD_GET_VERSION64 Version)
  2396. {
  2397. switch(m_KdSupport)
  2398. {
  2399. case EXDI_KD_IOCTL:
  2400. //
  2401. // User has indicated the target supports the
  2402. // KD version ioctl.
  2403. //
  2404. ULONG Command;
  2405. ULONG Retrieved;
  2406. HRESULT Status;
  2407. Command = EXDI_IOCTL_GET_KD_VERSION;
  2408. if ((Status = m_Server->Ioctl(sizeof(Command), (PBYTE)&Command,
  2409. sizeof(*Version), &Retrieved,
  2410. (PBYTE)Version)) != S_OK)
  2411. {
  2412. return Status;
  2413. }
  2414. if (Retrieved != sizeof(*Version))
  2415. {
  2416. return E_FAIL;
  2417. }
  2418. // This mode implies a recent kernel so we can
  2419. // assume 64-bit kd.
  2420. DbgKdApi64 = TRUE;
  2421. break;
  2422. case EXDI_KD_GS_PCR:
  2423. //
  2424. // User has indicated that a version of NT
  2425. // is running and that the PCR can be accessed
  2426. // through GS. Look up the version block from
  2427. // the PCR.
  2428. //
  2429. if (m_ExpectedMachine == IMAGE_FILE_MACHINE_AMD64)
  2430. {
  2431. ULONG64 KdVer;
  2432. ULONG Done;
  2433. if ((Status = g_Amd64Machine.
  2434. GetExdiContext(m_Context, &m_ContextData)) != S_OK)
  2435. {
  2436. return Status;
  2437. }
  2438. if ((Status = m_Server->
  2439. ReadVirtualMemory(m_ContextData.Amd64Context.
  2440. DescriptorGs.SegBase +
  2441. FIELD_OFFSET(AMD64_KPCR, KdVersionBlock),
  2442. sizeof(KdVer), 8, (PBYTE)&KdVer,
  2443. &Done)) != S_OK)
  2444. {
  2445. return Status;
  2446. }
  2447. if (Done != sizeof(KdVer))
  2448. {
  2449. return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
  2450. }
  2451. if ((Status = m_Server->
  2452. ReadVirtualMemory(KdVer, sizeof(*Version), 8, (PBYTE)Version,
  2453. &Done)) != S_OK)
  2454. {
  2455. return Status;
  2456. }
  2457. if (Done != sizeof(*Version))
  2458. {
  2459. return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
  2460. }
  2461. // This mode implies a recent kernel so we can
  2462. // assume 64-bit kd.
  2463. DbgKdApi64 = TRUE;
  2464. // Update the version block's Simulation field to
  2465. // indicate that this is a simulated execution.
  2466. Version->Simulation = DBGKD_SIMULATION_EXDI;
  2467. if ((Status = m_Server->
  2468. WriteVirtualMemory(KdVer, sizeof(*Version), 8, (PBYTE)Version,
  2469. &Done)) != S_OK)
  2470. {
  2471. return Status;
  2472. }
  2473. if (Done != sizeof(*Version))
  2474. {
  2475. return HRESULT_FROM_WIN32(ERROR_WRITE_FAULT);
  2476. }
  2477. }
  2478. else
  2479. {
  2480. return E_INVALIDARG;
  2481. }
  2482. break;
  2483. case EXDI_KD_NONE:
  2484. //
  2485. // Fake up a version structure.
  2486. //
  2487. Version->MajorVersion = KD_MAJOR_EXDI << 8;
  2488. Version->ProtocolVersion = 0;
  2489. Version->Flags = DBGKD_VERS_FLAG_PTR64 | DBGKD_VERS_FLAG_NOMM;
  2490. Version->MachineType = (USHORT)m_ExpectedMachine;
  2491. Version->KernBase = 0;
  2492. Version->PsLoadedModuleList = 0;
  2493. Version->DebuggerDataList = 0;
  2494. break;
  2495. }
  2496. return S_OK;
  2497. }
  2498. HRESULT
  2499. ExdiLiveKernelTargetInfo::RequestBreakIn(void)
  2500. {
  2501. return m_Server->Halt();
  2502. }
  2503. HRESULT
  2504. ExdiLiveKernelTargetInfo::Reboot(void)
  2505. {
  2506. HRESULT Status = m_Server->Reboot();
  2507. if (Status == S_OK)
  2508. {
  2509. ResetConnection(DEBUG_SESSION_REBOOT);
  2510. }
  2511. return Status;
  2512. }
  2513. //----------------------------------------------------------------------------
  2514. //
  2515. // UserTargetInfo miscellaneous methods.
  2516. //
  2517. // Data space methods and system objects methods are elsewhere.
  2518. //
  2519. //----------------------------------------------------------------------------
  2520. HRESULT
  2521. UserTargetInfo::Initialize(void)
  2522. {
  2523. // Nothing to do right now.
  2524. return S_OK;
  2525. }
  2526. void
  2527. UserTargetInfo::Uninitialize(void)
  2528. {
  2529. RELEASE(m_Services);
  2530. }
  2531. HRESULT
  2532. UserTargetInfo::GetImageVersionInformation(PCSTR ImagePath,
  2533. ULONG64 ImageBase,
  2534. PCSTR Item,
  2535. PVOID Buffer,
  2536. ULONG BufferSize,
  2537. PULONG VerInfoSize)
  2538. {
  2539. return m_Services->
  2540. GetFileVersionInformation(ImagePath, Item,
  2541. Buffer, BufferSize, VerInfoSize);
  2542. }
  2543. ULONG64
  2544. UserTargetInfo::GetCurrentTimeDateN(void)
  2545. {
  2546. ULONG64 TimeDate;
  2547. if (m_Services->GetCurrentTimeDateN(&TimeDate) == S_OK)
  2548. {
  2549. return TimeDate;
  2550. }
  2551. else
  2552. {
  2553. return 0;
  2554. }
  2555. }
  2556. ULONG64
  2557. UserTargetInfo::GetCurrentSystemUpTimeN(void)
  2558. {
  2559. ULONG64 UpTime;
  2560. if (m_Services->GetCurrentSystemUpTimeN(&UpTime) == S_OK)
  2561. {
  2562. return UpTime;
  2563. }
  2564. else
  2565. {
  2566. return 0;
  2567. }
  2568. }
  2569. ULONG64
  2570. UserTargetInfo::GetProcessUpTimeN(ULONG64 Process)
  2571. {
  2572. ULONG64 UpTime;
  2573. if (m_Services->GetProcessUpTimeN(Process, &UpTime) == S_OK)
  2574. {
  2575. return UpTime;
  2576. }
  2577. else
  2578. {
  2579. return 0;
  2580. }
  2581. }
  2582. HRESULT
  2583. UserTargetInfo::RequestBreakIn(void)
  2584. {
  2585. PPROCESS_INFO Process = g_CurrentProcess;
  2586. if (Process == NULL)
  2587. {
  2588. Process = g_ProcessHead;
  2589. if (Process == NULL)
  2590. {
  2591. return E_UNEXPECTED;
  2592. }
  2593. }
  2594. return m_Services->RequestBreakIn(Process->FullHandle);
  2595. }
  2596. //----------------------------------------------------------------------------
  2597. //
  2598. // Base TargetInfo methods that trivially fail.
  2599. //
  2600. //----------------------------------------------------------------------------
  2601. #define UNEXPECTED_VOID(Class, Method, Args) \
  2602. void \
  2603. Class::Method Args \
  2604. { \
  2605. ErrOut("TargetInfo::" #Method " is not available in the current debug session\n"); \
  2606. }
  2607. #define UNEXPECTED_HR(Class, Method, Args) \
  2608. HRESULT \
  2609. Class::Method Args \
  2610. { \
  2611. ErrOut("TargetInfo::" #Method " is not available in the current debug session\n"); \
  2612. return E_UNEXPECTED; \
  2613. }
  2614. #define UNEXPECTED_ULONG64(Class, Method, Val, Args) \
  2615. ULONG64 \
  2616. Class::Method Args \
  2617. { \
  2618. ErrOut("TargetInfo::" #Method " is not available in the current debug session\n"); \
  2619. return Val; \
  2620. }
  2621. TargetInfo g_UnexpectedTarget;
  2622. UNEXPECTED_HR(TargetInfo, Initialize, (void))
  2623. UNEXPECTED_HR(TargetInfo, ReadVirtual, (
  2624. IN ULONG64 Offset,
  2625. OUT PVOID Buffer,
  2626. IN ULONG BufferSize,
  2627. OUT OPTIONAL PULONG BytesRead
  2628. ))
  2629. UNEXPECTED_HR(TargetInfo, WriteVirtual, (
  2630. IN ULONG64 Offset,
  2631. IN PVOID Buffer,
  2632. IN ULONG BufferSize,
  2633. OUT OPTIONAL PULONG BytesWritten
  2634. ))
  2635. UNEXPECTED_HR(TargetInfo, ReadPhysical, (
  2636. IN ULONG64 Offset,
  2637. OUT PVOID Buffer,
  2638. IN ULONG BufferSize,
  2639. OUT OPTIONAL PULONG BytesRead
  2640. ))
  2641. UNEXPECTED_HR(TargetInfo, WritePhysical, (
  2642. IN ULONG64 Offset,
  2643. IN PVOID Buffer,
  2644. IN ULONG BufferSize,
  2645. OUT OPTIONAL PULONG BytesWritten
  2646. ))
  2647. UNEXPECTED_HR(TargetInfo, ReadControl, (
  2648. IN ULONG Processor,
  2649. IN ULONG64 Offset,
  2650. OUT PVOID Buffer,
  2651. IN ULONG BufferSize,
  2652. OUT OPTIONAL PULONG BytesRead
  2653. ))
  2654. UNEXPECTED_HR(TargetInfo, WriteControl, (
  2655. IN ULONG Processor,
  2656. IN ULONG64 Offset,
  2657. IN PVOID Buffer,
  2658. IN ULONG BufferSize,
  2659. OUT OPTIONAL PULONG BytesWritten
  2660. ))
  2661. UNEXPECTED_HR(TargetInfo, ReadIo, (
  2662. IN ULONG InterfaceType,
  2663. IN ULONG BusNumber,
  2664. IN ULONG AddressSpace,
  2665. IN ULONG64 Offset,
  2666. OUT PVOID Buffer,
  2667. IN ULONG BufferSize,
  2668. OUT OPTIONAL PULONG BytesRead
  2669. ))
  2670. UNEXPECTED_HR(TargetInfo, WriteIo, (
  2671. IN ULONG InterfaceType,
  2672. IN ULONG BusNumber,
  2673. IN ULONG AddressSpace,
  2674. IN ULONG64 Offset,
  2675. IN PVOID Buffer,
  2676. IN ULONG BufferSize,
  2677. OUT OPTIONAL PULONG BytesWritten
  2678. ))
  2679. UNEXPECTED_HR(TargetInfo, ReadMsr, (
  2680. IN ULONG Msr,
  2681. OUT PULONG64 Value
  2682. ))
  2683. UNEXPECTED_HR(TargetInfo, WriteMsr, (
  2684. IN ULONG Msr,
  2685. IN ULONG64 Value
  2686. ))
  2687. UNEXPECTED_HR(TargetInfo, ReadBusData, (
  2688. IN ULONG BusDataType,
  2689. IN ULONG BusNumber,
  2690. IN ULONG SlotNumber,
  2691. IN ULONG Offset,
  2692. OUT PVOID Buffer,
  2693. IN ULONG BufferSize,
  2694. OUT OPTIONAL PULONG BytesRead
  2695. ))
  2696. UNEXPECTED_HR(TargetInfo, WriteBusData, (
  2697. IN ULONG BusDataType,
  2698. IN ULONG BusNumber,
  2699. IN ULONG SlotNumber,
  2700. IN ULONG Offset,
  2701. IN PVOID Buffer,
  2702. IN ULONG BufferSize,
  2703. OUT OPTIONAL PULONG BytesWritten
  2704. ))
  2705. UNEXPECTED_HR(TargetInfo, CheckLowMemory, (
  2706. ))
  2707. UNEXPECTED_HR(TargetInfo, ReadHandleData, (
  2708. IN ULONG64 Handle,
  2709. IN ULONG DataType,
  2710. OUT OPTIONAL PVOID Buffer,
  2711. IN ULONG BufferSize,
  2712. OUT OPTIONAL PULONG DataSize
  2713. ))
  2714. UNEXPECTED_HR(TargetInfo, GetTargetContext, (
  2715. ULONG64 Thread,
  2716. PVOID Context
  2717. ))
  2718. UNEXPECTED_HR(TargetInfo, SetTargetContext, (
  2719. ULONG64 Thread,
  2720. PVOID Context
  2721. ))
  2722. UNEXPECTED_HR(TargetInfo, GetThreadIdByProcessor, (
  2723. IN ULONG Processor,
  2724. OUT PULONG Id
  2725. ))
  2726. UNEXPECTED_HR(TargetInfo, GetThreadInfoDataOffset, (
  2727. PTHREAD_INFO Thread,
  2728. ULONG64 ThreadHandle,
  2729. PULONG64 Offset))
  2730. UNEXPECTED_HR(TargetInfo, GetProcessInfoDataOffset, (
  2731. PTHREAD_INFO Thread,
  2732. ULONG Processor,
  2733. ULONG64 ThreadData,
  2734. PULONG64 Offset))
  2735. UNEXPECTED_HR(TargetInfo, GetThreadInfoTeb, (
  2736. PTHREAD_INFO Thread,
  2737. ULONG Processor,
  2738. ULONG64 ThreadData,
  2739. PULONG64 Offset))
  2740. UNEXPECTED_HR(TargetInfo, GetProcessInfoPeb, (
  2741. PTHREAD_INFO Thread,
  2742. ULONG Processor,
  2743. ULONG64 ThreadData,
  2744. PULONG64 Offset))
  2745. UNEXPECTED_HR(TargetInfo, GetSelDescriptor, (
  2746. MachineInfo* Machine,
  2747. ULONG64 Thread,
  2748. ULONG Selector,
  2749. PDESCRIPTOR64 Desc))
  2750. UNEXPECTED_HR(TargetInfo, GetTargetKdVersion, (
  2751. PDBGKD_GET_VERSION64 Version))
  2752. UNEXPECTED_HR(TargetInfo, ReadBugCheckData, (
  2753. PULONG Code, ULONG64 Args[4]))
  2754. UNEXPECTED_HR(TargetInfo, GetExceptionContext, (
  2755. PCROSS_PLATFORM_CONTEXT Context))
  2756. UNEXPECTED_VOID(TargetInfo, InitializeWatchTrace, (
  2757. void))
  2758. UNEXPECTED_VOID(TargetInfo, ProcessWatchTraceEvent, (
  2759. PDBGKD_TRACE_DATA TraceData,
  2760. ADDR PcAddr))
  2761. UNEXPECTED_HR(TargetInfo, WaitForEvent, (
  2762. ULONG Flags,
  2763. ULONG Timeout))
  2764. UNEXPECTED_HR(TargetInfo, RequestBreakIn, (void))
  2765. UNEXPECTED_HR(TargetInfo, Reboot, (void))
  2766. UNEXPECTED_HR(TargetInfo, InsertCodeBreakpoint, (
  2767. PPROCESS_INFO Process,
  2768. MachineInfo* Machine,
  2769. PADDR Addr,
  2770. PUCHAR StorageSpace))
  2771. UNEXPECTED_HR(TargetInfo, RemoveCodeBreakpoint, (
  2772. PPROCESS_INFO Process,
  2773. MachineInfo* Machine,
  2774. PADDR Addr,
  2775. PUCHAR StorageSpace))
  2776. UNEXPECTED_HR(TargetInfo, QueryMemoryRegion, (
  2777. PULONG64 Handle,
  2778. BOOL HandleIsOffset,
  2779. PMEMORY_BASIC_INFORMATION64 Info))