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.

2661 lines
72 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Abstraction of target-specific information.
  4. //
  5. // Copyright (C) Microsoft Corporation, 1999-2002.
  6. //
  7. //----------------------------------------------------------------------------
  8. #include "ntsdp.hpp"
  9. ULONG g_NumberTargets;
  10. TargetInfo* g_TargetHead;
  11. //----------------------------------------------------------------------------
  12. //
  13. // TargetInfo.
  14. //
  15. //----------------------------------------------------------------------------
  16. TargetInfo::TargetInfo(ULONG Class, ULONG Qual, BOOL DynamicEvents)
  17. {
  18. m_Class = Class;
  19. m_ClassQualifier = Qual;
  20. m_DynamicEvents = DynamicEvents;
  21. m_UserId = FindNextUserId(LAYER_TARGET);
  22. m_Next = NULL;
  23. m_NumEvents = 1;
  24. m_EventIndex = 0;
  25. m_NextEventIndex = 0;
  26. m_FirstWait = TRUE;
  27. m_EventPossible = FALSE;
  28. m_BreakInMessage = FALSE;
  29. FlushSelectorCache();
  30. m_PhysicalCache.SetTarget(this);
  31. PCHAR CacheEnv = getenv("_NT_DEBUG_CACHE_SIZE");
  32. if (CacheEnv != NULL)
  33. {
  34. m_PhysicalCache.m_MaxSize = atol(CacheEnv);
  35. m_PhysicalCache.m_UserSize = m_PhysicalCache.m_MaxSize;
  36. }
  37. ResetSystemInfo();
  38. }
  39. TargetInfo::~TargetInfo(void)
  40. {
  41. DeleteSystemInfo();
  42. Unlink();
  43. g_UserIdFragmented[LAYER_TARGET]++;
  44. if (g_Target == this)
  45. {
  46. g_Target = NULL;
  47. }
  48. if (g_EventTarget == this)
  49. {
  50. g_EventTarget = NULL;
  51. DiscardLastEvent();
  52. }
  53. }
  54. void
  55. TargetInfo::Link(void)
  56. {
  57. TargetInfo* Cur;
  58. TargetInfo* Prev;
  59. Prev = NULL;
  60. for (Cur = g_TargetHead; Cur; Cur = Cur->m_Next)
  61. {
  62. if (Cur->m_UserId > this->m_UserId)
  63. {
  64. break;
  65. }
  66. Prev = Cur;
  67. }
  68. m_Next = Cur;
  69. if (!Prev)
  70. {
  71. g_TargetHead = this;
  72. }
  73. else
  74. {
  75. Prev->m_Next = this;
  76. }
  77. g_NumberTargets++;
  78. NotifyChangeEngineState(DEBUG_CES_SYSTEMS, m_UserId, TRUE);
  79. }
  80. void
  81. TargetInfo::Unlink(void)
  82. {
  83. TargetInfo* Cur;
  84. TargetInfo* Prev;
  85. Prev = NULL;
  86. for (Cur = g_TargetHead; Cur; Cur = Cur->m_Next)
  87. {
  88. if (Cur == this)
  89. {
  90. break;
  91. }
  92. Prev = Cur;
  93. }
  94. if (!Cur)
  95. {
  96. return;
  97. }
  98. if (!Prev)
  99. {
  100. g_TargetHead = this->m_Next;
  101. }
  102. else
  103. {
  104. Prev->m_Next = this->m_Next;
  105. }
  106. g_NumberTargets--;
  107. NotifyChangeEngineState(DEBUG_CES_SYSTEMS, DEBUG_ANY_ID, TRUE);
  108. }
  109. HRESULT
  110. TargetInfo::Initialize(void)
  111. {
  112. return S_OK;
  113. }
  114. void
  115. TargetInfo::DebuggeeReset(ULONG Reason, BOOL FromEvent)
  116. {
  117. if (Reason == DEBUG_SESSION_REBOOT)
  118. {
  119. dprintf("Shutdown occurred...unloading all symbol tables.\n");
  120. }
  121. else if (Reason == DEBUG_SESSION_HIBERNATE)
  122. {
  123. dprintf("Hibernate occurred\n");
  124. }
  125. if (FromEvent && g_EventTarget == this)
  126. {
  127. g_EngStatus &= ~ENG_STATUS_SUSPENDED;
  128. }
  129. DeleteSystemInfo();
  130. ResetSystemInfo();
  131. // If we were waiting for a shutdown event
  132. // reset the command state to indicate that
  133. // we successfully received the shutdown.
  134. if (FromEvent && SPECIAL_EXECUTION(g_CmdState))
  135. {
  136. g_CmdState = 'i';
  137. }
  138. DiscardedTargets(Reason);
  139. }
  140. HRESULT
  141. TargetInfo::SwitchToTarget(TargetInfo* From)
  142. {
  143. SetPromptThread(m_CurrentProcess->m_CurrentThread,
  144. SPT_DEFAULT_OCI_FLAGS);
  145. return S_OK;
  146. }
  147. ModuleInfo*
  148. TargetInfo::GetModuleInfo(BOOL UserMode)
  149. {
  150. if (UserMode)
  151. {
  152. switch(m_PlatformId)
  153. {
  154. case VER_PLATFORM_WIN32_NT:
  155. return &g_NtTargetUserModuleIterator;
  156. case VER_PLATFORM_WIN32_WINDOWS:
  157. case VER_PLATFORM_WIN32_CE:
  158. return &g_ToolHelpModuleIterator;
  159. default:
  160. ErrOut("System module info not available\n");
  161. return NULL;
  162. }
  163. }
  164. else
  165. {
  166. if (m_PlatformId != VER_PLATFORM_WIN32_NT)
  167. {
  168. ErrOut("System module info only available on "
  169. "Windows NT/2000/XP\n");
  170. return NULL;
  171. }
  172. DBG_ASSERT(IS_KERNEL_TARGET(this));
  173. return &g_NtKernelModuleIterator;
  174. }
  175. }
  176. UnloadedModuleInfo*
  177. TargetInfo::GetUnloadedModuleInfo(void)
  178. {
  179. if (m_PlatformId != VER_PLATFORM_WIN32_NT)
  180. {
  181. ErrOut("System unloaded module info only available on "
  182. "Windows NT/2000/XP\n");
  183. return NULL;
  184. }
  185. if (IS_KERNEL_TARGET(this))
  186. {
  187. return &g_NtKernelUnloadedModuleIterator;
  188. }
  189. else
  190. {
  191. return &g_NtUserUnloadedModuleIterator;
  192. }
  193. }
  194. HRESULT
  195. TargetInfo::GetImageVersionInformation(ProcessInfo* Process,
  196. PCSTR ImagePath,
  197. ULONG64 ImageBase,
  198. PCSTR Item,
  199. PVOID Buffer, ULONG BufferSize,
  200. PULONG VerInfoSize)
  201. {
  202. HRESULT Status;
  203. IMAGE_NT_HEADERS64 NtHdr;
  204. //
  205. // This default implementation attempts to read the image's
  206. // raw version information in memory.
  207. //
  208. if ((Status = ReadImageNtHeaders(Process, ImageBase, &NtHdr)) != S_OK)
  209. {
  210. return Status;
  211. }
  212. if (NtHdr.OptionalHeader.NumberOfRvaAndSizes <=
  213. IMAGE_DIRECTORY_ENTRY_RESOURCE)
  214. {
  215. // No resource information so no version information.
  216. return E_NOINTERFACE;
  217. }
  218. return ReadImageVersionInfo(Process, ImageBase, Item,
  219. Buffer, BufferSize, VerInfoSize,
  220. &NtHdr.OptionalHeader.
  221. DataDirectory[IMAGE_DIRECTORY_ENTRY_RESOURCE]);
  222. }
  223. HRESULT
  224. TargetInfo::Reload(ThreadInfo* Thread,
  225. PCSTR Args, PCSTR* ArgsRet)
  226. {
  227. HRESULT Status;
  228. CHAR AnsiString[MAX_IMAGE_PATH];
  229. LPSTR SpecificModule = NULL;
  230. BOOL SpecificWild = TRUE;
  231. ULONG64 Address = 0;
  232. ULONG ImageSize = 0;
  233. PCHAR Scan;
  234. ULONG ModCount;
  235. BOOL IgnoreSignature = FALSE;
  236. ULONG ReloadSymOptions;
  237. BOOL UnloadOnly = FALSE;
  238. BOOL ReallyVerbose = FALSE;
  239. BOOL LoadUserSymbols = TRUE;
  240. BOOL UserModeList = IS_USER_TARGET(this);
  241. BOOL ForceSymbolLoad = FALSE;
  242. BOOL PrintImageListOnly = FALSE;
  243. BOOL AddrLoad = FALSE;
  244. BOOL UseDebuggerModuleList;
  245. BOOL SkipPathChecks = FALSE;
  246. ModuleInfo* ModIter;
  247. BOOL Wow64ModLoaded = FALSE;
  248. HRESULT RetStatus = S_OK;
  249. MODULE_INFO_ENTRY ModEntry = {0};
  250. ProcessInfo* Process;
  251. ImageInfo* ImageAdded;
  252. if ((!IS_USER_TARGET(this) && !IS_KERNEL_TARGET(this)) ||
  253. !Thread)
  254. {
  255. ErrOut("Reload failure, partially initialized target\n");
  256. return E_UNEXPECTED;
  257. }
  258. Process = Thread->m_Process;
  259. // Historically, live user-mode reload has always
  260. // just used the internal module list so preserve that.
  261. UseDebuggerModuleList = IS_USER_TARGET(this) && !IS_DUMP_TARGET(this);
  262. for (;;)
  263. {
  264. while (*Args && *Args <= ' ')
  265. {
  266. Args++;
  267. }
  268. if (*Args != '/' && *Args != '-')
  269. {
  270. break;
  271. }
  272. Args++;
  273. while (*Args > ' ' && *Args != ';')
  274. {
  275. switch(*Args++)
  276. {
  277. case 'a':
  278. // for internal use only: loads whatever is found at the
  279. // passed address
  280. AddrLoad = TRUE;
  281. break;
  282. case 'd':
  283. UseDebuggerModuleList = TRUE;
  284. break;
  285. case 'f':
  286. ForceSymbolLoad = TRUE;
  287. break;
  288. case 'i':
  289. IgnoreSignature = TRUE;
  290. // We always force symbol loading in this
  291. // case as we can't delay ignoring the signature.
  292. ForceSymbolLoad = TRUE;
  293. break;
  294. case 'l':
  295. PrintImageListOnly = TRUE;
  296. break;
  297. case 'n':
  298. LoadUserSymbols = FALSE;
  299. break;
  300. case 'P':
  301. // Internal-only switch.
  302. SkipPathChecks = TRUE;
  303. break;
  304. case 's':
  305. UseDebuggerModuleList = FALSE;
  306. break;
  307. case 'u':
  308. if (!_strnicmp(Args, "ser", 3) &&
  309. (Args[3] == ' ' || Args[3] == '\t' || !Args[3]))
  310. {
  311. UserModeList = TRUE;
  312. if (!m_SystemRangeStart)
  313. {
  314. ErrOut("Unknown system range start, "
  315. "check kernel symbols\n");
  316. *ArgsRet = Args;
  317. return E_INVALIDARG;
  318. }
  319. Args += 3;
  320. }
  321. else
  322. {
  323. UnloadOnly = TRUE;
  324. }
  325. break;
  326. case 'v':
  327. ReallyVerbose = TRUE;
  328. break;
  329. case 'w':
  330. SpecificWild = FALSE;
  331. break;
  332. default:
  333. dprintf("Reload: Unknown option '%c'\n", Args[-1]);
  334. case '?':
  335. dprintf("Usage: .reload [flags] [module [= Address "
  336. "[, Size] ]]\n");
  337. dprintf(" Flags: /d Use the debugger's module list\n");
  338. dprintf(" Default for live user-mode "
  339. "sessions\n");
  340. dprintf(" /f Force immediate symbol load "
  341. "instead of deferred\n");
  342. dprintf(" /i Force symbol load by ignoring "
  343. "mismatches in the pdb signature\n"
  344. " (implies /f)\n");
  345. dprintf(" /l Just list the modules. "
  346. "Kernel output same as !drivers\n");
  347. dprintf(" /n Do not load from user-mode list "
  348. "in kernel sessions\n");
  349. dprintf(" /s Use the system's module list\n");
  350. dprintf(" Default for dump and kernel sessions\n");
  351. dprintf(" /u Unload modules, no reload\n");
  352. dprintf(" /user Load only user-mode modules "
  353. "in kernel sessions\n");
  354. dprintf(" /v Verbose\n");
  355. dprintf(" /w No wildcard matching on "
  356. "module name\n");
  357. dprintf("\nUse \".hh .reload\" or open debugger.chm in "
  358. "the debuggers directory to get\n"
  359. "detailed documentation on this command.\n\n");
  360. *ArgsRet = Args;
  361. return E_INVALIDARG;
  362. }
  363. }
  364. }
  365. PSTR RawString;
  366. ULONG RawStringLen;
  367. RawString = BufferStringValue((PSTR*)&Args,
  368. STRV_SPACE_IS_SEPARATOR |
  369. STRV_ALLOW_EMPTY_STRING |
  370. STRV_NO_MODIFICATION,
  371. &RawStringLen, NULL);
  372. *ArgsRet = Args;
  373. if (!RawString || !RawStringLen)
  374. {
  375. AddrLoad = FALSE;
  376. }
  377. else
  378. {
  379. if (RawStringLen >= DIMA(AnsiString))
  380. {
  381. return E_INVALIDARG;
  382. }
  383. memcpy(AnsiString, RawString, RawStringLen * sizeof(*RawString));
  384. AnsiString[RawStringLen] = 0;
  385. //
  386. // Support .reload <image.ext>=<base>,<size>.
  387. //
  388. if (Scan = strchr(AnsiString, '='))
  389. {
  390. *Scan++ = 0;
  391. Address = EvalStringNumAndCatch(Scan);
  392. if (!Address)
  393. {
  394. ErrOut("Invalid address %s\n", Scan);
  395. return E_INVALIDARG;
  396. }
  397. if (!m_Machine->m_Ptr64)
  398. {
  399. Address = EXTEND64(Address);
  400. }
  401. if (Scan = strchr(Scan, ','))
  402. {
  403. Scan++;
  404. ImageSize = (ULONG)EvalStringNumAndCatch(Scan);
  405. if (!ImageSize)
  406. {
  407. ErrOut("Invalid ImageSize %s\n", Scan);
  408. return E_INVALIDARG;
  409. }
  410. }
  411. }
  412. if (UnloadOnly)
  413. {
  414. BOOL Deleted;
  415. Deleted = Process->
  416. DeleteImageByName(AnsiString, INAME_MODULE);
  417. if (!Deleted)
  418. {
  419. // The user might have given an image name
  420. // instead of a module name so try that.
  421. Deleted = Process->DeleteImageByName
  422. (PathTail(AnsiString), INAME_IMAGE_PATH_TAIL);
  423. }
  424. if (Deleted)
  425. {
  426. dprintf("Unloaded %s\n", AnsiString);
  427. return S_OK;
  428. }
  429. else
  430. {
  431. dprintf("Unable to find module '%s'\n", AnsiString);
  432. return E_NOINTERFACE;
  433. }
  434. }
  435. SpecificModule = _strdup(AnsiString);
  436. if (!SpecificModule)
  437. {
  438. return E_OUTOFMEMORY;
  439. }
  440. if (IS_KERNEL_TARGET(this) &&
  441. _stricmp(AnsiString, KERNEL_MODULE_NAME) == 0)
  442. {
  443. ForceSymbolLoad = TRUE;
  444. }
  445. else
  446. {
  447. if (AddrLoad)
  448. {
  449. free(SpecificModule);
  450. SpecificModule = NULL;
  451. }
  452. }
  453. }
  454. if (!PrintImageListOnly && !SkipPathChecks)
  455. {
  456. if (g_SymbolSearchPath == NULL ||
  457. *g_SymbolSearchPath == NULL)
  458. {
  459. dprintf("*********************************************************************\n");
  460. dprintf("* Symbols can not be loaded because symbol path is not initialized. *\n");
  461. dprintf("* *\n");
  462. dprintf("* The Symbol Path can be set by: *\n");
  463. dprintf("* using the _NT_SYMBOL_PATH environment variable. *\n");
  464. dprintf("* using the -y <symbol_path> argument when starting the debugger. *\n");
  465. dprintf("* using .sympath and .sympath+ *\n");
  466. dprintf("*********************************************************************\n");
  467. RetStatus = E_INVALIDARG;
  468. goto FreeSpecMod;
  469. }
  470. if (IS_DUMP_WITH_MAPPED_IMAGES(this) &&
  471. (g_ExecutableImageSearchPath == NULL ||
  472. *g_ExecutableImageSearchPath == NULL))
  473. {
  474. dprintf("*********************************************************************\n");
  475. dprintf("* Analyzing Minidumps requires access to the actual executable *\n");
  476. dprintf("* images for the crashed system *\n");
  477. dprintf("* *\n");
  478. dprintf("* The Executable Image Path can be set by: *\n");
  479. dprintf("* using the _NT_EXECUTABLE_IMAGE_PATH environment variable. *\n");
  480. dprintf("* using the -i <image_path> argument when starting the debugger. *\n");
  481. dprintf("* using .exepath and .exepath+ *\n");
  482. dprintf("*********************************************************************\n");
  483. RetStatus = E_INVALIDARG;
  484. goto FreeSpecMod;
  485. }
  486. }
  487. //
  488. // If both the module name and the address are specified, then just load
  489. // the module right now, as this is only used when normal symbol loading
  490. // would have failed in the first place.
  491. //
  492. if (SpecificModule && Address)
  493. {
  494. if (IgnoreSignature)
  495. {
  496. ReloadSymOptions = SymGetOptions();
  497. SymSetOptions(ReloadSymOptions | SYMOPT_LOAD_ANYTHING);
  498. }
  499. ModEntry.NamePtr = SpecificModule,
  500. ModEntry.Base = Address;
  501. ModEntry.Size = ImageSize;
  502. ModEntry.CheckSum = -1;
  503. if ((RetStatus = Process->
  504. AddImage(&ModEntry, TRUE, &ImageAdded)) != S_OK)
  505. {
  506. ErrOut("Unable to add module at %s\n", FormatAddr64(Address));
  507. }
  508. if (IgnoreSignature)
  509. {
  510. SymSetOptions(ReloadSymOptions);
  511. }
  512. goto FreeSpecMod;
  513. }
  514. //
  515. // Don't unload and reset things if we are looking for a specific module
  516. // or if we're going to use the existing module list.
  517. //
  518. if (SpecificModule == NULL)
  519. {
  520. if (!PrintImageListOnly &&
  521. (!UseDebuggerModuleList || UnloadOnly))
  522. {
  523. if (IS_KERNEL_TARGET(this) && UserModeList)
  524. {
  525. // This is a .reload /user, so only delete
  526. // the user-mode modules.
  527. Process->DeleteImagesBelowOffset(m_SystemRangeStart);
  528. }
  529. else
  530. {
  531. Process->DeleteImages();
  532. }
  533. }
  534. if (UnloadOnly)
  535. {
  536. dprintf("Unloaded all modules\n");
  537. return S_OK;
  538. }
  539. if (!IS_USER_TARGET(this) && !UseDebuggerModuleList)
  540. {
  541. if (IS_LIVE_KERNEL_TARGET(this))
  542. {
  543. // This is just a refresh and hopefully won't fail.
  544. ((LiveKernelTargetInfo*)this)->InitFromKdVersion();
  545. }
  546. QueryKernelInfo(Thread, TRUE);
  547. }
  548. //
  549. // Print out the correct statement based on the type of output we
  550. // want to provide
  551. //
  552. if (PrintImageListOnly)
  553. {
  554. if (UseDebuggerModuleList)
  555. {
  556. dprintf("Debugger Module List Summary\n");
  557. }
  558. else
  559. {
  560. dprintf("System %s Summary\n",
  561. IS_USER_TARGET(this) ? "Image" : "Driver and Image");
  562. }
  563. dprintf("Base ");
  564. if (m_Machine->m_Ptr64)
  565. {
  566. dprintf(" ");
  567. }
  568. #if 0
  569. if (Flags & 1)
  570. {
  571. dprintf("Code Size Data Size Resident "
  572. "Standby Driver Name\n");
  573. }
  574. else if (Flags & 2)
  575. {
  576. dprintf("Code Data Locked Resident Standby "
  577. "Loader Entry Driver Name\n");
  578. }
  579. else
  580. {
  581. #endif
  582. if (UseDebuggerModuleList)
  583. {
  584. dprintf("Image Size "
  585. "Image Name Creation Time\n");
  586. }
  587. else
  588. {
  589. dprintf("Code Size Data Size "
  590. "Image Name Creation Time\n");
  591. }
  592. }
  593. else if (UseDebuggerModuleList)
  594. {
  595. dprintf("Reloading current modules\n");
  596. }
  597. else if (!IS_USER_TARGET(this))
  598. {
  599. dprintf("Loading %s Symbols\n",
  600. UserModeList ? "User" : "Kernel");
  601. }
  602. }
  603. //
  604. // Get the beginning of the module list.
  605. //
  606. if (UseDebuggerModuleList)
  607. {
  608. ModIter = &g_DebuggerModuleIterator;
  609. }
  610. else
  611. {
  612. ModIter = GetModuleInfo(UserModeList);
  613. }
  614. if (ModIter == NULL)
  615. {
  616. // Error messages already printed.
  617. RetStatus = E_UNEXPECTED;
  618. goto FreeSpecMod;
  619. }
  620. if ((Status = ModIter->Initialize(Thread)) != S_OK)
  621. {
  622. // Error messages already printed.
  623. // Fold unprepared-to-reload S_FALSE into S_OK.
  624. RetStatus = SUCCEEDED(Status) ? S_OK : Status;
  625. goto FreeSpecMod;
  626. }
  627. if (IgnoreSignature)
  628. {
  629. ReloadSymOptions = SymGetOptions();
  630. SymSetOptions(ReloadSymOptions | SYMOPT_LOAD_ANYTHING);
  631. }
  632. // Suppress notifications until everything is done.
  633. g_EngNotify++;
  634. LoadLoop:
  635. for (ModCount=0; ; ModCount++)
  636. {
  637. // Flush regularly so the user knows something is
  638. // happening during the reload.
  639. FlushCallbacks();
  640. if (CheckUserInterrupt())
  641. {
  642. break;
  643. }
  644. if (ModCount > 1000)
  645. {
  646. ErrOut("ModuleList is corrupt - walked over 1000 module entries\n");
  647. break;
  648. }
  649. if (ModEntry.DebugHeader)
  650. {
  651. free(ModEntry.DebugHeader);
  652. }
  653. ZeroMemory(&ModEntry, sizeof(ModEntry));
  654. if ((Status = ModIter->GetEntry(&ModEntry)) != S_OK)
  655. {
  656. // Error message already printed in error case.
  657. // Works for end-of-list case also.
  658. break;
  659. }
  660. //
  661. // Check size of images
  662. //
  663. if (!ModEntry.Size)
  664. {
  665. VerbOut("Image at %s had size 0\n",
  666. FormatAddr64(ModEntry.Base));
  667. //
  668. // Override this since we know all images are at least 1 page long
  669. //
  670. ModEntry.Size = m_Machine->m_PageSize;
  671. }
  672. //
  673. // Warn if not all the information was gathered
  674. //
  675. if (!ModEntry.ImageInfoValid)
  676. {
  677. VerbOut("Unable to read image header at %s\n",
  678. FormatAddr64(ModEntry.Base));
  679. }
  680. //
  681. // Are we looking for a module at a specific address ?
  682. //
  683. if (AddrLoad)
  684. {
  685. if (Address < ModEntry.Base ||
  686. Address >= ModEntry.Base + ModEntry.Size)
  687. {
  688. continue;
  689. }
  690. }
  691. if (ModEntry.UnicodeNamePtr)
  692. {
  693. ModEntry.NamePtr =
  694. ConvertAndValidateImagePathW((PWSTR)ModEntry.NamePtr,
  695. ModEntry.NameLength /
  696. sizeof(WCHAR),
  697. ModEntry.Base,
  698. AnsiString,
  699. DIMA(AnsiString));
  700. ModEntry.UnicodeNamePtr = 0;
  701. }
  702. else
  703. {
  704. ModEntry.NamePtr =
  705. ValidateImagePath((PSTR)ModEntry.NamePtr,
  706. ModEntry.NameLength,
  707. ModEntry.Base,
  708. AnsiString,
  709. DIMA(AnsiString));
  710. }
  711. //
  712. // If we are loading a specific module:
  713. //
  714. // If the Module is NT, we take the first module in the list as it is
  715. // guaranteed to be the kernel. Reset the Base address if it was
  716. // not set.
  717. //
  718. // Otherwise, actually compare the strings and continue if they don't
  719. // match
  720. //
  721. if (SpecificModule)
  722. {
  723. if (!UserModeList &&
  724. _stricmp( SpecificModule, KERNEL_MODULE_NAME ) == 0)
  725. {
  726. if (!m_KdVersion.KernBase)
  727. {
  728. m_KdVersion.KernBase = ModEntry.Base;
  729. }
  730. if (!m_KdDebuggerData.KernBase)
  731. {
  732. m_KdDebuggerData.KernBase = ModEntry.Base;
  733. }
  734. }
  735. else
  736. {
  737. if (!MatchPathTails(SpecificModule, ModEntry.NamePtr,
  738. SpecificWild))
  739. {
  740. continue;
  741. }
  742. }
  743. }
  744. PCSTR NamePtrTail = PathTail(ModEntry.NamePtr);
  745. if (PrintImageListOnly)
  746. {
  747. PCHAR Time;
  748. //
  749. // The timestamp in minidumps was corrupt until NT5 RC3
  750. // The timestamp could also be invalid because it was paged out
  751. // in which case it's value is UNKNOWN_TIMESTAMP.
  752. if (IS_KERNEL_TRIAGE_DUMP(this) &&
  753. (m_ActualSystemVersion > NT_SVER_START &&
  754. m_ActualSystemVersion <= NT_SVER_W2K_RC3))
  755. {
  756. Time = "";
  757. }
  758. Time = TimeToStr(ModEntry.TimeDateStamp);
  759. if (UseDebuggerModuleList)
  760. {
  761. dprintf("%s %6lx (%4ld k) %12s %s\n",
  762. FormatAddr64(ModEntry.Base), ModEntry.Size,
  763. KBYTES(ModEntry.Size), NamePtrTail,
  764. Time);
  765. }
  766. else
  767. {
  768. dprintf("%s %6lx (%4ld k) %5lx (%3ld k) %12s %s\n",
  769. FormatAddr64(ModEntry.Base),
  770. ModEntry.SizeOfCode, KBYTES(ModEntry.SizeOfCode),
  771. ModEntry.SizeOfData, KBYTES(ModEntry.SizeOfData),
  772. NamePtrTail, Time);
  773. }
  774. }
  775. else
  776. {
  777. //
  778. // Don't bother reloading the kernel if we are not specifically
  779. // asked since we know those symbols were reloaded by the
  780. // QueryKernelInfo call.
  781. //
  782. if (!SpecificModule && !UserModeList &&
  783. m_KdDebuggerData.KernBase == ModEntry.Base)
  784. {
  785. continue;
  786. }
  787. if (ReallyVerbose)
  788. {
  789. dprintf("AddImage: %s\n DllBase = %s\n Size = %08x\n "
  790. "Checksum = %08x\n TimeDateStamp = %08x\n",
  791. ModEntry.NamePtr, FormatAddr64(ModEntry.Base),
  792. ModEntry.Size, ModEntry.CheckSum,
  793. ModEntry.TimeDateStamp);
  794. }
  795. else
  796. {
  797. if (!SpecificModule)
  798. {
  799. dprintf(".");
  800. }
  801. }
  802. if (Address)
  803. {
  804. ModEntry.Base = Address;
  805. }
  806. if ((RetStatus = Process->
  807. AddImage(&ModEntry, ForceSymbolLoad, &ImageAdded)) != S_OK)
  808. {
  809. ErrOut("Unable to add module at %s\n",
  810. FormatAddr64(ModEntry.Base));
  811. }
  812. }
  813. if (SpecificModule)
  814. {
  815. free( SpecificModule );
  816. goto Notify;
  817. }
  818. if (AddrLoad)
  819. {
  820. goto Notify;
  821. }
  822. }
  823. if (UseDebuggerModuleList || IS_KERNEL_TARGET(this) || UserModeList)
  824. {
  825. // print newline after all the '.'
  826. dprintf("\n");
  827. }
  828. if (!UseDebuggerModuleList && !UserModeList && SpecificModule == NULL)
  829. {
  830. // If we just reloaded the kernel modules
  831. // go through the unloaded module list.
  832. if (!PrintImageListOnly)
  833. {
  834. dprintf("Loading unloaded module list\n");
  835. }
  836. ListUnloadedModules(PrintImageListOnly ?
  837. LUM_OUTPUT : LUM_OUTPUT_TERSE, NULL);
  838. }
  839. //
  840. // If we got to the end of the kernel symbols, try to load the
  841. // user mode symbols for the current process.
  842. //
  843. if (!UseDebuggerModuleList &&
  844. (UserModeList == FALSE) &&
  845. (LoadUserSymbols == TRUE) &&
  846. SUCCEEDED(Status))
  847. {
  848. if (!AddrLoad && !SpecificModule)
  849. {
  850. dprintf("Loading User Symbols\n");
  851. }
  852. UserModeList = TRUE;
  853. ModIter = GetModuleInfo(UserModeList);
  854. if (ModIter != NULL && ModIter->Initialize(Thread) == S_OK)
  855. {
  856. goto LoadLoop;
  857. }
  858. }
  859. if (!SpecificModule && !Wow64ModLoaded)
  860. {
  861. ModIter = &g_NtWow64UserModuleIterator;
  862. Wow64ModLoaded = TRUE;
  863. if (ModIter->Initialize(Thread) == S_OK)
  864. {
  865. dprintf("Loading Wow64 Symbols\n");
  866. goto LoadLoop;
  867. }
  868. }
  869. // In the multiple load situation we always return OK
  870. // since an error wouldn't tell you much about what
  871. // actually occurred.
  872. // Specific loads that haven't already been handled are checked
  873. // right after this.
  874. RetStatus = S_OK;
  875. //
  876. // If we still have not managed to load a named file, just pass the name
  877. // and the address and hope for the best.
  878. //
  879. if (SpecificModule && !PrintImageListOnly)
  880. {
  881. WarnOut("\nModule \"%s\" was not found in the module list.\n",
  882. SpecificModule);
  883. WarnOut("Debugger will attempt to load \"%s\" at given base %s.\n\n",
  884. SpecificModule, FormatAddr64(Address));
  885. WarnOut("Please provide the full image name, including the "
  886. "extension (i.e. kernel32.dll)\nfor more reliable results. "
  887. "Base address and size overrides can be given as\n"
  888. ".reload <image.ext>=<base>,<size>.\n");
  889. ZeroMemory(&ModEntry, sizeof(ModEntry));
  890. ModEntry.NamePtr = SpecificModule,
  891. ModEntry.Base = Address;
  892. ModEntry.Size = ImageSize;
  893. if ((RetStatus = Process->
  894. AddImage(&ModEntry, TRUE, &ImageAdded)) != S_OK)
  895. {
  896. ErrOut("Unable to add module at %s\n", FormatAddr64(Address));
  897. }
  898. free(SpecificModule);
  899. }
  900. Notify:
  901. // If we've gotten this far we've done one or more reloads
  902. // and postponed notifications. Do them now that all the work
  903. // has been done.
  904. g_EngNotify--;
  905. if (SUCCEEDED(RetStatus))
  906. {
  907. NotifyChangeSymbolState(DEBUG_CSS_LOADS | DEBUG_CSS_UNLOADS, 0,
  908. Process);
  909. }
  910. if (IgnoreSignature)
  911. {
  912. SymSetOptions(ReloadSymOptions);
  913. }
  914. if (ModEntry.DebugHeader)
  915. {
  916. free(ModEntry.DebugHeader);
  917. }
  918. return RetStatus;
  919. FreeSpecMod:
  920. free(SpecificModule);
  921. return RetStatus;
  922. }
  923. ULONG64
  924. TargetInfo::GetCurrentTimeDateN(void)
  925. {
  926. // No information.
  927. return 0;
  928. }
  929. ULONG64
  930. TargetInfo::GetCurrentSystemUpTimeN(void)
  931. {
  932. // No information.
  933. return 0;
  934. }
  935. ULONG64
  936. TargetInfo::GetProcessUpTimeN(ProcessInfo* Process)
  937. {
  938. // No information.
  939. return 0;
  940. }
  941. HRESULT
  942. TargetInfo::GetProcessTimes(ProcessInfo* Process,
  943. PULONG64 Create,
  944. PULONG64 Exit,
  945. PULONG64 Kernel,
  946. PULONG64 User)
  947. {
  948. // No information.
  949. return E_NOTIMPL;
  950. }
  951. HRESULT
  952. TargetInfo::GetThreadTimes(ThreadInfo* Thread,
  953. PULONG64 Create,
  954. PULONG64 Exit,
  955. PULONG64 Kernel,
  956. PULONG64 User)
  957. {
  958. // No information.
  959. return E_NOTIMPL;
  960. }
  961. HRESULT
  962. TargetInfo::GetProductInfo(PULONG ProductType, PULONG SuiteMask)
  963. {
  964. if (m_PlatformId == VER_PLATFORM_WIN32_NT)
  965. {
  966. return ReadSharedUserProductInfo(ProductType, SuiteMask);
  967. }
  968. else
  969. {
  970. return E_NOTIMPL;
  971. }
  972. }
  973. HRESULT
  974. TargetInfo::GetEventIndexDescription(IN ULONG Index,
  975. IN ULONG Which,
  976. IN OPTIONAL PSTR Buffer,
  977. IN ULONG BufferSize,
  978. OUT OPTIONAL PULONG DescSize)
  979. {
  980. switch(Which)
  981. {
  982. case DEBUG_EINDEX_NAME:
  983. return FillStringBuffer("Default", 0,
  984. Buffer, BufferSize, DescSize);
  985. default:
  986. return E_INVALIDARG;
  987. }
  988. }
  989. HRESULT
  990. TargetInfo::WaitInitialize(ULONG Flags,
  991. ULONG Timeout,
  992. WAIT_INIT_TYPE Type,
  993. PULONG DesiredTimeout)
  994. {
  995. // Placeholder.
  996. return S_OK;
  997. }
  998. HRESULT
  999. TargetInfo::ReleaseLastEvent(ULONG ContinueStatus)
  1000. {
  1001. // Placeholder.
  1002. return S_OK;
  1003. }
  1004. HRESULT
  1005. TargetInfo::ClearBreakIn(void)
  1006. {
  1007. // Placeholder.
  1008. return S_OK;
  1009. }
  1010. //----------------------------------------------------------------------------
  1011. //
  1012. // LiveKernelTargetInfo miscellaneous methods.
  1013. //
  1014. // Data space methods and system objects methods are elsewhere.
  1015. //
  1016. //----------------------------------------------------------------------------
  1017. LiveKernelTargetInfo::LiveKernelTargetInfo(ULONG Qual, BOOL DynamicEvents)
  1018. : TargetInfo(DEBUG_CLASS_KERNEL, Qual, DynamicEvents)
  1019. {
  1020. m_ConnectOptions = NULL;
  1021. }
  1022. HRESULT
  1023. LiveKernelTargetInfo::ReadBugCheckData(PULONG Code, ULONG64 Args[4])
  1024. {
  1025. ULONG64 BugCheckData;
  1026. ULONG64 Data[5];
  1027. HRESULT Status;
  1028. ULONG Read;
  1029. if (!(BugCheckData = m_KdDebuggerData.KiBugcheckData))
  1030. {
  1031. if (!GetOffsetFromSym(m_ProcessHead,
  1032. "nt!KiBugCheckData", &BugCheckData, NULL) ||
  1033. !BugCheckData)
  1034. {
  1035. ErrOut("Unable to resolve nt!KiBugCheckData\n");
  1036. return E_NOINTERFACE;
  1037. }
  1038. }
  1039. if (m_Machine->m_Ptr64)
  1040. {
  1041. Status = ReadVirtual(m_ProcessHead, BugCheckData, Data,
  1042. sizeof(Data), &Read);
  1043. }
  1044. else
  1045. {
  1046. ULONG i;
  1047. ULONG Data32[5];
  1048. Status = ReadVirtual(m_ProcessHead, BugCheckData, Data32,
  1049. sizeof(Data32), &Read);
  1050. Read *= 2;
  1051. for (i = 0; i < DIMA(Data); i++)
  1052. {
  1053. Data[i] = EXTEND64(Data32[i]);
  1054. }
  1055. }
  1056. if (Status != S_OK || Read != sizeof(Data))
  1057. {
  1058. ErrOut("Unable to read KiBugCheckData\n");
  1059. return Status == S_OK ? E_FAIL : Status;
  1060. }
  1061. *Code = (ULONG)Data[0];
  1062. memcpy(Args, Data + 1, sizeof(Data) - sizeof(ULONG64));
  1063. return S_OK;
  1064. }
  1065. ULONG64
  1066. LiveKernelTargetInfo::GetCurrentTimeDateN(void)
  1067. {
  1068. ULONG64 TimeDate;
  1069. if (m_ActualSystemVersion > NT_SVER_START &&
  1070. m_ActualSystemVersion < NT_SVER_END &&
  1071. ReadSharedUserTimeDateN(&TimeDate) == S_OK)
  1072. {
  1073. return TimeDate;
  1074. }
  1075. else
  1076. {
  1077. return 0;
  1078. }
  1079. }
  1080. ULONG64
  1081. LiveKernelTargetInfo::GetCurrentSystemUpTimeN(void)
  1082. {
  1083. ULONG64 UpTime;
  1084. if (m_ActualSystemVersion > NT_SVER_START &&
  1085. m_ActualSystemVersion < NT_SVER_END &&
  1086. ReadSharedUserUpTimeN(&UpTime) == S_OK)
  1087. {
  1088. return UpTime;
  1089. }
  1090. else
  1091. {
  1092. return 0;
  1093. }
  1094. }
  1095. //----------------------------------------------------------------------------
  1096. //
  1097. // ConnLiveKernelTargetInfo miscellaneous methods.
  1098. //
  1099. // Data space methods and system objects methods are elsewhere.
  1100. //
  1101. //----------------------------------------------------------------------------
  1102. ConnLiveKernelTargetInfo::ConnLiveKernelTargetInfo(void)
  1103. : LiveKernelTargetInfo(DEBUG_KERNEL_CONNECTION, TRUE)
  1104. {
  1105. m_Transport = NULL;
  1106. ResetConnection();
  1107. }
  1108. ConnLiveKernelTargetInfo::~ConnLiveKernelTargetInfo(void)
  1109. {
  1110. RELEASE(m_Transport);
  1111. }
  1112. #define BUS_TYPE "_NT_DEBUG_BUS"
  1113. #define DBG_BUS1394_NAME "1394"
  1114. HRESULT
  1115. ConnLiveKernelTargetInfo::Initialize(void)
  1116. {
  1117. HRESULT Status;
  1118. DbgKdTransport* Trans = NULL;
  1119. ULONG Index;
  1120. // Try and find the transport by name.
  1121. Index = ParameterStringParser::
  1122. GetParser(m_ConnectOptions, DBGKD_TRANSPORT_COUNT,
  1123. g_DbgKdTransportNames);
  1124. if (Index < DBGKD_TRANSPORT_COUNT)
  1125. {
  1126. switch(Index)
  1127. {
  1128. case DBGKD_TRANSPORT_COM:
  1129. Trans = new DbgKdComTransport(this);
  1130. break;
  1131. case DBGKD_TRANSPORT_1394:
  1132. Trans = new DbgKd1394Transport(this);
  1133. break;
  1134. }
  1135. if (!Trans)
  1136. {
  1137. return E_OUTOFMEMORY;
  1138. }
  1139. }
  1140. if (Trans == NULL)
  1141. {
  1142. PCHAR BusType;
  1143. // Couldn't identify the transport from options so check
  1144. // the environment. Default to com port.
  1145. if (BusType = getenv(BUS_TYPE))
  1146. {
  1147. if (strstr(BusType, DBG_BUS1394_NAME))
  1148. {
  1149. Trans = new DbgKd1394Transport(this);
  1150. if (!Trans)
  1151. {
  1152. return E_OUTOFMEMORY;
  1153. }
  1154. }
  1155. }
  1156. if (!Trans)
  1157. {
  1158. Trans = new DbgKdComTransport(this);
  1159. if (!Trans)
  1160. {
  1161. return E_OUTOFMEMORY;
  1162. }
  1163. }
  1164. }
  1165. // Clear parameter state.
  1166. Trans->ResetParameters();
  1167. if (!Trans->ParseParameters(m_ConnectOptions))
  1168. {
  1169. Status = E_INVALIDARG;
  1170. }
  1171. else
  1172. {
  1173. Status = Trans->Initialize();
  1174. if (Status != S_OK)
  1175. {
  1176. ErrOut("Kernel debugger failed initialization, %s\n \"%s\"\n",
  1177. FormatStatusCode(Status), FormatStatus(Status));
  1178. }
  1179. }
  1180. if (Status == S_OK)
  1181. {
  1182. m_Transport = Trans;
  1183. // The initial target must always be considered the
  1184. // current partition so that it can successfully
  1185. // attempt the first wait.
  1186. m_CurrentPartition = TRUE;
  1187. Status = LiveKernelTargetInfo::Initialize();
  1188. }
  1189. else
  1190. {
  1191. delete Trans;
  1192. }
  1193. return Status;
  1194. }
  1195. HRESULT
  1196. ConnLiveKernelTargetInfo::GetDescription(PSTR Buffer, ULONG BufferLen,
  1197. PULONG DescLen)
  1198. {
  1199. HRESULT Status;
  1200. if (m_Transport)
  1201. {
  1202. char Buf[MAX_PATH];
  1203. m_Transport->GetParameters(Buf, sizeof(Buf));
  1204. Status = AppendToStringBuffer(S_OK, "Remote KD: ", TRUE,
  1205. &Buffer, &BufferLen, DescLen);
  1206. return AppendToStringBuffer(Status, Buf, FALSE,
  1207. &Buffer, &BufferLen, DescLen);
  1208. }
  1209. else
  1210. {
  1211. return FillStringBuffer("", 1,
  1212. Buffer, BufferLen, DescLen);
  1213. }
  1214. }
  1215. void
  1216. ConnLiveKernelTargetInfo::DebuggeeReset(ULONG Reason, BOOL FromEvent)
  1217. {
  1218. if (m_Transport != NULL)
  1219. {
  1220. m_Transport->Restart();
  1221. }
  1222. //
  1223. // If alternate partitions were created get rid of them.
  1224. //
  1225. TargetInfo* Target = FindTargetBySystemId(DBGKD_PARTITION_ALTERNATE);
  1226. if (Target == this)
  1227. {
  1228. Target = FindTargetBySystemId(DBGKD_PARTITION_DEFAULT);
  1229. }
  1230. delete Target;
  1231. ResetConnection();
  1232. m_CurrentPartition = TRUE;
  1233. LiveKernelTargetInfo::DebuggeeReset(Reason, FromEvent);
  1234. }
  1235. HRESULT
  1236. ConnLiveKernelTargetInfo::SwitchProcessors(ULONG Processor)
  1237. {
  1238. m_SwitchProcessor = Processor + 1;
  1239. g_CmdState = 's';
  1240. // Return S_FALSE to indicate that the switch is pending.
  1241. return S_FALSE;
  1242. }
  1243. HRESULT
  1244. ConnLiveKernelTargetInfo::SwitchToTarget(TargetInfo* From)
  1245. {
  1246. if (!IS_CONN_KERNEL_TARGET(From))
  1247. {
  1248. return E_NOTIMPL;
  1249. }
  1250. ((ConnLiveKernelTargetInfo*)From)->m_SwitchTarget = this;
  1251. g_CmdState = 's';
  1252. // Return S_FALSE to indicate that the switch is pending.
  1253. return S_FALSE;
  1254. }
  1255. HRESULT
  1256. ConnLiveKernelTargetInfo::GetTargetKdVersion(PDBGKD_GET_VERSION64 Version)
  1257. {
  1258. DBGKD_MANIPULATE_STATE64 m;
  1259. PDBGKD_MANIPULATE_STATE64 Reply;
  1260. PDBGKD_GET_VERSION64 a = &m.u.GetVersion64;
  1261. ULONG rc;
  1262. m.ApiNumber = DbgKdGetVersionApi;
  1263. m.ReturnStatus = STATUS_PENDING;
  1264. a->ProtocolVersion = 1; // request context records on state changes
  1265. do
  1266. {
  1267. m_Transport->WritePacket(&m, sizeof(m),
  1268. PACKET_TYPE_KD_STATE_MANIPULATE,
  1269. NULL, 0);
  1270. rc = m_Transport->
  1271. WaitForPacket(PACKET_TYPE_KD_STATE_MANIPULATE, &Reply);
  1272. } while (rc != DBGKD_WAIT_PACKET);
  1273. *Version = Reply->u.GetVersion64;
  1274. KdOut("DbgKdGetVersion returns %08lx\n", Reply->ReturnStatus);
  1275. return CONV_NT_STATUS(Reply->ReturnStatus);
  1276. }
  1277. HRESULT
  1278. ConnLiveKernelTargetInfo::RequestBreakIn(void)
  1279. {
  1280. // Tell the waiting thread to break in.
  1281. m_Transport->m_BreakIn = TRUE;
  1282. return S_OK;
  1283. }
  1284. HRESULT
  1285. ConnLiveKernelTargetInfo::ClearBreakIn(void)
  1286. {
  1287. m_Transport->m_BreakIn = FALSE;
  1288. return S_OK;
  1289. }
  1290. HRESULT
  1291. ConnLiveKernelTargetInfo::Reboot(void)
  1292. {
  1293. DBGKD_MANIPULATE_STATE64 m;
  1294. //
  1295. // Format state manipulate message
  1296. //
  1297. m.ApiNumber = DbgKdRebootApi;
  1298. m.ReturnStatus = STATUS_PENDING;
  1299. //
  1300. // Send the message.
  1301. //
  1302. m_Transport->WritePacket(&m, sizeof(m),
  1303. PACKET_TYPE_KD_STATE_MANIPULATE,
  1304. NULL, 0);
  1305. InvalidateMemoryCaches(FALSE);
  1306. DebuggeeReset(DEBUG_SESSION_REBOOT, TRUE);
  1307. KdOut("DbgKdReboot returns 0x00000000\n");
  1308. return S_OK;
  1309. }
  1310. HRESULT
  1311. ConnLiveKernelTargetInfo::Crash(ULONG Code)
  1312. {
  1313. DBGKD_MANIPULATE_STATE64 m;
  1314. //
  1315. // Format state manipulate message
  1316. //
  1317. m.ApiNumber = DbgKdCauseBugCheckApi;
  1318. m.ReturnStatus = STATUS_PENDING;
  1319. *(PULONG)&m.u = Code;
  1320. m_Transport->WritePacket(&m, sizeof(m),
  1321. PACKET_TYPE_KD_STATE_MANIPULATE,
  1322. NULL, 0);
  1323. DiscardLastEvent();
  1324. KdOut("DbgKdCrash returns 0x00000000\n");
  1325. return S_OK;
  1326. }
  1327. void
  1328. ConnLiveKernelTargetInfo::ResetConnection(void)
  1329. {
  1330. m_CurrentPartition = FALSE;
  1331. m_SwitchTarget = NULL;
  1332. m_KdpSearchPageHits = 0;
  1333. m_KdpSearchPageHitOffsets = 0;
  1334. m_KdpSearchPageHitIndex = 0;
  1335. m_KdpSearchCheckPoint = 0;
  1336. m_KdpSearchInProgress = 0;
  1337. m_KdpSearchStartPageFrame = 0;
  1338. m_KdpSearchEndPageFrame = 0;
  1339. m_KdpSearchAddressRangeStart = 0;
  1340. m_KdpSearchAddressRangeEnd = 0;
  1341. m_KdpSearchPfnValue = 0;
  1342. }
  1343. //----------------------------------------------------------------------------
  1344. //
  1345. // LocalLiveKernelTargetInfo miscellaneous methods.
  1346. //
  1347. // Data space methods and system objects methods are elsewhere.
  1348. //
  1349. //----------------------------------------------------------------------------
  1350. HRESULT
  1351. LocalLiveKernelTargetInfo::Initialize(void)
  1352. {
  1353. DBGKD_GET_VERSION64 Version;
  1354. // Do a quick check to see if this kernel even
  1355. // supports the necessary debug services.
  1356. if (!NT_SUCCESS(g_NtDllCalls.
  1357. NtSystemDebugControl(SysDbgQueryVersion, NULL, 0,
  1358. &Version, sizeof(Version), NULL)))
  1359. {
  1360. ErrOut("The system does not support local kernel debugging.\n");
  1361. ErrOut("Local kernel debugging requires Windows XP, Administrative\n"
  1362. "privileges, and is not supported by WOW64.\n");
  1363. return E_NOTIMPL;
  1364. }
  1365. return LiveKernelTargetInfo::Initialize();
  1366. }
  1367. HRESULT
  1368. LocalLiveKernelTargetInfo::GetDescription(PSTR Buffer, ULONG BufferLen,
  1369. PULONG DescLen)
  1370. {
  1371. return FillStringBuffer("Local KD", 0,
  1372. Buffer, BufferLen, DescLen);
  1373. }
  1374. HRESULT
  1375. LocalLiveKernelTargetInfo::GetTargetKdVersion(PDBGKD_GET_VERSION64 Version)
  1376. {
  1377. NTSTATUS Status = g_NtDllCalls.
  1378. NtSystemDebugControl(SysDbgQueryVersion, NULL, 0,
  1379. Version, sizeof(*Version), NULL);
  1380. return CONV_NT_STATUS(Status);
  1381. }
  1382. //----------------------------------------------------------------------------
  1383. //
  1384. // ExdiLiveKernelTargetInfo miscellaneous methods.
  1385. //
  1386. // Data space methods and system objects methods are elsewhere.
  1387. //
  1388. //----------------------------------------------------------------------------
  1389. ExdiNotifyRunChange::ExdiNotifyRunChange(void)
  1390. {
  1391. m_Event = NULL;
  1392. }
  1393. ExdiNotifyRunChange::~ExdiNotifyRunChange(void)
  1394. {
  1395. Uninitialize();
  1396. }
  1397. HRESULT
  1398. ExdiNotifyRunChange::Initialize(void)
  1399. {
  1400. m_Event = CreateEvent(NULL, FALSE, FALSE, NULL);
  1401. if (m_Event == NULL)
  1402. {
  1403. return WIN32_LAST_STATUS();
  1404. }
  1405. return S_OK;
  1406. }
  1407. void
  1408. ExdiNotifyRunChange::Uninitialize(void)
  1409. {
  1410. if (m_Event != NULL)
  1411. {
  1412. CloseHandle(m_Event);
  1413. m_Event = NULL;
  1414. }
  1415. }
  1416. STDMETHODIMP
  1417. ExdiNotifyRunChange::QueryInterface(
  1418. THIS_
  1419. IN REFIID InterfaceId,
  1420. OUT PVOID* Interface
  1421. )
  1422. {
  1423. if (DbgIsEqualIID(IID_IUnknown, InterfaceId) ||
  1424. DbgIsEqualIID(__uuidof(IeXdiClientNotifyRunChg), InterfaceId))
  1425. {
  1426. *Interface = this;
  1427. return S_OK;
  1428. }
  1429. *Interface = NULL;
  1430. return E_NOINTERFACE;
  1431. }
  1432. STDMETHODIMP_(ULONG)
  1433. ExdiNotifyRunChange::AddRef(
  1434. THIS
  1435. )
  1436. {
  1437. return 1;
  1438. }
  1439. STDMETHODIMP_(ULONG)
  1440. ExdiNotifyRunChange::Release(
  1441. THIS
  1442. )
  1443. {
  1444. return 0;
  1445. }
  1446. STDMETHODIMP
  1447. ExdiNotifyRunChange::NotifyRunStateChange(RUN_STATUS_TYPE ersCurrent,
  1448. HALT_REASON_TYPE ehrCurrent,
  1449. ADDRESS_TYPE CurrentExecAddress,
  1450. DWORD dwExceptionCode)
  1451. {
  1452. if (ersCurrent == rsRunning)
  1453. {
  1454. // We're waiting for things to stop so ignore this.
  1455. return S_OK;
  1456. }
  1457. m_HaltReason = ehrCurrent;
  1458. m_ExecAddress = CurrentExecAddress;
  1459. m_ExceptionCode = dwExceptionCode;
  1460. SetEvent(m_Event);
  1461. return S_OK;
  1462. }
  1463. class ExdiParams : public ParameterStringParser
  1464. {
  1465. public:
  1466. virtual ULONG GetNumberParameters(void)
  1467. {
  1468. // No need to get.
  1469. return 0;
  1470. }
  1471. virtual void GetParameter(ULONG Index,
  1472. PSTR Name, ULONG NameSize,
  1473. PSTR Value, ULONG ValueSize)
  1474. {
  1475. }
  1476. virtual void ResetParameters(void);
  1477. virtual BOOL SetParameter(PCSTR Name, PCSTR Value);
  1478. CLSID m_Clsid;
  1479. EXDI_KD_SUPPORT m_KdSupport;
  1480. BOOL m_ForceX86;
  1481. BOOL m_ExdiDataBreaks;
  1482. };
  1483. void
  1484. ExdiParams::ResetParameters(void)
  1485. {
  1486. ZeroMemory(&m_Clsid, sizeof(m_Clsid));
  1487. m_KdSupport = EXDI_KD_NONE;
  1488. m_ForceX86 = FALSE;
  1489. m_ExdiDataBreaks = FALSE;
  1490. }
  1491. BOOL
  1492. ScanExdiDriverList(PCSTR Name, LPCLSID Clsid)
  1493. {
  1494. char Pattern[MAX_PARAM_VALUE];
  1495. CopyString(Pattern, Name, DIMA(Pattern));
  1496. _strupr(Pattern);
  1497. HKEY ListKey;
  1498. if (RegOpenKeyEx(HKEY_LOCAL_MACHINE,
  1499. "Software\\Microsoft\\eXdi\\DriverList", 0,
  1500. KEY_ALL_ACCESS, &ListKey) != ERROR_SUCCESS)
  1501. {
  1502. return FALSE;
  1503. }
  1504. ULONG Index = 0;
  1505. BOOL Status = FALSE;
  1506. char ValName[MAX_PARAM_VALUE];
  1507. WCHAR WideValName[MAX_PARAM_VALUE];
  1508. ULONG NameLen, ValLen;
  1509. ULONG Type;
  1510. char Value[MAX_PARAM_VALUE];
  1511. for (;;)
  1512. {
  1513. NameLen = sizeof(ValName);
  1514. ValLen = sizeof(Value);
  1515. if (RegEnumValue(ListKey, Index, ValName, &NameLen, NULL,
  1516. &Type, (PBYTE)Value, &ValLen) != ERROR_SUCCESS)
  1517. {
  1518. break;
  1519. }
  1520. if (Type == REG_SZ &&
  1521. MatchPattern(Value, Pattern) &&
  1522. MultiByteToWideChar(CP_ACP, 0, ValName, -1, WideValName,
  1523. sizeof(WideValName) / sizeof(WCHAR)) > 0 &&
  1524. g_Ole32Calls.CLSIDFromString(WideValName, Clsid) == S_OK)
  1525. {
  1526. Status = TRUE;
  1527. break;
  1528. }
  1529. Index++;
  1530. }
  1531. RegCloseKey(ListKey);
  1532. return Status;
  1533. }
  1534. BOOL
  1535. ExdiParams::SetParameter(PCSTR Name, PCSTR Value)
  1536. {
  1537. if (!_strcmpi(Name, "CLSID"))
  1538. {
  1539. WCHAR WideValue[MAX_PARAM_VALUE];
  1540. if (MultiByteToWideChar(CP_ACP, 0, Value, -1, WideValue,
  1541. sizeof(WideValue) / sizeof(WCHAR)) == 0)
  1542. {
  1543. return FALSE;
  1544. }
  1545. return g_Ole32Calls.CLSIDFromString(WideValue, &m_Clsid) == S_OK;
  1546. }
  1547. else if (!_strcmpi(Name, "Desc"))
  1548. {
  1549. return ScanExdiDriverList(Value, &m_Clsid);
  1550. }
  1551. else if (!_strcmpi(Name, "DataBreaks"))
  1552. {
  1553. if (!Value)
  1554. {
  1555. return FALSE;
  1556. }
  1557. if (!_strcmpi(Value, "Exdi"))
  1558. {
  1559. m_ExdiDataBreaks = TRUE;
  1560. }
  1561. else if (!_strcmpi(Value, "Default"))
  1562. {
  1563. m_ExdiDataBreaks = FALSE;
  1564. }
  1565. else
  1566. {
  1567. return FALSE;
  1568. }
  1569. }
  1570. else if (!_strcmpi(Name, "ForceX86"))
  1571. {
  1572. m_ForceX86 = TRUE;
  1573. }
  1574. else if (!_strcmpi(Name, "Kd"))
  1575. {
  1576. if (!Value)
  1577. {
  1578. return FALSE;
  1579. }
  1580. if (!_strcmpi(Value, "Ioctl"))
  1581. {
  1582. m_KdSupport = EXDI_KD_IOCTL;
  1583. }
  1584. else if (!_strcmpi(Value, "GsPcr"))
  1585. {
  1586. m_KdSupport = EXDI_KD_GS_PCR;
  1587. }
  1588. else
  1589. {
  1590. return FALSE;
  1591. }
  1592. }
  1593. else
  1594. {
  1595. return FALSE;
  1596. }
  1597. return TRUE;
  1598. }
  1599. PCSTR g_ExdiGroupNames[] =
  1600. {
  1601. "exdi",
  1602. };
  1603. ExdiLiveKernelTargetInfo::ExdiLiveKernelTargetInfo(void)
  1604. : LiveKernelTargetInfo(DEBUG_KERNEL_EXDI_DRIVER, TRUE)
  1605. {
  1606. m_Server = NULL;
  1607. m_MarshalledServer = NULL;
  1608. m_Context = NULL;
  1609. m_ContextValid = FALSE;
  1610. m_IoctlMin = DBGENG_EXDI_IOC_BEFORE_FIRST;
  1611. m_IoctlMax = DBGENG_EXDI_IOC_BEFORE_FIRST;
  1612. m_BpHit.Type = DBGENG_EXDI_IOCTL_BREAKPOINT_NONE;
  1613. }
  1614. ExdiLiveKernelTargetInfo::~ExdiLiveKernelTargetInfo(void)
  1615. {
  1616. m_RunChange.Uninitialize();
  1617. RELEASE(m_Context);
  1618. RELEASE(m_MarshalledServer);
  1619. RELEASE(m_Server);
  1620. g_Ole32Calls.CoUninitialize();
  1621. }
  1622. HRESULT
  1623. ExdiLiveKernelTargetInfo::Initialize(void)
  1624. {
  1625. HRESULT Status;
  1626. // Load ole32.dll so we can call CoCreateInstance.
  1627. if ((Status = InitDynamicCalls(&g_Ole32CallsDesc)) != S_OK)
  1628. {
  1629. return Status;
  1630. }
  1631. ULONG Group;
  1632. Group = ParameterStringParser::
  1633. GetParser(m_ConnectOptions, DIMA(g_ExdiGroupNames), g_ExdiGroupNames);
  1634. if (Group == PARSER_INVALID)
  1635. {
  1636. return E_INVALIDARG;
  1637. }
  1638. ExdiParams Params;
  1639. Params.ResetParameters();
  1640. if (!Params.ParseParameters(m_ConnectOptions))
  1641. {
  1642. return E_INVALIDARG;
  1643. }
  1644. m_KdSupport = Params.m_KdSupport;
  1645. m_ExdiDataBreaks = Params.m_ExdiDataBreaks;
  1646. if (FAILED(Status = g_Ole32Calls.CoInitializeEx(NULL, COM_THREAD_MODEL)))
  1647. {
  1648. return Status;
  1649. }
  1650. if ((Status = g_Ole32Calls.CoCreateInstance(Params.m_Clsid, NULL,
  1651. CLSCTX_LOCAL_SERVER,
  1652. __uuidof(IeXdiServer),
  1653. (PVOID*)&m_Server)) != S_OK)
  1654. {
  1655. goto EH_CoInit;
  1656. }
  1657. if ((Status = g_Ole32Calls.CoMarshalInterThreadInterfaceInStream
  1658. (__uuidof(IeXdiServer), m_Server, &m_MarshalledServer)) != S_OK)
  1659. {
  1660. goto EH_Server;
  1661. }
  1662. if ((Status = m_Server->GetTargetInfo(&m_GlobalInfo)) != S_OK)
  1663. {
  1664. goto EH_MarshalledServer;
  1665. }
  1666. if (Params.m_ForceX86 ||
  1667. m_GlobalInfo.TargetProcessorFamily == PROCESSOR_FAMILY_X86)
  1668. {
  1669. if (!Params.m_ForceX86 &&
  1670. (Status = m_Server->
  1671. QueryInterface(__uuidof(IeXdiX86_64Context),
  1672. (PVOID*)&m_Context)) == S_OK)
  1673. {
  1674. m_ContextType = EXDI_CTX_AMD64;
  1675. m_ExpectedMachine = IMAGE_FILE_MACHINE_AMD64;
  1676. }
  1677. else if ((Status = m_Server->
  1678. QueryInterface(__uuidof(IeXdiX86ExContext),
  1679. (PVOID*)&m_Context)) == S_OK)
  1680. {
  1681. m_ContextType = EXDI_CTX_X86_EX;
  1682. m_ExpectedMachine = IMAGE_FILE_MACHINE_I386;
  1683. }
  1684. else if ((Status = m_Server->
  1685. QueryInterface(__uuidof(IeXdiX86Context),
  1686. (PVOID*)&m_Context)) == S_OK)
  1687. {
  1688. m_ContextType = EXDI_CTX_X86;
  1689. m_ExpectedMachine = IMAGE_FILE_MACHINE_I386;
  1690. }
  1691. else
  1692. {
  1693. goto EH_MarshalledServer;
  1694. }
  1695. }
  1696. else if (m_GlobalInfo.TargetProcessorFamily == PROCESSOR_FAMILY_IA64)
  1697. {
  1698. if ((Status = m_Server->
  1699. QueryInterface(__uuidof(IeXdiIA64Context),
  1700. (PVOID*)&m_Context)) == S_OK)
  1701. {
  1702. m_ContextType = EXDI_CTX_IA64;
  1703. m_ExpectedMachine = IMAGE_FILE_MACHINE_IA64;
  1704. }
  1705. }
  1706. else
  1707. {
  1708. Status = E_NOINTERFACE;
  1709. goto EH_MarshalledServer;
  1710. }
  1711. DWORD HwCode, SwCode;
  1712. if ((Status = m_Server->GetNbCodeBpAvail(&HwCode, &SwCode)) != S_OK)
  1713. {
  1714. goto EH_Context;
  1715. }
  1716. // We'd prefer to use software code breakpoints for our
  1717. // software code breakpoints so that hardware resources
  1718. // aren't consumed for a breakpoint we don't need to
  1719. // use hardware for. However, some servers, such as
  1720. // the x86-64 SimNow implementation, do not support
  1721. // software breakpoints.
  1722. // Also, if the number of hardware breakpoints is
  1723. // unbounded, go ahead and let the server choose.
  1724. // SimNow advertises -1 -1 for some reason and
  1725. // this is necessary to get things to work.
  1726. if (SwCode > 0 && HwCode != (DWORD)-1)
  1727. {
  1728. m_CodeBpType = cbptSW;
  1729. }
  1730. else
  1731. {
  1732. m_CodeBpType = cbptAlgo;
  1733. }
  1734. if ((Status = m_RunChange.Initialize()) != S_OK)
  1735. {
  1736. goto EH_Context;
  1737. }
  1738. if ((Status = LiveKernelTargetInfo::Initialize()) != S_OK)
  1739. {
  1740. goto EH_RunChange;
  1741. }
  1742. //
  1743. // Check and see if this EXDI implementation supports
  1744. // the extended Ioctl's we've defined.
  1745. //
  1746. DBGENG_EXDI_IOCTL_BASE_IN IoctlIn;
  1747. DBGENG_EXDI_IOCTL_IDENTIFY_OUT IoctlOut;
  1748. ULONG OutUsed;
  1749. IoctlIn.Code = DBGENG_EXDI_IOC_IDENTIFY;
  1750. if (m_Server->
  1751. Ioctl(sizeof(IoctlIn), (PBYTE)&IoctlIn,
  1752. sizeof(IoctlOut), &OutUsed, (PBYTE)&IoctlOut) == S_OK &&
  1753. IoctlOut.Signature == DBGENG_EXDI_IOCTL_IDENTIFY_SIGNATURE)
  1754. {
  1755. m_IoctlMin = IoctlOut.BeforeFirst;
  1756. m_IoctlMax = IoctlOut.AfterLast;
  1757. if (DBGENG_EXDI_IOC_GET_BREAKPOINT_HIT <= m_IoctlMin ||
  1758. DBGENG_EXDI_IOC_GET_BREAKPOINT_HIT >= m_IoctlMax)
  1759. {
  1760. // Can't use EXDI data breakpoints without this ioctl.
  1761. WarnOut("EXDI data breakpoints not supported\n");
  1762. m_ExdiDataBreaks = FALSE;
  1763. }
  1764. }
  1765. m_ContextValid = FALSE;
  1766. return S_OK;
  1767. EH_RunChange:
  1768. m_RunChange.Uninitialize();
  1769. EH_Context:
  1770. RELEASE(m_Context);
  1771. EH_MarshalledServer:
  1772. RELEASE(m_MarshalledServer);
  1773. EH_Server:
  1774. RELEASE(m_Server);
  1775. EH_CoInit:
  1776. g_Ole32Calls.CoUninitialize();
  1777. return Status;
  1778. }
  1779. HRESULT
  1780. ExdiLiveKernelTargetInfo::GetDescription(PSTR Buffer, ULONG BufferLen,
  1781. PULONG DescLen)
  1782. {
  1783. return FillStringBuffer("eXDI KD", 0,
  1784. Buffer, BufferLen, DescLen);
  1785. }
  1786. HRESULT
  1787. ExdiLiveKernelTargetInfo::SwitchProcessors(ULONG Processor)
  1788. {
  1789. HRESULT Status;
  1790. if (DBGENG_EXDI_IOC_SET_CURRENT_PROCESSOR <= m_IoctlMin ||
  1791. DBGENG_EXDI_IOC_SET_CURRENT_PROCESSOR >= m_IoctlMax)
  1792. {
  1793. // Switch Ioctl not supported.
  1794. return E_NOTIMPL;
  1795. }
  1796. DBGENG_EXDI_IOCTL_SET_CURRENT_PROCESSOR_IN IoctlIn;
  1797. ULONG OutUsed;
  1798. IoctlIn.Code = DBGENG_EXDI_IOC_SET_CURRENT_PROCESSOR;
  1799. IoctlIn.Processor = Processor;
  1800. if ((Status = m_Server->Ioctl(sizeof(IoctlIn), (PBYTE)&IoctlIn,
  1801. 0, &OutUsed, (PBYTE)&IoctlIn)) != S_OK)
  1802. {
  1803. ErrOut("Unable to switch processors, %s\n",
  1804. FormatStatusCode(Status));
  1805. return Status;
  1806. }
  1807. SetCurrentProcessorThread(this, Processor, FALSE);
  1808. return S_OK;
  1809. }
  1810. #define EXDI_IOCTL_GET_KD_VERSION ((ULONG)'VDKG')
  1811. HRESULT
  1812. ExdiLiveKernelTargetInfo::GetTargetKdVersion(PDBGKD_GET_VERSION64 Version)
  1813. {
  1814. switch(m_KdSupport)
  1815. {
  1816. case EXDI_KD_IOCTL:
  1817. //
  1818. // User has indicated the target supports the
  1819. // KD version ioctl.
  1820. //
  1821. ULONG Command;
  1822. ULONG Retrieved;
  1823. HRESULT Status;
  1824. Command = EXDI_IOCTL_GET_KD_VERSION;
  1825. if ((Status = m_Server->Ioctl(sizeof(Command), (PBYTE)&Command,
  1826. sizeof(*Version), &Retrieved,
  1827. (PBYTE)Version)) != S_OK)
  1828. {
  1829. return Status;
  1830. }
  1831. if (Retrieved != sizeof(*Version))
  1832. {
  1833. return E_FAIL;
  1834. }
  1835. // This mode implies a recent kernel so we can
  1836. // assume 64-bit kd.
  1837. m_KdApi64 = TRUE;
  1838. break;
  1839. case EXDI_KD_GS_PCR:
  1840. //
  1841. // User has indicated that a version of NT
  1842. // is running and that the PCR can be accessed
  1843. // through GS. Look up the version block from
  1844. // the PCR.
  1845. //
  1846. if (m_ExpectedMachine == IMAGE_FILE_MACHINE_AMD64)
  1847. {
  1848. ULONG64 KdVer;
  1849. ULONG Done;
  1850. if ((Status = Amd64MachineInfo::
  1851. StaticGetExdiContext(m_Context, &m_ContextData,
  1852. m_ContextType)) != S_OK)
  1853. {
  1854. return Status;
  1855. }
  1856. if ((Status = m_Server->
  1857. ReadVirtualMemory(m_ContextData.Amd64Context.
  1858. DescriptorGs.SegBase +
  1859. AMD64_KPCR_KD_VERSION_BLOCK,
  1860. sizeof(KdVer), 8, (PBYTE)&KdVer,
  1861. &Done)) != S_OK)
  1862. {
  1863. return Status;
  1864. }
  1865. if (Done != sizeof(KdVer))
  1866. {
  1867. return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
  1868. }
  1869. if ((Status = m_Server->
  1870. ReadVirtualMemory(KdVer, sizeof(*Version), 8, (PBYTE)Version,
  1871. &Done)) != S_OK)
  1872. {
  1873. return Status;
  1874. }
  1875. if (Done != sizeof(*Version))
  1876. {
  1877. return HRESULT_FROM_WIN32(ERROR_READ_FAULT);
  1878. }
  1879. // This mode implies a recent kernel so we can
  1880. // assume 64-bit kd.
  1881. m_KdApi64 = TRUE;
  1882. // Update the version block's Simulation field to
  1883. // indicate that this is a simulated execution.
  1884. Version->Simulation = DBGKD_SIMULATION_EXDI;
  1885. if ((Status = m_Server->
  1886. WriteVirtualMemory(KdVer, sizeof(*Version), 8, (PBYTE)Version,
  1887. &Done)) != S_OK)
  1888. {
  1889. return Status;
  1890. }
  1891. if (Done != sizeof(*Version))
  1892. {
  1893. return HRESULT_FROM_WIN32(ERROR_WRITE_FAULT);
  1894. }
  1895. }
  1896. else
  1897. {
  1898. return E_INVALIDARG;
  1899. }
  1900. break;
  1901. case EXDI_KD_NONE:
  1902. //
  1903. // Fake up a version structure.
  1904. //
  1905. Version->MajorVersion = DBGKD_MAJOR_EXDI << 8;
  1906. Version->ProtocolVersion = 0;
  1907. Version->Flags = DBGKD_VERS_FLAG_PTR64 | DBGKD_VERS_FLAG_NOMM;
  1908. Version->MachineType = (USHORT)m_ExpectedMachine;
  1909. Version->KernBase = 0;
  1910. Version->PsLoadedModuleList = 0;
  1911. Version->DebuggerDataList = 0;
  1912. break;
  1913. }
  1914. return S_OK;
  1915. }
  1916. HRESULT
  1917. ExdiLiveKernelTargetInfo::RequestBreakIn(void)
  1918. {
  1919. //
  1920. // m_Server was created by the session thread but
  1921. // RequestBreakIn can be called from any thread.
  1922. // The thread may not be initialized for multithreading
  1923. // and so we have to explicitly unmarshal the server
  1924. // interface into this thread to make sure that
  1925. // the method call will be successful regardless of
  1926. // the COM threading model for the current thread.
  1927. //
  1928. if (GetCurrentThreadId() == g_SessionThread)
  1929. {
  1930. return m_Server->Halt();
  1931. }
  1932. else
  1933. {
  1934. HRESULT Status;
  1935. IeXdiServer* Server;
  1936. LARGE_INTEGER Move;
  1937. ZeroMemory(&Move, sizeof(Move));
  1938. if ((Status = m_MarshalledServer->
  1939. Seek(Move, STREAM_SEEK_SET, NULL)) != S_OK ||
  1940. (Status = g_Ole32Calls.CoUnmarshalInterface
  1941. (m_MarshalledServer, __uuidof(IeXdiServer),
  1942. (void **)&Server)) != S_OK)
  1943. {
  1944. return Status;
  1945. }
  1946. Status = Server->Halt();
  1947. Server->Release();
  1948. return Status;
  1949. }
  1950. }
  1951. HRESULT
  1952. ExdiLiveKernelTargetInfo::Reboot(void)
  1953. {
  1954. HRESULT Status = m_Server->Reboot();
  1955. if (Status == S_OK)
  1956. {
  1957. DebuggeeReset(DEBUG_SESSION_REBOOT, TRUE);
  1958. }
  1959. return Status;
  1960. }
  1961. ULONG
  1962. ExdiLiveKernelTargetInfo::GetCurrentProcessor(void)
  1963. {
  1964. if (DBGENG_EXDI_IOC_GET_CURRENT_PROCESSOR <= m_IoctlMin ||
  1965. DBGENG_EXDI_IOC_GET_CURRENT_PROCESSOR >= m_IoctlMax)
  1966. {
  1967. // Ioctl unsupported so assume processor zero.
  1968. return 0;
  1969. }
  1970. DBGENG_EXDI_IOCTL_BASE_IN IoctlIn;
  1971. DBGENG_EXDI_IOCTL_GET_CURRENT_PROCESSOR_OUT IoctlOut;
  1972. ULONG OutUsed;
  1973. IoctlIn.Code = DBGENG_EXDI_IOC_GET_CURRENT_PROCESSOR;
  1974. if (m_Server->
  1975. Ioctl(sizeof(IoctlIn), (PBYTE)&IoctlIn,
  1976. sizeof(IoctlOut), &OutUsed, (PBYTE)&IoctlOut) == S_OK)
  1977. {
  1978. return IoctlOut.Processor;
  1979. }
  1980. // Failure, assume processor zero.
  1981. ErrOut("Unable to get current processor\n");
  1982. return 0;
  1983. }
  1984. //----------------------------------------------------------------------------
  1985. //
  1986. // UserTargetInfo miscellaneous methods.
  1987. //
  1988. // Data space methods and system objects methods are elsewhere.
  1989. //
  1990. //----------------------------------------------------------------------------
  1991. LiveUserTargetInfo::LiveUserTargetInfo(ULONG Qual)
  1992. : TargetInfo(DEBUG_CLASS_USER_WINDOWS, Qual, TRUE)
  1993. {
  1994. m_Services = NULL;
  1995. m_ServiceFlags = 0;
  1996. strcpy(m_ProcessServer, "<Local>");
  1997. m_Local = TRUE;
  1998. m_DataBpAddrValid = FALSE;
  1999. m_ProcessPending = NULL;
  2000. m_AllPendingFlags = 0;
  2001. }
  2002. LiveUserTargetInfo::~LiveUserTargetInfo(void)
  2003. {
  2004. // Force processes and threads to get cleaned up while
  2005. // the services are still available to close handles.
  2006. DeleteSystemInfo();
  2007. RELEASE(m_Services);
  2008. }
  2009. HRESULT
  2010. LiveUserTargetInfo::Initialize(void)
  2011. {
  2012. // Nothing to do right now.
  2013. return TargetInfo::Initialize();
  2014. }
  2015. HRESULT
  2016. LiveUserTargetInfo::GetDescription(PSTR Buffer, ULONG BufferLen,
  2017. PULONG DescLen)
  2018. {
  2019. HRESULT Status;
  2020. Status = AppendToStringBuffer(S_OK, "Live user mode", TRUE,
  2021. &Buffer, &BufferLen, DescLen);
  2022. Status = AppendToStringBuffer(Status, ": ", FALSE,
  2023. &Buffer, &BufferLen, DescLen);
  2024. Status = AppendToStringBuffer(Status, m_ProcessServer, FALSE,
  2025. &Buffer, &BufferLen, DescLen);
  2026. return Status;
  2027. }
  2028. HRESULT
  2029. LiveUserTargetInfo::GetImageVersionInformation(ProcessInfo* Process,
  2030. PCSTR ImagePath,
  2031. ULONG64 ImageBase,
  2032. PCSTR Item,
  2033. PVOID Buffer,
  2034. ULONG BufferSize,
  2035. PULONG VerInfoSize)
  2036. {
  2037. HRESULT Status;
  2038. PWSTR FileW;
  2039. if ((Status = AnsiToWide(ImagePath, &FileW)) != S_OK)
  2040. {
  2041. return Status;
  2042. }
  2043. Status = m_Services->
  2044. GetFileVersionInformationA(FileW, Item,
  2045. Buffer, BufferSize, VerInfoSize);
  2046. FreeWide(FileW);
  2047. return Status;
  2048. }
  2049. ULONG64
  2050. LiveUserTargetInfo::GetCurrentTimeDateN(void)
  2051. {
  2052. ULONG64 TimeDate;
  2053. if (m_Services->GetCurrentTimeDateN(&TimeDate) == S_OK)
  2054. {
  2055. return TimeDate;
  2056. }
  2057. else
  2058. {
  2059. return 0;
  2060. }
  2061. }
  2062. ULONG64
  2063. LiveUserTargetInfo::GetCurrentSystemUpTimeN(void)
  2064. {
  2065. ULONG64 UpTime;
  2066. if (m_Services->GetCurrentSystemUpTimeN(&UpTime) == S_OK)
  2067. {
  2068. return UpTime;
  2069. }
  2070. else
  2071. {
  2072. return 0;
  2073. }
  2074. }
  2075. ULONG64
  2076. LiveUserTargetInfo::GetProcessUpTimeN(ProcessInfo* Process)
  2077. {
  2078. ULONG64 UpTime;
  2079. if (Process &&
  2080. m_Services->GetProcessUpTimeN(Process->m_SysHandle, &UpTime) == S_OK)
  2081. {
  2082. return UpTime;
  2083. }
  2084. else
  2085. {
  2086. return 0;
  2087. }
  2088. }
  2089. HRESULT
  2090. LiveUserTargetInfo::GetProcessTimes(ProcessInfo* Process,
  2091. PULONG64 Create,
  2092. PULONG64 Exit,
  2093. PULONG64 Kernel,
  2094. PULONG64 User)
  2095. {
  2096. return m_Services->GetProcessTimes(Process->m_SysHandle,
  2097. Create, Exit, Kernel, User);
  2098. }
  2099. HRESULT
  2100. LiveUserTargetInfo::GetThreadTimes(ThreadInfo* Thread,
  2101. PULONG64 Create,
  2102. PULONG64 Exit,
  2103. PULONG64 Kernel,
  2104. PULONG64 User)
  2105. {
  2106. return m_Services->GetThreadTimes(Thread->m_Handle,
  2107. Create, Exit, Kernel, User);
  2108. }
  2109. HRESULT
  2110. LiveUserTargetInfo::RequestBreakIn(void)
  2111. {
  2112. ProcessInfo* Process = g_Process;
  2113. if (!Process)
  2114. {
  2115. // No current process, so find any process.
  2116. Process = m_ProcessHead;
  2117. if (!Process)
  2118. {
  2119. return E_UNEXPECTED;
  2120. }
  2121. }
  2122. return m_Services->
  2123. RequestBreakIn(Process->m_SysHandle);
  2124. }
  2125. //----------------------------------------------------------------------------
  2126. //
  2127. // Base TargetInfo methods that trivially fail.
  2128. //
  2129. //----------------------------------------------------------------------------
  2130. #define UNEXPECTED_VOID(Class, Method, Args) \
  2131. void \
  2132. Class::Method Args \
  2133. { \
  2134. ErrOut("TargetInfo::" #Method " is not available in the current debug session\n"); \
  2135. }
  2136. #define UNEXPECTED_HR(Class, Method, Args) \
  2137. HRESULT \
  2138. Class::Method Args \
  2139. { \
  2140. ErrOut("TargetInfo::" #Method " is not available in the current debug session\n"); \
  2141. return E_UNEXPECTED; \
  2142. }
  2143. #define UNEXPECTED_ULONG64(Class, Method, Val, Args) \
  2144. ULONG64 \
  2145. Class::Method Args \
  2146. { \
  2147. ErrOut("TargetInfo::" #Method " is not available in the current debug session\n"); \
  2148. return Val; \
  2149. }
  2150. UNEXPECTED_HR(TargetInfo, ReadVirtual, (
  2151. IN ProcessInfo* Process,
  2152. IN ULONG64 Offset,
  2153. OUT PVOID Buffer,
  2154. IN ULONG BufferSize,
  2155. OUT OPTIONAL PULONG BytesRead
  2156. ))
  2157. UNEXPECTED_HR(TargetInfo, WriteVirtual, (
  2158. IN ProcessInfo* Process,
  2159. IN ULONG64 Offset,
  2160. IN PVOID Buffer,
  2161. IN ULONG BufferSize,
  2162. OUT OPTIONAL PULONG BytesWritten
  2163. ))
  2164. UNEXPECTED_HR(TargetInfo, ReadPhysical, (
  2165. IN ULONG64 Offset,
  2166. OUT PVOID Buffer,
  2167. IN ULONG BufferSize,
  2168. IN ULONG Flags,
  2169. OUT OPTIONAL PULONG BytesRead
  2170. ))
  2171. UNEXPECTED_HR(TargetInfo, WritePhysical, (
  2172. IN ULONG64 Offset,
  2173. IN PVOID Buffer,
  2174. IN ULONG BufferSize,
  2175. IN ULONG Flags,
  2176. OUT OPTIONAL PULONG BytesWritten
  2177. ))
  2178. UNEXPECTED_HR(TargetInfo, ReadControl, (
  2179. IN ULONG Processor,
  2180. IN ULONG64 Offset,
  2181. OUT PVOID Buffer,
  2182. IN ULONG BufferSize,
  2183. OUT OPTIONAL PULONG BytesRead
  2184. ))
  2185. UNEXPECTED_HR(TargetInfo, WriteControl, (
  2186. IN ULONG Processor,
  2187. IN ULONG64 Offset,
  2188. IN PVOID Buffer,
  2189. IN ULONG BufferSize,
  2190. OUT OPTIONAL PULONG BytesWritten
  2191. ))
  2192. UNEXPECTED_HR(TargetInfo, ReadIo, (
  2193. IN ULONG InterfaceType,
  2194. IN ULONG BusNumber,
  2195. IN ULONG AddressSpace,
  2196. IN ULONG64 Offset,
  2197. OUT PVOID Buffer,
  2198. IN ULONG BufferSize,
  2199. OUT OPTIONAL PULONG BytesRead
  2200. ))
  2201. UNEXPECTED_HR(TargetInfo, WriteIo, (
  2202. IN ULONG InterfaceType,
  2203. IN ULONG BusNumber,
  2204. IN ULONG AddressSpace,
  2205. IN ULONG64 Offset,
  2206. IN PVOID Buffer,
  2207. IN ULONG BufferSize,
  2208. OUT OPTIONAL PULONG BytesWritten
  2209. ))
  2210. UNEXPECTED_HR(TargetInfo, ReadMsr, (
  2211. IN ULONG Msr,
  2212. OUT PULONG64 Value
  2213. ))
  2214. UNEXPECTED_HR(TargetInfo, WriteMsr, (
  2215. IN ULONG Msr,
  2216. IN ULONG64 Value
  2217. ))
  2218. UNEXPECTED_HR(TargetInfo, ReadBusData, (
  2219. IN ULONG BusDataType,
  2220. IN ULONG BusNumber,
  2221. IN ULONG SlotNumber,
  2222. IN ULONG Offset,
  2223. OUT PVOID Buffer,
  2224. IN ULONG BufferSize,
  2225. OUT OPTIONAL PULONG BytesRead
  2226. ))
  2227. UNEXPECTED_HR(TargetInfo, WriteBusData, (
  2228. IN ULONG BusDataType,
  2229. IN ULONG BusNumber,
  2230. IN ULONG SlotNumber,
  2231. IN ULONG Offset,
  2232. IN PVOID Buffer,
  2233. IN ULONG BufferSize,
  2234. OUT OPTIONAL PULONG BytesWritten
  2235. ))
  2236. UNEXPECTED_HR(TargetInfo, CheckLowMemory, (
  2237. ))
  2238. UNEXPECTED_HR(TargetInfo, GetTargetContext, (
  2239. ULONG64 Thread,
  2240. PVOID Context
  2241. ))
  2242. UNEXPECTED_HR(TargetInfo, SetTargetContext, (
  2243. ULONG64 Thread,
  2244. PVOID Context
  2245. ))
  2246. UNEXPECTED_HR(TargetInfo, GetThreadIdByProcessor, (
  2247. IN ULONG Processor,
  2248. OUT PULONG Id
  2249. ))
  2250. UNEXPECTED_HR(TargetInfo, GetThreadInfoDataOffset, (
  2251. ThreadInfo* Thread,
  2252. ULONG64 ThreadHandle,
  2253. PULONG64 Offset))
  2254. UNEXPECTED_HR(TargetInfo, GetProcessInfoDataOffset, (
  2255. ThreadInfo* Thread,
  2256. ULONG Processor,
  2257. ULONG64 ThreadData,
  2258. PULONG64 Offset))
  2259. UNEXPECTED_HR(TargetInfo, GetThreadInfoTeb, (
  2260. ThreadInfo* Thread,
  2261. ULONG Processor,
  2262. ULONG64 ThreadData,
  2263. PULONG64 Offset))
  2264. UNEXPECTED_HR(TargetInfo, GetProcessInfoPeb, (
  2265. ThreadInfo* Thread,
  2266. ULONG Processor,
  2267. ULONG64 ThreadData,
  2268. PULONG64 Offset))
  2269. UNEXPECTED_HR(TargetInfo, GetSelDescriptor, (
  2270. ThreadInfo* Thread,
  2271. MachineInfo* Machine,
  2272. ULONG Selector,
  2273. PDESCRIPTOR64 Desc))
  2274. UNEXPECTED_HR(TargetInfo, SwitchProcessors, (
  2275. ULONG Processor))
  2276. UNEXPECTED_HR(TargetInfo, GetTargetKdVersion, (
  2277. PDBGKD_GET_VERSION64 Version))
  2278. UNEXPECTED_HR(TargetInfo, ReadBugCheckData, (
  2279. PULONG Code, ULONG64 Args[4]))
  2280. UNEXPECTED_HR(TargetInfo, GetExceptionContext, (
  2281. PCROSS_PLATFORM_CONTEXT Context))
  2282. UNEXPECTED_VOID(TargetInfo, InitializeWatchTrace, (
  2283. void))
  2284. UNEXPECTED_VOID(TargetInfo, ProcessWatchTraceEvent, (
  2285. PDBGKD_TRACE_DATA TraceData,
  2286. PADDR PcAddr,
  2287. PBOOL StepOver))
  2288. UNEXPECTED_HR(TargetInfo, WaitForEvent, (
  2289. ULONG Flags,
  2290. ULONG Timeout,
  2291. ULONG ElapsedTime,
  2292. PULONG EventStatus))
  2293. UNEXPECTED_HR(TargetInfo, RequestBreakIn, (void))
  2294. UNEXPECTED_HR(TargetInfo, Reboot, (void))
  2295. UNEXPECTED_HR(TargetInfo, Crash, (ULONG Code))
  2296. UNEXPECTED_HR(TargetInfo, InsertCodeBreakpoint, (
  2297. ProcessInfo* Process,
  2298. MachineInfo* Machine,
  2299. PADDR Addr,
  2300. ULONG InstrFlags,
  2301. PUCHAR StorageSpace))
  2302. UNEXPECTED_HR(TargetInfo, RemoveCodeBreakpoint, (
  2303. ProcessInfo* Process,
  2304. MachineInfo* Machine,
  2305. PADDR Addr,
  2306. ULONG InstrFlags,
  2307. PUCHAR StorageSpace))
  2308. UNEXPECTED_HR(TargetInfo, InsertTargetCountBreakpoint, (
  2309. PADDR Addr,
  2310. ULONG Flags))
  2311. UNEXPECTED_HR(TargetInfo, RemoveTargetCountBreakpoint, (
  2312. PADDR Addr))
  2313. UNEXPECTED_HR(TargetInfo, QueryTargetCountBreakpoint, (
  2314. PADDR Addr,
  2315. PULONG Flags,
  2316. PULONG Calls,
  2317. PULONG MinInstr,
  2318. PULONG MaxInstr,
  2319. PULONG TotInstr,
  2320. PULONG MaxCps))
  2321. UNEXPECTED_HR(TargetInfo, QueryMemoryRegion, (
  2322. ProcessInfo* Process,
  2323. PULONG64 Handle,
  2324. BOOL HandleIsOffset,
  2325. PMEMORY_BASIC_INFORMATION64 Info))