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.

2417 lines
68 KiB

  1. /*++
  2. Copyright (c) 1993-2000 Microsoft Corporation
  3. Module Name:
  4. setupext.c
  5. Abstract:
  6. This file contains the generic routines and initialization code
  7. for the kernel debugger extensions dll.
  8. --*/
  9. #define KDEXT_64BIT
  10. #include <windows.h>
  11. #include <wdbgexts.h>
  12. #include <stdio.h>
  13. #include <stdlib.h>
  14. #include <string.h>
  15. #include <ntverp.h>
  16. //
  17. // BUGBUG - need to find better way to get these values
  18. //
  19. #define HASH_BUCKET_COUNT 509
  20. #define WizPagesTypeMax 7
  21. #define LOADED_INF_SIG 0x24666e49
  22. #define INF_STYLE_NONE 0x00000000 // unrecognized or non-existent
  23. #define INF_STYLE_OLDNT 0x00000001 // winnt 3.x
  24. #define INF_STYLE_WIN4 0x00000002 // Win95
  25. #define SPOST_NONE 0
  26. #define SPOST_PATH 1
  27. #define SPOST_URL 2
  28. #define SPOST_MAX 3
  29. #define DRIVERSIGN_NONE 0x00000000
  30. #define DRIVERSIGN_WARNING 0x00000001
  31. #define DRIVERSIGN_BLOCKING 0x00000002
  32. #define SP_FILE_QUEUE_SIG 0xc78e1098
  33. #define FILEOP_COPY 0
  34. #define FILEOP_RENAME 1
  35. #define FILEOP_DELETE 2
  36. #define FILEOP_ABORT 0
  37. #define FILEOP_DOIT 1
  38. #define FILEOP_SKIP 2
  39. #define FILEOP_RETRY FILEOP_DOIT
  40. #define FILEOP_NEWPATH 4
  41. //
  42. // Local function prototypes
  43. //
  44. VOID
  45. UtilGetWStringField (
  46. ULONG64 Address,
  47. PUCHAR Structure,
  48. PUCHAR Field,
  49. PWCHAR Buffer,
  50. ULONG Size
  51. );
  52. VOID
  53. UtilReadWString (
  54. ULONG64 Address,
  55. PWCHAR Buffer,
  56. ULONG64 Size
  57. );
  58. VOID
  59. UtilDumpHex (
  60. PUCHAR Buffer,
  61. ULONG Size
  62. );
  63. VOID
  64. DumpUnwindList(
  65. ULONG64 pun,
  66. BOOL recursive
  67. );
  68. VOID
  69. DumpTargetEnt(
  70. ULONG64 pte
  71. );
  72. VOID
  73. DumpDelayMoveList(
  74. ULONG64 pdn,
  75. BOOL recursive
  76. );
  77. VOID
  78. DumpFileQueueNodeList(
  79. ULONG64 pfqn,
  80. ULONG64 mask,
  81. BOOL recursive
  82. );
  83. VOID
  84. DumpSourceMediaInfoList(
  85. ULONG64 smi,
  86. ULONG64 mask,
  87. BOOL recursive
  88. );
  89. VOID
  90. DumpCatalogInfoList(
  91. ULONG64 ci,
  92. ULONG64 mask,
  93. BOOL recursive
  94. );
  95. VOID
  96. DumpAltPlatformInfo(
  97. ULONG64 api
  98. );
  99. VOID
  100. DumpXFile(
  101. ULONG64 pxf,
  102. ULONG64 mask
  103. );
  104. VOID
  105. DumpXDirectory(
  106. ULONG64 pxdir,
  107. ULONG64 mask
  108. );
  109. VOID
  110. DumpXDrive(
  111. ULONG64 pxd,
  112. ULONG64 mask
  113. );
  114. VOID
  115. DumpInfVersionNode(
  116. ULONG64 ver
  117. );
  118. VOID
  119. DumpInfLine(
  120. ULONG64 line,
  121. ULONG64 valuedata
  122. );
  123. VOID
  124. DumpStringTableHeader(
  125. ULONG64 st
  126. );
  127. VOID
  128. DumpInfSection(
  129. ULONG64 section,
  130. ULONG64 linedata,
  131. ULONG64 valuedata
  132. );
  133. ULONG64
  134. GetStringTableData(
  135. ULONG64 st
  136. );
  137. ULONG64
  138. GetFirstNode(
  139. ULONG64 stdata,
  140. ULONG64 offset,
  141. PULONG64 poffset
  142. );
  143. ULONG64
  144. GetNextNode(
  145. ULONG64 stdata,
  146. ULONG64 node,
  147. PULONG64 offset
  148. );
  149. BOOL
  150. CheckInterupted(
  151. VOID
  152. );
  153. LPCSTR
  154. GetWizPage(
  155. DWORD i
  156. );
  157. VOID
  158. DumpOcComponent(
  159. ULONG64 offset,
  160. ULONG64 node,
  161. ULONG64 pcomp
  162. );
  163. //
  164. // globals
  165. //
  166. EXT_API_VERSION ApiVersion = { (VER_PRODUCTVERSION_W >> 8), (VER_PRODUCTVERSION_W & 0xff), EXT_API_VERSION_NUMBER64, 0 };
  167. WINDBG_EXTENSION_APIS ExtensionApis;
  168. USHORT SavedMajorVersion;
  169. USHORT SavedMinorVersion;
  170. ULONG64 EXPRLastDump = 0;
  171. //
  172. // this string is for supporting both the old and the new way of getting
  173. // data from the kernel. Maybe it will go away soon.
  174. //
  175. char ___SillyString[200];
  176. DllInit(
  177. HANDLE hModule,
  178. DWORD dwReason,
  179. DWORD dwReserved
  180. )
  181. {
  182. switch (dwReason) {
  183. case DLL_THREAD_ATTACH:
  184. break;
  185. case DLL_THREAD_DETACH:
  186. break;
  187. case DLL_PROCESS_DETACH:
  188. break;
  189. case DLL_PROCESS_ATTACH:
  190. break;
  191. }
  192. return TRUE;
  193. }
  194. VOID
  195. WinDbgExtensionDllInit(
  196. PWINDBG_EXTENSION_APIS64 lpExtensionApis, // 64Bit Change
  197. USHORT MajorVersion,
  198. USHORT MinorVersion
  199. )
  200. {
  201. ExtensionApis = *lpExtensionApis;
  202. SavedMajorVersion = MajorVersion;
  203. SavedMinorVersion = MinorVersion;
  204. return;
  205. }
  206. VOID
  207. CheckVersion(
  208. VOID
  209. )
  210. {
  211. return;
  212. }
  213. LPEXT_API_VERSION
  214. ExtensionApiVersion(
  215. VOID
  216. )
  217. {
  218. return &ApiVersion;
  219. }
  220. VOID
  221. UtilGetWStringField (
  222. ULONG64 Address,
  223. PUCHAR Structure,
  224. PUCHAR Field,
  225. PWCHAR Buffer,
  226. ULONG Size
  227. )
  228. {
  229. ULONG offset = 0;
  230. GetFieldOffset (Structure, Field, &offset);
  231. UtilReadWString (offset + Address, Buffer, Size);
  232. }
  233. VOID
  234. UtilReadWString (
  235. ULONG64 Address,
  236. PWCHAR Buffer,
  237. ULONG64 Size
  238. )
  239. {
  240. ULONG64 count = 0;
  241. ZeroMemory (Buffer, (ULONG) Size);
  242. while (1)
  243. {
  244. if (count == (Size-1)) {
  245. break;
  246. }
  247. ReadMemory (Address + (count * sizeof (WCHAR)),
  248. Buffer + count,
  249. sizeof (WCHAR),
  250. NULL);
  251. if (!Buffer[count]) {
  252. break;
  253. }
  254. count ++;
  255. }
  256. }
  257. ULONG64
  258. UtilStringToUlong64 (
  259. UCHAR *String
  260. )
  261. {
  262. ULONG64 ReturnValue = 0;
  263. sscanf (String, "%I64x", &ReturnValue);
  264. return ReturnValue;
  265. }
  266. VOID
  267. UtilDumpHex (
  268. PUCHAR Buffer,
  269. ULONG Size
  270. )
  271. {
  272. ULONG count = 0, count2 = 0;
  273. dprintf ("\n%08lx:", Buffer);
  274. while (count < Size) {
  275. if (! (count%16) && count) {
  276. dprintf ("|");
  277. for (count2 = 16; count2; count2--) {
  278. if (Buffer[count - count2] >= 0x30) {
  279. dprintf ("%c", (UCHAR) Buffer[count - count2]);
  280. } else {
  281. dprintf (".");
  282. }
  283. }
  284. dprintf ("\n%08lx:", Buffer + count);
  285. }
  286. dprintf ("%02x ", (UCHAR) Buffer[count]);
  287. count ++;
  288. }
  289. }
  290. VOID
  291. DumpUnwindList(
  292. ULONG64 pun,
  293. BOOL recursive
  294. )
  295. {
  296. InitTypeRead (pun, SETUPAPI!SP_UNWIND_NODE);
  297. dprintf( "\t\t***SP_UNWIND_NODE structure***\n" );
  298. dprintf( "\t\t NextNode : 0x%I64x\n", ReadField (NextNode));
  299. dprintf( "\t\t TargetID : 0x%I64x\n", ReadField (TargetID));
  300. dprintf( "\t\t SecurityDesc : 0x%I64x\n", ReadField (SecurityDesc));
  301. dprintf( "\t\t CreateTime : 0x%I64x 0x%I64x\n",
  302. ReadField (CreateTime.dwLowDateTime),
  303. ReadField (CreateTime.dwHighDateTime));
  304. dprintf( "\t\t AccessTime : 0x%I64x 0x%I64x\n",
  305. ReadField (AccessTime.dwLowDateTime),
  306. ReadField (AccessTime.dwHighDateTime));
  307. dprintf( "\t\t WriteTime : 0x%I64x 0x%I64x\n",
  308. ReadField (WriteTime.dwLowDateTime),
  309. ReadField (WriteTime.dwHighDateTime));
  310. if (ReadField (NextNode) && recursive) {
  311. if (CheckInterupted()) {
  312. return;
  313. }
  314. DumpUnwindList(ReadField (NextNode), TRUE );
  315. }
  316. }
  317. VOID
  318. DumpTargetEnt(
  319. ULONG64 pte
  320. )
  321. {
  322. InitTypeRead (pte, SETUPAPI!SP_TARGET_ENT);
  323. dprintf( "\t\t***SP_TARGET_ENT structure***\n" );
  324. dprintf( "\t\t TargetRoot : 0x%I64x\n", ReadField (TargetRoot));
  325. dprintf( "\t\t TargetSubDir : 0x%I64x\n", ReadField (TargetSubDir));
  326. dprintf( "\t\t TargetFilename : 0x%I64\n", ReadField (TargetFilename));
  327. dprintf( "\t\t BackupRoot : 0x%I64x\n", ReadField (BackupRoot));
  328. dprintf( "\t\t BackupSubDir : 0x%I64x\n", ReadField (BackupSubDir));
  329. dprintf( "\t\t BackupFilename : 0x%I64x\n", ReadField (BackupFilename));
  330. dprintf( "\t\t NewTargetFilename : 0x%I64x\n", ReadField (NewTargetFilename));
  331. dprintf( "\t\t InternalFlags : 0x%I64x\n", ReadField (InternalFlags));
  332. }
  333. VOID
  334. DumpDelayMoveList(
  335. ULONG64 pdn,
  336. BOOL recursive
  337. )
  338. {
  339. InitTypeRead (pdn, SETUPAPI!SP_DELAYMOVE_NODE);
  340. dprintf( "\t\t***SP_DELAYMOVE_NODE structure***\n" );
  341. dprintf( "\t\t NextNode : 0x%I64x\n", ReadField (NextNode));
  342. dprintf( "\t\t SourceFilename : 0x%I64x\n", ReadField (SourceFilename));
  343. dprintf( "\t\t TargetFilename : 0x%I64x\n", ReadField (TargetFilename));
  344. dprintf( "\t\t SecurityDesc (stringtable index) : 0x%I64x\n", ReadField (SecurityDesc));
  345. if (ReadField (NextNode) && recursive) {
  346. if (CheckInterupted()) {
  347. return;
  348. }
  349. DumpDelayMoveList( ReadField (Next), TRUE );
  350. }
  351. }
  352. VOID
  353. DumpFileQueueNodeList(
  354. ULONG64 pfqn,
  355. ULONG64 mask,
  356. BOOL recursive
  357. )
  358. {
  359. InitTypeRead (pfqn, SP_FILE_QUEUE_NODE);
  360. dprintf( "\t\t***SP_FILE_QUEUE_NODE structure***\n" );
  361. dprintf( "\t\t Next : 0x%I64x\n", ReadField (Next));
  362. dprintf( "\t\t Operation : 0x%I64x ( %s )\n", ReadField (Operation),
  363. (ReadField (Operation) == FILEOP_DELETE) ? "DELETE" :
  364. (ReadField (Operation) == FILEOP_RENAME) ? "RENAME" :
  365. "COPY" );
  366. dprintf( "\t\t SourceRootPath : 0x%I64x\n", ReadField (SourceRootPath));
  367. dprintf( "\t\t SourcePath : 0x%I64x\n", ReadField (SourcePath));
  368. dprintf( "\t\t SourceFilename : 0x%I64x\n", ReadField (SourceFilename));
  369. dprintf( "\t\t TargetDirectory : 0x%I64x\n", ReadField (TargetDirectory));
  370. dprintf( "\t\t SecurityDesc : 0x%I64x\n", ReadField (SecurityDesc));
  371. dprintf( "\t\t SourceMediaInfo : 0x%I64x\n", ReadField (SourceMediaInfo));
  372. if (ReadField (SourceMediaInfo) && recursive) {
  373. if (CheckInterupted()) {
  374. return;
  375. }
  376. DumpSourceMediaInfoList( ReadField (SourceMediaInfo), mask, FALSE );
  377. InitTypeRead (pfqn, SP_FILE_QUEUE_NODE);
  378. }
  379. dprintf( "\t\t StyleFlags : 0x%I64x\n", ReadField (StyleFlags));
  380. dprintf( "\t\t InternalFlags : 0x%I64x\n", ReadField (InternalFlags));
  381. dprintf( "\t\t CatalogInfo : 0x%I64x\n", ReadField (CatalogInfo));
  382. if (ReadField (CatalogInfo) && recursive) {
  383. if (CheckInterupted()) {
  384. return;
  385. }
  386. DumpCatalogInfoList( ReadField (CatalogInfo), mask, FALSE );
  387. InitTypeRead (pfqn, SP_FILE_QUEUE_NODE);
  388. }
  389. if (ReadField (Next) && recursive) {
  390. DumpFileQueueNodeList( ReadField (Next), mask, TRUE );
  391. }
  392. }
  393. VOID
  394. DumpSourceMediaInfoList(
  395. ULONG64 smi,
  396. ULONG64 mask,
  397. BOOL recursive
  398. )
  399. {
  400. InitTypeRead (smi, SETUPAPI!SOURCE_MEDIA_INFO);
  401. dprintf( "\t\t***SOURCE_MEDIA_INFO structure***\n" );
  402. dprintf( "\t\t Next : 0x%I64x\n", ReadField (Next));
  403. dprintf( "\t\t Description : 0x%I64x\n", ReadField (Description));
  404. dprintf( "\t\t DescriptionDisplayName : 0x%I64x\n", ReadField (DescriptionDisplayName));
  405. dprintf( "\t\t Tagfile : 0x%I64x\n", ReadField (Tagfile));
  406. dprintf( "\t\t SourceRootPath : 0x%I64x\n", ReadField (SourceRootPath));
  407. dprintf( "\t\t CopyQueue : 0x%I64x\n", ReadField (CopyQueue));
  408. if (ReadField (CopyQueue) && (mask & 8) && recursive) {
  409. if (CheckInterupted()) {
  410. return;
  411. }
  412. DumpFileQueueNodeList( ReadField (CopyQueue), mask, FALSE );
  413. InitTypeRead (smi, SETUPAPI!SOURCE_MEDIA_INFO);
  414. }
  415. dprintf( "\t\t CopyNodeCount : 0x%I64x\n", ReadField (CopyNodeCount));
  416. dprintf( "\t\t Flags : 0x%I64x\n", ReadField (Flags));
  417. if (ReadField (Next) && recursive) {
  418. if (CheckInterupted()) {
  419. return;
  420. }
  421. DumpSourceMediaInfoList( ReadField (next), mask, TRUE );
  422. }
  423. }
  424. VOID
  425. DumpCatalogInfoList(
  426. ULONG64 ci,
  427. ULONG64 mask,
  428. BOOL recursive
  429. )
  430. {
  431. WCHAR Buffer[200];
  432. InitTypeRead (ci, SETUPAPI!SPQ_CATALOG_INFO);
  433. dprintf( "\t\t***SPQ_CATALOG_INFO structure***\n" );
  434. dprintf( "\t\t Next : 0x%I64x\n", ReadField (Next));
  435. dprintf( "\t\t CatalogFileFromInf : 0x%I64x\n", ReadField (CatalogFileFromInf));
  436. dprintf( "\t\t AltCatalogFileFromInf : 0x%I64x\n", ReadField (AltCatalogFileFromInf));
  437. dprintf( "\t\t AltCatalogFileFromInfPending : 0x%I64x\n", ReadField (AltCatalogFileFromInfPending));
  438. dprintf( "\t\t InfFullPath : 0x%I64x\n", ReadField (InfFullPath));
  439. dprintf( "\t\t InfOriginalName : 0x%I64x\n", ReadField (InfOriginalName));
  440. dprintf( "\t\t InfFinalPath : 0x%I64x\n", ReadField (InfFinalPath));
  441. dprintf( "\t\t VerificationFailureError : 0x%I64x\n", ReadField (VerificationFailureError));
  442. dprintf( "\t\t Flags : 0x%I64x\n", ReadField (Flags));
  443. UtilGetWStringField (ci, "SETUPAPI!SPQ_CATALOG_INFO", "CatalogFilenameOnSystem", Buffer, sizeof (Buffer));
  444. dprintf( "\t\t CatalogFilenameOnSystem : %ws\n", Buffer);
  445. if (ReadField (Next) && recursive) {
  446. if (CheckInterupted()) {
  447. return;
  448. }
  449. DumpCatalogInfoList(ReadField (Next), mask, TRUE ) ;
  450. }
  451. }
  452. VOID
  453. DumpAltPlatformInfo(
  454. ULONG64 api
  455. )
  456. {
  457. InitTypeRead (api, SETUPAPI!SP_ALTPLATFORM_INFO);
  458. dprintf( "\t\t***SP_ALT_PLATFORM_INFO structure***\n" );
  459. dprintf( "\t\t cbSize : 0x%I64x\n", ReadField (cbSize));
  460. dprintf( "\t\t Platform : 0x%I64x\n", ReadField (Platform));
  461. dprintf( "\t\t MajorVersion : 0x%I64x\n", ReadField (MajorVersion));
  462. dprintf( "\t\t MinorVersion : 0x%I64x\n", ReadField (MinorVersion));
  463. dprintf( "\t\t ProcessorArchitecture : 0x%I64x\n", ReadField (ProcessorArchitecture));
  464. dprintf( "\t\t Reserved : 0x%I64x\n", ReadField (Reserved));
  465. }
  466. VOID
  467. DumpXFile(
  468. ULONG64 pxf,
  469. ULONG64 mask
  470. )
  471. {
  472. if ((mask & 4) == 0 ) {
  473. return;
  474. }
  475. InitTypeRead (pxf, SETUPAPI!XFILE);
  476. dprintf( "\t\t ***XFILE structure***\n" );
  477. dprintf( "\t\t CurrentSize : 0x%I64x", ReadField (CurrentSize));
  478. if (ReadField (CurrentSize) == -1) {
  479. dprintf( " (doesn't currently exist)" );
  480. }
  481. dprintf( "\n\t\t NewSize : 0x%I64x", ReadField (NewSize));
  482. if (ReadField (NewSize) == -1) {
  483. dprintf( " (will be deleted)" );
  484. }
  485. dprintf("\n");
  486. }
  487. VOID
  488. DumpXDirectory(
  489. ULONG64 pxdir,
  490. ULONG64 mask
  491. )
  492. {
  493. ULONG64 pst;
  494. DWORD i;
  495. ULONG64 offset;
  496. ULONG64 stdata = 0,pextradata = 0;
  497. //STRING_TABLE st;
  498. //PSTRING_NODEW node;//, prev;
  499. //PXFILE pxf;
  500. ULONG64 node = 0, boffset = 0, count = 0;
  501. WCHAR Buffer [200];
  502. ULONG64 pxf = 0;
  503. if ((mask & 2) == 0 ) {
  504. return;
  505. }
  506. InitTypeRead (pxdir, SETUPAPI!XDIRECTORY);
  507. dprintf( "\t\t ***XDIRECTORY structure***\n");
  508. dprintf( "\t\t SpaceRequired : 0x%x\n", ReadField (SpaceRequired));
  509. dprintf( "\t\t FilesTable : 08%08x\n", ReadField (FilesTable));
  510. pst = ReadField (FilesTable);
  511. DumpStringTableHeader (pst);
  512. stdata = GetStringTableData (pst);
  513. if (!stdata) {
  514. dprintf("error retrieving string table data!\n");
  515. return;
  516. }
  517. //
  518. // now, dump each node in the string table
  519. //
  520. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  521. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  522. if (!node) {
  523. // dprintf("No data at hash bucket %d\n", i);
  524. } else {
  525. dprintf("Data at hash bucket %d\n", i);
  526. while (node) {
  527. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  528. count = 0;
  529. while (1)
  530. {
  531. if (count == sizeof (Buffer)) {
  532. break;
  533. }
  534. ReadMemory (node + boffset + count,
  535. (PWCHAR) &Buffer + count/2,
  536. sizeof (WCHAR),
  537. NULL);
  538. if (!Buffer[count/2]) {
  539. break;
  540. }
  541. count +=2;
  542. }
  543. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  544. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  545. pxf = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  546. DumpXFile(pxf, mask );
  547. node = GetNextNode( stdata, node, &offset );
  548. if (CheckInterupted()) {
  549. return;
  550. }
  551. }
  552. }
  553. if (CheckInterupted()) {
  554. return;
  555. }
  556. }
  557. }
  558. VOID
  559. DumpXDrive(
  560. ULONG64 pxd,
  561. ULONG64 mask
  562. )
  563. {
  564. DWORD i;
  565. ULONG64 offset = 0;
  566. ULONG64 stdata = 0, pextradata = 0, pst = 0;
  567. //STRING_TABLE st;
  568. //PSTRING_NODEW node;//, prev;
  569. //PXDIRECTORY pxdir;
  570. ULONG64 node = 0, pxdir = 0, boffset = 0, count = 0;
  571. WCHAR Buffer [200];
  572. if ((mask & 1) == 0) {
  573. return;
  574. }
  575. InitTypeRead (pxd, SETUPAPI!XDRIVE);
  576. dprintf( "\t\t***XDRIVE structure***\n");
  577. dprintf( "\t\t SpaceRequired : 0x%I64x\n", ReadField (SpaceRequired));
  578. dprintf( "\t\t BytesPerCluster : 0x%I64x\n", ReadField (BytesPerCluster));
  579. dprintf( "\t\t Slop : 0x%I64x\n", ReadField (Slop));
  580. dprintf( "\t\t DirsTable : 0x%016I64x\n", ReadField (DirsTable));
  581. pst = ReadField (DirsTable);
  582. DumpStringTableHeader (pst);
  583. stdata = GetStringTableData(pst );
  584. if (!stdata) {
  585. dprintf("error retrieving string table data!\n");
  586. return;
  587. }
  588. //
  589. // now, dump each node in the string table
  590. //
  591. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  592. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  593. if (!node) {
  594. // dprintf("No data at hash bucket %d\n", i);
  595. } else {
  596. dprintf("Data at hash bucket %d\n", i);
  597. while (node) {
  598. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  599. count = 0;
  600. while (1)
  601. {
  602. if (count == sizeof (Buffer)) {
  603. break;
  604. }
  605. ReadMemory (node + boffset + count,
  606. (PWCHAR) &Buffer + count/2,
  607. sizeof (WCHAR),
  608. NULL);
  609. if (!Buffer[count/2]) {
  610. break;
  611. }
  612. count +=2;
  613. }
  614. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  615. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  616. pxdir = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  617. DumpXDirectory(pxdir, mask );
  618. node = GetNextNode( stdata, node, &offset );
  619. if (CheckInterupted()) {
  620. return;
  621. }
  622. }
  623. }
  624. if (CheckInterupted()) {
  625. return;
  626. }
  627. }
  628. }
  629. VOID
  630. DumpInfVersionNode(
  631. ULONG64 ver
  632. )
  633. {
  634. WCHAR Buffer[200];
  635. InitTypeRead (ver, SETUPAPI!INF_VERSION_NODE);
  636. dprintf("***INF_VERSION_NODE***\n");
  637. dprintf("\t FilenameSize : 0x%x\n", ReadField (FilenameSize));
  638. dprintf("\t DataBlock : 0x%x\n", ReadField (DataBlock));
  639. dprintf("\t DataSize : 0x%x\n", ReadField (DataSize));
  640. dprintf("\t DatumCount : 0x%x\n", ReadField (DatumCount));
  641. UtilGetWStringField (ver, "SETUPAPI!INF_VERSION_NODE", "Filename", Buffer, sizeof (Buffer));
  642. dprintf("\t Filename : %ws\n", Buffer);
  643. return;
  644. }
  645. VOID
  646. DumpInfLine(
  647. ULONG64 line,
  648. ULONG64 valuedata
  649. )
  650. {
  651. DWORD i;
  652. ULONG64 ptr = 0;
  653. ULONG64 data = 0;
  654. ULONG ulongptrsize = GetTypeSize ("SETUPAPI!ULONG_PTR");
  655. InitTypeRead (line, SETUPAPI!INF_LINE);
  656. dprintf("\t ValueCount : 0x%I64x\n", ReadField (ValueCount));
  657. dprintf("\t Flags : 0x%I64x\n", ReadField (Flags));
  658. dprintf("\t Values : 0x%I64x\n", ReadField (Values));
  659. if (ReadField (Flags) > 3) {
  660. return;
  661. }
  662. for (i = 0; i< ReadField (ValueCount); i++) {
  663. ptr = valuedata + (ReadField (Values) * ulongptrsize) + (i * ulongptrsize);
  664. ReadMemory (ptr, &data, ulongptrsize, NULL);
  665. dprintf("\t data [%ld] : 0x%I64x [0x%I64x]\n", i, ptr, data);
  666. if (CheckInterupted()) {
  667. return;
  668. }
  669. }
  670. }
  671. VOID
  672. DumpInfSection(
  673. ULONG64 section,
  674. ULONG64 linedata,
  675. ULONG64 valuedata
  676. )
  677. {
  678. DWORD i;
  679. //INF_LINE line;
  680. ULONG64 line;
  681. ULONG64 data;
  682. InitTypeRead (section, SETUPAPI!INF_SECTION);
  683. dprintf("***INF_SECTION***\n");
  684. dprintf("\t SectionName : 0x%I64x\n", ReadField (SectionName));
  685. dprintf("\t LineCount : 0x%I64x\n", ReadField (LineCount));
  686. dprintf("\t Lines : 0x%I64x\n", ReadField (Lines));
  687. for (i = 0; i< ReadField (LineCount); i++) {
  688. data = linedata + (GetTypeSize ("SETUPAPI!INF_LINE") * ReadField (Lines)) + GetTypeSize ("SETUPAPI!INF_LINE") * i;
  689. dprintf("***INF_LINE [%ld] at 0x%I64x***\n", i, data);
  690. DumpInfLine (data, valuedata);
  691. //
  692. // Have to reinit type read because of DumpInfLine
  693. //
  694. InitTypeRead (section, SETUPAPI!INF_SECTION);
  695. if (CheckInterupted()) {
  696. return;
  697. }
  698. }
  699. }
  700. VOID
  701. DumpStringTableHeader(
  702. ULONG64 st
  703. )
  704. {
  705. //
  706. // dump the string table header
  707. //
  708. InitTypeRead (st, SETUPAPI!STRING_TABLE);
  709. dprintf("\tBase Data ptr:\t0x%016I64x\n", ReadField (Data));
  710. dprintf("\tDataSize:\t0x%016I64x\n", ReadField (DataSize));
  711. dprintf("\tBufferSize:\t0x%016I64x\n", ReadField (BufferSize));
  712. dprintf("\tExtraDataSize:\t0x%016I64x\n", ReadField (ExtraDataSize));
  713. }
  714. ULONG64
  715. GetStringTableData(
  716. ULONG64 st
  717. )
  718. {
  719. InitTypeRead (st, SETUPAPI!STRING_TABLE);
  720. return ReadField (Data);
  721. }
  722. ULONG64
  723. GetFirstNode(
  724. ULONG64 stdata,
  725. ULONG64 offset,
  726. PULONG64 poffset
  727. )
  728. {
  729. ULONG64 NodeAddress = 0;
  730. ReadPtr (offset, &NodeAddress);
  731. *poffset = NodeAddress;
  732. if (NodeAddress == -1) {
  733. return 0;
  734. }
  735. return NodeAddress + stdata;
  736. }
  737. ULONG64
  738. GetNextNode(
  739. ULONG64 stdata,
  740. ULONG64 node,
  741. PULONG64 offset
  742. )
  743. {
  744. ULONG64 next, nextoffset;
  745. //
  746. // BUG BUG: Hack for ptr - STRING_NODEW is not built into any file
  747. // so I will cheat because I know that the offset is the first entry
  748. //
  749. ReadPtr (node, &nextoffset);
  750. if (nextoffset == -1) {
  751. *offset = 0;
  752. return 0;
  753. }
  754. next = stdata + nextoffset;
  755. *offset = nextoffset;
  756. return next;
  757. }
  758. BOOL
  759. CheckInterupted(
  760. VOID
  761. )
  762. {
  763. if ( CheckControlC() ) {
  764. dprintf( "\nInterrupted\n\n" );
  765. return TRUE;
  766. }
  767. return FALSE;
  768. }
  769. LPCSTR
  770. GetWizPage(
  771. DWORD i
  772. )
  773. {
  774. LPCSTR WizPage[] = {
  775. "WizPagesWelcome", // welcome page
  776. "WizPagesMode", // setup mode page
  777. "WizPagesEarly", // pages that come after the mode page and before prenet pages
  778. "WizPagesPrenet", // pages that come before network setup
  779. "WizPagesPostnet", // pages that come after network setup
  780. "WizPagesLate", // pages that come after postnet pages and before the final page
  781. "WizPagesFinal", // final page
  782. "WizPagesTypeMax"
  783. };
  784. return WizPage[i];
  785. }
  786. VOID
  787. DumpOcComponent(
  788. ULONG64 offset,
  789. ULONG64 node,
  790. ULONG64 pcomp
  791. )
  792. {
  793. DWORD i;
  794. ULONG count;
  795. WCHAR Buffer[200];
  796. UtilReadWString (node + GetTypeSize ("SETUPAPI!ULONG_PTR"),
  797. Buffer,
  798. sizeof (Buffer));
  799. InitTypeRead (pcomp, OCMANAGE!OPTIONAL_COMPONENT);
  800. dprintf("OC_COMPONENT Data for node %ws : 0x%p\n", Buffer, offset );
  801. dprintf( "\t InfStringId:\t\t0x%016I64x\n", ReadField (InfStringId));
  802. dprintf( "\t TopLevelStringId:\t0x%016I64x\n", ReadField (TopLevelStringId));
  803. dprintf( "\t ParentStringId:\t0x%016I64x\n", ReadField (ParentStringId));
  804. dprintf( "\t FirstChildStringId:\t0x%016I64x\n", ReadField (FirstChildStringId));
  805. dprintf( "\t ChildrenCount:\t\t0x%016I64x\n", ReadField (ChildrenCount));
  806. dprintf( "\t NextSiblingStringId:\t0x%016I64x\n", ReadField (NextSiblingStringId));
  807. dprintf( "\t NeedsCount:\t\t%d\n", ReadField (NeedsCount));
  808. if (ReadField (NeedsCount)) {
  809. // read and dump needs list
  810. for (i = 0; i < ReadField (NeedsCount); i++) {
  811. ReadMemory(ReadField (NeedsStringIds) + (i * sizeof (ULONG)), &count, sizeof (count), NULL);
  812. dprintf("\t NeedsStringIds #%d:\t0x%08x\n", i, count);
  813. if (CheckInterupted()) {
  814. return;
  815. }
  816. }
  817. }
  818. dprintf( "\t NeededByCount:\t\t%d\n", ReadField (NeededByCount));
  819. if (ReadField (NeededByCount)) {
  820. // read and dump needs list
  821. for (i = 0; i < ReadField (NeededByCount); i++) {
  822. ReadMemory(ReadField (NeededByStringIds) + (i * sizeof (ULONG)), &count, sizeof (count), NULL);
  823. dprintf("\t NeededByStringIds #%d: 0x%08x\n", i, count);
  824. if (CheckInterupted()) {
  825. return;
  826. }
  827. }
  828. }
  829. dprintf( "\t ExcludeCount:\t\t%d\n", ReadField (ExcludeCount));
  830. if (ReadField (ExcludeCount)) {
  831. // read and dump Excludes list
  832. for (i = 0; i < ReadField (ExcludeCount); i++) {
  833. ReadMemory(ReadField (ExcludeStringIds) + (i * sizeof (ULONG)), &count, sizeof (ULONG), NULL);
  834. dprintf("\t ExcludeStringIds #%d: 0x%08x\n", i, count);
  835. if (CheckInterupted()) {
  836. return;
  837. }
  838. }
  839. }
  840. dprintf( "\t ExcludedByCount:\t%d\n", ReadField (ExcludedByCount));
  841. if (ReadField (ExcludedByCount)) {
  842. // read and dump Excludes list
  843. for (i = 0; i < ReadField (ExcludedByCount); i++) {
  844. ReadMemory(ReadField (ExcludedByStringIds) + (i * sizeof (ULONG)), &count, sizeof (ULONG), NULL);
  845. dprintf("\t ExcludesStringIds #%d:\t0x%08x\n", i, count);
  846. if (CheckInterupted()) {
  847. return;
  848. }
  849. }
  850. }
  851. dprintf( "\t InternalFlags:\t\t0x%08x\n", ReadField (InternalFlags));
  852. //
  853. // bugbug correct identifier
  854. //
  855. dprintf( "\t SizeApproximation:\t0x%016I64x\n", ReadField (SizeApproximation));
  856. dprintf( "\t IconIndex:\t\t0x%016I64x\n", ReadField (IconIndex));
  857. UtilGetWStringField (pcomp, "OCMANAGE!OPTIONAL_COMPONENT", "IconDll", Buffer, sizeof (Buffer));
  858. dprintf( "\t IconDll:\t\t%ws\n", Buffer);
  859. UtilGetWStringField (pcomp, "OCMANAGE!OPTIONAL_COMPONENT", "IconResource", Buffer, sizeof (Buffer));
  860. dprintf( "\t IconResource:\t\t%ws\n", Buffer);
  861. dprintf( "\t SelectionState:\t0x%016I64x\n", ReadField (SelectionState));
  862. dprintf( "\t OriginalSelectionState:0x%016I64x\n", ReadField (OriginalSelectionState));
  863. dprintf( "\t InstalledState:\t0x%016I64x\n", ReadField (InstalledState));
  864. dprintf( "\t ModeBits:\t\t0x%08x\n", ReadField (ModeBits));
  865. UtilGetWStringField (pcomp, "OCMANAGE!OPTIONAL_COMPONENT", "Description", Buffer, sizeof (Buffer));
  866. dprintf( "\t Description:\t\t%ws\n", Buffer);
  867. UtilGetWStringField (pcomp, "OCMANAGE!OPTIONAL_COMPONENT", "Tip", Buffer, sizeof (Buffer));
  868. dprintf( "\t Tip:\t\t\t%ws\n", Buffer);
  869. UtilGetWStringField (pcomp, "OCMANAGE!OPTIONAL_COMPONENT", "InstallationDllName", Buffer, sizeof (Buffer));
  870. dprintf( "\t InstallationDllName:\t%ws\n", Buffer);
  871. UtilGetWStringField (pcomp, "OCMANAGE!OPTIONAL_COMPONENT", "InterfaceFunctionName", Buffer, sizeof (Buffer));
  872. dprintf( "\t InterfaceFunctionName:\t%s\n", Buffer);
  873. dprintf( "\t InstallationDll:\t0x%016I64x\n", ReadField (InstallationDll));
  874. dprintf( "\t ExpectedVersion:\t0x%016I64x\n", ReadField (ExpectedVersion));
  875. dprintf( "\t Exists:\t\t0x%016I64x\n", ReadField (Exists));
  876. dprintf( "\t Flags:\t\t\t0x%016I64x\n\n\n", ReadField (Flags));
  877. return;
  878. }
  879. DECLARE_API( setuphelp )
  880. {
  881. dprintf("setupexts help:\n\n");
  882. dprintf("!setuphelp - This message\n");
  883. dprintf("!ocm [address] [opt. flag] - Dump the OC_MANAGER structure at address, flag increased verbosity\n");
  884. dprintf("!space [address] [opt. flag] - Dump the DISK_SPACE_LIST structure at specified address\n");
  885. dprintf("!st [address] - Dump the contents of a STRING_TABLE structure at specified address\n");
  886. dprintf("!stfind [address] [element] - Dump the specified string table element\n");
  887. dprintf("!queue [address] [opt. flag] - Dump the specified file queue\n");
  888. dprintf("!qcontext [address] - Dump the specified default queue context \n");
  889. dprintf("!infdump [addr] [opt. flag] - Dump the specified hinf \n");
  890. }
  891. DECLARE_API( st )
  892. /*++
  893. Routine Description:
  894. This debugger extension dumps a string table at the address specified.
  895. Arguments:
  896. Return Value:
  897. --*/
  898. {
  899. ULONG64 pst;
  900. DWORD i;
  901. ULONG64 offset;
  902. ULONG64 pextradata;
  903. ULONG64 stdata;
  904. WCHAR Buffer[200];
  905. ULONG64 boffset, node;
  906. ULONG count = 0;
  907. if (args==0) {
  908. dprintf ("st: no string table specified.\n");
  909. return;
  910. }
  911. ZeroMemory (&Buffer, sizeof (Buffer));
  912. pst = UtilStringToUlong64 ((UCHAR *)args);
  913. dprintf("Base String Table Address:\t0x%p\n", pst);
  914. DumpStringTableHeader(pst);
  915. stdata = GetStringTableData(pst);
  916. //
  917. // now, dump each node in the string table
  918. //
  919. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  920. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  921. if (!node) {
  922. // dprintf("No data at hash bucket %d\n", i);
  923. } else {
  924. dprintf("Data at hash bucket %d\n", i);
  925. while (node) {
  926. //
  927. // BUG BUG: Hack for offset - STRING_NODEW is not built into any file
  928. // so I will cheat because I know that the offset is after a ptr
  929. //
  930. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  931. count = 0;
  932. while (1)
  933. {
  934. if (count == sizeof (Buffer)) {
  935. break;
  936. }
  937. ReadMemory (node + boffset + count,
  938. (PWCHAR) &Buffer + count/2,
  939. sizeof (WCHAR),
  940. NULL);
  941. if (!Buffer[count/2]) {
  942. break;
  943. }
  944. count +=2;
  945. }
  946. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  947. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  948. pextradata = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  949. dprintf("\tExtra Data:\t0x%016I64x\n", pextradata );
  950. node = GetNextNode(stdata, node, &offset );
  951. if (CheckInterupted()) {
  952. return;
  953. }
  954. }
  955. }
  956. }
  957. }
  958. DECLARE_API( stfind )
  959. /*++
  960. Routine Description:
  961. This debugger extension dumps the data for a given string table number
  962. Arguments:
  963. Return Value:
  964. --*/
  965. {
  966. ULONG64 pst, element, stdata, boffset;
  967. DWORD i;
  968. ULONG64 offset;
  969. ULONG64 pextradata;
  970. ULONG64 node;
  971. UCHAR arg[2][100];
  972. WCHAR Buffer[200];
  973. ULONG64 count = 0, argcount = 0;
  974. PUCHAR argptr = (PUCHAR) args;
  975. ZeroMemory (&arg, sizeof (arg));
  976. ZeroMemory (&Buffer, sizeof (Buffer));
  977. while (*argptr != 0) {
  978. if (*argptr == ' ') {
  979. argcount++;
  980. count = 0;
  981. argptr++;
  982. }
  983. if (argcount > 1) {
  984. break;
  985. }
  986. arg[argcount][count] = *argptr;
  987. count++;
  988. argptr++;
  989. }
  990. if (!arg[0][0] || !arg[1][0]) {
  991. dprintf ("stfind: missing one or more parameters\nusage:!stfind [address] [element]\n");
  992. return;
  993. }
  994. pst = UtilStringToUlong64 (arg[0]);
  995. element = UtilStringToUlong64 (arg[1]);
  996. stdata = GetStringTableData(pst);
  997. if (!stdata) {
  998. dprintf("Error retrieving string table data!\n");
  999. return;
  1000. }
  1001. //
  1002. // search each node in the string table
  1003. //
  1004. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  1005. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  1006. if (!node) {
  1007. } else {
  1008. while (node) {
  1009. if (element == offset) {
  1010. //
  1011. // BUG BUG: Hack for offset - STRING_NODEW is not built into any file
  1012. // so I will cheat because I know that the offset is after a ptr
  1013. //
  1014. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  1015. count = 0;
  1016. while (1)
  1017. {
  1018. if (count == sizeof (Buffer)) {
  1019. break;
  1020. }
  1021. ReadMemory (node + boffset + count,
  1022. (PWCHAR) &Buffer + count/2,
  1023. sizeof (WCHAR),
  1024. NULL);
  1025. if (!Buffer[count/2]) {
  1026. break;
  1027. }
  1028. count +=2;
  1029. }
  1030. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  1031. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  1032. pextradata = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  1033. dprintf("\tExtra Data:\t0x%016I64x\n", pextradata );
  1034. return;
  1035. }
  1036. node = GetNextNode( stdata, node, &offset );
  1037. if (CheckInterupted()) {
  1038. return;
  1039. }
  1040. }
  1041. }
  1042. }
  1043. dprintf("Couldn't find element\n");
  1044. }
  1045. DECLARE_API( ocm )
  1046. /*++
  1047. Routine Description:
  1048. This debugger extension dumps an OC_MANAGER (UNICODE!) structure at the specified address
  1049. Arguments:
  1050. Return Value:
  1051. --*/
  1052. {
  1053. ULONG64 pocm;
  1054. DWORD i;
  1055. ULONG64 infdata,compdata;
  1056. ULONG64 Mask = 0;
  1057. LONG count = 0;
  1058. UCHAR arg[2][100];
  1059. PUCHAR argptr = (PUCHAR) args;
  1060. ULONG64 offset = 0;
  1061. WCHAR Buffer[200];
  1062. ULONG argcount = 0;
  1063. ULONG64 node = 0, boffset = 0;
  1064. ZeroMemory (&arg, sizeof (arg));
  1065. while (*argptr != 0) {
  1066. if (*argptr == ' ') {
  1067. argcount++;
  1068. count = 0;
  1069. argptr++;
  1070. }
  1071. if (argcount > 1) {
  1072. break;
  1073. }
  1074. arg[argcount][count] = *argptr;
  1075. count++;
  1076. argptr++;
  1077. }
  1078. if (!arg[0][0]) {
  1079. dprintf ("ocm: missing one or more parameters\nusage:!ocm [address] [verbosity]\n");
  1080. return;
  1081. }
  1082. pocm = UtilStringToUlong64 (arg[0]);
  1083. Mask = UtilStringToUlong64 (arg[1]);
  1084. InitTypeRead (pocm, OCMANAGE!OC_MANAGER);
  1085. //
  1086. // dump the OCM structure
  1087. //
  1088. dprintf("OC_MANAGER structure at Address:\t0x%016I64x\n", pocm);
  1089. dprintf("\tCallbacks :\n");
  1090. dprintf("\t\tFillInSetupDataA:\t0x%016I64x\n", ReadField (Callbacks.FillInSetupDataA));
  1091. dprintf("\t\tLogError:\t\t0x%016I64x\n", ReadField (Callbacks.LogError));
  1092. dprintf("\t\tSetReboot:\t\t0x%016I64x\n", ReadField (Callbacks.SetReboot));
  1093. dprintf("\t\tFillInSetupDataW:\t0x%016I64x\n", ReadField (Callbacks.FillInSetupDataW));
  1094. dprintf("\tMasterOcInf:\t\t0x%016I64x\n", ReadField (MasterOcInf));
  1095. dprintf("\tUnattendedInf:\t\t0x%016I64x\n", ReadField (UnattendedInf));
  1096. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "MasterOcInfPath", Buffer, sizeof (Buffer));
  1097. dprintf("\tMasterOcInfPath:\t%ws\n", Buffer);
  1098. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "UnattendedInfPath", Buffer, sizeof (Buffer));
  1099. dprintf("\tUnattendInfPath:\t%ws\n", Buffer);
  1100. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "SourceDir", Buffer, sizeof (Buffer));
  1101. dprintf("\tSourceDir:\t\t%ws\n", Buffer);
  1102. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "SuiteName", Buffer, sizeof (Buffer));
  1103. dprintf("\tSuiteName:\t\t%ws\n", Buffer);
  1104. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "SetupPageTitle", Buffer, sizeof (Buffer));
  1105. dprintf("\tSetupPageTitle:\t\t%ws\n", Buffer);
  1106. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "WindowTitle", Buffer, sizeof (Buffer));
  1107. dprintf("\tWindowTitle:\t\t%ws\n", Buffer);
  1108. dprintf("\tInfListStringTable:\t0x%016I64x\n", ReadField (InfListStringTable));
  1109. dprintf("\tComponentStringTable:\t0x%016I64x\n", ReadField (ComponentStringTable));
  1110. dprintf("\tOcSetupPage:\t\t0x%016I64x\n", ReadField (OcSetupPage));
  1111. dprintf("\tSetupMode:\t\t%d\n", ReadField (SetupMode));
  1112. dprintf("\tTopLevelOcCount:\t%d\n", ReadField (TopLevelOcCount));
  1113. if (ReadField (TopLevelOcCount)) {
  1114. // read and dump needs list
  1115. for (i = 0; i < ReadField (TopLevelOcCount); i++) {
  1116. //
  1117. // BUG BUG - No way to read size of String Ids off target, so assume LONG
  1118. //
  1119. ReadMemory(ReadField (TopLevelOcStringIds) + (i * sizeof (LONG)), &count, sizeof (count), NULL);
  1120. dprintf("\t TopLevelOcStringIds #%d:\t0x%08x\n", i, count);
  1121. if (CheckInterupted()) {
  1122. return;
  1123. }
  1124. }
  1125. }
  1126. dprintf("\tTopLevelParenOcCount:\t%d\n", ReadField (TopLevelParentOcCount));
  1127. if (ReadField (TopLevelParentOcCount)) {
  1128. // read and dump needs list
  1129. for (i = 0; i < ReadField (TopLevelParentOcCount); i++) {
  1130. //
  1131. // BUG BUG - No way to read size of String Ids off target, so assume LONG
  1132. //
  1133. ReadMemory(ReadField (TopLevelParentOcStringIds) + (i * sizeof (LONG)), &count, sizeof (count), NULL);
  1134. dprintf("\t TopLevelParentOcStringIds #%d:\t0x%08x\n", i, count);
  1135. if (CheckInterupted()) {
  1136. return;
  1137. }
  1138. }
  1139. }
  1140. dprintf("\tSubComponentsPresent:\t%d\n", ReadField (SubComponentsPresent));
  1141. //
  1142. // BugBug WizardPagesOrder there's not really any way to tell the exact upper bound of
  1143. // each array, though we know that it's <= TopLevelParentOcCount...since this is the case
  1144. // we just dump the point to each array of pages...
  1145. //
  1146. for (i = 0; i < WizPagesTypeMax; i++) {
  1147. ULONG wizardpageorder = 0;
  1148. //
  1149. // BUG BUG - Again, assuming that this type will always be ULONG
  1150. //
  1151. GetFieldOffset ("OCMANAGE!OC_MANAGER", "WizardPagesOrder", (PULONG) &offset);
  1152. ReadMemory (pocm + offset + (i * sizeof (ULONG)), &wizardpageorder, sizeof (ULONG), NULL);
  1153. dprintf("\tWizardPagesOrder[%i] (%s)\t: 0x%08x\n",
  1154. i,
  1155. GetWizPage(i),
  1156. wizardpageorder);
  1157. if (CheckInterupted()) {
  1158. return;
  1159. }
  1160. }
  1161. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "PrivateDataSubkey", Buffer, sizeof (Buffer));
  1162. dprintf("\tPrivateDataSubkey:\t\t%ws\n", Buffer);
  1163. dprintf("\thKeyPrivateData:\t\t0x%016I64x\n", ReadField (hKeyPrivateData));
  1164. dprintf("\thKeyPrivateDataRoot:\t\t0x%016I64x\n", ReadField (hKeyPrivateDataRoot));
  1165. dprintf("\tProgressTextWindow:\t\t0x%016I64x\n", ReadField (ProgressTextWindow));
  1166. dprintf("\tCurrentComponentStringId:\t0x%016I64x\n", ReadField(CurrentComponentStringId));
  1167. dprintf("\tAbortedCount:\t\t%d\n", ReadField (AbortedCount));
  1168. if (ReadField (AbortedCount)) {
  1169. // read and dump needs list
  1170. for (i = 0; i < ReadField (AbortedCount); i++) {
  1171. ReadMemory(ReadField (AbortedComponentIds) + (i * sizeof (LONG)), &count, sizeof(count), NULL);
  1172. dprintf("\t AbortedComponentIds #%d:\t0x%08x\n", i, count);
  1173. if (CheckInterupted()) {
  1174. return;
  1175. }
  1176. }
  1177. }
  1178. dprintf("\tInternalFlags:\t\t0x%016I64x\n\n\n", ReadField (InternalFlags));
  1179. dprintf("\tSetupData.SetupMode :\t\t0x%016I64x\n", ReadField (SetupData.SetupMode));
  1180. dprintf("\tSetupData.ProductType :\t\t0x%016I64x\n", ReadField (SetupData.ProductType));
  1181. dprintf("\tSetupData.OperationFlags :\t0x%016I64x\n", ReadField (SetupData.OperationFlags));
  1182. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "SetupData.SourcePath", Buffer, sizeof (Buffer));
  1183. dprintf("\tSetupData.SourcePath :\t\t%ws\n", Buffer);
  1184. UtilGetWStringField (pocm, "OCMANAGE!OC_MANAGER", "SetupData.UnattendFile", Buffer, sizeof (Buffer));
  1185. dprintf("\tSetupData.UnattendFile :\t\t%ws\n", Buffer);
  1186. //
  1187. // Verbose print
  1188. //
  1189. if ((Mask&1) && ReadField (InfListStringTable)) {
  1190. ULONG64 pinfdata = 0;
  1191. dprintf("\t\t***InfListStringTable***\n");
  1192. pinfdata = GetStringTableData( ReadField (InfListStringTable));
  1193. if (!pinfdata) {
  1194. dprintf("error retrieving string table data!\n");
  1195. return;
  1196. }
  1197. // now, dump each node with data in the string table
  1198. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  1199. node = GetFirstNode(pinfdata, (pinfdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset);
  1200. if (!node) {
  1201. // dprintf("No data at hash bucket %d\n", i);
  1202. } else {
  1203. //dprintf("Data at hash bucket %d\n", i);
  1204. while (node) {
  1205. ULONG64 pocinf = 0;
  1206. //dprintf("\tNode Name:%ws\n", node->String);
  1207. UtilReadWString (node + GetTypeSize ("SETUPAPI!ULONG_PTR"),
  1208. Buffer,
  1209. sizeof (Buffer)
  1210. );
  1211. boffset = wcslen (Buffer) * sizeof (WCHAR);
  1212. ReadPtr (node + GetTypeSize ("SETUPAPI!ULONG_PTR") + boffset + 1,
  1213. &pocinf);
  1214. pocinf = node + GetTypeSize ("SETUPAPI!ULONG_PTR") + boffset + 2;
  1215. if (pocinf) {
  1216. InitTypeRead (pocinf, OCMANAGE!OC_INF);
  1217. dprintf("\tNode Data for %ws\t (0x%08x): 0x%016I64x\n",
  1218. Buffer,
  1219. offset,
  1220. ReadField (Handle)
  1221. );
  1222. } else {
  1223. dprintf("\tNo Node Data for %ws\n",
  1224. Buffer
  1225. );
  1226. }
  1227. node = GetNextNode(pinfdata, node, &offset );
  1228. if (CheckInterupted()) {
  1229. return;
  1230. }
  1231. }
  1232. }
  1233. }
  1234. dprintf("\n\n");
  1235. }
  1236. InitTypeRead (pocm, OCMANAGE!OC_MANAGER);
  1237. if ((Mask&1) && ReadField (ComponentStringTable)) {
  1238. ULONG64 compdata = 0;
  1239. dprintf("\t\t***ComponentStringTable***\n");
  1240. compdata = GetStringTableData(ReadField (ComponentStringTable));
  1241. if (!compdata) {
  1242. dprintf("error retrieving string table data!\n");
  1243. return;
  1244. }
  1245. //
  1246. // dump each node with data in the string table
  1247. //
  1248. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  1249. node = GetFirstNode(compdata, (compdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset);
  1250. if (!node) {
  1251. // dprintf("No data at hash bucket %d\n", i);
  1252. } else {
  1253. //dprintf("Data at hash bucket %d\n", i);
  1254. while (node) {
  1255. ULONG64 pcomp = 0;
  1256. //dprintf("\tNode Name:%ws\n", node->String);
  1257. UtilReadWString (node + GetTypeSize ("SETUPAPI!ULONG_PTR"),
  1258. Buffer,
  1259. sizeof (Buffer)
  1260. );
  1261. boffset = wcslen (Buffer) * sizeof (WCHAR);
  1262. pcomp = node + GetTypeSize ("SETUPAPI!ULONG_PTR") + boffset + 2;
  1263. if (pcomp) {
  1264. DumpOcComponent( offset , node, pcomp );
  1265. } else {
  1266. dprintf("\tNo Node Data for %ws\n",
  1267. Buffer
  1268. );
  1269. }
  1270. if (CheckInterupted()) {
  1271. return;
  1272. }
  1273. node = GetNextNode( compdata, node, &offset );
  1274. }
  1275. }
  1276. }
  1277. }
  1278. return;
  1279. }
  1280. DECLARE_API( infdump )
  1281. /*++
  1282. Routine Description:
  1283. This debugger extension dumps the data related to an HINF structure
  1284. Arguments:
  1285. Return Value:
  1286. --*/
  1287. {
  1288. DWORD ReturnLength;
  1289. ULONG64 pinf;
  1290. //LOADED_INF inf;
  1291. //INF_SECTION InfSection;
  1292. //INF_LINE InfLine;
  1293. DWORD i;
  1294. ULONG64 offset = 0, count = 0;
  1295. ULONG64 stdata,pextradata;
  1296. //STRING_TABLE st;
  1297. //PSTRING_NODEW node;//, prev;
  1298. PUCHAR argptr = (PUCHAR) args;
  1299. UCHAR arg[2][100];
  1300. WCHAR Buffer[200];
  1301. ULONG argcount = 0;
  1302. ULONG64 node = 0, boffset = 0, pst = 0;
  1303. ULONG64 Mask = 0;
  1304. ZeroMemory (&arg, sizeof (arg));
  1305. while (*argptr != 0) {
  1306. if (*argptr == ' ') {
  1307. argcount++;
  1308. count = 0;
  1309. argptr++;
  1310. }
  1311. if (argcount > 1) {
  1312. break;
  1313. }
  1314. arg[argcount][count] = *argptr;
  1315. count++;
  1316. argptr++;
  1317. }
  1318. if (!arg[0][0]) {
  1319. dprintf ("infdump: missing one or more parameters\nusage:!infdump [address] [verbosity]\n");
  1320. return;
  1321. }
  1322. pinf = UtilStringToUlong64 (arg[0]);
  1323. Mask = UtilStringToUlong64 (arg[1]);
  1324. InitTypeRead (pinf, SETUPAPI!LOADED_INF);
  1325. count = ReadField (Signature);
  1326. dprintf("LOADED_INF at :\t0x%016I64x\n", pinf);
  1327. dprintf("\t Signature : 0x%08x (%s)\n", (ULONG) count, ((count == LOADED_INF_SIG) ? "Valid" : "Invalid"));
  1328. if (ReadField (Signature) != LOADED_INF_SIG) {
  1329. return;
  1330. }
  1331. dprintf("\t FileHandle:\t0x%016I64x\n", ReadField (FileHandle));
  1332. dprintf("\t MappingHandle:\t0x%016I64x\n", ReadField (MappingHandle));
  1333. dprintf("\t ViewAddress:\t0x%016I64x\n", ReadField (ViewAddress));
  1334. if (ReadField (FileHandle) == (ULONG64) INVALID_HANDLE_VALUE) {
  1335. dprintf(" *** In memory INF ***\n" );
  1336. } else {
  1337. dprintf(" *** PNF ***\n" );
  1338. }
  1339. dprintf("\t StringTable:\t0x%016I64x\n", ReadField (StringTable));
  1340. dprintf("\t SectionCount:\t0x%016I64x\n", ReadField (SectionCount));
  1341. dprintf("\tSectionBlock:\t0x%016I64x\n", ReadField (SectionBlock));
  1342. for (i = 0; i < ReadField (SectionCount); i++) {
  1343. dprintf("***INF_SECTION [%d] at 0x%016I64x***\n",i, ReadField (SectionBlock) + (GetTypeSize ("SETUPAPI!INF_SECTION") * i));
  1344. DumpInfSection( ReadField (SectionBlock) + (GetTypeSize ("SETUPAPI!INF_SECTION") * i), ReadField (LineBlock), ReadField (ValueBlock));
  1345. //
  1346. // Need to reinit type read because previous functions change the
  1347. // default read structure type
  1348. //
  1349. InitTypeRead (pinf, SETUPAPI!LOADED_INF);
  1350. if (CheckInterupted()) {
  1351. return;
  1352. }
  1353. }
  1354. dprintf("\tLineBlock : 0x%I64x\n", ReadField (LineBlock));
  1355. dprintf("\t ValueBlock : 0x%I64x\n", ReadField (ValueBlock));
  1356. DumpInfVersionNode(ReadField (VersionBlock));
  1357. InitTypeRead (pinf, SETUPAPI!LOADED_INF);
  1358. dprintf("\t HasStrings : 0x%I64x\n", ReadField (HasStrings));
  1359. UtilGetWStringField (pinf, "SETUPAPI!LOADED_INF", "OsLoaderPath", Buffer, sizeof (Buffer));
  1360. dprintf("\t OsLoaderPath : %ws\n", Buffer);
  1361. dprintf("\t InfSourceMediaType : 0x%I64x ( ", ReadField (InfSourceMediaType));
  1362. if (ReadField (InfSourceMediaType)) {
  1363. if (ReadField (InfSourceMediaType) & SPOST_PATH ) {
  1364. dprintf("SPOST_PATH ");
  1365. }
  1366. if (ReadField (InfSourceMediaType) & SPOST_URL) {
  1367. dprintf("SPOST_URL ");
  1368. }
  1369. } else {
  1370. dprintf("SPOST_NONE ");
  1371. }
  1372. dprintf(")\n");
  1373. UtilGetWStringField (pinf, "SETUPAPI!LOADED_INF", "InfSourcePath", Buffer, sizeof (Buffer));
  1374. dprintf("\t InfSourcePath : %ws\n", Buffer);
  1375. UtilGetWStringField (pinf, "SETUPAPI!LOADED_INF", "OriginalInfName", Buffer, sizeof (Buffer));
  1376. dprintf("\t OriginalInfName : %ws\n", Buffer);
  1377. dprintf("\t SubstValueList : 0x%I64x\n", ReadField (SubstValueList));
  1378. dprintf("\t SubstValueCount : 0x%I64x\n", ReadField (SubstValueCount));
  1379. dprintf("\t Style : 0x%x ( ", ReadField (Style));
  1380. if (ReadField (Style) & INF_STYLE_OLDNT) {
  1381. dprintf("INF_STYLE_OLDNT ");
  1382. }
  1383. if (ReadField (Style) & INF_STYLE_WIN4) {
  1384. dprintf("INF_STYLE_WIN4 ");
  1385. }
  1386. dprintf(")\n");
  1387. dprintf("\t SectionBlockSizeBytes : 0x%x\n", ReadField (SectionBlockSizeBytes));
  1388. dprintf("\t LineBlockSizeBytes : 0x%x\n", ReadField (LineBlockSizeBytes));
  1389. dprintf("\t ValueBlockSizeBytes : 0x%x\n", ReadField (ValueBlockSizeBytes));
  1390. dprintf("\t LanguageId : 0x%x\n", ReadField (LanguageId));
  1391. dprintf("\t UserDirIdList : 0x%x\n", ReadField (UserDirIdList));
  1392. dprintf("\tLock[0] : 0x%x\n", ReadField (Lock.handles[0]));
  1393. dprintf("\tLock[1] : 0x%x\n", ReadField (Lock.handles[1]));
  1394. dprintf("\tPrev : 0x%x\n", ReadField (Prev));
  1395. dprintf("\tNext : 0x%x\n", ReadField (Next));
  1396. pst = ReadField (StringTable);
  1397. DumpStringTableHeader (pst);
  1398. stdata = GetStringTableData (pst);
  1399. //
  1400. // now, dump each node in the string table
  1401. //
  1402. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  1403. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  1404. if (!node) {
  1405. // dprintf("No data at hash bucket %d\n", i);
  1406. } else {
  1407. dprintf("Data at hash bucket %d\n", i);
  1408. while (node) {
  1409. //
  1410. // BUG BUG: Hack for offset - STRING_NODEW is not built into any file
  1411. // so I will cheat because I know that the offset is after a ptr
  1412. //
  1413. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  1414. count = 0;
  1415. while (1)
  1416. {
  1417. if (count == sizeof (Buffer)) {
  1418. break;
  1419. }
  1420. ReadMemory (node + boffset + count,
  1421. (PWCHAR) &Buffer + count/2,
  1422. sizeof (WCHAR),
  1423. NULL);
  1424. if (!Buffer[count/2]) {
  1425. break;
  1426. }
  1427. count +=2;
  1428. }
  1429. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  1430. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  1431. pextradata = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  1432. dprintf("\tExtra Data:\t0x%016I64x\n", pextradata );
  1433. node = GetNextNode(stdata, node, &offset );
  1434. if (CheckInterupted()) {
  1435. return;
  1436. }
  1437. }
  1438. }
  1439. }
  1440. return;
  1441. }
  1442. DECLARE_API( space )
  1443. /*++
  1444. Routine Description:
  1445. This debugger extension dumps the data related to a HDSKSPC structure
  1446. Arguments:
  1447. Return Value:
  1448. --*/
  1449. {
  1450. DWORD ReturnLength;
  1451. ULONG64 pst = 0;
  1452. ULONG64 dsl = 0;
  1453. DWORD i;
  1454. ULONG64 offset = 0, count = 0, boffset = 0;
  1455. ULONG64 stdata = 0,pextradata = 0;
  1456. ULONG64 Mask = 0;
  1457. ULONG64 node = 0, pxd = 0, pte = 0;
  1458. PUCHAR argptr = (PUCHAR) args;
  1459. UCHAR arg[2][100];
  1460. WCHAR Buffer[200];
  1461. ULONG argcount = 0;
  1462. while (*argptr != 0) {
  1463. if (*argptr == ' ') {
  1464. argcount++;
  1465. count = 0;
  1466. argptr++;
  1467. }
  1468. if (argcount > 1) {
  1469. break;
  1470. }
  1471. arg[argcount][count] = *argptr;
  1472. count++;
  1473. argptr++;
  1474. }
  1475. if (!arg[0][0]) {
  1476. dprintf ("space: missing one or more parameters\nusage:!space [address] [verbosity]\n");
  1477. return;
  1478. }
  1479. dsl = UtilStringToUlong64 (arg[0]);
  1480. Mask = UtilStringToUlong64 (arg[1]);
  1481. InitTypeRead (dsl, SETUPAPI!DISK_SPACE_LIST);
  1482. dprintf("DISK_SPACE_LIST at :\t0x%016I64x\n", dsl);
  1483. GetFieldOffset ("SETUPAPI!DISK_SPACE_LIST", "Lock", (ULONG *) &offset);
  1484. boffset = GetTypeSize ("SETUPAPI!HANDLE");
  1485. ReadMemory (dsl + offset, &count, (ULONG) boffset, NULL);
  1486. dprintf("\tLock[0] : 0x%016I64x\n", count);
  1487. ReadMemory (dsl + offset + boffset, &count, (ULONG) boffset, NULL);
  1488. dprintf("\tLock[1] : 0x%016I64x\n", count);
  1489. dprintf("\tDrivesTable : 0x%016I64x\n", ReadField (DrivesTable));
  1490. dprintf("\tFlags : 0x%016I64x\n", ReadField (Flags));
  1491. pst = ReadField (DrivesTable);
  1492. dprintf("\t ***DrivesTable***\n");
  1493. DumpStringTableHeader(pst);
  1494. stdata = GetStringTableData(pst);
  1495. if (!stdata) {
  1496. dprintf("error retrieving string table data!\n");
  1497. return;
  1498. }
  1499. //
  1500. // now, dump each node in the string table
  1501. //
  1502. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  1503. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  1504. if (!node) {
  1505. // dprintf("No data at hash bucket %d\n", i);
  1506. } else {
  1507. dprintf("Data at hash bucket %d\n", i);
  1508. while (node) {
  1509. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  1510. count = 0;
  1511. while (1)
  1512. {
  1513. if (count == sizeof (Buffer)) {
  1514. break;
  1515. }
  1516. ReadMemory (node + boffset + count,
  1517. (PWCHAR) &Buffer + count/2,
  1518. sizeof (WCHAR),
  1519. NULL);
  1520. if (!Buffer[count/2]) {
  1521. break;
  1522. }
  1523. count +=2;
  1524. }
  1525. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  1526. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  1527. pxd = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  1528. DumpXDrive( pxd, Mask );
  1529. node = GetNextNode( stdata, node, &offset );
  1530. if (CheckInterupted()) {
  1531. return;
  1532. }
  1533. }
  1534. }
  1535. if (CheckInterupted()) {
  1536. return;
  1537. }
  1538. }
  1539. }
  1540. DECLARE_API( queue )
  1541. /*++
  1542. Routine Description:
  1543. This debugger extension dumps the data related to a HSPFILEQ
  1544. Arguments:
  1545. Return Value:
  1546. --*/
  1547. {
  1548. ULONG64 ReturnLength;
  1549. ULONG64 pfq = 0,pst = 0, pte = 0;
  1550. //SP_FILE_QUEUE fq;
  1551. //PSP_TARGET_ENT pte;
  1552. DWORD i;
  1553. ULONG64 offset = 0, count = 0, boffset = 0;
  1554. ULONG64 stdata = 0, pextradata = 0, node = 0;
  1555. //STRING_TABLE st;
  1556. //PSTRING_NODEW node;//, prev;
  1557. ULONG64 Mask = 0;
  1558. PUCHAR argptr = (PUCHAR) args;
  1559. UCHAR arg[2][100];
  1560. WCHAR Buffer[200];
  1561. ULONG argcount = 0;
  1562. while (*argptr != 0) {
  1563. if (*argptr == ' ') {
  1564. argcount++;
  1565. count = 0;
  1566. argptr++;
  1567. }
  1568. if (argcount > 1) {
  1569. break;
  1570. }
  1571. arg[argcount][count] = *argptr;
  1572. count++;
  1573. argptr++;
  1574. }
  1575. if (!arg[0][0]) {
  1576. dprintf ("queue: missing one or more parameters\nusage:!queue [address] [verbosity]\n");
  1577. return;
  1578. }
  1579. pfq = UtilStringToUlong64 (arg[0]);
  1580. Mask = UtilStringToUlong64 (arg[1]);
  1581. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1582. dprintf("SP_FILE_QUEUE at :\t0x%016I64x\n", pfq);
  1583. dprintf("\t BackupQueue : 0x%016I64x\n", ReadField (BackupQueue));
  1584. dprintf("\t DeleteQueue : 0x%016I64x\n", ReadField (DeleteQueue));
  1585. dprintf("\t RenameQueue : 0x%016I64x\n", ReadField (RenameQueue));
  1586. dprintf("\t CopyNodeCount : 0x%016I64x\n", ReadField (CopyNodeCount));
  1587. dprintf("\t DeleteNodeCount : 0x%016I64x\n", ReadField (DeleteNodeCount));
  1588. dprintf("\t RenameNodeCount : 0x%016I64x\n", ReadField (RenameNodeCount));
  1589. dprintf("\t BackupNodeCount : 0x%016I64x\n", ReadField (BackupNodeCount));
  1590. dprintf("\t SourceMediaList : 0x%016I64x\n", ReadField (SourceMediaList));
  1591. dprintf("\t SourceMediaCount : 0x%016I64x\n", ReadField (SourceMediaCount));
  1592. dprintf("\t CatalogList : 0x%016I64x\n", ReadField (CatalogList));
  1593. dprintf("\t DriverSigningPolicy : 0x%016I64x (%s)\n",
  1594. ReadField (DriverSigningPolicy),
  1595. (ReadField (DriverSigningPolicy) == DRIVERSIGN_BLOCKING) ? "DRIVERSIGN_BLOCKING" :
  1596. (ReadField (DriverSigningPolicy) == DRIVERSIGN_WARNING) ? "DRIVERSIGN_WARNING" :
  1597. "DRIVERSIGN_NONE" );
  1598. dprintf("\t hWndDriverSigningUi : 0x%016I64x\n", ReadField (hWndDriverSigningUi));
  1599. dprintf("\t DeviceDescStringId : 0x%016I64x\n", ReadField (DeviceDescStringId));
  1600. dprintf("\t AltPlatformInfo : 0x%016I64x\n", ReadField (AltPlatformInfo));
  1601. GetFieldOffset ("SETUPAPI!SP_FILE_QUEUE", "AltPlatformInfo", (ULONG *) &offset);
  1602. DumpAltPlatformInfo(pfq + offset);
  1603. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1604. dprintf("\t AltCatalogFile : 0x%016I64x\n", ReadField (AltCatalogFile));
  1605. dprintf("\t StringTable : 0x%016I64x\n", ReadField (StringTable));
  1606. dprintf("\t LockRefCount : 0x%016I64x\n", ReadField (LockRefCount));
  1607. dprintf("\t Flags : 0x%016I64x\n", ReadField (Flags));
  1608. dprintf("\t SisSourceHandle : 0x%016I64x\n", ReadField (SisSourceHandle));
  1609. dprintf("\t SisSourceDirectory : 0x%016I64x\n", ReadField (SisSourceDirectory));
  1610. dprintf("\t BackupInfID : 0x%016I64x\n", ReadField (BackupInfID));
  1611. dprintf("\t TargetLookupTable : 0x%016I64x\n", ReadField (TargetLookupTable));
  1612. dprintf("\t UnwindQueue : 0x%016I64x\n", ReadField (UnwindQueue));
  1613. dprintf("\t DelayMoveQueue : 0x%016I64x\n", ReadField (DelayMoveQueue));
  1614. dprintf("\t DelayMoveQueueTail : 0x%016I64x\n", ReadField (DelayMoveQueueTail));
  1615. dprintf("\t Signature : 0x%016I64x (%s)\n",
  1616. ReadField (Signature),
  1617. (ReadField (Signature) == SP_FILE_QUEUE_SIG) ? "VALID" : "INVALID" );
  1618. //
  1619. // dump the queue nodes
  1620. //
  1621. if (Mask & 1) {
  1622. if (ReadField (BackupQueue)) {
  1623. dprintf("\t ***BackupQueue***\n");
  1624. DumpFileQueueNodeList(ReadField (BackupQueue), Mask, TRUE );
  1625. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1626. }
  1627. if (ReadField (DeleteQueue)) {
  1628. dprintf("\t ***DeleteQueue***\n");
  1629. DumpFileQueueNodeList(ReadField (DeleteQueue), Mask, TRUE );
  1630. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1631. }
  1632. if (ReadField (RenameQueue)) {
  1633. dprintf("\t ***RenameQueue***\n");
  1634. DumpFileQueueNodeList( ReadField (RenameQueue), Mask, TRUE );
  1635. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1636. }
  1637. if (ReadField (SourceMediaList)) {
  1638. dprintf("\t ***source media list***\n");
  1639. DumpSourceMediaInfoList( ReadField (SourceMediaList), Mask, TRUE );
  1640. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1641. }
  1642. }
  1643. //
  1644. // dump the catalog info
  1645. //
  1646. if (Mask & 2) {
  1647. if (ReadField (CatalogList)) {
  1648. dprintf("\t ***CatalogList***\n");
  1649. DumpCatalogInfoList( ReadField (CatalogList), Mask, TRUE );
  1650. }
  1651. }
  1652. //
  1653. // dump the string table
  1654. //
  1655. if (Mask & 4) {
  1656. dprintf("\t ***StringTable***\n");
  1657. pst = ReadField (StringTable);
  1658. DumpStringTableHeader (pst);
  1659. stdata = GetStringTableData (pst);
  1660. if (!stdata) {
  1661. dprintf("error retrieving string table data!\n");
  1662. return;
  1663. }
  1664. }
  1665. //
  1666. // now, dump each node in the string table
  1667. //
  1668. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  1669. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  1670. if (!node) {
  1671. // dprintf("No data at hash bucket %d\n", i);
  1672. } else {
  1673. dprintf("Data at hash bucket %d\n", i);
  1674. while (node) {
  1675. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  1676. count = 0;
  1677. while (1)
  1678. {
  1679. if (count == sizeof (Buffer)) {
  1680. break;
  1681. }
  1682. ReadMemory (node + boffset + count,
  1683. (PWCHAR) &Buffer + count/2,
  1684. sizeof (WCHAR),
  1685. NULL);
  1686. if (!Buffer[count/2]) {
  1687. break;
  1688. }
  1689. count +=2;
  1690. }
  1691. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  1692. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  1693. pextradata = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  1694. dprintf("\tExtra Data:\t0x%016I64x\n", pextradata );
  1695. node = GetNextNode( stdata, node, &offset );
  1696. if (CheckInterupted()) {
  1697. return;
  1698. }
  1699. }
  1700. }
  1701. if (CheckInterupted()) {
  1702. return;
  1703. }
  1704. }
  1705. dprintf("\t ***TargetLookupTable***\n");
  1706. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1707. pst = ReadField (TargetLookupTable);
  1708. DumpStringTableHeader (pst);
  1709. stdata = GetStringTableData (pst);
  1710. if (!stdata) {
  1711. dprintf("error retrieving string table data!\n");
  1712. return;
  1713. }
  1714. //
  1715. // now, dump each node in the string table
  1716. //
  1717. for (i = 0; i<HASH_BUCKET_COUNT; i++ ) {
  1718. node = GetFirstNode(stdata, (stdata + (GetTypeSize ("SETUPAPI!ULONG_PTR") * i)), &offset );
  1719. if (!node) {
  1720. // dprintf("No data at hash bucket %d\n", i);
  1721. } else {
  1722. dprintf("Data at hash bucket %d\n", i);
  1723. while (node) {
  1724. boffset = GetTypeSize ("SETUPAPI!ULONG_PTR");
  1725. count = 0;
  1726. while (1)
  1727. {
  1728. if (count == sizeof (Buffer)) {
  1729. break;
  1730. }
  1731. ReadMemory (node + boffset + count,
  1732. (PWCHAR) &Buffer + count/2,
  1733. sizeof (WCHAR),
  1734. NULL);
  1735. if (!Buffer[count/2]) {
  1736. break;
  1737. }
  1738. count +=2;
  1739. }
  1740. dprintf("\tEntry Name:\t%ws (0x%08x)\n", Buffer, offset);
  1741. InitTypeRead (pst, SETUPAPI!STRING_TABLE);
  1742. pte = ReadField (Data) + offset + (wcslen(Buffer) + 1)*sizeof(WCHAR) + sizeof(DWORD);
  1743. DumpTargetEnt(pte);
  1744. node = GetNextNode( stdata, node, &offset );
  1745. if (CheckInterupted()) {
  1746. return;
  1747. }
  1748. }
  1749. }
  1750. if (CheckInterupted()) {
  1751. return;
  1752. }
  1753. }
  1754. //
  1755. // backup stuff
  1756. //
  1757. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1758. if (Mask & 8) {
  1759. if (ReadField (UnwindQueue)) {
  1760. dprintf("\t ***UnwindQueue***\n");
  1761. DumpUnwindList( ReadField (UnwindQueue), TRUE );
  1762. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1763. }
  1764. if (ReadField (DelayMoveQueue)) {
  1765. dprintf("\t ***DelayMoveQueue***\n");
  1766. DumpDelayMoveList(ReadField (DelayMoveQueue), TRUE );
  1767. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1768. }
  1769. if (ReadField (DelayMoveQueueTail)) {
  1770. dprintf("\t ***DelayMoveQueueTail***\n");
  1771. DumpDelayMoveList( ReadField (DelayMoveQueueTail), TRUE );
  1772. InitTypeRead (pfq, SETUPAPI!SP_FILE_QUEUE);
  1773. }
  1774. }
  1775. return;
  1776. }
  1777. DECLARE_API( qcontext )
  1778. /*++
  1779. Routine Description:
  1780. This debugger extension dumps the data related to a queue context structure
  1781. Arguments:
  1782. Return Value:
  1783. --*/
  1784. {
  1785. ULONG64 pqc = 0, count = 0;
  1786. PUCHAR argptr = (PUCHAR) args;
  1787. UCHAR arg[2][100];
  1788. WCHAR Buffer[200];
  1789. ULONG argcount = 0;
  1790. while (*argptr != 0) {
  1791. if (*argptr == ' ') {
  1792. argcount++;
  1793. count = 0;
  1794. argptr++;
  1795. }
  1796. if (argcount > 1) {
  1797. break;
  1798. }
  1799. arg[argcount][count] = *argptr;
  1800. count++;
  1801. argptr++;
  1802. }
  1803. if (!arg[0][0]) {
  1804. dprintf ("qcontext: missing one or more parameters\nusage:!qcontext [address]\n");
  1805. return;
  1806. }
  1807. pqc = UtilStringToUlong64 (arg[0]);
  1808. InitTypeRead (pqc, SETUPAPI!QUEUECONTEXT);
  1809. dprintf("QUEUECONTEXT at :\t0x%016I64x\n", pqc);
  1810. dprintf("\t OwnerWindow : 0x%016I64x\n", ReadField (OwnerWindow));
  1811. dprintf("\t MainThreadId : 0x%016I64x\n", ReadField (MainThreadId));
  1812. dprintf("\t ProgressDialog : 0x%016I64x\n", ReadField (ProgressDialog));
  1813. dprintf("\t ProgressBar : 0x%016I64x\n", ReadField (ProgressBar));
  1814. dprintf("\t Cancelled : 0x%016I64x\n", ReadField (Cancelled));
  1815. UtilGetWStringField (pqc, "SETUPAPI!QUEUECONTEXT", "CurrentSourceName", Buffer, sizeof (Buffer));
  1816. dprintf("\t CurrentSourceName : %ws\n", Buffer);
  1817. dprintf("\t ScreenReader : 0x%016I64x\n", ReadField (ScreenReader));
  1818. dprintf("\t MessageBoxUp : 0x%016I64x\n", ReadField (MessageBoxUp));
  1819. dprintf("\t PendingUiType : 0x%016I64x\n", ReadField (PendingUiType));
  1820. dprintf("\t PendingUiParameters : 0x%016I64x\n", ReadField (PendingUiParameters));
  1821. dprintf("\t CancelReturnCode : 0x%016I64x\n", ReadField (CancelReturnCode));
  1822. dprintf("\t DialogKilled : 0x%016I64x\n", ReadField (DialogKilled));
  1823. dprintf("\t AlternateProgressWindow : 0x%016I64x\n", ReadField (AlternateProgressWindow));
  1824. dprintf("\t ProgressMsg : 0x%016I64x\n", ReadField (ProgressMsg));
  1825. dprintf("\t NoToAllMask : 0x%016I64x\n", ReadField (NoToAllMask));
  1826. dprintf("\t UiThreadHandle : 0x%016I64x\n", ReadField (UiThreadHandle));
  1827. }