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.

2061 lines
62 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: gdiexts.cxx
  3. *
  4. * Copyright (c) 1995-2000 Microsoft Corporation
  5. *
  6. \**************************************************************************/
  7. #include "precomp.hxx"
  8. // TODO: Break this file up grouping close knit extensions together.
  9. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  10. VOID vPrintBLTRECORD(VOID *pv);
  11. void vDumpLOGFONTW(LOGFONTW*, LOGFONTW*);
  12. #endif // DOES NOT SUPPORT API64
  13. //
  14. // This function is used for writing DIB images to disk in BMP format
  15. // from a debugger extension.
  16. //
  17. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  18. #define DIBDBG
  19. int WriteDIBToFile(void *pBits, DWORD w, DWORD h,
  20. LONG byte_width, int colordepth,
  21. void *pPal, DWORD palentries,
  22. char *filename) {
  23. FILE *fp;
  24. VOID *pvTmpBits=NULL;
  25. VOID *pvTmpPal=NULL;
  26. int r;
  27. #ifdef DIBDBG
  28. dprintf("input:\n");
  29. dprintf("pBits: %p\n", pBits);
  30. dprintf("width: %ld\n", w);
  31. dprintf("height: %ld\n", h);
  32. dprintf("byte width: %ld\n", byte_width);
  33. dprintf("color depth: %ld\n", colordepth);
  34. dprintf("pPal: %p\n", pPal);
  35. dprintf("palette entries: %ld\n", palentries);
  36. dprintf("filename: %s\n", filename);
  37. #endif
  38. dprintf("starting\n");
  39. if((fp = fopen(filename, "wb")) == NULL) {
  40. dprintf("Error opening %s\n", filename);
  41. dprintf("If you're using a share, make sure the share is writeable by the machine running the debugger\n");
  42. return 1;
  43. }
  44. dprintf("opened\n");
  45. if((pPal==NULL)&&(palentries!=0)) {
  46. dprintf("Palette pointer is NULL, but palentries is %ld (should be 0)\n", palentries);
  47. fclose(fp);
  48. return 2;
  49. }
  50. if(byte_width<0) {
  51. dprintf("Upside down DIB, inverting...\n");
  52. byte_width = -byte_width;
  53. }
  54. //write the file header
  55. BITMAPFILEHEADER bfh;
  56. bfh.bfType='MB'; //backwords 'BM'
  57. bfh.bfSize = (DWORD)byte_width*h+sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER);
  58. bfh.bfReserved1=0;
  59. bfh.bfReserved2=0;
  60. bfh.bfOffBits=sizeof(BITMAPFILEHEADER)+sizeof(BITMAPINFOHEADER)+sizeof(DWORD)*palentries;
  61. r = fwrite(&bfh, sizeof(bfh), 1, fp);
  62. if(!r) {
  63. dprintf("Error writing file header\n");
  64. fclose(fp);
  65. return 5;
  66. }
  67. dprintf("header\n");
  68. //write the BITMAPINFOHEADER
  69. BITMAPINFOHEADER bih;
  70. bih.biSize = sizeof(BITMAPINFOHEADER);
  71. bih.biWidth = (LONG)w;
  72. bih.biHeight = (LONG)h;
  73. bih.biPlanes = 1;
  74. bih.biBitCount = (WORD)colordepth;
  75. bih.biCompression = 0;
  76. bih.biSizeImage = 0;
  77. bih.biXPelsPerMeter = 0;
  78. bih.biYPelsPerMeter = 0;
  79. bih.biClrUsed = 0;
  80. bih.biClrImportant = 0;
  81. r = fwrite(&bih, sizeof(bih), 1, fp);
  82. if(!r) {
  83. dprintf("Error writing header\n");
  84. fclose(fp);
  85. return 4;
  86. }
  87. dprintf("header\n");
  88. //write out the palette - if one exists
  89. if( (pPal!=NULL)&&(palentries>0) ) {
  90. dprintf("writing the palette\n");
  91. pvTmpPal = (void *)malloc(sizeof(DWORD)*palentries);
  92. if(pvTmpPal==NULL) {
  93. fclose(fp);
  94. return 7;
  95. }
  96. move2(pvTmpPal, pPal, sizeof(DWORD)*palentries);
  97. r = fwrite(pvTmpPal, sizeof(DWORD)*palentries, 1, fp);
  98. if(!r) {
  99. dprintf("Error writing palette\n");
  100. fclose(fp);
  101. return 3;
  102. }
  103. }
  104. dprintf("palette\n");
  105. //write out the bits
  106. pvTmpBits = (VOID *)malloc(byte_width*h);
  107. if(pvTmpBits==NULL) {
  108. if(pvTmpPal) free(pvTmpPal);
  109. fclose(fp);
  110. return 8;
  111. }
  112. move2(pvTmpBits, pBits, byte_width*h);
  113. dprintf("bits\n");
  114. r = fwrite(pvTmpBits, byte_width*h, 1, fp);
  115. if(!r) {
  116. dprintf("Error writing bits\n");
  117. fclose(fp);
  118. return 6;
  119. }
  120. dprintf("write\n");
  121. fclose(fp);
  122. if(pvTmpPal) free(pvTmpPal);
  123. if(pvTmpBits) free(pvTmpBits);
  124. dprintf("Wrote DIB to %s\n", filename);
  125. return 0;
  126. }
  127. #endif // DOES NOT SUPPORT API64
  128. /******************************Public*Routine******************************\
  129. * DECLARE_API( ddib )
  130. *
  131. * History:
  132. * 11/12/98 -by- Adrian Secchia [asecchia]
  133. * Wrote it.
  134. \**************************************************************************/
  135. DECLARE_API( ddib )
  136. {
  137. PARSE_ARGUMENTS(ddib_help);
  138. if(ntok<1) {
  139. goto ddib_help;
  140. }
  141. int w_sw, h_sw, b_sw, f_sw, y_sw, p_sw, i_sw;
  142. //find valid tokens - ignore the rest
  143. w_sw = parse_iFindSwitch(tokens, ntok, 'w');
  144. h_sw = parse_iFindSwitch(tokens, ntok, 'h');
  145. b_sw = parse_iFindSwitch(tokens, ntok, 'b');
  146. f_sw = parse_iFindSwitch(tokens, ntok, 'f');
  147. y_sw = parse_iFindSwitch(tokens, ntok, 'y');
  148. p_sw = parse_iFindSwitch(tokens, ntok, 'p');
  149. i_sw = parse_iFindSwitch(tokens, ntok, 'i');
  150. //
  151. // i must be present unless all of w, h and b are present.
  152. // conversely w, h and b must be present unless i is present.
  153. // f must always be present
  154. //
  155. if( ((i_sw<0) && ((w_sw<0) || (h_sw<0) || (b_sw<0)) ) ||
  156. (f_sw<0)) {
  157. dprintf("required parameter missing\n");
  158. goto ddib_help;
  159. }
  160. if( (w_sw>ntok-3) || (h_sw>ntok-3) ||
  161. (b_sw>ntok-3) || (f_sw>ntok-3) ||
  162. (y_sw>ntok-3) || (p_sw>ntok-4) ||
  163. (i_sw>ntok-3) ) {
  164. dprintf("invalid parameter format\n");
  165. goto ddib_help;
  166. }
  167. EXIT_API(S_OK);
  168. ddib_help:
  169. dprintf("Usage: ddib [-?] [-i LPBITMAPINFO] [-w Width] [-h Height] [-f filename] [-b Bits] [-y Byte_Width] [-p palbits palsize] pbits\n");
  170. dprintf("\t-i required parameter specifies LPBITMAPINFO structure (hex)\n");
  171. dprintf("\t-w required parameter specifies width in pixels (hex)\n");
  172. dprintf("\t-h required parameter specifies height in pixels (hex)\n");
  173. dprintf("\t-b required parameter specifies number of bits per pixel (hex)\n");
  174. dprintf("\t-y optional parameter specifies byte width of dib (hex)\n"
  175. "\t if omitted this parameter is computed from w and b parameters\n");
  176. dprintf("\t-p optonal parameter specifies the palette pointer and the number of palette entries (hex)\n");
  177. dprintf("\t-f required parameter specifies the filename to store the dib - usually a public share\n");
  178. dprintf("\tpBits required parameter specifies pointer to the bit data - must be last.\n");
  179. dprintf("If the -i option is supplied then the -w, -h and -b become optional.\n");
  180. dprintf("If the -i is omitted, then -w, -h and -b are required.\n");
  181. EXIT_API(S_OK);
  182. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  183. int r;
  184. PVOID pvBits;
  185. PVOID pvPal=NULL;
  186. DWORD palsize = 0;
  187. DWORD bmiSize;
  188. LPBITMAPINFO pbmi;
  189. BITMAPINFO bmi;
  190. LONG w, h, b, bw;
  191. if(i_sw>=0) {
  192. pbmi = (LPBITMAPINFO)GetExpression(tokens[i_sw+1]);
  193. move2(&bmiSize, pbmi, sizeof(DWORD)); //Get the size of the BITMAPINFOHEADER
  194. if(bmiSize>sizeof(BITMAPINFOHEADER)) {
  195. dprintf("Invalid bmiSize\n");
  196. bmiSize = sizeof(BITMAPINFOHEADER);
  197. }
  198. move2(&bmi, pbmi, bmiSize); //I wonder if this could run off the end of the bitmapinfoheader while reading (it is a variable length structure - both the BITMAPINFOHEADER and the RGBQUAD)
  199. //
  200. // Set the parameters - they are possibly overwritten later
  201. // if other parameters are specified.
  202. //
  203. w = bmi.bmiHeader.biWidth;
  204. h = bmi.bmiHeader.biHeight;
  205. b = bmi.bmiHeader.biBitCount;
  206. //
  207. // Get the palette from the LPBITMAPINFO structure providing that
  208. // the user hasn't specified a manual palette address
  209. //
  210. if(p_sw<0) {
  211. pvPal = (PVOID) ( (PBYTE)pbmi+sizeof(BITMAPINFOHEADER) ); //point to the start of the rgbquad array
  212. switch(b) {
  213. case 0: break;
  214. case 1: palsize = 2; break;
  215. case 4: palsize = 16; break;
  216. case 8: palsize = 256; break;
  217. case 16:
  218. if(bmi.bmiHeader.biCompression==BI_BITFIELDS) {
  219. palsize = 3;
  220. break;
  221. }
  222. case 24:
  223. case 32:
  224. palsize = 0;
  225. pvPal = NULL;
  226. break;
  227. default:
  228. palsize = 0;
  229. pvPal = NULL;
  230. dprintf("WARNING: you're trying to dump a DIB with an unusual bit depth %d\n", b);
  231. dprintf("bit depth should be specified in hex!\n");
  232. break;
  233. }
  234. }
  235. if( (bmi.bmiHeader.biClrUsed<palsize) && (bmi.bmiHeader.biClrUsed>0) ) {
  236. palsize = bmi.bmiHeader.biClrUsed;
  237. }
  238. }
  239. if(w_sw>=0) { w = (LONG)GetExpression(tokens[w_sw+1]); }
  240. if(h_sw>=0) { h = (LONG)GetExpression(tokens[h_sw+1]); }
  241. if(b_sw>=0) { b = (LONG)GetExpression(tokens[b_sw+1]); }
  242. if(p_sw>=0) {
  243. pvPal = (PVOID)GetExpression(tokens[p_sw+1]);
  244. palsize = (LONG)GetExpression(tokens[p_sw+2]);
  245. }
  246. if(y_sw>=0) {
  247. bw = (LONG)GetExpression(tokens[y_sw+1]);
  248. } else {
  249. switch(b) {
  250. case 32: bw = w*4; break;
  251. case 24: bw = w*3; break;
  252. case 16: bw = w*2; break;
  253. case 8: bw = w; break;
  254. case 1: bw = w/8 + (int)((w%8) != 0); break;
  255. default: bw = w;
  256. }
  257. }
  258. pvBits = (PVOID)GetExpression(tokens[ntok-1]);
  259. if( (r=WriteDIBToFile(pvBits, w, h, bw, b, pvPal, palsize, tokens[f_sw+1])) !=0 ) {
  260. dprintf("Error %d writing to file\n", r);
  261. goto ddib_help;
  262. }
  263. return;
  264. #endif // DOES NOT SUPPORT API64
  265. }
  266. /******************************Public*Routine******************************\
  267. * VOID vPrintBLTRECORD
  268. *
  269. * Dump the contents of BLTRECORD structure
  270. *
  271. * History:
  272. * 13-Apr-1993 -by- Donald Sidoroff [donalds]
  273. * Wrote it.
  274. \**************************************************************************/
  275. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  276. VOID vPrintBLTRECORD(VOID *pv)
  277. {
  278. BLTRECORD *pblt = (BLTRECORD *) pv;
  279. dprintf("SURFOBJ *psoTrg 0x%08lx\n", pblt->pSurfTrg()->pSurfobj());
  280. dprintf("SURFOBJ *psoSrc 0x%08lx\n", pblt->pSurfSrc()->pSurfobj());
  281. dprintf("SURFOBJ *psoMsk 0x%08lx\n", pblt->pSurfMsk()->pSurfobj());
  282. dprintf("POINTFIX aptfx[0] = (0x%07lx.%1lx, 0x%07lx.%1lx)\n",
  283. pblt->pptfx()[0].x >> 4, pblt->pptfx()[0].x & 15, pblt->pptfx()[0].y >> 4, pblt->pptfx()[0].y & 15);
  284. dprintf("POINTFIX aptfx[1] = (0x%07lx.%1lx, 0x%07lx.%1lx)\n",
  285. pblt->pptfx()[1].x >> 4, pblt->pptfx()[1].x & 15, pblt->pptfx()[1].y >> 4, pblt->pptfx()[1].y & 15);
  286. dprintf("POINTFIX aptfx[2] = (0x%07lx.%1lx, 0x%07lx.%1lx)\n",
  287. pblt->pptfx()[2].x >> 4, pblt->pptfx()[2].x & 15, pblt->pptfx()[2].y >> 4, pblt->pptfx()[2].y & 15);
  288. dprintf("POINTFIX aptfx[3] = (0x%07lx.%1lx, 0x%07lx.%1lx)\n",
  289. pblt->pptfx()[3].x >> 4, pblt->pptfx()[3].x & 15, pblt->pptfx()[3].y >> 4, pblt->pptfx()[3].y & 15);
  290. dprintf("POINTL aptlTrg[0] = (0x%08lx, 0x%08lx)\n", pblt->pptlTrg()[0].x, pblt->pptlTrg()[0].y);
  291. dprintf("POINTL aptlTrg[1] = (0x%08lx, 0x%08lx)\n", pblt->pptlTrg()[1].x, pblt->pptlTrg()[1].y);
  292. dprintf("POINTL aptlTrg[2] = (0x%08lx, 0x%08lx)\n", pblt->pptlTrg()[2].x, pblt->pptlTrg()[2].y);
  293. dprintf("POINTL aptlSrc[0] = (0x%08lx, 0x%08lx)\n", pblt->pptlSrc()[0].x, pblt->pptlSrc()[0].y);
  294. dprintf("POINTL aptlSrc[1] = (0x%08lx, 0x%08lx)\n", pblt->pptlSrc()[1].x, pblt->pptlSrc()[1].y);
  295. dprintf("POINTL aptlMask[0] = (0x%08lx, 0x%08lx)\n", pblt->pptlMask()[0].x, pblt->pptlMask()[0].y);
  296. dprintf("POINTL aptlBrush[0] = (0x%08lx, 0x%08lx)\n", pblt->pptlBrush()[0].x, pblt->pptlBrush()[0].y);
  297. dprintf("ROP4 rop4 = 0x%08lx, FLONG flState = 0x%08lx\n", pblt->rop(), pblt->flGet());
  298. }
  299. #endif // DOES NOT SUPPORT API64
  300. /******************************Public*Routine******************************\
  301. * DECLARE_API( dblt )
  302. *
  303. * History:
  304. * 21-Feb-1995 -by- Lingyun Wang [lingyunw]
  305. * Wrote it.
  306. \**************************************************************************/
  307. DECLARE_API( dblt )
  308. {
  309. dprintf("Use 'dt win32k!BLTRECORD -r <Address>'\n");
  310. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  311. DWORD blt[1024];
  312. PARSE_POINTER(dblt_help);
  313. dprintf("BLTRECORD structure at 0x%p:\n", (PVOID)arg);
  314. move2(blt, (BLTRECORD *)arg, sizeof(BLTRECORD));
  315. vPrintBLTRECORD(blt);
  316. return;
  317. dblt_help:
  318. dprintf("Usage: dblt [-?] BLTRECORD_PTR\n");
  319. #endif // DOES NOT SUPPORT API64
  320. EXIT_API(S_OK);
  321. }
  322. /******************************Public*Routine******************************\
  323. * xlate
  324. *
  325. \**************************************************************************/
  326. DECLARE_API( xlate )
  327. {
  328. return ExtDumpType(Client, "xlate", "XLATE", args);
  329. }
  330. /******************************Public*Routine******************************\
  331. * bltinfo
  332. *
  333. \**************************************************************************/
  334. DECLARE_API( bltinfo )
  335. {
  336. return ExtDumpType(Client, "bltinfo", "BLTINFO", args);
  337. }
  338. /******************************Public*Routine******************************\
  339. * stats
  340. *
  341. * 27-Feb-1995 -by- Eric Kutter [erick]
  342. * Wrote it.
  343. \**************************************************************************/
  344. PSZ apszGetDCDword[] =
  345. {
  346. "GCAPS ",
  347. "STRETCHBLTMODE ",
  348. "GRAPHICSMODE ",
  349. "ROP2 ",
  350. "BKMODE ",
  351. "POLYFILLMODE ",
  352. "TEXTALIGN ",
  353. "TEXTCHARACTEREXTRA ",
  354. "TEXTCOLOR ",
  355. "BKCOLOR ",
  356. "RELABS ",
  357. "BREAKEXTRA ",
  358. "CBREAK ",
  359. "MAPMODE ",
  360. "ARCDIRECTION ",
  361. "SAVEDEPTH ",
  362. "FONTLANGUAGEINFO "
  363. };
  364. PSZ apszSetDCDword[] =
  365. {
  366. "UNUSED ",
  367. "EPSPRINTESCCALLED ",
  368. "COPYCOUNT ",
  369. "BKMODE ",
  370. "POLYFILLMODE ",
  371. "ROP2 ",
  372. "STRETCHBLTMODE ",
  373. "TEXTALIGN ",
  374. "BKCOLOR ",
  375. "RELABS ",
  376. "TEXTCHARACTEREXTRA ",
  377. "TEXTCOLOR ",
  378. "SELECTFONT ",
  379. "MAPPERFLAGS ",
  380. "MAPMODE ",
  381. "ARCDIRECTION ",
  382. "GRAPHICSMODE "
  383. };
  384. PSZ apszGetDCPoint[] =
  385. {
  386. "UNUSED ",
  387. "VPEXT ",
  388. "WNDEXT ",
  389. "VPORG ",
  390. "WNDORG ",
  391. "ASPECTRATIOFILTER ",
  392. "BRUSHORG ",
  393. "DCORG ",
  394. "CURRENTPOSITION "
  395. };
  396. PSZ apszSetDCPoint[] =
  397. {
  398. "VPEXT ",
  399. "WNDEXT ",
  400. "VPORG ",
  401. "WNDORG ",
  402. "OFFVPORG ",
  403. "OFFWNDORG ",
  404. "MAX "
  405. };
  406. DECLARE_API( stats )
  407. {
  408. dprintf("Extension 'stats' is not converted.\n");
  409. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  410. #if DBG
  411. DWORD adw[100];
  412. PDWORD pdw;
  413. int i;
  414. PARSE_ARGUMENTS(stats_help);
  415. // Get DCDword
  416. GetAddress(pdw, "win32k!acGetDCDword");
  417. move2(adw, pdw, sizeof(DWORD) * DDW_MAX);
  418. dprintf("\nGetDCDword %lx:\n",pdw);
  419. //CHECKLOOP
  420. for (i = 0; i < DDW_MAX; ++i)
  421. {
  422. if (adw[i])
  423. dprintf("\t%2ld: %s, %4d\n",i,apszGetDCDword[i],adw[i]);
  424. }
  425. // Set DCDword
  426. GetAddress(pdw, "win32k!acSetDCDword");
  427. move2(adw, pdw, sizeof(DWORD) * GASDDW_MAX);
  428. dprintf("\nSetDCDword:\n");
  429. //CHECKLOOP
  430. for (i = 0; i < GASDDW_MAX; ++i)
  431. {
  432. if (adw[i])
  433. dprintf("\t%2ld: %s, %4d\n",i,apszSetDCDword[i],adw[i]);
  434. }
  435. // Get DCPoint
  436. GetAddress(pdw, "win32k!acGetDCPoint");
  437. move2(adw, pdw, sizeof(DWORD) * DCPT_MAX);
  438. dprintf("\nGetDCPoint:\n");
  439. //CHECKLOOP
  440. for (i = 0; i < DCPT_MAX; ++i)
  441. {
  442. if (adw[i])
  443. dprintf("\t%2ld: %s, %4d\n",i,apszGetDCPoint[i],adw[i]);
  444. }
  445. // Set DCPoint
  446. GetAddress(pdw, "win32k!acSetDCPoint");
  447. move2(adw, pdw, sizeof(DWORD) * GASDCPT_MAX);
  448. dprintf("\nSetDCPoint:\n");
  449. //CHECKLOOP
  450. for (i = 0; i < GASDCPT_MAX; ++i)
  451. {
  452. if (adw[i])
  453. dprintf("\t%2ld: %s, %4d\n",i,apszSetDCPoint[i],adw[i]);
  454. }
  455. #else
  456. goto stats_help;
  457. #endif
  458. return;
  459. stats_help:
  460. dprintf("Usage: stats [-?]\n");
  461. dprintf("-? displays this help.\n");
  462. dprintf("stats only works in checked builds.\n");
  463. #endif // DOES NOT SUPPORT API64
  464. EXIT_API(S_OK);
  465. }
  466. /******************************Public*Routine******************************\
  467. * PALETTE
  468. *
  469. \**************************************************************************/
  470. DECLARE_API( palette )
  471. {
  472. BEGIN_API( palette );
  473. HRESULT hr = S_OK;
  474. OutputControl OutCtl(Client);
  475. ULONG64 PaletteAddr;
  476. DEBUG_VALUE Arg;
  477. DEBUG_VALUE Offset;
  478. while (isspace(*args)) args++;
  479. if (*args == '-' ||
  480. (hr = Evaluate(Client, args, DEBUG_VALUE_INT64, 0, &Arg, NULL)) != S_OK)
  481. {
  482. OutCtl.Output("Usage: palette [-?] <HPALETTE | PALETTE Addr>\n");
  483. }
  484. else
  485. {
  486. hr = GetObjectAddress(Client,Arg.I64,&PaletteAddr,PAL_TYPE,TRUE,TRUE);
  487. if (hr != S_OK || PaletteAddr == 0)
  488. {
  489. DEBUG_VALUE ObjHandle;
  490. TypeOutputParser TypeParser(Client);
  491. OutputState OutState(Client);
  492. ULONG64 PaletteAddrFromHmgr;
  493. PaletteAddr = Arg.I64;
  494. // Try to read hHmgr from PALETTE type, but if that
  495. // fails use the BASEOBJECT type, which is public.
  496. if ((hr = OutState.Setup(0, &TypeParser)) != S_OK ||
  497. (hr = OutState.OutputTypeVirtual(PaletteAddr, GDIType(PALETTE), 0)) != S_OK ||
  498. (hr = TypeParser.Get(&ObjHandle, "hHmgr", DEBUG_VALUE_INT64)) != S_OK)
  499. {
  500. OutCtl.OutErr("Unable to get contents of PALETTE's handle\n");
  501. OutCtl.OutErr(" (Type Read returned %s)\n", pszHRESULT(hr));
  502. OutCtl.OutErr(" 0x%p is neither an HPALETTE nor valid PALETTE address\n", Arg.I64);
  503. }
  504. else
  505. {
  506. if (GetObjectAddress(Client,ObjHandle.I64,&PaletteAddrFromHmgr,
  507. PAL_TYPE,TRUE,FALSE) == S_OK &&
  508. PaletteAddr != PaletteAddrFromHmgr)
  509. {
  510. OutCtl.OutWarn("\tNote: PALETTE may not be valid.\n"
  511. "\t It does not have a valid handle manager entry.\n");
  512. }
  513. }
  514. }
  515. if (hr == S_OK)
  516. {
  517. hr = DumpType(Client, "PALETTE", PaletteAddr);
  518. if (hr != S_OK)
  519. {
  520. OutCtl.OutErr("Type Dump for PALETTE returned %s.\n", pszHRESULT(hr));
  521. }
  522. }
  523. }
  524. return hr;
  525. }
  526. DECLARE_API( dppal )
  527. {
  528. INIT_API();
  529. ExtOut("Obsolete: Use 'palette poi(<EPALOBJ Addr>)'.\n");
  530. EXIT_API(S_OK);
  531. }
  532. /******************************Public*Routine******************************\
  533. * DECLARE_API( sprite )
  534. *
  535. \**************************************************************************/
  536. PCSTR SpriteFields[] = {
  537. "dwShape",
  538. "fl",
  539. "BlendFunction",
  540. "pState",
  541. "pNextZ",
  542. "pNextY",
  543. "pPreviousY",
  544. "pNextActive",
  545. "rclSprite",
  546. "rclSrc",
  547. "psoShape",
  548. "psoUnderlay",
  549. "prgnClip",
  550. "ppalShape",
  551. NULL
  552. };
  553. DECLARE_API( sprite )
  554. {
  555. BEGIN_API( sprite );
  556. HRESULT hr = S_OK;
  557. BOOL DumpAll = FALSE;
  558. DEBUG_VALUE Offset;
  559. ULONG64 Module;
  560. ULONG TypeId;
  561. OutputControl OutCtl(Client);
  562. while (isspace(*args)) args++;
  563. if (args[0] == '-' && tolower(args[1]) == 'a' && isspace(args[2]))
  564. {
  565. DumpAll = TRUE;
  566. args+=3;
  567. }
  568. if (*args == '-' ||
  569. (hr = Evaluate(Client, args, DEBUG_VALUE_INT64, 0, &Offset, NULL)) != S_OK ||
  570. Offset.I64 == 0)
  571. {
  572. OutCtl.Output("Usage: sprite [-?a] <SPRITE Addr>\n"
  573. " -a - dump entire structure\n");
  574. }
  575. else
  576. {
  577. if ((hr = GetTypeId(Client, "SPRITE", &TypeId, &Module)) == S_OK)
  578. {
  579. TypeOutputDumper TypeReader(Client, &OutCtl);
  580. if (!DumpAll)
  581. {
  582. TypeReader.MarkFields(SpriteFields);
  583. }
  584. OutCtl.Output(" SPRITE @ 0x%p:\n", Offset.I64);
  585. hr = TypeReader.OutputVirtual(Module, TypeId, Offset.I64);
  586. }
  587. if (hr != S_OK)
  588. {
  589. OutCtl.OutErr("Type Dump for SPRITE returned %s.\n", pszHRESULT(hr));
  590. }
  591. }
  592. return hr;
  593. }
  594. /******************************Public*Routine******************************\
  595. * DECLARE_API( spritestate )
  596. *
  597. \**************************************************************************/
  598. PCSTR SpriteStateFields[] = {
  599. "hdev",
  600. "cVisible",
  601. "pListZ",
  602. "pListY",
  603. "psoScreen",
  604. "cVisible",
  605. "pRange",
  606. "pRangeLimit",
  607. "psoComposite",
  608. "prgnUnlocked",
  609. NULL
  610. };
  611. PCSTR SpriteStateCursorFields[] = {
  612. "pSpriteCursor",
  613. "xHotCursor",
  614. "yHotCursor",
  615. "ulNumCursors",
  616. "pTopCursor",
  617. "pBottomCursor",
  618. "ulTrailTimeStamp",
  619. "ulTrailPeriod",
  620. NULL
  621. };
  622. PCSTR SpriteStateHookFields[] = {
  623. "bHooked",
  624. "bInsideDriverCall",
  625. "flOriginalSurfFlags",
  626. "iOriginalType",
  627. "flSpriteSurfFlags",
  628. "iSpriteType",
  629. NULL
  630. };
  631. PCSTR SpriteStateMetaFields[] = {
  632. "cMultiMon",
  633. "ahdevMultiMon",
  634. "pListMeta",
  635. NULL
  636. };
  637. PCSTR SpriteStateLargeFields[] = {
  638. "coTmp",
  639. "coRectangular",
  640. NULL
  641. };
  642. DECLARE_API( spritestate )
  643. {
  644. BEGIN_API( spritestate );
  645. HRESULT hr = S_OK;
  646. BOOL BadSwitch = FALSE;
  647. BOOL DumpAll = FALSE;
  648. BOOL DumpCursor = FALSE;
  649. BOOL DumpHook = FALSE;
  650. BOOL DumpMeta = FALSE;
  651. DEBUG_VALUE Offset;
  652. ULONG64 Module;
  653. ULONG TypeId;
  654. OutputControl OutCtl(Client);
  655. while (!BadSwitch)
  656. {
  657. while (isspace(*args)) args++;
  658. if (*args != '-') break;
  659. args++;
  660. BadSwitch = (*args == '\0' || isspace(*args));
  661. while (*args != '\0' && !isspace(*args))
  662. {
  663. switch (*args)
  664. {
  665. case 'a': DumpAll = TRUE; break;
  666. case 'c': DumpCursor = TRUE; break;
  667. case 'h': DumpHook = TRUE; break;
  668. case 'm': DumpMeta = TRUE; break;
  669. default:
  670. BadSwitch = TRUE;
  671. break;
  672. }
  673. if (BadSwitch) break;
  674. args++;
  675. }
  676. }
  677. if (BadSwitch ||
  678. (hr = Evaluate(Client, args, DEBUG_VALUE_INT64, 0, &Offset, NULL)) != S_OK ||
  679. Offset.I64 == 0)
  680. {
  681. OutCtl.Output("Usage: spritestate [-?chma] <SPRITESTATE Addr>\n"
  682. " -c - dump cursor fields\n"
  683. " -h - dump hook fields\n"
  684. " -m - dump meta fields\n"
  685. " -a - dump entire structure\n");
  686. }
  687. else
  688. {
  689. if ((hr = GetTypeId(Client, "SPRITESTATE", &TypeId, &Module)) == S_OK)
  690. {
  691. TypeOutputDumper TypeReader(Client, &OutCtl);
  692. if (DumpAll)
  693. {
  694. TypeReader.ExcludeMarked();
  695. TypeReader.MarkFields(SpriteStateLargeFields);
  696. }
  697. else
  698. {
  699. TypeReader.IncludeMarked();
  700. TypeReader.MarkFields(SpriteStateFields);
  701. if (DumpCursor)
  702. {
  703. TypeReader.MarkFields(SpriteStateCursorFields);
  704. }
  705. if (DumpHook)
  706. {
  707. TypeReader.MarkFields(SpriteStateHookFields);
  708. }
  709. if (DumpMeta)
  710. {
  711. TypeReader.MarkFields(SpriteStateMetaFields);
  712. }
  713. }
  714. OutCtl.Output(" SPRITESTATE @ 0x%p:\n", Offset.I64);
  715. hr = TypeReader.OutputVirtual(Module, TypeId, Offset.I64);
  716. }
  717. if (hr != S_OK)
  718. {
  719. OutCtl.OutErr("Type Dump for SPRITESTATE returned %s.\n", pszHRESULT(hr));
  720. }
  721. }
  722. return hr;
  723. }
  724. /**************************************************************************\
  725. * PDEV Fields
  726. *
  727. \**************************************************************************/
  728. PCSTR GeneralPDEVFields[] = {
  729. "ppdevNext",
  730. "fl",
  731. "cPdevRefs",
  732. "cPdevOpenRefs",
  733. "pldev",
  734. "dhpdev",
  735. "hSpooler",
  736. "pSurface",
  737. "ppalSurf",
  738. "eDirectDrawGlobal.",
  739. "SpriteState.",
  740. "pDesktopId",
  741. "pGraphicsDevice",
  742. "ppdevParent",
  743. "hsemDevLock",
  744. "ptlOrigin",
  745. "apfn.",
  746. "daDirectDrawContext.",
  747. NULL
  748. };
  749. PCSTR PDEVPointerFields[] = {
  750. "ptlPointer",
  751. "pfnDrvSetPointerShape",
  752. "pfnDrvMovePointer",
  753. "pfnMovePointer",
  754. "pfnSync",
  755. "hsemPointer",
  756. NULL
  757. };
  758. PCSTR PDEVFontFields[] = {
  759. "hlfntDefault",
  760. "hlfntAnsiVariable",
  761. "hlfntAnsiFixed",
  762. "prfntActive",
  763. "prfntInactive",
  764. "cInactive",
  765. NULL
  766. };
  767. PCSTR PDEVDevInfoFields[] = {
  768. "devinfo.flGraphicsCaps",
  769. "devinfo.cFonts",
  770. "devinfo.iDitherFormat",
  771. "devinfo.cxDither",
  772. "devinfo.cyDither",
  773. "devinfo.hpalDefault",
  774. "devinfo.flGraphicsCaps2",
  775. NULL
  776. };
  777. PCSTR PDEVPatternFields[] = {
  778. "ahsurf", // To Do: make sure array gets dumped
  779. "pDevHTInfo",
  780. NULL
  781. };
  782. PCSTR PDEVGDIInfoFields[] = {
  783. "GdiInfo",
  784. "flAccelerated",
  785. NULL
  786. };
  787. PCSTR PDEVSpriteStateFields[] = {
  788. "SpriteState.bHooked",
  789. "SpriteState.pListZ",
  790. "SpriteState.psoScreen",
  791. "SpriteState.cVisible",
  792. "SpriteState.cMultiMon",
  793. "SpriteState.bInsideDriverCall",
  794. "SpriteState.iOriginalType",
  795. "SpriteState.iSpriteType",
  796. "SpriteState.pBottomCursor",
  797. "SpriteState.ulNumCursors",
  798. NULL
  799. };
  800. /******************************Public*Routine******************************\
  801. * PDEV
  802. *
  803. \**************************************************************************/
  804. DECLARE_API( pdev )
  805. {
  806. BEGIN_API( pdev );
  807. INIT_API();
  808. HRESULT hr = S_OK;
  809. DEBUG_VALUE Offset;
  810. ULONG64 Module;
  811. ULONG TypeId;
  812. OutputControl OutCtl(Client);
  813. BOOL BadSwitch = FALSE;
  814. BOOL DumpAll = FALSE;
  815. BOOL DumpDEVINFO = FALSE;
  816. BOOL DumpFont = FALSE;
  817. BOOL DumpGDIINFO = FALSE;
  818. BOOL DumpPattern = FALSE;
  819. BOOL DumpPointer = FALSE;
  820. BOOL DumpSpriteState = FALSE;
  821. BOOL Recurse = FALSE;
  822. BOOL DisplaysOnly = FALSE;
  823. while (!BadSwitch)
  824. {
  825. while (isspace(*args)) args++;
  826. if (*args != '-') break;
  827. args++;
  828. BadSwitch = (*args == '\0' || isspace(*args));
  829. while (*args != '\0' && !isspace(*args))
  830. {
  831. switch (*args)
  832. {
  833. case 'a': DumpAll = TRUE; break;
  834. case 'd': DumpDEVINFO = TRUE; break;
  835. case 'f': DumpFont = TRUE; break;
  836. case 'g': DumpGDIINFO = TRUE; break;
  837. case 'n': DumpPattern = TRUE; break;
  838. case 'p': DumpPointer = TRUE; break;
  839. case 's': DumpSpriteState = TRUE; break;
  840. case 'r':
  841. case 'R': Recurse = TRUE; break;
  842. case 'D': DisplaysOnly = TRUE; break;
  843. default:
  844. BadSwitch = TRUE;
  845. break;
  846. }
  847. if (BadSwitch) break;
  848. args++;
  849. }
  850. }
  851. if (BadSwitch)
  852. {
  853. OutCtl.Output("Usage: pdev [-?adfgnpsRD] [PDEV Addr]\n"
  854. "\n"
  855. " PDEV Addr - address of PDEV otherwise win32k!gppdevList is used\n"
  856. "\n"
  857. " a - All info (dump everything)\n"
  858. " d - DEVINFO struct\n"
  859. " f - Font info\n"
  860. " g - GDIINFO struct\n"
  861. " m - DEVMODE\n"
  862. " n - Default patterns\n"
  863. " p - Pointer info\n"
  864. " s - SpriteState\n"
  865. "\n"
  866. " R - Recurse\n"
  867. " D - Display devices only\n");
  868. }
  869. else if (*args != '\0' &&
  870. ((hr = Evaluate(Client, args, DEBUG_VALUE_INT64, 0, &Offset, NULL)) != S_OK ||
  871. Offset.I64 == 0))
  872. {
  873. if (hr == S_OK)
  874. {
  875. OutCtl.Output("Expression %s evalated to zero.\n", args);
  876. }
  877. else
  878. {
  879. OutCtl.OutErr("Evaluate(%s) returned %s.\n", args, pszHRESULT(hr));
  880. }
  881. }
  882. else
  883. {
  884. // If no address was given use win32k!gppdevList
  885. if (*args == '\0')
  886. {
  887. DEBUG_VALUE ppdevList;
  888. hr = g_pExtControl->Evaluate(GDISymbol(gppdevList),
  889. DEBUG_VALUE_INT64,
  890. &ppdevList,
  891. NULL);
  892. if (hr == S_OK)
  893. {
  894. if (SessionId == CURRENT_SESSION)
  895. {
  896. hr = g_pExtData->ReadPointersVirtual(1, ppdevList.I64, &Offset.I64);
  897. }
  898. else
  899. {
  900. ULONG64 ppdevListPhys;
  901. if ((hr = GetPhysicalAddress(Client,
  902. SessionId,
  903. ppdevList.I64,
  904. &ppdevListPhys)) == S_OK)
  905. {
  906. hr = ReadPointerPhysical(Client, ppdevListPhys, &Offset.I64);
  907. if (hr == S_OK)
  908. {
  909. OutCtl.Output("First PDEV in session %lu located at 0x%p.\n",
  910. SessionId, Offset.I64);
  911. }
  912. }
  913. }
  914. if (hr == S_OK)
  915. {
  916. if (Offset.I64 == 0)
  917. {
  918. OutCtl.OutErr(" Displays are not initialized or symbols are incorrect.\n"
  919. " %s @ %#p is NULL.\n", GDISymbol(gppdevList), ppdevList.I64);
  920. hr = S_FALSE;
  921. }
  922. }
  923. else
  924. {
  925. OutCtl.OutErr("Unable to get the contents of %s @ %#p\n", GDISymbol(gppdevList), ppdevList.I64);
  926. }
  927. }
  928. else
  929. {
  930. OutCtl.OutErr("Unable to locate %s\n", GDISymbol(gppdevList));
  931. }
  932. }
  933. OutputFilter OutFilter(Client);
  934. OutputState OutState(Client);
  935. if (hr == S_OK &&
  936. (hr = OutState.Setup(0, &OutFilter)) == S_OK &&
  937. (hr = GetTypeId(Client, "PDEV", &TypeId, &Module)) == S_OK)
  938. {
  939. TypeOutputDumper TypeReader(OutState.Client, &OutCtl);
  940. do
  941. {
  942. if (OutCtl.GetInterrupt() == S_OK) break;
  943. OutCtl.Output("PDEV @ 0x%p:\n", Offset.I64);
  944. // Read two fields to OutFilter: 'ppdevNext' and 'fl'
  945. OutFilter.DiscardOutput();
  946. TypeReader.IncludeMarked();
  947. TypeReader.ClearMarks();
  948. TypeReader.MarkField("ppdevNext");
  949. TypeReader.MarkField("fl");
  950. if ((hr = OutCtl.SetControl(DEBUG_OUTCTL_THIS_CLIENT |
  951. DEBUG_OUTCTL_NOT_LOGGED |
  952. DEBUG_OUTCTL_OVERRIDE_MASK,
  953. OutState.Client)) == S_OK &&
  954. (hr = TypeReader.OutputVirtual(Module, TypeId, Offset.I64)) == S_OK &&
  955. (hr = OutCtl.SetControl(DEBUG_OUTCTL_AMBIENT, Client)) == S_OK)
  956. {
  957. // If we only want displays, check for PDEV_DISPLAY
  958. // in OutFilter (
  959. if (!DisplaysOnly ||
  960. OutFilter.Query("PDEV_DISPLAY") == S_OK)
  961. {
  962. TypeReader.ClearMarks();
  963. if (DumpAll)
  964. {
  965. TypeReader.ExcludeMarked();
  966. // Don't recurse for big sub structures
  967. TypeReader.MarkField("SpriteState.*");
  968. TypeReader.MarkField("devinfo.*");
  969. TypeReader.MarkField("GdiInfo.*");
  970. }
  971. else
  972. {
  973. TypeReader.IncludeMarked();
  974. TypeReader.MarkFields(GeneralPDEVFields);
  975. if (DumpDEVINFO)
  976. {
  977. TypeReader.MarkFields(PDEVDevInfoFields);
  978. }
  979. if (DumpFont)
  980. {
  981. TypeReader.MarkFields(PDEVFontFields);
  982. }
  983. if (DumpGDIINFO)
  984. {
  985. TypeReader.MarkFields(PDEVGDIInfoFields);
  986. }
  987. if (DumpPattern)
  988. {
  989. TypeReader.MarkFields(PDEVPatternFields);
  990. }
  991. if (DumpPointer)
  992. {
  993. TypeReader.MarkFields(PDEVPointerFields);
  994. }
  995. if (DumpSpriteState)
  996. {
  997. TypeReader.MarkFields(PDEVSpriteStateFields);
  998. }
  999. }
  1000. hr = TypeReader.OutputVirtual(Module, TypeId, Offset.I64);
  1001. }
  1002. else
  1003. {
  1004. OutCtl.Output(" Not marked PDEV_DISPLAY.\n");
  1005. }
  1006. if (Recurse)
  1007. {
  1008. hr = OutFilter.Query("ppdevNext", &Offset, DEBUG_VALUE_INT64);
  1009. if (hr == S_OK)
  1010. {
  1011. if (Offset.I64 != 0)
  1012. {
  1013. OutCtl.Output("-----------------------------------\n");
  1014. }
  1015. else
  1016. {
  1017. Recurse = FALSE;
  1018. }
  1019. }
  1020. }
  1021. }
  1022. } while (hr == S_OK && Recurse);
  1023. if (hr != S_OK)
  1024. {
  1025. OutCtl.OutErr("Type Dump for PDEV returned %s.\n", pszHRESULT(hr));
  1026. }
  1027. }
  1028. else
  1029. {
  1030. OutCtl.OutErr("Type Dump setup for PDEV returned %s.\n", pszHRESULT(hr));
  1031. }
  1032. }
  1033. EXIT_API(hr);
  1034. }
  1035. DECLARE_API( dpdev )
  1036. {
  1037. return pdev(Client, args);
  1038. }
  1039. /******************************Public*Routine******************************\
  1040. * dldev
  1041. *
  1042. * Syntax: dldev [LDEV pointer]
  1043. *
  1044. * History:
  1045. * Andre Vachon [andreva]
  1046. * Wrote it.
  1047. \**************************************************************************/
  1048. DECLARE_API (dldev)
  1049. {
  1050. dprintf("Extension 'dldev' is not converted.\n");
  1051. #if ENABLE_OLD_EXTS // DOES NOT SUPPORT API64
  1052. BOOL recursive = TRUE;
  1053. PWSZ psz;
  1054. PLDEV pldevNext, pl_CD;
  1055. LDEV ldev;
  1056. WCHAR DriverName[MAX_PATH];
  1057. SYSTEM_GDI_DRIVER_INFORMATION GdiDriverInfo;
  1058. BOOL invalid_type = false;
  1059. BOOL force;
  1060. int forcenum=0;
  1061. BOOL forcecount;
  1062. BOOL FirstLoop=FALSE;
  1063. GetValue(pldevNext, "win32k!gpldevDrivers");
  1064. PARSE_ARGUMENTS(dldev_help);
  1065. if(ntok<1) { goto dldev_help; }
  1066. tok_pos = parse_FindNonSwitch(tokens, ntok);
  1067. if(tok_pos==-1) { goto dldev_help; }
  1068. if(parse_IsSwitch(tokens, tok_pos-1, 'F')) {
  1069. tok_pos = parse_FindNonSwitch(tokens, ntok, tok_pos+1);
  1070. }
  1071. if(tok_pos==-1) { goto dldev_help; }
  1072. pl_CD = pldevNext = (PLDEV)GetExpression(tokens[tok_pos]);
  1073. force = (parse_FindSwitch(tokens, ntok, 'f')!=-1);
  1074. forcecount = ((tok_pos = parse_FindSwitch(tokens, ntok, 'F'))!=-1);
  1075. if(tok_pos != -1) {
  1076. if(((tok_pos+1)>=ntok)||
  1077. (sscanf(tokens[tok_pos+1], "%d", &forcenum)!=1)) {
  1078. goto dldev_help;
  1079. }
  1080. }
  1081. dprintf("\n--------------------------------------------------\n");
  1082. do
  1083. {
  1084. if(forcecount) {
  1085. if((--forcenum)<0) {
  1086. break;
  1087. }
  1088. }
  1089. if(pl_CD) {
  1090. ReadMemory((UINT_PTR)pl_CD, &ldev, sizeof(LDEV), NULL);
  1091. pl_CD = ldev.pldevNext;
  1092. if(pl_CD) {
  1093. ReadMemory((UINT_PTR)pl_CD, &ldev, sizeof(LDEV), NULL);
  1094. pl_CD = ldev.pldevNext;
  1095. }
  1096. }
  1097. ReadMemory((UINT_PTR)pldevNext, &ldev, sizeof(LDEV), NULL);
  1098. dprintf("ldev = 0x%lx\n", pldevNext);
  1099. switch (ldev.ldevType)
  1100. {
  1101. case LDEV_DEVICE_DISPLAY:
  1102. psz = L"LDEV_DEVICE_DISPLAY";
  1103. break;
  1104. case LDEV_DEVICE_PRINTER:
  1105. psz = L"LDEV_DEVICE_PRINTER";
  1106. break;
  1107. case LDEV_FONT:
  1108. psz = L"LDEV_FONT";
  1109. break;
  1110. case LDEV_DEVICE_META:
  1111. psz = L"LDEV_DEVICE_META";
  1112. break;
  1113. case LDEV_DEVICE_MIRROR:
  1114. psz = L"LDEV_DEVICE_MIRROR";
  1115. break;
  1116. case LDEV_IMAGE:
  1117. psz = L"LDEV_IMAGE";
  1118. break;
  1119. default:
  1120. invalid_type = true;
  1121. psz = L"INVALID LDEV TYPE";
  1122. break;
  1123. }
  1124. dprintf("next ldev = 0x%lx\n", ldev.pldevNext );
  1125. dprintf("previous ldev = 0x%lx\n", ldev.pldevPrev );
  1126. dprintf("levtype = %ws\n", psz );
  1127. dprintf("cRefs = %d\n", ldev.cldevRefs );
  1128. dprintf("ulDriverVersion = 0x%lx\n", ldev.ulDriverVersion);
  1129. dprintf("pGdiDriverInfo = 0x%lx\n", ldev.pGdiDriverInfo );
  1130. dprintf("name = ");
  1131. if (ldev.pGdiDriverInfo == NULL)
  1132. {
  1133. dprintf("Linked-in driver\n");
  1134. }
  1135. else
  1136. {
  1137. ReadMemory((ULONG_PTR) ldev.pGdiDriverInfo,
  1138. &GdiDriverInfo,
  1139. sizeof(SYSTEM_GDI_DRIVER_INFORMATION),
  1140. NULL);
  1141. ReadMemory((ULONG_PTR) GdiDriverInfo.DriverName.Buffer,
  1142. DriverName,
  1143. GdiDriverInfo.DriverName.Length,
  1144. NULL);
  1145. *(DriverName + GdiDriverInfo.DriverName.Length/2) = UNICODE_NULL;
  1146. dprintf("%ws\n", &DriverName);
  1147. }
  1148. if(invalid_type) {
  1149. dprintf("The ldev is invalid\n");
  1150. }
  1151. dprintf("\n");
  1152. if(!FirstLoop&&(pl_CD==pldevNext)) {
  1153. dprintf("ERROR: Cycle detected in linked list.\n");
  1154. break;
  1155. }
  1156. if(CheckControlC()) {
  1157. dprintf("User Break\n");
  1158. return;
  1159. }
  1160. FirstLoop=FALSE;
  1161. } while ( (!invalid_type||force||forcecount) && recursive && (pldevNext = ldev.pldevNext));
  1162. dprintf("--------------------------------------------------\n\n");
  1163. return;
  1164. dldev_help:
  1165. dprintf("Usage: dldev [-?] [-f] [-F #] ldev\n");
  1166. dprintf("-f forces the recursion even if the type is invalid\n");
  1167. dprintf("In an infinite loop, Ctrl-C will eventually break the recursion\n");
  1168. #endif // DOES NOT SUPPORT API64
  1169. EXIT_API(S_OK);
  1170. }
  1171. /******************************Public*Routine******************************\
  1172. * dgdev
  1173. *
  1174. * Syntax: dgdev [GRAPHICS_DEVICE pointer]
  1175. *
  1176. * History:
  1177. * Andre Vachon [andreva]
  1178. * Wrote it.
  1179. * Jason Hartman [jasonha]
  1180. * Converted to new debugger API.
  1181. \**************************************************************************/
  1182. char szCurrentDeviceList[] = GDISymbol(gpGraphicsDeviceList);
  1183. char szLocalDeviceList[] = GDISymbol(gpLocalGraphicsDeviceList);
  1184. char szRemoteDeviceList[] = GDISymbol(gpRemoteGraphicsDeviceList);
  1185. char szCurrentDeviceListLast[] = GDISymbol(gpGraphicsDeviceListLast);
  1186. char szLocalDeviceListLast[] = GDISymbol(gpLocalGraphicsDeviceListLast);
  1187. char szRemoteDeviceListLast[] = GDISymbol(gpRemoteGraphicsDeviceListLast);
  1188. char szGraphicsDeviceHeader[] = "--------------------------------------------------\n"
  1189. "GRAPHICS_DEVICE @ ";
  1190. DECLARE_API( dgdev )
  1191. {
  1192. INIT_API();
  1193. BEGIN_API( dgdev );
  1194. HRESULT hr;
  1195. ULONG64 GDeviceAddr = 0;
  1196. ULONG64 LastPointerAddr = 0;
  1197. ULONG64 LastGDExpected = 0;
  1198. BOOL recursive = FALSE;
  1199. BOOL bDumpModes = FALSE;
  1200. BOOL UseAddress = FALSE;
  1201. char *pszDeviceList = NULL;
  1202. char szPGDSymbolBuffer[128];
  1203. ULONG error;
  1204. OutputControl OutCtl(Client);
  1205. #define GRAPHICS_DEVICE_CBDEVMODEINFO 0
  1206. #define GRAPHICS_DEVICE_DEVMODEINFO 1
  1207. FIELD_INFO GraphicsDeviceFields[] = {
  1208. { DbgStr("cbdevmodeInfo"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1209. { DbgStr("devmodeInfo"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1210. { DbgStr("szNtDeviceName"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_WCHAR_STRING, 0, NULL},
  1211. { DbgStr("szWinDeviceName"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_WCHAR_STRING, 0, NULL},
  1212. { DbgStr("pNextGraphicsDevice"),NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1213. { DbgStr("pVgaDevice"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1214. { DbgStr("pDeviceHandle"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1215. { DbgStr("pPhysDeviceHandle"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1216. { DbgStr("hkClassDriverConfig"),NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1217. { DbgStr("stateFlags"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, FlagCallback},
  1218. { DbgStr("numRawModes"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1219. { DbgStr("devmodeMarks"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1220. { DbgStr("DiplayDriverNames"), DbgStr("Di(s)playDriverNames :"), 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_MULTI_STRING | DBG_DUMP_FIELD_WCHAR_STRING, 0, NULL},
  1221. #if 1
  1222. { DbgStr("DeviceDescription"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_WCHAR_STRING, 0, NULL},
  1223. #else
  1224. { DbgStr("DeviceDescription"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, WStringCallback},
  1225. #endif
  1226. { DbgStr("numMonitorDevice"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1227. { DbgStr("MonitorDevices"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1228. { DbgStr("pFileObject"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL},
  1229. };
  1230. FIELD_INFO GraphicsDeviceLink = { DbgStr("pNextGraphicsDevice"), DbgStr(""), 0, DBG_DUMP_FIELD_FULL_NAME, 0, NextItemCallback};
  1231. SYM_DUMP_PARAM GraphicsDeviceSym = {
  1232. sizeof(SYM_DUMP_PARAM), DbgStr(GDIType(tagGRAPHICS_DEVICE)), 0, 0/*GDeviceAddr*/,
  1233. NULL, afdGRAPHICS_DEVICE_stateFlags, NULL,
  1234. sizeof(GraphicsDeviceFields)/sizeof(GraphicsDeviceFields[0]),
  1235. GraphicsDeviceFields
  1236. };
  1237. PrepareCallbacks(FALSE);
  1238. // Interpret command line
  1239. PARSE_ARGUMENTS(dgdev_help);
  1240. if (parse_iFindSwitch(tokens, ntok, 'm')!=-1)
  1241. {
  1242. GraphicsDeviceFields[GRAPHICS_DEVICE_CBDEVMODEINFO].fieldCallBack = SizeDEVMODEListCallback;
  1243. GraphicsDeviceFields[GRAPHICS_DEVICE_DEVMODEINFO].fieldCallBack = DEVMODEListCallback;
  1244. }
  1245. if (parse_iFindSwitch(tokens, ntok, 'R')!=-1) { recursive = TRUE; }
  1246. // Determine where to start looking: global or commnad line arg?
  1247. // -c means current/last device list
  1248. if (parse_iFindSwitch(tokens, ntok, 'c')!=-1)
  1249. {
  1250. pszDeviceList = szCurrentDeviceList;
  1251. LastPointerAddr = GetExpression(szCurrentDeviceListLast);
  1252. }
  1253. // -l means local device list
  1254. if (parse_iFindSwitch(tokens, ntok, 'l')!=-1)
  1255. {
  1256. if (pszDeviceList != NULL) goto dgdev_help;
  1257. pszDeviceList = szLocalDeviceList;
  1258. LastPointerAddr = GetExpression(szLocalDeviceListLast);
  1259. }
  1260. // -r means remote device list
  1261. if (parse_iFindSwitch(tokens, ntok, 'r')!=-1)
  1262. {
  1263. if (pszDeviceList != NULL) goto dgdev_help;
  1264. pszDeviceList = szRemoteDeviceList;
  1265. LastPointerAddr = GetExpression(szRemoteDeviceListLast);
  1266. }
  1267. // -p may not be used with -c, -l, or -r
  1268. if (parse_iFindSwitch(tokens, ntok, 'p')!=-1)
  1269. {
  1270. if (pszDeviceList != NULL) goto dgdev_help;
  1271. }
  1272. tok_pos = parse_FindNonSwitch(tokens, ntok);
  1273. // Evaluate expression
  1274. if (tok_pos != -1)
  1275. {
  1276. ULONG64 Displacement;
  1277. if (pszDeviceList != NULL)
  1278. {
  1279. dprintf(" No expression maybe used with -c, -l, or -r.\n");
  1280. goto dgdev_help;
  1281. }
  1282. GDeviceAddr = GetExpression(tokens[tok_pos]);
  1283. if (GDeviceAddr == 0)
  1284. {
  1285. dprintf(" Expression \"%s\" evaluated to NULL.\n", tokens[tok_pos]);
  1286. EXIT_API(S_OK);
  1287. }
  1288. // Look up symbol for address if we can
  1289. Displacement = -1;
  1290. szPGDSymbolBuffer[0] = 0;
  1291. GetSymbol(GDeviceAddr, szPGDSymbolBuffer, &Displacement);
  1292. if (Displacement == 0 && szPGDSymbolBuffer[0] != 0)
  1293. {
  1294. pszDeviceList = szPGDSymbolBuffer;
  1295. }
  1296. else
  1297. {
  1298. UseAddress = TRUE;
  1299. }
  1300. }
  1301. // -p means the expression is a list pointer
  1302. if (parse_iFindSwitch(tokens, ntok, 'p')!=-1)
  1303. {
  1304. if (tok_pos == -1)
  1305. {
  1306. dprintf(" Missing expression with -p.\n");
  1307. goto dgdev_help;
  1308. }
  1309. // Use list show method
  1310. GDeviceAddr = 0;
  1311. if (pszDeviceList == NULL)
  1312. {
  1313. pszDeviceList = tokens[tok_pos];
  1314. }
  1315. }
  1316. // User either specified a list or a pointer to a list
  1317. if (GDeviceAddr == 0)
  1318. {
  1319. // TRUE if no -R, FALSE otherwise
  1320. recursive = !recursive;
  1321. if (pszDeviceList == NULL)
  1322. {
  1323. pszDeviceList = szCurrentDeviceList;
  1324. }
  1325. dprintf("Using Graphics Device List from %s\n", pszDeviceList);
  1326. DEBUG_VALUE pgdevList;
  1327. hr = g_pExtControl->Evaluate(pszDeviceList,
  1328. DEBUG_VALUE_INT64,
  1329. &pgdevList,
  1330. NULL);
  1331. if (hr == S_OK && pgdevList.I64 != 0)
  1332. {
  1333. if (SessionId == CURRENT_SESSION)
  1334. {
  1335. hr = g_pExtData->ReadPointersVirtual(1, pgdevList.I64, &GDeviceAddr);
  1336. if (hr != S_OK)
  1337. {
  1338. OutCtl.OutErr(" ReadPointer for %s failed at 0x%p.\n",
  1339. pszDeviceList, pgdevList.I64);
  1340. }
  1341. }
  1342. else
  1343. {
  1344. ULONG64 pgdevListPhys;
  1345. UseAddress = TRUE;
  1346. if ((hr = GetPhysicalAddress(Client,
  1347. SessionId,
  1348. pgdevList.I64,
  1349. &pgdevListPhys)) == S_OK)
  1350. {
  1351. hr = ReadPointerPhysical(Client, pgdevListPhys, &GDeviceAddr);
  1352. if (hr == S_OK)
  1353. {
  1354. OutCtl.Output("First GRAPHICS_DEVICE in session %lu located at 0x%p.\n",
  1355. SessionId, GDeviceAddr);
  1356. }
  1357. else
  1358. {
  1359. OutCtl.OutErr(" ReadPointerPhysical for %s failed at # 0x%p.\n",
  1360. pszDeviceList, pgdevListPhys);
  1361. }
  1362. }
  1363. else
  1364. {
  1365. OutCtl.OutErr(" Failed Virtual to Physical conversion for %s (0x%p) in session %ld.\n",
  1366. pszDeviceList, pgdevList.I64, SessionId);
  1367. }
  1368. }
  1369. if (hr != S_OK) EXIT_API(S_OK);
  1370. // If a list last pointer exists, look it up.
  1371. if (LastPointerAddr != 0)
  1372. {
  1373. if (SessionId == CURRENT_SESSION)
  1374. {
  1375. hr = g_pExtData->ReadPointersVirtual(1, LastPointerAddr, &LastGDExpected);
  1376. if (hr != S_OK)
  1377. {
  1378. OutCtl.OutErr(" ReadPointer 0x%p failed.\n", LastPointerAddr);
  1379. }
  1380. }
  1381. else
  1382. {
  1383. ULONG64 pgdevLastPhys;
  1384. if ((hr = GetPhysicalAddress(Client,
  1385. SessionId,
  1386. LastPointerAddr,
  1387. &pgdevLastPhys)) == S_OK)
  1388. {
  1389. hr = ReadPointerPhysical(Client, pgdevLastPhys, &LastGDExpected);
  1390. if (hr == S_OK)
  1391. {
  1392. OutCtl.Output("Last GRAPHICS_DEVICE in session %lu located at 0x%p.\n",
  1393. SessionId, LastGDExpected);
  1394. }
  1395. else
  1396. {
  1397. OutCtl.OutErr(" ReadPointerPhysical for %s failed at # 0x%p.\n",
  1398. pszDeviceList, pgdevLastPhys);
  1399. }
  1400. }
  1401. else
  1402. {
  1403. OutCtl.OutErr(" Failed Virtual to Physical conversion for %s (0x%p) in session %ld.\n",
  1404. pszDeviceList, LastPointerAddr, SessionId);
  1405. }
  1406. }
  1407. }
  1408. if (GDeviceAddr == 0)
  1409. {
  1410. OutCtl.Output("Graphics Device address is NULL.\n");
  1411. EXIT_API(S_OK);
  1412. }
  1413. }
  1414. else
  1415. {
  1416. // We should only be here if a -clr look up failed.
  1417. if (hr != S_OK)
  1418. {
  1419. OutCtl.OutErr(" Evaluate(%s) returned %s\n",
  1420. pszDeviceList, pszHRESULT(hr));
  1421. }
  1422. else
  1423. {
  1424. OutCtl.OutErr(" Evaluate(%s) = NULL\n", pszHRESULT(hr));
  1425. }
  1426. OutCtl.OutErr(" Please double check symbols for " GDIModule() ".\n");
  1427. EXIT_API(S_OK);
  1428. }
  1429. }
  1430. if (recursive)
  1431. {
  1432. // Enable linked list resursion
  1433. GraphicsDeviceSym.Options |= DBG_DUMP_LIST;
  1434. GraphicsDeviceSym.listLink = &GraphicsDeviceLink;
  1435. NextItemCallbackInit(szGraphicsDeviceHeader, LastGDExpected);
  1436. }
  1437. else
  1438. {
  1439. // Printer header since this is a single structure dump
  1440. dprintf(szGraphicsDeviceHeader);
  1441. if (UseAddress)
  1442. {
  1443. dprintf("%#p\n", GDeviceAddr);
  1444. }
  1445. }
  1446. if (UseAddress)
  1447. {
  1448. // Dump from a type w/ an address
  1449. GraphicsDeviceSym.addr = GDeviceAddr;
  1450. }
  1451. else
  1452. {
  1453. // Dump from a symbol
  1454. GraphicsDeviceSym.sName = DbgStr(pszDeviceList);
  1455. if (GetTypeSize(pszDeviceList) == 8)
  1456. {
  1457. GraphicsDeviceLink.fieldCallBack = PointerToNextItemCallback;
  1458. }
  1459. }
  1460. // Do the dumping
  1461. error = Ioctl( IG_DUMP_SYMBOL_INFO, &GraphicsDeviceSym, GraphicsDeviceSym.size );
  1462. if (error)
  1463. {
  1464. dprintf("Unable to get contents of GRAPHICS_DEVICE\n");
  1465. dprintf(" (Ioctl returned %s)\n", pszWinDbgError(error));
  1466. }
  1467. dprintf("--------------------------------------------------\n\n");
  1468. // Did we find end of list as expected?
  1469. if (recursive && !LastCallbackItemFound())
  1470. {
  1471. dprintf(" * Error: Last expected GRAPHICS_DEVICE @ %#p was not found.\n", LastGDExpected);
  1472. }
  1473. EXIT_API(S_OK);
  1474. dgdev_help:
  1475. dprintf("Usage: dgdev [-?] [-mR] [-clr | [-p] expr ]\n"
  1476. " ? - Show this help\n"
  1477. " m - Dump modes\n"
  1478. " R - Recurse for address; don't for list\n"
  1479. " c - Recurse list from current list [default]\n"
  1480. " l - Recurse list from local list\n"
  1481. " r - Recurse list from remote list\n"
  1482. " p - expr is address or symbol for pointer to list\n"
  1483. " expr - Address or symbol for GRAPHICS_DEVICE to show\n"
  1484. );
  1485. EXIT_API(S_OK);
  1486. }
  1487. /******************************Public*Routine******************************\
  1488. * BRUSH
  1489. *
  1490. \**************************************************************************/
  1491. DECLARE_API( brush )
  1492. {
  1493. BEGIN_API( brush );
  1494. HRESULT hr = S_OK;
  1495. ULONG64 BrushAddr;
  1496. DEBUG_VALUE Arg;
  1497. DEBUG_VALUE Offset;
  1498. OutputControl OutCtl(Client);
  1499. while (isspace(*args)) args++;
  1500. if (*args == '-' ||
  1501. (hr = Evaluate(Client, args, DEBUG_VALUE_INT64, 0, &Arg, NULL)) != S_OK)
  1502. {
  1503. OutCtl.Output("Usage: brush [-?] <HBRUSH | BRUSH Addr>\n");
  1504. }
  1505. else
  1506. {
  1507. hr = GetObjectAddress(Client,Arg.I64,&BrushAddr,BRUSH_TYPE,TRUE,TRUE);
  1508. if (hr != S_OK || BrushAddr == 0)
  1509. {
  1510. DEBUG_VALUE ObjHandle;
  1511. TypeOutputParser TypeParser(Client);
  1512. OutputState OutState(Client);
  1513. ULONG64 BrushAddrFromHmgr;
  1514. BrushAddr = Arg.I64;
  1515. // Try to read hHmgr from BRUSH type, but if that
  1516. // fails use the BASEOBJECT type, which is public.
  1517. if ((hr = OutState.Setup(0, &TypeParser)) != S_OK ||
  1518. (hr = OutState.OutputTypeVirtual(BrushAddr, GDIType(BRUSH), 0)) != S_OK ||
  1519. (hr = TypeParser.Get(&ObjHandle, "hHmgr", DEBUG_VALUE_INT64)) != S_OK)
  1520. {
  1521. OutCtl.OutErr("Unable to get contents of BRUSH's handle\n");
  1522. OutCtl.OutErr(" (Type Read returned %s)\n", pszHRESULT(hr));
  1523. OutCtl.OutErr(" 0x%p is neither an HBRUSH nor valid BRUSH address\n", Arg.I64);
  1524. }
  1525. else
  1526. {
  1527. if (GetObjectAddress(Client,ObjHandle.I64,&BrushAddrFromHmgr,
  1528. BRUSH_TYPE,TRUE,FALSE) == S_OK &&
  1529. BrushAddrFromHmgr != BrushAddr)
  1530. {
  1531. OutCtl.OutWarn("\tNote: BRUSH may not be valid.\n"
  1532. "\t It does not have a valid handle manager entry.\n");
  1533. }
  1534. }
  1535. }
  1536. if (hr == S_OK)
  1537. {
  1538. hr = DumpType(Client, "BRUSH", BrushAddr);
  1539. if (hr != S_OK)
  1540. {
  1541. OutCtl.OutErr("Type Dump for BRUSH returned %s.\n", pszHRESULT(hr));
  1542. }
  1543. }
  1544. }
  1545. return hr;
  1546. }
  1547. /******************************Public*Routine******************************\
  1548. * DECLARE_API( dpbrush ) - OBSOLETE
  1549. *
  1550. \**************************************************************************/
  1551. DECLARE_API( dpbrush )
  1552. {
  1553. INIT_API();
  1554. ExtOut("Obsolete: Use '!gdikdx.brush <Handle | Address>'.\n");
  1555. EXIT_API(S_OK);
  1556. }
  1557. /******************************Public*Routine******************************\
  1558. * DECLARE_API( ebrush )
  1559. *
  1560. * Dumps an EBRUSHOBJ
  1561. *
  1562. \**************************************************************************/
  1563. DECLARE_API( ebrush )
  1564. {
  1565. return ExtDumpType(Client, "ebrush", "EBRUSHOBJ", args);
  1566. }
  1567. /******************************Public*Routine******************************\
  1568. * DECLARE_API( semorder )
  1569. *
  1570. \**************************************************************************/
  1571. #define NUM_ALOC_FIELDS 5
  1572. ULONG gSemAcquireLocArrayLength = 0;
  1573. ULONG SemAcquireLocCountCallback(
  1574. PFIELD_INFO pField,
  1575. PULONG pSemAcquireLocArrayLength
  1576. )
  1577. {
  1578. ULONG Count = (ULONG)pField->address;
  1579. *pSemAcquireLocArrayLength = (Count < gSemAcquireLocArrayLength) ? Count : 0;
  1580. return ULONGCallback(pField, pSemAcquireLocArrayLength);
  1581. }
  1582. DECLARE_API( semorder )
  1583. {
  1584. ULONG64 ThreadAddress = CURRENT_THREAD_ADDRESS;
  1585. ULONG64 Tcb_Header_Type;
  1586. DEBUG_VALUE W32ThreadAddress;
  1587. ULONG64 SemTableAddress;
  1588. BOOL bShowALocs = TRUE;
  1589. ULONG error;
  1590. static char szHeader[] = " hSem x hold count\tOrder\tParent";
  1591. static char szHeaderALoc[] = " hSem x hold count\tOrder\tParent \n\t Acquisitions: name and location";
  1592. ULONG dwProcessor=0;
  1593. HANDLE hCurrentThread=NULL;
  1594. INIT_API();
  1595. PARSE_ARGUMENTS(semorder_help);
  1596. if (parse_iFindSwitch(tokens, ntok, 'n')!=-1)
  1597. {
  1598. bShowALocs = FALSE;
  1599. }
  1600. if (!GetExpressionEx(args, &ThreadAddress, &args))
  1601. {
  1602. while (*args && isspace(*args)) args++;
  1603. if (*args)
  1604. {
  1605. if (args[0] == '-' && args[1]=='n' && (args[2] == 0 || isspace(args[2])))
  1606. {
  1607. args += 2;
  1608. while (*args && isspace(*args)) args++;
  1609. if (*args && !GetExpressionEx(args, &ThreadAddress, &args))
  1610. {
  1611. dprintf("Error: invalid arguments: %s\n", args);
  1612. goto semorder_help;
  1613. }
  1614. }
  1615. else
  1616. {
  1617. dprintf("Error: invalid arguments: %s\n", args);
  1618. goto semorder_help;
  1619. }
  1620. }
  1621. }
  1622. if (S_OK != GetThreadField(Client, &ThreadAddress, "Tcb.Win32Thread",
  1623. &W32ThreadAddress, DEBUG_VALUE_INT64))
  1624. {
  1625. EXIT_API(S_OK);
  1626. }
  1627. ExtVerb(" W32Thread = 0x%p\n", W32ThreadAddress.I64);
  1628. if (error = GetFieldValue(W32ThreadAddress.I64, GDIType(W32THREAD), "pSemTable", SemTableAddress))
  1629. {
  1630. dprintf("Unable to get pSemTable from W32THREAD 0x%p\n", W32ThreadAddress.I64 );
  1631. dprintf(" (GetFieldValue returned %s)\n", pszWinDbgError(error));
  1632. EXIT_API(S_OK);
  1633. }
  1634. ExtVerb(" pSemTable = %p\n", SemTableAddress);
  1635. if (SemTableAddress == 0)
  1636. {
  1637. dprintf(" No semaphores have been tracked for validation.\n");
  1638. }
  1639. else
  1640. {
  1641. FIELD_INFO SemEntryList = { NULL, DbgStr(szHeaderALoc),
  1642. 0 /*pSemTable->numEntries*/, 0, 0, ArrayCallback };
  1643. FIELD_INFO SemEntryFields[] = {
  1644. { DbgStr("Acquired"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME | DBG_DUMP_FIELD_ARRAY, 0, NULL},
  1645. { DbgStr("Acquired.name"), DbgStr("\n\t"), 0, DBG_DUMP_FIELD_FULL_NAME, 0, AStringCallback},
  1646. { DbgStr("Acquired.func"), DbgStr(" in"), 0, DBG_DUMP_FIELD_FULL_NAME, 0, AStringCallback},
  1647. { DbgStr("Acquired.file"), DbgStr(" @"), 0, DBG_DUMP_FIELD_FULL_NAME, 0, AStringCallback},
  1648. { DbgStr("Acquired.line"), DbgStr(":"), 0, DBG_DUMP_FIELD_FULL_NAME, 0, LONGCallback},
  1649. { DbgStr("hsem"), DbgStr(" "), 0, DBG_DUMP_FIELD_FULL_NAME, 0, DWORDCallback},
  1650. { DbgStr("count"), DbgStr(" x "), 0, DBG_DUMP_FIELD_FULL_NAME, 0, SemAcquireLocCountCallback},
  1651. { DbgStr("order"), DbgStr("\t"), 0, DBG_DUMP_FIELD_FULL_NAME, 0, ULONGCallback},
  1652. { DbgStr("parent"), DbgStr("\t"), 0, DBG_DUMP_FIELD_FULL_NAME, 0, DWORDCallback},
  1653. };
  1654. SYM_DUMP_PARAM SemEntrySym = {
  1655. sizeof (SYM_DUMP_PARAM), DbgStr(GDIType(SemEntry)),
  1656. DBG_DUMP_NO_PRINT | DBG_DUMP_ARRAY,
  1657. 0 /*pSemTable->entries*/,
  1658. &SemEntryList, &SemEntryFields[0].size, NULL,
  1659. sizeof(SemEntryFields)/sizeof(SemEntryFields[0]), SemEntryFields
  1660. };
  1661. PrepareCallbacks(FALSE, 0);
  1662. if (error = (ULONG)InitTypeRead(SemTableAddress, win32k!SemTable))
  1663. {
  1664. dprintf("Error: InitTypeRead for SemTable returned %s\n", pszWinDbgError(error));
  1665. EXIT_API(S_OK);
  1666. }
  1667. SemEntryList.size = (ULONG)ReadField(numEntries);
  1668. if (SemEntryList.size == 0)
  1669. {
  1670. dprintf(" No entries are currently held.\n");
  1671. }
  1672. else
  1673. {
  1674. SemEntrySym.addr = ReadField(entries);
  1675. gSemAcquireLocArrayLength = 0;
  1676. if (bShowALocs)
  1677. {
  1678. FIELD_INFO SemEntryLocEntrySizeField = { DbgStr("Acquired[0]"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL};
  1679. FIELD_INFO SemEntryLocArraySizeField = { DbgStr("Acquired"), NULL, 0, DBG_DUMP_FIELD_FULL_NAME, 0, NULL};
  1680. SYM_DUMP_PARAM SemEntryLocSizeSym = {
  1681. sizeof (SYM_DUMP_PARAM), DbgStr(GDIType(SemEntry)),
  1682. DBG_DUMP_NO_PRINT, 0,
  1683. NULL, NULL, NULL,
  1684. 1, &SemEntryLocEntrySizeField
  1685. };
  1686. // Get size of one entry
  1687. error = Ioctl(IG_DUMP_SYMBOL_INFO, &SemEntryLocSizeSym, SemEntryLocSizeSym.size);
  1688. if (!error && SemEntryLocEntrySizeField.size != 0)
  1689. {
  1690. SemEntryLocSizeSym.Fields = &SemEntryLocArraySizeField;
  1691. // Get size of entire array
  1692. error = Ioctl(IG_DUMP_SYMBOL_INFO, &SemEntryLocSizeSym, SemEntryLocSizeSym.size);
  1693. if (!error)
  1694. {
  1695. gSemAcquireLocArrayLength = SemEntryLocArraySizeField.size / SemEntryLocEntrySizeField.size;
  1696. }
  1697. }
  1698. }
  1699. if (gSemAcquireLocArrayLength == 0)
  1700. {
  1701. // Setup dump to ignore acquisition location info
  1702. SemEntryList.printName = DbgStr(szHeader);
  1703. SemEntrySym.nFields -= NUM_ALOC_FIELDS;
  1704. SemEntrySym.Fields += NUM_ALOC_FIELDS;
  1705. SemEntryFields[NUM_ALOC_FIELDS+1].fieldCallBack = ULONGCallback;
  1706. }
  1707. error = Ioctl(IG_DUMP_SYMBOL_INFO, &SemEntrySym, SemEntrySym.size);
  1708. dprintf("\n");
  1709. if (error)
  1710. {
  1711. dprintf("Error: Ioctl returned %s\n", pszWinDbgError(error));
  1712. }
  1713. }
  1714. }
  1715. EXIT_API(S_OK);
  1716. semorder_help:
  1717. dprintf("Usage: semorder [-n] [thread]\n"
  1718. "\n"
  1719. " -n Don't display acquisition location details\n");
  1720. EXIT_API(S_OK);
  1721. }