Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

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