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.

1269 lines
36 KiB

  1. /*++
  2. Copyright (c) 1992-2000 Microsoft Corporation
  3. Module Name:
  4. power.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Revision History:
  8. --*/
  9. // podev - dump power relevent data (and other data) about a device object
  10. // polist [arg] - if no arg, dump data about powerirpseriallist
  11. // if arg, show entries in serialist that refer to that device object
  12. // podevnode - dump inverted tree and inclusion %
  13. // podevnode <any> - dump normal pnp tree, used only for testing with inverted tree
  14. // postate - dump state statistics
  15. #include "precomp.h"
  16. #pragma hdrstop
  17. VOID
  18. popDumpDeviceName(
  19. ULONG64 DeviceAddress
  20. );
  21. __inline
  22. ULONG64
  23. GetAddress(
  24. IN ULONG64 Base,
  25. IN PCHAR Type,
  26. IN PCHAR Field)
  27. {
  28. ULONG Offset;
  29. GetFieldOffset(Type, Field, &Offset);
  30. return(Base + Offset);
  31. }
  32. typedef struct {
  33. ULONG Flags;
  34. PUCHAR String;
  35. } DEFBITS, *PDEFBITS;
  36. DEFBITS ActFlags[] = {
  37. POWER_ACTION_QUERY_ALLOWED, "QueryApps",
  38. POWER_ACTION_UI_ALLOWED, "UIAllowed",
  39. POWER_ACTION_OVERRIDE_APPS, "OverrideApps",
  40. POWER_ACTION_DISABLE_WAKES, "DisableWakes",
  41. POWER_ACTION_CRITICAL, "Critical",
  42. 0, NULL
  43. };
  44. PUCHAR rgPowerNotifyOrder[PO_ORDER_MAXIMUM+1] = {
  45. "Non-Paged, PnP, Video",
  46. "Non-Paged, PnP",
  47. "Non-Paged, Root-Enum, Video",
  48. "Non-Paged, Root-Enum",
  49. "Paged, PnP, Video",
  50. "Paged, PnP",
  51. "Paged, Root-Enum, Video",
  52. "Paged, Root-Enum"
  53. };
  54. static UCHAR Buffer[50];
  55. VOID
  56. poDumpDevice(
  57. ULONG64 DeviceAddress
  58. );
  59. DECLARE_API( podev )
  60. /*++
  61. Routine Description:
  62. Dump the power relevent fields of a device object.
  63. Arguments:
  64. args - the location of the device object of interest
  65. Return Value:
  66. None
  67. --*/
  68. {
  69. ULONG64 deviceToDump;
  70. deviceToDump = GetExpression(args);
  71. dprintf("Device object is for:\n");
  72. poDumpDevice(deviceToDump);
  73. return S_OK;
  74. }
  75. VOID
  76. poDumpDevice(
  77. ULONG64 DeviceAddress
  78. )
  79. /*++
  80. Routine Description:
  81. Displays the driver name for the device object if possible, and
  82. then displays power relevent fields.
  83. Arguments:
  84. DeviceAddress - address of device object to dump.
  85. Return Value:
  86. None
  87. --*/
  88. {
  89. ULONG result;
  90. ULONG i;
  91. PUCHAR buffer;
  92. UNICODE_STRING unicodeString;
  93. ULONG64 nextEntry;
  94. ULONG64 queueAddress;
  95. ULONG64 irp;
  96. ULONG64 pObjectHeader;
  97. ULONG64 pNameInfo;
  98. ULONG rmr;
  99. ULONG Type;
  100. ULONG Flags;
  101. ULONG64 Temp, DeviceObjectExtension, Dope;
  102. USHORT Length;
  103. if (GetFieldValue(DeviceAddress,
  104. "nt!_DEVICE_OBJECT",
  105. "Type",
  106. Type)) {
  107. dprintf("%08p: Could not read device object\n", DeviceAddress);
  108. return;
  109. }
  110. if (Type != IO_TYPE_DEVICE) {
  111. dprintf("%08p: is not a device object\n", DeviceAddress);
  112. return;
  113. }
  114. //
  115. // Dump the device name if present.
  116. //
  117. pObjectHeader = KD_OBJECT_TO_OBJECT_HEADER(DeviceAddress);
  118. if (GetFieldValue(pObjectHeader,
  119. "nt!_OBJECT_HEADER",
  120. "Type",
  121. Temp)) {
  122. ULONG64 pName;
  123. KD_OBJECT_HEADER_TO_NAME_INFO( pObjectHeader, &pNameInfo );
  124. if (GetFieldValue(pNameInfo,
  125. "nt!_OBJECT_HEADER_NAME_INFO",
  126. "Name.Length",
  127. Length)) {
  128. if (Length > 0x1000) // sanity check
  129. {
  130. Length = 0x1000;
  131. }
  132. buffer = LocalAlloc(LPTR, Length);
  133. if (buffer != NULL) {
  134. unicodeString.MaximumLength = Length;
  135. unicodeString.Length = Length;
  136. unicodeString.Buffer = (PWSTR)buffer;
  137. GetFieldValue(pNameInfo,
  138. "nt!_OBJECT_HEADER_NAME_INFO",
  139. "Name.Buffer",
  140. pName);
  141. if (ReadMemory(pName,
  142. buffer,
  143. unicodeString.Length,
  144. &result) && (result == unicodeString.Length)) {
  145. unicodeString.Buffer[(unicodeString.Length/sizeof(WCHAR))-1] = 0;
  146. dprintf(" %wZ", &unicodeString);
  147. }
  148. LocalFree(buffer);
  149. }
  150. }
  151. }
  152. //
  153. // Dump Irps related to driver.
  154. //
  155. InitTypeRead(DeviceAddress, nt!_DEVICE_OBJECT);
  156. dprintf(" DriverObject %08lx\n", ReadField(DriverObject));
  157. dprintf("Current Irp %08lx RefCount %d Type %08lx ",
  158. ReadField(CurrentIrp),
  159. ReadField(ReferenceCount),
  160. ReadField(DeviceType));
  161. if (ReadField(AttachedDevice)) {
  162. dprintf("AttachedDev %08p ", ReadField(AttachedDevice));
  163. }
  164. if (ReadField(Vpb)) {
  165. dprintf("Vpb %08p ", ReadField(Vpb));
  166. }
  167. dprintf("DevFlags %08lx", (Flags = (ULONG) ReadField(Flags)));
  168. if (Flags & DO_POWER_PAGABLE) dprintf(" DO_POWER_PAGABLE");
  169. if (Flags & DO_POWER_INRUSH) dprintf(" DO_POWER_INRUSH");
  170. if (Flags & DO_POWER_NOOP) dprintf(" DO_POWER_NOOP");
  171. dprintf("\n");
  172. DeviceObjectExtension = ReadField(DeviceObjectExtension);
  173. if (ReadField(DeviceQueue.Busy)) {
  174. ULONG Off;
  175. GetFieldOffset("nt!_DEVICE_OBJECT", "DeviceQueue.DeviceListHead", &Off);
  176. nextEntry = ReadField(DeviceQueue.DeviceListHead.Flink);
  177. if (nextEntry == DeviceAddress + Off) {
  178. dprintf("Device queue is busy -- Queue empty\n");
  179. } else {
  180. ULONG Qoffset, IrpOffset;
  181. dprintf("DeviceQueue: ");
  182. i = 0;
  183. GetFieldOffset("nt!_DEVICE_OBJECT", "DeviceListEntry", &Qoffset);
  184. GetFieldOffset("nt!_IRP", "Tail.Overlay.DeviceQueueEntry", &IrpOffset);
  185. while ( nextEntry != ( DeviceAddress + Off )) {
  186. queueAddress = (nextEntry - Qoffset);
  187. if (GetFieldValue(queueAddress,
  188. "nt!_KDEVICE_QUEUE_ENTRY",
  189. "DeviceListEntry.Flink",
  190. nextEntry)) {
  191. dprintf("%08p: Could not read queue entry\n", DeviceAddress);
  192. return;
  193. }
  194. // nextEntry = queueEntry.DeviceListEntry.Flink;
  195. irp = (queueAddress - IrpOffset);
  196. dprintf("%08p%s",
  197. irp,
  198. (i & 0x03) == 0x03 ? "\n\t " : " ");
  199. if (CheckControlC()) {
  200. break;
  201. }
  202. }
  203. dprintf("\n");
  204. }
  205. } else {
  206. dprintf("Device queue is not busy.\n");
  207. }
  208. dprintf("Device Object Extension: %08p:\n", DeviceObjectExtension);
  209. if (GetFieldValue(DeviceObjectExtension,
  210. "nt!_DEVOBJ_EXTENSION",
  211. "PowerFlags",
  212. Flags)) {
  213. dprintf("Could not read Device Object Extension %p\n", DeviceObjectExtension);
  214. return;
  215. }
  216. dprintf("PowerFlags: %08lx =>", Flags);
  217. #define PopGetDoSystemPowerState(Flags) \
  218. (Flags & POPF_SYSTEM_STATE)
  219. #define PopGetDoDevicePowerState(Flags) \
  220. ((Flags & POPF_DEVICE_STATE) >> 4)
  221. dprintf("SystemState=%1x", PopGetDoSystemPowerState(Flags) );
  222. dprintf(" DeviceState=%lx", PopGetDoDevicePowerState(Flags) );
  223. if (Flags & POPF_SYSTEM_ACTIVE) dprintf(" syact");
  224. if (Flags & POPF_SYSTEM_PENDING) dprintf(" sypnd");
  225. if (Flags & POPF_DEVICE_ACTIVE) dprintf(" dvact");
  226. if (Flags & POPF_DEVICE_PENDING) dprintf(" dvpnd");
  227. GetFieldValue(DeviceObjectExtension,"nt!_DEVOBJ_EXTENSION","Dope",Dope);
  228. dprintf("\nDope: %08lx:\n", Dope);
  229. if (Dope != 0) {
  230. rmr = GetFieldValue(Dope, "nt!_DEVICE_OBJECT_POWER_EXTENSION",
  231. "DeviceType", Type);
  232. if (!rmr) {
  233. InitTypeRead(Dope, nt!_DEVICE_OBJECT_POWER_EXTENSION);
  234. dprintf("IdleCount: %08p ConIdlTime: %08p PerfIdlTime: %08p\n",
  235. ReadField(IdleCount), ReadField(ConservationIdleTime), ReadField(PerformanceIdleTime));
  236. dprintf("NotifySourceList fl:%08p bl:%08p\n",
  237. ReadField(NotifySourceList.Flink), ReadField(NotifySourceList.Blink));
  238. dprintf("NotifyTargetList fl:%08p bl:%08p\n",
  239. ReadField(NotifyTargetList.Flink), ReadField(NotifyTargetList.Blink));
  240. dprintf("PowerChannelSummary TotalCount: %08p D0Count: %08p\n",
  241. ReadField(PowerChannelSummary.TotalCount), ReadField(PowerChannelSummary.D0Count));
  242. dprintf("PowerChannelSummary NotifyList fl:%08p bl:%08p\n",
  243. ReadField(PowerChannelSummary.NotifyList.Flink),
  244. ReadField(PowerChannelSummary.NotifyList.Blink)
  245. );
  246. }
  247. }
  248. return;
  249. }
  250. VOID
  251. poDumpList(
  252. ULONG64 DeviceAddress
  253. );
  254. DECLARE_API( polist )
  255. /*++
  256. Routine Description:
  257. Dump the irp serial list, unless a devobj address is given,
  258. in which case dump the irps in the serial list that point to
  259. that device object
  260. Arguments:
  261. args - the location of the device object of interest
  262. Return Value:
  263. None
  264. --*/
  265. {
  266. ULONG64 deviceToDump;
  267. deviceToDump = 0;
  268. deviceToDump = GetExpression(args);
  269. if (deviceToDump == 0) {
  270. dprintf("All entries in Power Irp Serial List\n");
  271. } else {
  272. dprintf("Entries in Power Irp Serial List for: %08p:\n", deviceToDump);
  273. }
  274. if (!IsPtr64()) {
  275. deviceToDump = (ULONG64) (LONG64) (LONG) deviceToDump;
  276. }
  277. poDumpList(deviceToDump);
  278. return S_OK;
  279. }
  280. VOID
  281. poDumpList(
  282. ULONG64 DeviceAddress
  283. )
  284. /*++
  285. Routine Description:
  286. Arguments:
  287. DeviceAddress - address of device object to dump.
  288. Return Value:
  289. None
  290. --*/
  291. {
  292. ULONG64 listhead, irpa, iosla, p;
  293. ULONG isll, result;
  294. ULONG IrpOffset;
  295. isll = GetUlongValue("nt!PopIrpSerialListLength");
  296. dprintf("PopIrpSerialListLength = %d\n", isll);
  297. listhead = GetExpression("nt!PopIrpSerialList");
  298. GetFieldOffset("nt!_IRP", "Tail.Overlay.DeviceQueueEntry", &IrpOffset);
  299. for (p = GetPointerFromAddress( listhead );
  300. (p != listhead) && p;
  301. p = GetPointerFromAddress( p))
  302. {
  303. ULONG64 DeviceObject, CurrentStackLocation;
  304. irpa = p - IrpOffset;
  305. if (GetFieldValue(irpa, "nt!_IRP", "Tail.Overlay.CurrentStackLocation", CurrentStackLocation))
  306. {
  307. dprintf("Cannot read Irp: %08p\n", irpa);
  308. return;
  309. }
  310. iosla = CurrentStackLocation + DBG_PTR_SIZE;
  311. if (GetFieldValue(iosla, "nt!_IO_STACK_LOCATION", "DeviceObject", DeviceObject) )
  312. {
  313. dprintf("Cannot read Io Stk Loc: %08p\n", iosla);
  314. return;
  315. }
  316. InitTypeRead(iosla, nt!_IO_STACK_LOCATION);
  317. if ((DeviceAddress == 0) || (DeviceAddress == DeviceObject)) {
  318. dprintf("Irp:%08p DevObj:%08p ", irpa, DeviceObject);
  319. dprintf("Ctx:%08p ", ReadField(Parameters.Power.SystemContext));
  320. if (ReadField(Parameters.Power.SystemContext) & POP_INRUSH_CONTEXT) {
  321. dprintf("inrush ");
  322. } else {
  323. dprintf(" ");
  324. }
  325. if (ReadField(Parameters.Power.Type) == SystemPowerState) {
  326. dprintf("sysirp ");
  327. dprintf("S%d\n", (LONG)(ReadField(Parameters.Power.State.SystemState)) - (LONG)PowerSystemWorking);
  328. } else {
  329. dprintf("devirp ");
  330. dprintf("D%d\n", (LONG)(ReadField(Parameters.Power.State.DeviceState)) - (LONG)PowerDeviceD0);
  331. }
  332. }
  333. if (CheckControlC())
  334. {
  335. break;
  336. }
  337. }
  338. return;
  339. }
  340. VOID
  341. poDumpRequestedList(
  342. ULONG64 DeviceAddress
  343. );
  344. DECLARE_API( poreqlist )
  345. /*++
  346. Routine Description:
  347. Dump the irp serial list, unless a devobj address is given,
  348. in which case dump the irps in the serial list that point to
  349. that device object
  350. Arguments:
  351. args - the location of the device object of interest
  352. Return Value:
  353. None
  354. --*/
  355. {
  356. ULONG64 deviceToDump;
  357. deviceToDump = GetExpression(args);
  358. if (deviceToDump == 0) {
  359. dprintf("All active Power Irps from PoRequestPowerIrp\n");
  360. } else {
  361. dprintf("Active Power Irps from PoRequestPowerIrp for: %08p:\n",
  362. deviceToDump);
  363. }
  364. poDumpRequestedList(deviceToDump);
  365. return S_OK;
  366. }
  367. VOID
  368. poDumpRequestedList (
  369. ULONG64 DeviceAddress
  370. )
  371. /*++
  372. Routine Description:
  373. Dump PopRequestedIrps List, "A list of all the power irps created from
  374. PoReqestPowerIrp.
  375. Arguments:
  376. DeviceAddress - optional address to which requested power IRPs were sent
  377. --*/
  378. {
  379. BOOL blocked = FALSE;
  380. ULONG64 listhead;
  381. ULONG64 p, spAddr, irpAddr;
  382. ULONG result;
  383. ULONG Off;
  384. dprintf("PopReqestedPowerIrpList\n");
  385. listhead = GetExpression("nt!PopRequestedIrps");
  386. GetFieldOffset("nt!_IO_STACK_LOCATION", "Parameters.Others.Argument1", &Off);
  387. dprintf("FieldOffset = %p\n",Off);
  388. for (p = GetPointerFromAddress( listhead );
  389. p != listhead;
  390. p = GetPointerFromAddress( p ))
  391. {
  392. ULONG64 CurrentStackLocation;
  393. ULONG MajorFunction;
  394. //
  395. // Reguested list is a double list of stack locations
  396. //
  397. spAddr = p - Off;
  398. if (GetFieldValue(spAddr, "nt!_IO_STACK_LOCATION",
  399. "Parameters.Others.Argument3", irpAddr)) {
  400. dprintf("Cannot read 1st stack Location: %08p\n", spAddr);
  401. return;
  402. }
  403. //
  404. // The 3rd argument of which has the pointer to the irp itself
  405. //
  406. if (GetFieldValue(irpAddr, "nt!_IRP", "Tail.Overlay.CurrentStackLocation", CurrentStackLocation))
  407. {
  408. dprintf("Cannot read Irp: %08p\n", irpAddr);
  409. return;
  410. }
  411. dprintf ("Irp %08p ", irpAddr);
  412. //
  413. // Assume the if the IRP is in this list that it has a valid
  414. // current stack location
  415. //
  416. spAddr = CurrentStackLocation;
  417. if (GetFieldValue(spAddr, "nt!_IO_STACK_LOCATION", "MajorFunction", MajorFunction) )
  418. {
  419. dprintf("Cannot read current stack location: %08p\n", spAddr);
  420. return;
  421. }
  422. //
  423. // Check to see if the irp is blocked
  424. //
  425. blocked = FALSE;
  426. if (MajorFunction != IRP_MJ_POWER) {
  427. //
  428. // Irp is blocked. The next stack location is the real one
  429. //
  430. blocked = TRUE;
  431. spAddr = CurrentStackLocation + DBG_PTR_SIZE;
  432. if (GetFieldValue(spAddr, "nt!_IO_STACK_LOCATION", "MajorFunction", MajorFunction) )
  433. {
  434. dprintf("Cannot read current stack location: %08p\n", spAddr);
  435. return;
  436. }
  437. }
  438. if ((DeviceAddress == 0) || (DeviceAddress == ReadField(DeviceObject))) {
  439. ULONG MinorFunction = 0;
  440. ULONG64 DeviceObject = 0;
  441. ULONG64 SystemContext = 0;
  442. ULONG64 Temp = 0;
  443. UCHAR IOStack[] = "nt!_IO_STACK_LOCATION";
  444. GetFieldValue(spAddr,IOStack, "DeviceObject", DeviceObject);
  445. GetFieldValue(spAddr,IOStack, "Parameters.Power.SystemContext", SystemContext);
  446. GetFieldValue(spAddr,IOStack, "MinorFunction", MinorFunction);
  447. dprintf("DevObj %08p", DeviceObject);
  448. DumpDevice(DeviceObject,0, FALSE);
  449. dprintf(" Ctx %08p ", SystemContext);
  450. if ((SystemContext & POP_INRUSH_CONTEXT) == POP_INRUSH_CONTEXT) {
  451. dprintf("* ");
  452. } else {
  453. dprintf(" ");
  454. }
  455. switch (MinorFunction) {
  456. case IRP_MN_QUERY_POWER:
  457. dprintf ("Query Power ");
  458. goto PoDumpRequestedListPowerPrint;
  459. case IRP_MN_SET_POWER:
  460. dprintf ("Set Power ");
  461. PoDumpRequestedListPowerPrint:
  462. GetFieldValue(spAddr, IOStack, "Parameters.Power.Type",Temp);
  463. if ((ULONG) Temp == SystemPowerState) {
  464. GetFieldValue(spAddr, IOStack, "Parameters.Power.State.SystemState", Temp);
  465. dprintf("S%d ", (LONG)Temp - (LONG)PowerSystemWorking);
  466. } else {
  467. GetFieldValue(spAddr, IOStack, "Parameters.Power.State.DeviceState", Temp);
  468. dprintf("D%d ", (LONG)Temp - (LONG)PowerDeviceD0);
  469. }
  470. GetFieldValue(spAddr,IOStack,"Parameters.Power.ShutdownType", Temp);
  471. dprintf ("ShutdownType %x", (LONG) Temp);
  472. break;
  473. case IRP_MN_WAIT_WAKE:
  474. GetFieldValue(spAddr, IOStack, "Parameters.WaitWake.PowerState", Temp);
  475. dprintf ("Wait Wake S%d", (LONG)Temp - (LONG)PowerSystemWorking);
  476. break;
  477. case IRP_MN_POWER_SEQUENCE:
  478. dprintf ("Power Sequence Irp");
  479. break;
  480. }
  481. if (blocked) {
  482. dprintf(" [blocked]");
  483. }
  484. dprintf("\n");
  485. }
  486. }
  487. return;
  488. }
  489. VOID poDumpNodePower();
  490. DECLARE_API( ponode )
  491. /*++
  492. Routine Description:
  493. If an argument is present, dump the devnode list in pnp order.
  494. (used only for testing)
  495. Otherwise dump the devnode inverted stack.
  496. (po enumeration order)
  497. Arguments:
  498. args - flag
  499. Return Value:
  500. None
  501. --*/
  502. {
  503. ULONG flag;
  504. dprintf("Dump Inverted DevNode Tree (power order)\n");
  505. poDumpNodePower();
  506. return S_OK;
  507. }
  508. VOID
  509. poDumpNodePower(
  510. )
  511. /*++
  512. Routine Description:
  513. Dump the devnode tree in power order.
  514. Arguments:
  515. Return Value:
  516. None
  517. --*/
  518. {
  519. #if 0
  520. LONG level, SizeOfLE, LevelOff, pdo_off;
  521. ULONG64 parray, listhead, effaddr, pdo, devNodeAddr, limit;
  522. level = GetUlongValue("nt!IopMaxDeviceNodeLevel");
  523. parray = GetExpression("nt!IopDeviceNodeStack");
  524. dprintf("Max level = %5d\n", level);
  525. dprintf("IopDeviceNodeStack %08p\n", parray);
  526. parray = GetPointerFromAddress(parray);
  527. dprintf("*IopDeviceNodeStack %08p\n", parray);
  528. dprintf("Level ListHead DevNode PDO\n");
  529. dprintf("----- -------- -------- --------\n");
  530. SizeOfLE = GetTypeSize("nt!_LIST_ENTRY");
  531. GetFieldOffset("nt!_DEVICE_NODE", "LevelList", &LevelOff);
  532. GetFieldOffset("nt!_DEVICE_NODE", "PhysicalDeviceObject", &pdo_off);
  533. for ( ; level >= 0; level--) {
  534. effaddr = (level * SizeOfLE) + parray;
  535. listhead = GetPointerFromAddress( effaddr);
  536. dprintf("%5d %08lx\n", level, listhead);
  537. if (listhead) {
  538. limit = 0;
  539. for (effaddr = GetPointerFromAddress(listhead);
  540. effaddr != listhead;
  541. effaddr = GetPointerFromAddress(effaddr))
  542. {
  543. devNodeAddr = (effaddr - LevelOff);
  544. pdo = GetPointerFromAddress((devNodeAddr+pdo_off));
  545. dprintf(" %08p %08p ", devNodeAddr, pdo);
  546. popDumpDeviceName(pdo);
  547. dprintf("\n");
  548. }
  549. }
  550. }
  551. #endif
  552. }
  553. VOID
  554. popDumpDeviceName(
  555. ULONG64 DeviceAddress
  556. )
  557. {
  558. ULONG result;
  559. PUCHAR buffer;
  560. UNICODE_STRING unicodeString;
  561. ULONG64 pObjectHeader;
  562. ULONG64 pNameInfo;
  563. ULONG Type;
  564. ULONG Flags;
  565. ULONG64 Temp;
  566. USHORT Length;
  567. if (GetFieldValue(DeviceAddress, "nt!_DEVICE_OBJECT", "Type", Type)) {
  568. dprintf("%08p: Could not read device object\n", DeviceAddress);
  569. return;
  570. }
  571. if (Type != IO_TYPE_DEVICE) {
  572. dprintf("%08p: is not a device object\n", DeviceAddress);
  573. return;
  574. }
  575. //
  576. // Dump the device name if present.
  577. //
  578. pObjectHeader = KD_OBJECT_TO_OBJECT_HEADER(DeviceAddress);
  579. if (GetFieldValue(pObjectHeader, "nt!_OBJECT_HEADER", "Type", Temp)) {
  580. ULONG64 pName;
  581. KD_OBJECT_HEADER_TO_NAME_INFO( pObjectHeader, &pNameInfo );
  582. if (GetFieldValue(pNameInfo, "nt!_OBJECT_HEADER_NAME_INFO",
  583. "Name.Length",
  584. Length)) {
  585. if (Length > 0x1000) // sanity check
  586. {
  587. Length = 0x1000;
  588. }
  589. buffer = LocalAlloc(LPTR, Length);
  590. if (buffer != NULL) {
  591. unicodeString.MaximumLength = Length;
  592. unicodeString.Length = Length;
  593. unicodeString.Buffer = (PWSTR)buffer;
  594. GetFieldValue(pNameInfo,
  595. "nt!_OBJECT_HEADER_NAME_INFO",
  596. "Name.Buffer",
  597. pName);
  598. if (ReadMemory(pName,
  599. buffer,
  600. unicodeString.Length,
  601. &result) && (result == unicodeString.Length)) {
  602. unicodeString.Buffer[(unicodeString.Length/sizeof(WCHAR))-1] = 0;
  603. dprintf(" %wZ", &unicodeString);
  604. }
  605. LocalFree(buffer);
  606. }
  607. }
  608. }
  609. return;
  610. }
  611. PUCHAR
  612. PowerAction(
  613. IN POWER_ACTION Action
  614. )
  615. {
  616. switch (Action) {
  617. case PowerActionNone: return "None";
  618. case PowerActionReserved: return "Reserved";
  619. case PowerActionSleep: return "Sleep";
  620. case PowerActionHibernate: return "Hibernate";
  621. case PowerActionShutdown: return "Shutdown";
  622. case PowerActionShutdownReset: return "ShutdownReset";
  623. case PowerActionShutdownOff: return "ShutdownOff";
  624. case PowerActionWarmEject: return "WarmEject";
  625. }
  626. return "???";
  627. }
  628. PUCHAR
  629. SystemState(
  630. SYSTEM_POWER_STATE State
  631. )
  632. {
  633. switch (State) {
  634. case PowerSystemUnspecified: return "Unspecified";
  635. case PowerSystemWorking: return "Working";
  636. case PowerSystemSleeping1: return "Sleeping1";
  637. case PowerSystemSleeping2: return "Sleeping2";
  638. case PowerSystemSleeping3: return "Sleeping3";
  639. case PowerSystemHibernate: return "Hibernate";
  640. case PowerSystemShutdown: return "Shutdown";
  641. }
  642. sprintf (Buffer, "State=%x", State);
  643. return Buffer;
  644. }
  645. PUCHAR
  646. PoIrpMinor (
  647. UCHAR IrpMinor
  648. )
  649. {
  650. switch (IrpMinor) {
  651. case IRP_MN_QUERY_POWER: return "QueryPower";
  652. case IRP_MN_SET_POWER: return "SetPower";
  653. }
  654. return "??";
  655. }
  656. PUCHAR
  657. TF (
  658. BOOLEAN Flag
  659. )
  660. {
  661. switch (Flag) {
  662. case TRUE: return "TRUE";
  663. case FALSE: return "FALSE";
  664. }
  665. sprintf (Buffer, "%x", Flag);
  666. return Buffer;
  667. }
  668. PWCHAR
  669. DumpDoName (
  670. IN ULONG64 Str
  671. )
  672. {
  673. static WCHAR Name[50];
  674. memset (Name, 0, sizeof(Name));
  675. ReadMemory (Str, Name, sizeof(Name), NULL);
  676. Name[sizeof(Name)-1] = 0;
  677. return Name;
  678. }
  679. PUCHAR
  680. DumpQueueHead (
  681. IN ULONG64 StrucAddr,
  682. IN ULONG64 Struc,
  683. IN ULONG Offset
  684. )
  685. {
  686. ULONG64 Head, Flink, Blink;
  687. ULONG64 Va;
  688. Head = Struc + Offset;
  689. Va = StrucAddr + Offset;
  690. GetFieldValue(Head, "nt!_LIST_ENTRY", "Flink", Flink);
  691. GetFieldValue(Head, "nt!_LIST_ENTRY", "Blink", Blink);
  692. if (Flink == Va && Blink == Va) {
  693. sprintf (Buffer, "Head:%08I64lx Empty", UNEXTEND64(Va));
  694. } else {
  695. sprintf (Buffer, "Head:%08I64lx F:%08I64lx B:%08I64lx", UNEXTEND64(Va), UNEXTEND64(Flink), UNEXTEND64(Blink));
  696. }
  697. return Buffer;
  698. }
  699. VOID
  700. DumpDevicePowerIrp (
  701. IN PUCHAR Desc,
  702. IN ULONG64 StrucAddr,
  703. IN ULONG64 Head,
  704. IN ULONG Offset
  705. )
  706. {
  707. ULONG64 Va;
  708. ULONG64 Link;
  709. ULONG64 Addr;
  710. ULONG Off;
  711. GetFieldOffset("nt!_POP_DEVICE_SYS_STATE", "Head", &Off);
  712. Va = (StrucAddr + Off + Offset);
  713. Link = GetPointerFromAddress(Head + Offset);
  714. if (Link == Va) {
  715. return ;
  716. }
  717. dprintf ("\n%s:\n", Desc);
  718. while (Link != Va) {
  719. ULONG64 Irp, Notify;
  720. Addr = Link - Offset;
  721. if (GetFieldValue(Addr, "nt!_POP_DEVICE_POWER_IRP", "Irp", Irp)) {
  722. dprintf ("Could not power irp\n");
  723. break;
  724. }
  725. GetFieldValue(Addr, "nt!_POP_DEVICE_SYS_STATE", "Notify", Notify);
  726. dprintf (" Irp: %08p Notify %08p\n", Irp, Notify);
  727. Link = GetPointerFromAddress(Addr + Offset);
  728. }
  729. }
  730. VOID
  731. poDumpOldNotifyList(
  732. VOID
  733. )
  734. {
  735. BOOLEAN GdiOff;
  736. UCHAR LastOrder;
  737. ULONG PartOffset, NoLists, SizeOfLE, Off, HeadOff;
  738. ULONG64 DevState, Notify;
  739. LONG i;
  740. ULONG64 ListHead;
  741. ULONG64 Link;
  742. dprintf(" NoLists........: %p\n", (NoLists = (ULONG) ReadField(Order.NoLists)));
  743. SizeOfLE = GetTypeSize("nt!_LIST_ENTRY");
  744. GdiOff = FALSE;
  745. LastOrder = 0xff;
  746. Notify = ReadField(Order.Notify);
  747. for (i=NoLists-1; i >= 0; i--) {
  748. ListHead = Notify + i*SizeOfLE;
  749. if (GetFieldValue(ListHead, "nt!_LIST_ENTRY", "Flink", Link)) {
  750. dprintf ("Could not read list head\n");
  751. break;
  752. }
  753. while (Link != ListHead) {
  754. UCHAR OrderLevel;
  755. if (GetFieldValue(Link, "nt!_PO_DEVICE_NOTIFY", "OrderLevel", OrderLevel)) {
  756. dprintf ("Could not read link\n");
  757. break;
  758. }
  759. if (LastOrder != OrderLevel) {
  760. LastOrder = OrderLevel;
  761. dprintf (" %x %s",
  762. LastOrder,
  763. LastOrder <= PO_ORDER_MAXIMUM ? rgPowerNotifyOrder[LastOrder] : ""
  764. );
  765. if (!GdiOff && OrderLevel <= PO_ORDER_GDI_NOTIFICATION) {
  766. GdiOff = TRUE;
  767. dprintf (", GdiOff\n");
  768. } else {
  769. dprintf ("\n");
  770. }
  771. }
  772. InitTypeRead(Link, nt!_PO_DEVICE_NOTIFY);
  773. dprintf (" %02x %x:%x %08x %c",
  774. i,
  775. OrderLevel,
  776. (ULONG) ReadField(NodeLevel),
  777. Link,
  778. ((UCHAR) ReadField(WakeNeeded) ? 'w' : ' ')
  779. );
  780. dprintf (" %ws\t", DumpDoName (ReadField(DriverName)));
  781. dprintf (" %ws\n", DumpDoName (ReadField(DeviceName)));
  782. Link = ReadField(Link.Flink);
  783. if (CheckControlC()) {
  784. return;
  785. }
  786. }
  787. }
  788. }
  789. ULONG
  790. DumpNotifyCallback(
  791. PFIELD_INFO pAddrInfo,
  792. PVOID Context
  793. )
  794. {
  795. if (CheckControlC()) {return 0;}
  796. InitTypeRead(pAddrInfo->address, nt!_PO_DEVICE_NOTIFY);
  797. dprintf(" %c %08p: %08p %ws\t",
  798. ReadField(WakeNeeded) ? 'w' : ' ',
  799. pAddrInfo->address,
  800. ReadField(Node),
  801. DumpDoName(ReadField(DriverName)));
  802. dprintf("%ws\n",DumpDoName(ReadField(DeviceName)));
  803. return(0);
  804. }
  805. VOID
  806. poDumpNewNotifyList(
  807. IN ULONG64 DevState
  808. )
  809. {
  810. BOOLEAN GdiOff;
  811. UCHAR LastOrder;
  812. ULONG PartOffset, NoLists, SizeOfLE, Off, HeadOff;
  813. ULONG64 Level, Notify;
  814. LONG i,j;
  815. ULONG64 ListHead;
  816. ULONG64 Link;
  817. ULONG LevelOffset;
  818. ULONG SizeOfLevel;
  819. CHAR FlinkBuff[32];
  820. PCHAR NotifyList[] = {"WaitSleep",
  821. "ReadySleep",
  822. "Pending",
  823. "Complete",
  824. "ReadyS0",
  825. "WaitS0"};
  826. SizeOfLevel = GetTypeSize("nt!_PO_NOTIFY_ORDER_LEVEL");
  827. GdiOff = FALSE;
  828. if (GetFieldOffset("nt!_POP_DEVICE_SYS_STATE",
  829. "Order.OrderLevel",
  830. &LevelOffset)) {
  831. dprintf("Couldn't get field offset for Order.OrderLevel.");
  832. return;
  833. }
  834. for (i=PO_ORDER_MAXIMUM;i>=0;i--) {
  835. if (CheckControlC()) {return;}
  836. Level = DevState + LevelOffset + i*SizeOfLevel;
  837. InitTypeRead(Level, nt!_PO_NOTIFY_ORDER_LEVEL);
  838. if (ReadField(DeviceCount)) {
  839. dprintf("Level %d (%08p) %d/%d\t%s\n",
  840. i,
  841. Level,
  842. (ULONG)ReadField(ActiveCount),
  843. (ULONG)ReadField(DeviceCount),
  844. rgPowerNotifyOrder[i]);
  845. for (j=0;j<sizeof(NotifyList)/sizeof(PCHAR);j++) {
  846. if (CheckControlC()) {return;}
  847. sprintf(FlinkBuff, "%s.Flink",NotifyList[j]);
  848. if (GetFieldValue(Level,
  849. "nt!_PO_NOTIFY_ORDER_LEVEL",
  850. FlinkBuff,
  851. Link)) {
  852. dprintf("couldn't get field value for PO_NOTIFY_ORDER_LEVEL.%s\n",FlinkBuff);
  853. return;
  854. }
  855. if (Link != GetAddress(Level, "nt!_PO_NOTIFY_ORDER_LEVEL", FlinkBuff)) {
  856. dprintf(" %s:\n",NotifyList[j]);
  857. ListType("_PO_DEVICE_NOTIFY",
  858. Link,
  859. 1,
  860. "Link.Flink",
  861. NULL,
  862. DumpNotifyCallback);
  863. }
  864. }
  865. }
  866. }
  867. }
  868. VOID
  869. PoDevState (
  870. VOID
  871. )
  872. /*++
  873. Routine Description:
  874. Dumps the current power action structure
  875. Arguments:
  876. args - the location of the device object of interest
  877. Return Value:
  878. None
  879. --*/
  880. {
  881. ULONG64 addr;
  882. LONG i;
  883. ULONG64 ListHead;
  884. ULONG64 Link;
  885. ULONG64 DevState, Notify;
  886. BOOLEAN GdiOff;
  887. UCHAR IrpMinor;
  888. ULONG PartOffset, NoLists, SizeOfLE, Off, HeadOff;
  889. addr = GetExpression( "nt!PopAction" );
  890. if (!addr) {
  891. dprintf("Error retrieving address of PopAction\n");
  892. return;
  893. }
  894. if (GetFieldValue(addr, "nt!POP_POWER_ACTION", "DevState", DevState)) {
  895. dprintf("Error reading PopAction\n");
  896. return;
  897. }
  898. if (!DevState) {
  899. dprintf("No Device State allocated on PopAction\n");
  900. return;
  901. }
  902. if (GetFieldValue(DevState, "nt!_POP_DEVICE_SYS_STATE", "IrpMinor", IrpMinor)) {
  903. dprintf("Error reading device state structure\n");
  904. return;
  905. }
  906. GetFieldOffset("nt!_POP_DEVICE_SYS_STATE","PresentIrpQueue", &Off);
  907. InitTypeRead(DevState, nt!_POP_DEVICE_SYS_STATE);
  908. dprintf ("PopAction.DevState %08x\n", DevState);
  909. dprintf(" Irp minor......: %s\n", PoIrpMinor (IrpMinor));
  910. dprintf(" System State...: %s\n", SystemState((ULONG) ReadField(SystemState)));
  911. dprintf(" Worker thread..: %08p\n", ReadField(Thread));
  912. dprintf(" Status.........: %x\n", (ULONG) ReadField(Status));
  913. dprintf(" Waking.........: %s\n", TF (((UCHAR) ReadField(Waking))) );
  914. dprintf(" Cancelled......: %s\n", TF (((UCHAR) ReadField(Cancelled))) );
  915. dprintf(" Ignore errors..: %s\n", TF (((UCHAR) ReadField(IgnoreErrors))) );
  916. dprintf(" Ignore not imp.: %s\n", TF (((UCHAR) ReadField(IgnoreNotImplemented))) );
  917. dprintf(" Wait any.......: %s\n", TF (((UCHAR) ReadField(WaitAny))) );
  918. dprintf(" Wait all.......: %s\n", TF (((UCHAR) ReadField(WaitAll))) );
  919. dprintf(" Present Irp Q..: %s\n",
  920. DumpQueueHead (DevState, DevState, Off)
  921. );
  922. dprintf("\n");
  923. dprintf("Order:\n");
  924. dprintf(" DevNode Seq....: %x\n", (ULONG) ReadField(Order.DevNodeSequence));
  925. if (ReadField(Order.NoLists)) {
  926. poDumpOldNotifyList();
  927. } else {
  928. poDumpNewNotifyList(DevState);
  929. }
  930. //
  931. // Dump device notification list order
  932. //
  933. //
  934. // Dump device power irps
  935. //
  936. GetFieldOffset("nt!_POP_DEVICE_SYS_STATE","Head", &HeadOff);
  937. GetFieldOffset("nt!_POP_DEVICE_POWER_IRP", "Pending", &Off);
  938. DumpDevicePowerIrp ("Pending irps", DevState, DevState+HeadOff, Off);
  939. GetFieldOffset("nt!_POP_DEVICE_POWER_IRP", "Complete", &Off);
  940. DumpDevicePowerIrp ("Completed irps", DevState, DevState+HeadOff, Off);
  941. GetFieldOffset("nt!_POP_DEVICE_POWER_IRP", "Abort", &Off);
  942. DumpDevicePowerIrp ("Abort irps", DevState, DevState+HeadOff, Off);
  943. GetFieldOffset("nt!_POP_DEVICE_POWER_IRP", "Failed", &Off);
  944. DumpDevicePowerIrp ("Failed irps", DevState, DevState+HeadOff, Off);
  945. dprintf("\n");
  946. }
  947. DECLARE_API( poaction )
  948. /*++
  949. Routine Description:
  950. Dumps the current power action structure
  951. Arguments:
  952. args - the location of the device object of interest
  953. Return Value:
  954. None
  955. --*/
  956. {
  957. ULONG64 addr;
  958. ULONG i;
  959. UCHAR c, State, Updates;
  960. ULONG Flags;
  961. addr = GetExpression( "nt!PopAction" );
  962. if (!addr) {
  963. dprintf("Error retrieving address of PopAction\n");
  964. return E_INVALIDARG;
  965. }
  966. if (GetFieldValue(addr, "nt!POP_POWER_ACTION", "State", State)) {
  967. dprintf("Error reading PopAction\n");
  968. return E_INVALIDARG;
  969. }
  970. InitTypeRead(addr, nt!POP_POWER_ACTION);
  971. dprintf("PopAction: %08x\n", addr);
  972. dprintf(" State..........: %x ", State);
  973. switch (State) {
  974. case PO_ACT_IDLE: dprintf ("- Idle\n"); break;
  975. case PO_ACT_NEW_REQUEST: dprintf ("- New request\n"); break;
  976. case PO_ACT_CALLOUT: dprintf ("- Winlogon callout\n"); break;
  977. case PO_ACT_SET_SYSTEM_STATE: dprintf ("- Set System State\n"); break;
  978. default: dprintf ("\n"); break;
  979. }
  980. dprintf(" Updates........: %x ", (Updates = (UCHAR) ReadField(Updates)));
  981. if (Updates & PO_PM_USER) dprintf(" user ");
  982. if (Updates & PO_PM_REISSUE) dprintf(" reissue ");
  983. if (Updates & PO_PM_SETSTATE) dprintf(" setstate ");
  984. if (ReadField(Shutdown)) dprintf(" SHUTDOWN-set ");
  985. dprintf("\n");
  986. dprintf(" Action.........: %s\n", PowerAction((ULONG) ReadField(Action)));
  987. dprintf(" Lightest State.: %s\n", SystemState((ULONG) ReadField(LightestState)));
  988. dprintf(" Flags..........: %x", (Flags = (ULONG) ReadField(Flags)));
  989. c = ' ';
  990. for (i=0; ActFlags[i].Flags; i++) {
  991. if (Flags & ActFlags[i].Flags) {
  992. dprintf ("%c%s", c, ActFlags[i].String);
  993. c = '|';
  994. }
  995. }
  996. dprintf("\n");
  997. dprintf(" Irp minor......: %s\n", PoIrpMinor ((UCHAR)ReadField(IrpMinor)));
  998. dprintf(" System State...: %s\n", SystemState((ULONG) ReadField(SystemState)));
  999. dprintf(" Hiber Context..: %08p\n", ReadField(HiberContext));
  1000. if (ReadField(DevState)) {
  1001. dprintf ("\n");
  1002. PoDevState ();
  1003. }
  1004. dprintf("\n");
  1005. return S_OK;
  1006. }