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.

6184 lines
184 KiB

  1. /*++
  2. Copyright (c) 1997-2000 Microsoft Corporation
  3. Module Name:
  4. devnode.c
  5. Abstract:
  6. WinDbg Extension Api
  7. Revision History:
  8. --*/
  9. #include "precomp.h"
  10. //#include "pci.h"
  11. #pragma hdrstop
  12. #include "stddef.h"
  13. #include <initguid.h>
  14. #include "devnode.h"
  15. #define FLAG_NAME(flag) {flag, # flag}
  16. FLAG_NAME DeviceNodeFlags[] = {
  17. FLAG_NAME(DNF_MADEUP), // 00000001
  18. FLAG_NAME(DNF_DUPLICATE), // 00000002
  19. FLAG_NAME(DNF_HAL_NODE), // 00000004
  20. FLAG_NAME(DNF_REENUMERATE), // 00000008
  21. FLAG_NAME(DNF_ENUMERATED), // 00000010
  22. FLAG_NAME(DNF_IDS_QUERIED), // 00000020
  23. FLAG_NAME(DNF_HAS_BOOT_CONFIG), // 00000040
  24. FLAG_NAME(DNF_BOOT_CONFIG_RESERVED), // 00000080
  25. FLAG_NAME(DNF_NO_RESOURCE_REQUIRED), // 00000100
  26. FLAG_NAME(DNF_RESOURCE_REQUIREMENTS_NEED_FILTERED), // 00000200
  27. FLAG_NAME(DNF_RESOURCE_REQUIREMENTS_CHANGED), // 00000400
  28. FLAG_NAME(DNF_NON_STOPPED_REBALANCE), // 00000800
  29. FLAG_NAME(DNF_LEGACY_DRIVER), // 00001000
  30. FLAG_NAME(DNF_HAS_PROBLEM), // 00002000
  31. FLAG_NAME(DNF_HAS_PRIVATE_PROBLEM), // 00004000
  32. FLAG_NAME(DNF_HARDWARE_VERIFICATION), // 00008000
  33. FLAG_NAME(DNF_DEVICE_GONE), // 00010000
  34. FLAG_NAME(DNF_LEGACY_RESOURCE_DEVICENODE), // 00020000
  35. FLAG_NAME(DNF_NEEDS_REBALANCE), // 00040000
  36. FLAG_NAME(DNF_LOCKED_FOR_EJECT), // 00080000
  37. FLAG_NAME(DNF_DRIVER_BLOCKED), // 00100000
  38. {0,0}
  39. };
  40. FLAG_NAME DeviceNodeUserFlags[] = {
  41. FLAG_NAME(DNUF_WILL_BE_REMOVED), // 00000001
  42. FLAG_NAME(DNUF_DONT_SHOW_IN_UI), // 00000002
  43. FLAG_NAME(DNUF_NEED_RESTART), // 00000004
  44. FLAG_NAME(DNUF_NOT_DISABLEABLE), // 00000008
  45. FLAG_NAME(DNUF_SHUTDOWN_QUERIED), // 00000010
  46. FLAG_NAME(DNUF_SHUTDOWN_SUBTREE_DONE), // 00000020
  47. {0,0}
  48. };
  49. #define DeviceD1 0x00000001
  50. #define DeviceD2 0x00000002
  51. #define LockSupported 0x00000004
  52. #define EjectSupported 0x00000008
  53. #define Removable 0x00000010
  54. #define DockDevice 0x00000020
  55. #define UniqueID 0x00000040
  56. #define SilentInstall 0x00000080
  57. #define RawDeviceOK 0x00000100
  58. #define SurpriseRemovalOK 0x00000200
  59. #define WakeFromD0 0x00000400
  60. #define WakeFromD1 0x00000800
  61. #define WakeFromD2 0x00001000
  62. #define WakeFromD3 0x00002000
  63. #define HardwareDisabled 0x00004000
  64. #define NonDynamic 0x00008000
  65. #define WarmEjectSupported 0x00010000
  66. #define NoDisplayInUI 0x00020000
  67. FLAG_NAME DeviceNodeCapabilityFlags[] = {
  68. FLAG_NAME(DeviceD1), // 00000001
  69. FLAG_NAME(DeviceD2), // 00000002
  70. FLAG_NAME(LockSupported), // 00000004
  71. FLAG_NAME(EjectSupported), // 00000008
  72. FLAG_NAME(Removable), // 00000010
  73. FLAG_NAME(DockDevice), // 00000020
  74. FLAG_NAME(UniqueID), // 00000040
  75. FLAG_NAME(SilentInstall), // 00000080
  76. FLAG_NAME(RawDeviceOK), // 00000100
  77. FLAG_NAME(SurpriseRemovalOK), // 00000200
  78. FLAG_NAME(WakeFromD0), // 00000400
  79. FLAG_NAME(WakeFromD1), // 00000800
  80. FLAG_NAME(WakeFromD2), // 00001000
  81. FLAG_NAME(WakeFromD3), // 00002000
  82. FLAG_NAME(HardwareDisabled), // 00004000
  83. FLAG_NAME(NonDynamic), // 00008000
  84. FLAG_NAME(WarmEjectSupported), // 00010000
  85. FLAG_NAME(NoDisplayInUI), // 00020000
  86. {0,0}
  87. };
  88. #define PROBLEM_MAP_SIZE 0x33
  89. #if PROBLEM_MAP_SIZE != NUM_CM_PROB
  90. #error Add new problem code to DevNodeProblems and update PROBLEM_MAP_SIZE.
  91. #endif
  92. PUCHAR DevNodeProblems[] = {
  93. NULL,
  94. "CM_PROB_NOT_CONFIGURED",
  95. "CM_PROB_DEVLOADER_FAILED",
  96. "CM_PROB_OUT_OF_MEMORY",
  97. "CM_PROB_ENTRY_IS_WRONG_TYPE",
  98. "CM_PROB_LACKED_ARBITRATOR",
  99. "CM_PROB_BOOT_CONFIG_CONFLICT",
  100. "CM_PROB_FAILED_FILTER",
  101. "CM_PROB_DEVLOADER_NOT_FOUND",
  102. "CM_PROB_INVALID_DATA",
  103. "CM_PROB_FAILED_START",
  104. "CM_PROB_LIAR",
  105. "CM_PROB_NORMAL_CONFLICT",
  106. "CM_PROB_NOT_VERIFIED",
  107. "CM_PROB_NEED_RESTART",
  108. "CM_PROB_REENUMERATION",
  109. "CM_PROB_PARTIAL_LOG_CONF",
  110. "CM_PROB_UNKNOWN_RESOURCE",
  111. "CM_PROB_REINSTALL",
  112. "CM_PROB_REGISTRY",
  113. "CM_PROB_VXDLDR",
  114. "CM_PROB_WILL_BE_REMOVED",
  115. "CM_PROB_DISABLED",
  116. "CM_PROB_DEVLOADER_NOT_READY",
  117. "CM_PROB_DEVICE_NOT_THERE",
  118. "CM_PROB_MOVED",
  119. "CM_PROB_TOO_EARLY",
  120. "CM_PROB_NO_VALID_LOG_CONF",
  121. "CM_PROB_FAILED_INSTALL",
  122. "CM_PROB_HARDWARE_DISABLED",
  123. "CM_PROB_CANT_SHARE_IRQ",
  124. "CM_PROB_FAILED_ADD",
  125. "CM_PROB_DISABLED_SERVICE",
  126. "CM_PROB_TRANSLATION_FAILED",
  127. "CM_PROB_NO_SOFTCONFIG",
  128. "CM_PROB_BIOS_TABLE",
  129. "CM_PROB_IRQ_TRANSLATION_FAILED",
  130. "CM_PROB_FAILED_DRIVER_ENTRY",
  131. "CM_PROB_DRIVER_FAILED_PRIOR_UNLOAD",
  132. "CM_PROB_DRIVER_FAILED_LOAD",
  133. "CM_PROB_DRIVER_SERVICE_KEY_INVALID",
  134. "CM_PROB_LEGACY_SERVICE_NO_DEVICES",
  135. "CM_PROB_DUPLICATE_DEVICE",
  136. "CM_PROB_FAILED_POST_START",
  137. "CM_PROB_HALTED",
  138. "CM_PROB_PHANTOM",
  139. "CM_PROB_SYSTEM_SHUTDOWN",
  140. "CM_PROB_HELD_FOR_EJECT",
  141. "CM_PROB_DRIVER_BLOCKED",
  142. "CM_PROB_REGISTRY_TOO_LARGE",
  143. "CM_PROB_SETPROPERTIES_FAILED"
  144. };
  145. extern
  146. VOID
  147. DevExtIsapnp(
  148. ULONG64 Extension
  149. );
  150. extern
  151. VOID
  152. DevExtPcmcia(
  153. ULONG64 Extension
  154. );
  155. extern
  156. VOID
  157. DevExtHID(
  158. ULONG64 Extension
  159. );
  160. VOID
  161. DumpResourceDescriptorHeader(
  162. ULONG Depth,
  163. ULONG Number,
  164. UCHAR Option,
  165. UCHAR Type,
  166. UCHAR SharingDisposition,
  167. USHORT Flags
  168. );
  169. BOOLEAN
  170. DumpDevNode(
  171. ULONG64 DeviceNode,
  172. ULONG Depth,
  173. BOOLEAN DumpSibling,
  174. BOOLEAN DumpChild,
  175. BOOLEAN DumpCmRes,
  176. BOOLEAN DumpCmResReqList,
  177. BOOLEAN DumpCmResTrans,
  178. BOOLEAN DumpOnlyDevnodesWithProblems,
  179. BOOLEAN DumpOnlyNonStartedDevnodes,
  180. PUNICODE_STRING ServiceName,
  181. BOOLEAN PrintDefault,
  182. BOOLEAN DumpStateHistory
  183. );
  184. BOOLEAN
  185. DumpPendingEjects(
  186. BOOLEAN DumpCmRes,
  187. BOOLEAN DumpCmResReqList,
  188. BOOLEAN DumpCmResTrans
  189. );
  190. BOOLEAN
  191. DumpPendingRemovals(
  192. BOOLEAN DumpCmRes,
  193. BOOLEAN DumpCmResReqList,
  194. BOOLEAN DumpCmResTrans
  195. );
  196. BOOLEAN
  197. DumpDeviceEventEntry(
  198. ULONG64 DeviceEvent,
  199. ULONG64 ListHead,
  200. BOOL FollowLinks
  201. );
  202. VOID
  203. DumpPlugPlayEventBlock(
  204. ULONG64 PlugPlayEventBlock,
  205. ULONG Size
  206. );
  207. BOOLEAN
  208. DumpResourceList64(
  209. LPSTR Description,
  210. ULONG Depth,
  211. ULONG64 ResourceList
  212. );
  213. BOOLEAN
  214. DumpResourceRequirementList64(
  215. ULONG Depth,
  216. ULONG64 ResourceRequirementList
  217. );
  218. BOOLEAN
  219. DumpE820ResourceList64(
  220. ULONG Depth,
  221. ULONG64 ResourceList
  222. );
  223. BOOLEAN
  224. DumpArbiter(
  225. IN DWORD Depth,
  226. IN ULONG64 ArbiterAddr,
  227. IN BOOLEAN DisplayAliases
  228. );
  229. #define ARBITER_DUMP_IO 0x1
  230. #define ARBITER_DUMP_MEMORY 0x2
  231. #define ARBITER_DUMP_IRQ 0x4
  232. #define ARBITER_DUMP_DMA 0x8
  233. #define ARBITER_DUMP_BUS_NUMBER 0x10
  234. #define ARBITER_NO_DUMP_ALIASES 0x100
  235. #define ARBITER_DUMP_ALL (ARBITER_DUMP_IO | \
  236. ARBITER_DUMP_MEMORY | \
  237. ARBITER_DUMP_IRQ | \
  238. ARBITER_DUMP_DMA | \
  239. ARBITER_DUMP_BUS_NUMBER)
  240. BOOLEAN
  241. DumpArbitersForDevNode(
  242. IN DWORD Depth,
  243. IN ULONG64 DevNodeAddr,
  244. IN DWORD Flags
  245. );
  246. VOID
  247. PrintDevNodeState(
  248. IN ULONG Depth,
  249. IN PUCHAR Field,
  250. IN ULONG State
  251. );
  252. DECLARE_API( ioreslist )
  253. /*++
  254. Routine Description:
  255. Dump a device object.
  256. Arguments:
  257. args - the location of the device object to dump.
  258. Return Value:
  259. None
  260. --*/
  261. {
  262. ULONG64 requirementList;
  263. requirementList = GetExpression(args);
  264. DumpResourceRequirementList64(0, requirementList);
  265. return S_OK;
  266. }
  267. DECLARE_API( cmreslist )
  268. /*++
  269. Routine Description:
  270. Dump a device object.
  271. Arguments:
  272. args - the location of the device object to dump.
  273. Return Value:
  274. None
  275. --*/
  276. {
  277. ULONG64 resourceList;
  278. resourceList = GetExpression(args);
  279. DumpResourceList64("CmResourceList", 0, resourceList);
  280. return S_OK;
  281. }
  282. DECLARE_API( e820reslist )
  283. /*++
  284. Routine Description:
  285. Dump an e820 resource table
  286. Arguments:
  287. args - the location of the resources list to dump
  288. Return Value:
  289. None
  290. --*/
  291. {
  292. ULONG64 resourceList;
  293. resourceList = GetExpression(args);
  294. DumpE820ResourceList64(0, resourceList );
  295. return S_OK;
  296. }
  297. #define DUMP_CHILD 1
  298. #define DUMP_CM_RES 2
  299. #define DUMP_CM_RES_REQ_LIST 4
  300. #define DUMP_CM_RES_TRANS 8
  301. #define DUMP_NOT_STARTED 0x10
  302. #define DUMP_PROBLEMS 0x20
  303. BOOLEAN
  304. xReadMemory(
  305. ULONG64 S,
  306. PVOID D,
  307. ULONG Len
  308. )
  309. {
  310. ULONG result;
  311. return (ReadMemory((S), D, Len, &result) && (result == Len));
  312. }
  313. DECLARE_API( devnode )
  314. /*++
  315. Routine Description:
  316. Dump a device object.
  317. Arguments:
  318. args - the location of the device object to dump.
  319. Return Value:
  320. None
  321. --*/
  322. {
  323. ULONG64 deviceNode=0;
  324. ULONG verbose = 0;
  325. PUCHAR buffer = NULL;
  326. UNICODE_STRING serviceName;
  327. ANSI_STRING ansiString;
  328. BOOLEAN serviceNameAllocated = FALSE;
  329. NTSTATUS status;
  330. ULONG64 tmp;
  331. buffer = LocalAlloc(LPTR, 256);
  332. if (buffer) {
  333. RtlZeroMemory(buffer, 256);
  334. if (GetExpressionEx(args, &deviceNode, &args)) {
  335. if (sscanf(args, "%lx %255s", &verbose, buffer)) {
  336. if (buffer [0] != '\0') {
  337. RtlInitAnsiString(&ansiString, (PCSZ)buffer);
  338. status = RtlAnsiStringToUnicodeString(&serviceName,
  339. &ansiString,
  340. TRUE);
  341. if (NT_SUCCESS(status)) {
  342. serviceNameAllocated = TRUE;
  343. }
  344. }
  345. }
  346. }
  347. LocalFree(buffer);
  348. } else if (GetExpressionEx(args, &deviceNode, &args)) {
  349. if (sscanf(args,"%lx", &tmp)) {
  350. verbose = (ULONG) tmp;
  351. }
  352. }
  353. if (deviceNode == 0) {
  354. ULONG64 addr = GetExpression( "nt!IopRootDeviceNode" );
  355. ULONG64 dummy;
  356. if (addr == 0) {
  357. dprintf("Error retrieving address of IopRootDeviceNode\n");
  358. return E_INVALIDARG;
  359. }
  360. if (!ReadPointer(addr, &deviceNode)) {
  361. dprintf("Error reading value of IopRootDeviceNode (%#010p)\n", addr);
  362. return E_INVALIDARG;
  363. }
  364. dprintf("Dumping IopRootDeviceNode (= %#08p)\n", deviceNode);
  365. } else if (deviceNode == 1) {
  366. DumpPendingRemovals((BOOLEAN) ((verbose & DUMP_CM_RES) != 0),
  367. (BOOLEAN) ((verbose & DUMP_CM_RES_REQ_LIST) != 0),
  368. (BOOLEAN) ((verbose & DUMP_CM_RES_TRANS) != 0)
  369. );
  370. return E_INVALIDARG;
  371. } else if (deviceNode == 2) {
  372. DumpPendingEjects((BOOLEAN) ((verbose & DUMP_CM_RES) != 0),
  373. (BOOLEAN) ((verbose & DUMP_CM_RES_REQ_LIST) != 0),
  374. (BOOLEAN) ((verbose & DUMP_CM_RES_TRANS) != 0)
  375. );
  376. return E_INVALIDARG;
  377. }
  378. if (serviceNameAllocated) {
  379. DumpDevNode( deviceNode,
  380. 0,
  381. FALSE,
  382. (BOOLEAN) ((verbose & DUMP_CHILD) != 0),
  383. (BOOLEAN) ((verbose & DUMP_CM_RES) != 0),
  384. (BOOLEAN) ((verbose & DUMP_CM_RES_REQ_LIST) != 0),
  385. (BOOLEAN) ((verbose & DUMP_CM_RES_TRANS) != 0),
  386. (BOOLEAN) ((verbose & DUMP_PROBLEMS) != 0),
  387. (BOOLEAN) ((verbose & DUMP_NOT_STARTED) != 0),
  388. &serviceName,
  389. FALSE,
  390. TRUE
  391. );
  392. RtlFreeUnicodeString(&serviceName);
  393. } else {
  394. DumpDevNode( deviceNode,
  395. 0,
  396. FALSE,
  397. (BOOLEAN) ((verbose & DUMP_CHILD) != 0),
  398. (BOOLEAN) ((verbose & DUMP_CM_RES) != 0),
  399. (BOOLEAN) ((verbose & DUMP_CM_RES_REQ_LIST) != 0),
  400. (BOOLEAN) ((verbose & DUMP_CM_RES_TRANS) != 0),
  401. (BOOLEAN) ((verbose & DUMP_PROBLEMS) != 0),
  402. (BOOLEAN) ((verbose & DUMP_NOT_STARTED) != 0),
  403. NULL,
  404. FALSE,
  405. TRUE
  406. );
  407. }
  408. return S_OK;
  409. }
  410. static CCHAR DebugBuffer[300];
  411. VOID
  412. xdprintf(
  413. ULONG Depth,
  414. PCCHAR S,
  415. ...
  416. )
  417. {
  418. va_list ap;
  419. ULONG i;
  420. for (i=0; i<Depth; i++) {
  421. dprintf (" ");
  422. }
  423. va_start(ap, S);
  424. vsprintf(DebugBuffer, S, ap);
  425. dprintf(DebugBuffer);
  426. va_end(ap);
  427. }
  428. VOID
  429. DumpFlags(
  430. ULONG Depth,
  431. LPSTR FlagDescription,
  432. ULONG Flags,
  433. PFLAG_NAME FlagTable
  434. )
  435. {
  436. ULONG i;
  437. ULONG mask = 0;
  438. ULONG count = 0;
  439. UCHAR prolog[64];
  440. if (StringCbPrintf(prolog, sizeof(prolog), "%s (%#010x) ", FlagDescription, Flags) != S_OK)
  441. {
  442. return;
  443. }
  444. xdprintf(Depth, "%s", prolog);
  445. if (Flags == 0) {
  446. dprintf("\n");
  447. return;
  448. }
  449. memset(prolog, ' ', strlen(prolog));
  450. for (i = 0; FlagTable[i].Name != 0; i++) {
  451. PFLAG_NAME flag = &(FlagTable[i]);
  452. mask |= flag->Flag;
  453. if ((Flags & flag->Flag) == flag->Flag) {
  454. //
  455. // print trailing comma
  456. //
  457. if (count != 0) {
  458. dprintf(", ");
  459. //
  460. // Only print two flags per line.
  461. //
  462. if ((count % 2) == 0) {
  463. dprintf("\n");
  464. xdprintf(Depth, "%s", prolog);
  465. }
  466. }
  467. dprintf("%s", flag->Name);
  468. count++;
  469. }
  470. }
  471. dprintf("\n");
  472. if ((Flags & (~mask)) != 0) {
  473. xdprintf(Depth, "%sUnknown flags %#010lx\n", prolog, (Flags & (~mask)));
  474. }
  475. return;
  476. }
  477. BOOLEAN
  478. DumpE820ResourceList64(
  479. ULONG Depth,
  480. ULONG64 ResourceList
  481. )
  482. {
  483. BOOLEAN continueDump = TRUE;
  484. CHAR Buff[80];
  485. ULONG i;
  486. ULONG ListOffset;
  487. ULONG64 Count;
  488. ULONG64 Type;
  489. ULONG64 V1;
  490. ULONG64 V2;
  491. #define Res2(F, V) GetFieldValue(ResourceList, "nt!_ACPI_BIOS_MULTI_NODE", #F, V)
  492. #define Res(F) GetFieldValue(ResourceList, "nt!_ACPI_BIOS_MULTI_NODE", #F, F)
  493. #define Entry(F,V) (sprintf(Buff,"E820Entry[%lx].%s",i,#F),\
  494. GetFieldValue(ResourceList,"nt!_ACPI_BIOS_MULTI_NODE", Buff, V))
  495. if (ResourceList == 0) {
  496. goto GetOut;
  497. }
  498. if (Res(Count)) {
  499. goto GetOut;
  500. }
  501. if (Count == 0) {
  502. goto GetOut;
  503. }
  504. xdprintf(Depth, "ACPI_BIOS_MULTI_NODE (an E820 Resource List) at %#010p\n", ResourceList);
  505. Depth++;
  506. for (i = 0; i < Count; i++) {
  507. if (CheckControlC()) {
  508. continueDump = FALSE;
  509. break;
  510. }
  511. Entry(Type,Type);
  512. switch(Type) {
  513. case 1: // AcpiAddressRangeMemory
  514. xdprintf(Depth,"Memory - ");
  515. break;
  516. case 2: // AcpiAddressRangeReserved
  517. xdprintf(Depth,"Reserved - ");
  518. break;
  519. case 3: // AcpiAddressRangeACPI
  520. xdprintf(Depth,"ACPI - ");
  521. break;
  522. case 4: // AcpiAddressRangeNVS
  523. xdprintf(Depth,"NVS - ");
  524. break;
  525. case 5: // AcpiAddressRangeMaximum
  526. default:
  527. xdprintf(Depth,"Unknown - ");
  528. break;
  529. }
  530. Entry(Base.QuadPart, V1);
  531. Entry(Length.QuadPart, V2);
  532. dprintf( "%16I64x - %#16I64x (Length %#10I64x)", V1, (V1 + V2 - 1), V2 );
  533. if (Type == 2) {
  534. dprintf(" [Ignored]");
  535. }
  536. if (Type == 3 || Type == 4) {
  537. if (V2 > 0xFFFFFFFF) {
  538. dprintf(" [Illegal Range]");
  539. }
  540. }
  541. dprintf("\n");
  542. }
  543. GetOut:
  544. #undef Res
  545. #undef Res2
  546. #undef Entry
  547. return continueDump;
  548. }
  549. BOOLEAN
  550. DumpResourceRequirementList64(
  551. ULONG Depth,
  552. ULONG64 ResourceRequirementList
  553. )
  554. {
  555. ULONG64 requirementList = 0;
  556. ULONG64 resourceList;
  557. ULONG64 descriptors;
  558. ULONG ListSize;
  559. ULONG i;
  560. ULONG j;
  561. ULONG k;
  562. ULONG result;
  563. BOOLEAN continueDump = TRUE;
  564. ULONG InterfaceType, BusNumber, SlotNumber, Reserved1, Reserved2, Reserved3;
  565. ULONG AlternativeLists;
  566. ULONG ListOffset, SizeOfIoResList, SizeofIoDesc;
  567. #define Res2(F, V) GetFieldValue(ResourceRequirementList, "nt!_IO_RESOURCE_REQUIREMENTS_LIST", #F, V)
  568. #define Res(F) GetFieldValue(ResourceRequirementList, "nt!_IO_RESOURCE_REQUIREMENTS_LIST", #F, F)
  569. if (ResourceRequirementList == 0) {
  570. goto GetOut;
  571. }
  572. if (Res(ListSize)) {
  573. goto GetOut;
  574. }
  575. if (ListSize == 0) {
  576. goto GetOut;
  577. }
  578. Res(InterfaceType); Res(BusNumber); Res(SlotNumber);
  579. xdprintf(Depth, "IoResList at ");
  580. dprintf("%#010p : Interface %#x Bus %#x Slot %#x\n",
  581. ResourceRequirementList,
  582. InterfaceType,
  583. BusNumber,
  584. SlotNumber);
  585. Res2(Reserved[0], Reserved1); Res2(Reserved[1], Reserved2);
  586. Res2(Reserved[2], Reserved3);
  587. if ((Reserved1 |
  588. Reserved2 |
  589. Reserved3) != 0) {
  590. xdprintf(Depth, "Reserved Values = {%#010lx, %#010lx, %#010lx}\n",
  591. Reserved1,
  592. Reserved2,
  593. Reserved3);
  594. }
  595. Depth++;
  596. Res(AlternativeLists);
  597. GetFieldOffset("nt!_IO_RESOURCE_REQUIREMENTS_LIST", "List", &ListOffset);
  598. resourceList = ResourceRequirementList + ListOffset;
  599. SizeOfIoResList = GetTypeSize("IO_RESOURCE_LIST");
  600. SizeofIoDesc = GetTypeSize("IO_RESOURCE_DESCRIPTOR");
  601. for (i = 0; i < AlternativeLists; i++) {
  602. ULONG Version, Revision, Count;
  603. if (CheckControlC()) {
  604. continueDump = FALSE;
  605. break;
  606. }
  607. GetFieldValue(resourceList, "nt!_IO_RESOURCE_LIST", "Version", Version);
  608. GetFieldValue(resourceList, "nt!_IO_RESOURCE_LIST", "Revision", Revision);
  609. GetFieldValue(resourceList, "nt!_IO_RESOURCE_LIST", "Count", Count);
  610. xdprintf(Depth, "Alternative %d (Version %d.%d)\n",
  611. i,
  612. Version,
  613. Revision);
  614. Depth++;
  615. for (j = 0; j < Count; j++) {
  616. CHAR Buff[80];
  617. ULONG64 Q1, Q2;
  618. ULONG Option, Type, ShareDisposition, Flags, V1, V2, V3, Data[3];
  619. #define Desc(F,V) (sprintf(Buff,"Descriptors[%lx].%s",j, #F), \
  620. GetFieldValue(resourceList, "nt!_IO_RESOURCE_LIST", Buff, V))
  621. if (CheckControlC()) {
  622. continueDump = FALSE;
  623. goto GetOut;
  624. }
  625. // descriptors = resourceList->Descriptors + j;
  626. Desc(Option,Option); Desc(Type,Type);
  627. Desc(ShareDisposition,ShareDisposition);
  628. Desc(Flags,Flags);
  629. DumpResourceDescriptorHeader(Depth,
  630. j,
  631. (UCHAR)Option,
  632. (UCHAR) Type,
  633. (UCHAR) ShareDisposition,
  634. (USHORT) Flags);
  635. Depth++;
  636. switch (Type) {
  637. case CmResourceTypeBusNumber:
  638. Desc(u.BusNumber.MinBusNumber, V1);
  639. Desc(u.BusNumber.MaxBusNumber, V2);
  640. Desc(u.BusNumber.Length, V3);
  641. xdprintf(Depth, "0x%x - 0x%x for length 0x%x\n",
  642. V1, V2, V3);
  643. break;
  644. case CmResourceTypePort:
  645. case CmResourceTypeMemory:
  646. Desc(u.Generic.Length, V1);
  647. Desc(u.Generic.Alignment, V2);
  648. Desc(u.Port.MinimumAddress.QuadPart, Q1);
  649. Desc(u.Port.MaximumAddress.QuadPart, Q2);
  650. xdprintf(Depth, "%#08lx byte range with alignment %#08lx\n", V1, V2);
  651. xdprintf(Depth, "%I64x - %#I64x\n", Q1, Q2);
  652. break;
  653. case CmResourceTypeInterrupt:
  654. Desc(u.Interrupt.MinimumVector,V1);
  655. Desc(u.Interrupt.MaximumVector,V2);
  656. xdprintf(Depth, "0x%x - 0x%x\n", V1,V2);
  657. break;
  658. default:
  659. Desc(u.DevicePrivate.Data, Data);
  660. xdprintf(Depth,
  661. "Data: : 0x%x 0x%x 0x%x\n",
  662. Data[0],
  663. Data[1],
  664. Data[2]);
  665. break;
  666. }
  667. Depth--;
  668. #undef Desc
  669. }
  670. Depth--;
  671. resourceList += (SizeOfIoResList + SizeofIoDesc*(j-1));
  672. }
  673. GetOut:
  674. xdprintf(Depth, "\n");
  675. #undef Res
  676. #undef Res2
  677. return continueDump;
  678. }
  679. BOOLEAN
  680. DumpResourceList64(
  681. LPSTR Description,
  682. ULONG Depth,
  683. ULONG64 ResourceList
  684. )
  685. {
  686. ULONG64 resourceListWalker;
  687. ULONG i;
  688. ULONG j;
  689. ULONG k;
  690. BOOLEAN continueDump = TRUE;
  691. ULONG Count, ListSize, ListOffset;
  692. ULONG64 ListAddr;
  693. if (ResourceList == 0) {
  694. goto GetOut;
  695. }
  696. resourceListWalker = ResourceList;
  697. if (GetFieldOffset("nt!_CM_RESOURCE_LIST", "List", &ListOffset)) {
  698. goto GetOut;
  699. }
  700. ListAddr = ResourceList + ListOffset;
  701. GetFieldValue(ResourceList, "nt!_CM_RESOURCE_LIST", "Count", Count);
  702. resourceListWalker = ListAddr;
  703. for (i = 0; i < Count; i++) {
  704. ULONG Partial_Count=0, PartialListAddr, BusNumber=0, Partial_Version=0, Partial_Revision=0;
  705. CHAR ResListType[] = "nt!_CM_FULL_RESOURCE_DESCRIPTOR";
  706. ULONG64 InterfaceType=0;
  707. ULONG PartDescOffset;
  708. if (CheckControlC()) {
  709. continueDump = FALSE;
  710. break;
  711. }
  712. GetFieldValue(resourceListWalker, ResListType, "InterfaceType", InterfaceType);
  713. GetFieldValue(resourceListWalker, ResListType, "BusNumber", BusNumber);
  714. GetFieldValue(resourceListWalker, ResListType, "PartialResourceList.Version", Partial_Version);
  715. GetFieldValue(resourceListWalker, ResListType, "PartialResourceList.Revision", Partial_Revision);
  716. GetFieldValue(resourceListWalker, ResListType, "PartialResourceList.Count", Partial_Count);
  717. GetFieldOffset(ResListType, "PartialResourceList.PartialDescriptors", &PartDescOffset);
  718. resourceListWalker = resourceListWalker + PartDescOffset;
  719. xdprintf(Depth, "%s at ", Description);
  720. dprintf("%#010p Version %d.%d Interface %#x Bus #%#x\n",
  721. ResourceList,
  722. Partial_Version,
  723. Partial_Revision,
  724. (ULONG) InterfaceType,
  725. BusNumber);
  726. Depth++;
  727. for (j = 0; j < Partial_Count; j++) {
  728. CHAR PartResType[] = "nt!_CM_PARTIAL_RESOURCE_DESCRIPTOR";
  729. ULONG Type=0, ShareDisposition=0, Flags=0, sz, u_Port_Length=0, u_Memory_Length=0,
  730. u_Interrupt_Level=0, u_Interrupt_Vector=0,
  731. u_Dma_Channel=0, u_Dma_Port=0, u_Dma_Reserved1=0, u_BusNumber_Start=0,
  732. u_BusNumber_Length=0, u_DevicePrivate_Data[3];
  733. ULONG64 u_Port_QuadPart=0, u_Memory_QuadPart=0, u_Interrupt_Affinity=0;
  734. if (CheckControlC()) {
  735. continueDump = FALSE;
  736. goto GetOut;
  737. }
  738. sz = GetTypeSize(PartResType);
  739. if (GetFieldValue(resourceListWalker,
  740. PartResType,
  741. "Type",
  742. Type)) {
  743. goto GetOut;
  744. }
  745. GetFieldValue(resourceListWalker, PartResType, "ShareDisposition", ShareDisposition);
  746. GetFieldValue(resourceListWalker, PartResType, "Flags", Flags);
  747. xdprintf(Depth, "Entry %d - %s (%#x) %s (%#x)\n",
  748. j,
  749. (Type == CmResourceTypeNull ? "Null" :
  750. Type == CmResourceTypePort ? "Port" :
  751. Type == CmResourceTypeInterrupt ? "Interrupt" :
  752. Type == CmResourceTypeMemory ? "Memory" :
  753. Type == CmResourceTypeDma ? "Dma" :
  754. Type == CmResourceTypeDeviceSpecific ? "DeviceSpecific" :
  755. Type == CmResourceTypeBusNumber ? "BusNumber" :
  756. Type == CmResourceTypeDevicePrivate ? "DevicePrivate" :
  757. Type == CmResourceTypeConfigData ? "ConfigData" : "Unknown"),
  758. Type,
  759. (ShareDisposition == CmResourceShareUndetermined ? "Undetermined Sharing" :
  760. ShareDisposition == CmResourceShareDeviceExclusive ? "Device Exclusive" :
  761. ShareDisposition == CmResourceShareDriverExclusive ? "Driver Exclusive" :
  762. ShareDisposition == CmResourceShareShared ? "Shared" : "Unknown Sharing"),
  763. ShareDisposition);
  764. Depth++;
  765. xdprintf(Depth, "Flags (%#04wx) - ", Flags);
  766. switch (Type) {
  767. case CmResourceTypePort:
  768. //
  769. // CM_RESOURCE_PORT_MEMORY = ~CM_RESOURCE_PORT_IO
  770. //
  771. if ( (~Flags) & ~CM_RESOURCE_PORT_MEMORY) {
  772. dprintf("PORT_MEMORY ");
  773. }
  774. if (Flags & CM_RESOURCE_PORT_IO) {
  775. dprintf("PORT_IO ");
  776. }
  777. if (Flags & CM_RESOURCE_PORT_10_BIT_DECODE) {
  778. dprintf("10_BIT_DECODE ");
  779. }
  780. if (Flags & CM_RESOURCE_PORT_12_BIT_DECODE) {
  781. dprintf("12_BIT_DECODE ");
  782. }
  783. if (Flags & CM_RESOURCE_PORT_16_BIT_DECODE) {
  784. dprintf("16_BIT_DECODE ");
  785. }
  786. if (Flags & CM_RESOURCE_PORT_POSITIVE_DECODE) {
  787. dprintf("POSITIVE_DECODE ");
  788. }
  789. if (Flags & CM_RESOURCE_PORT_PASSIVE_DECODE) {
  790. dprintf ("PASSIVE_DECODE ");
  791. }
  792. if (Flags & CM_RESOURCE_PORT_WINDOW_DECODE) {
  793. dprintf ("WINDOW_DECODE ");
  794. }
  795. dprintf("\n");
  796. GetFieldValue(resourceListWalker, PartResType, "u.Port.Start.QuadPart", u_Port_QuadPart);
  797. GetFieldValue(resourceListWalker, PartResType, "u.Port.Length", u_Port_Length);
  798. xdprintf(Depth, "Range starts at %#I64lx for %#x bytes\n",
  799. u_Port_QuadPart,
  800. u_Port_Length);
  801. break;
  802. case CmResourceTypeMemory:
  803. if (Flags == CM_RESOURCE_MEMORY_READ_WRITE) {
  804. dprintf("READ_WRITE ");
  805. }
  806. if (Flags & CM_RESOURCE_MEMORY_READ_ONLY) {
  807. dprintf("READ_ONLY ");
  808. }
  809. if (Flags & CM_RESOURCE_MEMORY_WRITE_ONLY) {
  810. dprintf("WRITE_ONLY ");
  811. }
  812. if (Flags & CM_RESOURCE_MEMORY_PREFETCHABLE) {
  813. dprintf("PREFETCHABLE ");
  814. }
  815. if (Flags & CM_RESOURCE_MEMORY_COMBINEDWRITE) {
  816. dprintf("COMBINEDWRITE ");
  817. }
  818. if (Flags & CM_RESOURCE_MEMORY_24) {
  819. dprintf("MEMORY_24 ");
  820. }
  821. dprintf("\n");
  822. GetFieldValue(resourceListWalker, PartResType, "u.Memory.Start.QuadPart", u_Memory_QuadPart);
  823. GetFieldValue(resourceListWalker, PartResType, "u.Memory.Length", u_Memory_Length);
  824. xdprintf(Depth, "Range starts at %#018I64lx for %#x bytes\n",
  825. u_Memory_QuadPart,
  826. u_Memory_Length);
  827. break;
  828. case CmResourceTypeInterrupt:
  829. if (Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE) {
  830. dprintf("LEVEL_SENSITIVE ");
  831. }
  832. if (Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
  833. dprintf("LATCHED ");
  834. }
  835. dprintf("\n");
  836. GetFieldValue(resourceListWalker, PartResType, "u.Interrupt.Level", u_Interrupt_Level);
  837. GetFieldValue(resourceListWalker, PartResType, "u.Interrupt.Vector", u_Interrupt_Vector);
  838. GetFieldValue(resourceListWalker, PartResType, "u.Interrupt.Affinity", u_Interrupt_Affinity);
  839. xdprintf(Depth, "Level %#x, Vector %#x, Affinity %#I64x\n",
  840. u_Interrupt_Level,
  841. u_Interrupt_Vector,
  842. u_Interrupt_Affinity);
  843. break;
  844. case CmResourceTypeDma:
  845. if (Flags & CM_RESOURCE_DMA_8) {
  846. dprintf("DMA_8 ");
  847. }
  848. if (Flags & CM_RESOURCE_DMA_16) {
  849. dprintf("DMA_16 ");
  850. }
  851. if (Flags & CM_RESOURCE_DMA_32) {
  852. dprintf("DMA_32 ");
  853. }
  854. if (Flags & CM_RESOURCE_DMA_8_AND_16) {
  855. dprintf("DMA_8_AND_16 ");
  856. }
  857. if (Flags & CM_RESOURCE_DMA_BUS_MASTER) {
  858. dprintf("DMA_BUS_MASTER ");
  859. }
  860. if (Flags & CM_RESOURCE_DMA_TYPE_A) {
  861. dprintf("DMA_A ");
  862. }
  863. if (Flags & CM_RESOURCE_DMA_TYPE_B) {
  864. dprintf("DMA_B ");
  865. }
  866. if (Flags & CM_RESOURCE_DMA_TYPE_F) {
  867. dprintf("DMA_F ");
  868. }
  869. dprintf("\n");
  870. GetFieldValue(resourceListWalker, PartResType, "u.Dma.Channel", u_Dma_Channel);
  871. GetFieldValue(resourceListWalker, PartResType, "u.Dma.Port", u_Dma_Port);
  872. GetFieldValue(resourceListWalker, PartResType, "u.Dma.Reserved1", u_Dma_Reserved1);
  873. xdprintf(Depth, "Channel %#x Port %#x (Reserved1 %#x)\n",
  874. u_Dma_Channel,
  875. u_Dma_Port,
  876. u_Dma_Reserved1);
  877. break;
  878. case CmResourceTypeBusNumber:
  879. dprintf("\n");
  880. GetFieldValue(resourceListWalker, PartResType, "u.BusNumber.Start", u_BusNumber_Start);
  881. GetFieldValue(resourceListWalker, PartResType, "u.BusNumber.Length", u_BusNumber_Length);
  882. xdprintf(Depth, "Range starts at %#010lx for %#x values\n",
  883. u_BusNumber_Start,
  884. u_BusNumber_Length);
  885. break;
  886. default:
  887. dprintf("\n");
  888. GetFieldValue(resourceListWalker, PartResType, "u.DevicePrivate.Data", u_DevicePrivate_Data);
  889. xdprintf(Depth, "Data - {%#010lx, %#010lx, %#010lx}\n",
  890. u_DevicePrivate_Data[0],
  891. u_DevicePrivate_Data[1],
  892. u_DevicePrivate_Data[2]);
  893. break;
  894. }
  895. Depth--;
  896. resourceListWalker += sz; // sizeof(partialDescriptors);
  897. }
  898. }
  899. GetOut:
  900. xdprintf(Depth, "\n");
  901. return continueDump;
  902. }
  903. BOOLEAN
  904. DumpRelationsList(
  905. ULONG64 RelationsList,
  906. BOOLEAN DumpCmRes,
  907. BOOLEAN DumpCmResReqList,
  908. BOOLEAN DumpCmResTrans
  909. )
  910. {
  911. ULONG64 listEntryAddr;
  912. ULONG64 deviceObjectAddr;
  913. ULONG i, j, EntrySize;
  914. BOOLEAN continueDump = TRUE;
  915. CHAR RelListType[] = "nt!_RELATION_LIST", RelListentryType[] = "nt!_RELATION_LIST_ENTRY";
  916. ULONG64 EntryAddr;
  917. ULONG Count=0, TagCount=0, FirstLevel=0, MaxLevel=0;
  918. ULONG EntryOffset;
  919. if (GetFieldValue(RelationsList, RelListType, "Count",Count)) {
  920. xdprintf(1, "Error reading relation list @ ");
  921. dprintf("0x%08p)\n", RelationsList);
  922. return continueDump;
  923. }
  924. EntrySize = DBG_PTR_SIZE;
  925. GetFieldOffset(RelListType, "Entries", &EntryOffset);
  926. EntryAddr=RelationsList + EntryOffset;
  927. GetFieldValue(RelationsList, RelListType, "TagCount", TagCount);
  928. GetFieldValue(RelationsList, RelListType, "FirstLevel", FirstLevel);
  929. GetFieldValue(RelationsList, RelListType, "MaxLevel", MaxLevel);
  930. xdprintf(1, "Relation List @ "); dprintf("0x%08p\n", RelationsList);
  931. xdprintf(2, "Count = %d, TagCount = %d, FirstLevel = %d, MaxLevel = %d\n",
  932. Count,
  933. TagCount,
  934. FirstLevel,
  935. MaxLevel);
  936. for (i = 0; i <= (MaxLevel - FirstLevel); i++) {
  937. ULONG res,Entry_Count=0, MaxCount=0, DeviceSize;
  938. ULONG64 DeviceAddr;
  939. FIELD_INFO relListEntryFields[] = {
  940. {"Devices", "", 0, DBG_DUMP_FIELD_RETURN_ADDRESS, 0, NULL},
  941. };
  942. if (CheckControlC()) {
  943. continueDump = FALSE;
  944. break;
  945. }
  946. listEntryAddr = 0;
  947. if (ReadPointer( EntryAddr + i*EntrySize,
  948. &listEntryAddr)) {
  949. if (!listEntryAddr) {
  950. xdprintf(2, "Null relation list entry\n");
  951. }else if (!GetFieldValue(listEntryAddr, RelListentryType,
  952. "Count",Entry_Count)) {
  953. ULONG DeviceOffset;
  954. GetFieldOffset(RelListentryType, "Devices", &DeviceOffset);
  955. DeviceAddr = listEntryAddr + DeviceOffset;
  956. DeviceSize = EntrySize; // == pointer size
  957. GetFieldValue(listEntryAddr, RelListentryType, "MaxCount", MaxCount);
  958. xdprintf(2, "Relation List Entry @ "); dprintf("0x%08p\n", listEntryAddr);
  959. xdprintf(3, "Count = %d, MaxCount = %d\n", Entry_Count, MaxCount);
  960. xdprintf(3, "Devices at level %d\n", FirstLevel + i);
  961. for (j = 0; j < Entry_Count; j++) {
  962. if (CheckControlC()) {
  963. continueDump = FALSE;
  964. break;
  965. }
  966. if (ReadPointer( DeviceAddr + j*DeviceSize,
  967. &deviceObjectAddr)) {
  968. ULONG64 DeviceNode=0;
  969. FIELD_INFO DevObjFields[] = {
  970. // Implicitly reads the pointer DeviceObjectExtension and its field DeviceNode
  971. {"DeviceObjectExtension", "", 0, DBG_DUMP_FIELD_RECUR_ON_THIS, 0, NULL},
  972. {"DeviceObjectExtension.DeviceNode", "", 0, DBG_DUMP_FIELD_COPY_FIELD_DATA, 0, (PVOID) &DeviceNode}
  973. };
  974. if (!deviceObjectAddr) {
  975. continue;
  976. }
  977. xdprintf(4, "Device Object = ");
  978. dprintf("0x%08p (%sagged, %sirect)\n",
  979. deviceObjectAddr & ~3,
  980. (deviceObjectAddr & 1) ? "T" : "Not t",
  981. (deviceObjectAddr & 2) ? "D" : "Ind");
  982. if (!GetFieldValue(deviceObjectAddr, "nt!_DEVICE_OBJECT",
  983. "DeviceObjectExtension.DeviceNode",
  984. DeviceNode)) {
  985. if (DeviceNode) {
  986. continueDump = DumpDevNode(DeviceNode,
  987. 5,
  988. FALSE,
  989. FALSE,
  990. DumpCmRes,
  991. DumpCmResReqList,
  992. DumpCmResTrans,
  993. FALSE,
  994. FALSE,
  995. (PUNICODE_STRING)NULL,
  996. TRUE,
  997. TRUE
  998. );
  999. }
  1000. } else {
  1001. xdprintf(5, "Error reading device object @ ");
  1002. dprintf("0x%08p)\n",deviceObjectAddr);
  1003. }
  1004. } else {
  1005. xdprintf(4, "Error reading relation list entry device ");
  1006. dprintf("%d @ 0x%08p)\n",
  1007. j,
  1008. DeviceAddr + j*DeviceSize);
  1009. }
  1010. if (!continueDump) {
  1011. break;
  1012. }
  1013. }
  1014. } else {
  1015. xdprintf(2, "Error reading relation list entry @ ");
  1016. dprintf("0x%08p)\n",
  1017. listEntryAddr);
  1018. }
  1019. } else {
  1020. xdprintf(1, "Error reading relation list entry ");
  1021. dprintf("%d @ 0x%08p)\n",
  1022. i,
  1023. EntryAddr + i*EntrySize);
  1024. }
  1025. if (!continueDump) {
  1026. break;
  1027. }
  1028. }
  1029. return continueDump;
  1030. }
  1031. BOOLEAN
  1032. DumpPendingRemovals(
  1033. BOOLEAN DumpCmRes,
  1034. BOOLEAN DumpCmResReqList,
  1035. BOOLEAN DumpCmResTrans
  1036. )
  1037. {
  1038. ULONG64 listHeadAddr, pendingEntryAddr;
  1039. BOOLEAN continueDump = TRUE;
  1040. ULONG64 Head_Blink=0, Head_Flink=0, Link_Flink=0;
  1041. listHeadAddr = GetExpression( "nt!IopPendingSurpriseRemovals" );
  1042. if (listHeadAddr == 0) {
  1043. dprintf("Error retrieving address of IopPendingSurpriseRemovals\n");
  1044. return continueDump;
  1045. }
  1046. if (GetFieldValue(listHeadAddr, "nt!_LIST_ENTRY", "Flink", Head_Flink) ||
  1047. GetFieldValue(listHeadAddr, "nt!_LIST_ENTRY", "Blink", Head_Blink)) {
  1048. dprintf("Error reading value of IopPendingSurpriseRemovals (0x%08p)\n", listHeadAddr);
  1049. return continueDump;
  1050. }
  1051. if (Head_Flink == listHeadAddr) {
  1052. dprintf("There are no removals currently pending\n");
  1053. return continueDump;
  1054. }
  1055. for (pendingEntryAddr = Head_Flink;
  1056. pendingEntryAddr != listHeadAddr;
  1057. pendingEntryAddr = Link_Flink) {
  1058. ULONG64 RelationsList=0, DeviceObject=0;
  1059. if (CheckControlC()) {
  1060. continueDump = FALSE;
  1061. break;
  1062. }
  1063. if (GetFieldValue(pendingEntryAddr, "nt!_PENDING_RELATIONS_LIST_ENTRY", "DeviceObject", DeviceObject)){
  1064. dprintf("Error reading pending relations list entry (0x%08p)\n", pendingEntryAddr);
  1065. return continueDump;
  1066. }
  1067. GetFieldValue(pendingEntryAddr, "nt!_PENDING_RELATIONS_LIST_ENTRY", "Link.Flink", Link_Flink);
  1068. GetFieldValue(pendingEntryAddr, "nt!_PENDING_RELATIONS_LIST_ENTRY", "RelationsList", RelationsList);
  1069. dprintf("Pending Removal of PDO 0x%08p, Pending Relations List Entry @ 0x%08p\n",
  1070. DeviceObject,
  1071. pendingEntryAddr
  1072. );
  1073. continueDump = DumpRelationsList( RelationsList,
  1074. DumpCmRes,
  1075. DumpCmResReqList,
  1076. DumpCmResTrans
  1077. );
  1078. if (!continueDump) {
  1079. break;
  1080. }
  1081. }
  1082. return continueDump;
  1083. }
  1084. BOOLEAN
  1085. DumpPendingEjects(
  1086. BOOLEAN DumpCmRes,
  1087. BOOLEAN DumpCmResReqList,
  1088. BOOLEAN DumpCmResTrans
  1089. )
  1090. {
  1091. ULONG64 listHeadAddr, pendingEntryAddr;
  1092. BOOLEAN continueDump = TRUE;
  1093. ULONG64 Head_Blink=0, Head_Flink=0, Link_Flink=0;
  1094. listHeadAddr = GetExpression( "nt!IopPendingEjects" );
  1095. if (listHeadAddr == 0) {
  1096. dprintf("Error retrieving address of IopEjects\n");
  1097. return continueDump;
  1098. }
  1099. if (GetFieldValue(listHeadAddr, "nt!_LIST_ENTRY", "Flink", Head_Flink) ||
  1100. GetFieldValue(listHeadAddr, "nt!_LIST_ENTRY", "Blink", Head_Blink)) {
  1101. dprintf("Error reading value of IopPendingSurpriseRemovals (0x%08p)\n", listHeadAddr);
  1102. return continueDump;
  1103. }
  1104. if (Head_Flink == listHeadAddr) {
  1105. dprintf("There are no ejects currently pending\n");
  1106. return continueDump;
  1107. }
  1108. for (pendingEntryAddr = Head_Flink;
  1109. pendingEntryAddr != listHeadAddr;
  1110. pendingEntryAddr = Link_Flink) {
  1111. ULONG64 RelationsList=0, DeviceObject=0, EjectIrp=0;
  1112. if (CheckControlC()) {
  1113. continueDump = FALSE;
  1114. break;
  1115. }
  1116. if (GetFieldValue(pendingEntryAddr, "nt!_PENDING_RELATIONS_LIST_ENTRY", "DeviceObject", DeviceObject)){
  1117. dprintf("Error reading pending relations list entry (0x%08p)\n", pendingEntryAddr);
  1118. return continueDump;
  1119. }
  1120. GetFieldValue(pendingEntryAddr, "nt!_PENDING_RELATIONS_LIST_ENTRY", "Link.Flink", Link_Flink);
  1121. GetFieldValue(pendingEntryAddr, "nt!_PENDING_RELATIONS_LIST_ENTRY", "RelationsList", RelationsList);
  1122. GetFieldValue(pendingEntryAddr, "nt!_PENDING_RELATIONS_LIST_ENTRY", "EjectIrp", EjectIrp);
  1123. dprintf("Pending Eject of PDO 0x%08p, EjectIrp = 0x%08p, \nPending Relations List Entry @ 0x%08p\n",
  1124. DeviceObject,
  1125. EjectIrp,
  1126. pendingEntryAddr
  1127. );
  1128. continueDump = DumpRelationsList( RelationsList,
  1129. DumpCmRes,
  1130. DumpCmResReqList,
  1131. DumpCmResTrans
  1132. );
  1133. if (!continueDump) {
  1134. break;
  1135. }
  1136. }
  1137. return continueDump;
  1138. }
  1139. BOOLEAN
  1140. DumpDevNode(
  1141. ULONG64 DeviceNode,
  1142. ULONG Depth,
  1143. BOOLEAN DumpSibling,
  1144. BOOLEAN DumpChild,
  1145. BOOLEAN DumpCmRes,
  1146. BOOLEAN DumpCmResReqList,
  1147. BOOLEAN DumpCmResTrans,
  1148. BOOLEAN DumpOnlyDevnodesWithProblems,
  1149. BOOLEAN DumpOnlyNonStartedDevnodes,
  1150. PUNICODE_STRING ServiceName OPTIONAL,
  1151. BOOLEAN PrintDefault,
  1152. BOOLEAN DumpStateHistory
  1153. )
  1154. /*++
  1155. Routine Description:
  1156. Displays the driver name for the device object if FullDetail == FALSE.
  1157. Otherwise displays more information about the device and the device queue.
  1158. Arguments:
  1159. DeviceAddress - address of device object to dump.
  1160. FullDetail - TRUE means the device object name, driver name, and
  1161. information about Irps queued to the device.
  1162. DumpOnlyDevnodesWithFlags -
  1163. if set, then the only devnodes that will be dumped are
  1164. those with one of the FlagsSet bits set or one of the
  1165. FlagsNotSet bits not set.
  1166. Return Value:
  1167. None
  1168. --*/
  1169. {
  1170. ULONG result;
  1171. // DEVICE_NODE deviceNode;
  1172. BOOLEAN print = TRUE;
  1173. BOOLEAN continueDump = TRUE;
  1174. CHAR DevNodeType[]="nt!_DEVICE_NODE";
  1175. USHORT ServiceName_Len=0, ServiceName_MaxLen=0, InstancePath_Len=0, InstancePath_Max=0;
  1176. ULONG Flags=0, BusNumber=0, Header_SignalState=0, UserFlags=0;
  1177. ULONG CapabilityFlags=0, DisableableDepends=0, Problem=0;
  1178. ULONG FailureStatus=0, State=0, PreviousState=0;
  1179. ULONG StateHistoryEntry = 0;
  1180. ULONG StateHistoryValue = 0;
  1181. ULONG64 ServiceName_Buff=0, PhysicalDeviceObject=0, Parent=0, Sibling=0,
  1182. Child=0, InterfaceType=0, DuplicatePDO=0, TargetDeviceNotify_Blink=0, TargetDeviceNotify_Flink=0,
  1183. PreviousResourceList=0, ResourceList=0, BootResources=0, ResourceListTranslated=0,
  1184. ResourceRequirements=0, InstancePath_Buff=0, PreviousResourceRequirements=0;
  1185. ULONG64 TargetDeviceNotifyAddress;
  1186. ULONG AmountRead;
  1187. PNP_DEVNODE_STATE StateHistory[STATE_HISTORY_SIZE];
  1188. if (CheckControlC()) {
  1189. return FALSE;
  1190. }
  1191. GetFieldOffset("nt!_DEVICE_NODE", "TargetDeviceNotify", &result);
  1192. TargetDeviceNotifyAddress = DeviceNode + result;
  1193. #define DevFld(F) GetFieldValue(DeviceNode, DevNodeType, #F, F)
  1194. #define DevFld2(F, V) GetFieldValue(DeviceNode, DevNodeType, #F, V)
  1195. if (DevFld2(ServiceName.Length, ServiceName_Len)) {
  1196. xdprintf(Depth, "");
  1197. dprintf("%08p: Could not read device node\n", DeviceNode);
  1198. return TRUE;
  1199. }
  1200. DevFld2(ServiceName.MaximumLength, ServiceName_MaxLen);
  1201. DevFld2(ServiceName.Buffer, ServiceName_Buff);
  1202. DevFld(Flags); DevFld(PhysicalDeviceObject); DevFld(Parent);
  1203. DevFld(Sibling); DevFld(Child); DevFld(InterfaceType);
  1204. DevFld(BusNumber);DevFld(DuplicatePDO); DevFld(State);
  1205. DevFld(PreviousState);
  1206. DevFld2(InstancePath.Length, InstancePath_Len);
  1207. DevFld2(InstancePath.MaximumLength, InstancePath_Max);
  1208. DevFld2(InstancePath.Buffer, InstancePath_Buff);
  1209. DevFld2(TargetDeviceNotify.Blink, TargetDeviceNotify_Blink);
  1210. DevFld2(TargetDeviceNotify.Flink, TargetDeviceNotify_Flink);
  1211. DevFld(UserFlags); DevFld(CapabilityFlags); DevFld(DisableableDepends);
  1212. DevFld(Problem); DevFld(FailureStatus);
  1213. DevFld(PreviousResourceList); DevFld(PreviousResourceRequirements);
  1214. DevFld(ResourceList);
  1215. DevFld(BootResources); DevFld(ResourceListTranslated);
  1216. DevFld(ResourceRequirements); DevFld(StateHistoryEntry);
  1217. #undef DevFld
  1218. #undef DevFld2
  1219. //
  1220. // Check if printing should be suppressed
  1221. //
  1222. if (!PrintDefault && ServiceName != NULL) {
  1223. if ((ServiceName_Buff == 0) || (ServiceName_MaxLen <= 0) ||
  1224. (ServiceName_MaxLen > 1024)) {
  1225. print = FALSE;
  1226. } else {
  1227. //
  1228. // Compare the service names
  1229. //
  1230. UNICODE_STRING v;
  1231. v.Buffer = LocalAlloc(LPTR, ServiceName_MaxLen);
  1232. if (v.Buffer != NULL) {
  1233. v.MaximumLength = ServiceName_MaxLen;
  1234. v.Length = ServiceName_Len;
  1235. if (ReadMemory(ServiceName_Buff,
  1236. v.Buffer,
  1237. ServiceName_Len,
  1238. (PULONG) &AmountRead)) {
  1239. if (RtlCompareUnicodeString(ServiceName,
  1240. &v,
  1241. TRUE) != 0) {
  1242. //
  1243. // We are not interested in this devnode
  1244. //
  1245. print = FALSE;
  1246. }
  1247. }
  1248. LocalFree(v.Buffer);
  1249. }
  1250. }
  1251. }
  1252. if (DumpOnlyDevnodesWithProblems) {
  1253. print = (BOOLEAN) ((Flags & (DNF_HAS_PROBLEM | DNF_HAS_PRIVATE_PROBLEM)) != 0);
  1254. } else if (DumpOnlyNonStartedDevnodes) {
  1255. print = (BOOLEAN) (State != DeviceNodeStarted);
  1256. }
  1257. if (print) {
  1258. xdprintf(Depth, "");
  1259. dprintf("DevNode %#010p for PDO %#010p\n",
  1260. DeviceNode,
  1261. PhysicalDeviceObject);
  1262. Depth++;
  1263. if (!DumpChild) {
  1264. xdprintf(Depth, "");
  1265. dprintf("Parent %#010p Sibling %#010p Child %#010p\n",
  1266. Parent,
  1267. Sibling,
  1268. Child);
  1269. if ((LONG) InterfaceType != -1 ||
  1270. (BusNumber != -1 && BusNumber != -16)) {
  1271. xdprintf(Depth, "InterfaceType %#x Bus Number %#x\n",
  1272. (LONG) InterfaceType,
  1273. BusNumber);
  1274. }
  1275. if (DuplicatePDO != 0) {
  1276. dprintf("Duplicate PDO %#010p", DuplicatePDO);
  1277. }
  1278. }
  1279. if (InstancePath_Buff != 0) {
  1280. UNICODE_STRING64 v;
  1281. xdprintf(Depth, "InstancePath is \"");
  1282. v.MaximumLength = InstancePath_Max;
  1283. v.Length = InstancePath_Len;
  1284. v.Buffer = InstancePath_Buff;
  1285. DumpUnicode64(v);
  1286. dprintf("\"\n");
  1287. }
  1288. if (ServiceName_Buff != 0) {
  1289. UNICODE_STRING64 v;
  1290. xdprintf(Depth, "ServiceName is \"");
  1291. v.MaximumLength = ServiceName_MaxLen;
  1292. v.Length = ServiceName_Len;
  1293. v.Buffer = ServiceName_Buff;
  1294. DumpUnicode64(v);
  1295. dprintf("\"\n");
  1296. }
  1297. if ((TargetDeviceNotify_Flink != 0 ||
  1298. TargetDeviceNotify_Blink != 0) &&
  1299. (TargetDeviceNotify_Blink != TargetDeviceNotifyAddress ||
  1300. TargetDeviceNotify_Flink != TargetDeviceNotifyAddress)) {
  1301. xdprintf(Depth, "TargetDeviceNotify List - ");
  1302. dprintf ("f %#010p b %#010p\n",
  1303. TargetDeviceNotify_Flink,
  1304. TargetDeviceNotify_Blink);
  1305. }
  1306. PrintDevNodeState(Depth, "State", State);
  1307. PrintDevNodeState(Depth, "Previous State", PreviousState);
  1308. if (!DumpChild) {
  1309. if (DumpStateHistory) {
  1310. GetFieldOffset("nt!_DEVICE_NODE", "StateHistory", &result);
  1311. if (ReadMemory(DeviceNode+result,
  1312. StateHistory,
  1313. sizeof(StateHistory),
  1314. &AmountRead)) {
  1315. UCHAR Description[20];
  1316. ULONG index;
  1317. INT i;
  1318. for (i = STATE_HISTORY_SIZE - 1; i >= 0; i--) {
  1319. index = (i + StateHistoryEntry) % STATE_HISTORY_SIZE;
  1320. sprintf(Description, "StateHistory[%02d]", index);
  1321. PrintDevNodeState(Depth, Description, StateHistory[index]);
  1322. }
  1323. }
  1324. DumpFlags(Depth, "Flags", Flags, DeviceNodeFlags);
  1325. if (UserFlags != 0) {
  1326. DumpFlags(Depth, "UserFlags", UserFlags, DeviceNodeUserFlags);
  1327. }
  1328. if (CapabilityFlags != 0) {
  1329. DumpFlags(Depth, "CapabilityFlags", CapabilityFlags, DeviceNodeCapabilityFlags);
  1330. }
  1331. if (DisableableDepends != 0) {
  1332. xdprintf(Depth, "DisableableDepends = %d (%s)\n", DisableableDepends,
  1333. (UserFlags&DNUF_NOT_DISABLEABLE)?"including self":"from children");
  1334. }
  1335. }
  1336. }
  1337. if (Flags & DNF_HAS_PROBLEM) {
  1338. if (Problem < NUM_CM_PROB && DevNodeProblems[Problem] != NULL) {
  1339. xdprintf(Depth, "Problem = %s\n", DevNodeProblems[Problem]);
  1340. } else {
  1341. xdprintf(Depth, "Problem = Unknown problem (%d)\n", Problem);
  1342. }
  1343. if (Problem == CM_PROB_FAILED_START) {
  1344. xdprintf(Depth, "Failure Status %#010lx\n", FailureStatus);
  1345. continueDump = DumpResourceList64( "Previous CmResourceList",
  1346. Depth,
  1347. PreviousResourceList);
  1348. if (continueDump) {
  1349. continueDump = DumpResourceRequirementList64( Depth,
  1350. PreviousResourceRequirements);
  1351. }
  1352. }
  1353. }
  1354. if (continueDump && DumpCmRes) {
  1355. continueDump = DumpResourceList64( "CmResourceList",
  1356. Depth,
  1357. ResourceList);
  1358. if (continueDump) {
  1359. continueDump = DumpResourceList64( "BootResourcesList",
  1360. Depth,
  1361. BootResources);
  1362. }
  1363. }
  1364. if (continueDump && DumpCmResTrans) {
  1365. continueDump = DumpResourceList64( "TranslatedResourceList",
  1366. Depth,
  1367. ResourceListTranslated);
  1368. }
  1369. if (continueDump && DumpCmResReqList) {
  1370. continueDump = DumpResourceRequirementList64( Depth,
  1371. ResourceRequirements);
  1372. }
  1373. }
  1374. if (continueDump && DumpChild && Child) {
  1375. continueDump = DumpDevNode( Child,
  1376. Depth,
  1377. DumpChild, // whem dumping a child, dump its siblings, too
  1378. DumpChild,
  1379. DumpCmRes,
  1380. DumpCmResReqList,
  1381. DumpCmResTrans,
  1382. DumpOnlyDevnodesWithProblems,
  1383. DumpOnlyNonStartedDevnodes,
  1384. ServiceName,
  1385. print,
  1386. DumpStateHistory
  1387. );
  1388. }
  1389. if (continueDump && DumpSibling && Sibling) {
  1390. continueDump = DumpDevNode( Sibling,
  1391. (print ? (Depth - 1):Depth),
  1392. DumpSibling,
  1393. DumpChild,
  1394. DumpCmRes,
  1395. DumpCmResReqList,
  1396. DumpCmResTrans,
  1397. DumpOnlyDevnodesWithProblems,
  1398. DumpOnlyNonStartedDevnodes,
  1399. ServiceName,
  1400. PrintDefault,
  1401. DumpStateHistory
  1402. );
  1403. }
  1404. return continueDump;
  1405. }
  1406. LPSTR
  1407. GetCmResourceTypeString(
  1408. IN UCHAR Type
  1409. )
  1410. {
  1411. LPSTR typeString;
  1412. switch (Type) {
  1413. case CmResourceTypeNull:
  1414. typeString = "Null";
  1415. break;
  1416. case CmResourceTypePort:
  1417. typeString = "Port";
  1418. break;
  1419. case CmResourceTypeInterrupt:
  1420. typeString = "Interrupt";
  1421. break;
  1422. case CmResourceTypeMemory:
  1423. typeString = "Memory";
  1424. break;
  1425. case CmResourceTypeDma:
  1426. typeString = "Dma";
  1427. break;
  1428. case CmResourceTypeDeviceSpecific:
  1429. typeString = "DeviceSpeific";
  1430. break;
  1431. case CmResourceTypeBusNumber:
  1432. typeString = "BusNumber";
  1433. break;
  1434. case CmResourceTypeMaximum:
  1435. typeString = "Maximum";
  1436. break;
  1437. case CmResourceTypeNonArbitrated:
  1438. typeString = "NonArbitrated/ConfigData";
  1439. break;
  1440. case CmResourceTypeDevicePrivate:
  1441. typeString = "DevicePrivate";
  1442. break;
  1443. case CmResourceTypePcCardConfig:
  1444. typeString = "PcCardConfig";
  1445. break;
  1446. default:
  1447. typeString = "Unknown";
  1448. break;
  1449. }
  1450. return typeString;
  1451. }
  1452. VOID
  1453. DumpResourceDescriptorHeader(
  1454. ULONG Depth,
  1455. ULONG Number,
  1456. UCHAR Option,
  1457. UCHAR Type,
  1458. UCHAR SharingDisposition,
  1459. USHORT Flags
  1460. )
  1461. {
  1462. PUCHAR typeString;
  1463. PUCHAR sharingString;
  1464. xdprintf (Depth, "");
  1465. if (Option & IO_RESOURCE_PREFERRED) {
  1466. dprintf("Preferred ");
  1467. }
  1468. if (Option & IO_RESOURCE_DEFAULT) {
  1469. dprintf("Default ");
  1470. }
  1471. if (Option & IO_RESOURCE_ALTERNATIVE) {
  1472. dprintf("Alternative ");
  1473. }
  1474. dprintf ("Descriptor %d - ", Number);
  1475. typeString = GetCmResourceTypeString(Type);
  1476. switch (SharingDisposition) {
  1477. case CmResourceShareUndetermined:
  1478. sharingString = "Undetermined Sharing";
  1479. break;
  1480. case CmResourceShareDeviceExclusive:
  1481. sharingString = "Device Exclusive";
  1482. break;
  1483. case CmResourceShareDriverExclusive:
  1484. sharingString = "Driver Exclusive";
  1485. break;
  1486. case CmResourceShareShared:
  1487. sharingString = "Shared";
  1488. break;
  1489. default:
  1490. sharingString = "Unknown Sharing";
  1491. break;
  1492. }
  1493. dprintf("%s (%#x) %s (%#x)\n",
  1494. typeString,
  1495. Type,
  1496. sharingString,
  1497. SharingDisposition);
  1498. Depth++;
  1499. xdprintf (Depth, "Flags (%#04wx) - ", Flags);
  1500. switch (Type) {
  1501. case CmResourceTypePort:
  1502. if (Flags == CM_RESOURCE_PORT_MEMORY) {
  1503. dprintf ("PORT_MEMORY ");
  1504. }
  1505. if (Flags & CM_RESOURCE_PORT_IO) {
  1506. dprintf ("PORT_IO ");
  1507. }
  1508. if (Flags & CM_RESOURCE_PORT_10_BIT_DECODE) {
  1509. dprintf ("10_BIT_DECODE ");
  1510. }
  1511. if (Flags & CM_RESOURCE_PORT_12_BIT_DECODE) {
  1512. dprintf ("12_BIT_DECODE ");
  1513. }
  1514. if (Flags & CM_RESOURCE_PORT_16_BIT_DECODE) {
  1515. dprintf ("16_BIT_DECODE ");
  1516. }
  1517. if (Flags & CM_RESOURCE_PORT_POSITIVE_DECODE) {
  1518. dprintf ("POSITIVE_DECODE ");
  1519. }
  1520. break;
  1521. case CmResourceTypeMemory:
  1522. if (Flags == CM_RESOURCE_MEMORY_READ_WRITE) {
  1523. dprintf ("READ_WRITE ");
  1524. }
  1525. if (Flags & CM_RESOURCE_MEMORY_READ_ONLY) {
  1526. dprintf ("READ_ONLY ");
  1527. }
  1528. if (Flags & CM_RESOURCE_MEMORY_WRITE_ONLY) {
  1529. dprintf ("WRITE_ONLY ");
  1530. }
  1531. if (Flags & CM_RESOURCE_MEMORY_PREFETCHABLE) {
  1532. dprintf ("PREFETCHABLE ");
  1533. }
  1534. if (Flags & CM_RESOURCE_MEMORY_COMBINEDWRITE) {
  1535. dprintf ("COMBINEDWRITE ");
  1536. }
  1537. if (Flags & CM_RESOURCE_MEMORY_24) {
  1538. dprintf ("MEMORY_24 ");
  1539. }
  1540. break;
  1541. case CmResourceTypeInterrupt:
  1542. if (Flags == CM_RESOURCE_INTERRUPT_LEVEL_SENSITIVE) {
  1543. dprintf ("LEVEL_SENSITIVE ");
  1544. }
  1545. if (Flags & CM_RESOURCE_INTERRUPT_LATCHED) {
  1546. dprintf ("LATCHED ");
  1547. }
  1548. break;
  1549. case CmResourceTypeDma:
  1550. if (Flags & CM_RESOURCE_DMA_8) {
  1551. dprintf ("DMA_8 ");
  1552. }
  1553. if (Flags & CM_RESOURCE_DMA_16) {
  1554. dprintf ("DMA_16 ");
  1555. }
  1556. if (Flags & CM_RESOURCE_DMA_32) {
  1557. dprintf ("DMA_32 ");
  1558. }
  1559. if (Flags & CM_RESOURCE_DMA_8_AND_16) {
  1560. dprintf ("DMA_8_AND_16");
  1561. }
  1562. if (Flags & CM_RESOURCE_DMA_TYPE_A) {
  1563. dprintf ("DMA_TYPE_A");
  1564. }
  1565. if (Flags & CM_RESOURCE_DMA_TYPE_B) {
  1566. dprintf ("DMA_TYPE_B");
  1567. }
  1568. if (Flags & CM_RESOURCE_DMA_TYPE_F) {
  1569. dprintf ("DMA_TYPE_F");
  1570. }
  1571. break;
  1572. }
  1573. dprintf("\n");
  1574. }
  1575. DECLARE_API( arbiter )
  1576. /*++
  1577. Routine Description:
  1578. Dumps all the arbiters in the system, their allocated ranges, and
  1579. the owners of the ranges.
  1580. !arbiter [flags]
  1581. flags 1 - I/O port arbiters
  1582. 2 - memory arbiters
  1583. 4 - IRQ arbiters
  1584. 8 - DMA arbiters
  1585. If no flags are specified, all arbiters are dumped.
  1586. Arguments:
  1587. args - optional flags specifying which arbiters to dump
  1588. Return Value:
  1589. None
  1590. --*/
  1591. {
  1592. DWORD Flags=0;
  1593. ULONG64 addr;
  1594. ULONG64 deviceNode;
  1595. Flags = (ULONG) GetExpression(args);
  1596. if (Flags == 0) {
  1597. Flags = ARBITER_DUMP_ALL;
  1598. } else if (Flags == ARBITER_NO_DUMP_ALIASES) {
  1599. Flags = ARBITER_NO_DUMP_ALIASES + ARBITER_DUMP_ALL;
  1600. }
  1601. //
  1602. // Find the root devnode and dump its arbiters
  1603. //
  1604. addr = GetExpression( "nt!IopRootDeviceNode" );
  1605. if (addr == 0) {
  1606. dprintf("Error retrieving address of IopRootDeviceNode\n");
  1607. return E_INVALIDARG;
  1608. }
  1609. if (!ReadPointer(addr, &deviceNode)) {
  1610. dprintf("Error reading value of IopRootDeviceNode (%#010p)\n", addr);
  1611. return E_INVALIDARG;
  1612. }
  1613. DumpArbitersForDevNode(0, deviceNode, Flags);
  1614. return S_OK;
  1615. }
  1616. BOOLEAN
  1617. DumpArbitersForDevNode(
  1618. IN DWORD Depth,
  1619. IN ULONG64 DevNodeAddr,
  1620. IN DWORD Flags
  1621. )
  1622. /*++
  1623. Routine Description:
  1624. Dumps all the arbiters for the specified devnode. Recursively calls
  1625. itself on the specified devnode's children.
  1626. Arguments:
  1627. Depth - Supplies the print depth.
  1628. DevNodeAddr - Supplies the address of the devnode.
  1629. Flags - Supplies the type of arbiters to dump:
  1630. ARBITER_DUMP_IO
  1631. ARBITER_DUMP_MEMORY
  1632. ARBITER_DUMP_IRQ
  1633. ARBITER_DUMP_DMA
  1634. Return Value:
  1635. None
  1636. --*/
  1637. {
  1638. ULONG result;
  1639. ULONG64 NextArbiter, startAddress;
  1640. ULONG64 ArbiterAddr;
  1641. BOOLEAN PrintedHeader = FALSE;
  1642. BOOLEAN continueDump = TRUE;
  1643. UCHAR devNodeType[] = "nt!_DEVICE_NODE";
  1644. ULONG DevArbOffset, DevNodeOffset;
  1645. ULONG64 DeviceArbiterList_Flink=0, InstancePath_Buffer=0, Child=0, Sibling=0;
  1646. UNICODE_STRING64 InstancePath;
  1647. // Get offset for listing
  1648. if (GetFieldOffset("nt!_PI_RESOURCE_ARBITER_ENTRY", "DeviceArbiterList.Flink", &DevArbOffset)) {
  1649. return TRUE;
  1650. }
  1651. if (GetFieldValue(DevNodeAddr, devNodeType, "DeviceArbiterList.Flink", DeviceArbiterList_Flink)) {
  1652. xdprintf(Depth, ""); dprintf("%08p: Could not read device node\n", DevNodeAddr);
  1653. return TRUE;
  1654. }
  1655. GetFieldOffset("nt!_DEVICE_NODE", "DeviceArbiterList.Flink", &DevNodeOffset);
  1656. GetFieldValue(DevNodeAddr, devNodeType, "Child", Child);
  1657. GetFieldValue(DevNodeAddr, devNodeType, "Sibling", Sibling);
  1658. GetFieldValue(DevNodeAddr, devNodeType, "InstancePath.Buffer", InstancePath.Buffer);
  1659. GetFieldValue(DevNodeAddr, devNodeType, "InstancePath.Length", InstancePath.Length);
  1660. GetFieldValue(DevNodeAddr, devNodeType, "InstancePath.MaximumLength", InstancePath.MaximumLength);
  1661. //
  1662. // Dump the list of arbiters
  1663. //
  1664. startAddress = DevNodeAddr + DevNodeOffset;
  1665. NextArbiter = DeviceArbiterList_Flink;
  1666. while (NextArbiter != startAddress) {
  1667. ULONG ResourceType=0;
  1668. if (CheckControlC()) {
  1669. return FALSE;
  1670. }
  1671. ArbiterAddr = NextArbiter - DevArbOffset;
  1672. // CONTAINING_RECORD(NextArbiter, PI_RESOURCE_ARBITER_ENTRY, DeviceArbiterList);
  1673. if (GetFieldValue(ArbiterAddr, "nt!_PI_RESOURCE_ARBITER_ENTRY", "ResourceType", ResourceType)) {
  1674. xdprintf(Depth, "Could not read arbiter entry ");
  1675. dprintf("%08p for devnode %08p\n", ArbiterAddr, DevNodeAddr);
  1676. break;
  1677. }
  1678. if (((ResourceType == CmResourceTypePort) && (Flags & ARBITER_DUMP_IO)) ||
  1679. ((ResourceType == CmResourceTypeInterrupt) && (Flags & ARBITER_DUMP_IRQ)) ||
  1680. ((ResourceType == CmResourceTypeMemory) && (Flags & ARBITER_DUMP_MEMORY)) ||
  1681. ((ResourceType == CmResourceTypeDma) && (Flags & ARBITER_DUMP_DMA)) ||
  1682. ((ResourceType == CmResourceTypeBusNumber) && (Flags & ARBITER_DUMP_BUS_NUMBER))) {
  1683. if (!PrintedHeader) {
  1684. dprintf("\n");
  1685. xdprintf(Depth, ""); dprintf("DEVNODE %08p ", DevNodeAddr);
  1686. if (InstancePath.Buffer != 0) {
  1687. dprintf("(");
  1688. DumpUnicode64(InstancePath);
  1689. dprintf(")");
  1690. }
  1691. dprintf("\n");
  1692. PrintedHeader = TRUE;
  1693. }
  1694. continueDump = DumpArbiter( Depth+1,
  1695. ArbiterAddr,
  1696. // &ArbiterEntry,
  1697. (BOOLEAN)!(Flags & ARBITER_NO_DUMP_ALIASES)
  1698. );
  1699. if (!continueDump) {
  1700. break;
  1701. }
  1702. }
  1703. GetFieldValue(ArbiterAddr, "nt!_PI_RESOURCE_ARBITER_ENTRY", "DeviceArbiterList.Flink", NextArbiter);
  1704. }
  1705. //
  1706. // Dump this devnode's children (if any)
  1707. //
  1708. if (continueDump && Child) {
  1709. continueDump = DumpArbitersForDevNode( Depth + 1, Child, Flags);
  1710. }
  1711. //
  1712. // Dump this devnode's siblings (if any)
  1713. //
  1714. if (continueDump && Sibling) {
  1715. continueDump = DumpArbitersForDevNode( Depth, Sibling, Flags);
  1716. }
  1717. return continueDump;
  1718. }
  1719. BOOLEAN
  1720. DumpArbiter(
  1721. IN DWORD Depth,
  1722. IN ULONG64 ArbiterAddr,
  1723. IN BOOLEAN DisplayAliases
  1724. )
  1725. /*++
  1726. Routine Description:
  1727. Dumps out the specified arbiter.
  1728. Arguments:
  1729. Depth - Supplies the print depth.
  1730. ArbiterAddr - Supplies the original address of the arbiter (on the target)
  1731. Arbiter - Supplies the arbiter
  1732. Return Value:
  1733. None.
  1734. --*/
  1735. {
  1736. ULONG64 PciInstance;
  1737. ULONG64 InstanceAddr;
  1738. BOOL IsPciArbiter = FALSE;
  1739. WCHAR NameBuffer[64];
  1740. BOOLEAN continueDump = TRUE;
  1741. UCHAR ArbiterTyp[] = "nt!_PI_RESOURCE_ARBITER_ENTRY";
  1742. UCHAR ArbIntfTyp[] = "nt!_ARBITER_INTERFACE";
  1743. ULONG64 ArbiterInterface=0, Context=0, NamePtr=0, ResourceType=0;
  1744. ULONG ListHeadOff;
  1745. //
  1746. // First obtain the ARBITER_INTERFACE.
  1747. //
  1748. if (GetFieldValue(ArbiterAddr, ArbiterTyp, "ArbiterInterface", ArbiterInterface)) {
  1749. dprintf("Error reading ArbiterInterface %08p for ArbiterEntry at %08p\n",
  1750. ArbiterInterface,
  1751. ArbiterAddr);
  1752. return continueDump;
  1753. }
  1754. if (!ArbiterInterface ||
  1755. GetFieldValue(ArbiterInterface, ArbIntfTyp, "Context", Context)) {
  1756. dprintf("Error reading ArbiterInterface %08p for ArbiterEntry at %08p\n",
  1757. ArbiterInterface,
  1758. ArbiterAddr);
  1759. return continueDump;
  1760. }
  1761. //
  1762. // Now that we have the ARBITER_INTERFACE we need to get the ARBITER_INSTANCE.
  1763. // This is not as easy as it should be since PeterJ is paranoid and encrypts the
  1764. // pointer to it. Luckily, we know his secret encryption method and can decrypt it.
  1765. // First we have to figure out if this is PCI's arbiter. Quick hack check is to see
  1766. // if the low bit is set.
  1767. //
  1768. if (Context & 1) {
  1769. ULONG Offset;
  1770. GetFieldOffset("nt!_PCI_ARBITER_INSTANCE", "CommonInstance", &Offset);
  1771. IsPciArbiter = TRUE;
  1772. PciInstance = (Context ^ PciFdoExtensionType);
  1773. InstanceAddr = PciInstance + Offset;
  1774. } else {
  1775. //
  1776. // We will assume that the context is just a pointer to an ARBITER_INSTANCE structure
  1777. //
  1778. InstanceAddr = Context;
  1779. }
  1780. //
  1781. // Read the instance
  1782. //
  1783. if (GetFieldValue(InstanceAddr, "nt!_ARBITER_INSTANCE", "Name", NamePtr)) {
  1784. dprintf("Error reading ArbiterInstance %08p for ArbiterInterface at %08p\n",
  1785. InstanceAddr,
  1786. ArbiterInterface);
  1787. return continueDump;
  1788. }
  1789. GetFieldValue(InstanceAddr, "nt!_ARBITER_INSTANCE", "ResourceType", ResourceType);
  1790. xdprintf(Depth,
  1791. "%s Arbiter \"",
  1792. GetCmResourceTypeString((UCHAR)ResourceType));
  1793. if (NamePtr != 0) {
  1794. ULONG result;
  1795. if (ReadMemory(NamePtr,NameBuffer,sizeof(NameBuffer),&result)) {
  1796. NameBuffer[sizeof(NameBuffer)/sizeof(WCHAR) - 1] = 0;
  1797. dprintf("%ws",NameBuffer);
  1798. }
  1799. }
  1800. dprintf("\" at %08p\n",InstanceAddr);
  1801. xdprintf(Depth+1,"Allocated ranges:\n");
  1802. GetFieldOffset("nt!_RTL_RANGE_LIST", "ListHead", &ListHeadOff);
  1803. InitTypeRead(InstanceAddr, nt!_ARBITER_INSTANCE);
  1804. continueDump = DumpRangeList( Depth+2,
  1805. ReadField(Allocation) + ListHeadOff,
  1806. FALSE,
  1807. TRUE,
  1808. DisplayAliases,
  1809. NULL);
  1810. if (continueDump) {
  1811. InitTypeRead(InstanceAddr, nt!_ARBITER_INSTANCE);
  1812. xdprintf(Depth+1,"Possible allocation:\n");
  1813. continueDump = DumpRangeList(Depth+2, ReadField(PossibleAllocation) + ListHeadOff,
  1814. FALSE, TRUE, DisplayAliases, NULL);
  1815. }
  1816. return continueDump;
  1817. }
  1818. VOID
  1819. DumpRangeEntry(
  1820. IN DWORD Depth,
  1821. IN ULONG64 RangeEntry,
  1822. IN BOOLEAN OwnerIsDevObj,
  1823. IN BOOLEAN DisplayAliases,
  1824. IN pUserDataInterpretationFunction PrintUserData OPTIONAL
  1825. )
  1826. /*++
  1827. Routine Description:
  1828. Dumps out the specified RTLP_RANGE_LIST_ENTRY
  1829. Arguments:
  1830. Depth - Supplies the print depth.
  1831. RangeList - Supplies the address of the RTLP_RANGE_LIST_ENTRY
  1832. OwnerIsDevObj - Indicates that the owner field is a pointer to a DEVICE_OBJECT
  1833. Return Value:
  1834. None.
  1835. --*/
  1836. {
  1837. ULONG PrivateFlags=0, Attributes=0, PublicFlags=0;
  1838. ULONG64 Owner=0, Start=0, End=0, UserData=0;
  1839. if (GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "PrivateFlags", PrivateFlags)) {
  1840. dprintf("Cannot find _RTLP_RANGE_LIST_ENTRY type.\n");
  1841. return ;
  1842. }
  1843. // dprintf("Range Entry %p\n", RangeEntry);
  1844. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "Attributes", Attributes);
  1845. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "Start", Start);
  1846. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "End", End);
  1847. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "PublicFlags", PublicFlags);
  1848. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "Allocated.Owner", Owner);
  1849. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "Allocated.UserData", UserData);
  1850. if (!(PrivateFlags & RTLP_RANGE_LIST_ENTRY_MERGED)) {
  1851. ULONG64 DeviceObjectExtension=0, DeviceNode=0;
  1852. if ((Attributes & ARBITER_RANGE_ALIAS) && !DisplayAliases) {
  1853. return;
  1854. }
  1855. if (OwnerIsDevObj && Owner) {
  1856. if (GetFieldValue(Owner, "nt!_DEVICE_OBJECT", "DeviceObjectExtension", DeviceObjectExtension)) {
  1857. dprintf("Error reading DeviceObject %08p\n",
  1858. Owner
  1859. );
  1860. return;
  1861. }
  1862. if (GetFieldValue(DeviceObjectExtension, "nt!_DEVOBJ_EXTENSION", "DeviceNode", DeviceNode)) {
  1863. dprintf("Error reading DeviceObjectExtension %08p\n",
  1864. DeviceObjectExtension
  1865. );
  1866. return;
  1867. }
  1868. }
  1869. xdprintf(Depth,
  1870. "%016I64x - %016I64x %c%c%c%c%c",
  1871. Start,
  1872. End,
  1873. PublicFlags & RTL_RANGE_SHARED ? 'S' : ' ',
  1874. PublicFlags & RTL_RANGE_CONFLICT ? 'C' : ' ',
  1875. (Attributes & ARBITER_RANGE_BOOT_ALLOCATED)? 'B' : (Attributes & ARBITER_RANGE_SHARE_DRIVER_EXCLUSIVE)? 'D' : ' ',
  1876. Attributes & ARBITER_RANGE_ALIAS ? 'A' : ' ',
  1877. Attributes & ARBITER_RANGE_POSITIVE_DECODE ? 'P' : ' ');
  1878. dprintf(" %08p ",Owner);
  1879. if (Owner) {
  1880. UNICODE_STRING64 ServiceName;
  1881. GetFieldValue(DeviceNode, "nt!_DEVICE_NODE", "ServiceName.Buffer", ServiceName.Buffer);
  1882. if (OwnerIsDevObj && ServiceName.Buffer) {
  1883. GetFieldValue(DeviceNode, "nt!_DEVICE_NODE", "ServiceName.Length", ServiceName.Length);
  1884. GetFieldValue(DeviceNode, "nt!_DEVICE_NODE", "ServiceName.MaximumLength", ServiceName.MaximumLength);
  1885. dprintf(" (");
  1886. DumpUnicode64(ServiceName);
  1887. dprintf(")");
  1888. }
  1889. } else {
  1890. dprintf("<Not on bus>");
  1891. }
  1892. if (PrintUserData) {
  1893. PrintUserData(UserData);
  1894. }
  1895. } else {
  1896. xdprintf(Depth,
  1897. "%016I64x - %016I64x %c%c ",
  1898. Start,
  1899. End,
  1900. PublicFlags & RTL_RANGE_SHARED ? 'S' : ' ',
  1901. PublicFlags & RTL_RANGE_CONFLICT ? 'C' : ' '
  1902. );
  1903. }
  1904. dprintf("\n");
  1905. }
  1906. BOOLEAN
  1907. DumpRangeList(
  1908. IN DWORD Depth,
  1909. IN ULONG64 RangeListHead,
  1910. IN BOOLEAN IsMerged,
  1911. IN BOOLEAN OwnerIsDevObj,
  1912. IN BOOLEAN DisplayAliases,
  1913. IN pUserDataInterpretationFunction PrintUserData OPTIONAL
  1914. )
  1915. /*++
  1916. Routine Description:
  1917. Dumps out the specified RTL_RANGE_LIST
  1918. Arguments:
  1919. Depth - Supplies the print depth.
  1920. RangeListHead - Supplies the address of the LIST_ENTRY containing the RTLP_RANGE_LIST_ENTRYs
  1921. IsMerged - Indicates whether this list is in a merged range
  1922. OwnerIsDevObj - Indicates that the owner field is a pointer to a DEVICE_OBJECT
  1923. Return Value:
  1924. None.
  1925. --*/
  1926. {
  1927. ULONG64 ListEntry, EntryAddr;
  1928. ULONG ListEntryOffset, ListHeadOffset;
  1929. BOOLEAN continueDump = TRUE;
  1930. GetFieldOffset("nt!_RTLP_RANGE_LIST_ENTRY", "ListEntry", &ListEntryOffset);
  1931. GetFieldOffset("nt!_RTLP_RANGE_LIST_ENTRY", "Merged.ListHead", &ListHeadOffset);
  1932. //
  1933. // Read the range list
  1934. //
  1935. if (GetFieldValue(RangeListHead, "nt!_LIST_ENTRY", "Flink", ListEntry)) {
  1936. dprintf("Error reading RangeList %08p\n", RangeListHead);
  1937. return TRUE;
  1938. }
  1939. if (ListEntry == RangeListHead) {
  1940. xdprintf(Depth, "< none >\n");
  1941. return TRUE;
  1942. }
  1943. while (ListEntry != RangeListHead) {
  1944. ULONG PrivateFlags=0;
  1945. ULONG64 ListHeadAddr=0;
  1946. if (CheckControlC()) {
  1947. continueDump = FALSE;
  1948. break;
  1949. }
  1950. EntryAddr = ListEntry - ListEntryOffset;
  1951. if (GetFieldValue(EntryAddr, "nt!_RTLP_RANGE_LIST_ENTRY", "PrivateFlags", PrivateFlags)) {
  1952. dprintf("Error reading RangeEntry %08p from RangeList %08p\n",
  1953. EntryAddr,
  1954. RangeListHead);
  1955. return TRUE;
  1956. }
  1957. if (PrivateFlags & RTLP_RANGE_LIST_ENTRY_MERGED) {
  1958. //
  1959. // This is a merged range list, call ourselves recursively
  1960. //
  1961. DumpRangeEntry(Depth, EntryAddr, FALSE, DisplayAliases, PrintUserData);
  1962. continueDump = DumpRangeList(Depth + 1, EntryAddr + ListHeadOffset, TRUE, TRUE, DisplayAliases, PrintUserData);
  1963. if (!continueDump) {
  1964. break;
  1965. }
  1966. } else {
  1967. DumpRangeEntry(Depth, EntryAddr, OwnerIsDevObj, DisplayAliases, PrintUserData);
  1968. }
  1969. GetFieldValue(EntryAddr, "nt!_RTLP_RANGE_LIST_ENTRY", "ListEntry.Flink", ListEntry);
  1970. }
  1971. return continueDump;
  1972. }
  1973. DECLARE_API( range )
  1974. /*++
  1975. Routine Description:
  1976. Dumps an RTL_RANGE_LIST
  1977. Arguments:
  1978. args - specifies the address of the RTL_RANGE_LIST
  1979. Return Value:
  1980. None
  1981. --*/
  1982. {
  1983. ULONG ListHeadOffset;
  1984. BOOLEAN continueDump = TRUE;
  1985. ULONG64 RangeList;
  1986. if (GetFieldOffset("nt!_RTL_RANGE_LIST", "ListHead", &ListHeadOffset)) {
  1987. dprintf("Cannot find _RTL_RANGE_LIST type.\n");
  1988. return E_INVALIDARG;
  1989. }
  1990. RangeList = GetExpression(args);
  1991. DumpRangeList(0, RangeList + ListHeadOffset, FALSE, FALSE, TRUE, NULL);
  1992. return S_OK;
  1993. }
  1994. ULONG
  1995. DumpArbList(
  1996. PFIELD_INFO ListElement,
  1997. PVOID Context
  1998. )
  1999. {
  2000. UCHAR andOr = ' ';
  2001. ULONG resourceType = 0xffffffff;
  2002. ULONG remaining;
  2003. PULONG data;
  2004. PCHAR headingDefault = " Owner Data";
  2005. PCHAR formatDefault = "%c %s %c %08x %08x %08x %08x %08x %08x\n";
  2006. PCHAR headingMemIo = " Owner Length Alignment Minimum Address - Maximum Address\n";
  2007. PCHAR formatMemIo = "%c %s %c %8x %8x %08x%08x - %08x%08x\n";
  2008. PCHAR headingIrqDma = " Owner Minimum - Maximum\n";
  2009. PCHAR formatIrqDma = "%c %s %c %8x - %-8x\n";
  2010. PCHAR heading = headingDefault;
  2011. PCHAR format = formatDefault;
  2012. CHAR shared;
  2013. CHAR ownerBuffer[20];
  2014. PCHAR ownerBlank = " ";
  2015. PCHAR ownerText = ownerBlank;
  2016. ULONG64 pcurrent=ListElement->address;
  2017. ULONG64 palternative;
  2018. static ULONG64 previousOwner = 0;
  2019. BOOLEAN doHeading = TRUE;
  2020. BOOLEAN verbose = FALSE;
  2021. ULONG Flag = *((PULONG) Context);
  2022. ULONG AlternativeCount=0, resDescSize;
  2023. ULONG64 PhysicalDeviceObject, Alternatives;
  2024. ULONG Flags=0, InterfaceType=0, RequestSource=0;
  2025. //
  2026. // Check if user wants out.
  2027. //
  2028. if (CheckControlC()) {
  2029. dprintf("User terminated with <control>C\n");
  2030. return TRUE;
  2031. }
  2032. if ((LONG64)pcurrent >= 0) {
  2033. dprintf("List broken, forward entry is not a valid kernel address.\n");
  2034. return TRUE;
  2035. }
  2036. if (Flag & 1) {
  2037. verbose = TRUE;
  2038. }
  2039. //
  2040. // Get the arbitration list entry from host memory.
  2041. //
  2042. if (GetFieldValue(pcurrent, "nt!_ARBITER_LIST_ENTRY", "PhysicalDeviceObject", PhysicalDeviceObject)) {
  2043. dprintf("Couldn't read _ARBITER_LIST_ENTRY at %p\n", pcurrent);
  2044. return TRUE;
  2045. }
  2046. //
  2047. // Check if we've changed device objects.
  2048. //
  2049. if (previousOwner != PhysicalDeviceObject) {
  2050. previousOwner = PhysicalDeviceObject;
  2051. sprintf(ownerBuffer, "%08I64lx", previousOwner);
  2052. ownerText = ownerBuffer;
  2053. andOr = ' ';
  2054. if (verbose) {
  2055. doHeading = TRUE;
  2056. }
  2057. }
  2058. //
  2059. // Run the alternatives for this device object.
  2060. //
  2061. GetFieldValue(pcurrent, "nt!_ARBITER_LIST_ENTRY", "AlternativeCount", AlternativeCount);
  2062. GetFieldValue(pcurrent, "nt!_ARBITER_LIST_ENTRY", "Alternatives", Alternatives);
  2063. GetFieldValue(pcurrent, "nt!_ARBITER_LIST_ENTRY", "Flags", Flags);
  2064. GetFieldValue(pcurrent, "nt!_ARBITER_LIST_ENTRY", "InterfaceType", InterfaceType);
  2065. GetFieldValue(pcurrent, "nt!_ARBITER_LIST_ENTRY", "RequestSource", RequestSource);
  2066. resDescSize = GetTypeSize("nt!_IO_RESOURCE_DESCRIPTOR");
  2067. for (remaining = AlternativeCount, palternative = Alternatives;
  2068. remaining;
  2069. remaining--, palternative+=resDescSize) {
  2070. ULONG Type=0, ShareDisposition=0, Gen_Length=0, Gen_Alignment=0;
  2071. ULONG Gen_Min_Low, Gen_Min_Hi=0, Gen_Max_Low=0, Gen_Max_Hi=0;
  2072. ULONG Int_Min=0, Int_Max=0, DevData[6]={0};
  2073. //
  2074. // Check if user wants out.
  2075. //
  2076. if (CheckControlC()) {
  2077. dprintf("User terminated with <control>C\n");
  2078. return TRUE;
  2079. }
  2080. //
  2081. // Read this resource descriptor from memory. (An optimization
  2082. // would be to read the entire array or to buffer it).
  2083. //
  2084. if (GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "Type", Type)){
  2085. dprintf("Couldn't read IO_RESOURCE_DESCRIPTOR at %08p, quitting.\n",
  2086. palternative
  2087. );
  2088. return TRUE;
  2089. }
  2090. if (Type != resourceType) {
  2091. if (resourceType == 0xffffffff) {
  2092. //
  2093. // Go look at the first alternative to figure out what
  2094. // resource type is being arbitrated.
  2095. //
  2096. resourceType = Type;
  2097. switch (resourceType) {
  2098. case CmResourceTypeNull:
  2099. dprintf("Arbitration list resource type is NULL. Seems odd.\n");
  2100. break;
  2101. case CmResourceTypePort:
  2102. dprintf("Arbitrating CmResourceTypePort resources\n");
  2103. format = formatMemIo;
  2104. heading = headingMemIo;
  2105. break;
  2106. case CmResourceTypeInterrupt:
  2107. dprintf("Arbitrating CmResourceTypeInterrupt resources\n");
  2108. format = formatIrqDma;
  2109. heading = headingIrqDma;
  2110. break;
  2111. case CmResourceTypeMemory:
  2112. dprintf("Arbitrating CmResourceTypeMemory resources\n");
  2113. format = formatMemIo;
  2114. heading = headingMemIo;
  2115. break;
  2116. case CmResourceTypeDma:
  2117. dprintf("Arbitrating CmResourceTypeDma resources\n");
  2118. format = formatIrqDma;
  2119. heading = headingIrqDma;
  2120. break;
  2121. default:
  2122. dprintf("Arbitrating resource type 0x%x\n", Type);
  2123. }
  2124. } else {
  2125. dprintf("error: Resource Type change, arbiters don't do multiple\n");
  2126. dprintf("types. Resource Type was 0x%x, new type 0x%x, quitting.\n",
  2127. resourceType, Type);
  2128. return TRUE;
  2129. }
  2130. }
  2131. if (doHeading) {
  2132. if (verbose) {
  2133. dprintf("Owning object %08p, Flags 0x%x, Interface 0x%x, Source 0x%x\n",
  2134. PhysicalDeviceObject,
  2135. Flags,
  2136. InterfaceType,
  2137. RequestSource
  2138. );
  2139. }
  2140. dprintf(heading);
  2141. doHeading = FALSE;
  2142. }
  2143. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "ShareDisposition", ShareDisposition);
  2144. shared = ShareDisposition == CmResourceShareShared ? 'S' : ' ';
  2145. switch (resourceType) {
  2146. case CmResourceTypePort:
  2147. case CmResourceTypeMemory:
  2148. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Generic.Length", Gen_Length);
  2149. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Generic.Alignment", Gen_Alignment);
  2150. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Generic.MinimumAddress.HighPart", Gen_Min_Hi);
  2151. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Generic.MinimumAddress.LowPart", Gen_Min_Low);
  2152. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Generic.MaximumAddress.HighPart", Gen_Max_Hi);
  2153. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Generic.MaximumAddress.LowPart", Gen_Max_Low );
  2154. dprintf(format,
  2155. andOr,
  2156. ownerText,
  2157. shared,
  2158. Gen_Length,
  2159. Gen_Alignment,
  2160. Gen_Min_Hi,
  2161. Gen_Min_Low,
  2162. Gen_Max_Hi,
  2163. Gen_Max_Low
  2164. );
  2165. break;
  2166. case CmResourceTypeInterrupt:
  2167. case CmResourceTypeDma:
  2168. //
  2169. // Dma and Interrupt are same format,... overload.
  2170. //
  2171. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Interrupt.MinimumVector", Int_Min);
  2172. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.Interrupt.MaximumVector", Int_Max);
  2173. dprintf(format,
  2174. andOr,
  2175. ownerText,
  2176. shared,
  2177. Int_Min,
  2178. Int_Max
  2179. );
  2180. break;
  2181. default:
  2182. GetFieldValue(palternative, "nt!_IO_RESOURCE_DESCRIPTOR", "u.DevicePrivate.Data", DevData);
  2183. data = DevData;
  2184. dprintf(format,
  2185. andOr,
  2186. ownerText,
  2187. shared,
  2188. *data,
  2189. *(data + 0),
  2190. *(data + 1),
  2191. *(data + 2),
  2192. *(data + 3),
  2193. *(data + 4),
  2194. *(data + 5)
  2195. );
  2196. break;
  2197. }
  2198. ownerText = ownerBlank;
  2199. andOr = '|';
  2200. }
  2201. if (AlternativeCount == 0) {
  2202. //
  2203. // Get here if the alternatives list was empty.
  2204. //
  2205. if (doHeading) {
  2206. dprintf("Owning object %08p, Flags 0x%x, Interface 0x%x\n",
  2207. PhysicalDeviceObject,
  2208. Flags,
  2209. InterfaceType
  2210. );
  2211. }
  2212. dprintf("Arbiter list entry (@%08p) has 0 resources. Seems odd.\n",
  2213. pcurrent
  2214. );
  2215. }
  2216. andOr = '&';
  2217. return FALSE; // Continue dumping the list
  2218. }
  2219. DECLARE_API( arblist )
  2220. /*++
  2221. Routine Description:
  2222. Dumps an arbitration list (2nd parameter to PnpTestAllocation).
  2223. !arblist address
  2224. If no address specified we try to tell you what to do.
  2225. Arguments:
  2226. address of the arbitration list.
  2227. Return Value:
  2228. None
  2229. --*/
  2230. {
  2231. ULONG64 ArbitrationList = 0;
  2232. ULONG Flags = 0;
  2233. ULONG64 pcurrent;
  2234. ULONG64 palternative;
  2235. ULONG64 KModeCheck;
  2236. BOOL Ptr64 = IsPtr64();
  2237. if (GetExpressionEx(args, &ArbitrationList, &args)) {
  2238. Flags = (ULONG) GetExpression(args);
  2239. }
  2240. if (ArbitrationList == 0) {
  2241. dprintf("!arblist <address> [flags]\n");
  2242. dprintf(" <address> is the address of an arbitration list.\n");
  2243. dprintf(" [flags] Bitmask used to adjust what is printed.\n");
  2244. dprintf(" 0001 Include interface, flags and source for each device\n");
  2245. dprintf("\n");
  2246. dprintf(" Prints out an arbitration list. An arbitration list\n");
  2247. dprintf(" is the set of resources for which arbitration is\n");
  2248. dprintf(" needed. (eg second parameter to PnpTestAllocation).\n");
  2249. return E_INVALIDARG;
  2250. }
  2251. if (Ptr64) {
  2252. KModeCheck = 0x8000000000000000L;
  2253. } else {
  2254. KModeCheck = 0xffffffff80000000L;
  2255. }
  2256. //
  2257. // The argument is a pointer to a list head.
  2258. //
  2259. if (!((LONG64)ArbitrationList & KModeCheck)) {
  2260. dprintf("The arbitration list pointer must be a kernel mode address.\n");
  2261. return E_INVALIDARG;
  2262. }
  2263. if (GetFieldValue(ArbitrationList, "nt!_LIST_ENTRY", "Flink", pcurrent)) {
  2264. dprintf("error reading arbitration list ListHead, cannot continue.\n");
  2265. return E_INVALIDARG;
  2266. }
  2267. //
  2268. // A little validation.
  2269. //
  2270. if (!(pcurrent & KModeCheck)) {
  2271. dprintf("%08p does not point to a valid list head.\n", ArbitrationList);
  2272. return E_INVALIDARG;
  2273. }
  2274. if (pcurrent == ArbitrationList) {
  2275. dprintf("%08p points to an empty list.\n", ArbitrationList);
  2276. return E_INVALIDARG;
  2277. }
  2278. //
  2279. // Run the list.
  2280. //
  2281. ListType("_ARBITER_LIST_ENTRY", pcurrent, TRUE, "ListEntry.Flink", (PVOID) &Flags, DumpArbList);
  2282. return S_OK;
  2283. }
  2284. ULONG
  2285. TokenizeString(
  2286. PUCHAR Input,
  2287. PUCHAR *Output,
  2288. ULONG Max
  2289. )
  2290. /*++
  2291. Routine Description:
  2292. Convert an input string of white space delimited tokens into
  2293. an array of strings. The routine will produce an array of
  2294. pointers to strings where the (maximum) size of the array is
  2295. given by Max. Note, if Max is too small to fully tokenize the
  2296. string, the last element of the array will point to the remainder
  2297. of the string.
  2298. Arguments:
  2299. Input Input string
  2300. Output Pointer to an array which will be filled in with
  2301. pointers to each new token.
  2302. Max Maximum number of strings.
  2303. Return Value:
  2304. Number of tokens found.
  2305. --*/
  2306. {
  2307. ULONG count = 0;
  2308. PUCHAR tok;
  2309. BOOLEAN inToken = FALSE;
  2310. UCHAR c;
  2311. if (Max == 0) {
  2312. return 0;
  2313. }
  2314. while ((c = *Input++) != '\0') {
  2315. if (isspace(c)) {
  2316. if (!inToken) {
  2317. //
  2318. // Continue skipping characters.
  2319. //
  2320. continue;
  2321. }
  2322. //
  2323. // Found end of Token, delimit it and change state.
  2324. //
  2325. inToken = FALSE;
  2326. *(Input - 1) = '\0';
  2327. } else {
  2328. //
  2329. // Non-blank character.
  2330. //
  2331. if (inToken) {
  2332. //
  2333. // Continue search for end of token.
  2334. //
  2335. continue;
  2336. }
  2337. //
  2338. // New Token.
  2339. //
  2340. inToken = TRUE;
  2341. *Output++ = Input - 1;
  2342. count++;
  2343. if (count == Max) {
  2344. //
  2345. // We can't find any more so return what we still
  2346. // have as the last thing.
  2347. //
  2348. return count;
  2349. }
  2350. }
  2351. }
  2352. return count;
  2353. }
  2354. //
  2355. // DevExtPCI
  2356. //
  2357. // Data structures and functions to implement !devext pci.
  2358. //
  2359. PUCHAR DevExtPciDeviceState[] = {
  2360. "PciNotStarted",
  2361. "PciStarted",
  2362. "PciDeleted",
  2363. "PciStopped",
  2364. "PciSurpriseRemoved",
  2365. "PciSynchronizedOperation"
  2366. };
  2367. PUCHAR DevExtPciSystemPowerState[] = {
  2368. "Unspecified",
  2369. "Working",
  2370. "Sleeping1",
  2371. "Sleeping2",
  2372. "Sleeping3",
  2373. "Hibernate",
  2374. "Shutdown"
  2375. };
  2376. PUCHAR DevExtPciDevicePowerState[] = {
  2377. "Unspecified",
  2378. "D0",
  2379. "D1",
  2380. "D2",
  2381. "D3"
  2382. };
  2383. struct {
  2384. USHORT VendorId;
  2385. PUCHAR VendorName;
  2386. } DevExtPciVendors[] = {
  2387. { 0x003D, "LOCKHEED MARTIN"},
  2388. { 0x0E11, "COMPAQ"},
  2389. { 0x1002, "ATI TECHNOLOGIES INC"},
  2390. { 0x1003, "ULSI SYSTEMS"},
  2391. { 0x1004, "VLSI TECHNOLOGY INC"},
  2392. { 0x1006, "REPLY GROUP"},
  2393. { 0x1007, "NETFRAME SYSTEMS INC"},
  2394. { 0x1008, "EPSON"},
  2395. { 0x100A, "PHOENIX TECHNOLOGIES"},
  2396. { 0x100B, "NATIONAL SEMICONDUCTOR CORPORATION"},
  2397. { 0x100C, "TSENG LABS INC"},
  2398. { 0x100D, "AST RESEARCH INC"},
  2399. { 0x1010, "VIDEO LOGIC LTD"},
  2400. { 0x1011, "DIGITAL EQUIPMENT CORPORATION"},
  2401. { 0x1012, "MICRONICS COMPUTERS INC"},
  2402. { 0x1013, "CIRRUS LOGIC"},
  2403. { 0x1014, "IBM"},
  2404. { 0x1015, "LSI LOGIC CORP OF CANADA"},
  2405. { 0x1016, "ICL PERSONAL SYSTEMS"},
  2406. { 0x1017, "SPEA SOFTWARE AG"},
  2407. { 0x1018, "UNISYS SYSTEMS"},
  2408. { 0x1019, "ELITEGROUP COMPUTER SYS"},
  2409. { 0x101A, "NCR"},
  2410. { 0x101C, "WESTERN DIGITAL"},
  2411. { 0x101E, "AMERICAN MEGATRENDS"},
  2412. { 0x101F, "PICTURETEL"},
  2413. { 0x1021, "OKI ELECTRIC INDUSTRY"},
  2414. { 0x1022, "ADVANCED MICRO DEVICES"},
  2415. { 0x1023, "TRIDENT MICROSYSTEMS"},
  2416. { 0x1025, "ACER INCORPORATED"},
  2417. { 0x1028, "DELL COMPUTER CORPORATION"},
  2418. { 0x102B, "MATROX"},
  2419. { 0x102C, "CHIPS AND TECHNOLOGIES"},
  2420. { 0x102E, "OLIVETTI ADVANCED TECHNOLOGY"},
  2421. { 0x102F, "TOSHIBA AMERICA ELECT."},
  2422. { 0x1030, "TMC RESEARCH"},
  2423. { 0x1031, "MIRO COMPUTER PRODUCTS AG"},
  2424. { 0x1033, "NEC CORPORATION"},
  2425. { 0x1033, "NEC CORPORATION"},
  2426. { 0x1034, "BURNDY CORPORATION"},
  2427. { 0x1035, "COMP.&COMM. RESH. LAB"},
  2428. { 0x1036, "FUTURE DOMAIN"},
  2429. { 0x1037, "HITACHI MICRO SYSTEMS"},
  2430. { 0x1038, "AMP, INC"},
  2431. { 0x1039, "SILICON INTEGRATED SYSTEM"},
  2432. { 0x103A, "SEIKO EPSON CORPORATION"},
  2433. { 0x103B, "TATUNG CO. OF AMERICA"},
  2434. { 0x103C, "HEWLETT PACKARD"},
  2435. { 0x103E, "SOLLIDAY ENGINEERING"},
  2436. { 0x103F, "SYNOPSYS INC."},
  2437. { 0x1040, "ACCELGRAPHICS INC."},
  2438. { 0x1042, "PC TECHNOLOGY INC"},
  2439. { 0x1043, "ASUSTEK COMPUTER, INC."},
  2440. { 0x1044, "DISTRIBUTED PROCESSING TECHNOLOGY"},
  2441. { 0x1045, "OPTI"},
  2442. { 0x1046, "IPC CORPORATION, LTD."},
  2443. { 0x1047, "GENOA SYSTEMS CORP"},
  2444. { 0x1048, "ELSA GMBH"},
  2445. { 0x1049, "FOUNTAIN TECHNOLOGY"},
  2446. { 0x104A, "SGS THOMSON"},
  2447. { 0x104B, "BUSLOGIC"},
  2448. { 0x104C, "TEXAS INSTRUMENTS"},
  2449. { 0x104D, "SONY CORPORATION"},
  2450. { 0x104E, "OAK TECHNOLOGY, INC"},
  2451. { 0x1050, "WINBOND ELECTRONICS CORP"},
  2452. { 0x1051, "ANIGMA, INC."},
  2453. { 0x1055, "EFAR MICROSYSTEMS"},
  2454. { 0x1057, "MOTOROLA"},
  2455. { 0x1058, "ELECTRONICS & TELEC. RSH"},
  2456. { 0x1059, "TEKNOR INDUSTRIAL COMPUTERS INC"},
  2457. { 0x105A, "PROMISE TECHNOLOGY"},
  2458. { 0x105B, "FOXCONN INTERNATIONAL"},
  2459. { 0x105C, "WIPRO INFOTECH LIMITED"},
  2460. { 0x105D, "NUMBER 9 COMPUTER COMPANY"},
  2461. { 0x105E, "VTECH COMPUTERS LTD"},
  2462. { 0x105F, "INFOTRONIC AMERICA INC"},
  2463. { 0x1060, "UNITED MICROELECTRONICS"},
  2464. { 0x1061, "I.T.T."},
  2465. { 0x1062, "MASPAR COMPUTER CORP"},
  2466. { 0x1063, "OCEAN OFFICE AUTOMATION"},
  2467. { 0x1064, "ALCATEL CIT"},
  2468. { 0x1065, "TEXAS MICROSYSTEMS"},
  2469. { 0x1066, "PICOPOWER TECHNOLOGY"},
  2470. { 0x1067, "MITSUBISHI ELECTRONICS"},
  2471. { 0x1068, "DIVERSIFIED TECHNOLOGY"},
  2472. { 0x1069, "MYLEX CORPORATION"},
  2473. { 0x106B, "APPLE COMPUTER INC."},
  2474. { 0x106C, "HYUNDAI ELECTRONICS AMERI"},
  2475. { 0x106D, "SEQUENT"},
  2476. { 0x106E, "DFI, INC"},
  2477. { 0x106F, "CITY GATE DEVELOPMENT LTD"},
  2478. { 0x1070, "DAEWOO TELECOM LTD"},
  2479. { 0x1073, "YAMAHA CORPORATION"},
  2480. { 0x1074, "NEXGEN MICROSYSTEME"},
  2481. { 0x1075, "ADVANCED INTEGRATION RES."},
  2482. { 0x1076, "CHAINTECH COMPUTER CO. LTD"},
  2483. { 0x1077, "Q LOGIC"},
  2484. { 0x1078, "CYRIX CORPORATION"},
  2485. { 0x1079, "I-BUS"},
  2486. { 0x107B, "GATEWAY 2000"},
  2487. { 0x107C, "LG ELECTRONICS"},
  2488. { 0x107D, "LEADTEK RESEARCH INC."},
  2489. { 0x107E, "INTERPHASE CORPORATION"},
  2490. { 0x107F, "DATA TECHNOLOGY CORPORATION"},
  2491. { 0x1080, "CYPRESS SEMICONDUCTOR"},
  2492. { 0x1081, "RADIUS"},
  2493. { 0x1083, "FOREX COMPUTER CORPORATION"},
  2494. { 0x1085, "TULIP COMPUTERS INT.B.V."},
  2495. { 0x1089, "DATA GENERAL CORPORATION"},
  2496. { 0x108A, "BIT 3 COMPUTER"},
  2497. { 0x108C, "OAKLEIGH SYSTEMS INC."},
  2498. { 0x108D, "OLICOM"},
  2499. { 0x108E, "SUN MICROSYSTEMS"},
  2500. { 0x108F, "SYSTEMSOFT"},
  2501. { 0x1090, "ENCORE COMPUTER CORPORATION"},
  2502. { 0x1091, "INTERGRAPH CORPORATION"},
  2503. { 0x1092, "DIAMOND MULTMEDIA SYSTEMS"},
  2504. { 0x1093, "NATIONAL INSTRUMENTS"},
  2505. { 0x1094, "FIRST INT'L COMPUTERS"},
  2506. { 0x1095, "CMD TECHNOLOGY INC"},
  2507. { 0x1096, "ALACRON"},
  2508. { 0x1098, "QUANTUM DESIGNS (H.K.) LTD"},
  2509. { 0x109B, "GEMLIGHT COMPUTER LTD."},
  2510. { 0x109E, "BROOKTREE CORPORATION"},
  2511. { 0x109F, "TRIGEM COMPUTER INC."},
  2512. { 0x10A0, "MEIDENSHA CORPORATION"},
  2513. { 0x10A2, "QUANTUM CORPORATION"},
  2514. { 0x10A3, "EVEREX SYSTEMS INC"},
  2515. { 0x10A5, "RACAL INTERLAN"},
  2516. { 0x10A8, "SIERRA SEMICONDUCTOR"},
  2517. { 0x10A9, "SILICON GRAPHICS"},
  2518. { 0x10AA, "ACC MICROELECTRONICS"},
  2519. { 0x10AD, "SYMPHONY LABS"},
  2520. { 0x10AE, "CORNERSTONE TECHNOLOGY"},
  2521. { 0x10B0, "CARDEXPERT TECHNOLOGY"},
  2522. { 0x10B1, "CABLETRON SYSTEMS INC"},
  2523. { 0x10B2, "RAYTHEON COMPANY"},
  2524. { 0x10B3, "DATABOOK INC"},
  2525. { 0x10B4, "STB SYSTEMS INC"},
  2526. { 0x10B5, "PLX TECHNOLOGY"},
  2527. { 0x10B6, "MADGE NETWORKS"},
  2528. { 0x10B7, "3COM CORPORATION"},
  2529. { 0x10B8, "STANDARD MICROSYSTEMS"},
  2530. { 0x10B9, "ACER LABS"},
  2531. { 0x10BA, "MITSUBISHI ELECTRONICS CORP."},
  2532. { 0x10BC, "ADVANCED LOGIC RESEARCH"},
  2533. { 0x10BD, "SURECOM TECHNOLOGY"},
  2534. { 0x10C0, "BOCA RESEARCH INC."},
  2535. { 0x10C1, "ICM CO., LTD."},
  2536. { 0x10C2, "AUSPEX SYSTEMS INC."},
  2537. { 0x10C3, "SAMSUNG SEMICONDUCTORS"},
  2538. { 0x10C4, "AWARD SOFTWARE INTERNATIONAL INC."},
  2539. { 0x10C5, "XEROX CORPORATION"},
  2540. { 0x10C6, "RAMBUS INC."},
  2541. { 0x10C8, "NEOMAGIC CORPORATION"},
  2542. { 0x10C9, "DATAEXPERT CORPORATION"},
  2543. { 0x10CB, "OMRON CORPORATION"},
  2544. { 0x10CC, "MENTOR ARC INC"},
  2545. { 0x10CD, "ADVANCED SYSTEM PRODUCTS, INC"},
  2546. { 0x10D0, "FUJITSU LIMITED"},
  2547. { 0x10D1, "FUTURE+ SYSTEMS"},
  2548. { 0x10D2, "MOLEX INCORPORATED"},
  2549. { 0x10D3, "JABIL CIRCUIT INC"},
  2550. { 0x10D4, "HUALON MICROELECTRONICS"},
  2551. { 0x10D6, "CETIA"},
  2552. { 0x10D7, "BCM ADVANCED"},
  2553. { 0x10D8, "ADVANCED PERIPHERALS LABS"},
  2554. { 0x10DA, "THOMAS-CONRAD CORPORATION"},
  2555. { 0x10DC, "CERN/ECP/EDU"},
  2556. { 0x10DD, "EVANS & SUTHERLAND"},
  2557. { 0x10DE, "NVIDIA CORPORATION"},
  2558. { 0x10DF, "EMULEX CORPORATION"},
  2559. { 0x10E0, "INTEGRATED MICRO SOLUTIONS INC."},
  2560. { 0x10E1, "TEKRAM TECHNOLOGY CO.,LTD."},
  2561. { 0x10E2, "APTIX CORPORATION"},
  2562. { 0x10E3, "TUNDRA SEMICONDUCTOR (formerly NEWBRIDGE MICROSYSTEMS)"},
  2563. { 0x10E4, "TANDEM COMPUTERS"},
  2564. { 0x10E5, "MICRO INDUSTRIES CORPORATION"},
  2565. { 0x10E6, "GAINBERY COMPUTER PRODUCTS INC."},
  2566. { 0x10E7, "VADEM"},
  2567. { 0x10E8, "APPLIED MICRO CIRCUITS CORPORATION"},
  2568. { 0x10E9, "ALPS ELECTRIC CO. LTD."},
  2569. { 0x10EB, "ARTISTS GRAPHICS"},
  2570. { 0x10EC, "REALTEK SEMICONDUCTOR CO., LTD."},
  2571. { 0x10ED, "ASCII CORPORATION"},
  2572. { 0x10EE, "XILINX CORPORATION"},
  2573. { 0x10EF, "RACORE COMPUTER PRODUCTS, INC."},
  2574. { 0x10F0, "PERITEK CORPORATION"},
  2575. { 0x10F1, "TYAN COMPUTER"},
  2576. { 0x10F3, "ALARIS, INC."},
  2577. { 0x10F4, "S-MOS SYSTEMS"},
  2578. { 0x10F5, "NKK CORPORATION"},
  2579. { 0x10F6, "CREATIVE ELECTRONIC SYSTEMS SA"},
  2580. { 0x10F7, "MATSUSHITA ELECTRIC INDUSTRIAL CO., LTD."},
  2581. { 0x10F8, "ALTOS INDIA LTD"},
  2582. { 0x10F9, "PC DIRECT"},
  2583. { 0x10FA, "TRUEVISION"},
  2584. { 0x10FB, "THESYS GES. F. MIKROELEKTRONIK MGH"},
  2585. { 0x10FC, "I-O DATA DEVICE, INC."},
  2586. { 0x10FD, "SOYO COMPUTER INC."},
  2587. { 0x10FE, "FAST ELECTRONIC GMBH"},
  2588. { 0x10FF, "NCUBE"},
  2589. { 0x1100, "JAZZ MULTIMEDIA"},
  2590. { 0x1101, "INITIO CORPORATION"},
  2591. { 0x1102, "CREATIVE LABS"},
  2592. { 0x1103, "TRIONES TECHNOLOGIES, INC."},
  2593. { 0x1104, "RASTEROPS"},
  2594. { 0x1105, "SIGMA DESIGNS, INC"},
  2595. { 0x1106, "VIA TECHNOLOGIES, INC."},
  2596. { 0x1107, "STRATUS COMPUTERS"},
  2597. { 0x1108, "PROTEON, INC."},
  2598. { 0x1109, "COGENT DATA TECHNOLOGIES"},
  2599. { 0x110A, "SIEMENS NIXDORF IS/AG"},
  2600. { 0x110B, "CHROMATIC RESEARCH INC."},
  2601. { 0x110C, "MINI-MAX TECHNOLOGY, INC."},
  2602. { 0x110D, "ZNYX ADVANCED SYSTEMS"},
  2603. { 0x110E, "CPU TECHNOLOGY"},
  2604. { 0x110F, "ROSS TECHNOLOGY"},
  2605. { 0x1110, "Fire Power Systems, Inc."},
  2606. { 0x1111, "SANTA CRUZ OPERATION"},
  2607. { 0x1112, "RNS (formerly ROCKWELL NETWORK SYSTEMS)"},
  2608. { 0x1114, "ATMEL CORPORATION"},
  2609. { 0x1117, "DATACUBE, INC"},
  2610. { 0x1118, "BERG ELECTRONICS"},
  2611. { 0x1119, "VORTEX COMPUTERSYSTEME GMBH"},
  2612. { 0x111A, "EFFICIENT NETWORKS"},
  2613. { 0x111B, "LITTON GCS"},
  2614. { 0x111C, "TRICORD SYSTEMS"},
  2615. { 0x111D, "INTEGRATED DEVICE TECH"},
  2616. { 0x111F, "PRECISION DIGITAL IMAGES"},
  2617. { 0x1120, "EMC CORPORATION"},
  2618. { 0x1122, "MULTI-TECH SYSTEMS, INC."},
  2619. { 0x1123, "EXCELLENT DESIGN, INC."},
  2620. { 0x1124, "LEUTRON VISION AG"},
  2621. { 0x1127, "FORE SYSTEMS INC"},
  2622. { 0x1129, "FIRMWORKS"},
  2623. { 0x112A, "HERMES ELECTRONICS COMPANY, LTD."},
  2624. { 0x112B, "LINOTYPE - HELL AG"},
  2625. { 0x112C, "ZENITH DATA SYSTEMS"},
  2626. { 0x112E, "INFOMEDIA MICROELECTRONICS INC."},
  2627. { 0x112F, "IMAGING TECHNLOGY INC"},
  2628. { 0x1130, "COMPUTERVISION"},
  2629. { 0x1131, "PHILIPS SEMICONDUCTORS"},
  2630. { 0x1132, "MITEL CORP."},
  2631. { 0x1133, "EICON TECHNOLOGY CORPORATION"},
  2632. { 0x1134, "MERCURY COMPUTER SYSTEMS"},
  2633. { 0x1135, "FUJI XEROX CO LTD"},
  2634. { 0x1136, "MOMENTUM DATA SYSTEMS"},
  2635. { 0x1137, "CISCO SYSTEMS INC"},
  2636. { 0x1138, "ZIATECH CORPORATION"},
  2637. { 0x1139, "DYNAMIC PICTURES INC"},
  2638. { 0x113A, "FWB INC"},
  2639. { 0x113B, "NETWORK COMPUTING DEVICES"},
  2640. { 0x113C, "CYCLONE MICROSYSTEMS"},
  2641. { 0x113D, "LEADING EDGE PRODUCTS INC"},
  2642. { 0x113E, "SANYO ELECTRIC CO"},
  2643. { 0x113F, "EQUINOX SYSTEMS"},
  2644. { 0x1140, "INTERVOICE INC"},
  2645. { 0x1141, "CREST MICROSYSTEM INC"},
  2646. { 0x1142, "ALLIANCE SEMICONDUCTOR CORPORATION"},
  2647. { 0x1143, "NETPOWER, INC"},
  2648. { 0x1144, "CINCINNATI MILACRON"},
  2649. { 0x1145, "WORKBIT CORP"},
  2650. { 0x1146, "FORCE COMPUTERS"},
  2651. { 0x1147, "INTERFACE CORP"},
  2652. { 0x1148, "SYSKONNECT"},
  2653. { 0x1149, "WIN SYSTEM CORPORATION"},
  2654. { 0x114A, "VMIC"},
  2655. { 0x114B, "CANOPUS CO., LTD"},
  2656. { 0x114C, "ANNABOOKS"},
  2657. { 0x114D, "IC CORPORATION"},
  2658. { 0x114E, "NIKON SYSTEMS INC"},
  2659. { 0x114F, "DIGI INTERNATIONAL"},
  2660. { 0x1151, "JAE ELECTRONICS INC."},
  2661. { 0x1152, "MEGATEK"},
  2662. { 0x1153, "LAND WIN ELECTRONIC CORP"},
  2663. { 0x1154, "MELCO INC"},
  2664. { 0x1155, "PINE TECHNOLOGY LTD"},
  2665. { 0x1156, "PERISCOPE ENGINEERING"},
  2666. { 0x1157, "AVSYS CORPORATION"},
  2667. { 0x1158, "VOARX R & D INC"},
  2668. { 0x1159, "MUTECH CORP"},
  2669. { 0x115A, "HARLEQUIN LTD"},
  2670. { 0x115B, "PARALLAX GRAPHICS"},
  2671. { 0x115C, "PHOTRON LTD."},
  2672. { 0x115D, "XIRCOM"},
  2673. { 0x115E, "PEER PROTOCOLS INC"},
  2674. { 0x115F, "MAXTOR CORPORATION"},
  2675. { 0x1160, "MEGASOFT INC"},
  2676. { 0x1161, "PFU LIMITED"},
  2677. { 0x1162, "OA LABORATORY CO LTD"},
  2678. { 0x1163, "RENDITION"},
  2679. { 0x1164, "ADVANCED PERIPHERALS TECH"},
  2680. { 0x1165, "IMAGRAPH"},
  2681. { 0x1166, "RELIANCE COMPUTER CORP."},
  2682. { 0x1167, "MUTOH INDUSTRIES INC"},
  2683. { 0x1168, "THINE ELECTRONICS INC"},
  2684. { 0x116A, "POLARIS COMMUNICATIONS"},
  2685. { 0x116B, "CONNECTWARE INC"},
  2686. { 0x116C, "INTELLIGENT RESOURCES"},
  2687. { 0x116E, "ELECTRONICS FOR IMAGING"},
  2688. { 0x116F, "WORKSTATION TECHNOLOGY"},
  2689. { 0x1170, "INVENTEC CORPORATION"},
  2690. { 0x1171, "LOUGHBOROUGH SOUND IMAGES"},
  2691. { 0x1172, "ALTERA CORPORATION"},
  2692. { 0x1173, "ADOBE SYSTEMS, INC"},
  2693. { 0x1174, "BRIDGEPORT MACHINES"},
  2694. { 0x1175, "MITRON COMPUTER INC."},
  2695. { 0x1176, "SBE INCORPORATED"},
  2696. { 0x1177, "SILICON ENGINEERING"},
  2697. { 0x1178, "ALFA, INC."},
  2698. { 0x117A, "A-TREND TECHNOLOGY"},
  2699. { 0x117C, "ATTO TECHNOLOGY"},
  2700. { 0x117D, "BECTON & DICKINSON"},
  2701. { 0x117E, "T/R SYSTEMS"},
  2702. { 0x117F, "INTEGRATED CIRCUIT SYSTEMS"},
  2703. { 0x1180, "RICOH CO LTD"},
  2704. { 0x1181, "TELMATICS INTERNATIONAL"},
  2705. { 0x1183, "FUJIKURA LTD"},
  2706. { 0x1184, "FORKS INC"},
  2707. { 0x1185, "DATAWORLD"},
  2708. { 0x1186, "D-LINK SYSTEM INC"},
  2709. { 0x1187, "ADVANCED TECHNOLOGY LABORATORIES"},
  2710. { 0x1188, "SHIMA SEIKI MANUFACTURING LTD."},
  2711. { 0x1189, "MATSUSHITA ELECTRONICS CO LTD"},
  2712. { 0x118A, "HILEVEL TECHNOLOGY"},
  2713. { 0x118B, "HYPERTEC PTY LIMITED"},
  2714. { 0x118C, "COROLLARY, INC"},
  2715. { 0x118D, "BITFLOW INC"},
  2716. { 0x118E, "HERMSTEDT GMBH"},
  2717. { 0x118F, "GREEN LOGIC"},
  2718. { 0x1191, "ARTOP ELECTRONIC CORP"},
  2719. { 0x1192, "DENSAN CO., LTD"},
  2720. { 0x1193, "ZEITNET INC."},
  2721. { 0x1194, "TOUCAN TECHNOLOGY"},
  2722. { 0x1195, "RATOC SYSTEM INC"},
  2723. { 0x1196, "HYTEC ELECTRONICS LTD"},
  2724. { 0x1197, "GAGE APPLIED SCIENCES, INC."},
  2725. { 0x1198, "LAMBDA SYSTEMS INC"},
  2726. { 0x1199, "ATTACHMATE CORPORATION"},
  2727. { 0x1199, "DIGITAL COMMUNICATIONS ASSOCIATES INC"},
  2728. { 0x119A, "MIND SHARE, INC."},
  2729. { 0x119B, "OMEGA MICRO INC."},
  2730. { 0x119C, "INFORMATION TECHNOLOGY INST."},
  2731. { 0x119D, "BUG SAPPORO JAPAN"},
  2732. { 0x119E, "FUJITSU"},
  2733. { 0x119F, "BULL HN INFORMATION SYSTEMS"},
  2734. { 0x11A0, "CONVEX COMPUTER CORPORATION"},
  2735. { 0x11A1, "HAMAMATSU PHOTONICS K.K."},
  2736. { 0x11A2, "SIERRA RESEARCH AND TECHNOLOGY"},
  2737. { 0x11A4, "BARCO GRAPHICS NV"},
  2738. { 0x11A5, "MICROUNITY SYSTEMS ENG. INC"},
  2739. { 0x11A6, "PURE DATA"},
  2740. { 0x11A7, "POWER COMPUTING CORP."},
  2741. { 0x11A8, "SYSTECH CORP."},
  2742. { 0x11A9, "INNOSYS"},
  2743. { 0x11AA, "ACTEL"},
  2744. { 0x11AB, "GALILEO TECHNOLOGY LTD."},
  2745. { 0x11AC, "CANON INFORMATION SYSTEMS"},
  2746. { 0x11AD, "LITE-ON COMMUNICATIONS INC"},
  2747. { 0x11AE, "AZTECH SYSTEM LTD"},
  2748. { 0x11AE, "SCITEX CORPORATION"},
  2749. { 0x11AF, "AVID TECHNOLOGY INC"},
  2750. { 0x11AF, "PRO-LOG CORPORATION"},
  2751. { 0x11B0, "V3 SEMICONDUCTOR"},
  2752. { 0x11B1, "APRICOT COMPUTERS"},
  2753. { 0x11B2, "EASTMAN KODAK"},
  2754. { 0x11B3, "BARR SYSTEMS INC."},
  2755. { 0x11B4, "LEITCH TECHNOLOGY INTERNATIONAL"},
  2756. { 0x11B5, "RADSTONE TECHNOLOGY PLC"},
  2757. { 0x11B6, "UNITED VIDEO CORP"},
  2758. { 0x11B8, "XPOINT TECHNOLOGIES INC"},
  2759. { 0x11B9, "PATHLIGHT TECHNOLOGY INC"},
  2760. { 0x11BA, "VIDEOTRON CORP"},
  2761. { 0x11BB, "PYRAMID TECHNOLOGY"},
  2762. { 0x11BC, "NETWORK PERIPHERALS INC"},
  2763. { 0x11BD, "PINNACLE SYSTEMS INC."},
  2764. { 0x11BE, "INTERNATIONAL MICROCIRCUITS INC"},
  2765. { 0x11BF, "ASTRODESIGN, INC."},
  2766. { 0x11C0, "HEWLETT PACKARD"},
  2767. { 0x11C1, "AT&T MICROELECTRONICS"},
  2768. { 0x11C2, "SAND MICROELECTRONICS"},
  2769. { 0x11C4, "DOCUMENT TECHNOLOGIES, IND"},
  2770. { 0x11C5, "SHIVA CORPORATION"},
  2771. { 0x11C6, "DAINIPPON SCREEN MFG. CO. LTD"},
  2772. { 0x11C7, "D.C.M. DATA SYSTEMS"},
  2773. { 0x11C8, "DOLPHIN INTERCONNECT"},
  2774. { 0x11C9, "MAGMA"},
  2775. { 0x11CA, "LSI SYSTEMS, INC"},
  2776. { 0x11CB, "SPECIALIX RESEARCH LTD"},
  2777. { 0x11CC, "MICHELS & KLEBERHOFF COMPUTER GMBH"},
  2778. { 0x11CD, "HAL COMPUTER SYSTEMS, INC."},
  2779. { 0x11CE, "PRIMARY RATE INC"},
  2780. { 0x11CF, "PIONEER ELECTRONIC CORPORATION"},
  2781. { 0x11D0, "LORAL FREDERAL SYSTEMS - MANASSAS"},
  2782. { 0x11D1, "AURAVISION"},
  2783. { 0x11D2, "INTERCOM INC."},
  2784. { 0x11D3, "TRANCELL SYSTEMS INC"},
  2785. { 0x11D4, "ANALOG DEVICES"},
  2786. { 0x11D5, "IKON CORPORATION"},
  2787. { 0x11D6, "TEKELEC TECHNOLOGIES"},
  2788. { 0x11D7, "TRENTON TERMINALS INC"},
  2789. { 0x11D8, "IMAGE TECHNOLOGIES DEVELOPMENT"},
  2790. { 0x11D9, "TEC CORPORATION"},
  2791. { 0x11DA, "NOVELL"},
  2792. { 0x11DB, "SEGA ENTERPRISES LITD"},
  2793. { 0x11DC, "QUESTRA CORPORATION"},
  2794. { 0x11DD, "CROSFIELD ELECTRONICS LIMITED"},
  2795. { 0x11DE, "ZORAN CORPORATION"},
  2796. { 0x11DF, "NEW WAVE PDG"},
  2797. { 0x11E0, "CRAY COMMUNICATIONS A/S"},
  2798. { 0x11E1, "GEC PLESSEY SEMI INC."},
  2799. { 0x11E2, "SAMSUNG INFORMATION SYSTEMS AMERICA"},
  2800. { 0x11E3, "QUICKLOGIC CORPORATION"},
  2801. { 0x11E4, "SECOND WAVE INC"},
  2802. { 0x11E5, "IIX CONSULTING"},
  2803. { 0x11E6, "MITSUI-ZOSEN SYSTEM RESEARCH"},
  2804. { 0x11E7, "TOSHIBA AMERICA, ELEC. COMPANY"},
  2805. { 0x11E8, "DIGITAL PROCESSING SYSTEMS INC."},
  2806. { 0x11E9, "HIGHWATER DESIGNS LTD."},
  2807. { 0x11EA, "ELSAG BAILEY"},
  2808. { 0x11EB, "FORMATION INC."},
  2809. { 0x11EC, "CORECO INC"},
  2810. { 0x11ED, "MEDIAMATICS"},
  2811. { 0x11EE, "DOME IMAGING SYSTEMS INC"},
  2812. { 0x11EF, "NICOLET TECHNOLOGIES B.V."},
  2813. { 0x11F0, "COMPU-SHACK GMBH"},
  2814. { 0x11F1, "SYMBIOS LOGIC INC"},
  2815. { 0x11F2, "PICTURE TEL JAPAN K.K."},
  2816. { 0x11F3, "KEITHLEY METRABYTE"},
  2817. { 0x11F4, "KINETIC SYSTEMS CORPORATION"},
  2818. { 0x11F5, "COMPUTING DEVICES INTERNATIONAL"},
  2819. { 0x11F6, "POWERMATIC DATA SYSTEMS LTD"},
  2820. { 0x11F7, "SCIENTIFIC ATLANTA"},
  2821. { 0x11F8, "PMC-SIERRA INC"},
  2822. { 0x11F9, "I-CUBE INC"},
  2823. { 0x11FA, "KASAN ELECTRONICS COMPANY, LTD."},
  2824. { 0x11FB, "DATEL INC"},
  2825. { 0x11FC, "SILICON MAGIC"},
  2826. { 0x11FD, "HIGH STREET CONSULTANTS"},
  2827. { 0x11FE, "COMTROL CORPORATION"},
  2828. { 0x11FF, "SCION CORPORATION"},
  2829. { 0x1200, "CSS CORPORATION"},
  2830. { 0x1201, "VISTA CONTROLS CORP"},
  2831. { 0x1202, "NETWORK GENERAL CORP."},
  2832. { 0x1203, "BAYER CORPORATION, AGFA DIVISION"},
  2833. { 0x1204, "LATTICE SEMICONDUCTOR CORPORATION"},
  2834. { 0x1205, "ARRAY CORPORATION"},
  2835. { 0x1206, "AMDAHL CORPORATION"},
  2836. { 0x1208, "PARSYTEC GMBH"},
  2837. { 0x1209, "SCI SYSTEMS INC"},
  2838. { 0x120A, "SYNAPTEL"},
  2839. { 0x120B, "ADAPTIVE SOLUTIONS"},
  2840. { 0x120D, "COMPRESSION LABS, INC."},
  2841. { 0x120E, "CYCLADES CORPORATION"},
  2842. { 0x120F, "ESSENTIAL COMMUNICATIONS"},
  2843. { 0x1210, "HYPERPARALLEL TECHNOLOGIES"},
  2844. { 0x1211, "BRAINTECH INC"},
  2845. { 0x1212, "KINGSTON TECHNOLOGY CORP."},
  2846. { 0x1213, "APPLIED INTELLIGENT SYSTEMS, INC."},
  2847. { 0x1214, "PERFORMANCE TECHNOLOGIES, INC."},
  2848. { 0x1215, "INTERWARE CO., LTD"},
  2849. { 0x1216, "PURUP PREPRESS A/S"},
  2850. { 0x1217, "2 MICRO, INC."},
  2851. { 0x1218, "HYBRICON CORP."},
  2852. { 0x1219, "FIRST VIRTUAL CORPORATION"},
  2853. { 0x121A, "3DFX INTERACTIVE, INC."},
  2854. { 0x121B, "ADVANCED TELECOMMUNICATIONS MODULES"},
  2855. { 0x121C, "NIPPON TEXA CO., LTD"},
  2856. { 0x121D, "LIPPERT AUTOMATIONSTECHNIK GMBH"},
  2857. { 0x121E, "CSPI"},
  2858. { 0x121F, "ARCUS TECHNOLOGY, INC."},
  2859. { 0x1220, "ARIEL CORPORATION"},
  2860. { 0x1221, "CONTEC CO., LTD"},
  2861. { 0x1222, "ANCOR COMMUNICATIONS, INC."},
  2862. { 0x1223, "HEURIKON/COMPUTER PRODUCTS"},
  2863. { 0x122C, "SICAN GMBH"},
  2864. { 0x1234, "TECHNICAL CORP."},
  2865. { 0x1239, "THE 3DO Company"},
  2866. { 0x124F, "INFORTREND TECHNOLOGY INC."},
  2867. { 0x126F, "SILICON MOTION"},
  2868. { 0x1275, "NETWORK APPLIANCE"},
  2869. { 0x1278, "TRANSTECH PARALLEL SYSTEMS"},
  2870. { 0x127B, "PIXERA CORPORATION"},
  2871. { 0x1297, "HOLCO ENTERPRISE"},
  2872. { 0x12A1, "SIMPACT, INC"},
  2873. { 0x12BA, "BITTWARE RESEARCH SYSTEMS, INC."},
  2874. { 0x12E7, "SEBRING SYSTEMS, INC."},
  2875. { 0x12EB, "AUREAL SEMICONDUCTOR"},
  2876. { 0x3D3D, "3DLABS"},
  2877. { 0x4005, "AVANCE LOGIC INC"},
  2878. { 0x5333, "S3 INC."},
  2879. { 0x8086, "INTEL"},
  2880. { 0x8E0E, "COMPUTONE CORPORATION"},
  2881. { 0x9004, "ADAPTEC"},
  2882. { 0xE159, "TIGER JET NETWORK INC."},
  2883. { 0xEDD8, "ARK LOGIC INC"}
  2884. };
  2885. //
  2886. // Taken from the PCI driver
  2887. //
  2888. #define PCI_TYPE0_RANGE_COUNT ((PCI_TYPE0_ADDRESSES) + 1)
  2889. #define PCI_TYPE1_RANGE_COUNT ((PCI_TYPE1_ADDRESSES) + 4)
  2890. #define PCI_TYPE2_RANGE_COUNT ((PCI_TYPE2_ADDRESSES) + 1)
  2891. #if PCI_TYPE0_RANGE_COUNT > PCI_TYPE1_RANGE_COUNT
  2892. #if PCI_TYPE0_RANGE_COUNT > PCI_TYPE2_RANGE_COUNT
  2893. #define PCI_MAX_RANGE_COUNT PCI_TYPE0_RANGE_COUNT
  2894. #else
  2895. #define PCI_MAX_RANGE_COUNT PCI_TYPE2_RANGE_COUNT
  2896. #endif
  2897. #else
  2898. #if PCI_TYPE1_RANGE_COUNT > PCI_TYPE2_RANGE_COUNT
  2899. #define PCI_MAX_RANGE_COUNT PCI_TYPE1_RANGE_COUNT
  2900. #else
  2901. #define PCI_MAX_RANGE_COUNT PCI_TYPE2_RANGE_COUNT
  2902. #endif
  2903. #endif
  2904. VOID
  2905. DevExtUsage()
  2906. {
  2907. dprintf("!devext [<address> <type>]\n");
  2908. dprintf(" <address> is the address of a device extension to\n");
  2909. dprintf(" be dumped.\n");
  2910. dprintf(" <type> is the type of the object owning this extension:\n");
  2911. dprintf(" PCI if it is a PCI device extension\n");
  2912. dprintf(" ISAPNP if it is an ISAPNP device extension\n");
  2913. dprintf(" PCMCIA if it is a PCMCIA device extension\n");
  2914. dprintf(" HID if it is an HID device extension\n");
  2915. return;
  2916. }
  2917. VOID
  2918. DevExtPciFindClassCodes(
  2919. ULONG PdoxBaseClass,
  2920. ULONG PdoxSubClass,
  2921. PUCHAR * BaseClass,
  2922. PUCHAR * SubClass
  2923. )
  2924. {
  2925. PUCHAR bc = "Unknown Base Class";
  2926. PUCHAR sc = "Unknown Sub Class";
  2927. switch (PdoxBaseClass) {
  2928. case PCI_CLASS_PRE_20:
  2929. // Class 00 - PCI_CLASS_PRE_20:
  2930. bc = "Pre PCI 2.0";
  2931. switch (PdoxSubClass) {
  2932. case PCI_SUBCLASS_PRE_20_NON_VGA:
  2933. sc = "Pre PCI 2.0 Non-VGA Device";
  2934. break;
  2935. case PCI_SUBCLASS_PRE_20_VGA:
  2936. sc = "Pre PCI 2.0 VGA Device";
  2937. break;
  2938. }
  2939. break;
  2940. case PCI_CLASS_MASS_STORAGE_CTLR:
  2941. // Class 01 - PCI_CLASS_MASS_STORAGE_CTLR:
  2942. bc = "Mass Storage Controller";
  2943. switch (PdoxSubClass) {
  2944. case PCI_SUBCLASS_MSC_SCSI_BUS_CTLR:
  2945. sc = "SCSI";
  2946. break;
  2947. case PCI_SUBCLASS_MSC_IDE_CTLR:
  2948. sc = "IDE";
  2949. break;
  2950. case PCI_SUBCLASS_MSC_FLOPPY_CTLR:
  2951. sc = "Floppy";
  2952. break;
  2953. case PCI_SUBCLASS_MSC_IPI_CTLR:
  2954. sc = "IPI";
  2955. break;
  2956. case PCI_SUBCLASS_MSC_RAID_CTLR:
  2957. sc = "RAID";
  2958. break;
  2959. case PCI_SUBCLASS_MSC_OTHER:
  2960. sc = "'Other'";
  2961. break;
  2962. }
  2963. break;
  2964. case PCI_CLASS_NETWORK_CTLR:
  2965. // Class 02 - PCI_CLASS_NETWORK_CTLR:
  2966. bc = "Network Controller";
  2967. switch (PdoxSubClass) {
  2968. case PCI_SUBCLASS_NET_ETHERNET_CTLR:
  2969. sc = "Ethernet";
  2970. break;
  2971. case PCI_SUBCLASS_NET_TOKEN_RING_CTLR:
  2972. sc = "Token Ring";
  2973. break;
  2974. case PCI_SUBCLASS_NET_FDDI_CTLR:
  2975. sc = "FDDI";
  2976. break;
  2977. case PCI_SUBCLASS_NET_ATM_CTLR:
  2978. sc = "ATM";
  2979. break;
  2980. case PCI_SUBCLASS_NET_OTHER:
  2981. sc = "'Other'";
  2982. break;
  2983. }
  2984. break;
  2985. case PCI_CLASS_DISPLAY_CTLR:
  2986. // Class 03 - PCI_CLASS_DISPLAY_CTLR:
  2987. // N.B. Sub Class 00 could be VGA or 8514 depending on Interface byte:
  2988. bc = "Display Controller";
  2989. switch (PdoxSubClass) {
  2990. case PCI_SUBCLASS_VID_VGA_CTLR:
  2991. sc = "VGA";
  2992. break;
  2993. case PCI_SUBCLASS_VID_XGA_CTLR:
  2994. sc = "XGA";
  2995. break;
  2996. case PCI_SUBCLASS_VID_OTHER:
  2997. sc = "'Other'";
  2998. break;
  2999. }
  3000. break;
  3001. case PCI_CLASS_MULTIMEDIA_DEV:
  3002. // Class 04 - PCI_CLASS_MULTIMEDIA_DEV:
  3003. bc = "Multimedia Device";
  3004. switch (PdoxSubClass) {
  3005. case PCI_SUBCLASS_MM_VIDEO_DEV:
  3006. sc = "Video";
  3007. break;
  3008. case PCI_SUBCLASS_MM_AUDIO_DEV:
  3009. sc = "Audio";
  3010. break;
  3011. case PCI_SUBCLASS_MM_OTHER:
  3012. sc = "'Other'";
  3013. break;
  3014. }
  3015. break;
  3016. case PCI_CLASS_MEMORY_CTLR:
  3017. // Class 05 - PCI_CLASS_MEMORY_CTLR:
  3018. bc = "Memory Controller";
  3019. switch (PdoxSubClass) {
  3020. case PCI_SUBCLASS_MEM_RAM:
  3021. sc = "RAM";
  3022. break;
  3023. case PCI_SUBCLASS_MEM_FLASH:
  3024. sc = "FLASH";
  3025. break;
  3026. case PCI_SUBCLASS_MEM_OTHER:
  3027. sc = "'Other'";
  3028. break;
  3029. }
  3030. break;
  3031. case PCI_CLASS_BRIDGE_DEV:
  3032. // Class 06 - PCI_CLASS_BRIDGE_DEV:
  3033. bc = "Bridge";
  3034. switch (PdoxSubClass) {
  3035. case PCI_SUBCLASS_BR_HOST:
  3036. sc = "HOST to PCI";
  3037. break;
  3038. case PCI_SUBCLASS_BR_ISA:
  3039. sc = "PCI to ISA";
  3040. break;
  3041. case PCI_SUBCLASS_BR_EISA:
  3042. sc = "PCI to EISA";
  3043. break;
  3044. case PCI_SUBCLASS_BR_MCA:
  3045. sc = "PCI to MCA";
  3046. break;
  3047. case PCI_SUBCLASS_BR_PCI_TO_PCI:
  3048. sc = "PCI to PCI";
  3049. break;
  3050. case PCI_SUBCLASS_BR_PCMCIA:
  3051. sc = "PCI to PCMCIA";
  3052. break;
  3053. case PCI_SUBCLASS_BR_NUBUS:
  3054. sc = "PCI to NUBUS";
  3055. break;
  3056. case PCI_SUBCLASS_BR_CARDBUS:
  3057. sc = "PCI to CardBus";
  3058. break;
  3059. case PCI_SUBCLASS_BR_OTHER:
  3060. sc = "PCI to 'Other'";
  3061. break;
  3062. }
  3063. break;
  3064. case PCI_CLASS_SIMPLE_COMMS_CTLR:
  3065. // Class 07 - PCI_CLASS_SIMPLE_COMMS_CTLR:
  3066. // N.B. Sub Class 00 and 01 additional info in Interface byte:
  3067. bc = "Simple Serial Communications Controller";
  3068. switch (PdoxSubClass) {
  3069. case PCI_SUBCLASS_COM_SERIAL:
  3070. sc = "Serial Port";
  3071. break;
  3072. case PCI_SUBCLASS_COM_PARALLEL:
  3073. sc = "Parallel Port";
  3074. break;
  3075. case PCI_SUBCLASS_COM_OTHER:
  3076. sc = "'Other'";
  3077. break;
  3078. }
  3079. break;
  3080. case PCI_CLASS_BASE_SYSTEM_DEV:
  3081. // Class 08 - PCI_CLASS_BASE_SYSTEM_DEV:
  3082. // N.B. See Interface byte for additional info.:
  3083. bc = "Base System Device";
  3084. switch (PdoxSubClass) {
  3085. case PCI_SUBCLASS_SYS_INTERRUPT_CTLR:
  3086. sc = "Interrupt Controller";
  3087. break;
  3088. case PCI_SUBCLASS_SYS_DMA_CTLR:
  3089. sc = "DMA Controller";
  3090. break;
  3091. case PCI_SUBCLASS_SYS_SYSTEM_TIMER:
  3092. sc = "System Timer";
  3093. break;
  3094. case PCI_SUBCLASS_SYS_REAL_TIME_CLOCK:
  3095. sc = "Real Time Clock";
  3096. break;
  3097. case PCI_SUBCLASS_SYS_OTHER:
  3098. sc = "'Other' base system device";
  3099. break;
  3100. }
  3101. break;
  3102. case PCI_CLASS_INPUT_DEV:
  3103. // Class 09 - PCI_CLASS_INPUT_DEV:
  3104. bc = "Input Device";
  3105. switch (PdoxSubClass) {
  3106. case PCI_SUBCLASS_INP_KEYBOARD:
  3107. sc = "Keyboard";
  3108. break;
  3109. case PCI_SUBCLASS_INP_DIGITIZER:
  3110. sc = "Digitizer";
  3111. break;
  3112. case PCI_SUBCLASS_INP_MOUSE:
  3113. sc = "Mouse";
  3114. break;
  3115. case PCI_SUBCLASS_INP_OTHER:
  3116. sc = "'Other'";
  3117. break;
  3118. }
  3119. break;
  3120. case PCI_CLASS_DOCKING_STATION:
  3121. // Class 0a - PCI_CLASS_DOCKING_STATION:
  3122. bc = "Docking Station";
  3123. switch (PdoxSubClass) {
  3124. case PCI_SUBCLASS_DOC_GENERIC:
  3125. sc = "Generic";
  3126. break;
  3127. case PCI_SUBCLASS_DOC_OTHER:
  3128. sc = "'Other'";
  3129. break;
  3130. }
  3131. break;
  3132. case PCI_CLASS_PROCESSOR:
  3133. // Class 0b - PCI_CLASS_PROCESSOR:
  3134. bc = "Processor";
  3135. switch (PdoxSubClass) {
  3136. case PCI_SUBCLASS_PROC_386:
  3137. sc = "386";
  3138. break;
  3139. case PCI_SUBCLASS_PROC_486:
  3140. sc = "486";
  3141. break;
  3142. case PCI_SUBCLASS_PROC_PENTIUM:
  3143. sc = "Pentium";
  3144. break;
  3145. case PCI_SUBCLASS_PROC_ALPHA:
  3146. sc = "Alpha";
  3147. break;
  3148. case PCI_SUBCLASS_PROC_POWERPC:
  3149. sc = "PowerPC";
  3150. break;
  3151. case PCI_SUBCLASS_PROC_COPROCESSOR:
  3152. sc = "CoProcessor";
  3153. break;
  3154. }
  3155. break;
  3156. case PCI_CLASS_SERIAL_BUS_CTLR:
  3157. // Class 0c - PCI_CLASS_SERIAL_BUS_CTLR:
  3158. bc = "Serial Bus Controller";
  3159. switch (PdoxSubClass) {
  3160. case PCI_SUBCLASS_SB_IEEE1394:
  3161. sc = "1394";
  3162. break;
  3163. case PCI_SUBCLASS_SB_ACCESS:
  3164. sc = "Access Bus";
  3165. break;
  3166. case PCI_SUBCLASS_SB_SSA:
  3167. sc = "SSA";
  3168. break;
  3169. case PCI_SUBCLASS_SB_USB:
  3170. sc = "USB";
  3171. break;
  3172. case PCI_SUBCLASS_SB_FIBRE_CHANNEL:
  3173. sc = "Fibre Channel";
  3174. break;
  3175. }
  3176. break;
  3177. case PCI_CLASS_NOT_DEFINED:
  3178. bc = "(Explicitly) Undefined";
  3179. break;
  3180. }
  3181. *BaseClass = bc;
  3182. *SubClass = sc;
  3183. }
  3184. VOID
  3185. DevExtPciPrintDeviceState(
  3186. PCI_OBJECT_STATE State
  3187. )
  3188. {
  3189. if ((sizeof(DevExtPciDeviceState) / sizeof(DevExtPciDeviceState[0])) !=
  3190. PciMaxObjectState) {
  3191. dprintf("\nWARNING: PCI_OBJECT_STATE enumeration changed, please review.\n");
  3192. }
  3193. if (State >= PciMaxObjectState) {
  3194. dprintf("Unknown PCI Object state.\n");
  3195. return;
  3196. }
  3197. dprintf(" Driver State = %s\n", DevExtPciDeviceState[State]);
  3198. }
  3199. //#if 0
  3200. VOID
  3201. DevExtPciPrintPowerState(
  3202. ULONG64 Power
  3203. )
  3204. {
  3205. #define MAXSYSPOWSTATES \
  3206. (sizeof(DevExtPciSystemPowerState) / sizeof(DevExtPciSystemPowerState[0]))
  3207. #define MAXDEVPOWSTATES \
  3208. (sizeof(DevExtPciDevicePowerState) / sizeof(DevExtPciDevicePowerState[0]))
  3209. SYSTEM_POWER_STATE index;
  3210. DEVICE_POWER_STATE systemStateMapping[PowerSystemMaximum];
  3211. ULONG64 pwrState, waitWakeIrp=0;
  3212. PUCHAR sw, sc, dd, dc, dw;
  3213. //
  3214. // A little sanity.
  3215. //
  3216. if (MAXSYSPOWSTATES != PowerSystemMaximum) {
  3217. dprintf("WARNING: System Power State definition has changed, ext dll is out of date.\n");
  3218. }
  3219. if (MAXDEVPOWSTATES != PowerDeviceMaximum) {
  3220. dprintf("WARNING: Device Power State definition has changed, ext dll is out of date.\n");
  3221. }
  3222. sw = sc = dc = dw = "<*BAD VAL*>";
  3223. GetFieldValue(Power, "pci!PCI_POWER_STATE", "CurrentSystemState", pwrState);
  3224. if (pwrState < PowerSystemMaximum) {
  3225. sc = DevExtPciSystemPowerState[pwrState];
  3226. }
  3227. GetFieldValue(Power, "pci!PCI_POWER_STATE", "CurrentDeviceState", pwrState);
  3228. if (pwrState < PowerDeviceMaximum) {
  3229. dc = DevExtPciDevicePowerState[pwrState];
  3230. }
  3231. GetFieldValue(Power, "pci!PCI_POWER_STATE", "DeviceWakeLevel", pwrState);
  3232. if (pwrState < PowerDeviceMaximum) {
  3233. dw = DevExtPciDevicePowerState[pwrState];
  3234. }
  3235. GetFieldValue(Power, "pci!PCI_POWER_STATE", "SystemWakeLevel", pwrState);
  3236. if (pwrState < PowerSystemMaximum) {
  3237. sw = DevExtPciSystemPowerState[pwrState];
  3238. }
  3239. dprintf(
  3240. " CurrentState: System %s, Device %s\n"
  3241. " WakeLevel: System %s, Device %s\n",
  3242. sc,
  3243. dc,
  3244. sw,
  3245. dw
  3246. );
  3247. GetFieldValue(Power, "pci!PCI_POWER_STATE", "SystemStateMapping", systemStateMapping);
  3248. for (index = PowerSystemWorking; index < PowerSystemMaximum; index++) {
  3249. if (systemStateMapping[index] != PowerDeviceUnspecified) {
  3250. if (systemStateMapping[index] < PowerDeviceMaximum) {
  3251. dc = DevExtPciDevicePowerState[systemStateMapping[index]];
  3252. } else {
  3253. dc = "<*BAD VAL*>";
  3254. }
  3255. dprintf(" %s:\t%s\n",
  3256. DevExtPciSystemPowerState[index],
  3257. dc
  3258. );
  3259. }
  3260. }
  3261. GetFieldValue(Power, "pci!PCI_POWER_STATE", "WaitWakeIrp", waitWakeIrp);
  3262. if (waitWakeIrp) {
  3263. dprintf(" WaitWakeIrp: %#08p\n",
  3264. waitWakeIrp
  3265. );
  3266. }
  3267. #undef MAXSYSPOWSTATES
  3268. #undef MAXDEVPOWSTATES
  3269. }
  3270. VOID
  3271. DevExtPciPrintSecondaryExtensions(
  3272. ULONG64 ListEntry
  3273. )
  3274. {
  3275. ULONG64 extension = 0, extype = 0;
  3276. if (!ListEntry) {
  3277. return;
  3278. }
  3279. xdprintf(1, "Secondary Extensions\n");
  3280. do {
  3281. GetFieldValue(ListEntry, "pci!PCI_SECONDARY_EXTENSION", "ExtensionType", extype);
  3282. switch (extype) {
  3283. case PciArb_Io:
  3284. xdprintf(2, "Arbiter - IO Port");
  3285. break;
  3286. case PciArb_Memory:
  3287. xdprintf(2, "Arbiter - Memory");
  3288. break;
  3289. case PciArb_Interrupt:
  3290. xdprintf(2, "Arbiter - Interrupt");
  3291. break;
  3292. case PciArb_BusNumber:
  3293. xdprintf(2, "Arbiter - Bus Number");
  3294. break;
  3295. case PciTrans_Interrupt:
  3296. xdprintf(2, "Translator - Interrupt");
  3297. break;
  3298. case PciInterface_BusHandler:
  3299. xdprintf(2, "Interface - Bus Handler");
  3300. break;
  3301. case PciInterface_IntRouteHandler:
  3302. xdprintf(2, "Interface - Interrupt Route Handler");
  3303. break;
  3304. default:
  3305. xdprintf(2, "Unknown Extension Type.");
  3306. break;
  3307. }
  3308. dprintf("\n");
  3309. GetFieldValue(ListEntry, "nt!_SINGLE_LIST_ENTRY", "Next", ListEntry);
  3310. } while (ListEntry);
  3311. }
  3312. PUCHAR
  3313. DevExtPciFindVendorId(
  3314. USHORT VendorId
  3315. )
  3316. /*++
  3317. Routine Description:
  3318. Get the vendor name given the vendor ID (assuming we know it).
  3319. Arguments:
  3320. VendorId 16 bit PCI Vendor ID.
  3321. Return Value:
  3322. Pointer to the vendor's name (or NULL).
  3323. --*/
  3324. {
  3325. #define PCIIDCOUNT (sizeof(DevExtPciVendors) / sizeof(DevExtPciVendors[0]))
  3326. ULONG index;
  3327. //
  3328. // Yep, a binary search would be much faster, good thing we only
  3329. // do this once per user iteration.
  3330. //
  3331. for (index = 0; index < PCIIDCOUNT; index++) {
  3332. if (DevExtPciVendors[index].VendorId == VendorId) {
  3333. return DevExtPciVendors[index].VendorName;
  3334. }
  3335. }
  3336. return NULL;
  3337. #undef PCIIDCOUNT
  3338. }
  3339. #define GET_PCI_PDO_FIELD(Pdo,Field,Value) \
  3340. GetPciExtensionField(TRUE, Pdo, Field, sizeof(Value), (PVOID)(&(Value)))
  3341. #define GET_PCI_FDO_FIELD(Fdo,Field,Value) \
  3342. GetPciExtensionField(FALSE, Fdo, Field, sizeof(Value), (PVOID)(&(Value)))
  3343. ULONG
  3344. GetPciExtensionField(
  3345. IN BOOLEAN IsPdo, // TRUE for PDO, false for FDO
  3346. IN ULONG64 TypeAddress,
  3347. IN PUCHAR Field,
  3348. IN ULONG OutSize,
  3349. OUT PVOID OutValue
  3350. )
  3351. {
  3352. ULONG ret;
  3353. static PCHAR pciFDO = "nt!_PCI_FDO_EXTENSION", pciPDO = "nt!_PCI_PDO_EXTENSION";
  3354. //
  3355. // Try the post Win2k name for a pci extension (includes a PCI_ prefix)
  3356. //
  3357. // This would work for public symbols
  3358. ret = GetFieldData(TypeAddress,
  3359. IsPdo ? pciPDO : pciFDO,
  3360. Field,
  3361. OutSize,
  3362. OutValue
  3363. );
  3364. if (ret) {
  3365. pciFDO = "pci!PCI_FDO_EXTENSION";
  3366. pciPDO = "pci!PCI_PDO_EXTENSION";
  3367. //
  3368. // If we have private symbols, nt won't have those types, so try in pci
  3369. //
  3370. ret = GetFieldData(TypeAddress,
  3371. IsPdo ? pciPDO : pciFDO,
  3372. Field,
  3373. OutSize,
  3374. OutValue
  3375. );
  3376. }
  3377. //
  3378. // If that failed then fall back on the name without the PCI_ prefix. This
  3379. // allows debugging Win2k clients with the post Win2k debugger
  3380. //
  3381. if (ret) {
  3382. ret = GetFieldData(TypeAddress,
  3383. IsPdo ? "pci!PDO_EXTENSION" : "pci!FDO_EXTENSION",
  3384. Field,
  3385. OutSize,
  3386. OutValue
  3387. );
  3388. }
  3389. if (ret) {
  3390. // didn't find anything, reste these
  3391. pciFDO = "nt!_PCI_FDO_EXTENSION";
  3392. pciPDO = "nt!_PCI_PDO_EXTENSION";
  3393. }
  3394. return ret;
  3395. }
  3396. typedef struct _PCI_SLOT_NUMBER {
  3397. union {
  3398. struct {
  3399. ULONG DeviceNumber:5;
  3400. ULONG FunctionNumber:3;
  3401. ULONG Reserved:24;
  3402. } bits;
  3403. ULONG AsULONG;
  3404. } u;
  3405. } PCI_SLOT_NUMBER, *PPCI_SLOT_NUMBER;
  3406. VOID
  3407. DevExtPciGetBusDevFunc(
  3408. IN ULONG64 PdoExt,
  3409. OUT PULONG Bus,
  3410. OUT PULONG Dev,
  3411. OUT PULONG Func
  3412. )
  3413. {
  3414. ULONG BaseBus=0;
  3415. ULONG64 ParentFdoExtension=0;
  3416. PCI_SLOT_NUMBER slot;
  3417. GET_PCI_PDO_FIELD(PdoExt, "ParentFdoExtension", ParentFdoExtension);
  3418. if (GET_PCI_FDO_FIELD(ParentFdoExtension, "BaseBus", BaseBus)) {
  3419. dprintf(
  3420. "Failed to read memory at %08x for sizeof FDO Extension.\n",
  3421. ParentFdoExtension
  3422. );
  3423. }
  3424. if (GET_PCI_PDO_FIELD(PdoExt, "Slot", slot)){
  3425. dprintf(
  3426. "Failed to read memory at %08x\n",
  3427. PdoExt
  3428. );
  3429. }
  3430. *Bus = BaseBus;
  3431. *Dev = slot.u.bits.DeviceNumber;
  3432. *Func = slot.u.bits.FunctionNumber;
  3433. }
  3434. VOID
  3435. DevExtPci(
  3436. ULONG64 Extension
  3437. )
  3438. /*++
  3439. Routine Description:
  3440. Dump a PCI Device extension.
  3441. Arguments:
  3442. Extension Address of the extension to be dumped.
  3443. Return Value:
  3444. None.
  3445. --*/
  3446. {
  3447. ULONG64 pdo=0, fdoX=0, pdoX=0, pcifield=0;
  3448. ULONG Signature=0, fieldoffset=0;
  3449. ULONG bus=0xff,dev=0xff,func=0xff;
  3450. USHORT vendorId=0xffff, deviceId=0xffff, subsystemVendorId=0xfff, subsystemId=0xffff;
  3451. UCHAR deviceState, baseClass, subClass, progIf, revisionId, interruptPin, rawInterruptLine, adjustedInterruptLine;
  3452. UCHAR secBus=0xff, subBus=0xff;
  3453. PUCHAR s;
  3454. PUCHAR bc;
  3455. PUCHAR sc;
  3456. ULONG i;
  3457. BOOLEAN found, subDecode=FALSE, isaBit=FALSE, vgaBit=FALSE;
  3458. if (GET_PCI_PDO_FIELD(Extension, "ExtensionType", Signature)) {
  3459. dprintf(
  3460. "Failed to read PCI object signature at %008p, giving up.\n",
  3461. Extension
  3462. );
  3463. return;
  3464. }
  3465. switch (Signature) {
  3466. case PciPdoExtensionType:
  3467. //
  3468. // PDO Extension.
  3469. //
  3470. DevExtPciGetBusDevFunc(Extension, &bus, &dev, &func);
  3471. dprintf("PDO Extension, Bus 0x%x, Device %x, Function %d.\n",
  3472. bus, dev, func
  3473. );
  3474. GET_PCI_PDO_FIELD(Extension, "PhysicalDeviceObject", pdo);
  3475. GET_PCI_PDO_FIELD(Extension, "ParentFdoExtension", fdoX);
  3476. dprintf(" DevObj %#08p PCI Parent Bus FDO DevExt %#08p\n",
  3477. pdo, fdoX
  3478. );
  3479. GET_PCI_PDO_FIELD(Extension, "DeviceState", deviceState);
  3480. GET_PCI_PDO_FIELD(Extension, "VendorId", vendorId);
  3481. GET_PCI_PDO_FIELD(Extension, "DeviceId", deviceId);
  3482. DevExtPciPrintDeviceState(deviceState);
  3483. s = DevExtPciFindVendorId(vendorId);
  3484. if (s != NULL) {
  3485. dprintf(" Vendor ID %04x (%s) Device ID %04X\n",
  3486. vendorId,
  3487. s,
  3488. deviceId
  3489. );
  3490. } else {
  3491. dprintf(
  3492. " Vendor ID %04x, Device ID %04X\n",
  3493. vendorId,
  3494. deviceId
  3495. );
  3496. }
  3497. GET_PCI_PDO_FIELD(Extension, "SubsystemVendorId", subsystemVendorId);
  3498. GET_PCI_PDO_FIELD(Extension, "SubsystemId", subsystemId);
  3499. if (subsystemVendorId || subsystemId) {
  3500. s = DevExtPciFindVendorId(subsystemVendorId);
  3501. if (s != NULL) {
  3502. dprintf(
  3503. " Subsystem Vendor ID %04x (%s) Subsystem ID %04X\n",
  3504. subsystemVendorId,
  3505. s,
  3506. subsystemId
  3507. );
  3508. } else {
  3509. dprintf(" Subsystem Vendor ID %04x, Subsystem ID %04X\n",
  3510. subsystemVendorId,
  3511. subsystemId
  3512. );
  3513. }
  3514. }
  3515. GET_PCI_PDO_FIELD(Extension, "BaseClass", baseClass);
  3516. GET_PCI_PDO_FIELD(Extension, "SubClass", subClass);
  3517. DevExtPciFindClassCodes(baseClass, subClass, &bc, &sc);
  3518. dprintf(" Class Base/Sub %02x/%02x (%s/%s)\n",
  3519. baseClass,
  3520. subClass,
  3521. bc,
  3522. sc);
  3523. GET_PCI_PDO_FIELD(Extension, "ProgIf", progIf);
  3524. GET_PCI_PDO_FIELD(Extension, "RevisionId", revisionId);
  3525. GET_PCI_PDO_FIELD(Extension, "InterruptPin", interruptPin);
  3526. GET_PCI_PDO_FIELD(Extension, "RawInterruptLine", rawInterruptLine);
  3527. GET_PCI_PDO_FIELD(Extension, "AdjustedInterruptLine", adjustedInterruptLine);
  3528. dprintf(" Programming Interface: %02x, Revision: %02x, IntPin: %02x, Line Raw/Adj %02x/%02x\n",
  3529. progIf,
  3530. revisionId,
  3531. interruptPin,
  3532. rawInterruptLine,
  3533. adjustedInterruptLine
  3534. );
  3535. {
  3536. USHORT enables=0;
  3537. GET_PCI_PDO_FIELD(Extension, "CommandEnables", enables);
  3538. dprintf(" Enables ((cmd & 7) = %x): %s%s%s",
  3539. enables,
  3540. enables == 0 ? "<none>" :
  3541. (enables & PCI_ENABLE_BUS_MASTER) ? "B" : "",
  3542. (enables & PCI_ENABLE_MEMORY_SPACE) ? "M" : "",
  3543. (enables & PCI_ENABLE_IO_SPACE) ? "I" : ""
  3544. );
  3545. GET_PCI_PDO_FIELD(Extension, "CapabilitiesPtr", pcifield);
  3546. if (pcifield) {
  3547. dprintf(" Capabilities Pointer = %02x\n", pcifield);
  3548. } else {
  3549. dprintf(" Capabilities Pointer = <none>\n");
  3550. }
  3551. }
  3552. GetFieldOffset("pci!PCI_PDO_EXTENSION", "PowerState", &fieldoffset);
  3553. DevExtPciPrintPowerState(Extension+fieldoffset);
  3554. if (baseClass == PCI_CLASS_BRIDGE_DEV) {
  3555. if ((subClass == PCI_SUBCLASS_BR_PCI_TO_PCI) ||
  3556. (subClass == PCI_SUBCLASS_BR_CARDBUS)) {
  3557. GetFieldOffset("pci!PCI_PDO_EXTENSION", "Dependent", &fieldoffset);
  3558. GetFieldValue(Extension+fieldoffset,
  3559. "pci!PCI_HEADER_TYPE_DEPENDENT",
  3560. "type1.SecondaryBus",
  3561. secBus);
  3562. GetFieldValue(Extension+fieldoffset,
  3563. "pci!PCI_HEADER_TYPE_DEPENDENT",
  3564. "type1.SecondaryBus",
  3565. subBus);
  3566. dprintf(" Bridge PCI-%s Secondary Bus = 0x%x, Subordinate Bus = 0x%x\n",
  3567. subClass == PCI_SUBCLASS_BR_PCI_TO_PCI
  3568. ? "PCI" : "CardBus",
  3569. secBus,
  3570. subBus
  3571. );
  3572. GetFieldValue(Extension+fieldoffset,
  3573. "pci!PCI_HEADER_TYPE_DEPENDENT",
  3574. "type1.SubtractiveDecode",
  3575. subDecode);
  3576. GetFieldValue(Extension+fieldoffset,
  3577. "pci!PCI_HEADER_TYPE_DEPENDENT",
  3578. "type1.IsaBitSet",
  3579. isaBit);
  3580. GetFieldValue(Extension+fieldoffset,
  3581. "pci!PCI_HEADER_TYPE_DEPENDENT",
  3582. "type1.VgaBitSet",
  3583. vgaBit);
  3584. if (subDecode || isaBit || vgaBit) {
  3585. CHAR preceed = ' ';
  3586. dprintf(" Bridge Flags:");
  3587. if (subDecode) {
  3588. dprintf("%c Subtractive Decode", preceed);
  3589. preceed = ',';
  3590. }
  3591. if (isaBit) {
  3592. dprintf("%c ISA", preceed);
  3593. preceed = ',';
  3594. }
  3595. if (vgaBit) {
  3596. dprintf("%c VGA", preceed);
  3597. preceed = ',';
  3598. }
  3599. dprintf("\n");
  3600. }
  3601. }
  3602. }
  3603. //
  3604. // Now lets parse our PCI_FUNCTION_RESOURCES struct
  3605. //
  3606. pcifield = 0;
  3607. GET_PCI_PDO_FIELD(Extension, "Resources", pcifield);
  3608. dprintf(" Requirements:");
  3609. if (pcifield) {
  3610. ULONG64 limit = 0, current=0;
  3611. ULONG ioSize=0, cmSize=0, type=0;
  3612. ULONG alignment, length, minhighpart, minlowpart, maxhighpart, maxlowpart;
  3613. ioSize = GetTypeSize("nt!IO_RESOURCE_DESCRIPTOR");
  3614. cmSize = GetTypeSize("nt!CM_PARTIAL_RESOURCE_DESCRIPTOR");
  3615. //
  3616. // Limit begins at offset 0
  3617. //
  3618. limit = pcifield;
  3619. found = FALSE;
  3620. dprintf(" Alignment Length Minimum Maximum\n");
  3621. for (i = 0; i < PCI_MAX_RANGE_COUNT; i++) {
  3622. type=0;
  3623. GetFieldValue(limit, "nt!IO_RESOURCE_DESCRIPTOR", "Type", type);
  3624. if (type == CmResourceTypeNull) {
  3625. continue;
  3626. }
  3627. GetFieldValue(limit, "nt!IO_RESOURCE_DESCRIPTOR", "u.Generic.Alignment", alignment);
  3628. GetFieldValue(limit, "nt!IO_RESOURCE_DESCRIPTOR", "u.Generic.Length", length);
  3629. GetFieldValue(limit, "nt!IO_RESOURCE_DESCRIPTOR", "u.Generic.MinimumAddress.HighPart", minhighpart);
  3630. GetFieldValue(limit, "nt!IO_RESOURCE_DESCRIPTOR", "u.Generic.MinimumAddress.LowPart", minlowpart);
  3631. GetFieldValue(limit, "nt!IO_RESOURCE_DESCRIPTOR", "u.Generic.MaximumAddress.HighPart", maxhighpart);
  3632. GetFieldValue(limit, "nt!IO_RESOURCE_DESCRIPTOR", "u.Generic.MaximumAddress.LowPart", maxlowpart);
  3633. dprintf(" %s: %08x %08x %08x%08x %08x%08x\n",
  3634. type == CmResourceTypeMemory ? "Memory" : " Io",
  3635. alignment,
  3636. length,
  3637. minhighpart,
  3638. minlowpart,
  3639. maxhighpart,
  3640. maxlowpart
  3641. );
  3642. limit += ioSize;
  3643. }
  3644. //
  3645. // Get the offset for Current so we can dump it next
  3646. //
  3647. GetFieldOffset("pci!PCI_FUNCTION_RESOURCES", "Current", &fieldoffset);
  3648. current = pcifield+fieldoffset;
  3649. dprintf(" Current:");
  3650. for (i = 0; i < PCI_MAX_RANGE_COUNT; i++) {
  3651. type=0;
  3652. length=0;
  3653. maxhighpart=0;
  3654. maxlowpart=0;
  3655. GetFieldValue(current, "nt!CM_PARTIAL_RESOURCE_DESCRIPTOR", "Type", type);
  3656. if (type == CmResourceTypeNull) {
  3657. continue;
  3658. }
  3659. if (!found) {
  3660. dprintf(" Start Length\n");
  3661. found = TRUE;
  3662. }
  3663. GetFieldValue(current, "nt!CM_PARTIAL_RESOURCE_DESCRIPTOR", "u.Generic.Start.HighPart", maxhighpart);
  3664. GetFieldValue(current, "nt!CM_PARTIAL_RESOURCE_DESCRIPTOR", "u.Generic.Start.LowPart", maxlowpart);
  3665. GetFieldValue(current, "nt!CM_PARTIAL_RESOURCE_DESCRIPTOR", "u.Generic.Length", length);
  3666. dprintf(" %s: %08x%08x %08x\n",
  3667. type == CmResourceTypeMemory ? "Memory" : " Io",
  3668. maxhighpart,
  3669. maxlowpart,
  3670. length
  3671. );
  3672. current += cmSize;
  3673. }
  3674. if (!found) {
  3675. dprintf(" <none>\n");
  3676. }
  3677. } else {
  3678. dprintf(" <none>\n");
  3679. }
  3680. GetFieldOffset("pci!PCI_PDO_EXTENSION", "SecondaryExtension", &fieldoffset);
  3681. GetFieldValue(Extension+fieldoffset, "nt!_SINGLE_LIST_ENTRY", "Next", pcifield);
  3682. DevExtPciPrintSecondaryExtensions(pcifield);
  3683. break;
  3684. case PciFdoExtensionType:
  3685. //
  3686. // FDO Extension
  3687. //
  3688. GET_PCI_FDO_FIELD(Extension, "BaseBus", bus);
  3689. GET_PCI_FDO_FIELD(Extension, "PhysicalDeviceObject", pdo);
  3690. dprintf("FDO Extension, Bus 0x%x, Parent PDO %#08p Bus is ", bus,pdo);
  3691. GET_PCI_FDO_FIELD(Extension, "BusRootFdoExtension", pcifield);
  3692. if (pcifield == Extension) {
  3693. dprintf("a root bus.\n");
  3694. } else {
  3695. GET_PCI_FDO_FIELD(Extension, "PhysicalDeviceObject", pcifield);
  3696. GetFieldValue(pcifield, "nt!_DEVICE_OBJECT", "DeviceExtension", pdoX);
  3697. if (!pdoX) {
  3698. dprintf("a child bus.\n");
  3699. }else{
  3700. DevExtPciGetBusDevFunc(pdoX, &bus, &dev, &func);
  3701. dprintf("a child of bus 0x%x.\n", bus);
  3702. }
  3703. }
  3704. GET_PCI_FDO_FIELD(Extension, "DeviceState", deviceState);
  3705. DevExtPciPrintDeviceState(deviceState);
  3706. GetFieldOffset("pci!PCI_FDO_EXTENSION", "PowerState", &fieldoffset);
  3707. DevExtPciPrintPowerState(Extension+fieldoffset);
  3708. GET_PCI_FDO_FIELD(Extension, "ChildWaitWakeCount", pcifield);
  3709. if (pcifield) {
  3710. dprintf("Number of PDO's with outstanding WAIT_WAKEs = %d\n", pcifield);
  3711. }
  3712. {
  3713. PUCHAR heading = " Child PDOXs:";
  3714. ULONG counter = 0;
  3715. ULONG64 list = 0;
  3716. GET_PCI_FDO_FIELD(Extension, "ChildPdoList", list);
  3717. while (list) {
  3718. if (counter == 0) {
  3719. dprintf(heading);
  3720. heading = "\n ";
  3721. counter = 1;
  3722. } else if (counter == 2) {
  3723. counter = 0;
  3724. } else {
  3725. counter++;
  3726. }
  3727. dprintf(" %#08p", list);
  3728. GET_PCI_PDO_FIELD(list, "Next", list);
  3729. }
  3730. dprintf("\n");
  3731. }
  3732. GetFieldOffset("pci!PCI_FDO_EXTENSION", "SecondaryExtension", &fieldoffset);
  3733. GetFieldValue(Extension+fieldoffset, "nt!_SINGLE_LIST_ENTRY", "Next", pcifield);
  3734. DevExtPciPrintSecondaryExtensions(pcifield);
  3735. break;
  3736. default:
  3737. dprintf("%08x doesn't seem to point to a PCI PDO or FDO extension,\n", Signature);
  3738. dprintf("the PCI Device object extension signatures don't match.\n");
  3739. return;
  3740. }
  3741. }
  3742. DECLARE_API( devext )
  3743. /*++
  3744. Routine Description:
  3745. Dumps a device extension.
  3746. Arguments:
  3747. address Address of the device extension to be dumped.
  3748. type Type of device extension.
  3749. Return Value:
  3750. None
  3751. --*/
  3752. {
  3753. #define DEVEXT_MAXTOKENS 3
  3754. #define DEVEXT_MAXBUFFER 80
  3755. #define DEVEXT_USAGE() { DevExtUsage(); return E_INVALIDARG; }
  3756. ULONG64 Extension = 0;
  3757. PUCHAR ExtensionType;
  3758. PUCHAR Tokens[DEVEXT_MAXTOKENS];
  3759. UCHAR Buffer[DEVEXT_MAXBUFFER];
  3760. PUCHAR s;
  3761. UCHAR c;
  3762. ULONG count;
  3763. //
  3764. // Validate parameters. Tokenize the incoming string, the first
  3765. // argument should be a (kernel mode) address, the second a string.
  3766. //
  3767. //
  3768. // args is const, we need to modify the buffer, copy it.
  3769. //
  3770. for (count = 0; count < DEVEXT_MAXBUFFER; count++) {
  3771. if ((Buffer[count] = args[count]) == '\0') {
  3772. break;
  3773. }
  3774. }
  3775. if (count == DEVEXT_MAXBUFFER) {
  3776. dprintf("Buffer to small to contain input arguments\n");
  3777. DEVEXT_USAGE();
  3778. }
  3779. if (TokenizeString(Buffer, Tokens, DEVEXT_MAXTOKENS) !=
  3780. (DEVEXT_MAXTOKENS - 1)) {
  3781. DEVEXT_USAGE();
  3782. }
  3783. if ((Extension = GetExpression(Tokens[0])) == 0) {
  3784. DEVEXT_USAGE();
  3785. }
  3786. // Signextend it
  3787. if (DBG_PTR_SIZE == sizeof(ULONG)) {
  3788. Extension = (ULONG64) (LONG64) (LONG) Extension;
  3789. }
  3790. if ((LONG64)Extension >= 0) {
  3791. DEVEXT_USAGE();
  3792. }
  3793. //
  3794. // The second argument should be a string telling us what kind of
  3795. // device extension to dump. Convert it to upper case to make life
  3796. // easier.
  3797. //
  3798. s = Tokens[1];
  3799. while ((c = *s) != '\0') {
  3800. *s++ = (UCHAR)toupper(c);
  3801. }
  3802. s = Tokens[1];
  3803. if (!strcmp(s, "PCI")) {
  3804. //
  3805. // It's a PCI device extension.
  3806. //
  3807. DevExtPci(Extension);
  3808. } else if (!strcmp(s, "PCMCIA")) {
  3809. //
  3810. // It's a PCMCIA device extension
  3811. //
  3812. DevExtPcmcia(Extension);
  3813. } else if (!strcmp(s, "HID")) {
  3814. //
  3815. // It's a HID device extension
  3816. //
  3817. DevExtHID(Extension);
  3818. } else if (!strcmp(s, "ISAPNP")) {
  3819. //
  3820. // Congratulations! It's an ISAPNP device extension
  3821. //
  3822. DevExtIsapnp(Extension);
  3823. #if 0
  3824. } else if (!strcmp(s, "SOME_OTHER_EXTENSION_TYPE")) {
  3825. //
  3826. // It's some other extension type.
  3827. //
  3828. DevExtSomeOther(Extension);
  3829. #endif
  3830. } else {
  3831. dprintf("Device extension type '%s' is not handled by !devext.\n", s);
  3832. }
  3833. return S_OK;
  3834. }
  3835. //
  3836. // pcitree data structures and functions
  3837. //
  3838. BOOLEAN
  3839. pcitreeProcessBus(
  3840. ULONG Indent,
  3841. ULONG64 InMemoryBusFdoX,
  3842. ULONG64 TreeTop
  3843. )
  3844. {
  3845. ULONG64 BusFdoX=InMemoryBusFdoX;
  3846. ULONG64 next;
  3847. PUCHAR bc, sc, vendor;
  3848. ULONG BaseBus, BaseClass, SubClass;
  3849. ULONG64 ChildPdoList;
  3850. #define PdoxFld(F,V) GET_PCI_PDO_FIELD(next, #F, V)
  3851. GET_PCI_FDO_FIELD(BusFdoX, "BaseBus", BaseBus);
  3852. GET_PCI_FDO_FIELD(BusFdoX, "ChildPdoList", next);
  3853. xdprintf(Indent,"");
  3854. dprintf( "Bus 0x%x (FDO Ext %08p)\n",
  3855. BaseBus,
  3856. InMemoryBusFdoX);
  3857. if (next == 0) {
  3858. xdprintf(Indent, "No devices have been enumerated on this bus.\n");
  3859. return TRUE;
  3860. }
  3861. Indent++;
  3862. do {
  3863. ULONG DeviceId, VendorId, DeviceNumber, FunctionNumber;
  3864. ULONG64 BridgeFdoExtension;
  3865. if (CheckControlC()) {
  3866. return FALSE;
  3867. }
  3868. if (PdoxFld(BaseClass,BaseClass)) {
  3869. xdprintf(Indent,"FAILED to read PDO Ext at ");
  3870. dprintf("%08p, cannot continue this bus.\n",
  3871. next
  3872. );
  3873. return TRUE;
  3874. }
  3875. PdoxFld(SubClass,SubClass);
  3876. PdoxFld(DeviceId,DeviceId);
  3877. PdoxFld(VendorId,VendorId);
  3878. PdoxFld(Slot.u.bits.DeviceNumber,DeviceNumber);
  3879. PdoxFld(Slot.u.bits.FunctionNumber,FunctionNumber);
  3880. DevExtPciFindClassCodes(BaseClass, SubClass, &bc, &sc);
  3881. xdprintf(Indent, "");
  3882. dprintf("%02x%02x %04x%04x (d=%x,%s f=%d) devext %08p %s/%s\n",
  3883. BaseClass,
  3884. SubClass,
  3885. DeviceId,
  3886. VendorId,
  3887. DeviceNumber,
  3888. (DeviceNumber > 9 ? "" : " "),
  3889. FunctionNumber,
  3890. next,
  3891. bc,
  3892. sc
  3893. );
  3894. #if 0
  3895. // removed, too talkative. plj.
  3896. vendor = DevExtPciFindVendorId(PdoX.VendorId);
  3897. if (vendor) {
  3898. xdprintf(Indent, " (%s)\n", vendor);
  3899. }
  3900. #endif
  3901. if (BaseClass == PCI_CLASS_BRIDGE_DEV && SubClass == PCI_SUBCLASS_BR_PCI_TO_PCI) {
  3902. //
  3903. // Process child bus.
  3904. //
  3905. PdoxFld(BridgeFdoExtension,BridgeFdoExtension);
  3906. //
  3907. // Recurse.
  3908. //
  3909. if (pcitreeProcessBus(Indent, BridgeFdoExtension, TreeTop) == FALSE) {
  3910. //
  3911. // Error, exit.
  3912. //
  3913. return FALSE;
  3914. }
  3915. }
  3916. PdoxFld(Next, next);
  3917. } while (next);
  3918. #undef PdoxFld
  3919. return TRUE;
  3920. }
  3921. DECLARE_API( pcitree )
  3922. /*++
  3923. Routine Description:
  3924. Dumps the pci tree. (Why is this here? Because the other PCI stuff
  3925. ended up in here because devnode was such a useful base).
  3926. Arguments:
  3927. None
  3928. Return Value:
  3929. None
  3930. --*/
  3931. {
  3932. ULONG Signature;
  3933. ULONG64 TreeTop;
  3934. ULONG64 list;
  3935. ULONG64 addr;
  3936. ULONG indent = 0;
  3937. ULONG rootCount = 0;
  3938. addr = GetExpression("Pci!PciFdoExtensionListHead");
  3939. if (addr == 0) {
  3940. dprintf("Error retrieving address of PciFdoExtensionListHead\n");
  3941. return E_INVALIDARG;
  3942. }
  3943. if (!ReadPointer(addr, &list)) {
  3944. dprintf("Error reading PciFdoExtensionListHead (@%08p)\n", addr);
  3945. return E_INVALIDARG;
  3946. }
  3947. if (list == 0) {
  3948. dprintf(
  3949. "PciFdoExtensionListHead forward pointer is NULL, list is empty\n"
  3950. );
  3951. return E_INVALIDARG;
  3952. }
  3953. TreeTop = list;
  3954. do {
  3955. ULONG64 BusRootFdoExtension;
  3956. if (CheckControlC()) {
  3957. dprintf("User terminated with <control>C\n");
  3958. break;
  3959. }
  3960. if (GET_PCI_FDO_FIELD(list, "BusRootFdoExtension", BusRootFdoExtension)) {
  3961. dprintf(
  3962. "Error reading PCI FDO extension at %08p, quitting.\n",
  3963. list
  3964. );
  3965. return E_INVALIDARG;
  3966. }
  3967. if (BusRootFdoExtension == list) {
  3968. //
  3969. // This is the FDO for a root bus.
  3970. //
  3971. rootCount++;
  3972. if (pcitreeProcessBus(0, list, TreeTop) == FALSE) {
  3973. //
  3974. // Asked not to continue;
  3975. //
  3976. dprintf("User terminated output.\n");
  3977. break;
  3978. }
  3979. }
  3980. GET_PCI_FDO_FIELD(list, "List.Next", list);
  3981. } while (list != 0);
  3982. dprintf("Total PCI Root busses processed = %d\n", rootCount);
  3983. return S_OK;
  3984. }
  3985. VOID
  3986. DumpDeviceCapabilities(
  3987. ULONG64 caps
  3988. ) {
  3989. FIELD_INFO fields [] = {
  3990. { "DeviceD1", "Spare1", 0, 0, 0, NULL},
  3991. { "DeviceD2", "\tDeviceD2", 0, 0, 0, NULL},
  3992. { "LockSupported", "\tLock", 0, 0, 0, NULL},
  3993. { "EjectSupported","\tEject", 0, 0, 0, NULL},
  3994. { "Removeable", "\tRemoveable", 0, 0, 0, NULL},
  3995. { "DockDevice", "\nDock Device",0, 0, 0, NULL},
  3996. { "UniqueID", "Unique ID", 0, 0, 0, NULL},
  3997. { "SilentInstall", "\tSilent Install", 0, 0, 0, NULL},
  3998. { "RawDeviceOK", "\tRawDeviceOK",0, 0, 0, NULL},
  3999. { "Address", "\nAddress", 0, 0, 0, NULL},
  4000. { "UINumber", "", 0, 0, 0, NULL},
  4001. { "DeviceState", "\nDevice State : ", 0, DBG_DUMP_FIELD_ARRAY , 0, NULL},
  4002. { "SystemWake", "\nSystemWake", 0, 0, 0, NULL},
  4003. { "DeviceWake", "", 0, 0, 0, NULL},
  4004. };
  4005. UCHAR nm[] = "_DEVICE_CAPABILITIES";
  4006. SYM_DUMP_PARAM Sym = {
  4007. sizeof (SYM_DUMP_PARAM),
  4008. &nm[0],
  4009. DBG_DUMP_NO_OFFSET | DBG_DUMP_COMPACT_OUT,
  4010. caps,
  4011. NULL,
  4012. NULL,
  4013. NULL,
  4014. sizeof (fields) / sizeof (FIELD_INFO),
  4015. &fields[0],
  4016. };
  4017. dprintf ("PnP CAPS: \n");
  4018. Ioctl(IG_DUMP_SYMBOL_INFO, &Sym, sizeof (Sym));
  4019. }
  4020. #if 0
  4021. VOID
  4022. DumpDeviceCapabilities(
  4023. PDEVICE_CAPABILITIES caps
  4024. )
  4025. {
  4026. ULONG i,j,k;
  4027. ULONG bitmask;
  4028. PCHAR bits [] = {
  4029. "Spare1",
  4030. "Spare1",
  4031. "Lock",
  4032. "Eject",
  4033. "Removeable",
  4034. "Dock Device",
  4035. "Unique ID",
  4036. "Silent Install",
  4037. "RawDeviceOK"
  4038. };
  4039. bitmask = * (((PULONG) caps) + 1);
  4040. dprintf ("PnP CAPS: ");
  4041. for (i = 0, j = 1, k = 0; i < sizeof (bits); i++, j <<= 1) {
  4042. if (bitmask & j) {
  4043. if (k) {
  4044. dprintf("\n ");
  4045. }
  4046. k ^= 1;
  4047. dprintf(bits [i]);
  4048. }
  4049. }
  4050. dprintf("\n");
  4051. dprintf(" Address %x UINumber %x \n",
  4052. caps->Address,
  4053. caps->UINumber);
  4054. dprintf(" Device State [");
  4055. for (i = 0; i < PowerSystemMaximum; i ++) {
  4056. dprintf ("%02x ", (caps->DeviceState [i] & 0xFF));
  4057. }
  4058. dprintf("]\n");
  4059. dprintf(" System Wake %x Device Wake %x\n",
  4060. caps->SystemWake,
  4061. caps->DeviceWake);
  4062. dprintf("\n");
  4063. }
  4064. #endif
  4065. VOID
  4066. DumpTranslator(
  4067. IN DWORD Depth,
  4068. IN ULONG64 TranslatorAddr
  4069. )
  4070. /*++
  4071. Routine Description:
  4072. Dumps out the specified translator.
  4073. Arguments:
  4074. Depth - Supplies the print depth.
  4075. TranslatorAddr - Supplies the original address of the arbiter (on the target)
  4076. Translator - Supplies the arbiter
  4077. Return Value:
  4078. None.
  4079. --*/
  4080. {
  4081. // TRANSLATOR_INTERFACE interface;
  4082. UCHAR buffer[256];
  4083. ULONG64 displacement;
  4084. ULONG ResourceType;
  4085. ULONG64 TranslatorInterface, TranslateResources, TranslateResourceRequirements;
  4086. if (GetFieldValue(TranslatorAddr,
  4087. "nt!_PI_RESOURCE_TRANSLATOR_ENTRY",
  4088. "ResourceType",
  4089. ResourceType)) {
  4090. xdprintf( Depth, "");
  4091. dprintf( "Could not read translator entry %08p\n",
  4092. TranslatorAddr
  4093. );
  4094. return;
  4095. }
  4096. GetFieldValue(TranslatorAddr,"nt!_PI_RESOURCE_TRANSLATOR_ENTRY","TranslatorInterface", TranslatorInterface);
  4097. xdprintf(Depth,
  4098. "%s Translator\n",
  4099. GetCmResourceTypeString((UCHAR)ResourceType)
  4100. );
  4101. if (GetFieldValue(TranslatorInterface,
  4102. "nt!_TRANSLATOR_INTERFACE",
  4103. "TranslateResources",
  4104. TranslateResources)) {
  4105. dprintf("Error reading TranslatorInterface %08p for TranslatorEntry at %08p\n",
  4106. TranslatorInterface,
  4107. TranslatorAddr);
  4108. return;
  4109. }
  4110. GetSymbol(TranslateResources, buffer, &displacement);
  4111. xdprintf(Depth+1, "Resources: %s", buffer, displacement);
  4112. if (displacement != 0) {
  4113. dprintf("+0x%1p\n", displacement);
  4114. } else {
  4115. dprintf("\n");
  4116. }
  4117. GetFieldValue(TranslatorInterface,"nt!_TRANSLATOR_INTERFACE",
  4118. "TranslateResourceRequirements",TranslateResourceRequirements);
  4119. GetSymbol(TranslateResourceRequirements, buffer, &displacement);
  4120. xdprintf(Depth+1, "Requirements: %s", buffer, displacement);
  4121. if (displacement != 0) {
  4122. dprintf("+0x%1p\n", displacement);
  4123. } else {
  4124. dprintf("\n");
  4125. }
  4126. return;
  4127. }
  4128. BOOLEAN
  4129. DumpTranslatorsForDevNode(
  4130. IN DWORD Depth,
  4131. IN ULONG64 DevNodeAddr,
  4132. IN DWORD Flags
  4133. )
  4134. /*++
  4135. Routine Description:
  4136. Dumps all the translators for the specified devnode. Recursively calls
  4137. itself on the specified devnode's children.
  4138. Arguments:
  4139. Depth - Supplies the print depth.
  4140. DevNodeAddr - Supplies the address of the devnode.
  4141. Flags - Supplies the type of arbiters to dump:
  4142. ARBITER_DUMP_IO
  4143. ARBITER_DUMP_MEMORY
  4144. ARBITER_DUMP_IRQ
  4145. ARBITER_DUMP_DMA
  4146. Return Value:
  4147. None
  4148. --*/
  4149. {
  4150. ULONG result;
  4151. ULONG64 nextTranslator;
  4152. ULONG64 translatorAddr;
  4153. BOOLEAN PrintedHeader = FALSE;
  4154. BOOLEAN continueDump = TRUE;
  4155. ULONG DeviceTranslatorListOffset, TransEntryOffset;
  4156. ULONG64 Child, Sibling;
  4157. if (GetFieldOffset("nt!_DEVICE_NODE", "DeviceTranslatorList", &DeviceTranslatorListOffset)) {
  4158. dprintf("_DEVICE_NODE type not found.\n");
  4159. return continueDump;
  4160. }
  4161. if (GetFieldOffset("nt!_PI_RESOURCE_TRANSLATOR_ENTRY", "DeviceTranslatorList", &TransEntryOffset)) {
  4162. dprintf("_PI_RESOURCE_TRANSLATOR_ENTRY type not found.\n");
  4163. return continueDump;
  4164. }
  4165. if (GetFieldValue(DevNodeAddr,
  4166. "nt!_DEVICE_NODE",
  4167. "DeviceTranslatorList.Flink",
  4168. nextTranslator)) {
  4169. xdprintf(Depth, ""); dprintf("%08p: Could not read device node\n", DevNodeAddr);
  4170. return continueDump;
  4171. }
  4172. // dprintf("Next %p, Devnode %p, Trans Off %x", nextTranslator, DevNodeAddr, DeviceTranslatorListOffset);
  4173. //
  4174. // Dump the list of translators
  4175. //
  4176. while (nextTranslator != DevNodeAddr+DeviceTranslatorListOffset) {
  4177. ULONG ResourceType;
  4178. if (CheckControlC()) {
  4179. continueDump = FALSE;
  4180. break;
  4181. }
  4182. translatorAddr = (nextTranslator-TransEntryOffset);
  4183. if (GetFieldValue(translatorAddr,
  4184. "nt!_PI_RESOURCE_TRANSLATOR_ENTRY",
  4185. "ResourceType",
  4186. ResourceType)) {
  4187. xdprintf( Depth, "");
  4188. dprintf ("Could not read translator entry %08p for devnode %08p\n",
  4189. translatorAddr,
  4190. DevNodeAddr);
  4191. break;
  4192. }
  4193. if (!PrintedHeader) {
  4194. UNICODE_STRING64 u;
  4195. dprintf("\n");
  4196. xdprintf(Depth, ""); dprintf("DEVNODE %08p ", DevNodeAddr);
  4197. GetFieldValue(DevNodeAddr,"nt!_DEVICE_NODE","InstancePath.Buffer", u.Buffer);
  4198. GetFieldValue(DevNodeAddr,"nt!_DEVICE_NODE","InstancePath.Length", u.Length);
  4199. GetFieldValue(DevNodeAddr,"nt!_DEVICE_NODE","InstancePath.MaximumLength", u.MaximumLength);
  4200. if (u.Buffer != 0) {
  4201. dprintf("(");
  4202. DumpUnicode64(u);
  4203. dprintf(")");
  4204. }
  4205. dprintf("\n");
  4206. PrintedHeader = TRUE;
  4207. }
  4208. if (((ResourceType == CmResourceTypePort) && (Flags & ARBITER_DUMP_IO)) ||
  4209. ((ResourceType == CmResourceTypeInterrupt) && (Flags & ARBITER_DUMP_IRQ)) ||
  4210. ((ResourceType == CmResourceTypeMemory) && (Flags & ARBITER_DUMP_MEMORY)) ||
  4211. ((ResourceType == CmResourceTypeDma) && (Flags & ARBITER_DUMP_DMA)) ||
  4212. ((ResourceType == CmResourceTypeBusNumber) && (Flags & ARBITER_DUMP_BUS_NUMBER))) {
  4213. DumpTranslator( Depth+1, translatorAddr);
  4214. }
  4215. GetFieldValue(translatorAddr,"nt!_PI_RESOURCE_TRANSLATOR_ENTRY","DeviceTranslatorList.Flink",nextTranslator);
  4216. }
  4217. GetFieldValue(DevNodeAddr,"nt!_DEVICE_NODE","Sibling", Sibling);
  4218. GetFieldValue(DevNodeAddr,"nt!_DEVICE_NODE","Child", Child);
  4219. //
  4220. // Dump this devnode's children (if any)
  4221. //
  4222. if (continueDump && Child) {
  4223. continueDump = DumpTranslatorsForDevNode( Depth+1, Child, Flags);
  4224. }
  4225. //
  4226. // Dump this devnode's siblings (if any)
  4227. //
  4228. if (continueDump && Sibling) {
  4229. continueDump = DumpTranslatorsForDevNode( Depth, Sibling, Flags);
  4230. }
  4231. return continueDump;
  4232. }
  4233. DECLARE_API( translator )
  4234. /*++
  4235. Routine Description:
  4236. Dumps all the translators in the system
  4237. !translator [flags]
  4238. flags 1 - I/O port arbiters
  4239. 2 - memory arbiters
  4240. 4 - IRQ arbiters
  4241. 8 - DMA arbiters
  4242. If no flags are specified, all translators are dumped.
  4243. Arguments:
  4244. args - optional flags specifying which arbiters to dump
  4245. Return Value:
  4246. None
  4247. --*/
  4248. {
  4249. DWORD Flags=0;
  4250. ULONG64 addr;
  4251. ULONG64 deviceNode;
  4252. if (!(Flags = (ULONG) GetExpression(args))) {
  4253. Flags = ARBITER_DUMP_ALL;
  4254. }
  4255. //
  4256. // Find the root devnode and dump its arbiters
  4257. //
  4258. addr = GetExpression( "nt!IopRootDeviceNode" );
  4259. if (addr == 0) {
  4260. dprintf("Error retrieving address of IopRootDeviceNode\n");
  4261. return E_INVALIDARG;
  4262. }
  4263. if (!ReadPointer(addr, &deviceNode)) {
  4264. dprintf("Error reading value of IopRootDeviceNode (%#010p)\n", addr);
  4265. return E_INVALIDARG;
  4266. }
  4267. DumpTranslatorsForDevNode(0, deviceNode, Flags);
  4268. return S_OK;
  4269. }
  4270. #define RAW_RANGE_DUMP_STATS_ONLY 0x00000001
  4271. VOID
  4272. DumpRawRangeEntry(
  4273. IN DWORD Depth,
  4274. IN ULONG64 RangeEntry
  4275. )
  4276. /*++
  4277. Routine Description:
  4278. Dumps out the specified RTLP_RANGE_LIST_ENTRY
  4279. Arguments:
  4280. Depth - Supplies the print depth.
  4281. RangeList - Supplies the address of the RTLP_RANGE_LIST_ENTRY
  4282. OwnerIsDevObj - Indicates that the owner field is a pointer to a DEVICE_OBJECT
  4283. Return Value:
  4284. None.
  4285. --*/
  4286. {
  4287. ULONG PublicFlags;
  4288. ULONG64 UserData, Owner;
  4289. ULONG64 Start, End;
  4290. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "Start", Start);
  4291. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "End", End);
  4292. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "PublicFlags", PublicFlags);
  4293. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "Allocated.UserData", UserData);
  4294. GetFieldValue(RangeEntry, "nt!_RTLP_RANGE_LIST_ENTRY", "Allocated.Owner", Owner);
  4295. xdprintf(Depth, "");
  4296. dprintf ("%016I64x - %016I64x %c%c %08p %08p\n",
  4297. Start,
  4298. End,
  4299. PublicFlags & RTL_RANGE_SHARED ? 'S' : ' ',
  4300. PublicFlags & RTL_RANGE_CONFLICT ? 'C' : ' ',
  4301. UserData,
  4302. Owner
  4303. );
  4304. }
  4305. BOOLEAN
  4306. DumpRawRangeList(
  4307. IN DWORD Depth,
  4308. IN ULONG64 RangeListHead,
  4309. IN ULONG Flags,
  4310. IN PULONG MergedCount OPTIONAL,
  4311. IN PULONG EntryCount
  4312. )
  4313. /*++
  4314. Routine Description:
  4315. Dumps out the specified RTL_RANGE_LIST
  4316. Arguments:
  4317. Depth - Supplies the print depth.
  4318. RangeListHead - Supplies the address of the LIST_ENTRY containing the RTLP_RANGE_LIST_ENTRYs
  4319. Return Value:
  4320. None.
  4321. --*/
  4322. {
  4323. ULONG64 EntryAddr;
  4324. ULONG64 ListEntry;
  4325. ULONG ListEntryOffset;
  4326. BOOLEAN continueDump = TRUE;
  4327. //
  4328. // Read the range list
  4329. //
  4330. if (GetFieldValue(RangeListHead, "nt!_LIST_ENTRY", "Flink", ListEntry)) {
  4331. dprintf("Error reading RangeList %08p\n", RangeListHead);
  4332. return continueDump;
  4333. }
  4334. if (ListEntry == RangeListHead) {
  4335. xdprintf(Depth, "< none >\n");
  4336. return continueDump;
  4337. }
  4338. GetFieldOffset("nt!RTLP_RANGE_LIST_ENTRY", "ListEntry", &ListEntryOffset);
  4339. while (ListEntry != RangeListHead) {
  4340. ULONG PrivateFlags;
  4341. ULONG64 Start, End;
  4342. if (CheckControlC()) {
  4343. continueDump = FALSE;
  4344. break;
  4345. }
  4346. EntryAddr = ( ListEntry - ListEntryOffset);
  4347. if (GetFieldValue(EntryAddr, "nt!_RTLP_RANGE_LIST_ENTRY",
  4348. "PrivateFlags", PrivateFlags)) {
  4349. dprintf("Error reading RangeEntry %08p from RangeList %08p\n",
  4350. EntryAddr,
  4351. RangeListHead);
  4352. return continueDump;
  4353. }
  4354. (*EntryCount)++;
  4355. if (PrivateFlags & RTLP_RANGE_LIST_ENTRY_MERGED) {
  4356. ULONG MergedOffset;
  4357. //
  4358. // This is a merged range list, call ourselves recursively
  4359. //
  4360. if (MergedCount) {
  4361. (*MergedCount)++;
  4362. }
  4363. if (!(Flags & RAW_RANGE_DUMP_STATS_ONLY)) {
  4364. GetFieldValue(EntryAddr, "nt!_RTLP_RANGE_LIST_ENTRY", "Start", Start);
  4365. GetFieldValue(EntryAddr, "nt!_RTLP_RANGE_LIST_ENTRY", "End", End);
  4366. xdprintf(Depth, "Merged Range - %I64x-%I64x\n", Start, End);
  4367. }
  4368. GetFieldOffset("nt!_RTLP_RANGE_LIST_ENTRY", "Merged.ListHead", &MergedOffset);
  4369. continueDump = DumpRawRangeList( Depth+1,
  4370. EntryAddr + MergedOffset,
  4371. Flags,
  4372. MergedCount,
  4373. EntryCount);
  4374. if (!continueDump) {
  4375. break;
  4376. }
  4377. } else if (!(Flags & RAW_RANGE_DUMP_STATS_ONLY)) {
  4378. DumpRawRangeEntry(Depth, EntryAddr);
  4379. }
  4380. GetFieldValue(EntryAddr, "nt!_RTLP_RANGE_LIST_ENTRY", "ListEntry.Flink", ListEntry);
  4381. }
  4382. return continueDump;
  4383. }
  4384. DECLARE_API( rawrange )
  4385. /*++
  4386. Routine Description:
  4387. Dumps an RTL_RANGE_LIST
  4388. Arguments:
  4389. args - specifies the address of the RTL_RANGE_LIST
  4390. Return Value:
  4391. None
  4392. --*/
  4393. {
  4394. ULONG64 RangeList=0;
  4395. ULONG mergedCount = 0, entryCount = 0, flags=0, Offset;
  4396. if (GetExpressionEx(args, &RangeList, &args)) {
  4397. flags = (ULONG) GetExpression(args);
  4398. }
  4399. GetFieldOffset("nt!_RTLP_RANGE_LIST_ENTRY", "ListHead", &Offset);
  4400. DumpRawRangeList(0, RangeList + Offset, flags, &mergedCount, &entryCount);
  4401. dprintf("Stats\nMerged = %i\nEntries = %i\n", mergedCount, entryCount);
  4402. return S_OK;
  4403. }
  4404. VOID
  4405. DumpIoResourceDescriptor(
  4406. IN ULONG Depth,
  4407. IN ULONG64 Descriptor
  4408. )
  4409. {
  4410. ULONG64 Q1, Q2;
  4411. ULONG Option, Type, ShareDisposition, Flags, V1, V2, V3, Data[3];
  4412. #define Desc(F,V) GetFieldValue(Descriptor, "nt!IO_RESOURCE_LIST", #F, V)
  4413. Desc(Option,Option); Desc(Type,Type);
  4414. Desc(ShareDisposition,ShareDisposition);
  4415. Desc(Flags,Flags);
  4416. DumpResourceDescriptorHeader(Depth,
  4417. 0,
  4418. (UCHAR) Option,
  4419. (UCHAR) Type,
  4420. (UCHAR) ShareDisposition,
  4421. (USHORT) Flags);
  4422. Depth++;
  4423. switch (Type) {
  4424. case CmResourceTypeBusNumber:
  4425. Desc(u.BusNumber.MinBusNumber, V1);
  4426. Desc(u.BusNumber.MaxBusNumber, V2);
  4427. Desc(u.BusNumber.Length, V3);
  4428. xdprintf(Depth, "0x%x - 0x%x for length 0x%x\n",
  4429. V1, V2, V3);
  4430. break;
  4431. case CmResourceTypePort:
  4432. case CmResourceTypeMemory:
  4433. Desc(u.Generic.Length, V1);
  4434. Desc(u.Generic.Alignment, V2);
  4435. Desc(u.Port.MinimumAddress.QuadPart, Q1);
  4436. Desc(u.Port.MaximumAddress.QuadPart, Q2);
  4437. xdprintf(Depth, "%#08lx byte range with alignment %#08lx\n", V1, V2);
  4438. xdprintf(Depth, "%I64x - %#I64x\n", Q1, Q2);
  4439. case CmResourceTypeInterrupt:
  4440. Desc(u.Interrupt.MinimumVector,V1);
  4441. Desc(u.Interrupt.MaximumVector,V2);
  4442. xdprintf(Depth, "0x%x - 0x%x\n", V1,V2);
  4443. break;
  4444. case CmResourceTypeDma:
  4445. Desc(u.Dma.MinimumChannel,V1);
  4446. Desc(u.Dma.MaximumChannel,V2);
  4447. xdprintf(Depth, "0x%x - 0x%x\n",V1, V2);
  4448. break;
  4449. default:
  4450. Desc(u.DevicePrivate.Data, Data);
  4451. xdprintf(Depth,
  4452. "Data: : 0x%x 0x%x 0x%x\n",
  4453. Data[0],
  4454. Data[1],
  4455. Data[2]);
  4456. break;
  4457. }
  4458. #undef Desc
  4459. }
  4460. DECLARE_API( ioresdes )
  4461. {
  4462. ULONG64 descriptorAddr;
  4463. descriptorAddr = GetExpression(args);
  4464. DumpIoResourceDescriptor(0, descriptorAddr);
  4465. return S_OK;
  4466. }
  4467. DECLARE_API(pnpevent)
  4468. /*++
  4469. Routine Description:
  4470. Dump a device object.
  4471. Arguments:
  4472. args - the location of the device object to dump.
  4473. Return Value:
  4474. None
  4475. --*/
  4476. {
  4477. ULONG64 deviceEventListAddr;
  4478. ULONG64 listHead;
  4479. ULONG64 deviceEvent = 0;
  4480. ULONG verbose = 0;
  4481. ULONG64 address;
  4482. ULONG offset;
  4483. BOOL followLinks;
  4484. ULONG64 status = 0, flink = 0, blink = 0;
  4485. ULONG eventQ_Header_SignalState = 0, lk_Event_Hdr_SignalState = 0;
  4486. address = GetExpression( "nt!PpDeviceEventList" );
  4487. if (address == 0) {
  4488. dprintf("Error retrieving address of PpDeviceEventList\n");
  4489. return E_INVALIDARG;
  4490. }
  4491. if (!ReadPointer(address, &deviceEventListAddr)) {
  4492. dprintf("Error reading value of PpDeviceEventList (%#010lx)\n", address);
  4493. return E_INVALIDARG;
  4494. }
  4495. if (GetFieldOffset("nt!_PNP_DEVICE_EVENT_LIST", "List", &offset)) {
  4496. dprintf("Cannot find _PNP_DEVICE_EVENT_LIST.List type.\n");
  4497. return E_INVALIDARG;
  4498. }
  4499. listHead = deviceEventListAddr + offset;
  4500. dprintf("\n********************************************************************************\n");
  4501. dprintf("Dumping PnP DeviceEvent Queue @ 0x%08p\n", deviceEventListAddr);
  4502. dprintf("********************************************************************************\n\n");
  4503. if (GetFieldValue(deviceEventListAddr, "nt!_PNP_DEVICE_EVENT_LIST", "Status", status)) {
  4504. dprintf("Error reading PpDeviceEventList->Status (%#010p)\n", deviceEventListAddr);
  4505. return E_INVALIDARG;
  4506. }
  4507. if (GetFieldValue(deviceEventListAddr, "nt!_PNP_DEVICE_EVENT_LIST", "EventQueueMutex.Header.SignalState", eventQ_Header_SignalState)) {
  4508. dprintf("Error reading PpDeviceEventList->EventQueueMutex.Header.SignalState (%#010p)\n", deviceEventListAddr);
  4509. return E_INVALIDARG;
  4510. }
  4511. if (GetFieldValue(deviceEventListAddr, "nt!_PNP_DEVICE_EVENT_LIST", "Lock.Event.Header.SignalState", lk_Event_Hdr_SignalState)) {
  4512. dprintf("Error reading PpDeviceEventList->Lock.Event.Header.SignalState (%#010p)\n", deviceEventListAddr);
  4513. return E_INVALIDARG;
  4514. }
  4515. if (GetFieldValue(deviceEventListAddr, "nt!_PNP_DEVICE_EVENT_LIST", "List.Flink", flink)) {
  4516. dprintf("Error reading PpDeviceEventList->List.Flink (%#010p)\n", deviceEventListAddr);
  4517. return E_INVALIDARG;
  4518. }
  4519. if (GetFieldValue(deviceEventListAddr, "nt!_PNP_DEVICE_EVENT_LIST", "List.Blink", blink)) {
  4520. dprintf("Error reading PpDeviceEventList->List.Blink (%#010p)\n", deviceEventListAddr);
  4521. return E_INVALIDARG;
  4522. }
  4523. dprintf(" Status = 0x%08I64X, EventQueueMutex is %sheld, Lock is %sheld\n",
  4524. status,
  4525. eventQ_Header_SignalState ? "not " : "",
  4526. lk_Event_Hdr_SignalState ? "not " : "");
  4527. dprintf(" List = 0x%08p, 0x%08p\n", flink, blink);
  4528. if (GetExpressionEx(args, &deviceEvent, &args)) {
  4529. verbose = (ULONG) GetExpression(args);
  4530. }
  4531. if (deviceEvent == 0) {
  4532. ULONG listEntryOffset = 0;
  4533. if (flink == listHead) {
  4534. dprintf("Event list is empty\n");
  4535. return E_INVALIDARG;
  4536. }
  4537. //
  4538. // Now get addtess of PNP_DEVICE_EVENT_ENTRY
  4539. //
  4540. if (GetFieldOffset("nt!_PNP_DEVICE_EVENT_ENTRY", "ListEntry", &offset)) {
  4541. dprintf("Cannot find _PNP_DEVICE_EVENT_ENTRY type.\n");
  4542. return E_INVALIDARG;
  4543. }
  4544. deviceEvent = flink - offset; // CONTAINING_RECORD(deviceEventList.List.Flink, PNP_DEVICE_EVENT_ENTRY, ListEntry);
  4545. followLinks = TRUE;
  4546. } else {
  4547. followLinks = FALSE;
  4548. }
  4549. DumpDeviceEventEntry( deviceEvent, listHead, followLinks );
  4550. return S_OK;
  4551. }
  4552. BOOLEAN
  4553. DumpDeviceEventEntry(
  4554. ULONG64 DeviceEvent,
  4555. ULONG64 ListHead,
  4556. BOOL FollowLinks
  4557. )
  4558. {
  4559. BOOLEAN continueDump = TRUE;
  4560. ULONG64 flink=0, blink=0, argument=0, callerEvent=0, callback=0, context=0;
  4561. ULONG64 vetoType=0, vetoName=0;
  4562. ULONG dataSize=0;
  4563. ULONG offset;
  4564. ULONG64 dataAddress;
  4565. dprintf("\nDumping DeviceEventEntry @ 0x%08p\n", DeviceEvent);
  4566. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "ListEntry.Flink", flink)) {
  4567. dprintf("Error reading DeviceEvent->ListEntry.Flink (%#010p)\n", DeviceEvent);
  4568. return FALSE;
  4569. }
  4570. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "ListEntry.Blink", blink)) {
  4571. dprintf("Error reading DeviceEvent->ListEntry.Blink (%#010p)\n", DeviceEvent);
  4572. return FALSE;
  4573. }
  4574. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "CallerEvent", callerEvent)) {
  4575. dprintf("Error reading DeviceEvent->CallerEvent (%#010p)\n", DeviceEvent);
  4576. return FALSE;
  4577. }
  4578. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "Callback", callback)) {
  4579. dprintf("Error reading DeviceEvent->Callback (%#010p)\n", DeviceEvent);
  4580. return FALSE;
  4581. }
  4582. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "Context", context)) {
  4583. dprintf("Error reading DeviceEvent->Context (%#010p)\n", DeviceEvent);
  4584. return FALSE;
  4585. }
  4586. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "VetoType", vetoType)) {
  4587. dprintf("Error reading DeviceEvent->VetoType (%#010p)\n", DeviceEvent);
  4588. return FALSE;
  4589. }
  4590. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "VetoName", vetoName)) {
  4591. dprintf("Error reading DeviceEvent->VetoName (%#010p)\n", DeviceEvent);
  4592. return FALSE;
  4593. }
  4594. dprintf(" ListEntry = 0x%08p, 0x%08p, Argument = 0x%08I64x\n",
  4595. flink, blink, argument);
  4596. dprintf(" CallerEvent = 0x%08p, Callback = 0x%08p, Context = 0x%08p\n",
  4597. callerEvent, callback, context);
  4598. dprintf(" VetoType = 0x%08p, VetoName = 0x%08p\n",
  4599. vetoType, vetoName);
  4600. if (GetFieldOffset("nt!_PNP_DEVICE_EVENT_ENTRY", "Data", &offset)) {
  4601. dprintf("Cannot find offset of Data in _PNP_DEVICE_EVENT_ENTRY type.\n");
  4602. return FALSE;
  4603. }
  4604. dataAddress = DeviceEvent + offset;
  4605. if (GetFieldValue(DeviceEvent, "nt!_PNP_DEVICE_EVENT_ENTRY", "Data.TotalSize", dataSize)) {
  4606. dprintf("Error reading DeviceEvent->Data.TotalSize (%#010p)\n", DeviceEvent);
  4607. return FALSE;
  4608. }
  4609. DumpPlugPlayEventBlock( dataAddress, dataSize );
  4610. if (FollowLinks && flink != ListHead) {
  4611. if (CheckControlC()) {
  4612. continueDump = FALSE;
  4613. } else {
  4614. if (GetFieldOffset("nt!_PNP_DEVICE_EVENT_ENTRY", "ListEntry", &offset)) {
  4615. dprintf("Cannot find offset of ListEntry in _PNP_DEVICE_EVENT_ENTRY type.\n");
  4616. return FALSE;
  4617. }
  4618. continueDump = DumpDeviceEventEntry(flink - offset,
  4619. ListHead,
  4620. TRUE);
  4621. }
  4622. }
  4623. return continueDump;
  4624. }
  4625. PUCHAR DevNodeStateNames[] = {
  4626. "DeviceNodeUnspecified",
  4627. "DeviceNodeUninitialized",
  4628. "DeviceNodeInitialized",
  4629. "DeviceNodeDriversAdded",
  4630. "DeviceNodeResourcesAssigned",
  4631. "DeviceNodeStartPending",
  4632. "DeviceNodeStartCompletion",
  4633. "DeviceNodeStartPostWork",
  4634. "DeviceNodeStarted",
  4635. "DeviceNodeQueryStopped",
  4636. "DeviceNodeStopped",
  4637. "DeviceNodeRestartCompletion",
  4638. "DeviceNodeEnumeratePending",
  4639. "DeviceNodeEnumerateCompletion",
  4640. "DeviceNodeAwaitingQueuedDeletion",
  4641. "DeviceNodeAwaitingQueuedRemoval",
  4642. "DeviceNodeQueryRemoved",
  4643. "DeviceNodeRemovePendingCloses",
  4644. "DeviceNodeRemoved",
  4645. "DeviceNodeDeletePendingCloses",
  4646. "DeviceNodeDeleted"
  4647. };
  4648. #define DEVNODE_STATE_NAMES_SIZE (sizeof(DevNodeStateNames) / sizeof(DevNodeStateNames[0]))
  4649. VOID
  4650. PrintDevNodeState(
  4651. IN ULONG Depth,
  4652. IN PUCHAR Field,
  4653. IN ULONG State
  4654. )
  4655. {
  4656. UCHAR *Description;
  4657. ULONG stateIndex;
  4658. stateIndex = State - 0x300; //DeviceNodeUnspecified;
  4659. if (stateIndex < DEVNODE_STATE_NAMES_SIZE) {
  4660. Description = DevNodeStateNames[stateIndex];
  4661. } else {
  4662. Description = "Unknown State";
  4663. }
  4664. xdprintf(Depth, "%s = %s (0x%x)\n", Field, Description, State);
  4665. }
  4666. VOID
  4667. DumpMultiSz(
  4668. IN PWCHAR MultiSz
  4669. )
  4670. {
  4671. PWCHAR p = MultiSz;
  4672. ULONG length;
  4673. while (*p) {
  4674. length = wcslen(p);
  4675. dprintf(" %S\n", p);
  4676. p += length + 1;
  4677. }
  4678. }
  4679. struct {
  4680. CONST GUID *Guid;
  4681. PCHAR Name;
  4682. } EventGuidTable[] = {
  4683. // From wdmguid.h
  4684. { &GUID_HWPROFILE_QUERY_CHANGE, "GUID_HWPROFILE_QUERY_CHANGE" },
  4685. { &GUID_HWPROFILE_CHANGE_CANCELLED, "GUID_HWPROFILE_CHANGE_CANCELLED" },
  4686. { &GUID_HWPROFILE_CHANGE_COMPLETE, "GUID_HWPROFILE_CHANGE_COMPLETE" },
  4687. { &GUID_DEVICE_INTERFACE_ARRIVAL, "GUID_DEVICE_INTERFACE_ARRIVAL" },
  4688. { &GUID_DEVICE_INTERFACE_REMOVAL, "GUID_DEVICE_INTERFACE_REMOVAL" },
  4689. { &GUID_TARGET_DEVICE_QUERY_REMOVE, "GUID_TARGET_DEVICE_QUERY_REMOVE" },
  4690. { &GUID_TARGET_DEVICE_REMOVE_CANCELLED, "GUID_TARGET_DEVICE_REMOVE_CANCELLED" },
  4691. { &GUID_TARGET_DEVICE_REMOVE_COMPLETE, "GUID_TARGET_DEVICE_REMOVE_COMPLETE" },
  4692. { &GUID_PNP_CUSTOM_NOTIFICATION, "GUID_PNP_CUSTOM_NOTIFICATION" },
  4693. { &GUID_PNP_POWER_NOTIFICATION, "GUID_PNP_POWER_NOTIFICATION" },
  4694. // From pnpmgr.h
  4695. { &GUID_DEVICE_ARRIVAL, "GUID_DEVICE_ARRIVAL" },
  4696. { &GUID_DEVICE_ENUMERATED, "GUID_DEVICE_ENUMERATED" },
  4697. { &GUID_DEVICE_ENUMERATE_REQUEST, "GUID_DEVICE_ENUMERATE_REQUEST" },
  4698. { &GUID_DEVICE_START_REQUEST, "GUID_DEVICE_START_REQUEST" },
  4699. { &GUID_DEVICE_REMOVE_PENDING, "GUID_DEVICE_REMOVE_PENDING" },
  4700. { &GUID_DEVICE_QUERY_AND_REMOVE, "GUID_DEVICE_QUERY_AND_REMOVE" },
  4701. { &GUID_DEVICE_EJECT, "GUID_DEVICE_EJECT" },
  4702. { &GUID_DEVICE_NOOP, "GUID_DEVICE_NOOP" },
  4703. { &GUID_DEVICE_SURPRISE_REMOVAL, "GUID_DEVICE_SURPRISE_REMOVAL" },
  4704. { &GUID_DRIVER_BLOCKED, "GUID_DRIVER_BLOCKED" },
  4705. };
  4706. #define EVENT_GUID_TABLE_SIZE (sizeof(EventGuidTable) / sizeof(EventGuidTable[0]))
  4707. VOID
  4708. LookupGuid(
  4709. IN CONST GUID *Guid,
  4710. IN OUT PCHAR String,
  4711. IN ULONG StringLength
  4712. )
  4713. {
  4714. int i;
  4715. for (i = 0; i < EVENT_GUID_TABLE_SIZE; i++) {
  4716. if (memcmp(Guid, EventGuidTable[i].Guid, sizeof(Guid)) == 0) {
  4717. strncpy(String, EventGuidTable[i].Name, StringLength - 1);
  4718. String[StringLength - 1] = '\0';
  4719. return;
  4720. }
  4721. }
  4722. _snprintf( String, StringLength, "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",
  4723. Guid->Data1,
  4724. Guid->Data2,
  4725. Guid->Data3,
  4726. Guid->Data4[0],
  4727. Guid->Data4[1],
  4728. Guid->Data4[2],
  4729. Guid->Data4[3],
  4730. Guid->Data4[4],
  4731. Guid->Data4[5],
  4732. Guid->Data4[6],
  4733. Guid->Data4[7] );
  4734. }
  4735. PUCHAR EventCategoryStrings[] = {
  4736. "HardwareProfileChangeEvent",
  4737. "TargetDeviceChangeEvent",
  4738. "DeviceClassChangeEvent",
  4739. "CustomDeviceEvent",
  4740. "DeviceInstallEvent",
  4741. "DeviceArrivalEvent",
  4742. "PowerEvent",
  4743. "VetoEvent",
  4744. "BlockedDriverEvent"
  4745. };
  4746. #define N_EVENT_CATEGORIES (sizeof(EventCategoryStrings) / sizeof(EventCategoryStrings[0]))
  4747. VOID
  4748. DumpPlugPlayEventBlock(
  4749. ULONG64 PlugPlayEventBlock,
  4750. ULONG Size
  4751. )
  4752. {
  4753. GUID EventGuid;
  4754. UCHAR guidString[256];
  4755. UCHAR PnpEventTyp[] = "nt!PLUGPLAY_EVENT_BLOCK";
  4756. char categoryString[80];
  4757. ULONG64 Result=0, DeviceObject=0;
  4758. ULONG EventCategory=0, TotalSize=0, Flags=0;
  4759. ULONG64 PtrVal=0;
  4760. ULONG offset;
  4761. PUCHAR buffer;
  4762. ULONG powerData;
  4763. dprintf("\n Dumping PlugPlayEventBlock @ 0x%08X\n", PlugPlayEventBlock);
  4764. if (GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "EventGuid", EventGuid)) {
  4765. dprintf("Error reading PlugPlayEventBlock (%#010p)\n", PlugPlayEventBlock);
  4766. return;
  4767. }
  4768. LookupGuid(&EventGuid, guidString, sizeof(guidString));
  4769. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "EventCategory", EventCategory);
  4770. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "Result", Result );
  4771. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "Flags", Flags );
  4772. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "TotalSize", TotalSize );
  4773. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "DeviceObject", DeviceObject );
  4774. if ( EventCategory > N_EVENT_CATEGORIES) {
  4775. sprintf(categoryString, "Unknown category (%d)", EventCategory);
  4776. } else {
  4777. if (StringCchCopy(categoryString, sizeof(categoryString), EventCategoryStrings[ EventCategory ]) != S_OK)
  4778. {
  4779. categoryString[0] = 0;
  4780. }
  4781. }
  4782. dprintf(" EventGuid = %s\n Category = %s\n",
  4783. guidString, categoryString);
  4784. dprintf(" Result = 0x%08p, Flags = 0x%08X, TotalSize = %d\n",
  4785. Result, Flags, TotalSize );
  4786. dprintf(" DeviceObject = 0x%08p\n", DeviceObject);
  4787. switch (EventCategory) {
  4788. case HardwareProfileChangeEvent:
  4789. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "u.ProfileNotification.Notification", PtrVal);
  4790. dprintf( " Notification = 0x%08p\n", PtrVal );
  4791. break;
  4792. case DeviceArrivalEvent:
  4793. break;
  4794. case TargetDeviceChangeEvent:
  4795. dprintf( " DeviceIds:\n");
  4796. GetFieldOffset(PnpEventTyp, "u.TargetDevice.DeviceIds", &offset);
  4797. buffer = LocalAlloc(LPTR, Size - offset);
  4798. xReadMemory(PlugPlayEventBlock + offset, buffer, Size - offset);
  4799. DumpMultiSz( (PWCHAR)buffer );
  4800. LocalFree(buffer);
  4801. break;
  4802. case DeviceClassChangeEvent:
  4803. #if DEBUGGER_GETS_FIXED
  4804. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "u.DeviceClass.ClassGuid", EventGuid);
  4805. #else
  4806. GetFieldOffset(PnpEventTyp, "u.DeviceClass.ClassGuid", &offset);
  4807. xReadMemory(PlugPlayEventBlock + offset, &EventGuid, sizeof(EventGuid));
  4808. #endif
  4809. LookupGuid(&EventGuid, guidString, sizeof(guidString));
  4810. dprintf( " ClassGuid = %s\n", guidString );
  4811. GetFieldOffset(PnpEventTyp, "u.DeviceClass.SymbolicLinkName", &offset);
  4812. buffer = LocalAlloc(LPTR, Size - offset);
  4813. xReadMemory(PlugPlayEventBlock + offset, buffer, Size - offset);
  4814. dprintf( " SymbolicLinkName = %S\n", (PWCHAR) buffer );
  4815. LocalFree(buffer);
  4816. break;
  4817. case CustomDeviceEvent:
  4818. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "u.CustomNotification.NotificationStructure", PtrVal);
  4819. dprintf( " NotificationStructure = 0x%08p\n DeviceIds:\n",
  4820. PtrVal);
  4821. GetFieldOffset(PnpEventTyp, "u.CustomNotification.DeviceIds", &offset);
  4822. buffer = LocalAlloc(LPTR, Size - offset);
  4823. xReadMemory(PlugPlayEventBlock + offset, buffer, Size - offset);
  4824. DumpMultiSz( (PWCHAR) buffer );
  4825. LocalFree(buffer);
  4826. break;
  4827. case DeviceInstallEvent:
  4828. GetFieldOffset(PnpEventTyp, "u.InstallDevice.DeviceId", &offset);
  4829. buffer = LocalAlloc(LPTR, Size - offset);
  4830. xReadMemory(PlugPlayEventBlock + offset, buffer, Size - offset);
  4831. dprintf( " DeviceId = %S\n", (PWCHAR) buffer );
  4832. LocalFree(buffer);
  4833. break;
  4834. case PowerEvent:
  4835. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "u.PowerNotification.NotificationCode", powerData);
  4836. dprintf( " NotificationCode = 0x%08X\n", powerData );
  4837. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "u.PowerNotification.NotificationData", powerData);
  4838. dprintf( " NotificationData = 0x%08X\n", powerData );
  4839. break;
  4840. case BlockedDriverEvent:
  4841. #if DEBUGGER_GETS_FIXED
  4842. GetFieldValue(PlugPlayEventBlock, PnpEventTyp, "u.BlockedDriverNotification.BlockedDriverGuid", EventGuid);
  4843. #else
  4844. GetFieldOffset(PnpEventTyp, "u.BlockedDriverNotification.BlockedDriverGuid", &offset);
  4845. xReadMemory(PlugPlayEventBlock + offset, &EventGuid, sizeof(EventGuid));
  4846. #endif
  4847. LookupGuid(&EventGuid, guidString, sizeof(guidString));
  4848. dprintf( " BlockedDriverGuid = %s\n", guidString );
  4849. break;
  4850. }
  4851. }
  4852. DECLARE_API( rellist )
  4853. /*++
  4854. Routine Description:
  4855. Dump a device object.
  4856. Arguments:
  4857. args - the location of the device object to dump.
  4858. Return Value:
  4859. None
  4860. --*/
  4861. {
  4862. ULONG64 relationList=0;
  4863. ULONG verbose=0;
  4864. if (GetExpressionEx(args, &relationList, &args)) {
  4865. verbose = (ULONG) GetExpression(args);
  4866. }
  4867. DumpRelationsList( relationList,
  4868. (BOOLEAN) (verbose & DUMP_CM_RES),
  4869. (BOOLEAN) (verbose & DUMP_CM_RES_REQ_LIST),
  4870. (BOOLEAN) (verbose & DUMP_CM_RES_TRANS)
  4871. );
  4872. return S_OK;
  4873. }
  4874. DECLARE_API( lbt )
  4875. /*++
  4876. Routine Description:
  4877. Dump the legacy bus information table.
  4878. Arguments:
  4879. args - none.
  4880. Return Value:
  4881. None
  4882. --*/
  4883. {
  4884. CHAR buffer[256];
  4885. ULONG size, deviceNodeOffset;
  4886. ULONG64 deviceNode;
  4887. ULONG64 listHeadAddr, legacyBusEntryAddr;
  4888. ULONG64 head_Flink, head_Blink, link_Flink;
  4889. USHORT instancePath_Len, instancePath_Max;
  4890. ULONG busNumber;
  4891. ULONG64 instancePath_Buff, interfaceType;
  4892. CHAR deviceNodeType[] ="nt!_DEVICE_NODE";
  4893. CHAR listEntryType[] = "nt!_LIST_ENTRY" ;
  4894. INTERFACE_TYPE Iface;
  4895. if ((size = GetTypeSize(listEntryType)) == 0) {
  4896. dprintf("Failed to get the size of %s\n", listEntryType);
  4897. return E_INVALIDARG;
  4898. }
  4899. if (GetFieldOffset(deviceNodeType, "LegacyBusListEntry.Flink", &deviceNodeOffset)) {
  4900. dprintf("Failed to get the offset of LegacyBusListEntry from %s\n", deviceNodeType);
  4901. return E_INVALIDARG;
  4902. }
  4903. dprintf("Legacy Bus Information Table...\n");
  4904. for (Iface = Internal; Iface < MaximumInterfaceType; Iface++) {
  4905. sprintf(buffer, "nt!IopLegacyBusInformationTable + %x", Iface * size);
  4906. if ((listHeadAddr = GetExpression(buffer)) == 0) {
  4907. dprintf("Error retrieving address of bus number list for interface %d\n", Iface);
  4908. continue;
  4909. }
  4910. if (GetFieldValue(listHeadAddr, listEntryType, "Flink", head_Flink) ||
  4911. GetFieldValue(listHeadAddr, listEntryType, "Blink", head_Blink)) {
  4912. dprintf("Error reading value of bus number list head (0x%08p) for interface %d\n", listHeadAddr, Iface);
  4913. continue;
  4914. }
  4915. if (head_Flink == listHeadAddr) {
  4916. continue;
  4917. }
  4918. for ( legacyBusEntryAddr = head_Flink;
  4919. legacyBusEntryAddr != listHeadAddr;
  4920. legacyBusEntryAddr = link_Flink) {
  4921. deviceNode = legacyBusEntryAddr - deviceNodeOffset;
  4922. if (GetFieldValue(deviceNode, deviceNodeType, "BusNumber", busNumber)) {
  4923. dprintf("Error reading BusNumber from (0x%08p)\n", deviceNode);
  4924. break;
  4925. }
  4926. if (GetFieldValue(deviceNode, deviceNodeType, "InstancePath.Length", instancePath_Len)) {
  4927. dprintf("Error reading InstancePath.Length from (0x%08p)\n", deviceNode);
  4928. break;
  4929. }
  4930. if (GetFieldValue(deviceNode, deviceNodeType, "InstancePath.MaximumLength", instancePath_Max)) {
  4931. dprintf("Error reading InstancePath.MaximumLength from (0x%08p)\n", deviceNode);
  4932. break;
  4933. }
  4934. if (GetFieldValue(deviceNode, deviceNodeType, "InstancePath.Buffer", instancePath_Buff)) {
  4935. dprintf("Error reading InstancePath.Buffer from (0x%08p)\n", deviceNode);
  4936. break;
  4937. }
  4938. if (instancePath_Buff != 0) {
  4939. UNICODE_STRING64 v;
  4940. switch (Iface) {
  4941. case InterfaceTypeUndefined: dprintf("InterfaceTypeUndefined"); break;
  4942. case Internal: dprintf("Internal"); break;
  4943. case Isa: dprintf("Isa"); break;
  4944. case Eisa: dprintf("Eisa"); break;
  4945. case MicroChannel: dprintf("Micro Channel"); break;
  4946. case TurboChannel: dprintf("Turbo Channel"); break;
  4947. case PCIBus: dprintf("PCI"); break;
  4948. case VMEBus: dprintf("VME"); break;
  4949. case NuBus: dprintf("NuBus"); break;
  4950. case PCMCIABus: dprintf("PCMCIA"); break;
  4951. case CBus: dprintf("CBus"); break;
  4952. case MPIBus: dprintf("MPIBus"); break;
  4953. case MPSABus: dprintf("MPSABus"); break;
  4954. case ProcessorInternal: dprintf("Processor Internal"); break;
  4955. case InternalPowerBus: dprintf("Internal Power Bus"); break;
  4956. case PNPISABus: dprintf("PnP Isa"); break;
  4957. case PNPBus: dprintf("PnP Bus"); break;
  4958. default: dprintf("** Unknown Interface Type **"); break;
  4959. }
  4960. dprintf("%d - !devnode 0x%08p\n", busNumber, deviceNode);
  4961. v.Buffer = instancePath_Buff;
  4962. v.Length = instancePath_Len;
  4963. v.MaximumLength = instancePath_Max;
  4964. dprintf("\t\""); DumpUnicode64(v); dprintf("\"\n");
  4965. }
  4966. if (GetFieldValue(legacyBusEntryAddr, listEntryType, "Flink", link_Flink)) {
  4967. dprintf("Error reading Flink from (0x%08p)\n", legacyBusEntryAddr);
  4968. break;
  4969. }
  4970. }
  4971. }
  4972. return S_OK;
  4973. }