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.

16840 lines
527 KiB

  1. /****************************** Module Header ******************************\
  2. * Module Name: userexts.c
  3. *
  4. * Copyright (c) 1985 - 1999, Microsoft Corporation
  5. *
  6. * This module contains user related debugging extensions.
  7. *
  8. * History:
  9. * 17-May-1991 DarrinM Created.
  10. * 22-Jan-1992 IanJa ANSI/Unicode neutral (all debug output is ANSI)
  11. * 23-Mar-1993 JerrySh Moved from winsrv.dll to userexts.dll
  12. * 21-Oct-1993 JerrySh Modified to work with WinDbg
  13. * 18-Oct-1994 ChrisWil Added Object Tracking extent.
  14. * 26-May-1995 Sanfords Made it more general for the good of humanity.
  15. * 09-Jun-1995 SanfordS Made to fit stdexts motif and to dual compile for
  16. * either USER or KERNEL mode.
  17. \***************************************************************************/
  18. #include "userkdx.h"
  19. #include "vkoem.h"
  20. #ifdef KERNEL
  21. CONST PSTR pszExtName = "USERKDX";
  22. #else
  23. CONST PSTR pszExtName = "USEREXTS";
  24. #endif
  25. #include <stdext64.h>
  26. #include <stdext64.c>
  27. /***************************************************************************\
  28. * Constants
  29. \***************************************************************************/
  30. #define CDWORDS 16
  31. #define BF_MAX_WIDTH 80
  32. #define BF_COLUMN_WIDTH 19
  33. typedef ULONG64 PTR, *PPTR;
  34. #define NULL_PTR ((PTR)(0))
  35. // If you want to debug the extension, enable this.
  36. #if 0
  37. #undef DEBUGPRINT
  38. #define DEBUGPRINT Print
  39. #endif
  40. /***************************************************************************\
  41. * Global variables
  42. \***************************************************************************/
  43. BOOL bShowFlagNames = TRUE;
  44. char gach1[80];
  45. char gach2[80];
  46. char gach3[80];
  47. int giBFColumn; // bit field: current column
  48. char gaBFBuff[BF_MAX_WIDTH + 1]; // bit field: buffer
  49. // used in dsi() and dinp()
  50. typedef struct {
  51. int iMetric;
  52. LPSTR pstrMetric;
  53. } SYSMET_ENTRY;
  54. #define SMENTRY(sm) {SM_##sm, #sm}
  55. /***************************************************************************\
  56. * Macros
  57. \***************************************************************************/
  58. #define TestWWF(pww, flag) (*(((PBYTE)(pww)) + (int)HIBYTE(flag)) & LOBYTE(flag))
  59. VOID ShowProgress(
  60. VOID);
  61. #define CHKBREAK() do { if (IsCtrlCHit()) return TRUE; } while (FALSE)
  62. #ifdef KERNEL // ########### KERNEL MODE ONLY MACROS ###############
  63. #define VAR(v) "win32k!" #v
  64. #define SYM(s) "win32k!" #s
  65. #define FIXKP(p) p
  66. #define RebaseSharedPtr(p) (p)
  67. #define FOREACHWINDOWSTATION(pwinsta) \
  68. pwinsta = GetGlobalPointer(VAR(grpWinStaList)); \
  69. SAFEWHILE (pwinsta != 0) {
  70. #define NEXTEACHWINDOWSTATION(pwinsta) \
  71. GetFieldValue(pwinsta, SYM(tagWINDOWSTATION), "rpwinstaNext", pwinsta); \
  72. }
  73. #define FOREACHDESKTOP(pdesk) \
  74. { \
  75. ULONG64 pwinsta; \
  76. \
  77. FOREACHWINDOWSTATION(pwinsta) \
  78. GetFieldValue(pwinsta, SYM(WINDOWSTATION), "rpdeskList", pdesk); \
  79. SAFEWHILE (pdesk != 0) {
  80. #define NEXTEACHDESKTOP(pdesk) \
  81. GetFieldValue(pdesk, SYM(DESKTOP), "rpdeskNext", pdesk); \
  82. } \
  83. NEXTEACHWINDOWSTATION(pwinsta) \
  84. }
  85. VOID PrintStackTrace(
  86. ULONG64 pStackTrace,
  87. int tracesCount);
  88. typedef ULONG (WDBGAPI *PPI_CALLBACK)(ULONG64 ppi, PVOID Data);
  89. typedef struct _PPI_CONTEXT {
  90. PPI_CALLBACK CallbackRoutine;
  91. PVOID Data;
  92. } PPI_CONTEXT;
  93. ULONG
  94. ForEachPpiCallback(
  95. PFIELD_INFO NextProcess,
  96. PVOID Context)
  97. {
  98. ULONG64 pEProcess = NextProcess->address;
  99. ULONG64 ppi = 0;
  100. PPI_CONTEXT *pPpiContext = (PPI_CONTEXT *)Context;
  101. /*
  102. * Dump Win32 Processes only
  103. */
  104. GetFieldValue(pEProcess, "nt!EPROCESS", "Win32Process", ppi);
  105. if (ppi) {
  106. return pPpiContext->CallbackRoutine(ppi, pPpiContext->Data);
  107. }
  108. return FALSE;
  109. }
  110. BOOL
  111. ForEachPpi(
  112. PPI_CALLBACK CallbackRoutine,
  113. PVOID Data)
  114. {
  115. ULONG64 ProcessHead;
  116. ULONG64 NextProcess;
  117. PPI_CONTEXT PpiContext;
  118. ProcessHead = EvalExp("PsActiveProcessHead");
  119. if (!ProcessHead) {
  120. Print("Unable to get value of PsActiveProcessHead\n");
  121. return FALSE;
  122. }
  123. if (GetFieldValue(ProcessHead, "nt!_LIST_ENTRY", "Flink", NextProcess)) {
  124. Print("Unable to get value of PsActiveProcessHead\n");
  125. return FALSE;
  126. }
  127. if (NextProcess == 0) {
  128. Print("PsActiveProcessHead->Flink is NULL!\n");
  129. return FALSE;
  130. }
  131. PpiContext.CallbackRoutine = CallbackRoutine;
  132. PpiContext.Data = Data;
  133. ListType("nt!_EPROCESS",
  134. NextProcess,
  135. 1,
  136. "ActiveProcessLinks.Flink",
  137. &PpiContext,
  138. ForEachPpiCallback);
  139. return TRUE;
  140. }
  141. typedef ULONG (WDBGAPI *PTI_CALLBACK)(ULONG64 pti, PVOID Data);
  142. typedef struct _PTI_CONTEXT {
  143. PTI_CALLBACK CallbackRoutine;
  144. PVOID Data;
  145. } PTI_CONTEXT;
  146. ULONG
  147. ForEachPtiCallback(
  148. ULONG64 ppi,
  149. PVOID Data)
  150. {
  151. ULONG64 pti = 0;
  152. PTI_CONTEXT *pPtiContext = (PTI_CONTEXT *)Data;
  153. if (GetFieldValue(ppi, SYM(PROCESSINFO), "ptiList", pti)) {
  154. DEBUGPRINT("ForEachPti: Can't get ptiList from ppi 0x%p.\n", ppi);
  155. }
  156. SAFEWHILE (pti != 0) {
  157. pPtiContext->CallbackRoutine(pti, pPtiContext->Data);
  158. if (GetFieldValue(pti, SYM(THREADINFO), "ptiSibling", pti)) {
  159. DEBUGPRINT("ForEachPti: Can't get ptiSibling from pti 0x%p.\n", pti);
  160. }
  161. }
  162. return FALSE;
  163. }
  164. ULONG
  165. ForEachPti(
  166. PTI_CALLBACK CallbackRoutine,
  167. PVOID Data)
  168. {
  169. PTI_CONTEXT PtiContext;
  170. PtiContext.CallbackRoutine = CallbackRoutine;
  171. PtiContext.Data = Data;
  172. return ForEachPpi(ForEachPtiCallback, &PtiContext);
  173. }
  174. #else //!KERNEL ############## USER MODE ONLY MACROS ################
  175. #define VAR(v) "user32!" #v
  176. #define SYM(s) "user32!" #s
  177. #define FIXKP(p) FixKernelPointer(p)
  178. #endif //!KERNEL ############## EITHER MODE MACROS ###################
  179. #define GETSHAREDINFO(psi) moveExp(&psi, VAR(gSharedInfo))
  180. #define FOREACHHANDLEENTRY(phe, i) \
  181. { \
  182. ULONG64 pshi, psi, cHandleEntries; \
  183. ULONG dwHESize = GetTypeSize(SYM(HANDLEENTRY)); \
  184. \
  185. GETSHAREDINFO(pshi); \
  186. if (GetFieldValue(pshi, SYM(SHAREDINFO), "psi", psi)) { \
  187. Print("FOREACHHANDLEENTRY:Could not get SERVERINFO from SHAREDINFO %p\n", pshi); \
  188. } \
  189. GetFieldValue(pshi, SYM(SHAREDINFO), "aheList", phe); \
  190. GetFieldValue(psi, SYM(SERVERINFO), "cHandleEntries", cHandleEntries); \
  191. for (i = 0; cHandleEntries; cHandleEntries--, i++, phe += dwHESize) { \
  192. if (IsCtrlCHit()) { \
  193. break; \
  194. }
  195. #define NEXTEACHHANDLEENTRY() \
  196. } \
  197. }
  198. /*
  199. * Use these macros to print field values, globals, local values, etc.
  200. * This assures consistent formating plus make the extensions easier to read and to maintain.
  201. */
  202. #define STRWD1 "67"
  203. #define STRWD2 "28"
  204. #define DWSTR1 "%08lx %." STRWD1 "s"
  205. #define DWSTR2 "%08lx %-" STRWD2 "." STRWD2 "s"
  206. #define PTRSTR1 "%08p %-" STRWD1 "s"
  207. #define PTRSTR2 "%08p %-" STRWD2 "." STRWD2 "s"
  208. #define DWPSTR1 "%08p %." STRWD1 "s"
  209. #define DWPSTR2 "%08p %-" STRWD2 "." STRWD2 "s"
  210. #define PRTFDW1(f1) Print(DWSTR1 "\n", ReadField(f1), #f1)
  211. #define PRTVDW1(s1, v1) Print(DWSTR1 "\n", v1, #s1)
  212. #define PRTFDW2(f1, f2) Print(DWSTR2 "\t" DWSTR2 "\n", (DWORD)ReadField(f1), #f1, (DWORD)ReadField(f2), #f2)
  213. #define PRTVDW2(s1, v1, s2, v2) Print(DWSTR2 "\t" DWPSTR2 "\n", v1, #s1, v2, #s2)
  214. #define PRTFRC(p, rc) Print("%-" STRWD2 "s{%#lx, %#lx, %#lx, %#lx}\n", #rc, ##p##rc.left, ##p##rc.top, ##p##rc.right, ##p##rc.bottom)
  215. #define PRTFPT(pt) Print("%-" STRWD2 "s{0x%x, 0x%x}\n", #pt, ReadField(pt.x), ReadField(pt.y))
  216. #define PRTVPT(s, pt) Print("%-" STRWD2 "s{0x%x, 0x%x}\n", #s, pt.x, pt.y)
  217. #define PRTFDWP1(f1) Print(DWPSTR1 "\n", ReadField(f1), #f1)
  218. #define PRTFDWP2(f1, f2) Print(DWPSTR2 "\t" DWPSTR2 "\n", ReadField(f1), #f1, ReadField(f2), #f2)
  219. #define PRTFDWPDW(f1, f2) Print(DWPSTR2 "\t" DWSTR2 "\n", ReadField(f1), #f1, ReadField(f2), #f2)
  220. #define PRTFDWDWP(p, f1, f2) Print(DWSTR2 "\t" DWPSTR2 "\n", (DWORD)##p##f1, #f1, (DWORD_PTR)##p##f2, #f2)
  221. /*
  222. * Bit Fields
  223. */
  224. #define BEGIN_PRTFFLG(p, type) InitTypeRead(p, type)
  225. #define PRTFFLG(f) PrintBitField(#f, (BOOL)!!(ReadField(f)))
  226. #define END_PRTFFLG() PrintEndBitField()
  227. #define PRTGDW1(g1) \
  228. { DWORD _dw1; \
  229. moveExpValue(&_dw1, VAR(g1)); \
  230. Print(DWSTR1 "\n", _dw1, #g1); }
  231. #define PRTGDW2(g1, g2) \
  232. { DWORD _dw1, _dw2; \
  233. moveExpValue(&_dw1, VAR(g1)); \
  234. moveExpValue(&_dw2, VAR(g2)); \
  235. Print(DWSTR2 "\t" DWSTR2 "\n", _dw1, #g1, _dw2, #g2); }
  236. #define PRTGPTR1(g1) \
  237. Print(PTRSTR1 "\n", GetGlobalPointer(VAR(g1)), #g1)
  238. #define PRTGPTR2(g1, g2) \
  239. Print(PTRSTR2 "\t" PTRSTR2 "\n", GetGlobalPointer(VAR(g1)), #g1, GetGlobalPointer(VAR(g2)), #g2)
  240. /* This macro requires char ach[...]; to be previously defined */
  241. #define PRTWND(s, pwnd) \
  242. { DebugGetWindowTextA(pwnd, ach, ARRAY_SIZE(ach)); \
  243. Print("%-" STRWD2 "s" DWPSTR2 "\n", #s, pwnd, ach); }
  244. #define PRTGWND(gpwnd) \
  245. { ULONG64 _pwnd; \
  246. moveExpValuePtr(&_pwnd, VAR(gpwnd)); \
  247. DebugGetWindowTextA(_pwnd, ach, ARRAY_SIZE(ach)); \
  248. Print("%-" STRWD2 "s" DWPSTR2 "\n", #gpwnd, _pwnd, ach); }
  249. #ifdef LATER // macros above need fix... and callers as well that mix up DWORD and PVOID.
  250. #define PRTGDW1(g1) \
  251. {\
  252. DWORD _dw1 = GetGlobalDWord(VAR(g1)); \
  253. Print(DWSTR1 "\n", _dw1, #g1); \
  254. }
  255. #define PRTGDW2(g1, g2) \
  256. {\
  257. DWORD _dw1 = GetGlobalDWord(VAR(g1)); \
  258. DWORD _dw2 = GetGlobalDWord(VAR(g2)); \
  259. Print(DWSTR2 "\t" DWSTR2 "\n", _dw1, #g1, _dw2, #g2); \
  260. }
  261. #define PRTGWND(gpwnd) \
  262. { ULONG64 _pwnd = GetGlobalPointer(VAR(gpwnd)); \
  263. DebugGetWindowTextA(_pwnd, ach); \
  264. Print("%-" STRWD2 "s" DWPSTR2 "\n", #gpwnd, _pwnd, ach); }
  265. #endif // LATER
  266. /****************************************************************************\
  267. * PROTOTYPES
  268. * Note that all Ixxx proc prototypes are generated by stdexts.h
  269. \****************************************************************************/
  270. #ifdef KERNEL
  271. BOOL GetAndDumpHE(ULONG64 dwT, PULONG64 phe, BOOL fPointerTest);
  272. LPSTR ProcessName(ULONG64 ppi);
  273. #else // !KERNEL
  274. ULONG64 FixKernelPointer(ULONG64 pKernel);
  275. BOOL DumpConvInfo(PCONV_INFO pcoi);
  276. #endif // !KERNEL
  277. LPSTR GetFlags(WORD wType, DWORD dwFlags, LPSTR pszBuf, BOOL fPrintZero);
  278. BOOL HtoHE(ULONG64 h, ULONG64 *pphe);
  279. ULONG64 GetPfromH(ULONG64 h, ULONG64 *pphe);
  280. BOOL getHEfromP(ULONG64 *pphe, ULONG64 p);
  281. ULONG64 HorPtoP(ULONG64 p, int type);
  282. BOOL DebugGetWindowTextA(ULONG64 pwnd, char *achDest, DWORD dwLength);
  283. BOOL DebugGetClassNameA(ULONG64 lpszClassName, char *achDest);
  284. BOOL dwrWorker(ULONG64 pwnd, int tab);
  285. BOOL CopyUnicodeString(
  286. IN ULONG64 pData,
  287. IN char * pszStructName,
  288. IN char * pszFieldName,
  289. OUT WCHAR *pszDest,
  290. IN ULONG cchMax);
  291. BOOL IsRemoteSession(
  292. VOID)
  293. {
  294. PPEB ppeb = NtCurrentPeb();
  295. return (ppeb->SessionId != 0);
  296. }
  297. int PtrWidth(
  298. VOID)
  299. {
  300. static int width = 0;
  301. if (width) {
  302. return width;
  303. }
  304. if (IsPtr64()) {
  305. return (width = 17);
  306. } else {
  307. return (width = 8);
  308. }
  309. }
  310. /****************************************************************************\
  311. * Flags stuff
  312. \****************************************************************************/
  313. typedef struct _WFLAGS {
  314. PSZ pszText;
  315. WORD wFlag;
  316. } WFLAGS;
  317. #define WF_ENTRY(flag) #flag, flag
  318. CONST WFLAGS aWindowFlags[] = { // sorted alphabetically
  319. WF_ENTRY(BFBITMAP),
  320. WF_ENTRY(BFBOTTOM),
  321. WF_ENTRY(BFCENTER),
  322. WF_ENTRY(BFFLAT),
  323. WF_ENTRY(BFICON),
  324. WF_ENTRY(BFLEFT),
  325. WF_ENTRY(BFMULTILINE),
  326. WF_ENTRY(BFNOTIFY),
  327. WF_ENTRY(BFPUSHLIKE),
  328. WF_ENTRY(BFRIGHT),
  329. WF_ENTRY(BFRIGHTBUTTON),
  330. WF_ENTRY(BFTOP),
  331. WF_ENTRY(BFVCENTER),
  332. WF_ENTRY(CBFAUTOHSCROLL),
  333. WF_ENTRY(CBFBUTTONUPTRACK),
  334. WF_ENTRY(CBFDISABLENOSCROLL),
  335. WF_ENTRY(CBFDROPDOWN),
  336. WF_ENTRY(CBFDROPDOWNLIST),
  337. WF_ENTRY(CBFDROPPABLE),
  338. WF_ENTRY(CBFDROPTYPE),
  339. WF_ENTRY(CBFEDITABLE),
  340. WF_ENTRY(CBFHASSTRINGS),
  341. WF_ENTRY(CBFLOWERCASE),
  342. WF_ENTRY(CBFNOINTEGRALHEIGHT),
  343. WF_ENTRY(CBFOEMCONVERT),
  344. WF_ENTRY(CBFOWNERDRAW),
  345. WF_ENTRY(CBFOWNERDRAWFIXED),
  346. WF_ENTRY(CBFOWNERDRAWVAR),
  347. WF_ENTRY(CBFSIMPLE),
  348. WF_ENTRY(CBFSORT),
  349. WF_ENTRY(CBFUPPERCASE),
  350. WF_ENTRY(DF3DLOOK),
  351. WF_ENTRY(DFCONTROL),
  352. WF_ENTRY(DFLOCALEDIT),
  353. WF_ENTRY(DFNOFAILCREATE),
  354. WF_ENTRY(DFSYSMODAL),
  355. WF_ENTRY(EFAUTOHSCROLL),
  356. WF_ENTRY(EFAUTOVSCROLL),
  357. WF_ENTRY(EFCOMBOBOX),
  358. WF_ENTRY(EFLOWERCASE),
  359. WF_ENTRY(EFMULTILINE),
  360. WF_ENTRY(EFNOHIDESEL),
  361. WF_ENTRY(EFNUMBER),
  362. WF_ENTRY(EFOEMCONVERT),
  363. WF_ENTRY(EFPASSWORD),
  364. WF_ENTRY(EFREADONLY),
  365. WF_ENTRY(EFUPPERCASE),
  366. WF_ENTRY(EFWANTRETURN),
  367. WF_ENTRY(SBFSIZEBOX),
  368. WF_ENTRY(SBFSIZEBOXBOTTOMRIGHT),
  369. WF_ENTRY(SBFSIZEBOXTOPLEFT),
  370. WF_ENTRY(SBFSIZEGRIP),
  371. WF_ENTRY(SFCENTERIMAGE),
  372. WF_ENTRY(SFEDITCONTROL),
  373. WF_ENTRY(SFELLIPSISMASK),
  374. WF_ENTRY(SFNOPREFIX),
  375. WF_ENTRY(SFNOTIFY),
  376. WF_ENTRY(SFREALSIZECONTROL),
  377. WF_ENTRY(SFREALSIZEIMAGE),
  378. WF_ENTRY(SFRIGHTJUST),
  379. WF_ENTRY(SFSUNKEN),
  380. WF_ENTRY(WEFACCEPTFILES),
  381. WF_ENTRY(WEFAPPWINDOW),
  382. WF_ENTRY(WEFCLIENTEDGE),
  383. WF_ENTRY(WEFCOMPOSITED),
  384. WF_ENTRY(WEFCONTEXTHELP),
  385. WF_ENTRY(WEFCONTROLPARENT),
  386. WF_ENTRY(WEFDLGMODALFRAME),
  387. WF_ENTRY(WEFDRAGOBJECT),
  388. #ifdef REDIRECTION
  389. WF_ENTRY(WEFEXTREDIRECTED),
  390. #endif
  391. WF_ENTRY(WEFGHOSTMAKEVISIBLE),
  392. #ifdef LAME_BUTTON
  393. WF_ENTRY(WEFLAMEBUTTON),
  394. #endif // LAME_BUTTON
  395. WF_ENTRY(WEFLEFTSCROLL),
  396. WF_ENTRY(WEFMDICHILD),
  397. WF_ENTRY(WEFNOACTIVATE),
  398. WF_ENTRY(WEFNOPARENTNOTIFY),
  399. WF_ENTRY(WEFPREDIRECTED),
  400. WF_ENTRY(WEFRIGHT),
  401. WF_ENTRY(WEFRTLREADING),
  402. WF_ENTRY(WEFSTATICEDGE),
  403. WF_ENTRY(WEFLAYERED),
  404. WF_ENTRY(WEFTOOLWINDOW),
  405. WF_ENTRY(WEFTOPMOST),
  406. WF_ENTRY(WEFTRANSPARENT),
  407. WF_ENTRY(WEFTRUNCATEDCAPTION),
  408. WF_ENTRY(WEFWINDOWEDGE),
  409. WF_ENTRY(WFALWAYSSENDNCPAINT),
  410. WF_ENTRY(WFANSICREATOR),
  411. WF_ENTRY(WFANSIPROC),
  412. WF_ENTRY(WFANYHUNGREDRAW),
  413. WF_ENTRY(WFBEINGACTIVATED),
  414. WF_ENTRY(WFBORDER),
  415. WF_ENTRY(WFBOTTOMMOST),
  416. WF_ENTRY(WFCAPTION),
  417. WF_ENTRY(WFCEPRESENT),
  418. WF_ENTRY(WFCHILD),
  419. WF_ENTRY(WFCLIPCHILDREN),
  420. WF_ENTRY(WFCLIPSIBLINGS),
  421. WF_ENTRY(WFCLOSEBUTTONDOWN),
  422. WF_ENTRY(WFCPRESENT),
  423. WF_ENTRY(WFDESTROYED),
  424. WF_ENTRY(WFDIALOGWINDOW),
  425. WF_ENTRY(WFDISABLED),
  426. WF_ENTRY(WFDLGFRAME),
  427. WF_ENTRY(WFDONTVALIDATE),
  428. WF_ENTRY(WFERASEBKGND),
  429. WF_ENTRY(WFFRAMEON),
  430. WF_ENTRY(WFFULLSCREEN),
  431. WF_ENTRY(WFGOTQUERYSUSPENDMSG),
  432. WF_ENTRY(WFGOTSUSPENDMSG),
  433. WF_ENTRY(WFGROUP),
  434. WF_ENTRY(WFHASPALETTE),
  435. WF_ENTRY(WFHASSPB),
  436. WF_ENTRY(WFHELPBUTTONDOWN),
  437. WF_ENTRY(WFHIDDENPOPUP),
  438. WF_ENTRY(WFHPRESENT),
  439. WF_ENTRY(WFHSCROLL),
  440. WF_ENTRY(WFICONICPOPUP),
  441. WF_ENTRY(WFINDESTROY),
  442. WF_ENTRY(WFINTERNALPAINT),
  443. WF_ENTRY(WFLINEDNBUTTONDOWN),
  444. WF_ENTRY(WFLINEUPBUTTONDOWN),
  445. WF_ENTRY(WFMAXBOX),
  446. WF_ENTRY(WFMAXFAKEREGIONAL),
  447. WF_ENTRY(WFMAXIMIZED),
  448. WF_ENTRY(WFMENUDRAW),
  449. WF_ENTRY(WFMINBOX),
  450. WF_ENTRY(WFMINIMIZED),
  451. WF_ENTRY(WFMPRESENT),
  452. WF_ENTRY(WFMSGBOX),
  453. WF_ENTRY(WFNOANIMATE),
  454. WF_ENTRY(WFNOIDLEMSG),
  455. WF_ENTRY(WFNONCPAINT),
  456. WF_ENTRY(WFOLDUI),
  457. WF_ENTRY(WFPAGEUPBUTTONDOWN),
  458. WF_ENTRY(WFPAGEDNBUTTONDOWN),
  459. WF_ENTRY(WFPAINTNOTPROCESSED),
  460. WF_ENTRY(WFPIXIEHACK),
  461. WF_ENTRY(WFPOPUP),
  462. WF_ENTRY(WFREALLYMAXIMIZABLE),
  463. WF_ENTRY(WFREDRAWFRAMEIFHUNG),
  464. WF_ENTRY(WFREDRAWIFHUNG),
  465. WF_ENTRY(WFREDUCEBUTTONDOWN),
  466. WF_ENTRY(WFSCROLLBUTTONDOWN),
  467. WF_ENTRY(WFSENDERASEBKGND),
  468. WF_ENTRY(WFSENDNCPAINT),
  469. WF_ENTRY(WFSENDSIZEMOVE),
  470. WF_ENTRY(WFSERVERSIDEPROC),
  471. WF_ENTRY(WFSHELLHOOKWND),
  472. WF_ENTRY(WFSIZEBOX),
  473. WF_ENTRY(WFSMQUERYDRAGICON),
  474. WF_ENTRY(WFSTARTPAINT),
  475. WF_ENTRY(WFSYNCPAINTPENDING),
  476. WF_ENTRY(WFSYSMENU),
  477. WF_ENTRY(WFTABSTOP),
  478. WF_ENTRY(WFTILED),
  479. WF_ENTRY(WFTITLESET),
  480. WF_ENTRY(WFTOGGLETOPMOST),
  481. WF_ENTRY(WFTOPLEVEL),
  482. WF_ENTRY(WFUPDATEDIRTY),
  483. WF_ENTRY(WFVERTSCROLLTRACK),
  484. WF_ENTRY(WFVISIBLE),
  485. WF_ENTRY(WFVPRESENT),
  486. WF_ENTRY(WFVSCROLL),
  487. WF_ENTRY(WFWIN31COMPAT),
  488. WF_ENTRY(WFWIN40COMPAT),
  489. WF_ENTRY(WFWIN50COMPAT),
  490. WF_ENTRY(WFWMPAINTSENT),
  491. WF_ENTRY(WFZOOMBUTTONDOWN),
  492. };
  493. CONST PCSTR aszTypeNames[/*TYPE_CTYPES*/] = {
  494. "Free",
  495. "Window",
  496. "Menu",
  497. "Icon/Cursor",
  498. "WPI(SWP) struct",
  499. "Hook",
  500. "Clipboard Data",
  501. "CallProcData",
  502. "Accelerator",
  503. "DDE access",
  504. "DDE conv",
  505. "DDE Transaction",
  506. "Monitor",
  507. "Keyboard Layout",
  508. "Keyboard File",
  509. "WinEvent hook",
  510. "Timer",
  511. "Input Context",
  512. #ifdef GENERIC_INPUT
  513. "HID Raw Data",
  514. "DEVICE INFO",
  515. #ifdef GI_PROCESSOR
  516. "Pre/PostProcessor",
  517. #endif
  518. #endif // GENERIC_INPUT
  519. "unknown",
  520. };
  521. const char * aszHeapTags[] = {
  522. "Unknown",
  523. "Class",
  524. "DesktopInfo",
  525. "ClientThreadInfo",
  526. "Text",
  527. "HandleTable",
  528. "SBInfo",
  529. "MenuItem",
  530. "MenuText",
  531. "IMEText",
  532. "PropList",
  533. NULL,
  534. };
  535. const char * aszHeapSubtags[] = {
  536. "",
  537. "Window",
  538. "Menu",
  539. "Cursor",
  540. "SetWindowPos",
  541. "Hook",
  542. "ClipData",
  543. "CallProc",
  544. "AccelTable",
  545. "DDEAccess",
  546. "DDEConve",
  547. "DDEXact",
  548. "Monitor",
  549. "KBDLayout",
  550. "KBDFile",
  551. "WinEventHook",
  552. "Timer",
  553. "IinputConText",
  554. "HIDData",
  555. "DeviceInfo",
  556. "CTyptes",
  557. NULL,
  558. };
  559. #include "ptagdbg.h" // derived from ntuser\kernel\ptag.lst and .\ptagdbg.bat
  560. #define NO_FLAG (LPCSTR)(LONG_PTR)0xFFFFFFFF // use this for non-meaningful entries.
  561. #define _MASKENUM_START (NO_FLAG-1)
  562. #define _MASKENUM_END (NO_FLAG-2)
  563. #define _SHIFT_BITS (NO_FLAG-3)
  564. #define _CONTINUE_ON (NO_FLAG-4)
  565. #define MASKENUM_START(mask) _MASKENUM_START, (LPCSTR)(mask)
  566. #define MASKENUM_END(shift) _MASKENUM_END, (LPCSTR)(shift)
  567. #define SHIFT_BITS(n) _SHIFT_BITS, (LPCSTR)(n)
  568. #define CONTINUE_ON(arr) _CONTINUE_ON, (LPCSTR)(arr)
  569. CONST PCSTR apszSmsFlags[] = {
  570. "SMF_REPLY" , // 0x0001
  571. "SMF_RECEIVERDIED" , // 0x0002
  572. "SMF_SENDERDIED" , // 0x0004
  573. "SMF_RECEIVERFREE" , // 0x0008
  574. "SMF_RECEIVEDMESSAGE" , // 0x0010
  575. NO_FLAG , // 0x0020
  576. NO_FLAG , // 0x0040
  577. NO_FLAG , // 0x0080
  578. "SMF_CB_REQUEST" , // 0x0100
  579. "SMF_CB_REPLY" , // 0x0200
  580. "SMF_CB_CLIENT" , // 0x0400
  581. "SMF_CB_SERVER" , // 0x0800
  582. "SMF_WOWRECEIVE" , // 0x1000
  583. "SMF_WOWSEND" , // 0x2000
  584. "SMF_RECEIVERBUSY" , // 0x4000
  585. NULL // 0x8000
  586. };
  587. CONST PCSTR apszTifFlags[] = {
  588. "TIF_INCLEANUP" , // 0x00000001
  589. "TIF_16BIT" , // 0x00000002
  590. "TIF_SYSTEMTHREAD" , // 0x00000004
  591. "TIF_CSRSSTHREAD" , // 0x00000008
  592. "TIF_TRACKRECTVISIBLE" , // 0x00000010
  593. "TIF_ALLOWFOREGROUNDACTIVATE" , // 0x00000020
  594. "TIF_DONTATTACHQUEUE" , // 0x00000040
  595. "TIF_DONTJOURNALATTACH" , // 0x00000080
  596. "TIF_WOW64" , // 0x00000100
  597. "TIF_INACTIVATEAPPMSG" , // 0x00000200
  598. "TIF_SPINNING" , // 0x00000400
  599. "TIF_PALETTEAWARE" , // 0x00000800
  600. "TIF_SHAREDWOW" , // 0x00001000
  601. "TIF_FIRSTIDLE" , // 0x00002000
  602. "TIF_WAITFORINPUTIDLE" , // 0x00004000
  603. "TIF_MOVESIZETRACKING" , // 0x00008000
  604. "TIF_VDMAPP" , // 0x00010000
  605. "TIF_DOSEMULATOR" , // 0x00020000
  606. "TIF_GLOBALHOOKER" , // 0x00040000
  607. "TIF_DELAYEDEVENT" , // 0x00080000
  608. "TIF_MSGPOSCHANGED" , // 0x00100000
  609. "TIF_SHUTDOWNCOMPLETE" , // 0x00200000
  610. "TIF_IGNOREPLAYBACKDELAY" , // 0x00400000
  611. "TIF_ALLOWOTHERACCOUNTHOOK" , // 0x00800000
  612. "TIF_GUITHREADINITIALIZED" , // 0x01000000
  613. "TIF_DISABLEIME" , // 0x02000000
  614. "TIF_INGETTEXTLENGTH" , // 0x04000000
  615. "TIF_ANSILENGTH" , // 0x08000000
  616. "TIF_DISABLEHOOKS" , // 0x10000000
  617. "TIF_RESTRICTED" , // 0x20000000
  618. "TIF_QUITPOSTED" , // 0x40000000
  619. NULL // no more
  620. };
  621. CONST PCSTR apszQsFlags[] = {
  622. "QS_KEY" , // 0x0001
  623. "QS_MOUSEMOVE" , // 0x0002
  624. "QS_MOUSEBUTTON" , // 0x0004
  625. "QS_POSTMESSAGE" , // 0x0008
  626. "QS_TIMER" , // 0x0010
  627. "QS_PAINT" , // 0x0020
  628. "QS_SENDMESSAGE" , // 0x0040
  629. "QS_HOTKEY" , // 0x0080
  630. "QS_ALLPOSTMESSAGE" , // 0x0100
  631. "QS_SMSREPLY" , // 0x0200
  632. "QS_RAWINPUT" , // 0x0400
  633. "QS_THREADATTACHED" , // 0x0800
  634. "QS_EXCLUSIVE" , // 0x1000
  635. "QS_EVENT" , // 0x2000
  636. "QS_TRANSFER" , // 0X4000
  637. NULL // 0x8000
  638. };
  639. CONST PCSTR apszMfFlags[] = {
  640. "MF_GRAYED" , // 0x0001
  641. "MF_DISABLED" , // 0x0002
  642. "MF_BITMAP" , // 0x0004
  643. "MF_CHECKED" , // 0x0008
  644. "MF_POPUP" , // 0x0010
  645. "MF_MENUBARBREAK" , // 0x0020
  646. "MF_MENUBREAK" , // 0x0040
  647. "MF_HILITE" , // 0x0080
  648. "MF_OWNERDRAW" , // 0x0100
  649. "MF_USECHECKBITMAPS" , // 0x0200
  650. NO_FLAG , // 0x0400
  651. "MF_SEPARATOR" , // 0x0800
  652. "MF_DEFAULT" , // 0x1000
  653. "MF_SYSMENU" , // 0x2000
  654. "MF_RIGHTJUSTIFY" , // 0x4000
  655. "MF_MOUSESELECT" , // 0x8000
  656. NULL
  657. };
  658. CONST PCSTR apszCsfFlags[] = {
  659. "CSF_SERVERSIDEPROC" , // 0x0001
  660. "CSF_ANSIPROC" , // 0x0002
  661. "CSF_WOWDEFERDESTROY" , // 0x0004
  662. "CSF_SYSTEMCLASS" , // 0x0008
  663. "CSF_WOWCLASS" , // 0x0010
  664. "CSF_WOWEXTRA" , // 0x0020
  665. "CSF_CACHEDSMICON" , // 0x0040
  666. "CSF_WIN40COMPAT" , // 0x0080
  667. "CSF_VERSIONCLASS" , // 0x0100
  668. NULL //
  669. };
  670. CONST PCSTR apszCsFlags[] = {
  671. "CS_VREDRAW" , // 0x0001
  672. "CS_HREDRAW" , // 0x0002
  673. "CS_KEYCVTWINDOW" , // 0x0004
  674. "CS_DBLCLKS" , // 0x0008
  675. NO_FLAG , // 0x0010
  676. "CS_OWNDC" , // 0x0020
  677. "CS_CLASSDC" , // 0x0040
  678. "CS_PARENTDC" , // 0x0080
  679. "CS_NOKEYCVT" , // 0x0100
  680. "CS_NOCLOSE" , // 0x0200
  681. NO_FLAG , // 0x0400
  682. "CS_SAVEBITS" , // 0x0800
  683. "CS_BYTEALIGNCLIENT" , // 0x1000
  684. "CS_BYTEALIGNWINDOW" , // 0x2000
  685. "CS_GLOBALCLASS" , // 0x4000
  686. NO_FLAG , // 0x8000
  687. "CS_IME" , // 0x10000
  688. "CS_DROPSHADOW" , // 0x20000
  689. NULL // no more
  690. };
  691. CONST PCSTR apszQfFlags[] = {
  692. "QF_UPDATEKEYSTATE" , // 0x0000001
  693. "used to be ALTTAB" , // 0x0000002
  694. "QF_FMENUSTATUSBREAK" , // 0x0000004
  695. "QF_FMENUSTATUS" , // 0x0000008
  696. "QF_FF10STATUS" , // 0x0000010
  697. "QF_MOUSEMOVED" , // 0x0000020
  698. "QF_ACTIVATIONCHANGE" , // 0x0000040
  699. "QF_TABSWITCHING" , // 0x0000080
  700. "QF_KEYSTATERESET" , // 0x0000100
  701. "QF_INDESTROY" , // 0x0000200
  702. "QF_LOCKNOREMOVE" , // 0x0000400
  703. "QF_FOCUSNULLSINCEACTIVE" , // 0x0000800
  704. NO_FLAG , // 0x0001000
  705. NO_FLAG , // 0x0002000
  706. "QF_DIALOGACTIVE" , // 0x0004000
  707. "QF_EVENTDEACTIVATEREMOVED" , // 0x0008000
  708. NO_FLAG , // 0x0010000
  709. "QF_TRACKMOUSELEAVE" , // 0x0020000
  710. "QF_TRACKMOUSEHOVER" , // 0x0040000
  711. "QF_TRACKMOUSEFIRING" , // 0x0080000
  712. "QF_CAPTURELOCKED" , // 0x00100000
  713. "QF_ACTIVEWNDTRACKING" , // 0x00200000
  714. NULL
  715. };
  716. CONST PCSTR apszW32pfFlags[] = {
  717. "W32PF_CONSOLEAPPLICATION" , // 0x00000001
  718. "W32PF_FORCEOFFFEEDBACK" , // 0x00000002
  719. "W32PF_STARTGLASS" , // 0x00000004
  720. "W32PF_WOW" , // 0x00000008
  721. "W32PF_READSCREENACCESSGRANTED" , // 0x00000010
  722. "W32PF_INITIALIZED" , // 0x00000020
  723. "W32PF_APPSTARTING" , // 0x00000040
  724. "W32PF_WOW64" , // 0x00000080
  725. "W32PF_ALLOWFOREGROUNDACTIVATE" , // 0x00000100
  726. "W32PF_OWNDCCLEANUP" , // 0x00000200
  727. "W32PF_SHOWSTARTGLASSCALLED" , // 0x00000400
  728. "W32PF_FORCEBACKGROUNDPRIORITY" , // 0x00000800
  729. "W32PF_TERMINATED" , // 0x00001000
  730. "W32PF_CLASSESREGISTERED" , // 0x00002000
  731. "W32PF_THREADCONNECTED" , // 0x00004000
  732. "W32PF_PROCESSCONNECTED" , // 0x00008000
  733. "W32PF_WAKEWOWEXEC" , // 0x00010000
  734. "W32PF_WAITFORINPUTIDLE" , // 0x00020000
  735. "W32PF_IOWINSTA" , // 0x00040000
  736. "W32PF_ALLOWSETFOREGROUND" , // 0x00080000
  737. "W32PF_OLELOADED" , // 0x00100000
  738. "W32PF_SCREENSAVER" , // 0x00200000
  739. "W32PF_IDLESCREENSAVER" , // 0x00400000
  740. "W32PF_DISABLEIME" , // 0x00800000
  741. "W32PF_SETUPAPP" , // 0x01000000
  742. "W32PF_RESTRICTED" , // 0x02000000
  743. "W32PF_CONSOLEHASFOCUS" , // 0x04000000
  744. "W32PF_DISABLEWINDOWSGHOSTING" , // 0x08000000
  745. NULL
  746. };
  747. CONST PCSTR apszHeFlags[] = {
  748. "HANDLEF_DESTROY" , // 0x0001
  749. "HANDLEF_INDESTROY" , // 0x0002
  750. "HANDLEF_INWAITFORDEATH" , // 0x0004
  751. "HANDLEF_FINALDESTROY" , // 0x0008
  752. "HANDLEF_MARKED_OK" , // 0x0010
  753. "HANDLEF_GRANTED" , // 0x0020
  754. "HANDLEF_POOL" , // 0x0040
  755. NULL,
  756. };
  757. CONST PCSTR apszHdataFlags[] = {
  758. "HDATA_APPOWNED" , // 0x0001
  759. NO_FLAG , // 0x0002
  760. NO_FLAG , // 0x0004
  761. NO_FLAG , // 0x0008
  762. NO_FLAG , // 0x0010
  763. NO_FLAG , // 0x0020
  764. NO_FLAG , // 0x0040
  765. NO_FLAG , // 0x0080
  766. "HDATA_EXECUTE" , // 0x0100
  767. "HDATA_INITIALIZED" , // 0x0200
  768. NO_FLAG , // 0x0400
  769. NO_FLAG , // 0x0800
  770. NO_FLAG , // 0x1000
  771. NO_FLAG , // 0x2000
  772. "HDATA_NOAPPFREE" , // 0x4000
  773. "HDATA_READONLY" , // 0x8000
  774. NULL
  775. };
  776. CONST PCSTR apszXiFlags[] = {
  777. "XIF_SYNCHRONOUS" , // 0x0001
  778. "XIF_COMPLETE" , // 0x0002
  779. "XIF_ABANDONED" , // 0x0004
  780. NULL
  781. };
  782. CONST PCSTR apszIifFlags[] = {
  783. "IIF_IN_SYNC_XACT" , // 0x0001
  784. NO_FLAG , // 0x0002
  785. NO_FLAG , // 0x0004
  786. NO_FLAG , // 0x0008
  787. NO_FLAG , // 0x0010
  788. NO_FLAG , // 0x0020
  789. NO_FLAG , // 0x0040
  790. NO_FLAG , // 0x0080
  791. NO_FLAG , // 0x0100
  792. NO_FLAG , // 0x0200
  793. NO_FLAG , // 0x0400
  794. NO_FLAG , // 0x0800
  795. NO_FLAG , // 0x1000
  796. NO_FLAG , // 0x2000
  797. NO_FLAG , // 0x4000
  798. "IIF_UNICODE" , // 0x8000
  799. NULL
  800. };
  801. CONST PCSTR apszTmrfFlags[] = {
  802. "TMRF_READY" , // 0x0001
  803. "TMRF_SYSTEM" , // 0x0002
  804. "TMRF_RIT" , // 0x0004
  805. "TMRF_INIT" , // 0x0008
  806. "TMRF_ONESHOT" , // 0x0010
  807. "TMRF_WAITING" , // 0x0020
  808. "TMRF_PTIWINDOW" , // 0x0040
  809. NULL , // 0x0080
  810. };
  811. CONST PCSTR apszSbFlags[] = {
  812. "SB_VERT" , // 0x0001
  813. "SB_CTL" , // 0x0002
  814. NULL , // 0x0004
  815. };
  816. CONST PCSTR apszCSFlags[] = {
  817. "FS_LATIN1" , // 0x00000001L
  818. "FS_LATIN2" , // 0x00000002L
  819. "FS_CYRILLIC" , // 0x00000004L
  820. "FS_GREEK" , // 0x00000008L
  821. "FS_TURKISH" , // 0x00000010L
  822. "FS_HEBREW" , // 0x00000020L
  823. "FS_ARABIC" , // 0x00000040L
  824. "FS_BALTIC" , // 0x00000080L
  825. "FS_VIETNAMESE" , // 0x00000100L
  826. NO_FLAG , // 0x00000200L
  827. NO_FLAG , // 0x00000400L
  828. NO_FLAG , // 0x00000800L
  829. NO_FLAG , // 0x00001000L
  830. NO_FLAG , // 0x00002000L
  831. NO_FLAG , // 0x00004000L
  832. NO_FLAG , // 0x00008000L
  833. "FS_THAI" , // 0x00010000L
  834. "FS_JISJAPAN" , // 0x00020000L
  835. "FS_CHINESESIMP" , // 0x00040000L
  836. "FS_WANSUNG" , // 0x00080000L
  837. "FS_CHINESETRAD" , // 0x00100000L
  838. "FS_JOHAB" , // 0x00200000L
  839. NO_FLAG , // 0x00400000L
  840. NO_FLAG , // 0x00800000L
  841. NO_FLAG , // 0x01000000L
  842. NO_FLAG , // 0x02000000L
  843. NO_FLAG , // 0x04000000L
  844. NO_FLAG , // 0x08000000L
  845. NO_FLAG , // 0x10000000L
  846. NO_FLAG , // 0x20000000L
  847. NO_FLAG , // 0x40000000L
  848. "FS_SYMBOL" , // 0x80000000L
  849. NULL
  850. };
  851. CONST PCSTR apszMenuTypeFlags[] = {
  852. NO_FLAG , // 0x0001
  853. NO_FLAG , // 0x0002
  854. "MFT_BITMAP" , // 0x0004 MF_BITMAP
  855. NO_FLAG , // 0x0008
  856. "MF_POPUP" , // 0x0010
  857. "MFT_MENUBARBREAK" , // 0x0020 MF_MENUBARBREAK
  858. "MFT_MENUBREAK" , // 0x0040 MF_MENUBREAK
  859. NO_FLAG , // 0x0080
  860. "MFT_OWNERDRAW" , // 0x0100 MF_OWNERDRAW
  861. NO_FLAG , // 0x0200
  862. NO_FLAG , // 0x0400
  863. "MFT_SEPARATOR" , // 0x0800 MF_SEPARATOR
  864. NO_FLAG , // 0x1000
  865. "MF_SYSMENU" , // 0x2000
  866. "MFT_RIGHTJUSTIFY" , // 0x4000 MF_RIGHTJUSTIFY
  867. NULL
  868. };
  869. CONST PCSTR apszMenuStateFlags[] = {
  870. "MF_GRAYED" , // 0x0001
  871. "MF_DISABLED" , // 0x0002
  872. NO_FLAG , // 0x0004
  873. "MFS_CHECKED" , // 0x0008 MF_CHECKED
  874. NO_FLAG , // 0x0010
  875. NO_FLAG , // 0x0020
  876. NO_FLAG , // 0x0040
  877. "MFS_HILITE" , // 0x0080 MF_HILITE
  878. NO_FLAG , // 0x0100
  879. NO_FLAG , // 0x0200
  880. NO_FLAG , // 0x0400
  881. NO_FLAG , // 0x0800
  882. "MFS_DEFAULT" , // 0x1000 MF_DEFAULT
  883. NO_FLAG , // 0x2000
  884. NO_FLAG , // 0x4000
  885. "MF_MOUSESELECT" , // 0x8000
  886. NULL
  887. };
  888. CONST PCSTR apszCursorfFlags[] = {
  889. "CURSORF_FROMRESOURCE", // 0x0001
  890. "CURSORF_GLOBAL", // 0x0002
  891. "CURSORF_LRSHARED", // 0x0004
  892. "CURSORF_ACON", // 0x0008
  893. "CURSORF_WOWCLEANUP" , // 0x0010
  894. NO_FLAG , // 0x0020
  895. "CURSORF_ACONFRAME", // 0x0040
  896. "CURSORF_SECRET", // 0x0080
  897. "CURSORF_LINKED", // 0x0100
  898. "CURSORF_SYSTEM", // 0x0200
  899. "CURSORF_SHADOW", // 0x0400
  900. NULL
  901. };
  902. CONST PCSTR apszMonfFlags[] = {
  903. "MONF_VISIBLE", // 0x01
  904. "MONF_PALETTEDISPLAY", // 0x02
  905. NULL,
  906. };
  907. CONST PCSTR apszSifFlags[] = {
  908. "PUSIF_PALETTEDISPLAY", // 0x00000001
  909. "PUSIF_SNAPTO", // 0x00000002
  910. "PUSIF_COMBOBOXANIMATION", // 0x00000004
  911. "PUSIF_LISTBOXSMOOTHSCROLLING", // 0x00000008
  912. NO_FLAG, // 0x00000010
  913. "PUSIF_KEYBOARDCUES", // 0x00000020
  914. NO_FLAG, // 0x00000040
  915. NO_FLAG, // 0x00000080
  916. NO_FLAG, // 0x00000100
  917. NO_FLAG, // 0x00000200
  918. NO_FLAG, // 0x00000400
  919. NO_FLAG, // 0x00000800
  920. NO_FLAG, // 0x00001000
  921. NO_FLAG, // 0x00002000
  922. NO_FLAG, // 0x00004000
  923. NO_FLAG, // 0x00008000
  924. NO_FLAG, // 0x00010000
  925. NO_FLAG, // 0x00020000
  926. NO_FLAG, // 0x00040000
  927. NO_FLAG, // 0x00080000
  928. NO_FLAG, // 0x00100000
  929. NO_FLAG, // 0x00200000
  930. NO_FLAG, // 0x00400000
  931. NO_FLAG, // 0x00800000
  932. NO_FLAG, // 0x01000000
  933. NO_FLAG, // 0x02000000
  934. NO_FLAG, // 0x04000000
  935. NO_FLAG, // 0x08000000
  936. NO_FLAG, // 0x10000000
  937. NO_FLAG, // 0x20000000
  938. NO_FLAG, // 0x40000000
  939. "PUSIF_UIEFFECTS", // 0x80000000
  940. NULL,
  941. };
  942. CONST PCSTR apszRipFlags[] = {
  943. "RIPF_PROMPTONERROR", // 0x0001
  944. "RIPF_PROMPTONWARNING", // 0x0002
  945. "RIPF_PROMPTONVERBOSE", // 0x0004
  946. NO_FLAG, // 0x0008
  947. "RIPF_PRINTONERROR", // 0x0010
  948. "RIPF_PRINTONWARNING", // 0x0020
  949. "RIPF_PRINTONVERBOSE", // 0x0040
  950. NO_FLAG, // 0x0080
  951. "RIPF_PRINTFILELINE", // 0x0100
  952. NULL
  953. };
  954. CONST PCSTR apszSRVIFlags[] = {
  955. "SRVIF_CHECKED", // 0x0001
  956. "SRVIF_LOGDESKTOPHEAPFAILURE", // 0x0002
  957. "SRVIF_DBCS", // 0x0004
  958. "SRVIF_IME", // 0x0008
  959. "SRVIF_MIDEAST", // 0x0010
  960. "SRVIF_HOOKED", // 0x0020
  961. "SRVIF_CICERO", // 0x0040
  962. NULL
  963. };
  964. CONST PCSTR apszPROPFlags[] = {
  965. "PROPF_INTERNAL", // 0x0001
  966. "PROPF_STRING", // 0x0002
  967. "PROPF_NOPOOL", // 0x0004
  968. };
  969. CONST PCSTR apszLpkEntryPoints[] = {
  970. "LpkTabbedTextOut" , // 0x00000001L
  971. "LpkPSMTextOut" , // 0x00000002L
  972. "LpkDrawTextEx" , // 0x00000004L
  973. "LpkEditControl" , // 0x00000008L
  974. NULL
  975. };
  976. /*
  977. * We need one of these per DWORD
  978. */
  979. CONST PCSTR aszUserPreferencesMask0[sizeof(DWORD) * 8] = {
  980. "ACTIVEWINDOWTRACKING", /* 0x1000 */
  981. "MENUANIMATION", /* 0x1002 */
  982. "COMBOBOXANIMATION", /* 0x1004 */
  983. "LISTBOXSMOOTHSCROLLING", /* 0x1006 */
  984. "GRADIENTCAPTIONS", /* 0x1008 */
  985. "KEYBOARDCUES", /* 0x100A */
  986. "ACTIVEWNDTRKZORDER", /* 0x100C */
  987. "HOTTRACKING", /* 0x100E */
  988. NO_FLAG, /* 0x1010 */
  989. "MENUFADE", /* 0x1012 */
  990. "SELECTIONFADE", /* 0x1014 */
  991. "TOOLTIPANIMATION", /* 0x1016 */
  992. "TOOLTIPFADE", /* 0x1018 */
  993. "CURSORSHADOW", /* 0x101A */
  994. NO_FLAG, /* 0x101C */
  995. NO_FLAG, /* 0x101E */
  996. NO_FLAG, /* 0x1020 */
  997. NO_FLAG, /* 0x1022 */
  998. NO_FLAG, /* 0x1024 */
  999. NO_FLAG, /* 0x1026 */
  1000. NO_FLAG, /* 0x1028 */
  1001. NO_FLAG, /* 0x102A */
  1002. NO_FLAG, /* 0x102C */
  1003. NO_FLAG, /* 0x102E */
  1004. NO_FLAG, /* 0x1030 */
  1005. NO_FLAG, /* 0x1032 */
  1006. NO_FLAG, /* 0x1034 */
  1007. NO_FLAG, /* 0x1036 */
  1008. NO_FLAG, /* 0x1038 */
  1009. NO_FLAG, /* 0x103A */
  1010. NO_FLAG, /* 0x103C */
  1011. "UIEFFECTS", /* 0x103E */
  1012. };
  1013. CONST PCSTR aszUserPreferences[SPI_DWORDRANGECOUNT] = {
  1014. "FOREGROUNDLOCKTIMEOUT", /* 0x2000 */
  1015. "ACTIVEWNDTRKTIMEOUT", /* 0x2002 */
  1016. "FOREGROUNDFLASHCOUNT", /* 0x2004 */
  1017. "CARETWIDTH", /* 0x2006 */
  1018. };
  1019. CONST PCSTR aszKeyEventFlags[] = {
  1020. "KEYEVENTF_EXTENDEDKEY", // 0x0001
  1021. "KEYEVENTF_KEYUP", // 0x0002
  1022. "KEYEVENTF_UNICODE", // 0x0004
  1023. "KEYEVENTF_SCANCODE", // 0x0008
  1024. NULL,
  1025. };
  1026. CONST PCSTR aszMouseEventFlags[] = {
  1027. "MOUSEEVENTF_MOVE", // 0x0001
  1028. "MOUSEEVENTF_LEFTDOWN", // 0x0002
  1029. "MOUSEEVENTF_LEFTUP", // 0x0004
  1030. "MOUSEEVENTF_RIGHTDOWN", // 0x0008
  1031. "MOUSEEVENTF_RIGHTUP", // 0x0010
  1032. "MOUSEEVENTF_MIDDLEDOWN", // 0x0020
  1033. "MOUSEEVENTF_MIDDLEUP", // 0x0040
  1034. NO_FLAG, // 0x0080
  1035. NO_FLAG, // 0x0100
  1036. NO_FLAG, // 0x0200
  1037. NO_FLAG, // 0x0400
  1038. "MOUSEEVENTF_WHEEL", // 0x0800
  1039. NO_FLAG, // 0x1000
  1040. NO_FLAG, // 0x2000
  1041. "MOUSEEVENTF_VIRTUALDESK", // 0x4000
  1042. "MOUSEEVENTF_ABSOLUTE", // 0x8000
  1043. NULL,
  1044. };
  1045. const char* aszWindowStyle[] = {
  1046. NO_FLAG, // 0x00000001
  1047. NO_FLAG, // 0x00000002
  1048. NO_FLAG, // 0x00000004
  1049. NO_FLAG, // 0x00000008
  1050. NO_FLAG, // 0x00000010
  1051. NO_FLAG, // 0x00000020
  1052. NO_FLAG, // 0x00000040
  1053. NO_FLAG, // 0x00000080
  1054. NO_FLAG, // 0x00000100
  1055. NO_FLAG, // 0x00000200
  1056. NO_FLAG, // 0x00000400
  1057. NO_FLAG, // 0x00000800
  1058. NO_FLAG, // 0x00001000
  1059. NO_FLAG, // 0x00002000
  1060. NO_FLAG, // 0x00004000
  1061. NO_FLAG, // 0x00008000
  1062. "WS_TABSTOP", // 0x00010000
  1063. "WS_GROUP", // 0x00020000
  1064. "WS_THICKFRAME", // 0x00040000
  1065. "WS_SYSMENU", // 0x00080000
  1066. "WS_HSCROLL", // 0x00100000
  1067. "WS_VSCROLL", // 0x00200000
  1068. "WS_DLGFRAME", // 0x00400000
  1069. "WS_BORDER", // 0x00800000
  1070. "WS_MAXIMIZE", // 0x01000000
  1071. "WS_CLIPCHILDREN", // 0x02000000
  1072. "WS_CLIPSIBLINGS", // 0x04000000
  1073. "WS_DISABLED", // 0x08000000
  1074. "WS_VISIBLE", // 0x10000000
  1075. "WS_MINIMIZE", // 0x20000000
  1076. "WS_CHILD", // 0x40000000
  1077. "WS_POPUP", // 0x80000000
  1078. NULL,
  1079. };
  1080. const char* aszDialogStyle[] = {
  1081. "DS_ABSALIGN", // 0x00000001
  1082. "DS_SYSMODAL", // 0x00000002
  1083. "DS_3DLOOK", // 0x00000004
  1084. "DS_FIXEDSYS", // 0x00000008
  1085. "DS_NOFAILCREATE", // 0x00000010
  1086. "DS_LOCALEDIT", // 0x00000020
  1087. "DS_SETFONT", // 0x00000040
  1088. "DS_MODALFRAME", // 0x00000080
  1089. "DS_NOIDLEMSG", // 0x00000100
  1090. "DS_SETFOREGROUND", // 0x00000200
  1091. "DS_CONTROL", // 0x00000400
  1092. "DS_CENTER", // 0x00000800
  1093. "DS_CENTERMOUSE", // 0x00001000
  1094. "DS_CONTEXTHELP", // 0x00002000
  1095. NO_FLAG, // 0x00004000
  1096. NO_FLAG, // 0x00008000
  1097. CONTINUE_ON(aszWindowStyle + 16),
  1098. };
  1099. const char* aszButtonStyle[] = {
  1100. MASKENUM_START(BS_TYPEMASK),
  1101. "BS_PUSHBUTTON", // 0
  1102. "BS_DEFPUSHBUTTON", // 1
  1103. "BS_CHECKBOX", // 2
  1104. "BS_AUTOCHECKBOX", // 3
  1105. "BS_RADIOBUTTON", // 4
  1106. "BS_3STATE", // 5
  1107. "BS_AUTO3STATE", // 6
  1108. "BS_GROUPBOX", // 7
  1109. "BS_USERBUTTON", // 8
  1110. "BS_AUTORADIOBUTTON", // 9
  1111. "BS_PUSHBOX", // a
  1112. "BS_OWNERDRAW", // b
  1113. MASKENUM_END(4),
  1114. NO_FLAG, // 0x00000010
  1115. "BS_LEFTTEXT", // 0x00000020
  1116. MASKENUM_START(BS_IMAGEMASK),
  1117. "BS_TEXT", // 0
  1118. "BS_ICON",
  1119. "BS_BITMAP",
  1120. MASKENUM_END(2),
  1121. MASKENUM_START(BS_HORZMASK),
  1122. NO_FLAG,
  1123. "BS_LEFT",
  1124. "BS_RIGHT",
  1125. "BS_CENTER",
  1126. MASKENUM_END(2),
  1127. MASKENUM_START(BS_VERTMASK),
  1128. NO_FLAG,
  1129. "BS_TOP", "BS_BOTTOM", "BS_VCENTER",
  1130. MASKENUM_END(2),
  1131. "BS_PUSHLIKE", // 0x00001000
  1132. "BS_MULTILINE", // 0x00002000
  1133. "BS_NOTIFY", // 0x00004000
  1134. "BS_FLAT", // 0x00008000
  1135. CONTINUE_ON(aszWindowStyle + 16),
  1136. };
  1137. const char* aszComboBoxStyle[] = {
  1138. MASKENUM_START(0x0f),
  1139. NO_FLAG, // 0
  1140. "CBS_SIMPLE", // 1
  1141. "CBS_DROPDOWN", // 2
  1142. "CBS_DROPDOWNLIST", // 3
  1143. MASKENUM_END(4),
  1144. "CBS_OWNERDRAWFIXED", // 0x0010L
  1145. "CBS_OWNERDRAWVARIABLE", // 0x0020L
  1146. "CBS_AUTOHSCROLL", // 0x0040L
  1147. "CBS_OEMCONVERT", // 0x0080L
  1148. "CBS_SORT", // 0x0100L
  1149. "CBS_HASSTRINGS", // 0x0200L
  1150. "CBS_NOINTEGRALHEIGHT", // 0x0400L
  1151. "CBS_DISABLENOSCROLL", // 0x0800L
  1152. NO_FLAG, // 0x1000L
  1153. "CBS_UPPERCASE", // 0x2000L
  1154. "CBS_LOWERCASE", // 0x4000L
  1155. NO_FLAG, // 0x8000L
  1156. CONTINUE_ON(aszWindowStyle + 16),
  1157. };
  1158. const char* aszStaticStyle[] = {
  1159. MASKENUM_START(SS_TYPEMASK),
  1160. "SS_LEFT", // 0x00000000L
  1161. "SS_CENTER", // 0x00000001L
  1162. "SS_RIGHT", // 0x00000002L
  1163. "SS_ICON", // 0x00000003L
  1164. "SS_BLACKRECT", // 0x00000004L
  1165. "SS_GRAYRECT", // 0x00000005L
  1166. "SS_WHITERECT", // 0x00000006L
  1167. "SS_BLACKFRAME", // 0x00000007L
  1168. "SS_GRAYFRAME", // 0x00000008L
  1169. "SS_WHITEFRAME", // 0x00000009L
  1170. "SS_USERITEM", // 0x0000000AL
  1171. "SS_SIMPLE", // 0x0000000BL
  1172. "SS_LEFTNOWORDWRAP", // 0x0000000CL
  1173. "SS_OWNERDRAW", // 0x0000000DL
  1174. "SS_BITMAP", // 0x0000000EL
  1175. "SS_ENHMETAFILE", // 0x0000000FL
  1176. "SS_ETCHEDHORZ", // 0x00000010L
  1177. "SS_ETCHEDVERT", // 0x00000011L
  1178. "SS_ETCHEDFRAME", // 0x00000012L
  1179. MASKENUM_END(5),
  1180. NO_FLAG, // 0x00000020L
  1181. "SS_REALSIZECONTROL", // 0x00000040L
  1182. "SS_NOPREFIX", // 0x00000080L /* Don't do "&" character translation */
  1183. "SS_NOTIFY", // 0x00000100L
  1184. "SS_CENTERIMAGE", // 0x00000200L
  1185. "SS_RIGHTJUST", // 0x00000400L
  1186. "SS_REALSIZEIMAGE", // 0x00000800L
  1187. "SS_SUNKEN", // 0x00001000L
  1188. "SS_EDITCONTROL", // 0x00002000L ;internal
  1189. MASKENUM_START(SS_ELLIPSISMASK),
  1190. NO_FLAG,
  1191. "SS_ENDELLIPSIS", // 0x00004000L
  1192. "SS_PATHELLIPSIS", // 0x00008000L
  1193. "SS_WORDELLIPSIS", // 0x0000C000L
  1194. MASKENUM_END(2),
  1195. CONTINUE_ON(aszWindowStyle + 16),
  1196. };
  1197. const char* aszListBoxStyle[] = {
  1198. "LBS_NOTIFY", // 0x0001L
  1199. "LBS_SORT", // 0x0002L
  1200. "LBS_NOREDRAW", // 0x0004L
  1201. "LBS_MULTIPLESEL", // 0x0008L
  1202. "LBS_OWNERDRAWFIXED", // 0x0010L
  1203. "LBS_OWNERDRAWVARIABLE", // 0x0020L
  1204. "LBS_HASSTRINGS", // 0x0040L
  1205. "LBS_USETABSTOPS", // 0x0080L
  1206. "LBS_NOINTEGRALHEIGHT", // 0x0100L
  1207. "LBS_MULTICOLUMN", // 0x0200L
  1208. "LBS_WANTKEYBOARDINPUT", // 0x0400L
  1209. "LBS_EXTENDEDSEL", // 0x0800L
  1210. "LBS_DISABLENOSCROLL", // 0x1000L
  1211. "LBS_NODATA", // 0x2000L
  1212. "LBS_NOSEL", // 0x4000L
  1213. NO_FLAG, // 0x8000L
  1214. CONTINUE_ON(aszWindowStyle + 16),
  1215. };
  1216. const char* aszEditStyle[] = {
  1217. MASKENUM_START(ES_FMTMASK),
  1218. "ES_LEFT", // 0x0000L
  1219. "ES_CENTER", // 0x0001L
  1220. "ES_RIGHT", // 0x0002L
  1221. MASKENUM_END(2),
  1222. "ES_MULTILINE", // 0x0004L
  1223. "ES_UPPERCASE", // 0x0008L
  1224. "ES_LOWERCASE", // 0x0010L
  1225. "ES_PASSWORD", // 0x0020L
  1226. "ES_AUTOVSCROLL", // 0x0040L
  1227. "ES_AUTOHSCROLL", // 0x0080L
  1228. "ES_NOHIDESEL", // 0x0100L
  1229. "ES_COMBOBOX", // 0x0200L ;internal
  1230. "ES_OEMCONVERT", // 0x0400L
  1231. "ES_READONLY", // 0x0800L
  1232. "ES_WANTRETURN", // 0x1000L
  1233. "ES_NUMBER", // 0x2000L ;public_winver_400
  1234. NO_FLAG, // 0x4000L
  1235. NO_FLAG, // 0x8000L
  1236. CONTINUE_ON(aszWindowStyle + 16),
  1237. };
  1238. const char* aszScrollBarStyle[] = {
  1239. "SBS_HORZ", // 0x0000L
  1240. "SBS_VERT", // 0x0001L
  1241. "SBS_TOPALIGN", // 0x0002L
  1242. "SBS_LEFTALIGN", // 0x0002L
  1243. "SBS_BOTTOMALIGN", // 0x0004L
  1244. "SBS_RIGHTALIGN", // 0x0004L
  1245. "SBS_SIZEBOXTOPLEFTALIGN", // 0x0002L
  1246. "SBS_SIZEBOXBOTTOMRIGHTALIGN", // 0x0004L
  1247. "SBS_SIZEBOX", // 0x0008L
  1248. "SBS_SIZEGRIP", // 0x0010L
  1249. SHIFT_BITS(8), // 8 bits
  1250. CONTINUE_ON(aszWindowStyle + 16),
  1251. };
  1252. const char* aszWindowExStyle[] = {
  1253. "WS_EX_DLGMODALFRAME", // 0x00000001L
  1254. "WS_EX_DRAGOBJECT", // 0x00000002L ;internal
  1255. "WS_EX_NOPARENTNOTIFY", // 0x00000004L
  1256. "WS_EX_TOPMOST", // 0x00000008L
  1257. "WS_EX_ACCEPTFILES", // 0x00000010L
  1258. "WS_EX_TRANSPARENT", // 0x00000020L
  1259. "WS_EX_MDICHILD", // 0x00000040L
  1260. "WS_EX_TOOLWINDOW", // 0x00000080L
  1261. "WS_EX_WINDOWEDGE", // 0x00000100L
  1262. "WS_EX_CLIENTEDGE", // 0x00000200L
  1263. "WS_EX_CONTEXTHELP", // 0x00000400L
  1264. NO_FLAG, // 0x00000800L
  1265. "WS_EX_RIGHT", // 0x00001000L
  1266. // "WS_EX_LEFT", // 0x00000000L
  1267. "WS_EX_RTLREADING", // 0x00002000L
  1268. // "WS_EX_LTRREADING", // 0x00000000L
  1269. "WS_EX_LEFTSCROLLBAR", // 0x00004000L
  1270. // "WS_EX_RIGHTSCROLLBAR", // 0x00000000L
  1271. NO_FLAG, // 0x00008000L
  1272. "WS_EX_CONTROLPARENT", // 0x00010000L
  1273. "WS_EX_STATICEDGE", // 0x00020000L
  1274. "WS_EX_APPWINDOW", // 0x00040000L
  1275. "WS_EX_LAYERED", // 0x00080000
  1276. NULL
  1277. };
  1278. const char* aszClientImcFlags[] = {
  1279. "IMCF_UNICODE", // 0x0001
  1280. "IMCF_ACTIVE", // 0x0002
  1281. "IMCF_CHGMSG", // 0x0004
  1282. "IMCF_SAVECTRL", // 0x0008
  1283. "IMCF_PROCESSEVENT", // 0x0010
  1284. "IMCF_FIRSTSELECT", // 0x0020
  1285. "IMCF_INDESTROY", // 0x0040
  1286. "IMCF_WINNLSDISABLE", // 0x0080
  1287. "IMCF_DEFAULTIMC", // 0x0100
  1288. NULL,
  1289. };
  1290. const char* aszConversionModes[] = {
  1291. "IME_CMODE_NATIVE", // 0x0001
  1292. "IME_CMODE_KATAKANA", // 0x0002 // only effect under IME_CMODE_NATIVE
  1293. NO_FLAG, // 0x0004
  1294. "IME_CMODE_FULLSHAPE", // 0x0008
  1295. "IME_CMODE_ROMAN", // 0x0010
  1296. "IME_CMODE_CHARCODE", // 0x0020
  1297. "IME_CMODE_HANJACONVERT", // 0x0040
  1298. "IME_CMODE_SOFTKBD", // 0x0080
  1299. "IME_CMODE_NOCONVERSION", // 0x0100
  1300. "IME_CMODE_EUDC", // 0x0200
  1301. "IME_CMODE_SYMBOL", // 0x0400
  1302. "IME_CMODE_FIXED", // 0x0800
  1303. NULL
  1304. };
  1305. const char* aszSentenceModes[] = {
  1306. "IME_SMODE_PLAURALCLAUSE", // 0x0001
  1307. "IME_SMODE_SINGLECONVERT", // 0x0002
  1308. "IME_SMODE_AUTOMATIC", // 0x0004
  1309. "IME_SMODE_PHRASEPREDICT", // 0x0008
  1310. "IME_SMODE_CONVERSATION", // 0x0010
  1311. NULL
  1312. };
  1313. const char* aszImeInit[] = {
  1314. "INIT_STATUSWNDPOS", // 0x00000001
  1315. "INIT_CONVERSION", // 0x00000002
  1316. "INIT_SENTENCE", // 0x00000004
  1317. "INIT_LOGFONT", // 0x00000008
  1318. "INIT_COMPFORM", // 0x00000010
  1319. "INIT_SOFTKBDPOS", // 0x00000020
  1320. NULL
  1321. };
  1322. const char* aszImeSentenceMode[] = {
  1323. "IME_SMODE_PLAURALCLAUSE", // 0x0001
  1324. "IME_SMODE_SINGLECONVERT", // 0x0002
  1325. "IME_SMODE_AUTOMATIC", // 0x0004
  1326. "IME_SMODE_PHRASEPREDICT", // 0x0008
  1327. "IME_SMODE_CONVERSATION", // 0x0010
  1328. NULL
  1329. };
  1330. const char* aszImeConversionMode[] = {
  1331. "IME_CMODE_NATIVE", // 0x0001
  1332. "IME_CMODE_KATAKANA", // 0x0002 // only effect under IME_CMODE_NATIVE
  1333. NO_FLAG,
  1334. "IME_CMODE_FULLSHAPE", // 0x0008
  1335. "IME_CMODE_ROMAN", // 0x0010
  1336. "IME_CMODE_CHARCODE", // 0x0020
  1337. "IME_CMODE_HANJACONVERT", // 0x0040
  1338. "IME_CMODE_SOFTKBD", // 0x0080
  1339. "IME_CMODE_NOCONVERSION", // 0x0100
  1340. "IME_CMODE_EUDC", // 0x0200
  1341. "IME_CMODE_SYMBOL", // 0x0400
  1342. "IME_CMODE_FIXED", // 0x0800
  1343. NULL
  1344. };
  1345. const char* aszImeDirtyFlags[] = {
  1346. "IMSS_UPDATE_OPEN", // 0x0001
  1347. "IMSS_UPDATE_CONVERSION", // 0x0002
  1348. "IMSS_UPDATE_SENTENCE", // 0x0004
  1349. NO_FLAG, // 0x0008
  1350. NO_FLAG, // 0x0010
  1351. NO_FLAG, // 0x0020
  1352. NO_FLAG, // 0x0040
  1353. NO_FLAG, // 0x0080
  1354. "IMSS_INIT_OPEN", // 0x0100
  1355. NULL
  1356. };
  1357. const char* aszImeCompFormFlags[] = {
  1358. // "CFS_DEFAULT", // 0x0000
  1359. "CFS_RECT", // 0x0001
  1360. "CFS_POINT", // 0x0002
  1361. "CFS_SCREEN", // 0x0004 @Internal
  1362. "CFS_VERTICAL", // 0x0008 @Internal
  1363. "CFS_HIDDEN", // 0x0010 @Internal
  1364. "CFS_FORCE_POSITION", // 0x0020
  1365. "CFS_CANDIDATEPOS", // 0x0040
  1366. "CFS_EXCLUDE", // 0x0080
  1367. NULL
  1368. };
  1369. const char* aszEdUndoType[] = {
  1370. "UNDO_INSERT", // 0x0001
  1371. "UNDO_DELETE", // 0x0002
  1372. NULL,
  1373. };
  1374. const char* aszDeviceInfoActionFlags[] = {
  1375. "GDIAF_ARRIVED", // 0x0001
  1376. "GDIAF_QUERYREMOVE", // 0x0002
  1377. "GDIAF_REMOVECANCELLED", // 0x0004
  1378. "GDIAF_DEPARTED", // 0x0008
  1379. "GDIAF_IME_STATUS", // 0x0010
  1380. "GDIAF_REFRESH_MOUSE", // 0x0020
  1381. NO_FLAG, // 0x0040
  1382. "GDIAF_FREEME", // 0x0080
  1383. "GDIAF_PNPWAITING", // 0x0100
  1384. "GDIAF_RETRYREAD", // 0x0200
  1385. "GDIAF_RECONNECT", // 0x0400
  1386. "GDIAF_STARTREAD", // 0x0800 // the device needs to be started
  1387. "GDIAF_STOPREAD", // 0x1000 // the device needs to be stopped
  1388. NULL,
  1389. };
  1390. const char* aszHidProcessMask[] = {
  1391. "TRIM_RAWMOUSE", // 0x0001
  1392. "TRIM_RAWKEYBOARD", // 0x0002
  1393. "TRIM_NOLEGACYMOUSE", // 0x0004
  1394. "TRIM_NOLEGACYKEYBOARD", // 0x0008
  1395. NULL,
  1396. };
  1397. const char* aszHookFlags[] = {
  1398. "HF_GLOBAL", // 0x0001
  1399. "HF_ANSI", // 0x0002
  1400. "HF_NEEDHC_SKIP", // 0x0004
  1401. "HF_HUNG", // 0x0008 // Hook Proc hung don't call if system
  1402. "HF_HOOKFAULTED", // 0x0010 // Hook Proc faulted
  1403. "HF_NOPLAYBACKDELAY", // 0x0020 // Ignore requested delay
  1404. "HF_DESTROYED", // 0x0080 // Set by FreeHook
  1405. // DEBUG only flags
  1406. "HF_INCHECKWHF", // 0x0100 // fsHooks is being updated
  1407. "HF_FREED", // 0x0200 // Object has been freed.
  1408. NULL,
  1409. };
  1410. const char * aszDcxFlags[] = {
  1411. "DCX_WINDOW", // 0x00000001L
  1412. "DCX_CACHE", // 0x00000002L
  1413. "DCX_NORESETATTRS", // 0x00000004L
  1414. "DCX_CLIPCHILDREN", // 0x00000008L
  1415. "DCX_CLIPSIBLINGS", // 0x00000010L
  1416. "DCX_PARENTCLIP", // 0x00000020L
  1417. "DCX_EXCLUDERGN", // 0x00000040L
  1418. "DCX_INTERSECTRGN", // 0x00000080L
  1419. "DCX_EXCLUDEUPDATE", // 0x00000100L
  1420. "DCX_INTERSECTUPDATE", // 0x00000200L
  1421. "DCX_LOCKWINDOWUPDATE", // 0x00000400L
  1422. "DCX_INVALID", // 0x00000800L
  1423. "DCX_INUSE", // 0x00001000L
  1424. "DCX_SAVEDRGNINVALID", // 0x00002000L
  1425. "DCX_REDIRECTED", // 0x00004000L
  1426. "DCX_OWNDC", // 0x00008000L
  1427. "DCX_USESTYLE", // 0x00010000L
  1428. "DCX_NEEDFONT", // 0x00020000L
  1429. "DCX_NODELETERGN", // 0x00040000L
  1430. "DCX_NOCLIPCHILDREN", // 0x00080000L
  1431. "DCX_NORECOMPUTE", // 0x00100000L
  1432. "DCX_VALIDATE", // 0x00200000L
  1433. "DCX_DESTROYTHIS", // 0x00400000L
  1434. "DCX_CREATEDC", // 0x00800000L
  1435. "DCX_REDIRECTEDBITMAP", // 0x08000000L
  1436. "DCX_PWNDORGINVISIBLE", // 0x10000000L
  1437. "DCX_NOMIRROR", // 0x40000000L
  1438. NULL
  1439. };
  1440. const char* aszDesktopFlags[] = {
  1441. "DF_ACTIVEONDESTROY",
  1442. "DF_ZOMBIE",
  1443. "DF_NOTRITUNLOCK",
  1444. "DF_QUITUNLOCK",
  1445. "DF_USERMODE",
  1446. "DF_SKIPSWITCHDESKTOP",
  1447. "DF_DTNONEWDESKTOP",
  1448. "DF_REDIRECTED",
  1449. "DF_DESKCREATED",
  1450. "DF_NEWDISPLAYSETTINGS",
  1451. "DF_TRACKMOUSEHOVER",
  1452. "DF_TRACKMOUSELEAVE",
  1453. "DF_TOOLTIPACTIVE",
  1454. "DF_TOOLTIPSHOWING",
  1455. "DF_HOTTRACKING",
  1456. "DF_DESTROYED",
  1457. "DF_DESKWNDDESTROYED",
  1458. "DF_DYING",
  1459. NULL
  1460. };
  1461. const char* aszWindowStationFlags[] = {
  1462. "WSF_SWITCHLOCK",
  1463. "WSF_OPENLOCK",
  1464. "WSF_NOIO",
  1465. "WSF_SHUTDOWN",
  1466. "WSF_DYING",
  1467. "WSF_REALSHUTDOWN",
  1468. "WSF_CLIPBOARDCHANGED",
  1469. "WSF_INDELAYEDRENDERING",
  1470. NULL
  1471. };
  1472. enum GF_FLAGS {
  1473. GF_SMS,
  1474. GF_TIF,
  1475. GF_QS,
  1476. GF_MF,
  1477. GF_CSF,
  1478. GF_CS,
  1479. GF_QF,
  1480. GF_W32PF,
  1481. GF_HE,
  1482. GF_HDATA,
  1483. GF_XI,
  1484. GF_IIF,
  1485. GF_TMRF,
  1486. GF_SB,
  1487. GF_CHARSETS,
  1488. GF_MENUTYPE,
  1489. GF_MENUSTATE,
  1490. GF_CURSORF,
  1491. GF_MON,
  1492. GF_SI,
  1493. GF_RIP,
  1494. GF_SRVI,
  1495. GF_PROP,
  1496. GF_UPM0,
  1497. GF_KI,
  1498. GF_MI,
  1499. GF_DS,
  1500. GF_WS,
  1501. GF_ES,
  1502. GF_BS,
  1503. GF_CBS,
  1504. GF_SS,
  1505. GF_LBS,
  1506. GF_SBS,
  1507. GF_WSEX,
  1508. GF_CLIENTIMC,
  1509. GF_CONVERSION,
  1510. GF_SENTENCE,
  1511. GF_IMEINIT,
  1512. GF_IMEDIRTY,
  1513. GF_IMECOMPFORM,
  1514. GF_EDUNDO,
  1515. GF_DIAF,
  1516. GF_HIDPROCESSMASK,
  1517. GF_HOOKFLAGS,
  1518. GF_DCXFLAGS,
  1519. GF_DESKTOPFLAGS,
  1520. GF_WINDOWSTATIONFLAGS,
  1521. GF_LPK,
  1522. GF_MAX
  1523. };
  1524. CONST PCSTR* aapszFlag[GF_MAX] = {
  1525. apszSmsFlags,
  1526. apszTifFlags,
  1527. apszQsFlags,
  1528. apszMfFlags,
  1529. apszCsfFlags,
  1530. apszCsFlags,
  1531. apszQfFlags,
  1532. apszW32pfFlags,
  1533. apszHeFlags,
  1534. apszHdataFlags,
  1535. apszXiFlags,
  1536. apszIifFlags,
  1537. apszTmrfFlags,
  1538. apszSbFlags,
  1539. apszCSFlags,
  1540. apszMenuTypeFlags,
  1541. apszMenuStateFlags,
  1542. apszCursorfFlags,
  1543. apszMonfFlags,
  1544. apszSifFlags,
  1545. apszRipFlags,
  1546. apszSRVIFlags,
  1547. apszPROPFlags,
  1548. aszUserPreferencesMask0,
  1549. aszKeyEventFlags,
  1550. aszMouseEventFlags,
  1551. aszDialogStyle,
  1552. aszWindowStyle,
  1553. aszEditStyle,
  1554. aszButtonStyle,
  1555. aszComboBoxStyle,
  1556. aszStaticStyle,
  1557. aszListBoxStyle,
  1558. aszScrollBarStyle,
  1559. aszWindowExStyle,
  1560. aszClientImcFlags,
  1561. aszConversionModes,
  1562. aszSentenceModes,
  1563. aszImeInit,
  1564. aszImeDirtyFlags,
  1565. aszImeCompFormFlags,
  1566. aszEdUndoType,
  1567. aszDeviceInfoActionFlags,
  1568. aszHidProcessMask,
  1569. aszHookFlags,
  1570. aszDcxFlags,
  1571. aszDesktopFlags,
  1572. aszWindowStationFlags,
  1573. apszLpkEntryPoints,
  1574. };
  1575. /************************************************************************\
  1576. * GetFlags
  1577. *
  1578. * Converts a 32bit set of flags into an appropriate string. pszBuf should
  1579. * be large enough to hold this string, no checks are done. pszBuf can be
  1580. * NULL, allowing use of a local static buffer but note that this is not
  1581. * reentrant. Output string has the form: "FLAG1 | FLAG2 ..." or "0".
  1582. *
  1583. * 6/9/1995 Created SanfordS
  1584. \************************************************************************/
  1585. LPSTR GetFlags(
  1586. WORD wType,
  1587. DWORD dwFlags,
  1588. LPSTR pszBuf,
  1589. BOOL fPrintZero)
  1590. {
  1591. static char szT[512];
  1592. WORD i;
  1593. BOOL fFirst = TRUE;
  1594. BOOL fNoMoreNames = FALSE;
  1595. CONST PCSTR *apszFlags;
  1596. LPSTR apszFlagNames[sizeof(DWORD) * 8], pszT;
  1597. const char** ppszNextFlag;
  1598. UINT uFlagsCount, uNextFlag;
  1599. DWORD dwUnnamedFlags, dwLoopFlag;
  1600. DWORD dwShiftBits;
  1601. DWORD dwOrigFlags;
  1602. if (pszBuf == NULL) {
  1603. pszBuf = szT;
  1604. }
  1605. if (!bShowFlagNames) {
  1606. sprintf(pszBuf, "%x", dwFlags);
  1607. return pszBuf;
  1608. }
  1609. if (wType >= GF_MAX) {
  1610. strcpy(pszBuf, "Invalid flag type.");
  1611. return pszBuf;
  1612. }
  1613. /*
  1614. * Initialize output buffer and names array
  1615. */
  1616. *pszBuf = '\0';
  1617. RtlZeroMemory(apszFlagNames, sizeof(apszFlagNames));
  1618. apszFlags = aapszFlag[wType];
  1619. /*
  1620. * Build a sorted array containing the names of the flags in dwFlags
  1621. */
  1622. uFlagsCount = 0;
  1623. dwUnnamedFlags = dwOrigFlags = dwFlags;
  1624. dwLoopFlag = 1;
  1625. dwShiftBits = 0;
  1626. reentry:
  1627. for (i = 0; dwFlags; dwFlags >>= 1, i++, dwLoopFlag <<= 1, ++dwShiftBits) {
  1628. const char* lpszFlagName = NULL;
  1629. /*
  1630. * Bail if we reached the end of the flag names array
  1631. */
  1632. if (apszFlags[i] == NULL) {
  1633. break;
  1634. }
  1635. if (apszFlags[i] == _MASKENUM_START) {
  1636. //
  1637. // Masked enumerative items.
  1638. //
  1639. DWORD en = 0;
  1640. DWORD dwMask = (DWORD)(ULONG_PTR)apszFlags[++i];
  1641. // First, clear up the handled bits.
  1642. dwUnnamedFlags &= ~dwMask;
  1643. lpszFlagName = NULL;
  1644. for (++i; apszFlags[i] != NULL && apszFlags[i] != _MASKENUM_END; ++i, ++en) {
  1645. if ((dwOrigFlags & dwMask) == (en << dwShiftBits )) {
  1646. if (apszFlags[i] != NO_FLAG) {
  1647. lpszFlagName = apszFlags[i];
  1648. }
  1649. }
  1650. }
  1651. //
  1652. // Shift the bits and get ready for the next item.
  1653. // Next item right after _MASKENUM_END holds the bits to shift.
  1654. //
  1655. dwFlags >>= (int)(ULONG_PTR)apszFlags[++i] - 1;
  1656. dwLoopFlag <<= (int)(ULONG_PTR)apszFlags[i] - 1;
  1657. dwShiftBits += (int)(ULONG_PTR)apszFlags[i] - 1;
  1658. if (lpszFlagName == NULL) {
  1659. //
  1660. // Could not find the match. Skip to the next item.
  1661. //
  1662. continue;
  1663. }
  1664. } else if (apszFlags[i] == _CONTINUE_ON) {
  1665. //
  1666. // Refer the other item array. Pointer to the array is stored at [i+1].
  1667. //
  1668. apszFlags = (LPSTR*)apszFlags[i + 1];
  1669. goto reentry;
  1670. } else if (apszFlags[i] == _SHIFT_BITS) {
  1671. //
  1672. // To save some space, just shift some bits..
  1673. //
  1674. dwFlags >>= (int)(ULONG_PTR)apszFlags[++i] - 1;
  1675. dwLoopFlag <<= (int)(ULONG_PTR)apszFlags[i] - 1;
  1676. dwShiftBits += (int)(ULONG_PTR)apszFlags[i] - 1;
  1677. continue;
  1678. } else {
  1679. /*
  1680. * Continue if this bit is not set or we don't have a name for it.
  1681. */
  1682. if (!(dwFlags & 1) || (apszFlags[i] == NO_FLAG)) {
  1683. continue;
  1684. }
  1685. lpszFlagName = apszFlags[i];
  1686. }
  1687. /*
  1688. * Find the sorted position where this name should go
  1689. */
  1690. ppszNextFlag = apszFlagNames;
  1691. uNextFlag = 0;
  1692. while (uNextFlag < uFlagsCount) {
  1693. if (strcmp(*ppszNextFlag, lpszFlagName) > 0) {
  1694. break;
  1695. }
  1696. ppszNextFlag++;
  1697. uNextFlag++;
  1698. }
  1699. /*
  1700. * Insert the new name
  1701. */
  1702. RtlMoveMemory((char*)(ppszNextFlag + 1), ppszNextFlag, (uFlagsCount - uNextFlag) * sizeof(DWORD));
  1703. *ppszNextFlag = lpszFlagName;
  1704. uFlagsCount++;
  1705. /*
  1706. * We got a name so clear it from the unnamed bits.
  1707. */
  1708. dwUnnamedFlags &= ~dwLoopFlag;
  1709. }
  1710. /*
  1711. * Build the string now
  1712. */
  1713. ppszNextFlag = apszFlagNames;
  1714. pszT = pszBuf;
  1715. /*
  1716. * Add the first name
  1717. */
  1718. if (uFlagsCount > 0) {
  1719. pszT += sprintf(pszT, "%s", *ppszNextFlag++);
  1720. uFlagsCount--;
  1721. }
  1722. /*
  1723. * Concatenate all other names with " |"
  1724. */
  1725. while (uFlagsCount > 0) {
  1726. pszT += sprintf(pszT, " | %s", *ppszNextFlag++);
  1727. uFlagsCount--;
  1728. }
  1729. /*
  1730. * If there are unamed bits, add them at the end
  1731. */
  1732. if (dwUnnamedFlags != 0) {
  1733. pszT += sprintf(pszT, " | %#lx", dwUnnamedFlags);
  1734. }
  1735. /*
  1736. * Print zero if needed and asked to do so
  1737. */
  1738. if (fPrintZero && (pszT == pszBuf)) {
  1739. sprintf(pszBuf, "0");
  1740. }
  1741. return pszBuf;
  1742. }
  1743. ///////////////////////////////////////////////////////////////////////////
  1744. //
  1745. // Enumerated items with mask
  1746. //
  1747. ///////////////////////////////////////////////////////////////////////////
  1748. typedef struct {
  1749. LPCSTR name;
  1750. DWORD value;
  1751. } EnumItem;
  1752. #define EITEM(a) { #a, a }
  1753. const EnumItem aClsTypes[] = {
  1754. EITEM(ICLS_BUTTON),
  1755. EITEM(ICLS_EDIT),
  1756. EITEM(ICLS_STATIC),
  1757. EITEM(ICLS_LISTBOX),
  1758. EITEM(ICLS_SCROLLBAR),
  1759. EITEM(ICLS_COMBOBOX),
  1760. EITEM(ICLS_CTL_MAX),
  1761. EITEM(ICLS_DESKTOP),
  1762. EITEM(ICLS_DIALOG),
  1763. EITEM(ICLS_MENU),
  1764. EITEM(ICLS_SWITCH),
  1765. EITEM(ICLS_ICONTITLE),
  1766. EITEM(ICLS_MDICLIENT),
  1767. EITEM(ICLS_COMBOLISTBOX),
  1768. EITEM(ICLS_DDEMLEVENT),
  1769. EITEM(ICLS_DDEMLMOTHER),
  1770. EITEM(ICLS_DDEML16BIT),
  1771. EITEM(ICLS_DDEMLCLIENTA),
  1772. EITEM(ICLS_DDEMLCLIENTW),
  1773. EITEM(ICLS_DDEMLSERVERA),
  1774. EITEM(ICLS_DDEMLSERVERW),
  1775. EITEM(ICLS_IME),
  1776. EITEM(ICLS_TOOLTIP),
  1777. NULL,
  1778. };
  1779. const EnumItem aCharSets[] = {
  1780. EITEM(ANSI_CHARSET),
  1781. EITEM(DEFAULT_CHARSET),
  1782. EITEM(SYMBOL_CHARSET),
  1783. EITEM(SHIFTJIS_CHARSET),
  1784. EITEM(HANGEUL_CHARSET),
  1785. EITEM(HANGUL_CHARSET),
  1786. EITEM(GB2312_CHARSET),
  1787. EITEM(CHINESEBIG5_CHARSET),
  1788. EITEM(OEM_CHARSET),
  1789. EITEM(JOHAB_CHARSET),
  1790. EITEM(HEBREW_CHARSET),
  1791. EITEM(ARABIC_CHARSET),
  1792. EITEM(GREEK_CHARSET),
  1793. EITEM(TURKISH_CHARSET),
  1794. EITEM(VIETNAMESE_CHARSET),
  1795. EITEM(THAI_CHARSET),
  1796. EITEM(EASTEUROPE_CHARSET),
  1797. EITEM(RUSSIAN_CHARSET),
  1798. NULL,
  1799. };
  1800. const EnumItem aImeHotKeys[] = {
  1801. // Windows for Simplified Chinese Edition hot key ID from 0x10 - 0x2F
  1802. EITEM(IME_CHOTKEY_IME_NONIME_TOGGLE),
  1803. EITEM(IME_CHOTKEY_SHAPE_TOGGLE),
  1804. EITEM(IME_CHOTKEY_SYMBOL_TOGGLE),
  1805. // Windows for Japanese Edition hot key ID from 0x30 - 0x4F
  1806. EITEM(IME_JHOTKEY_CLOSE_OPEN),
  1807. // Windows for Korean Edition hot key ID from 0x50 - 0x6F
  1808. EITEM(IME_KHOTKEY_SHAPE_TOGGLE),
  1809. EITEM(IME_KHOTKEY_HANJACONVERT),
  1810. EITEM(IME_KHOTKEY_ENGLISH),
  1811. // Windows for Traditional Chinese Edition hot key ID from 0x70 - 0x8F
  1812. EITEM(IME_THOTKEY_IME_NONIME_TOGGLE),
  1813. EITEM(IME_THOTKEY_SHAPE_TOGGLE),
  1814. EITEM(IME_THOTKEY_SYMBOL_TOGGLE),
  1815. // direct switch hot key ID from 0x100 - 0x11F
  1816. EITEM(IME_HOTKEY_DSWITCH_FIRST),
  1817. EITEM(IME_HOTKEY_DSWITCH_LAST),
  1818. // IME private hot key from 0x200 - 0x21F
  1819. EITEM(IME_ITHOTKEY_RESEND_RESULTSTR),
  1820. EITEM(IME_ITHOTKEY_PREVIOUS_COMPOSITION),
  1821. EITEM(IME_ITHOTKEY_UISTYLE_TOGGLE),
  1822. EITEM(IME_ITHOTKEY_RECONVERTSTRING),
  1823. EITEM(IME_HOTKEY_PRIVATE_LAST),
  1824. NULL,
  1825. };
  1826. const EnumItem aCandidateListStyle[] = {
  1827. EITEM(IME_CAND_UNKNOWN),// 0x0000
  1828. EITEM(IME_CAND_READ),// 0x0001
  1829. EITEM(IME_CAND_CODE),// 0x0002
  1830. EITEM(IME_CAND_MEANING),// 0x0003
  1831. EITEM(IME_CAND_RADICAL),// 0x0004
  1832. EITEM(IME_CAND_STROKE),// 0x0005
  1833. NULL
  1834. };
  1835. // TODO: put charset here
  1836. enum {
  1837. EI_CLSTYPE = 0,
  1838. EI_CHARSETTYPE,
  1839. EI_IMEHOTKEYTYPE,
  1840. EI_IMECANDIDATESTYLE,
  1841. EI_MAX
  1842. };
  1843. typedef struct {
  1844. DWORD dwMask;
  1845. const EnumItem* items;
  1846. } MaskedEnum;
  1847. const MaskedEnum aEnumItems[] = {
  1848. ~0, aClsTypes,
  1849. ~0, aCharSets,
  1850. ~0, aImeHotKeys,
  1851. ~0, aCandidateListStyle,
  1852. };
  1853. LPCSTR GetMaskedEnum(WORD wType, DWORD dwValue, LPSTR buf)
  1854. {
  1855. const EnumItem* item;
  1856. static char ach[32];
  1857. if (wType >= EI_MAX) {
  1858. strcpy(buf, "Invalid type.");
  1859. return buf;
  1860. }
  1861. dwValue &= aEnumItems[wType].dwMask;
  1862. item = aEnumItems[wType].items;
  1863. for (; item->name; ++item) {
  1864. if (item->value == dwValue) {
  1865. if (buf) {
  1866. strcpy(buf, item->name);
  1867. return buf;
  1868. }
  1869. return item->name;
  1870. }
  1871. }
  1872. if (buf) {
  1873. *buf = 0;
  1874. return buf;
  1875. }
  1876. sprintf(ach, "%x", wType);
  1877. return ach;
  1878. }
  1879. #define WM_ITEM(x, fInternal) { x, #x, fInternal }
  1880. CONST struct {
  1881. DWORD msg;
  1882. PCSTR pszMsg;
  1883. BOOLEAN fInternal;
  1884. } gaMsgs[] = {
  1885. #include "wm.txt"
  1886. };
  1887. #undef WM_ITEM
  1888. const char* GetWindowMessageName(UINT wm)
  1889. {
  1890. int i;
  1891. for (i = 0; i < sizeof gaMsgs; ++i) {
  1892. if (wm == gaMsgs[i].msg) {
  1893. if (!gaMsgs[i].fInternal) {
  1894. return gaMsgs[i].pszMsg;
  1895. }
  1896. return "";
  1897. }
  1898. }
  1899. return "";
  1900. }
  1901. const char* GetWindowMessageNameInternal(UINT wm)
  1902. {
  1903. int i;
  1904. for (i = 0; i < sizeof gaMsgs; ++i) {
  1905. if (wm == gaMsgs[i].msg) {
  1906. return gaMsgs[i].pszMsg;
  1907. }
  1908. }
  1909. return "";
  1910. }
  1911. /************************************************************************\
  1912. * Helper Procedures: dso etc.
  1913. *
  1914. * 04/19/2000 Created Hiro
  1915. \************************************************************************/
  1916. // to workaround nosy InitTypeRead
  1917. #define _InitTypeRead(Addr, lpszType) GetShortField(Addr, (PUCHAR)lpszType, 1)
  1918. #define CONTINUE EXCEPTION_EXECUTE_HANDLER
  1919. #define RAISE_EXCEPTION() RaiseException(EXCEPTION_ACCESS_VIOLATION, 0, 0, NULL)
  1920. #define BAD_SYMBOL(symbol) \
  1921. Print("Failed to get %s: bad symbol?\n", symbol); \
  1922. RAISE_EXCEPTION()
  1923. #define CANT_GET_VALUE(symbol, p) \
  1924. Print("Failed to get %s @ 0x%p: invalid address, or memory is paged out?\n", symbol, p); \
  1925. RAISE_EXCEPTION()
  1926. BOOL dso(
  1927. char* szStruct,
  1928. ULONG64 address,
  1929. ULONG dwOption)
  1930. {
  1931. SYM_DUMP_PARAM symDump = {
  1932. sizeof(symDump), szStruct, dwOption, // 0 for default dump like dt
  1933. address,
  1934. NULL, NULL, NULL, 0, NULL
  1935. };
  1936. return Ioctl(IG_DUMP_SYMBOL_INFO, &symDump, symDump.size);
  1937. }
  1938. ULONG64 GetPointer(
  1939. ULONG64 addr)
  1940. {
  1941. ULONG64 p = 0;
  1942. if (!ReadPointer(addr, &p)) {
  1943. CANT_GET_VALUE("a pointer", addr);
  1944. }
  1945. return p;
  1946. }
  1947. DWORD GetDWord(
  1948. ULONG64 addr)
  1949. {
  1950. ULONG64 dw = 0xbaadbaad;
  1951. if (!GetFieldData(addr, "DWORD", NULL, sizeof(dw), &dw)) {
  1952. CANT_GET_VALUE("DWORD", addr);
  1953. }
  1954. return (DWORD)dw;
  1955. }
  1956. WORD GetWord(
  1957. ULONG64 addr)
  1958. {
  1959. ULONG64 w = 0xbaad;
  1960. if (!GetFieldData(addr, "WORD", NULL, sizeof(w), &w)) {
  1961. CANT_GET_VALUE("WORD", addr);
  1962. }
  1963. return (WORD)w;
  1964. }
  1965. BYTE GetByte(
  1966. ULONG64 addr)
  1967. {
  1968. ULONG64 b = 0;
  1969. if (GetFieldData(addr, "BYTE", NULL, sizeof(b), &b)) {
  1970. CANT_GET_VALUE("BYTE", addr);
  1971. }
  1972. return (BYTE)b;
  1973. }
  1974. ULONG
  1975. GetUlongFromAddress(
  1976. ULONG64 Location)
  1977. {
  1978. ULONG Value;
  1979. ULONG result;
  1980. if ((!ReadMemory(Location, &Value, sizeof(ULONG), &result)) ||
  1981. (result < sizeof(ULONG))) {
  1982. Print("GetUlongFromAddress: unable to read from 0x%I64x\n", Location);
  1983. RAISE_EXCEPTION();
  1984. }
  1985. return Value;
  1986. }
  1987. ULONG64 GetGlobalPointer(
  1988. LPSTR symbol)
  1989. {
  1990. ULONG64 pp;
  1991. ULONG64 p = 0;
  1992. pp = EvalExp(symbol);
  1993. if (pp == 0) {
  1994. BAD_SYMBOL(symbol);
  1995. } else if (!ReadPointer(pp, &p)) {
  1996. CANT_GET_VALUE(symbol, pp);
  1997. }
  1998. return p;
  1999. }
  2000. ULONG64 GetGlobalMemberAddress(
  2001. LPSTR symbol,
  2002. LPSTR type,
  2003. LPSTR field)
  2004. {
  2005. ULONG64 pVar = EvalExp(symbol);
  2006. ULONG offset;
  2007. if (pVar == 0) {
  2008. BAD_SYMBOL(symbol);
  2009. }
  2010. if (GetFieldOffset(type, field, &offset)) {
  2011. BAD_SYMBOL(type);
  2012. }
  2013. return pVar + offset;
  2014. }
  2015. ULONG64 GetGlobalMember(
  2016. LPSTR symbol,
  2017. LPSTR type,
  2018. LPSTR field)
  2019. {
  2020. ULONG64 pVar = EvalExp(symbol);
  2021. ULONG64 val;
  2022. if (pVar == 0) {
  2023. BAD_SYMBOL(symbol);
  2024. }
  2025. if (GetFieldValue(pVar, type, field, val)) {
  2026. CANT_GET_VALUE(symbol, pVar);
  2027. }
  2028. return val;
  2029. }
  2030. #if 0
  2031. DWORD GetGlobalDWord(LPSTR symbol)
  2032. {
  2033. ULONG64 pdw;
  2034. ULONG64 dw = 0;
  2035. pdw = EvalExp(symbol);
  2036. if (pdw == 0) {
  2037. BAD_SYMBOL(symbol);
  2038. } else if (!GetFieldData(pdw, "DWORD", NULL, sizeof(dw), &dw)) {
  2039. CANT_GET_VALUE(symbol, pdw);
  2040. }
  2041. return (DWORD)(DWORD_PTR)dw;
  2042. }
  2043. WORD GetGlobalWord(LPSTR symbol)
  2044. {
  2045. ULONG64 pw;
  2046. WORD w = 0;
  2047. pw = EvalExp(symbol);
  2048. if (pw == 0) {
  2049. BAD_SYMBOL(symbol);
  2050. } else if (!GetFieldData(pw, (PUCHAR)"WORD", NULL, sizeof(w), (PVOID)&w)) {
  2051. CANT_GET_VALUE(symbol, pw);
  2052. }
  2053. return w;
  2054. }
  2055. BYTE GetGlobalByte(LPSTR symbol)
  2056. {
  2057. ULONG64 pb;
  2058. BYTE b = 0;
  2059. pb = EvalExp(symbol);
  2060. if (pb == 0) {
  2061. BAD_SYMBOL(symbol);
  2062. } else if (!GetFieldData(pb, (PUCHAR)"BYTE", NULL, sizeof(b), (PVOID)&b)) {
  2063. CANT_GET_VALUE(symbol, pb);
  2064. }
  2065. return b;
  2066. }
  2067. #endif
  2068. ULONG64 GetArrayElement(
  2069. ULONG64 pAddr,
  2070. LPSTR lpszStruc,
  2071. LPSTR lpszField,
  2072. ULONG64 index,
  2073. LPSTR lpszType)
  2074. {
  2075. static ULONG ulOffsetBase, ulSize;
  2076. ULONG64 result = 0;
  2077. if (lpszField) {
  2078. GetFieldOffset(lpszStruc, lpszField, &ulOffsetBase);
  2079. ulSize = GetTypeSize(lpszType);
  2080. }
  2081. ReadMemory(pAddr + ulOffsetBase + ulSize * index, &result, ulSize, NULL);
  2082. return result;
  2083. }
  2084. ULONG64 GetArrayElementPtr(
  2085. ULONG64 pAddr,
  2086. LPSTR lpszStruc,
  2087. LPSTR lpszField,
  2088. ULONG64 index)
  2089. {
  2090. static ULONG ulOffsetBase, ulSize;
  2091. ULONG64 result = 0;
  2092. if (lpszField) {
  2093. GetFieldOffset(lpszStruc, lpszField, &ulOffsetBase);
  2094. }
  2095. if (ulSize == 0) {
  2096. ulSize = GetTypeSize("PVOID");
  2097. }
  2098. ReadPointer(pAddr + ulOffsetBase + ulSize * index, &result);
  2099. return result;
  2100. }
  2101. /*
  2102. * Show progress in time consuming commands
  2103. * 10/15/2000 hiroyama
  2104. */
  2105. VOID ShowProgress(
  2106. VOID)
  2107. {
  2108. static int i = 0;
  2109. static const char* clock[] = {
  2110. "\r-\r",
  2111. "\r\\\r",
  2112. "\r|\r",
  2113. "\r/\r",
  2114. };
  2115. /*
  2116. * Show the progress :-)
  2117. */
  2118. Print(clock[i++ % ARRAY_SIZE(clock)]);
  2119. }
  2120. #define DOWNCAST(type, value) ((type)(ULONG_PTR)(value))
  2121. #ifdef KERNEL
  2122. BOOL HasValidSymbols(VOID)
  2123. {
  2124. if (EvalExp(VAR(gptiRit))) {
  2125. return TRUE;
  2126. }
  2127. return FALSE;
  2128. }
  2129. #endif
  2130. /*
  2131. * IsChk: returns TRUE if the window manager is CHK,
  2132. * could return TRUE regardless the entire system is FRE.
  2133. */
  2134. int gfChk = -1;
  2135. BOOL IsChk(VOID)
  2136. {
  2137. ULONG64 psi;
  2138. if (gfChk != -1) {
  2139. return gfChk;
  2140. }
  2141. psi = GetGlobalPointer(SYM(gpsi));
  2142. if (psi == 0) {
  2143. Print("Cannot get gpsi, assuming chk\n");
  2144. return TRUE;
  2145. }
  2146. if ((DWORD)GetArrayElement(psi, SYM(SERVERINFO), "aiSysMet", SM_DEBUG, "DWORD")) {
  2147. return gfChk = TRUE;
  2148. }
  2149. return gfChk = FALSE;
  2150. }
  2151. #ifdef KERNEL
  2152. /*
  2153. * Debugger specific object routines:
  2154. * copied from ntos/tools/kdexts2/precomp.h
  2155. * (and fixed bugs)
  2156. */
  2157. ULONG gObjectHeaderOffset;
  2158. __inline
  2159. ULONG64
  2160. KD_OBJECT_TO_OBJECT_HEADER(
  2161. ULONG64 o)
  2162. {
  2163. if (gObjectHeaderOffset == 0 && GetFieldOffset("nt!_OBJECT_HEADER", "Body", &gObjectHeaderOffset)) {
  2164. return 0;
  2165. }
  2166. return o - gObjectHeaderOffset;
  2167. }
  2168. __inline
  2169. ULONG64
  2170. KD_OBJECT_HEADER_TO_OBJECT(
  2171. ULONG64 o)
  2172. {
  2173. if (gObjectHeaderOffset && GetFieldOffset("nt!_OBJECT_HEADER", "Body", &gObjectHeaderOffset)) {
  2174. return 0;
  2175. }
  2176. return o + gObjectHeaderOffset;
  2177. }
  2178. __inline
  2179. VOID
  2180. KD_OBJECT_HEADER_TO_QUOTA_INFO(
  2181. ULONG64 oh,
  2182. PULONG64 pOutH
  2183. )
  2184. {
  2185. ULONG QuotaInfoOffset=0;
  2186. GetFieldValue(oh, "nt!__OBJECT_HEADER", "QuotaInfoOffset", QuotaInfoOffset);
  2187. *pOutH = (QuotaInfoOffset == 0 ? 0 : ((oh) - QuotaInfoOffset));
  2188. }
  2189. __inline
  2190. VOID
  2191. KD_OBJECT_HEADER_TO_HANDLE_INFO (
  2192. ULONG64 oh,
  2193. PULONG64 pOutH
  2194. )
  2195. {
  2196. ULONG HandleInfoOffset=0;
  2197. GetFieldValue(oh, "nt!__OBJECT_HEADER", "HandleInfoOffset", HandleInfoOffset);
  2198. *pOutH = (HandleInfoOffset == 0 ? 0 : ((oh) - HandleInfoOffset));
  2199. }
  2200. __inline
  2201. VOID
  2202. KD_OBJECT_HEADER_TO_NAME_INFO(
  2203. ULONG64 oh,
  2204. PULONG64 pOutH
  2205. )
  2206. {
  2207. ULONG NameInfoOffset=0;
  2208. GetFieldValue(oh, "nt!_OBJECT_HEADER", "NameInfoOffset", NameInfoOffset);
  2209. *pOutH = (NameInfoOffset == 0 ? 0 : ((oh) - NameInfoOffset));
  2210. }
  2211. #if 0
  2212. __inline
  2213. VOID
  2214. KD_OBJECT_HEADER_TO_CREATOR_INFO(
  2215. ULONG64 oh,
  2216. PULONG64 pOutH
  2217. )
  2218. {
  2219. ULONG Flags=0;
  2220. GetFieldValue(oh, "_OBJECT_HEADER", "Flags", Flags);
  2221. *pOutH = ((Flags & OB_FLAG_CREATOR_INFO) == 0 ? 0 : ((oh) - GetTypeSize("_OBJECT_HEADER_CREATOR_INFO")));
  2222. }
  2223. #endif
  2224. /*
  2225. * Object helper routines
  2226. */
  2227. #endif
  2228. #ifdef KERNEL
  2229. /************************************************************************\
  2230. * Procedure: GetObjectName
  2231. * Get the generic object name (not a file, symlink etc.)
  2232. *
  2233. * 10/15/2000 Hiroyama Created
  2234. \************************************************************************/
  2235. VOID GetObjectName(
  2236. ULONG64 ptr,
  2237. LPWSTR pwsz,
  2238. ULONG cchMax)
  2239. {
  2240. PTR pHead;
  2241. PTR pNameInfo;
  2242. PTR pBuffer;
  2243. PTR length;
  2244. WCHAR ach[80];
  2245. pwsz[0] = 0;
  2246. pHead = KD_OBJECT_TO_OBJECT_HEADER(ptr);
  2247. DEBUGPRINT("pHead=%p\n", pHead);
  2248. if (pHead == NULL_PTR) {
  2249. return;
  2250. }
  2251. KD_OBJECT_HEADER_TO_NAME_INFO(pHead, &pNameInfo);
  2252. DEBUGPRINT("pNameInfo=%p\n", pNameInfo);
  2253. if (pNameInfo == NULL_PTR) {
  2254. return;
  2255. }
  2256. GetFieldValue(pNameInfo, "nt!_OBJECT_HEADER_NAME_INFO", "Name.Buffer", pBuffer);
  2257. DEBUGPRINT("pBuffer=%p\n", pBuffer);
  2258. if (pBuffer == NULL_PTR) {
  2259. return;
  2260. }
  2261. GetFieldValue(pNameInfo, "nt!_OBJECT_HEADER_NAME_INFO", "Name.Length", length);
  2262. DEBUGPRINT("length=%x\n", length);
  2263. if (length == 0) {
  2264. return;
  2265. }
  2266. move(ach, pBuffer);
  2267. wcsncpy(pwsz, ach, cchMax);
  2268. pwsz[min(cchMax - 1, length / sizeof(WCHAR))] = 0;
  2269. }
  2270. /************************************************************************\
  2271. * Procedure: GetProcessName
  2272. *
  2273. * 06/27/97 GerardoB Created
  2274. *
  2275. \************************************************************************/
  2276. BOOL
  2277. GetProcessName(
  2278. PTR pEProcess,
  2279. LPWSTR lpBuffer)
  2280. {
  2281. UCHAR ImageFileName[16];
  2282. if (!GetFieldValue(pEProcess, "nt!EPROCESS", "ImageFileName", ImageFileName)) {
  2283. swprintf(lpBuffer, L"%.16hs", ImageFileName);
  2284. return TRUE;
  2285. } else {
  2286. Print("Unable to read _EPROCESS at %p\n", pEProcess);
  2287. return FALSE;
  2288. }
  2289. }
  2290. /************************************************************************\
  2291. * GetAppName
  2292. *
  2293. * 10/6/1995 Created JimA
  2294. \************************************************************************/
  2295. BOOL
  2296. GetAppName(
  2297. PTR pEThread,
  2298. PTR pti,
  2299. LPWSTR lpBuffer,
  2300. DWORD cbBuffer)
  2301. {
  2302. PTR pstrAppName = 0;
  2303. PTR Buffer;
  2304. USHORT Length;
  2305. BOOL fRead = FALSE;
  2306. GetFieldValue(pti, SYM(THREADINFO), "pstrAppName", pstrAppName);
  2307. if (pstrAppName != 0) {
  2308. if (!GetFieldValue(pstrAppName, SYM(UNICODE_STRING), "Buffer", Buffer)) {
  2309. GetFieldValue(pstrAppName, SYM(UNICODE_STRING), "Length", Length);
  2310. cbBuffer = min(cbBuffer - sizeof(WCHAR), Length);
  2311. if (tryMoveBlock(lpBuffer, Buffer, cbBuffer)) {
  2312. lpBuffer[cbBuffer / sizeof(WCHAR)] = 0;
  2313. fRead = TRUE;
  2314. }
  2315. }
  2316. } else {
  2317. PTR pEProcess;
  2318. GetFieldValue(pEThread, "nt!ETHREAD", "ThreadsProcess", pEProcess);
  2319. fRead = GetProcessName(pEProcess, lpBuffer);
  2320. }
  2321. if (!fRead) {
  2322. wcsncpy(lpBuffer, L"<unknown name>", cbBuffer / sizeof(WCHAR));
  2323. }
  2324. return fRead;
  2325. }
  2326. #define INVALID_SESSION_ID ((ULONG)0xbadbad)
  2327. BOOL _GetProcessSessionId(PTR Process, PULONG SessionId)
  2328. {
  2329. PTR SessionPointer;
  2330. *SessionId = INVALID_SESSION_ID;
  2331. GetFieldValue(Process, "nt!_EPROCESS", "Session", SessionPointer);
  2332. if (SessionPointer != NULL_PTR) {
  2333. if (GetFieldValue(SessionPointer, "nt!_MM_SESSION_SPACE",
  2334. "SessionId", *SessionId)) {
  2335. Print("Could not find _MM_SESSION_SPACE type at %p.\n", SessionPointer);
  2336. return FALSE;
  2337. }
  2338. }
  2339. return TRUE;
  2340. }
  2341. ULONG GetProcessSessionId(PTR Process)
  2342. {
  2343. ULONG sid;
  2344. _GetProcessSessionId(Process, &sid);
  2345. return sid;
  2346. }
  2347. #endif // KERNEL
  2348. #ifdef OLD_DEBUGGER
  2349. #ifdef KERNEL
  2350. /************************************************************************\
  2351. * PrintMessages
  2352. *
  2353. * Prints out qmsg structures.
  2354. *
  2355. * 6/9/1995 Created SanfordS
  2356. \************************************************************************/
  2357. BOOL PrintMessages(
  2358. PQMSG pqmsgRead)
  2359. {
  2360. QMSG qmsg;
  2361. ASYNCSENDMSG asm;
  2362. char *aszEvents[] = {
  2363. "MSG", // QEVENT_MESSAGE
  2364. "SHO", // QEVENT_SHOWWINDOW"
  2365. "CMD", // QEVENT_CANCLEMODE"
  2366. "SWP", // QEVENT_SETWINDOWPOS"
  2367. "UKS", // QEVENT_UPDATEKEYSTATE"
  2368. "DEA", // QEVENT_DEACTIVATE"
  2369. "ACT", // QEVENT_ACTIVATE"
  2370. "PST", // QEVENT_POSTMESSAGE"
  2371. "EXE", // QEVENT_EXECSHELL"
  2372. "CMN", // QEVENT_CANCELMENU"
  2373. "DSW", // QEVENT_DESTROYWINDOW"
  2374. "ASY", // QEVENT_ASYNCSENDMSG"
  2375. "HNG", // QEVENT_HUNGTHREAD"
  2376. "CMT", // QEVENT_CANCELMOUSEMOVETRK"
  2377. "NWE", // QEVENT_NOTIFYWINEVENT"
  2378. "RAC", // QEVENT_RITACCESSIBILITY"
  2379. "RSO", // QEVENT_RITSOUND"
  2380. "? ", // "?"
  2381. "? ", // "?"
  2382. "? " // "?"
  2383. };
  2384. #define NQEVENT (ARRAY_SIZE(aszEvents))
  2385. Print("typ pqmsg hwnd msg wParam lParam time ExInfo dwQEvent pti\n");
  2386. Print("-------------------------------------------------------------------------------\n");
  2387. SAFEWHILE (TRUE) {
  2388. move(qmsg, FIXKP(pqmsgRead));
  2389. if (qmsg.dwQEvent < NQEVENT) {
  2390. Print("%s %08lx ", aszEvents[qmsg.dwQEvent], pqmsgRead);
  2391. } else {
  2392. Print("??? %08lx ", pqmsgRead);
  2393. }
  2394. switch (qmsg.dwQEvent) {
  2395. case QEVENT_ASYNCSENDMSG:
  2396. move(asm, (PVOID)qmsg.msg.wParam);
  2397. Print("%07lx %04lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  2398. asm.hwnd, asm.message, asm.wParam, asm.lParam,
  2399. qmsg.msg.time, qmsg.ExtraInfo, qmsg.dwQEvent, qmsg.pti);
  2400. break;
  2401. case 0:
  2402. default:
  2403. Print("%07lx %04lx %08lx %08lx %08lx %08lx %08lx %08lx\n",
  2404. qmsg.msg.hwnd, qmsg.msg.message, qmsg.msg.wParam, qmsg.msg.lParam,
  2405. qmsg.msg.time, qmsg.ExtraInfo, qmsg.dwQEvent, qmsg.pti);
  2406. break;
  2407. }
  2408. if (qmsg.pqmsgNext != NULL) {
  2409. if (pqmsgRead == qmsg.pqmsgNext) {
  2410. Print("loop found in message list!");
  2411. return FALSE;
  2412. }
  2413. pqmsgRead = qmsg.pqmsgNext;
  2414. } else {
  2415. return TRUE;
  2416. }
  2417. }
  2418. return TRUE;
  2419. }
  2420. #endif // KERNEL
  2421. #endif // OLD_DEBUGGER
  2422. /************************************************************************\
  2423. * GetAndDumpHE
  2424. *
  2425. * Dumps given handle (dwT) and returns its phe.
  2426. *
  2427. * 6/9/1995 Documented SanfordS
  2428. \************************************************************************/
  2429. BOOL
  2430. GetAndDumpHE(
  2431. PTR dwT,
  2432. PPTR phe,
  2433. BOOL fPointerTest)
  2434. {
  2435. DWORD dw;
  2436. PTR pheT, phead;
  2437. PTR pshi, psi, h;
  2438. ULONG_PTR cHandleEntries;
  2439. /*
  2440. * Evaluate the argument string and get the address of the object to
  2441. * dump. Take either a handle or a pointer to the object.
  2442. */
  2443. dw = HMIndexFromHandle(dwT);
  2444. /*
  2445. * First see if it is a pointer because the handle index is only part of
  2446. * the 32 bit DWORD, and we may mistake a pointer for a handle.
  2447. */
  2448. if (!fPointerTest && IS_PTR(dwT)) {
  2449. if (GetFieldValue(dwT, SYM(HEAD), "h", h) == 0) {
  2450. if (GetAndDumpHE(h, phe, TRUE)) {
  2451. return TRUE;
  2452. }
  2453. }
  2454. }
  2455. /*
  2456. * Is it a handle? Does its index fit our table length?
  2457. */
  2458. GETSHAREDINFO(pshi);
  2459. GetFieldValue(pshi, SYM(SHAREDINFO), "psi", psi);
  2460. GetFieldValue(psi, SYM(SERVERINFO), "cHandleEntries", cHandleEntries);
  2461. if (dw >= cHandleEntries) {
  2462. return FALSE;
  2463. }
  2464. /*
  2465. * Grab the handle entry and see if it is ok.
  2466. */
  2467. GetFieldValue(pshi, SYM(SHAREDINFO), "aheList", pheT);
  2468. pheT += (dw * GetTypeSize("HANDLEENTRY"));
  2469. *phe = pheT;
  2470. /*
  2471. * If the type is too big, it's not a handle.
  2472. */
  2473. _InitTypeRead(pheT, SYM(HANDLEENTRY));
  2474. if (ReadField(bType) >= TYPE_CTYPES) {
  2475. pheT = 0;
  2476. } else {
  2477. phead = ReadField(phead);
  2478. if (ReadField(bType) != TYPE_FREE) {
  2479. /*
  2480. * See if the object references this handle entry: the clincher
  2481. * for a handle, if it is not FREE.
  2482. */
  2483. GetFieldValue(phead, SYM(HEAD), "h", h);
  2484. if (HMIndexFromHandle(h) != dw)
  2485. pheT = 0;
  2486. }
  2487. }
  2488. if (pheT == 0) {
  2489. if (!fPointerTest) {
  2490. Print("0x%p is not a valid object or handle.\n", dwT);
  2491. }
  2492. return FALSE;
  2493. }
  2494. /*
  2495. * Dump the ownership info and the handle entry info
  2496. */
  2497. GetFieldValue(phead, SYM(HEAD), "h", h);
  2498. #ifdef Idhe
  2499. Idhe(0, h, 0);
  2500. #endif
  2501. Print("\n");
  2502. return TRUE;
  2503. }
  2504. /************************************************************************\
  2505. * HtoHE
  2506. *
  2507. * Extracts HE and phe from given handle. Handle can be just an index.
  2508. * Assumes h is a valid handle. Returns FALSE only if it's totally wacko.
  2509. *
  2510. * 6/9/1995 Created SanfordS
  2511. \************************************************************************/
  2512. BOOL HtoHE(
  2513. PTR h,
  2514. PTR *pphe OPTIONAL)
  2515. {
  2516. PTR psi;
  2517. PTR pheT;
  2518. PTR cHandleEntries;
  2519. DWORD index;
  2520. index = HMIndexFromHandle(h);
  2521. GETSHAREDINFO(psi);
  2522. if (psi == 0) {
  2523. RAISE_EXCEPTION();
  2524. }
  2525. if (GetFieldValue(psi, SYM(SHAREDINFO), "aheList", pheT)) {
  2526. DEBUGPRINT("HtoHE(%I64x): Couldn't get aheList. Bad symbols?\n", h);
  2527. return FALSE;
  2528. }
  2529. if (GetFieldValue(psi, SYM(SHAREDINFO), "psi", psi)) {
  2530. DEBUGPRINT("HtoHE(%I64x): Couldn't get psi. Bad symbols?\n", h);
  2531. return FALSE;
  2532. }
  2533. if (GetFieldValue(psi, SYM(SERVERINFO), "cHandleEntries", cHandleEntries)) {
  2534. DEBUGPRINT("HtoHE(%I64x): Couldn't get cHandleEntries. Bad symbols?\n", h);
  2535. return FALSE;
  2536. }
  2537. if (index >= cHandleEntries) {
  2538. DEBUGPRINT("HtoHE(%I64x): index %d is too large.\n", h, index);
  2539. return FALSE;
  2540. }
  2541. pheT += index * GetTypeSize(SYM(HANDLEENTRY));
  2542. if (pphe != NULL) {
  2543. *pphe = pheT;
  2544. }
  2545. return TRUE;
  2546. }
  2547. /************************************************************************\
  2548. * GetPfromH
  2549. *
  2550. * Converts a handle to a pointer and extracts he and phe info. Returns a
  2551. * pointer to the object's HANDLEENTRY or NULL on failure.
  2552. *
  2553. * 6/9/1995 Created SanfordS
  2554. \************************************************************************/
  2555. ULONG64 GetPfromH(
  2556. PTR h,
  2557. PTR *pphe OPTIONAL)
  2558. {
  2559. PTR pheT;
  2560. PTR phead;
  2561. if (!HtoHE(h, &pheT)) {
  2562. DEBUGPRINT("GetPfromH(%p): failed to get HE.\n", h);
  2563. return 0;
  2564. }
  2565. if (GetFieldValue(pheT, SYM(HANDLEENTRY), "phead", phead)) {
  2566. DEBUGPRINT("GetPfromH(%p): failed to get phead.\n", h);
  2567. return 0;
  2568. }
  2569. if (pphe != NULL) {
  2570. *pphe = pheT;
  2571. }
  2572. return FIXKP(phead);
  2573. }
  2574. /************************************************************************\
  2575. * getHEfromP
  2576. *
  2577. * Converts a pointer to a handle and extracts the he and phe info.
  2578. *
  2579. * 6/9/1995 Created SanfordS
  2580. \************************************************************************/
  2581. BOOL getHEfromP(
  2582. PTR *pphe,
  2583. PTR p)
  2584. {
  2585. PTR pLookup, h;
  2586. p = FIXKP(p);
  2587. GetFieldValue(p, SYM(THROBJHEAD), "h", h);
  2588. pLookup = GetPfromH(h, pphe);
  2589. if (FIXKP(pLookup) != p) {
  2590. DEBUGPRINT("getHEfromP(%p): invalid.\n", p);
  2591. return FALSE;
  2592. }
  2593. return TRUE;
  2594. }
  2595. /************************************************************************\
  2596. * HorPtoP
  2597. *
  2598. * Generic function to accept either a user handle or pointer value and
  2599. * validate it and convert it to a pointer. type=-1 to allow any non-free
  2600. * type. type=-2 to allow any type.
  2601. *
  2602. * 6/9/1995 Created SanfordS
  2603. \************************************************************************/
  2604. ULONG64 HorPtoP(
  2605. PTR p,
  2606. int type)
  2607. {
  2608. PTR phe;
  2609. PTR pT;
  2610. PTR phead;
  2611. int bType;
  2612. if (p == 0) {
  2613. return 0;
  2614. }
  2615. p = FIXKP(p);
  2616. if (ReadPointer(p, &pT) && getHEfromP(&phe, p)) {
  2617. /*
  2618. * It was a pointer
  2619. */
  2620. GetFieldValue(phe, SYM(HANDLEENTRY), "bType", bType);
  2621. if ((type == -2 || bType != TYPE_FREE) &&
  2622. bType < TYPE_CTYPES &&
  2623. (type < 0 || bType == type)) {
  2624. GetFieldValue(phe, SYM(HANDLEENTRY), "phead", phead);
  2625. return FIXKP(phead);
  2626. }
  2627. }
  2628. pT = GetPfromH(p, NULL);
  2629. if (pT == 0) {
  2630. Print("WARNING: dumping %p even though it's not a valid pointer or handle!\n", (ULONG_PTR)p);
  2631. return p; // let it pass anyway so we can see how it got corrupted.
  2632. }
  2633. return FIXKP(pT);
  2634. }
  2635. /************************************************************************\
  2636. * Procedure: DebugGetWindowTextA
  2637. *
  2638. * Description: Places pwnd title into achDest.
  2639. *
  2640. * 06/09/1995 Created SanfordS
  2641. * 11/18/2000 Added dwLength parameter JasonSch
  2642. *
  2643. \************************************************************************/
  2644. BOOL DebugGetWindowTextA(
  2645. PTR pwnd,
  2646. char *achDest,
  2647. DWORD dwLength)
  2648. {
  2649. ULONG Length;
  2650. PTR Buffer;
  2651. WCHAR *lpwstr;
  2652. if (pwnd == 0) {
  2653. achDest[0] = '\0';
  2654. return FALSE;
  2655. }
  2656. pwnd = FIXKP(pwnd);
  2657. if (GetFieldValue(pwnd, SYM(WND), "strName.Length", Length) ||
  2658. GetFieldValue(pwnd, SYM(WND), "strName.Buffer", Buffer)) {
  2659. strcpy(achDest, "<< Can't get WND >>");
  2660. return FALSE;
  2661. }
  2662. if (Length == 0) {
  2663. strcpy(achDest, "<null>");
  2664. } else {
  2665. ULONG cbText = min(dwLength - 1, Length + sizeof(WCHAR));
  2666. lpwstr = LocalAlloc(LPTR, cbText);
  2667. if (!(tryMoveBlock(lpwstr, FIXKP(Buffer), cbText))) {
  2668. strcpy(achDest, "<< Can't get title >>");
  2669. LocalFree(lpwstr);
  2670. return FALSE;
  2671. }
  2672. RtlUnicodeToMultiByteN(achDest, dwLength, NULL, lpwstr, cbText);
  2673. achDest[cbText] = '\0';
  2674. LocalFree(lpwstr);
  2675. }
  2676. return TRUE;
  2677. }
  2678. /************************************************************************\
  2679. * DebugGetClassNameA
  2680. *
  2681. * Placed pcls name into achDest. No checks for size are made.
  2682. *
  2683. * 6/9/1995 Created SanfordS
  2684. \************************************************************************/
  2685. BOOL DebugGetClassNameA(
  2686. PTR lpszClassName,
  2687. char *achDest)
  2688. {
  2689. CHAR ach[80];
  2690. if (lpszClassName == 0) {
  2691. strcpy(achDest, "<null>");
  2692. } else {
  2693. if (!tryMove(ach, FIXKP(lpszClassName))) {
  2694. strcpy(achDest, "<inaccessible>");
  2695. } else {
  2696. strcpy(achDest, ach);
  2697. }
  2698. strcpy(achDest, ach);
  2699. }
  2700. return TRUE;
  2701. }
  2702. /************************************************************************\
  2703. * PrintBitField, PrintEndBitField
  2704. *
  2705. * Printout specified boolean value in a structure. Assuming
  2706. * strlen(pszFieldName) will not exceeds BF_COLUMN_WIDTH.
  2707. *
  2708. * 10/12/1997 Created HiroYama
  2709. \************************************************************************/
  2710. VOID PrintBitField(
  2711. LPSTR pszFieldName,
  2712. BOOL fValue)
  2713. {
  2714. int iWidth;
  2715. int iStart = giBFColumn;
  2716. sprintf(gach1, fValue ? "*%-s " : " %-s ", pszFieldName);
  2717. iWidth = (strlen(gach1) + BF_COLUMN_WIDTH - 1) / BF_COLUMN_WIDTH;
  2718. iWidth *= BF_COLUMN_WIDTH;
  2719. if ((giBFColumn += iWidth) >= BF_MAX_WIDTH) {
  2720. giBFColumn = iWidth;
  2721. Print("%s\n", gaBFBuff);
  2722. iStart = 0;
  2723. }
  2724. sprintf(gaBFBuff + iStart, "%-*s", iWidth, gach1);
  2725. }
  2726. VOID PrintEndBitField(
  2727. VOID)
  2728. {
  2729. if (giBFColumn != 0) {
  2730. giBFColumn = 0;
  2731. Print("%s\n", gaBFBuff);
  2732. }
  2733. }
  2734. LPCSTR pszObjStr[] = {
  2735. "Free",
  2736. "Window",
  2737. "Menu",
  2738. "Cursor",
  2739. "SetWindowPos",
  2740. "Hook",
  2741. "Thread Info",
  2742. "Clip Data",
  2743. "Call Proc",
  2744. "Accel Table",
  2745. "WindowStation",
  2746. "DeskTop",
  2747. "DdeAccess",
  2748. "DdeConv",
  2749. "DdeExact",
  2750. "Monitor",
  2751. "Ctypes",
  2752. "Console",
  2753. "Generic"
  2754. };
  2755. #ifdef KERNEL
  2756. /***********************************************************************\
  2757. * GetGdiHandleType
  2758. *
  2759. * Returns a static buffer address which will contain a > 0 length string
  2760. * if the type makes sense.
  2761. *
  2762. * 12/1/1995 Created SanfordS
  2763. \***********************************************************************/
  2764. LPCSTR GetGDIHandleType(
  2765. HOBJ ho)
  2766. {
  2767. ULONG64 pent; // base address of hmgr entries
  2768. ULONG ulTemp;
  2769. static CHAR szT[20];
  2770. ULONG gcMaxHmgr, index;
  2771. DWORD dwEntrySize = GetTypeSize(SYM(ENTRY));
  2772. // filched from gre\hmgr.h
  2773. #define INDEX_MASK ((1 << INDEX_BITS) - 1)
  2774. #define HmgIfromH(h) ((ULONG)(h) & INDEX_MASK)
  2775. szT[0] = '\0';
  2776. pent = GetGlobalPointer(VAR(gpentHmgr));
  2777. moveExpValue(&gcMaxHmgr, VAR(gcMaxHmgr));
  2778. index = HmgIfromH((ULONG_PTR) ho);
  2779. if (index > gcMaxHmgr) {
  2780. return szT;
  2781. }
  2782. _InitTypeRead(pent + index * dwEntrySize, SYM(ENTRY));
  2783. if ((USHORT)ReadField(FullUnique) != ((ULONG_PTR)ho >> 16)) {
  2784. return szT;
  2785. }
  2786. if ((HOBJ)ReadField(einfo.pobj.hHmgr) != ho) {
  2787. return szT;
  2788. }
  2789. ulTemp = (ULONG) ReadField(Objt);
  2790. switch(ulTemp) {
  2791. case DEF_TYPE:
  2792. strcpy(szT, "DEF");
  2793. break;
  2794. case DC_TYPE:
  2795. strcpy(szT, "DC");
  2796. break;
  2797. case RGN_TYPE:
  2798. strcpy(szT, "RGN");
  2799. break;
  2800. case SURF_TYPE:
  2801. strcpy(szT, "SURF");
  2802. break;
  2803. case PATH_TYPE:
  2804. strcpy(szT, "PATH");
  2805. break;
  2806. case PAL_TYPE:
  2807. strcpy(szT, "PAL");
  2808. break;
  2809. case ICMLCS_TYPE:
  2810. strcpy(szT, "ICMLCS");
  2811. break;
  2812. case LFONT_TYPE:
  2813. strcpy(szT, "LFONT");
  2814. break;
  2815. case RFONT_TYPE:
  2816. strcpy(szT, "RFONT");
  2817. break;
  2818. case PFE_TYPE:
  2819. strcpy(szT, "PFE");
  2820. break;
  2821. case PFT_TYPE:
  2822. strcpy(szT, "PFT");
  2823. break;
  2824. case ICMCXF_TYPE:
  2825. strcpy(szT, "ICMCXF");
  2826. break;
  2827. case SPRITE_TYPE:
  2828. strcpy(szT, "SPRITE");
  2829. break;
  2830. case SPACE_TYPE:
  2831. strcpy(szT, "SPACE");
  2832. break;
  2833. case META_TYPE:
  2834. strcpy(szT, "META");
  2835. break;
  2836. case EFSTATE_TYPE:
  2837. strcpy(szT, "EFSTATE");
  2838. break;
  2839. case BMFD_TYPE:
  2840. strcpy(szT, "BMFD");
  2841. break;
  2842. case VTFD_TYPE:
  2843. strcpy(szT, "VTFD");
  2844. break;
  2845. case TTFD_TYPE:
  2846. strcpy(szT, "TTFD");
  2847. break;
  2848. case RC_TYPE:
  2849. strcpy(szT, "RC");
  2850. break;
  2851. case TEMP_TYPE:
  2852. strcpy(szT, "TEMP");
  2853. break;
  2854. case DRVOBJ_TYPE:
  2855. strcpy(szT, "DRVOBJ");
  2856. break;
  2857. case DCIOBJ_TYPE:
  2858. strcpy(szT, "DCIOBJ");
  2859. break;
  2860. case SPOOL_TYPE:
  2861. strcpy(szT, "SPOOL");
  2862. break;
  2863. default:
  2864. ulTemp = LO_TYPE((USHORT)ReadField(FullUnique) << TYPE_SHIFT);
  2865. switch (ulTemp) {
  2866. case LO_BRUSH_TYPE:
  2867. strcpy(szT, "BRUSH");
  2868. break;
  2869. case LO_PEN_TYPE:
  2870. strcpy(szT, "LO_PEN");
  2871. break;
  2872. case LO_EXTPEN_TYPE:
  2873. strcpy(szT, "LO_EXTPEN");
  2874. break;
  2875. case CLIENTOBJ_TYPE:
  2876. strcpy(szT, "CLIENTOBJ");
  2877. break;
  2878. case LO_METAFILE16_TYPE:
  2879. strcpy(szT, "LO_METAFILE16");
  2880. break;
  2881. case LO_METAFILE_TYPE:
  2882. strcpy(szT, "LO_METAFILE");
  2883. break;
  2884. case LO_METADC16_TYPE:
  2885. strcpy(szT, "LO_METADC16");
  2886. break;
  2887. }
  2888. }
  2889. return szT;
  2890. }
  2891. #endif // KERNEL
  2892. VOID DirectAnalyze(
  2893. ULONG_PTR dw,
  2894. ULONG_PTR adw,
  2895. BOOL fNoSym)
  2896. {
  2897. DWORD index, cHandleEntries, dwHESize, dwHandleOffset;
  2898. ULONG64 dwOffset, pshi, psi, phe;
  2899. WORD uniq, w, aw;
  2900. CHAR ach[80];
  2901. #ifdef KERNEL
  2902. LPCSTR psz;
  2903. #endif
  2904. GETSHAREDINFO(pshi);
  2905. GetFieldValue(pshi, SYM(SHAREDINFO), "psi", psi);
  2906. dwHESize = GetTypeSize(SYM(HANDLEENTRY));
  2907. GetFieldOffset(SYM(SHAREDINFO), "aheList", &dwHandleOffset);
  2908. if (HIWORD(dw) != 0) {
  2909. /*
  2910. * See if its a handle
  2911. */
  2912. index = HMIndexFromHandle((ULONG)dw);
  2913. GetFieldValue(psi, SYM(SERVERINFO), "cHandleEntries", cHandleEntries);
  2914. if (index < cHandleEntries) {
  2915. uniq = HMUniqFromHandle(dw);
  2916. ReadPointer(pshi + dwHandleOffset, &phe);
  2917. phe += index * dwHESize;
  2918. _InitTypeRead(phe, SYM(HANDLEENTRY));
  2919. if (((WORD)ReadField(wUniq)) == uniq) {
  2920. Print("= a %s handle. ", pszObjStr[(ULONG)ReadField(bType)]);
  2921. fNoSym = TRUE;
  2922. }
  2923. }
  2924. #ifdef KERNEL
  2925. /*
  2926. * See if it's a GDI object handle
  2927. */
  2928. psz = GetGDIHandleType((HOBJ)dw);
  2929. if (*psz) {
  2930. Print("= a GDI %s type handle. ", psz);
  2931. fNoSym = TRUE;
  2932. }
  2933. #endif // KERNEL
  2934. /*
  2935. * See if it's an object pointer
  2936. */
  2937. if (_InitTypeRead(dw, SYM(HEAD))) {
  2938. if ((ULONG)ReadField(h)) {
  2939. index = HMIndexFromHandle((ULONG)ReadField(h));
  2940. if (index < cHandleEntries) {
  2941. ReadPointer(pshi + dwHandleOffset + index * dwHESize, &phe);
  2942. if (((ULONG_PTR)ReadField(phead)) == dw) {
  2943. Print("= a pointer to a %s.", pszObjStr[ReadField(bType)]);
  2944. fNoSym = TRUE;
  2945. }
  2946. }
  2947. }
  2948. /*
  2949. * Does this reference the stack itself?
  2950. */
  2951. w = HIWORD(dw);
  2952. aw = HIWORD(adw);
  2953. if (w == aw || w == aw - 1 || w == aw + 1) {
  2954. Print("= Stack Reference ");
  2955. fNoSym = TRUE;
  2956. }
  2957. if (!fNoSym) {
  2958. /*
  2959. * Its accessible so print its symbolic reference
  2960. */
  2961. GetSym(dw, ach, &dwOffset);
  2962. if (*ach) {
  2963. Print("= symbol \"%s\"", ach);
  2964. if (dwOffset) {
  2965. Print(" + %p", dwOffset);
  2966. }
  2967. }
  2968. }
  2969. }
  2970. }
  2971. Print("\n");
  2972. }
  2973. /***********************************************************************\
  2974. * Isas
  2975. *
  2976. * Analyzes the stack. Looks at a range of dwords and tries to make
  2977. * sense out of them. Identifies handles, user objects, and code
  2978. * addresses.
  2979. *
  2980. * 11/30/1995 Created SanfordS
  2981. \***********************************************************************/
  2982. BOOL Isas(
  2983. DWORD opts,
  2984. ULONG64 param1,
  2985. ULONG64 param2)
  2986. {
  2987. DWORD count = (DWORD)(UINT_PTR)param2;
  2988. DWORD_PTR dw;
  2989. DWORD dwPointerSize = GetTypeSize("PVOID");
  2990. if (param1 == 0) {
  2991. return FALSE;
  2992. }
  2993. if (opts & OFLAG(d)) {
  2994. DirectAnalyze((ULONG_PTR)param1, 0, opts & OFLAG(s));
  2995. } else {
  2996. if (count == 0) {
  2997. count = 25; // default span
  2998. }
  2999. Print("--- Stack analysis ---\n");
  3000. for ( ; count; count--, param1 += dwPointerSize) {
  3001. if (IsCtrlCHit()) {
  3002. break;
  3003. }
  3004. Print("[0x%p]: ", (ULONG_PTR)param1);
  3005. if (tryMove(dw, param1)) {
  3006. DirectAnalyze(dw, (DWORD_PTR)param1, OFLAG(s) & opts);
  3007. } else {
  3008. Print("No access\n");
  3009. }
  3010. }
  3011. }
  3012. return TRUE;
  3013. }
  3014. #ifdef KERNEL
  3015. typedef VOID (*AtomPrint)(DWORD dwOneShot, RTL_ATOM atom, USHORT usRefCount,
  3016. const WCHAR* pwszName, UCHAR uNameLength, UCHAR uFlags);
  3017. VOID DefAtomPrint(
  3018. DWORD dwOneShot,
  3019. RTL_ATOM atom,
  3020. USHORT usRefCount,
  3021. const WCHAR* pwszName,
  3022. UCHAR uNameLength,
  3023. UCHAR uFlags)
  3024. {
  3025. Print("%*s%hx(%2d) = %ls (%d)%s\n",
  3026. dwOneShot, dwOneShot ? " " : "", // hack: fOneShot is also used as a prefix spaces...
  3027. atom,
  3028. usRefCount,
  3029. pwszName,
  3030. uNameLength,
  3031. uFlags & RTL_ATOM_PINNED ? " pinned" : "");
  3032. }
  3033. /************************************************************************\
  3034. * DumpAtomTable
  3035. *
  3036. * Dumps an atom or entire atom table.
  3037. *
  3038. * 6/9/1995 Created SanfordS
  3039. \************************************************************************/
  3040. BOOL DumpAtomTable(
  3041. PTR table,
  3042. RTL_ATOM atomFind,
  3043. DWORD dwOneShot,
  3044. AtomPrint pfnPrint)
  3045. {
  3046. ULONG i;
  3047. ULONG cBuckets;
  3048. ULONG cb, cbPtr, cbBuckets;
  3049. ULONG64 pate;
  3050. RTL_ATOM atom;
  3051. UCHAR Flags;
  3052. USHORT RefCount;
  3053. UCHAR NameLength;
  3054. WCHAR *pName;
  3055. if (pfnPrint == NULL) {
  3056. pfnPrint = DefAtomPrint;
  3057. }
  3058. if (!dwOneShot) {
  3059. Print("\n");
  3060. }
  3061. cbPtr = GetTypeSize("PVOID");
  3062. GetFieldValue(table, "nt!_RTL_ATOM_TABLE", "NumberOfBuckets", cBuckets);
  3063. GetFieldOffset("nt!_RTL_ATOM_TABLE", "Buckets", &cbBuckets);
  3064. for (i = 0; i < cBuckets; i++) {
  3065. ShowProgress();
  3066. ReadPointer(table + cbBuckets + i * cbPtr, &pate);
  3067. if (atomFind == 0 && pate != 0 && !dwOneShot) {
  3068. Print(" Bucket %d\n", i);
  3069. }
  3070. while (pate != NULL_PTR) {
  3071. GetFieldValue(pate, "nt!_RTL_ATOM_TABLE_ENTRY", "Atom", atom);
  3072. GetFieldValue(pate, "nt!_RTL_ATOM_TABLE_ENTRY", "Flags", Flags);
  3073. GetFieldValue(pate, "nt!_RTL_ATOM_TABLE_ENTRY", "ReferenceCount", RefCount);
  3074. GetFieldValue(pate, "nt!_RTL_ATOM_TABLE_ENTRY", "NameLength", NameLength);
  3075. GetFieldOffset("nt!_RTL_ATOM_TABLE_ENTRY", "Name", &cb);
  3076. pName = LocalAlloc(LPTR, sizeof(WCHAR) * (NameLength + 1));
  3077. ReadMemory(pate + cb, (PVOID)pName, sizeof(WCHAR) * NameLength, &cb);
  3078. pName[NameLength] = L'\0';
  3079. if (atomFind == 0 || atom == atomFind) {
  3080. pfnPrint(dwOneShot, atom, RefCount, pName, NameLength, Flags);
  3081. if (atom == atomFind) {
  3082. LocalFree(pName);
  3083. return TRUE;
  3084. }
  3085. }
  3086. LocalFree(pName);
  3087. GetFieldValue(pate, "nt!_RTL_ATOM_TABLE_ENTRY", "HashLink", pate);
  3088. }
  3089. }
  3090. return FALSE;
  3091. }
  3092. /************************************************************************\
  3093. * Iatom
  3094. *
  3095. * Dumps an atom or the entire local USER atom table.
  3096. *
  3097. * 6/9/1995 Created SanfordS
  3098. \************************************************************************/
  3099. BOOL Iatom(
  3100. DWORD opts,
  3101. ULONG64 atom)
  3102. {
  3103. PTR table;
  3104. PTR pwinsta;
  3105. UNREFERENCED_PARAMETER(opts);
  3106. table = GetGlobalPointer(VAR(UserAtomTableHandle));
  3107. if (table != NULL_PTR) {
  3108. Print("\nPrivate atom table for WIN32K ");
  3109. DumpAtomTable(table, (RTL_ATOM)atom, FALSE, NULL);
  3110. }
  3111. FOREACHWINDOWSTATION(pwinsta)
  3112. GetFieldValue(pwinsta, SYM(WINDOWSTATION), "pGlobalAtomTable", table);
  3113. if (table != NULL_PTR) {
  3114. Print(" \nGlobal atom table for window station %lx ", pwinsta);
  3115. DumpAtomTable(table, (RTL_ATOM)atom, FALSE, NULL);
  3116. }
  3117. NEXTEACHWINDOWSTATION(pwinsta);
  3118. return TRUE;
  3119. }
  3120. #endif // KERNEL
  3121. #ifdef OLD_DEBUGGER
  3122. #ifndef KERNEL
  3123. /************************************************************************\
  3124. * DumpConvInfo
  3125. *
  3126. * Dumps DDEML client conversation info structures.
  3127. *
  3128. * 6/9/1995 Created SanfordS
  3129. \************************************************************************/
  3130. BOOL DumpConvInfo(
  3131. PCONV_INFO pcoi)
  3132. {
  3133. CL_CONV_INFO coi;
  3134. ADVISE_LINK al;
  3135. XACT_INFO xi;
  3136. move(coi, pcoi);
  3137. Print(" next = 0x%08lx\n", coi.ci.next);
  3138. Print(" pcii = 0x%08lx\n", coi.ci.pcii);
  3139. Print(" hUser = 0x%08lx\n", coi.ci.hUser);
  3140. Print(" hConv = 0x%08lx\n", coi.ci.hConv);
  3141. Print(" laService = 0x%04x\n", coi.ci.laService);
  3142. Print(" laTopic = 0x%04x\n", coi.ci.laTopic);
  3143. Print(" hwndPartner = 0x%08lx\n", coi.ci.hwndPartner);
  3144. Print(" hwndConv = 0x%08lx\n", coi.ci.hwndConv);
  3145. Print(" state = 0x%04x\n", coi.ci.state);
  3146. Print(" laServiceRequested= 0x%04x\n", coi.ci.laServiceRequested);
  3147. Print(" pxiIn = 0x%08lx\n", coi.ci.pxiIn);
  3148. Print(" pxiOut = 0x%08lx\n", coi.ci.pxiOut);
  3149. SAFEWHILE (coi.ci.pxiOut) {
  3150. move(xi, coi.ci.pxiOut);
  3151. Print(" hXact = (0x%08lx)->0x%08lx\n", xi.hXact, coi.ci.pxiOut);
  3152. coi.ci.pxiOut = xi.next;
  3153. }
  3154. Print(" dmqIn = 0x%08lx\n", coi.ci.dmqIn);
  3155. Print(" dmqOut = 0x%08lx\n", coi.ci.dmqOut);
  3156. Print(" aLinks = 0x%08lx\n", coi.ci.aLinks);
  3157. Print(" cLinks = 0x%08lx\n", coi.ci.cLinks);
  3158. SAFEWHILE (coi.ci.cLinks--) {
  3159. move(al, coi.ci.aLinks++);
  3160. Print(" pLinkCount = 0x%08x\n", al.pLinkCount);
  3161. Print(" wType = 0x%08x\n", al.wType);
  3162. Print(" state = 0x%08x\n", al.state);
  3163. if (coi.ci.cLinks) {
  3164. Print(" ---\n");
  3165. }
  3166. }
  3167. if (coi.ci.state & ST_CLIENT) {
  3168. Print(" hwndReconnect = 0x%08lx\n", coi.hwndReconnect);
  3169. Print(" hConvList = 0x%08lx\n", coi.hConvList);
  3170. }
  3171. return TRUE;
  3172. }
  3173. #endif // !KERNEL
  3174. #endif // OLD_DEBUGGER
  3175. #ifndef KERNEL
  3176. /************************************************************************\
  3177. * FixKernelPointer
  3178. *
  3179. * Converts a kernel object pointer into its client-side equivalent. Client
  3180. * pointers and NULL are unchanged.
  3181. *
  3182. * 6/15/1995 Created SanfordS
  3183. \************************************************************************/
  3184. ULONG64
  3185. FixKernelPointer(
  3186. PTR pKernel)
  3187. {
  3188. static ULONG64 pteb = 0;
  3189. static ULONG64 ulClientDelta;
  3190. static ULONG64 HighestUserAddress;
  3191. if (pKernel == 0) {
  3192. return 0;
  3193. }
  3194. if (HighestUserAddress == 0) {
  3195. SYSTEM_BASIC_INFORMATION SystemInformation;
  3196. if (NT_SUCCESS(NtQuerySystemInformation(SystemBasicInformation,
  3197. &SystemInformation,
  3198. sizeof(SystemInformation),
  3199. NULL))) {
  3200. HighestUserAddress = SystemInformation.MaximumUserModeAddress;
  3201. } else {
  3202. // Query failed. Assume usermode is the low half of the address
  3203. // space.
  3204. HighestUserAddress = MAXINT_PTR;
  3205. }
  3206. }
  3207. if (!IsPtr64()) {
  3208. pKernel = (ULONG)pKernel;
  3209. }
  3210. if (pKernel <= HighestUserAddress) {
  3211. return pKernel;
  3212. }
  3213. if (pteb == 0) {
  3214. ULONG pciOffset;
  3215. GetTebAddress(&pteb);
  3216. GetFieldOffset(SYM(TEB), "Win32ClientInfo", &pciOffset);
  3217. GetFieldValue(pteb + pciOffset, SYM(CLIENTINFO), "ulClientDelta", ulClientDelta);
  3218. }
  3219. return (pKernel - ulClientDelta);
  3220. }
  3221. ULONG64
  3222. RebaseSharedPtr(ULONG64 p)
  3223. {
  3224. ULONG64 pshi = 0;
  3225. ULONG64 ulSharedDelta;
  3226. if (p == 0) {
  3227. return 0;
  3228. }
  3229. moveExp(&pshi, VAR(gSharedInfo));
  3230. if (pshi == 0) {
  3231. RAISE_EXCEPTION();
  3232. }
  3233. if (!GetFieldValue(pshi, SYM(SHAREDINFO), "ulSharedDelta", ulSharedDelta)) {
  3234. RAISE_EXCEPTION();
  3235. }
  3236. return p - ulSharedDelta;
  3237. }
  3238. #endif // !KERNEL
  3239. /************************************************************************\
  3240. * Procedure: GetVKeyName
  3241. *
  3242. * 08/09/98 HiroYama Created
  3243. *
  3244. \************************************************************************/
  3245. typedef struct {
  3246. DWORD dwVKey;
  3247. const char* name;
  3248. } VKeyDef;
  3249. int compareVKey(const VKeyDef* a, const VKeyDef* b)
  3250. {
  3251. return a->dwVKey - b->dwVKey;
  3252. }
  3253. #define VKEY_ITEM(x) { x, #x }
  3254. const VKeyDef gVKeyDef[] = {
  3255. #include "vktbl.txt"
  3256. };
  3257. const char* _GetVKeyName(DWORD dwVKey, int n)
  3258. {
  3259. int i;
  3260. /*
  3261. * If dwVKey is one of alphabets or numerics, there's no VK_ macro defined.
  3262. */
  3263. if ((dwVKey >= 'A' && dwVKey <= 'Z') || (dwVKey >= '0' && dwVKey <= '9')) {
  3264. static char buffer[] = "VK_*";
  3265. if (n != 0) {
  3266. return "";
  3267. }
  3268. buffer[ARRAY_SIZE(buffer) - 2] = (BYTE)dwVKey;
  3269. return buffer;
  3270. }
  3271. /*
  3272. * Search the VKEY table.
  3273. */
  3274. for (i = 0; i < ARRAY_SIZE(gVKeyDef); ++i) {
  3275. const VKeyDef* result = gVKeyDef + i;
  3276. if (result->dwVKey == dwVKey) {
  3277. for (; i < ARRAY_SIZE(gVKeyDef); ++i) {
  3278. if (gVKeyDef[i].dwVKey != dwVKey) {
  3279. return "";
  3280. }
  3281. if (&gVKeyDef[i] - result == n) {
  3282. return gVKeyDef[i].name;
  3283. }
  3284. }
  3285. }
  3286. }
  3287. /*
  3288. * VKey name is not found.
  3289. */
  3290. return "";
  3291. }
  3292. const char* GetVKeyName(DWORD dwVKey)
  3293. {
  3294. static char buf[256];
  3295. const char* delim = "";
  3296. int n = 0;
  3297. buf[0] = 0;
  3298. for (n = 0; n < ARRAY_SIZE(gVKeyDef); ++n) {
  3299. const char* name = _GetVKeyName(dwVKey, n);
  3300. if (*name) {
  3301. strcat(buf, delim);
  3302. strcat(buf, name);
  3303. delim = " / ";
  3304. } else {
  3305. break;
  3306. }
  3307. }
  3308. return buf;
  3309. }
  3310. #undef VKEY_ITEM
  3311. #ifdef KERNEL
  3312. /************************************************************************\
  3313. * Procedure: DumpClassList
  3314. *
  3315. *
  3316. * 05/18/98 GerardoB Extracted from Idcls
  3317. \************************************************************************/
  3318. VOID DumpClassList(
  3319. DWORD opts,
  3320. ULONG64 pcls,
  3321. BOOL fPrivate)
  3322. {
  3323. ULONG64 pclsClone;
  3324. ULONG64 pclsNext;
  3325. SAFEWHILE (pcls != 0) {
  3326. if (GetFieldValue(pcls, SYM(CLS), "pclsClone", pclsClone)) {
  3327. Print(" Private class\t\tPCLS @ 0x%p - inaccessible, skipping...\n", pcls);
  3328. break;
  3329. }
  3330. Print(" %s class\t\t", fPrivate ? "Private" : "Public ");
  3331. Idcls(opts, pcls);
  3332. if (pclsClone != 0) {
  3333. SAFEWHILE (pclsClone != 0) {
  3334. if (GetFieldValue(pclsClone, SYM(CLS), "pclsNext", pclsNext)) {
  3335. Print("Could not access clone class at %p, skipping clones...\n", pclsClone);
  3336. break;
  3337. }
  3338. Print(" %s class clone\t", fPrivate ? "Private" : "Public ");
  3339. Idcls(opts, pclsClone);
  3340. pclsClone = pclsNext;
  3341. }
  3342. }
  3343. GetFieldValue(pcls, SYM(CLS), "pclsNext", pcls);
  3344. }
  3345. }
  3346. ULONG
  3347. dclsCallback(
  3348. ULONG64 ppi,
  3349. PVOID Data)
  3350. {
  3351. DWORD opts = PtrToUlong(Data);
  3352. ULONG64 pcls;
  3353. UNREFERENCED_PARAMETER(Data);
  3354. Print("\nClasses for process %p:\n", ppi);
  3355. GetFieldValue(ppi, SYM(PROCESSINFO), "pclsPrivateList", pcls);
  3356. DumpClassList(opts, pcls, TRUE);
  3357. GetFieldValue(ppi, SYM(PROCESSINFO), "pclsPublicList", pcls);
  3358. DumpClassList(opts, pcls, FALSE);
  3359. return FALSE;
  3360. }
  3361. /************************************************************************\
  3362. * Idcls
  3363. *
  3364. * Dumps window class structures
  3365. *
  3366. * 6/9/1995 Created SanfordS
  3367. \************************************************************************/
  3368. BOOL Idcls(
  3369. DWORD opts,
  3370. ULONG64 param1)
  3371. {
  3372. char ach[120];
  3373. ULONG64 dwOffset;
  3374. ULONG64 pcls = param1;
  3375. if (param1 == 0) {
  3376. ForEachPpi(dclsCallback, ULongToPtr(opts));
  3377. Print("\nGlobal Classes:\n");
  3378. pcls = GetGlobalPointer(VAR(gpclsList));
  3379. SAFEWHILE (pcls) {
  3380. Print(" Global Class\t\t");
  3381. Idcls(opts, pcls);
  3382. GetFieldValue(pcls, SYM(CLS), "pclsNext", pcls);
  3383. }
  3384. return TRUE;
  3385. }
  3386. /*
  3387. * Dump class list for a process
  3388. */
  3389. if (opts & OFLAG(p)) {
  3390. opts &= ~OFLAG(p);
  3391. Print("\nClasses for process %p:\n", param1);
  3392. GetFieldValue(param1, SYM(PROCESSINFO), "pclsPrivateList", pcls);
  3393. DumpClassList(opts, pcls, TRUE);
  3394. GetFieldValue(param1, SYM(PROCESSINFO), "pclsPublicList", pcls);
  3395. DumpClassList(opts, pcls, FALSE);
  3396. return TRUE;
  3397. }
  3398. _InitTypeRead(pcls, SYM(tagCLS));
  3399. DebugGetClassNameA(ReadField(lpszAnsiClassName), ach);
  3400. Print("PCLS @ 0x%p \t(%s)\n", pcls, ach);
  3401. if (opts & OFLAG(v)) {
  3402. Print("\t pclsNext 0x%p\n"
  3403. "\t atomClassNameAtom (V) 0x%04x\n"
  3404. "\t atomNVClassNameAtom (NV) 0x%04x\n"
  3405. "\t fnid 0x%04x\n"
  3406. "\t pDCE 0x%p\n"
  3407. "\t cWndReferenceCount 0x%08lx\n"
  3408. "\t flags %s\n",
  3409. ReadField(pclsNext),
  3410. (ULONG)ReadField(atomClassName),
  3411. (ULONG)ReadField(atomNVClassName),
  3412. (ULONG)ReadField(fnid),
  3413. ReadField(pdce),
  3414. (ULONG)ReadField(cWndReferenceCount),
  3415. GetFlags(GF_CSF, (WORD)ReadField(CSF_flags), NULL, TRUE));
  3416. if (ReadField(lpszClientAnsiMenuName)) {
  3417. move(ach, ReadField(lpszClientAnsiMenuName));
  3418. ach[sizeof(ach) - 1] = '\0';
  3419. } else {
  3420. ach[0] = '\0';
  3421. }
  3422. Print("\t lpszClientMenu 0x%p (%s)\n",
  3423. ReadField(lpszClientUnicodeMenuName),
  3424. ach);
  3425. Print("\t hTaskWow 0x%08lx\n"
  3426. "\t spcpdFirst 0x%p\n"
  3427. "\t pclsBase 0x%p\n"
  3428. "\t pclsClone 0x%p\n",
  3429. (ULONG)ReadField(hTaskWow),
  3430. ReadField(spcpdFirst),
  3431. ReadField(pclsBase),
  3432. ReadField(pclsClone));
  3433. GetSym(ReadField(lpfnWndProc), ach, &dwOffset);
  3434. Print("\t style %s\n"
  3435. "\t lpfnWndProc 0x%p = \"%s\" \n"
  3436. "\t cbclsExtra 0x%08lx\n"
  3437. "\t cbwndExtra 0x%08lx\n"
  3438. "\t hModule 0x%p\n"
  3439. "\t spicn 0x%p\n"
  3440. "\t spcur 0x%p\n"
  3441. "\t hbrBackground 0x%p\n"
  3442. "\t spicnSm 0x%p\n",
  3443. GetFlags(GF_CS, (DWORD)ReadField(style), NULL, TRUE),
  3444. ReadField(lpfnWndProc), ach,
  3445. (ULONG)ReadField(cbclsExtra),
  3446. (ULONG)ReadField(cbwndExtra),
  3447. ReadField(hModule),
  3448. ReadField(spicn),
  3449. ReadField(spcur),
  3450. ReadField(hbrBackground),
  3451. ReadField(spicnSm));
  3452. }
  3453. return TRUE;
  3454. }
  3455. #endif // KERNEL
  3456. #ifdef KERNEL
  3457. LPSTR ProcessName(
  3458. ULONG64 ppi)
  3459. {
  3460. ULONG64 pEProcess;
  3461. static UCHAR ImageFileName[16];
  3462. GetFieldValue(ppi, "win32k!W32PROCESS", "Process", pEProcess);
  3463. GetFieldValue(pEProcess, "nt!EPROCESS", "ImageFileName", ImageFileName);
  3464. if (ImageFileName[0]) {
  3465. return ImageFileName;
  3466. } else {
  3467. return "System";
  3468. }
  3469. }
  3470. #endif // KERNEL
  3471. #ifdef KERNEL
  3472. VOID PrintCurHeader()
  3473. {
  3474. Print("P = Process Owned.\n");
  3475. Print("P pcursor flags rt Res/Name ModAtom bpp cx cy xHot yHot hbmMask hbmColor hbmUserAlpha\n");
  3476. }
  3477. VOID PrintCurData(
  3478. ULONG64 pcur,
  3479. DWORD opts)
  3480. {
  3481. _InitTypeRead(pcur, SYM(CURSOR));
  3482. if ((opts & OFLAG(x)) &&
  3483. (((DWORD) ReadField(CURSORF_flags)) & (CURSORF_ACONFRAME | CURSORF_LINKED))) {
  3484. return; // skip acon frame or linked objects.
  3485. }
  3486. if (((DWORD) ReadField(CURSORF_flags)) & CURSORF_ACON) {
  3487. if (opts & OFLAG(a)) {
  3488. Print("--------------\n");
  3489. }
  3490. if (opts & OFLAG(o)) {
  3491. Print("\nOwner:%#010p (%s)\n", ReadField(head.ppi), ProcessName(ReadField(head.ppi)));
  3492. }
  3493. if (opts & OFLAG(v)) {
  3494. Print("\nACON @ 0x%p:\n", pcur);
  3495. Print(" ppiOwner = %#010p\n", ReadField(head.ppi));
  3496. Print(" CURSORF_flags = %s\n", GetFlags(GF_CURSORF, (DWORD) ReadField(CURSORF_flags), NULL, TRUE));
  3497. Print(" strName = %#010p\n", ReadField(strName.Buffer));
  3498. Print(" atomModName = %#x\n", (DWORD) ReadField(atomModName));
  3499. Print(" rt = %#x\n", (DWORD) ReadField(rt));
  3500. } else {
  3501. ULONG64 cpcur = 0;
  3502. GetFieldValue(pcur, SYM(ACON), "cpcur", cpcur);
  3503. Print("%c %#010p %#6x %#4x %#010p %#8x --- ACON (%d frames)\n",
  3504. ReadField(head.ppi) ? 'P' : ' ',
  3505. pcur,
  3506. (DWORD) ReadField(CURSORF_flags),
  3507. (DWORD) ReadField(rt),
  3508. ReadField(strName.Buffer),
  3509. (DWORD) ReadField(atomModName),
  3510. (DWORD) cpcur);
  3511. }
  3512. if (opts & OFLAG(a)) {
  3513. int i = 0;
  3514. ULONG cbElement = 0;
  3515. ULONG cbArrayOffset = 0;
  3516. ULONG64 curFrame = 0;
  3517. _InitTypeRead(pcur, SYM(ACON));
  3518. cbElement = GetTypeSize("PCURSOR");
  3519. GetFieldOffset(SYM(ACON), "aspcur", &cbArrayOffset);
  3520. Print("%d animation sequences, currently at step %d.\n",
  3521. (DWORD) ReadField(cicur),
  3522. (DWORD) ReadField(iicur));
  3523. i = (int) ReadField(cpcur);
  3524. while (i--) {
  3525. ReadPointer(pcur + cbArrayOffset + (i * cbElement), &curFrame);
  3526. PrintCurData(curFrame, opts & ~(OFLAG(x) | OFLAG(o)));
  3527. }
  3528. Print("--------------\n");
  3529. }
  3530. } else {
  3531. if (opts & OFLAG(v)) {
  3532. Print("\nCursor/Icon @ 0x%p:\n", pcur);
  3533. Print(" ppiOwner = %#010p (%s)\n", ReadField(head.ppi), ProcessName(ReadField(head.ppi)));
  3534. Print(" pcurNext = %#010p\n", ReadField(pcurNext));
  3535. Print(" CURSORF_flags = %s\n", GetFlags(GF_CURSORF, (DWORD) ReadField(CURSORF_flags), NULL, TRUE));
  3536. Print(" strName = %#010p\n", ReadField(strName.Buffer));
  3537. Print(" atomModName = %#x\n", (DWORD) ReadField(atomModName));
  3538. Print(" rt = %#x\n", (DWORD) ReadField(rt));
  3539. Print(" bpp = %d\n", (DWORD) ReadField(bpp));
  3540. Print(" cx = %d\n", (DWORD) ReadField(cx));
  3541. Print(" cy = %d\n", (DWORD) ReadField(cy));
  3542. Print(" xHotspot = %d\n", (DWORD) ReadField(xHotspot));
  3543. Print(" yHotspot = %d\n", (DWORD) ReadField(yHotspot));
  3544. Print(" hbmMask = %#x\n", (DWORD) ReadField(hbmMask));
  3545. Print(" hbmColor = %#x\n", (DWORD) ReadField(hbmColor));
  3546. Print(" hbmUserAlpha = %#x\n", (DWORD) ReadField(hbmUserAlpha));
  3547. } else {
  3548. if (opts & OFLAG(o)) {
  3549. Print("\nOwner:%#010p (%s)\n", ReadField(head.ppi), ProcessName(ReadField(head.ppi)));
  3550. }
  3551. Print("%c %#010p %#06x %#04x %#010p %#08x %3d %3d %3d %4d %4d %#010x %#010x %#010x\n",
  3552. ReadField(head.ppi) ? 'P' : ' ',
  3553. pcur,
  3554. (DWORD) ReadField(CURSORF_flags),
  3555. (DWORD) ReadField(rt),
  3556. ReadField(strName.Buffer),
  3557. (DWORD) ReadField(atomModName),
  3558. (DWORD) ReadField(bpp),
  3559. (DWORD) ReadField(cx),
  3560. (DWORD) ReadField(cy),
  3561. (DWORD) ReadField(xHotspot),
  3562. (DWORD) ReadField(yHotspot),
  3563. (DWORD) ReadField(hbmMask),
  3564. (DWORD) ReadField(hbmColor),
  3565. (DWORD) ReadField(hbmUserAlpha));
  3566. }
  3567. }
  3568. }
  3569. typedef struct tagMyCurData
  3570. {
  3571. ULONG64 ppiDesired;
  3572. ULONG idDesired;
  3573. DWORD opts;
  3574. } MyCurData;
  3575. ULONG WDBGAPI PrintPpiCurData(ULONG64 ppi, PVOID Data)
  3576. {
  3577. ULONG64 pcur = 0;
  3578. MyCurData * pMyCurData = (MyCurData *)Data;
  3579. if (pMyCurData == NULL) {
  3580. return 0;
  3581. }
  3582. _InitTypeRead(ppi, SYM(PROCESSINFO));
  3583. if (ReadField(pCursorCache)) {
  3584. Print("\nCache for process %#010p (%s):\n", ppi, ProcessName(ppi));
  3585. pcur = ReadField(pCursorCache);
  3586. while (pcur) {
  3587. _InitTypeRead(pcur, SYM(CURSOR));
  3588. if ((pMyCurData->idDesired == 0) || ((ULONG) ReadField(strName.Buffer) == pMyCurData->idDesired)) {
  3589. if (ReadField(head.ppi) != ppi) {
  3590. Print("Wrong cache! Owned by %#010p! --v\n", ReadField(head.ppi));
  3591. }
  3592. PrintCurData(pcur, pMyCurData->opts);
  3593. }
  3594. pcur = ReadField(pcurNext);
  3595. }
  3596. }
  3597. return 0;
  3598. }
  3599. /************************************************************************\
  3600. * Idcur
  3601. *
  3602. * Dump cursor structures.
  3603. *
  3604. * 6/9/1995 Created SanfordS
  3605. \************************************************************************/
  3606. BOOL Idcur(
  3607. DWORD opts,
  3608. ULONG64 param1)
  3609. {
  3610. ULONG64 ppi = 0;
  3611. ULONG64 ppiDesired = 0;
  3612. ULONG idDesired = 0;
  3613. ULONG64 pcur = 0;
  3614. ULONG64 phe = 0;
  3615. int cCursors = 0;
  3616. int i;
  3617. if (OFLAG(p) & opts) {
  3618. ppiDesired = param1;
  3619. param1 = 0;
  3620. } else if (OFLAG(i) & opts) {
  3621. idDesired = (ULONG) param1;
  3622. param1 = 0;
  3623. }
  3624. if (param1 == 0) {
  3625. if (!(OFLAG(v) & opts)) {
  3626. PrintCurHeader();
  3627. }
  3628. pcur = GetGlobalPointer(VAR(gpcurFirst));
  3629. if (pcur != 0 && ppiDesired == 0) {
  3630. Print("\nGlobal cache:\n");
  3631. while (pcur) {
  3632. _InitTypeRead(pcur, SYM(CURSOR));
  3633. if (!idDesired || ((ULONG) ReadField(strName.Buffer) == idDesired)) {
  3634. if (ReadField(head.ppi) != 0) {
  3635. Print("Wrong cache! Owned by %010p! --v\n", ReadField(head.ppi));
  3636. }
  3637. PrintCurData(pcur, opts);
  3638. }
  3639. pcur = ReadField(pcurNext);
  3640. }
  3641. }
  3642. if (ppiDesired == 0 || ppiDesired == ppi) {
  3643. MyCurData myCurData;
  3644. myCurData.ppiDesired = ppiDesired;
  3645. myCurData.idDesired = idDesired;
  3646. myCurData.opts = opts;
  3647. ForEachPpi(PrintPpiCurData, &myCurData);
  3648. }
  3649. Print("\nNon-cached cursor objects:\n");
  3650. FOREACHHANDLEENTRY(phe, i)
  3651. _InitTypeRead(phe, SYM(HANDLEENTRY));
  3652. if (ReadField(bType) == TYPE_CURSOR) {
  3653. pcur = ReadField(phead);
  3654. _InitTypeRead(pcur, SYM(CURSOR));
  3655. if (!(ReadField(CURSORF_flags) & (CURSORF_LINKED | CURSORF_ACONFRAME)) &&
  3656. (!idDesired || ((ULONG) ReadField(strName.Buffer) == idDesired)) &&
  3657. (ppiDesired == 0 || ppiDesired == ReadField(head.ppi))) {
  3658. PrintCurData(pcur, opts | OFLAG(x) | OFLAG(o));
  3659. }
  3660. cCursors++;
  3661. }
  3662. NEXTEACHHANDLEENTRY()
  3663. Print("\n%d Cursors/Icons Total.\n", cCursors);
  3664. return TRUE;
  3665. }
  3666. pcur = HorPtoP(param1, TYPE_CURSOR);
  3667. if (pcur == 0) {
  3668. Print("%010p : Invalid cursor handle or pointer.\n", param1);
  3669. return FALSE;
  3670. }
  3671. if (!(OFLAG(v) & opts)) {
  3672. PrintCurHeader();
  3673. }
  3674. PrintCurData(pcur, opts);
  3675. return TRUE;
  3676. }
  3677. #endif // KERNEL
  3678. #ifdef KERNEL
  3679. /************************************************************************\
  3680. * ddeexact
  3681. *
  3682. * Dumps DDEML transaction structures.
  3683. *
  3684. * 6/9/1995 Created SanfordS
  3685. \************************************************************************/
  3686. BOOL dddexact(
  3687. ULONG64 pxs,
  3688. DWORD opts)
  3689. {
  3690. _InitTypeRead(pxs, SYM(XSTATE));
  3691. if (opts & OFLAG(v)) {
  3692. Print(" XACT:0x%p\n", pxs);
  3693. Print(" snext = 0x%#p\n", ReadField(snext));
  3694. Print(" fnResponse = 0x%#p\n", ReadField(fnResponse));
  3695. Print(" hClient = 0x%08lx\n", (ULONG)ReadField(hClient));
  3696. Print(" hServer = 0x%08lx\n", (ULONG)ReadField(hServer));
  3697. Print(" pIntDdeInfo = 0x%#p\n", ReadField(pIntDdeInfo));
  3698. } else {
  3699. Print("0x%#p(0x%08lx) ", pxs, (ULONG)ReadField(flags));
  3700. }
  3701. return TRUE;
  3702. }
  3703. #endif // KERNEL
  3704. #ifdef KERNEL
  3705. /************************************************************************\
  3706. * ddeconv
  3707. *
  3708. * Dumps DDE tracking layer conversation structures.
  3709. *
  3710. * 6/9/1995 Created SanfordS
  3711. \************************************************************************/
  3712. BOOL dddeconv(
  3713. ULONG64 pDdeconv,
  3714. DWORD opts)
  3715. {
  3716. ULONG64 pxs;
  3717. int cX;
  3718. DWORD dwOffset, dwQosOffset;
  3719. _InitTypeRead(pDdeconv, SYM(DDECONV));
  3720. Print(" CONVERSATION-PAIR(0x%p:0x%p)\n", pDdeconv, ReadField(spartnerConv));
  3721. if (opts & OFLAG(v)) {
  3722. Print(" snext = 0x%p\n", ReadField(snext));
  3723. Print(" spwnd = 0x%p\n", ReadField(spwnd));
  3724. Print(" spwndPartner = 0x%p\n", ReadField(spwndPartner));
  3725. }
  3726. if (opts & (OFLAG(v) | OFLAG(r))) {
  3727. if (ReadField(spxsOut)){
  3728. pxs = ReadField(spxsOut);
  3729. cX = 0;
  3730. SAFEWHILE (pxs) {
  3731. if ((opts & OFLAG(r)) && !cX++) {
  3732. Print(" Transaction chain:");
  3733. } else {
  3734. Print(" ");
  3735. }
  3736. dddexact(pxs, opts);
  3737. if (opts & OFLAG(r)) {
  3738. GetFieldValue(pxs, SYM(STATE), "snext", pxs);
  3739. } else {
  3740. pxs = 0;
  3741. }
  3742. if (!pxs) {
  3743. Print("\n");
  3744. }
  3745. }
  3746. }
  3747. }
  3748. if (opts & OFLAG(v)) {
  3749. Print(" pfl = 0x%p\n", ReadField(pfl));
  3750. Print(" flags = 0x%08lx\n", (ULONG)ReadField(flags));
  3751. if ((opts & OFLAG(v)) && (opts & OFLAG(r)) && ReadField(pddei)) {
  3752. GetFieldOffset(SYM(DDECONV), "pddei", &dwOffset);
  3753. GetFieldOffset(SYM(DDEIMP), "qos", &dwQosOffset);
  3754. _InitTypeRead(pDdeconv + dwOffset + dwQosOffset, SYM(DDEI));
  3755. Print(" pddei = 0x%08lx\n", pDdeconv+ dwOffset);
  3756. Print(" Impersonation info:\n");
  3757. Print(" qos.Length = 0x%08lx\n", (ULONG)ReadField(Length));
  3758. Print(" qos.ImpersonationLevel = 0x%08lx\n", (ULONG)ReadField(ImpersonationLevel));
  3759. Print(" qos.ContextTrackingMode = 0x%08lx\n", (ULONG)ReadField(ContextTrackingMode));
  3760. Print(" qos.EffectiveOnly = 0x%08lx\n", (ULONG)ReadField(EffectiveOnly));
  3761. _InitTypeRead(pDdeconv + dwOffset, SYM(DDEIMP));
  3762. GetFieldOffset(SYM(DDEIMP), "ClientContext", &dwOffset);
  3763. Print(" ClientContext = 0x%#p\n", pDdeconv + dwOffset);
  3764. Print(" cRefInit = 0x%08lx\n", (ULONG)ReadField(cRefInit));
  3765. Print(" cRefConv = 0x%08lx\n", (ULONG)ReadField(cRefConv));
  3766. }
  3767. }
  3768. return TRUE;
  3769. }
  3770. #endif // KERNEL
  3771. #ifdef KERNEL
  3772. /************************************************************************\
  3773. * Idde
  3774. *
  3775. * Dumps DDE tracking layer state and structures.
  3776. *
  3777. * 6/9/1995 Created SanfordS
  3778. \************************************************************************/
  3779. BOOL Idde(
  3780. DWORD opts,
  3781. ULONG64 param1)
  3782. {
  3783. ULONG64 pshi, psi, cHandleEntries, pheList, h, pPropList, ptr;
  3784. ULONG64 pObj = 0;
  3785. UINT i, iFirstFree;
  3786. DWORD atomDdeTrack, dwOffset;
  3787. DWORD dwHESize = GetTypeSize(SYM(HANDLEENTRY));
  3788. DWORD dwPropSize = GetTypeSize(SYM(PROP));
  3789. BYTE bType;
  3790. moveExpValue(&atomDdeTrack, VAR(atomDDETrack));
  3791. GETSHAREDINFO(pshi);
  3792. GetFieldOffset(SYM(SHAREDINFO), "psi", &dwOffset);
  3793. ReadPointer(pshi + dwOffset, &psi);
  3794. GetFieldOffset(SYM(SHAREDINFO), "aheList", &dwOffset);
  3795. ReadPointer(pshi + dwOffset, &pheList);
  3796. GetFieldValue(psi, SYM(SERVERINFO), "cHandleEntries", cHandleEntries);
  3797. if (param1) {
  3798. /*
  3799. * get object param.
  3800. */
  3801. i = HMIndexFromHandle((ULONG_PTR)param1);
  3802. if (i >= cHandleEntries) {
  3803. GetFieldValue(param1, SYM(HEAD), "h", h);
  3804. i = HMIndexFromHandle(h);
  3805. }
  3806. if (i >= cHandleEntries) {
  3807. Print("0x%08lx is not a valid object.\n", h);
  3808. return FALSE;
  3809. }
  3810. GetFieldOffset(SYM(HANDLEENTRY), "phead", &dwOffset);
  3811. ReadPointer(pheList + i * dwHESize + dwOffset, &pObj);
  3812. /*
  3813. * verify type.
  3814. */
  3815. GetFieldValue(pheList + i * dwHESize, SYM(HANDLEENTRY), "bType", bType);
  3816. switch (bType) {
  3817. case TYPE_WINDOW:
  3818. GetFieldOffset(SYM(WND), "ppropList", &dwOffset);
  3819. ReadPointer(pObj + dwOffset, &pPropList);
  3820. GetFieldValue(pPropList, SYM(PROPLIST), "iFirstFree", iFirstFree);
  3821. for (i = 0; i < iFirstFree; i++) {
  3822. if (i == 0) {
  3823. Print("Window 0x%08lx conversations:\n", h);
  3824. }
  3825. GetFieldOffset(SYM(PROPLIST), "aprop", &dwOffset);
  3826. ReadPtr(pPropList + dwOffset + i * dwPropSize, &ptr);
  3827. _InitTypeRead(ptr, SYM(PROP));
  3828. if (ReadField(atomKey) == (ATOM)MAKEINTATOM(atomDdeTrack)) {
  3829. Print(" ");
  3830. dddeconv(ReadField(hData), opts);
  3831. }
  3832. }
  3833. return TRUE;
  3834. case TYPE_DDECONV:
  3835. case TYPE_DDEXACT:
  3836. break;
  3837. default:
  3838. Print("0x%08lx is not a valid window, conversation or transaction object.\n", h);
  3839. return FALSE;
  3840. }
  3841. }
  3842. /*
  3843. * look for all qualifying objects in the object table.
  3844. */
  3845. Print("DDE objects:\n");
  3846. for (i = 0; i < cHandleEntries; i++) {
  3847. _InitTypeRead(pheList + i * dwHESize , SYM(HANDLEENTRY));
  3848. if ((BYTE)ReadField(bType) == TYPE_DDECONV && ((pObj == FIXKP(ReadField(phead))) || pObj == 0)) {
  3849. dddeconv(FIXKP(ReadField(phead)), opts);
  3850. }
  3851. if ((BYTE)ReadField(bType) == TYPE_DDEXACT && (pObj == 0 || pObj == FIXKP(ReadField(phead)))) {
  3852. if (!(opts & OFLAG(v))) {
  3853. Print(" XACT:");
  3854. }
  3855. dddexact(FIXKP(ReadField(phead)), opts);
  3856. Print("\n");
  3857. }
  3858. }
  3859. return TRUE;
  3860. }
  3861. #endif // KERNEL
  3862. #ifdef OLD_DEBUGGER
  3863. #ifndef KERNEL
  3864. /************************************************************************\
  3865. * Iddeml
  3866. *
  3867. * Dumps the DDEML state for this client process.
  3868. *
  3869. * 6/9/1995 Created SanfordS
  3870. \************************************************************************/
  3871. BOOL Iddeml(
  3872. DWORD opts,
  3873. LPSTR lpas)
  3874. {
  3875. CHANDLEENTRY he, *phe;
  3876. int cHandles, ch, i;
  3877. DWORD Type;
  3878. DWORD_PTR Instance, Object, Pointer;
  3879. CL_INSTANCE_INFO cii, *pcii;
  3880. ATOM ns;
  3881. SERVER_LOOKUP sl;
  3882. LINK_COUNT lc;
  3883. CL_CONV_INFO cci;
  3884. PCL_CONV_INFO pcci;
  3885. CONVLIST cl;
  3886. HWND hwnd, *phwnd;
  3887. XACT_INFO xi;
  3888. DDEMLDATA dd;
  3889. CONV_INFO ci;
  3890. moveExpValue(&cHandles, "user32!cHandlesAllocated");
  3891. Instance = 0;
  3892. Type = 0;
  3893. Object = 0;
  3894. Pointer = 0;
  3895. SAFEWHILE (*lpas) {
  3896. SAFEWHILE (*lpas == ' ')
  3897. lpas++;
  3898. if (*lpas == 'i') {
  3899. lpas++;
  3900. Instance = (DWORD_PTR)EvalExp(lpas);
  3901. SAFEWHILE (*lpas != ' ' && *lpas != 0)
  3902. lpas++;
  3903. continue;
  3904. }
  3905. if (*lpas == 't') {
  3906. lpas++;
  3907. Type = (DWORD)(DWORD_PTR)EvalExp(lpas);
  3908. SAFEWHILE (*lpas != ' ' && *lpas != 0)
  3909. lpas++;
  3910. continue;
  3911. }
  3912. if (*lpas) {
  3913. Object = Pointer = (DWORD_PTR)EvalExp(lpas);
  3914. SAFEWHILE (*lpas != ' ' && *lpas != 0)
  3915. lpas++;
  3916. }
  3917. }
  3918. /*
  3919. * for each instance for this process...
  3920. */
  3921. pcii = GetGlobalPointer("user32!pciiList");
  3922. if (pcii == NULL) {
  3923. Print("No Instances exist.\n");
  3924. return TRUE;
  3925. }
  3926. move(cii, pcii);
  3927. SAFEWHILE (pcii != NULL) {
  3928. pcii = cii.next;
  3929. if (Instance == 0 || (Instance == (DWORD_PTR)cii.hInstClient)) {
  3930. Print("Objects for instance 0x%p:\n", cii.hInstClient);
  3931. ch = cHandles;
  3932. phe = GetGlobalPointer("user32!aHandleEntry");
  3933. SAFEWHILE (ch--) {
  3934. move(he, phe++);
  3935. if (he.handle == 0) {
  3936. continue;
  3937. }
  3938. if (InstFromHandle(cii.hInstClient) != InstFromHandle(he.handle)) {
  3939. continue;
  3940. }
  3941. if (Type && TypeFromHandle(he.handle) != Type) {
  3942. continue;
  3943. }
  3944. if (Object && (he.handle != (HANDLE)Object) &&
  3945. Pointer && he.dwData != Pointer) {
  3946. continue;
  3947. }
  3948. Print(" (0x%08lx)->0x%08lx ", he.handle, he.dwData);
  3949. switch (TypeFromHandle(he.handle)) {
  3950. case HTYPE_INSTANCE:
  3951. Print("Instance\n");
  3952. if (opts & OFLAG(v)) {
  3953. Print(" next = 0x%08lx\n", cii.next);
  3954. Print(" hInstServer = 0x%08lx\n", cii.hInstServer);
  3955. Print(" hInstClient = 0x%08lx\n", cii.hInstClient);
  3956. Print(" MonitorFlags = 0x%08lx\n", cii.MonitorFlags);
  3957. Print(" hwndMother = 0x%08lx\n", cii.hwndMother);
  3958. Print(" hwndEvent = 0x%08lx\n", cii.hwndEvent);
  3959. Print(" hwndTimeout = 0x%08lx\n", cii.hwndTimeout);
  3960. Print(" afCmd = 0x%08lx\n", cii.afCmd);
  3961. Print(" pfnCallback = 0x%08lx\n", cii.pfnCallback);
  3962. Print(" LastError = 0x%08lx\n", cii.LastError);
  3963. Print(" tid = 0x%08lx\n", cii.tid);
  3964. Print(" plaNameService = 0x%08lx\n", cii.plaNameService);
  3965. Print(" cNameServiceAlloc = 0x%08lx\n", cii.cNameServiceAlloc);
  3966. SAFEWHILE (cii.cNameServiceAlloc--) {
  3967. move(ns, cii.plaNameService++);
  3968. Print(" 0x%04lx\n", ns);
  3969. }
  3970. Print(" aServerLookup = 0x%08lx\n", cii.aServerLookup);
  3971. Print(" cServerLookupAlloc = 0x%08lx\n", cii.cServerLookupAlloc);
  3972. SAFEWHILE (cii.cServerLookupAlloc--) {
  3973. move(sl, cii.aServerLookup++);
  3974. Print(" laService = 0x%04x\n", sl.laService);
  3975. Print(" laTopic = 0x%04x\n", sl.laTopic);
  3976. Print(" hwndServer = 0x%08lx\n", sl.hwndServer);
  3977. if (cii.cServerLookupAlloc) {
  3978. Print(" ---\n");
  3979. }
  3980. }
  3981. Print(" ConvStartupState = 0x%08lx\n", cii.ConvStartupState);
  3982. Print(" flags = %s\n",
  3983. GetFlags(GF_IIF, cii.flags, NULL, TRUE));
  3984. Print(" cInDDEMLCallback = 0x%08lx\n", cii.cInDDEMLCallback);
  3985. Print(" pLinkCount = 0x%08lx\n", cii.pLinkCount);
  3986. SAFEWHILE (cii.pLinkCount) {
  3987. move(lc, cii.pLinkCount);
  3988. cii.pLinkCount = lc.next;
  3989. Print(" next = 0x%08lx\n", lc.next);
  3990. Print(" laTopic = 0x%04x\n", lc.laTopic);
  3991. Print(" gaItem = 0x%04x\n", lc.gaItem);
  3992. Print(" laItem = 0x%04x\n", lc.laItem);
  3993. Print(" wFmt = 0x%04x\n", lc.wFmt);
  3994. Print(" Total = 0x%04x\n", lc.Total);
  3995. Print(" Count = 0x%04x\n", lc.Count);
  3996. if (cii.pLinkCount != NULL) {
  3997. Print(" ---\n");
  3998. }
  3999. }
  4000. }
  4001. break;
  4002. case HTYPE_ZOMBIE_CONVERSATION:
  4003. Print("Zombie Conversation\n");
  4004. if (opts & OFLAG(v)) {
  4005. DumpConvInfo((PCONV_INFO)he.dwData);
  4006. }
  4007. break;
  4008. case HTYPE_SERVER_CONVERSATION:
  4009. Print("Server Conversation\n");
  4010. if (opts & OFLAG(v)) {
  4011. DumpConvInfo((PCONV_INFO)he.dwData);
  4012. }
  4013. break;
  4014. case HTYPE_CLIENT_CONVERSATION:
  4015. Print("Client Conversation\n");
  4016. if (opts & OFLAG(v)) {
  4017. DumpConvInfo((PCONV_INFO)he.dwData);
  4018. }
  4019. break;
  4020. case HTYPE_CONVERSATION_LIST:
  4021. if (IsRemoteSession()) {
  4022. Print("!ddeml for Conversation List doesn't work on HYDRA systems\n");
  4023. } else {
  4024. Print("Conversation List\n");
  4025. if (opts & OFLAG(v)) {
  4026. move(cl, (PVOID)he.dwData);
  4027. Print(" pcl = 0x%08lx\n", he.dwData);
  4028. Print(" chwnd = 0x%08lx\n", cl.chwnd);
  4029. i = 0;
  4030. phwnd = (HWND *)&((PCONVLIST)he.dwData)->ahwnd;
  4031. SAFEWHILE (cl.chwnd--) {
  4032. move(hwnd, phwnd++);
  4033. Print(" ahwnd[%d] = 0x%08lx\n", i, hwnd);
  4034. pcci = (PCL_CONV_INFO)GetWindowLongPtr(hwnd, GWLP_PCI);
  4035. SAFEWHILE (pcci) {
  4036. move(cci, pcci);
  4037. pcci = (PCL_CONV_INFO)cci.ci.next;
  4038. Print(" hConv = 0x%08lx\n", cci.ci.hConv);
  4039. }
  4040. i++;
  4041. }
  4042. }
  4043. }
  4044. break;
  4045. case HTYPE_TRANSACTION:
  4046. Print("Transaction\n");
  4047. if (opts & OFLAG(v)) {
  4048. move(xi, (PVOID)he.dwData);
  4049. Print(" next = 0x%08lx\n", xi.next);
  4050. Print(" pcoi = 0x%08lx\n", xi.pcoi);
  4051. move(ci, xi.pcoi);
  4052. Print(" hConv = 0x%08lx\n", ci.hConv);
  4053. Print(" hUser = 0x%08lx\n", xi.hUser);
  4054. Print(" hXact = 0x%08lx\n", xi.hXact);
  4055. Print(" pfnResponse = 0x%08lx\n", xi.pfnResponse);
  4056. Print(" gaItem = 0x%04x\n", xi.gaItem);
  4057. Print(" wFmt = 0x%04x\n", xi.wFmt);
  4058. Print(" wType; = 0x%04x\n", xi.wType);
  4059. Print(" wStatus; = 0x%04x\n", xi.wStatus);
  4060. Print(" flags; = %s\n",
  4061. GetFlags(GF_XI, xi.flags, NULL, TRUE));
  4062. Print(" state; = 0x%04x\n", xi.state);
  4063. Print(" hDDESent = 0x%08lx\n", xi.hDDESent);
  4064. Print(" hDDEResult = 0x%08lx\n", xi.hDDEResult);
  4065. }
  4066. break;
  4067. case HTYPE_DATA_HANDLE:
  4068. Print("Data Handle\n");
  4069. if (opts & OFLAG(v)) {
  4070. move(dd, (PVOID)he.dwData);
  4071. Print(" hDDE = 0x%08lx\n", dd.hDDE);
  4072. Print(" flags = %s\n",
  4073. GetFlags(GF_HDATA, (WORD)dd.flags, NULL, TRUE));
  4074. }
  4075. break;
  4076. }
  4077. }
  4078. }
  4079. if (pcii != NULL) {
  4080. move(cii, pcii);
  4081. }
  4082. }
  4083. return TRUE;
  4084. }
  4085. #endif // !KERNEL
  4086. #endif // OLD_DEBUGGER
  4087. #ifdef KERNEL
  4088. /*
  4089. * Hook helper routines
  4090. */
  4091. VOID IterateHooks(
  4092. PTR phk,
  4093. BOOL fLocalHook,
  4094. BOOL fDumpDllName)
  4095. {
  4096. int iHook;
  4097. ULONG64 offPfn;
  4098. PTR pti;
  4099. UINT flags;
  4100. int ihmod;
  4101. PTR patomTable;
  4102. PTR patomSysLoaded;
  4103. ATOM atom;
  4104. patomTable = GetGlobalPointer(VAR(UserAtomTableHandle));
  4105. patomSysLoaded = EvalExp(SYM(aatomSysLoaded));
  4106. SAFEWHILE (phk != 0) {
  4107. GetFieldValue(phk, SYM(tagHOOK), "iHook", iHook);
  4108. GetFieldValue(phk, SYM(tagHOOK), "offPfn", offPfn);
  4109. GetFieldValue(phk, SYM(tagHOOK), "flags", flags);
  4110. GetFieldValue(phk, SYM(tagHOOK), "ihmod", ihmod);
  4111. GetFieldValue(phk, SYM(tagHOOK), "head.pti", pti);
  4112. Print("\t 0x%p iHook %d, offPfn=0x%08p, ihmod=%d\n",
  4113. phk, iHook, offPfn, ihmod);
  4114. if (!fLocalHook) {
  4115. /*
  4116. * Dump the threadinfo of the hook originator.
  4117. */
  4118. Print("\t ");
  4119. Idt(OFLAG(p), pti);
  4120. }
  4121. Print("\t flags: %s\n", GetFlags(GF_HOOKFLAGS, flags, NULL, TRUE));
  4122. if (ihmod >= 0 && patomTable != NULL_PTR) {
  4123. /*
  4124. * Dump the hook DLL name.
  4125. */
  4126. ReadMemory(patomSysLoaded + sizeof(ATOM) * ihmod, &atom, sizeof(ATOM), NULL);
  4127. if (fDumpDllName && atom) {
  4128. if (!DumpAtomTable(patomTable, (RTL_ATOM)atom, 12, NULL)) {
  4129. Print("%12catom: %04x (unable to get the dll name)\n", ' ', (DWORD)atom);
  4130. }
  4131. }
  4132. }
  4133. GetFieldValue(phk, SYM(tagHOOK), "phkNext", phk);
  4134. }
  4135. }
  4136. VOID DumpHooks(PTR pDeskInfo, LPSTR psz, int i, BOOL fDumpDllName)
  4137. {
  4138. PTR phk = GetArrayElementPtr(pDeskInfo, SYM(tagDESKTOPINFO), "aphkStart", i + 1);
  4139. if (phk) {
  4140. Print("\t %s\n", psz);
  4141. IterateHooks(phk, FALSE, fDumpDllName);
  4142. }
  4143. }
  4144. VOID DumpLHooks(PTR pti, LPSTR psz, int i, BOOL fDumpDllName)
  4145. {
  4146. PTR phk = GetArrayElementPtr(pti, SYM(tagTHREADINFO), "aphkStart", i + 1);
  4147. if (phk) {
  4148. Print("\t %s\n", psz);
  4149. IterateHooks(phk, TRUE, fDumpDllName);
  4150. }
  4151. }
  4152. /***************************************************************************\
  4153. * ddesk - dumps list of desktops
  4154. * ddesk address - dumps simple statistics for desktop
  4155. * ddesk v address - dumps verbose statistics for desktop
  4156. * ddesk h address - dumps statistics for desktop plus handle list
  4157. *
  4158. * Dump handle table statistics.
  4159. *
  4160. * 02/21/1992 ScottLu Created.
  4161. * 06/09/1995 SanfordS Made to fit stdexts motif.
  4162. * 10/15/2000 Hiroyama Ported to ia64.
  4163. \***************************************************************************/
  4164. BOOL Iddesk(
  4165. DWORD opts,
  4166. ULONG64 param1)
  4167. {
  4168. try {
  4169. PTR pwinsta = NULL_PTR; // PWINDOWSTATION
  4170. PTR pdesk; // PDESKTOP
  4171. PTR pHead; // OBJECT_HEADER
  4172. PTR pDeskInfo;
  4173. DWORD acHandles[TYPE_CTYPES + 1];
  4174. BOOL abTrack[TYPE_CTYPES + 1];
  4175. PTR phe; // PHE
  4176. DWORD i;
  4177. WCHAR ach[80];
  4178. BOOL fMatch;
  4179. ULONG offsetPHead; // to reduce the symbol lookup
  4180. ULONG offsetBType;
  4181. ULONG offsetBFlags;
  4182. BYTE bType;
  4183. BOOL fDumpDllName = opts & OFLAG(d);
  4184. /*
  4185. * If there is no address, list all desktops on all terminals.
  4186. */
  4187. if (param1 == NULL_PTR) {
  4188. FOREACHWINDOWSTATION(pwinsta)
  4189. GetObjectName(pwinsta, ach, ARRAY_SIZE(ach));
  4190. Print("Windowstation: @ 0x%p %ws\n", pwinsta, ach);
  4191. Print("Other desktops:\n");
  4192. GetFieldValue(pwinsta, SYM(tagWINDOWSTATION), "rpdeskList", pdesk);
  4193. SAFEWHILE (pdesk) {
  4194. Print(" Desktop at 0x%p\n", pdesk);
  4195. Iddesk(opts & (OFLAG(v) | OFLAG(h) | OFLAG(d)), pdesk);
  4196. GetFieldValue(pdesk, SYM(tagDESKTOP), "rpdeskNext", pdesk);
  4197. }
  4198. Print("\n");
  4199. NEXTEACHWINDOWSTATION(pwinsta)
  4200. return TRUE;
  4201. }
  4202. pdesk = param1;
  4203. GetObjectName(pdesk, ach, ARRAY_SIZE(ach));
  4204. Print(" Name: %ws\n", ach);
  4205. pHead = KD_OBJECT_TO_OBJECT_HEADER(pdesk);
  4206. if (pHead == NULL_PTR) {
  4207. Print("can't get pHeader\n");
  4208. return TRUE;
  4209. }
  4210. /*
  4211. * Dump Header info
  4212. */
  4213. _InitTypeRead(pHead, "nt!_OBJECT_HEADER");
  4214. Print(" # Opens = %d\n", ReadField(HandleCount));
  4215. /*
  4216. * Dump some key info
  4217. */
  4218. _InitTypeRead(pdesk, SYM(tagDESKTOP));
  4219. Print(" dwFlags = %s\n", GetFlags(GF_DESKTOPFLAGS, (DWORD)ReadField(dwDTFlags), NULL, TRUE));
  4220. Print(" Heap = %#p\n", ReadField(pheapDesktop));
  4221. Print(" Windowstation = %#p\n", ReadField(rpwinstaParent));
  4222. Print(" Message pwnd = %#p\n", ReadField(spwndMessage));
  4223. Print(" System pmenu = %#p\n", ReadField(spmenuSys));
  4224. Print(" Console thread = 0x%x\n", ReadField(dwConsoleThreadId));
  4225. Print(" PtiList.Flink = %#p\n", ReadField(PtiList.Flink));
  4226. /*
  4227. * Dump DESKTOPINFO
  4228. */
  4229. pDeskInfo = ReadField(pDeskInfo);
  4230. _InitTypeRead(pDeskInfo, SYM(tagDESKTOPINFO));
  4231. Print(" Desktop pwnd = %#p\n", ReadField(spwnd));
  4232. Print("\tfsHooks = 0x%08lx\n", ReadField(fsHooks));
  4233. DumpHooks(pDeskInfo, "WH_MSGFILTER", WH_MSGFILTER, fDumpDllName);
  4234. DumpHooks(pDeskInfo, "WH_JOURNALRECORD", WH_JOURNALRECORD, fDumpDllName);
  4235. DumpHooks(pDeskInfo, "WH_JOURNALPLAYBACK", WH_JOURNALPLAYBACK, fDumpDllName);
  4236. DumpHooks(pDeskInfo, "WH_KEYBOARD", WH_KEYBOARD, fDumpDllName);
  4237. DumpHooks(pDeskInfo, "WH_GETMESSAGE", WH_GETMESSAGE, fDumpDllName);
  4238. DumpHooks(pDeskInfo, "WH_CALLWNDPROC", WH_CALLWNDPROC, fDumpDllName);
  4239. DumpHooks(pDeskInfo, "WH_CALLWNDPROCRET", WH_CALLWNDPROCRET, fDumpDllName);
  4240. DumpHooks(pDeskInfo, "WH_CBT", WH_CBT, fDumpDllName);
  4241. DumpHooks(pDeskInfo, "WH_SYSMSGFILTER", WH_SYSMSGFILTER, fDumpDllName);
  4242. DumpHooks(pDeskInfo, "WH_MOUSE", WH_MOUSE, fDumpDllName);
  4243. DumpHooks(pDeskInfo, "WH_HARDWARE", WH_HARDWARE, fDumpDllName);
  4244. DumpHooks(pDeskInfo, "WH_DEBUG", WH_DEBUG, fDumpDllName);
  4245. DumpHooks(pDeskInfo, "WH_SHELL", WH_SHELL, fDumpDllName);
  4246. DumpHooks(pDeskInfo, "WH_FOREGROUNDIDLE", WH_FOREGROUNDIDLE, fDumpDllName);
  4247. DumpHooks(pDeskInfo, "WH_KEYBOARD_LL", WH_KEYBOARD_LL, fDumpDllName);
  4248. DumpHooks(pDeskInfo, "WH_MOUSE_LL", WH_MOUSE_LL, fDumpDllName);
  4249. if (opts & OFLAG(h)) {
  4250. /*
  4251. * Find all objects allocated from the desktop.
  4252. */
  4253. for (i = 0; i < ARRAY_SIZE(acHandles); i++) {
  4254. abTrack[i] = FALSE;
  4255. acHandles[i] = 0;
  4256. }
  4257. abTrack[TYPE_WINDOW] = abTrack[TYPE_MENU] =
  4258. abTrack[TYPE_CALLPROC] =
  4259. abTrack[TYPE_HOOK] = TRUE;
  4260. if (opts & OFLAG(v)) {
  4261. Print("Handle Type\n");
  4262. Print("--------------------\n");
  4263. }
  4264. GetFieldOffset(SYM(HANDLEENTRY), "phead", &offsetPHead);
  4265. DEBUGPRINT("offsetPHead=%x\n", offsetPHead);
  4266. GetFieldOffset(SYM(HANDLEENTRY), "bType", &offsetBType);
  4267. DEBUGPRINT("offsetBType=%x\n", offsetBType);
  4268. GetFieldOffset(SYM(HANDLEENTRY), "bFlags", &offsetBFlags);
  4269. FOREACHHANDLEENTRY(phe, i)
  4270. fMatch = FALSE;
  4271. if ((i & 0x3) == 0) {
  4272. ShowProgress();
  4273. }
  4274. move(bType, phe + offsetBType);
  4275. if (bType >= TYPE_CTYPES) {
  4276. bType = TYPE_CTYPES; // unknown;
  4277. }
  4278. try {
  4279. PTR phead;
  4280. PTR rpdesk = NULL_PTR;
  4281. switch (bType) {
  4282. case TYPE_WINDOW:
  4283. {
  4284. static ULONG offset = 0;
  4285. ReadPointer(phe + offsetPHead, &phead);
  4286. if (offset == 0) {
  4287. GetFieldOffset(SYM(WND), "head.rpdesk", &offset);
  4288. DEBUGPRINT("offset=%x\n", offset);
  4289. }
  4290. ReadPointer(phead + offset, &rpdesk);
  4291. DEBUGPRINT("rpdesk=0x%p @ 0x%p phead=0x%p ", rpdesk, phead + offset, phead);
  4292. }
  4293. break;
  4294. case TYPE_MENU:
  4295. {
  4296. static ULONG offset = 0;
  4297. ReadPointer(phe + offsetPHead, &phead);
  4298. if (offset == 0) {
  4299. GetFieldOffset(SYM(tagMENU), "head.rpdesk", &offset);
  4300. }
  4301. ReadPointer(phead + offset, &rpdesk);
  4302. }
  4303. break;
  4304. case TYPE_CALLPROC:
  4305. {
  4306. static ULONG offset = 0;
  4307. ReadPointer(phe + offsetPHead, &phead);
  4308. if (offset == 0) {
  4309. GetFieldOffset(SYM(CALLPROCDATA), "head.rpdesk", &offset);
  4310. }
  4311. ReadPointer(phead + offset, &rpdesk);
  4312. }
  4313. break;
  4314. case TYPE_HOOK:
  4315. {
  4316. static ULONG offset = 0;
  4317. ReadPointer(phe + offsetPHead, &phead);
  4318. if (offset == 0) {
  4319. GetFieldOffset(SYM(tagHOOK), "head.rpdesk", &offset);
  4320. }
  4321. ReadPointer(phead + offset, &rpdesk);
  4322. }
  4323. break;
  4324. #if defined(GI_PROCESSOR) && defined(TYPE_RAWINPUT_PROCESSOR)
  4325. case TYPE_RAWINPUT_PROCESSOR:
  4326. {
  4327. static ULONG offset = 0;
  4328. ReadPointer(phe + offsetPHead, &phead);
  4329. if (offset == 0) {
  4330. GetFieldOffset(SYM(tagRAWINPUT_PROCESSOR), "head.rpdesk", &offset);
  4331. }
  4332. ReadPointer(phead + offset, &rpdesk);
  4333. }
  4334. break;
  4335. #endif
  4336. default:
  4337. break;
  4338. }
  4339. if (rpdesk == pdesk) {
  4340. fMatch = TRUE;
  4341. if (bType == TYPE_WINDOW) {
  4342. DEBUGPRINT("matched\n");
  4343. }
  4344. } else if (bType == TYPE_WINDOW) {
  4345. DEBUGPRINT("unmatched\n");
  4346. }
  4347. } except (CONTINUE) {
  4348. Print("Exception!\n");
  4349. }
  4350. if (!fMatch) {
  4351. continue;
  4352. }
  4353. acHandles[bType]++;
  4354. if (opts & OFLAG(v)) {
  4355. BYTE bFlags;
  4356. move(bFlags, phe + offsetBFlags);
  4357. Print("\r0x%08lx %c %s\n",
  4358. i,
  4359. (bFlags & HANDLEF_DESTROY) ? '*' : ' ',
  4360. aszTypeNames[bType]);
  4361. }
  4362. NEXTEACHHANDLEENTRY()
  4363. Print("\r");
  4364. if (!(opts & OFLAG(v))) {
  4365. Print(" \n");
  4366. Print("Count Type\n");
  4367. Print("--------------------\n");
  4368. for (i = 0; i < ARRAY_SIZE(acHandles); i++) {
  4369. if (abTrack[i])
  4370. Print("0x%08lx %s\n", acHandles[i], aszTypeNames[i]);
  4371. }
  4372. }
  4373. }
  4374. } except (CONTINUE) {
  4375. Print("AV!\n");
  4376. }
  4377. Print(" \n");
  4378. return TRUE;
  4379. }
  4380. #endif // KERNEL
  4381. BOOL IsNumChar(int c, int base)
  4382. {
  4383. return ('0' <= c && c <= '9') ||
  4384. (base == 16 && (('a' <= c && c <= 'f') || ('A' <= c && c <= 'F')));
  4385. }
  4386. NTSTATUS GetInteger(
  4387. LPSTR psz,
  4388. int base,
  4389. int *pi,
  4390. LPSTR *ppsz)
  4391. {
  4392. NTSTATUS Status = STATUS_INVALID_PARAMETER;
  4393. for (;;) {
  4394. if (IsNumChar(*psz, base)) {
  4395. Status = RtlCharToInteger(psz, base, pi);
  4396. if (ppsz && NT_SUCCESS(Status)) {
  4397. while (IsNumChar(*psz++, base)) {
  4398. /* do nothing */;
  4399. }
  4400. *ppsz = psz;
  4401. }
  4402. break;
  4403. }
  4404. if (*psz != ' ' && *psz != '\t') {
  4405. break;
  4406. }
  4407. psz++;
  4408. }
  4409. return Status;
  4410. }
  4411. typedef VOID (*PFNSETRIPFLAGS)(DWORD);
  4412. typedef DWORD (*PFNGETRIPFLAGS)(VOID);
  4413. typedef DWORD (*PFNGETRIPPID)(VOID);
  4414. BOOL Idf(DWORD opts, LPSTR pszName)
  4415. {
  4416. static char *szLevels[8] = {
  4417. "<none>",
  4418. "Errors",
  4419. "Warnings",
  4420. "Errors and Warnings",
  4421. "Verbose",
  4422. "Errors and Verbose",
  4423. "Warnings and Verbose",
  4424. "Errors, Warnings, and Verbose"
  4425. };
  4426. #ifndef KERNEL
  4427. PFNSETRIPFLAGS lpfnSetRipFlags;
  4428. static PFNGETRIPFLAGS lpfnGetRipFlags = NULL;
  4429. HMODULE hMod;
  4430. #endif
  4431. NTSTATUS Status;
  4432. ULONG ulFlags;
  4433. ULONG64 psi;
  4434. DWORD dwRipFlags = 0;
  4435. ULONG offsetRIPFlags;
  4436. if (opts & OFLAG(x)) {
  4437. /*
  4438. * !df -x foo
  4439. * This is an undocumented way to start a remote CMD session named
  4440. * "foo" on the machine that the debugger is running on.
  4441. * Sometimes useful to assist in debugging.
  4442. * Sometimes useful when trying to do dev work from home: if you don't
  4443. * already have a remote cmd.exe session to connect to, you probably
  4444. * have a remote debug session. You can use this debug extension to
  4445. * start a remote cmd session.
  4446. */
  4447. BOOL bRet;
  4448. char ach[80];
  4449. PROCESS_INFORMATION ProcessInfo;
  4450. STARTUPINFOA StartupInfoA;
  4451. if (pszName[0] == '\0') {
  4452. Print("must provide a name. eg; \"!df -x fred\"\n");
  4453. return TRUE;
  4454. }
  4455. sprintf(ach, "remote.exe /s cmd.exe %s", pszName);
  4456. RtlZeroMemory(&StartupInfoA, sizeof(STARTUPINFOA));
  4457. StartupInfoA.cb = sizeof(STARTUPINFOA);
  4458. StartupInfoA.lpTitle = pszName;
  4459. StartupInfoA.dwFlags = STARTF_USESHOWWINDOW;
  4460. StartupInfoA.wShowWindow = SW_SHOWMINIMIZED; // SW_HIDE is *too* sneaky
  4461. bRet = CreateProcessA(NULL,
  4462. ach,
  4463. NULL,
  4464. NULL,
  4465. FALSE,
  4466. CREATE_NEW_CONSOLE,
  4467. NULL,
  4468. NULL,
  4469. &StartupInfoA,
  4470. &ProcessInfo);
  4471. if (bRet) {
  4472. Print("Successfully created a minimized remote cmd process\n");
  4473. Print("use \"remote /c <machine> %s\" to connect\n", pszName);
  4474. Print("use \"exit\" to kill the remote cmd process\n");
  4475. }
  4476. NtClose(ProcessInfo.hProcess);
  4477. NtClose(ProcessInfo.hThread);
  4478. return TRUE;
  4479. }
  4480. psi = GetGlobalPointer(VAR(gpsi));
  4481. GetFieldOffset(SYM(SERVERINFO), "dwRIPFlags", &offsetRIPFlags);
  4482. #if 0
  4483. /*
  4484. * If !df is run against a fre system, neither of these fields will
  4485. * be present in the SERVERINFO structure, and thus the offsets will
  4486. * both be zero.
  4487. */
  4488. if (offsetRIPFlags == 0) {
  4489. Print("!df not supported on this system.\n");
  4490. return TRUE;
  4491. }
  4492. #endif
  4493. #ifndef KERNEL
  4494. hMod = GetModuleHandle(L"user32.dll");
  4495. if (opts & OFLAG(p)) {
  4496. lpfnSetRipFlags = (PFNSETRIPFLAGS)GetProcAddress(hMod,
  4497. "PrivateSetRipFlags");
  4498. } else {
  4499. lpfnSetRipFlags = (PFNSETRIPFLAGS)GetProcAddress(hMod,
  4500. "SetRipFlags");
  4501. }
  4502. if (lpfnSetRipFlags == NULL) {
  4503. Print("Error getting address for %sSetRipFlags export: 0x%x\n",
  4504. (opts & OFLAG(p)) ? "Private" : "",
  4505. GetLastError());
  4506. return TRUE;
  4507. }
  4508. if (lpfnGetRipFlags == NULL) {
  4509. lpfnGetRipFlags = (PFNGETRIPFLAGS)GetProcAddress(hMod, "GetRipFlags");
  4510. if (lpfnGetRipFlags == NULL) {
  4511. Print("Error getting address for GetRipFlags export: 0x%x\n",
  4512. GetLastError());
  4513. return TRUE;
  4514. }
  4515. }
  4516. #endif
  4517. #ifdef KERNEL
  4518. move(dwRipFlags, psi + offsetRIPFlags);
  4519. #else
  4520. dwRipFlags = (*lpfnGetRipFlags)();
  4521. #endif
  4522. Status = GetInteger(pszName, 16, &ulFlags, NULL);
  4523. if (NT_SUCCESS(Status) && !(ulFlags & ~RIPF_VALIDUSERFLAGS)) {
  4524. #ifdef KERNEL
  4525. dwRipFlags = (dwRipFlags & ~RIPF_VALIDUSERFLAGS) | ulFlags;
  4526. (lpExtensionApis->lpWriteProcessMemoryRoutine)(psi + offsetRIPFlags,
  4527. (PVOID)&dwRipFlags,
  4528. sizeof(dwRipFlags),
  4529. NULL);
  4530. move(dwRipFlags, psi + offsetRIPFlags);
  4531. #else
  4532. (*lpfnSetRipFlags)(ulFlags);
  4533. dwRipFlags = (*lpfnGetRipFlags)();
  4534. #endif
  4535. }
  4536. Print("Flags = %.3x\n", dwRipFlags & RIPF_VALIDUSERFLAGS);
  4537. Print(" Print Process/Component %sabled\n", (dwRipFlags & RIPF_HIDEPID) ? "dis" : "en");
  4538. Print(" Print File/Line %sabled\n", (dwRipFlags & RIPF_PRINTFILELINE) ? "en" : "dis");
  4539. Print(" Print on %s\n", szLevels[(dwRipFlags & RIPF_PRINT_MASK) >> RIPF_PRINT_SHIFT]);
  4540. Print(" Prompt on %s\n", szLevels[(dwRipFlags & RIPF_PROMPT_MASK) >> RIPF_PROMPT_SHIFT]);
  4541. if (opts & OFLAG(p)) {
  4542. Print(" RIPs shown for process %ld (0x%lX)\n",
  4543. HandleToUlong(NtCurrentTeb()->ClientId.UniqueProcess),
  4544. HandleToUlong(NtCurrentTeb()->ClientId.UniqueProcess));
  4545. } else {
  4546. Print(" All process RIPs are shown\n");
  4547. }
  4548. return TRUE;
  4549. }
  4550. #ifdef KERNEL
  4551. VOID DumpHotkeyWorker(
  4552. ULONG64 phk,
  4553. BOOL bRecursive)
  4554. {
  4555. WORD fsModifiers;
  4556. UINT vk;
  4557. PTR pwnd;
  4558. PTR pti;
  4559. int id;
  4560. SAFEWHILE (phk != 0) {
  4561. Print("photkey @ 0x%p\n", phk);
  4562. GetFieldValue(phk, SYM(HOTKEY), "vk", vk);
  4563. GetFieldValue(phk, SYM(HOTKEY), "fsModifiers", fsModifiers);
  4564. Print(" fsModifiers %lx, vk %x - ", fsModifiers, vk);
  4565. Print("%s%s%s%sVK:%x %s",
  4566. fsModifiers & MOD_SHIFT ? "Shift + " : "",
  4567. fsModifiers & MOD_ALT ? "Alt + " : "",
  4568. fsModifiers & MOD_CONTROL ? "Ctrl + " : "",
  4569. fsModifiers & MOD_WIN ? "Win + " : "",
  4570. vk,
  4571. GetVKeyName(vk));
  4572. GetFieldValue(phk, SYM(HOTKEY), "id", id);
  4573. GetFieldValue(phk, SYM(HOTKEY), "pti", pti);
  4574. GetFieldValue(phk, SYM(HOTKEY), "spwnd", pwnd);
  4575. Print("\n id %x\n", id);
  4576. Print(" pti %lx\n", pti);
  4577. Print(" pwnd %lx = ", pwnd);
  4578. if (pwnd == (PTR)PWND_FOCUS) {
  4579. Print("PWND_FOCUS\n");
  4580. } else if (pwnd == (PTR)PWND_INPUTOWNER) {
  4581. Print("PWND_INPUTOWNER\n");
  4582. } else {
  4583. CHAR ach[80];
  4584. /*
  4585. * Print title string.
  4586. */
  4587. DebugGetWindowTextA(pwnd, ach, ARRAY_SIZE(ach));
  4588. Print("\"%s\"\n", ach);
  4589. }
  4590. Print("\n");
  4591. if (bRecursive) {
  4592. GetFieldValue(phk, SYM(HOTKEY), "phkNext", phk);
  4593. } else {
  4594. break;
  4595. }
  4596. }
  4597. }
  4598. /***************************************************************************\
  4599. * dhot - dump hotkeys
  4600. *
  4601. * dhot - dumps all hotkeys
  4602. *
  4603. * 10/21/1994 IanJa Created.
  4604. * 06/09/1995 SanfordS Made to fit stdexts motif.
  4605. * 08/15/2002 JasonSch Modified to use new hotkey hash table.
  4606. \***************************************************************************/
  4607. BOOL Idhot(
  4608. DWORD opts,
  4609. ULONG64 phk)
  4610. {
  4611. if (!phk) {
  4612. DWORD dwPointerSize = GetTypeSize("PVOID");
  4613. int i = 0;
  4614. ULONG64 pwnd, pti, phkT;
  4615. phk = EvalExp(VAR(gphkHashTable));
  4616. for (; i < 128; ++i) {
  4617. ReadPointer(phk, &phkT);
  4618. GetFieldValue(phkT, SYM(HOTKEY), "pti", pti);
  4619. GetFieldValue(phkT, SYM(HOTKEY), "spwnd", pwnd);
  4620. if (pti != 0 || pwnd != 0) {
  4621. DumpHotkeyWorker(phkT, TRUE);
  4622. }
  4623. phk += dwPointerSize;
  4624. }
  4625. } else {
  4626. DumpHotkeyWorker(phk, !!(opts & OFLAG(r)));
  4627. }
  4628. return TRUE;
  4629. }
  4630. ULONG dhkCallback(
  4631. ULONG64 pti,
  4632. PVOID pData)
  4633. {
  4634. UNREFERENCED_PARAMETER(pData);
  4635. Idhk(OFLAG(r), pti);
  4636. return FALSE;
  4637. }
  4638. /***************************************************************************\
  4639. * dhk - dump hooks
  4640. *
  4641. * dhk - dumps local hooks on the foreground thread
  4642. * dhk g - dumps global hooks
  4643. * dhk address - dumps local hooks on THREADINFO at address
  4644. * dhk g address - dumps global hooks and local hooks on THREADINFO at address
  4645. * dhk * - dumps local hooks for all threads
  4646. * dhk g * - dumps global hooks and local hooks for all threads
  4647. *
  4648. * 10/21/94 IanJa Created.
  4649. * 6/9/1995 SanfordS made to fit stdexts motif
  4650. \***************************************************************************/
  4651. BOOL Idhk(
  4652. DWORD opts,
  4653. ULONG64 param1)
  4654. {
  4655. DWORD dwFlags;
  4656. PTR pti;
  4657. PTR pq = NULL_PTR;
  4658. BOOL fDumpDllName = opts & OFLAG(d);
  4659. static PTR gptiHkForeground;
  4660. #define DHKF_GLOBAL_HOOKS 1
  4661. #define DHKF_PTI_GIVEN 2
  4662. dwFlags = 0;
  4663. pti = NULL_PTR;
  4664. if (opts & OFLAG(g)) { // global hooks
  4665. dwFlags |= DHKF_GLOBAL_HOOKS;
  4666. }
  4667. if ((opts & OFLAG(r)) == 0) { // -r cannot be specified from the command line
  4668. // first time sets gptiHkForeground
  4669. pq = GetGlobalPointer(VAR(gpqForeground));
  4670. if (pq) {
  4671. GetFieldValue(pq, SYM(tagQ), "ptiKeyboard", gptiHkForeground);
  4672. } else {
  4673. // Happens during winlogon
  4674. gptiHkForeground = NULL_PTR;
  4675. }
  4676. }
  4677. if (param1 == 0) { // n.b. call from dhkCallback should always set param1
  4678. if (opts & OFLAG(c)) {
  4679. // !dhk -c: Use the current thread.
  4680. pti = GetGlobalPointer(VAR(gptiCurrent));
  4681. } else if (pq == NULL_PTR) {
  4682. // Happens during winlogon
  4683. Print("No foreground queue!\n");
  4684. return TRUE;
  4685. } else {
  4686. pti = gptiHkForeground;
  4687. }
  4688. } else {
  4689. dwFlags |= DHKF_PTI_GIVEN;
  4690. pti = param1;
  4691. }
  4692. if ((dwFlags & DHKF_PTI_GIVEN || !(dwFlags & DHKF_GLOBAL_HOOKS)) && (opts & OFLAG(a)) == 0) {
  4693. DWORD fsHooks;
  4694. GetFieldValue(pti, SYM(tagTHREADINFO), "fsHooks", fsHooks);
  4695. if (fsHooks || (opts & OFLAG(r)) == 0) {
  4696. Print("Local hooks on PTHREADINFO @ 0x%p%s:\n", pti,
  4697. pti == gptiHkForeground ? " (foreground thread)" : "");
  4698. Idt(OFLAG(p), pti);
  4699. DumpLHooks(pti, "WH_MSGFILTER", WH_MSGFILTER, fDumpDllName);
  4700. DumpLHooks(pti, "WH_JOURNALRECORD", WH_JOURNALRECORD, fDumpDllName);
  4701. DumpLHooks(pti, "WH_JOURNALPLAYBACK", WH_JOURNALPLAYBACK, fDumpDllName);
  4702. DumpLHooks(pti, "WH_KEYBOARD", WH_KEYBOARD, fDumpDllName);
  4703. DumpLHooks(pti, "WH_GETMESSAGE", WH_GETMESSAGE, fDumpDllName);
  4704. DumpLHooks(pti, "WH_CALLWNDPROC", WH_CALLWNDPROC, fDumpDllName);
  4705. DumpLHooks(pti, "WH_CALLWNDPROCRET", WH_CALLWNDPROCRET, fDumpDllName);
  4706. DumpLHooks(pti, "WH_CBT", WH_CBT, fDumpDllName);
  4707. DumpLHooks(pti, "WH_SYSMSGFILTER", WH_SYSMSGFILTER, fDumpDllName);
  4708. DumpLHooks(pti, "WH_MOUSE", WH_MOUSE, fDumpDllName);
  4709. DumpLHooks(pti, "WH_HARDWARE", WH_HARDWARE, fDumpDllName);
  4710. DumpLHooks(pti, "WH_DEBUG", WH_DEBUG, fDumpDllName);
  4711. DumpLHooks(pti, "WH_SHELL", WH_SHELL, fDumpDllName);
  4712. DumpLHooks(pti, "WH_FOREGROUNDIDLE", WH_FOREGROUNDIDLE, fDumpDllName);
  4713. DumpLHooks(pti, "WH_KEYBOARD_LL", WH_KEYBOARD_LL, fDumpDllName);
  4714. DumpLHooks(pti, "WH_MOUSE_LL", WH_MOUSE_LL, fDumpDllName);
  4715. }
  4716. }
  4717. if (dwFlags & DHKF_GLOBAL_HOOKS) {
  4718. PTR pDeskInfo;
  4719. PTR rpdesk;
  4720. DWORD fsHooks;
  4721. GetFieldValue(pti, SYM(tagTHREADINFO), "pDeskInfo", pDeskInfo);
  4722. GetFieldValue(pti, SYM(tagTHREADINFO), "rpdesk", rpdesk);
  4723. GetFieldValue(pDeskInfo, SYM(DESKTOPINFO), "fsHooks", fsHooks);
  4724. Print("Global hooks for Desktop @ 0x%p:\n", rpdesk);
  4725. Print("\tfsHooks 0x%08lx\n", fsHooks);
  4726. DumpHooks(pDeskInfo, "WH_MSGFILTER", WH_MSGFILTER, fDumpDllName);
  4727. DumpHooks(pDeskInfo, "WH_JOURNALRECORD", WH_JOURNALRECORD, fDumpDllName);
  4728. DumpHooks(pDeskInfo, "WH_JOURNALPLAYBACK", WH_JOURNALPLAYBACK, fDumpDllName);
  4729. DumpHooks(pDeskInfo, "WH_KEYBOARD", WH_KEYBOARD, fDumpDllName);
  4730. DumpHooks(pDeskInfo, "WH_GETMESSAGE", WH_GETMESSAGE, fDumpDllName);
  4731. DumpHooks(pDeskInfo, "WH_CALLWNDPROC", WH_CALLWNDPROC, fDumpDllName);
  4732. DumpHooks(pDeskInfo, "WH_CALLWNDPROCRET", WH_CALLWNDPROCRET, fDumpDllName);
  4733. DumpHooks(pDeskInfo, "WH_CBT", WH_CBT, fDumpDllName);
  4734. DumpHooks(pDeskInfo, "WH_SYSMSGFILTER", WH_SYSMSGFILTER, fDumpDllName);
  4735. DumpHooks(pDeskInfo, "WH_MOUSE", WH_MOUSE, fDumpDllName);
  4736. DumpHooks(pDeskInfo, "WH_HARDWARE", WH_HARDWARE, fDumpDllName);
  4737. DumpHooks(pDeskInfo, "WH_DEBUG", WH_DEBUG, fDumpDllName);
  4738. DumpHooks(pDeskInfo, "WH_SHELL", WH_SHELL, fDumpDllName);
  4739. DumpHooks(pDeskInfo, "WH_FOREGROUNDIDLE", WH_FOREGROUNDIDLE, fDumpDllName);
  4740. DumpHooks(pDeskInfo, "WH_KEYBOARD_LL", WH_KEYBOARD_LL, fDumpDllName);
  4741. DumpHooks(pDeskInfo, "WH_MOUSE_LL", WH_MOUSE_LL, fDumpDllName);
  4742. }
  4743. if (opts & OFLAG(a)) {
  4744. ForEachPti(dhkCallback, NULL);
  4745. }
  4746. return TRUE;
  4747. }
  4748. #endif // KERNEL
  4749. typedef VOID (*PFNSETDBGTAG)(int, DWORD);
  4750. BOOL Itag(
  4751. DWORD opts,
  4752. LPSTR pszName)
  4753. {
  4754. NTSTATUS Status;
  4755. PTR psi, pdbgtag;
  4756. DWORD dwAchNameOffset, dwAchDescOffset;
  4757. char achName[DBGTAG_NAMELENGTH];
  4758. char achDesc[DBGTAG_DESCRIPTIONLENGTH];
  4759. int tag = -1;
  4760. DWORD dwDBGTAGFlags, dwDBGTAGFlagsNew, dwOffset;
  4761. DWORD dwSize;
  4762. int i, iStart, iEnd;
  4763. char szT[100];
  4764. #ifndef KERNEL
  4765. static PFNSETDBGTAG lpfnSetDbgTag = NULL;
  4766. #endif
  4767. UNREFERENCED_PARAMETER(opts);
  4768. GetFieldOffset(SYM(SERVERINFO), "adwDBGTAGFlags", &dwOffset);
  4769. /*
  4770. * Get the tag index.
  4771. */
  4772. psi = GetGlobalPointer(VAR(gpsi));
  4773. if (!psi) {
  4774. Print("Couldn't get win32k!gpsi; bad symbols?\n");
  4775. return TRUE;
  4776. }
  4777. #ifndef KERNEL
  4778. if (lpfnSetDbgTag == NULL) {
  4779. HMODULE hMod = GetModuleHandle(L"user32.dll");
  4780. if (hMod != NULL) {
  4781. lpfnSetDbgTag = (PFNSETDBGTAG)GetProcAddress(hMod,
  4782. "SetDbgTag");
  4783. }
  4784. if (lpfnSetDbgTag == NULL) {
  4785. Print("Error getting address of SetDbgTag export (0x%x)\n",
  4786. GetLastError());
  4787. return TRUE;
  4788. }
  4789. }
  4790. #endif
  4791. Status = GetInteger(pszName, 10, &tag, &pszName);
  4792. if (*pszName != '\0' && !NT_SUCCESS(Status)) {
  4793. Print("ERROR: Dwayne, you must refer to tags by their number, not their name. How long have you been here?\n\n");
  4794. return FALSE;
  4795. }
  4796. if (!NT_SUCCESS(Status) || tag < 0 || DBGTAG_Max <= tag) {
  4797. tag = -1;
  4798. } else {
  4799. /*
  4800. * Get the flag value.
  4801. */
  4802. Status = GetInteger(pszName, 16, &dwDBGTAGFlagsNew, NULL);
  4803. if (NT_SUCCESS(Status) && !(dwDBGTAGFlagsNew & ~DBGTAG_VALIDUSERFLAGS)) {
  4804. /*
  4805. * Set the flag value.
  4806. */
  4807. #ifdef KERNEL
  4808. ReadMemory(psi + dwOffset + tag * sizeof(DWORD), &dwDBGTAGFlags, sizeof(DWORD), NULL);
  4809. COPY_FLAG(dwDBGTAGFlags, dwDBGTAGFlagsNew, DBGTAG_VALIDUSERFLAGS);
  4810. WriteMemory((psi + dwOffset + tag * sizeof(DWORD)), &dwDBGTAGFlags, sizeof(dwDBGTAGFlags), NULL);
  4811. #else
  4812. (*lpfnSetDbgTag)(tag, dwDBGTAGFlagsNew);
  4813. #endif
  4814. }
  4815. }
  4816. /*
  4817. * Print the header.
  4818. */
  4819. Print( "%-5s%-7s%-*s%-*s\n",
  4820. "Tag",
  4821. "Flags",
  4822. DBGTAG_NAMELENGTH,
  4823. "Name",
  4824. DBGTAG_DESCRIPTIONLENGTH,
  4825. "Description");
  4826. for (i = 0; i < 12 + DBGTAG_NAMELENGTH + DBGTAG_DESCRIPTIONLENGTH; i++) {
  4827. szT[i] = '-';
  4828. }
  4829. szT[i++] = '\n';
  4830. szT[i] = 0;
  4831. Print(szT);
  4832. if (tag != -1) {
  4833. iStart = iEnd = tag;
  4834. } else {
  4835. iStart = 0;
  4836. GetFieldValue(psi, SYM(SERVERINFO), "dwTagCount", iEnd);
  4837. }
  4838. psi += dwOffset;
  4839. pdbgtag = EvalExp(VAR(gadbgtag));
  4840. if (!pdbgtag) {
  4841. /*
  4842. * EvalExp already complained, so just return.
  4843. */
  4844. return TRUE;
  4845. }
  4846. GetFieldOffset(SYM(DBGTAG), "achName", &dwAchNameOffset);
  4847. GetFieldOffset(SYM(DBGTAG), "achDescription", &dwAchDescOffset);
  4848. dwSize = GetTypeSize(SYM(DBGTAG));
  4849. for (i = iStart; i <= iEnd; i++) {
  4850. ReadMemory(psi + i * sizeof(DWORD), &dwDBGTAGFlags, sizeof(DWORD), NULL);
  4851. if (pdbgtag) {
  4852. if (!ReadMemory(pdbgtag + dwAchNameOffset + i * dwSize, achName, DBGTAG_NAMELENGTH, NULL)) {
  4853. strcpy(achName, "(Not available)");
  4854. }
  4855. if (!ReadMemory(pdbgtag + dwAchDescOffset + i * dwSize, achDesc, DBGTAG_DESCRIPTIONLENGTH, NULL)) {
  4856. strcpy(achDesc, "(Not available)");
  4857. }
  4858. }
  4859. Print( "%-5d%-7d%-*s%-*s\n",
  4860. i,
  4861. dwDBGTAGFlags & DBGTAG_VALIDUSERFLAGS,
  4862. DBGTAG_NAMELENGTH,
  4863. achName,
  4864. DBGTAG_DESCRIPTIONLENGTH,
  4865. achDesc);
  4866. }
  4867. return TRUE;
  4868. }
  4869. /************************************************************************\
  4870. * Idhe
  4871. *
  4872. * Dump Handle Entry.
  4873. *
  4874. * 6/9/1995 Created SanfordS
  4875. \************************************************************************/
  4876. BOOL Idhe(
  4877. DWORD opts,
  4878. ULONG64 param1,
  4879. ULONG64 param2)
  4880. {
  4881. /* 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123456789 */
  4882. static const char szHeader [] = "Phe Handle phead pOwner cLockObj Type Flags\n";
  4883. static const char szHeader64[] = "Phe Handle phead pOwner cLockObj Type Flags\n";
  4884. static const char szFormat [] = "%p %p %p %p %7x %-15s %#4lx\n";
  4885. int i;
  4886. UINT uHandleCount = 0;
  4887. BYTE bType, bFlags;
  4888. PTR dw, phe, pheT, pOwner, pHead, h;
  4889. DWORD cLockObj;
  4890. WORD wUniq;
  4891. #ifdef KERNEL
  4892. PTR pahti = 0, ppi;
  4893. ULONG dwHtiSize = GetTypeSize(SYM(HANDLETYPEINFO));
  4894. BOOL bObjectCreateFlags;
  4895. #endif // KERNEL
  4896. /*
  4897. * If only the owner was provided, copy it to param2 so it's always in the
  4898. * same place.
  4899. */
  4900. if (!(opts & OFLAG(t)) && (opts & OFLAG(o))) {
  4901. param2 = param1;
  4902. }
  4903. /*
  4904. * If not a recursive call, print what we're dumping.
  4905. */
  4906. if (!(opts & OFLAG(r)) && (opts & (OFLAG(t) | OFLAG(o) | OFLAG(p)))) {
  4907. Print("Dumping handles");
  4908. if (opts & OFLAG(t)) {
  4909. if ((UINT_PTR)param1 >= TYPE_CTYPES) {
  4910. Print("\nInvalid Type: %#lx\n", param1);
  4911. return FALSE;
  4912. }
  4913. Print(" of type %d (%s)", (ULONG)param1, aszTypeNames[(UINT_PTR)param1]);
  4914. }
  4915. if (opts & OFLAG(o)) {
  4916. Print(" owned by %p", param2);
  4917. }
  4918. if (opts & OFLAG(p)) {
  4919. Print(" or any thread on this process");
  4920. }
  4921. Print("\n");
  4922. }
  4923. #ifdef KERNEL
  4924. /*
  4925. * If dumping handles for any thread in the process, we need the type flags.
  4926. */
  4927. if (opts & OFLAG(p)) {
  4928. pahti = EvalExp(VAR(gahti));
  4929. if (!pahti) {
  4930. Print("Couldn't get win32k!gahti\n");
  4931. return TRUE;
  4932. }
  4933. }
  4934. #endif // KERNEL
  4935. /*
  4936. * If a handle/phe was provided, just dump it.
  4937. */
  4938. if (!(opts & ~OFLAG(r)) && param1 != 0) {
  4939. dw = HorPtoP(param1, -2);
  4940. if (dw == 0) {
  4941. Print("0x%p is not a valid object or handle.\n", param1);
  4942. return FALSE;
  4943. }
  4944. } else {
  4945. /*
  4946. * Walk the handle table
  4947. */
  4948. Print(IsPtr64() ? szHeader64 : szHeader);
  4949. FOREACHHANDLEENTRY(phe, i)
  4950. /* Skip free handles */
  4951. GetFieldValue(phe, SYM(HANDLEENTRY), "bType", bType);
  4952. if (bType == TYPE_FREE) {
  4953. continue;
  4954. }
  4955. /* Type check */
  4956. if ((opts & OFLAG(t)) && bType != (BYTE)param1) {
  4957. continue;
  4958. }
  4959. /* thread check */
  4960. GetFieldValue(phe, SYM(HANDLEENTRY), "pOwner", pOwner);
  4961. if ((opts & OFLAG(o)) && FIXKP(pOwner) != param2) {
  4962. /* check for thread owned objects owned by the requested process */
  4963. if (opts & OFLAG(p)) {
  4964. #ifndef KERNEL
  4965. continue;
  4966. #else
  4967. GetFieldValue(pahti + bType * dwHtiSize, SYM(HANDLETYPEINFO), "bObjectCreateFlags", bObjectCreateFlags);
  4968. if (bObjectCreateFlags & OCF_PROCESSOWNED) {
  4969. continue;
  4970. }
  4971. if (!(bObjectCreateFlags & OCF_THREADOWNED)) {
  4972. continue;
  4973. }
  4974. GetFieldValue(pOwner, SYM(THREADINFO), "ppi", ppi);
  4975. if (ppi != param2) {
  4976. continue;
  4977. }
  4978. #endif // !KERNEL
  4979. } else {
  4980. continue;
  4981. }
  4982. }
  4983. GetFieldValue(phe, SYM(HANDLEENTRY), "phead", pHead);
  4984. if (pHead) {
  4985. Idhe(OFLAG(r), pHead, 0);
  4986. uHandleCount++;
  4987. }
  4988. NEXTEACHHANDLEENTRY()
  4989. Print("%d handle(s)\n", uHandleCount);
  4990. return TRUE;
  4991. }
  4992. if (!getHEfromP(&pheT, dw)) {
  4993. Print("%p is not a USER handle manager object.\n", param1);
  4994. return FALSE;
  4995. }
  4996. #ifdef KERNEL
  4997. /*
  4998. * If printing only one entry, print info about the owner
  4999. */
  5000. if (!(opts & OFLAG(r))) {
  5001. GetFieldValue(pheT, SYM(HANDLEENTRY), "pOwner", pOwner);
  5002. if (pOwner != 0) {
  5003. if (!(opts & OFLAG(p))) {
  5004. pahti = EvalExp(VAR(gahti));
  5005. }
  5006. GetFieldValue(pheT, SYM(HANDLEENTRY), "bType", bType);
  5007. GetFieldValue(pahti + bType * dwHtiSize, SYM(HANDLETYPEINFO), "bObjectCreateFlags", bObjectCreateFlags);
  5008. if (bObjectCreateFlags & OCF_PROCESSOWNED) {
  5009. Idp(OFLAG(p), pOwner);
  5010. } else if (bObjectCreateFlags & OCF_THREADOWNED) {
  5011. Idt(OFLAG(p), pOwner);
  5012. }
  5013. }
  5014. }
  5015. #endif // KERNEL
  5016. GetFieldValue(dw, SYM(HEAD), "cLockObj", cLockObj);
  5017. GetFieldValue(dw, SYM(HEAD), "h", h);
  5018. GetFieldValue(pheT, SYM(HANDLEENTRY), "phead", pHead);
  5019. GetFieldValue(pheT, SYM(HANDLEENTRY), "pOwner", pOwner);
  5020. GetFieldValue(pheT, SYM(HANDLEENTRY), "bType", bType);
  5021. GetFieldValue(pheT, SYM(HANDLEENTRY), "bFlags", bFlags);
  5022. GetFieldValue(pheT, SYM(HANDLEENTRY), "wUniq", wUniq);
  5023. /*
  5024. * If only dumping one, use !dso like format. Otherwise, print a table.
  5025. */
  5026. if (!(opts & OFLAG(r))) {
  5027. Print("0x%08x handle @ 0x%p\n", (DWORD)h, pheT);
  5028. Print("%4c0x%04x %-16s 0x%p %s\n",
  5029. ' ', (DWORD)(WORD)wUniq, "wUniq", pOwner, "pOwner");
  5030. Print("0x%p %-16s 0x%08x cLockObj\n",
  5031. pHead, "pHead", (DWORD)cLockObj);
  5032. Print(DWSTR1 " - %s\n", bType, "bType", aszTypeNames[bType]);
  5033. Print(DWSTR1 " - %s\n", bFlags,"bFlags", GetFlags(GF_HE, bFlags, NULL, TRUE));
  5034. } else {
  5035. Print(szFormat,
  5036. pheT, h, FIXKP(pHead), FIXKP(pOwner),
  5037. cLockObj, aszTypeNames[(DWORD)bType], (DWORD)bFlags);
  5038. }
  5039. return TRUE;
  5040. }
  5041. #ifdef KERNEL
  5042. /***************************************************************************\
  5043. * dhs - dumps simple statistics for whole table
  5044. * dhs t id - dumps simple statistics for objects created by thread id
  5045. * dhs p id - dumps simple statistics for objects created by process id
  5046. * dhs v - dumps verbose statistics for whole table
  5047. * dhs v t id - dumps verbose statistics for objects created by thread id.
  5048. * dhs v p id - dumps verbose statistics for objects created by process id.
  5049. * dhs y type - just dumps that type
  5050. *
  5051. * Dump handle table statistics.
  5052. *
  5053. * 02-21-92 ScottLu Created.
  5054. * 6/9/1995 SanfordS made to fit stdexts motif
  5055. \***************************************************************************/
  5056. BOOL Idhs(
  5057. DWORD opts,
  5058. ULONG64 param1)
  5059. {
  5060. PTR phe, pOwner, pEprocess, pEThread, pahti;
  5061. DWORD dwT, acHandles[TYPE_CTYPES], dwSize, handle;
  5062. DWORD cHandlesUsed, cHandlesSkipped, idProcess, i;
  5063. BYTE bType, bObjectCreateFlags, bFlags;
  5064. int Type, cLocalHandleEntries = 0;
  5065. pahti = EvalExp(VAR(gahti));
  5066. if (!pahti) {
  5067. return TRUE;
  5068. }
  5069. dwSize = GetTypeSize(SYM(HANDLETYPEINFO));
  5070. /*
  5071. * Evaluate the argument string and get the address of the object to
  5072. * dump. Take either a handle or a pointer to the object.
  5073. */
  5074. if (opts & OFLAG(y)) {
  5075. Type = (ULONG)(ULONG_PTR)param1;
  5076. } else if (opts & (OFLAG(t) | OFLAG(p))) {
  5077. dwT = (ULONG)(ULONG_PTR)param1;
  5078. }
  5079. cHandlesSkipped = 0;
  5080. cHandlesUsed = 0;
  5081. for (i = 0; i < TYPE_CTYPES; i++) {
  5082. acHandles[i] = 0;
  5083. }
  5084. if (param1) {
  5085. if (opts & OFLAG(p)) {
  5086. Print("Handle dump for client process id 0x%lx only:\n\n", dwT);
  5087. } else if (opts & OFLAG(t)) {
  5088. Print("Handle dump for client thread id 0x%lx only:\n\n", dwT);
  5089. } else if (opts & OFLAG(y)) {
  5090. Print("Handle dump for %s objects:\n\n", aszTypeNames[Type]);
  5091. }
  5092. } else {
  5093. Print("Handle dump for all processes and threads:\n\n");
  5094. }
  5095. if (opts & OFLAG(v)) {
  5096. Print("Handle Type\n");
  5097. Print("--------------------\n");
  5098. }
  5099. FOREACHHANDLEENTRY(phe, i)
  5100. ShowProgress();
  5101. ++cLocalHandleEntries;
  5102. GetFieldValue(phe, SYM(HANDLEENTRY), "bFlags", bFlags);
  5103. GetFieldValue(phe, SYM(HANDLEENTRY), "bType", bType);
  5104. if ((opts & OFLAG(y)) && bType != Type) {
  5105. continue;
  5106. }
  5107. GetFieldValue(phe, SYM(HANDLEENTRY), "pOwner", pOwner);
  5108. GetFieldValue(pahti + bType * dwSize, SYM(HANDLETYPEINFO), "bObjectCreateFlags", bObjectCreateFlags);
  5109. if (opts & OFLAG(p)) {
  5110. if (bObjectCreateFlags & OCF_PROCESSOWNED) {
  5111. if (pOwner == 0) {
  5112. continue;
  5113. }
  5114. GetFieldValue(pOwner, SYM(PROCESSINFO), "Process", pEprocess);
  5115. GetFieldValue(pEprocess, "nt!EPROCESS", "UniqueProcessId", idProcess);
  5116. if (idProcess == 0) {
  5117. // Print("Unable to read _EPROCESS at %p\n", pEprocess);
  5118. continue;
  5119. }
  5120. if (idProcess != dwT) {
  5121. continue;
  5122. }
  5123. } else {
  5124. continue;
  5125. }
  5126. } else if (opts & OFLAG(t)) {
  5127. if (!(bObjectCreateFlags & OCF_PROCESSOWNED)) {
  5128. if (pOwner == 0) {
  5129. continue;
  5130. }
  5131. GetFieldValue(pOwner, SYM(THREADINFO), "pEThread", pEThread);
  5132. GetFieldValue(pEThread, "nt!ETHREAD", "Cid.UniqueThread", handle);
  5133. if (handle != dwT) {
  5134. continue;
  5135. }
  5136. } else {
  5137. continue;
  5138. }
  5139. }
  5140. acHandles[bType]++;
  5141. if (bType == TYPE_FREE) {
  5142. continue;
  5143. }
  5144. cHandlesUsed++;
  5145. if (opts & OFLAG(v)) {
  5146. Print("0x%08lx %c %s\n",
  5147. i,
  5148. (bFlags & HANDLEF_DESTROY) ? '*' : ' ',
  5149. aszTypeNames[bType]);
  5150. }
  5151. NEXTEACHHANDLEENTRY()
  5152. Print("\r");
  5153. if (!(opts & OFLAG(v))) {
  5154. Print("Count Type\n");
  5155. Print("--------------------\n");
  5156. for (i = 0; i < TYPE_CTYPES; i++) {
  5157. if ((opts & OFLAG(y)) && Type != (int)i) {
  5158. continue;
  5159. }
  5160. Print("0x%08lx (%d) %s\n", acHandles[i], i, aszTypeNames[i]);
  5161. }
  5162. }
  5163. if (!(opts & OFLAG(y))) {
  5164. Print("\nTotal Accessible Handles: 0x%lx\n", cLocalHandleEntries);
  5165. Print("Used Accessible Handles: 0x%lx\n", cHandlesUsed);
  5166. Print("Free Accessible Handles: 0x%lx\n", cLocalHandleEntries - cHandlesUsed);
  5167. }
  5168. return TRUE;
  5169. }
  5170. #endif // KERNEL
  5171. #ifdef KERNEL
  5172. /***************************************************************************\
  5173. * di - dumps interesting globals in USER related to input.
  5174. *
  5175. * 11-14-91 DavidPe Created.
  5176. * 6/9/1995 SanfordS made to fit stdexts motif
  5177. \***************************************************************************/
  5178. BOOL Idi(
  5179. VOID)
  5180. {
  5181. char ach[80];
  5182. PRTGPTR2(gptiCurrent, grpdeskRitInput);
  5183. PRTGPTR2(gpqForeground, gpqForegroundPrev);
  5184. PRTGPTR2(gptiForeground, gpqCursor);
  5185. PRTGPTR1(gptiBlockInput);
  5186. {
  5187. DWORD dw;
  5188. PTR ptr1;
  5189. dw = DOWNCAST(DWORD, GetGlobalMember(VAR(glinp), SYM(LASTINPUT), "timeLastInputMessage"));
  5190. ptr1 = GetGlobalMember(VAR(glinp), SYM(LASTINPUT), "ptiLastWoken");
  5191. PRTVDW2(glinp.timeLastInputMessage, dw, glinp.ptiLastWoken, ptr1);
  5192. PRTGDW1(gwMouseOwnerButton);
  5193. }
  5194. {
  5195. POINT ptCursor;
  5196. PTR psi = GetGlobalPointer(VAR(gpsi));
  5197. GetFieldValue(psi, SYM(tagSERVERINFO), "ptCursor", ptCursor);
  5198. PRTVPT(gpsi->ptCursor, ptCursor);
  5199. }
  5200. {
  5201. PTR pdesk = GetGlobalPointer(VAR(grpdeskRitInput));
  5202. if (pdesk != NULL_PTR) {
  5203. PTR pDeskInfo;
  5204. PTR spwnd;
  5205. GetFieldValue(pdesk, SYM(tagDESKTOP), "pDeskInfo", pDeskInfo);
  5206. GetFieldValue(pDeskInfo, SYM(tagDESKTOPINFO), "spwnd", spwnd);
  5207. PRTWND(Desktop window, spwnd);
  5208. }
  5209. }
  5210. {
  5211. PTR pq = GetGlobalPointer(VAR(gpqForeground));
  5212. if (pq) {
  5213. PTR spwndFocus, spwndActive;
  5214. GetFieldValue(pq, SYM(tagQ), "spwndFocus", spwndFocus);
  5215. GetFieldValue(pq, SYM(tagQ), "spwndActive", spwndActive);
  5216. PRTWND(gpqForeground->spwndFocus, spwndFocus);
  5217. PRTWND(gpqForeground->spwndActive, spwndActive);
  5218. }
  5219. }
  5220. PRTGWND(gspwndScreenCapture);
  5221. PRTGWND(gspwndInternalCapture);
  5222. PRTGWND(gspwndMouseOwner);
  5223. return TRUE;
  5224. }
  5225. #endif // KERNEL
  5226. /************************************************************************\
  5227. * Idll
  5228. *
  5229. * Dump Linked Lists.
  5230. *
  5231. * ???????? Scottlu Created
  5232. * 6/9/1995 SanfordS made to fit stdexts motif
  5233. \************************************************************************/
  5234. BOOL Idll(
  5235. DWORD opts,
  5236. LPSTR lpas)
  5237. {
  5238. static DWORD iOffset;
  5239. static DWORD cStructs;
  5240. static DWORD cDwords;
  5241. static DWORD cDwordsBack;
  5242. static ULONG64 dw, dwHalfSpeed;
  5243. ULONG64 dwT;
  5244. DWORD cBytesBack;
  5245. DWORD i, j;
  5246. BOOL fIndirectFirst;
  5247. BOOL fTestAndCountOnly = FALSE;
  5248. ULONG64 dwFind = 0;
  5249. DWORD adw[CDWORDS];
  5250. ULONG64 dwValue;
  5251. UNREFERENCED_PARAMETER(opts);
  5252. /*
  5253. * Evaluate the argument string and get the address of the object to
  5254. * dump. Take either a handle or a pointer to the object.
  5255. */
  5256. while (*lpas == ' ') {
  5257. lpas++;
  5258. }
  5259. /*
  5260. * If there are no arguments, keep walking from the last
  5261. * pointer.
  5262. */
  5263. if (*lpas != 0) {
  5264. /*
  5265. * If the address has a '*' in front of it, it means start with the
  5266. * pointer stored at that address.
  5267. */
  5268. fIndirectFirst = FALSE;
  5269. if (*lpas == '*') {
  5270. lpas++;
  5271. fIndirectFirst = TRUE;
  5272. }
  5273. /*
  5274. * Scan past the address.
  5275. */
  5276. dw = dwValue = GetExpression(lpas);
  5277. if (fIndirectFirst) {
  5278. ReadPointer(dw, &dw);
  5279. }
  5280. dwHalfSpeed = dw;
  5281. cStructs = 25;
  5282. cDwords = 8;
  5283. iOffset = cDwordsBack = 0;
  5284. SAFEWHILE (TRUE) {
  5285. while (*lpas == ' ') {
  5286. lpas++;
  5287. }
  5288. switch(*lpas) {
  5289. case 'l':
  5290. /*
  5291. * length of each structure.
  5292. */
  5293. lpas++;
  5294. cDwords = (DWORD)(DWORD_PTR)GetExpression(lpas);
  5295. if (cDwords > CDWORDS) {
  5296. Print("\nl%d? - %d DWORDs maximum\n\n", cDwords, CDWORDS);
  5297. cDwords = CDWORDS;
  5298. }
  5299. break;
  5300. case 'b':
  5301. /*
  5302. * Go back cDwordsBack and dump cDwords from there
  5303. * (useful for LIST_ENTRYs, where Flink doesn't point to
  5304. * the start of the struct). cDwordsBack can be negative,
  5305. * to allow people to start dumping from a certain offset
  5306. * within the structure.
  5307. */
  5308. lpas++;
  5309. cDwordsBack = (DWORD)(DWORD_PTR)GetExpression(lpas);
  5310. if (cDwordsBack >= CDWORDS) {
  5311. Print("\nb%d? - %d DWORDs maximum\n\n", cDwordsBack, CDWORDS - 1);
  5312. cDwordsBack = CDWORDS - 1;
  5313. }
  5314. break;
  5315. case 'o':
  5316. /*
  5317. * Offset of 'next' pointer.
  5318. */
  5319. lpas++;
  5320. iOffset = (DWORD)(DWORD_PTR)GetExpression(lpas);
  5321. break;
  5322. case 'c':
  5323. /*
  5324. * Count of structures to dump
  5325. */
  5326. lpas++;
  5327. cStructs = (DWORD)(DWORD_PTR)GetExpression(lpas);
  5328. break;
  5329. case 'f':
  5330. /*
  5331. * Find element at given address
  5332. */
  5333. lpas++;
  5334. dwFind = EvalExp(lpas);
  5335. break;
  5336. case 't':
  5337. /*
  5338. * Test list for loop, and count
  5339. */
  5340. fTestAndCountOnly = TRUE;
  5341. cStructs = 0x100000;
  5342. default:
  5343. break;
  5344. }
  5345. while (*lpas && *lpas != ' ')
  5346. lpas++;
  5347. if (*lpas == 0)
  5348. break;
  5349. }
  5350. if (cDwordsBack > cDwords) {
  5351. Print("backing up %d DWORDS per struct (b%d): ",
  5352. cDwordsBack, cDwordsBack);
  5353. Print("increasing l%d to l%d so next link is included\n",
  5354. cDwords, cDwordsBack + 1);
  5355. cDwords = cDwordsBack + 1;
  5356. }
  5357. for (i = 0; i < CDWORDS; i++) {
  5358. adw[i] = 0;
  5359. }
  5360. }
  5361. cBytesBack = cDwordsBack * sizeof(DWORD);
  5362. for (i = 0; i < cStructs; i++) {
  5363. moveBlock(adw, (dw - cBytesBack), sizeof(DWORD) * cDwords);
  5364. if (!fTestAndCountOnly) {
  5365. Print("---- 0x%lx:\n", i);
  5366. for (j = 0; j < cDwords; j += 4) {
  5367. switch (cDwords - j) {
  5368. case 1:
  5369. Print("%p: %08lx\n",
  5370. dw + j * sizeof(DWORD),
  5371. adw[j + 0]);
  5372. break;
  5373. case 2:
  5374. Print("%p: %08lx %08lx\n",
  5375. dw + j * sizeof(DWORD),
  5376. adw[j + 0], adw[j + 1]);
  5377. break;
  5378. case 3:
  5379. Print("%p: %08lx %08lx %08lx\n",
  5380. dw + j * sizeof(DWORD),
  5381. adw[j + 0], adw[j + 1], adw[j + 2]);
  5382. break;
  5383. default:
  5384. Print("%p: %08lx %08lx %08lx %08lx\n",
  5385. dw + j * sizeof(DWORD),
  5386. adw[j + 0], adw[j + 1], adw[j + 2], adw[j + 3]);
  5387. }
  5388. }
  5389. } else if ((i & 0xff) == 0xff) {
  5390. Print("item 0x%lx at %p...\n", i+1, dw);
  5391. }
  5392. if (dwFind == dw) {
  5393. Print("====== FOUND ITEM ======\n");
  5394. break;
  5395. }
  5396. /*
  5397. * Give a chance to break out every 16 items
  5398. */
  5399. if ((i & 0xf) == 0xf) {
  5400. if (IsCtrlCHit()) {
  5401. Print("terminated by Ctrl-C on item 0x%lx at %p...\n", i, dw);
  5402. break;
  5403. }
  5404. }
  5405. /*
  5406. * Advance to next item.
  5407. */
  5408. dwT = dw + iOffset * sizeof(DWORD);
  5409. ReadPointer(dwT, &dw);
  5410. if (fTestAndCountOnly) {
  5411. /*
  5412. * Advance dwHalfSpeed every other time round the loop: if
  5413. * dw ever catches up to dwHalfSpeed, then we have a loop!
  5414. */
  5415. if (i & 1) {
  5416. dwT = dwHalfSpeed + iOffset * sizeof(DWORD);
  5417. ReadPointer(dwT, &dwHalfSpeed);
  5418. }
  5419. if (dw == dwHalfSpeed) {
  5420. Print("!!! Loop Detected on item 0x%lx at %lx...\n", i, dw);
  5421. break;
  5422. }
  5423. }
  5424. if (dw == 0) {
  5425. break;
  5426. }
  5427. }
  5428. Print("---- Total 0x%lx items ----\n", i+1);
  5429. return TRUE;
  5430. }
  5431. /************************************************************************\
  5432. * Ifind
  5433. *
  5434. * Find Linked List Element
  5435. *
  5436. * 11/22/95 JimA Created.
  5437. \************************************************************************/
  5438. BOOL Ifind(
  5439. DWORD opts,
  5440. LPSTR lpas)
  5441. {
  5442. DWORD iOffset = 0;
  5443. ULONG64 dwBase, dwAddr, dwTest, dwT, dwLast = 0;
  5444. UNREFERENCED_PARAMETER(opts);
  5445. /*
  5446. * Evaluate the argument string and get the address of the object to
  5447. * dump. Take either a handle or a pointer to the object.
  5448. */
  5449. while (*lpas == ' ') {
  5450. lpas++;
  5451. }
  5452. /*
  5453. * If there are no arguments, keep walking from the last
  5454. * pointer.
  5455. */
  5456. if (*lpas != 0) {
  5457. /*
  5458. * Scan past the addresses.
  5459. */
  5460. dwBase = EvalExp(lpas);
  5461. while (*lpas && *lpas != ' ') {
  5462. lpas++;
  5463. }
  5464. dwAddr = EvalExp(lpas);
  5465. while (*lpas && *lpas != ' ') {
  5466. lpas++;
  5467. }
  5468. iOffset = 0;
  5469. SAFEWHILE (*lpas != 0) {
  5470. while (*lpas == ' ') {
  5471. lpas++;
  5472. }
  5473. switch(*lpas) {
  5474. case 'o':
  5475. /*
  5476. * Offset of 'next' pointer.
  5477. */
  5478. lpas++;
  5479. iOffset = (DWORD)(DWORD_PTR)EvalExp(lpas);
  5480. break;
  5481. default:
  5482. break;
  5483. }
  5484. while (*lpas && *lpas != ' ') {
  5485. lpas++;
  5486. }
  5487. }
  5488. }
  5489. dwTest = dwBase;
  5490. while (dwTest && (ULONG_PTR)dwTest != (ULONG_PTR)dwAddr) {
  5491. dwLast = dwTest;
  5492. dwT = dwTest + iOffset * sizeof(DWORD);
  5493. move(dwTest, dwT);
  5494. }
  5495. if (dwTest == 0) {
  5496. Print("Address %#p not found\n", dwAddr);
  5497. } else {
  5498. Print("Address %#p found, previous = %#p\n", dwAddr, dwLast);
  5499. }
  5500. return TRUE;
  5501. }
  5502. #ifdef KERNEL
  5503. /***************************************************************************\
  5504. * dlr handle|pointer
  5505. *
  5506. * Dumps lock list for object
  5507. *
  5508. * 02-27-92 ScottLu Created.
  5509. * 6/9/1995 SanfordS made to fit stdexts motif
  5510. \***************************************************************************/
  5511. #define LR_FLAG(x) (1 << (x))
  5512. #define LR_SIMPLELOCK 0
  5513. BOOL Idlr(
  5514. DWORD opts,
  5515. LPSTR lpszParam)
  5516. {
  5517. PTR phe;
  5518. ULONG64 param;
  5519. ULONG64 plrT;
  5520. ULONG64 pTrace;
  5521. ULONG cbPtr, cbOffset;
  5522. ULONG64 psi;
  5523. DWORD dwDBGTAGFlags, dwLockRecordFlags;
  5524. psi = GetGlobalPointer(VAR(gpsi));
  5525. if (GetFieldOffset(SYM(SERVERINFO), "adwDBGTAGFlags", &cbOffset)) {
  5526. Print("failed to get the SERVERINFO::adwDBGTAGFlags\n");
  5527. return TRUE;
  5528. }
  5529. dwDBGTAGFlags = (DWORD)GetArrayElement(psi, SYM(SERVERINFO), "adwDBGTAGFlags", DBGTAG_TrackLocks, "DWORD");
  5530. dwDBGTAGFlags &= DBGTAG_VALIDUSERFLAGS;
  5531. moveExpValue(&dwLockRecordFlags, VAR(gdwLockRecordFlags));
  5532. if (opts & (OFLAG(s) | OFLAG(c))) {
  5533. DWORD flag;
  5534. if (!NT_SUCCESS(GetInteger(lpszParam, 0x10, &flag, NULL))) {
  5535. Print("Invalid arg: '%s'\n", lpszParam);
  5536. return FALSE;
  5537. }
  5538. if (opts & OFLAG(s)) {
  5539. dwLockRecordFlags |= LR_FLAG(flag);
  5540. } else {
  5541. dwLockRecordFlags &= ~LR_FLAG(flag);
  5542. }
  5543. Print("7\n");
  5544. WriteMemory(EvalExp(VAR(gdwLockRecordFlags)), &dwLockRecordFlags, sizeof dwLockRecordFlags, NULL);
  5545. Print("8\n");
  5546. // for to display it
  5547. opts |= OFLAG(l);
  5548. }
  5549. if (opts & OFLAG(l)) {
  5550. #define HT(type) { type, #type }
  5551. static const struct {
  5552. DWORD dwType;
  5553. char* lpszName;
  5554. } flags[] = {
  5555. //{ LR_SIMPLELOCK, "Rec SimpleLock" },
  5556. { LR_SIMPLELOCK, "Reserved" },
  5557. HT(TYPE_WINDOW),
  5558. HT(TYPE_MENU),
  5559. HT(TYPE_CURSOR),
  5560. HT(TYPE_SETWINDOWPOS),
  5561. HT(TYPE_HOOK),
  5562. HT(TYPE_CLIPDATA),
  5563. HT(TYPE_CALLPROC),
  5564. HT(TYPE_ACCELTABLE),
  5565. HT(TYPE_DDEACCESS),
  5566. HT(TYPE_DDECONV),
  5567. HT(TYPE_DDEXACT),
  5568. HT(TYPE_MONITOR),
  5569. HT(TYPE_KBDLAYOUT),
  5570. HT(TYPE_KBDFILE),
  5571. HT(TYPE_WINEVENTHOOK),
  5572. HT(TYPE_TIMER),
  5573. HT(TYPE_INPUTCONTEXT),
  5574. HT(TYPE_HIDDATA),
  5575. HT(TYPE_DEVICEINFO),
  5576. };
  5577. #undef HT
  5578. UINT i;
  5579. Print("gdwLockRecordFlags: %08x\n", dwLockRecordFlags);
  5580. for (i = 0; i < ARRAY_SIZE(flags); ++i) {
  5581. char prefix = ' ';
  5582. if (dwLockRecordFlags & LR_FLAG(flags[i].dwType)) {
  5583. prefix = '*';
  5584. }
  5585. Print(" %02x %c%-18s", (DWORD)flags[i].dwType, prefix, flags[i].lpszName);
  5586. if ((i + 1) % 3 == 0) {
  5587. Print("\n");
  5588. }
  5589. }
  5590. Print("\n");
  5591. return TRUE;
  5592. }
  5593. if (*lpszParam == '\0') {
  5594. Print("no arg!!\n");
  5595. return FALSE;
  5596. }
  5597. param = EvalExp(lpszParam);
  5598. if (!GetAndDumpHE(param, &phe, FALSE)) {
  5599. Print("!dlr: GetAndDumpHE failed\n");
  5600. return FALSE;
  5601. }
  5602. /*
  5603. * We have the handle entry: 'he' is filled in. Now dump the lock
  5604. * records. Remember the 1st record is the last transaction!
  5605. */
  5606. GetFieldValue(phe, SYM(HANDLEENTRY), "plr", plrT);
  5607. if (plrT != 0) {
  5608. Print("phe %p Dumping the lock records\n"
  5609. "----------------------------------------------\n"
  5610. "address cLock\n"
  5611. "----------------------------------------------\n", phe);
  5612. }
  5613. SAFEWHILE (plrT != 0) {
  5614. ULONG64 dw;
  5615. int i;
  5616. char ach[80];
  5617. _InitTypeRead(plrT, SYM(LOCKRECORD));
  5618. Print("%p %08d\n", ReadField(ppobj), ReadField(cLockObj));
  5619. GetFieldOffset(SYM(LOCKRECORD), "trace", &cbOffset);
  5620. cbPtr = GetTypeSize("PVOID");
  5621. for (i = 0; i < LOCKRECORD_STACK; i++) {
  5622. ReadPointer(plrT + cbOffset + i * cbPtr, &pTrace);
  5623. GetSym(pTrace, ach, &dw);
  5624. Print(" %s", ach);
  5625. if (dw != 0) {
  5626. Print("+0x%x", dw);
  5627. }
  5628. Print("\n");
  5629. }
  5630. plrT = ReadField(plrNext);
  5631. }
  5632. return TRUE;
  5633. }
  5634. #endif
  5635. VOID DumpMenu(
  5636. UINT uIndent,
  5637. DWORD opts,
  5638. PTR pMenu)
  5639. {
  5640. DWORD fFlags, cxMenu, cyMenu, dwContextHelpId, cch, dwSize;
  5641. UINT cAlloced, cItems, i;
  5642. INT iItem;
  5643. WCHAR szBufW[128];
  5644. char szIndent[256];
  5645. ULONG dwOffset;
  5646. PTR pwnd, pitem;
  5647. /*
  5648. * Compute our indent
  5649. */
  5650. for (i = 0; i < uIndent; szIndent[i++] = ' ')
  5651. /* do nothing */;
  5652. szIndent[i] = '\0';
  5653. dwSize = GetTypeSize("ITEM");
  5654. /*
  5655. * Print the menu header
  5656. */
  5657. if (!(opts & OFLAG(v))) {
  5658. Print("0x%p %s", pMenu, szIndent);
  5659. } else {
  5660. Print("%sPMENU @ 0x%p:\n", szIndent, pMenu);
  5661. }
  5662. /*
  5663. * Try and get the menu
  5664. */
  5665. if (_InitTypeRead(pMenu, SYM(MENU))) {
  5666. Print("Couldn't read PMENU at %p\n", pMenu);
  5667. return;
  5668. }
  5669. /*
  5670. * Print the information for this menu
  5671. */
  5672. fFlags = (DWORD)ReadField(fFlags);
  5673. cxMenu = (DWORD)ReadField(cxMenu);
  5674. cyMenu = (DWORD)ReadField(cyMenu);
  5675. dwContextHelpId = (DWORD)ReadField(dwContextHelpId);
  5676. cAlloced = (UINT)ReadField(cAlloced);
  5677. cItems = (UINT)ReadField(cItems);
  5678. iItem = (INT)ReadField(iItem);
  5679. pwnd = ReadField(spwndNotify);
  5680. if (!(opts & OFLAG(v))) {
  5681. Print("PMENU: fFlags=0x%lX, cItems=%lu, iItem=%lu, spwndNotify=0x%p\n",
  5682. fFlags, cItems, iItem, pwnd);
  5683. } else {
  5684. Print("%s fFlags............ %s\n"
  5685. "%s location.......... (%lu, %lu)\n",
  5686. szIndent, GetFlags(GF_MF, (WORD)fFlags, NULL, TRUE),
  5687. szIndent, cxMenu, cyMenu);
  5688. Print("%s spwndNotify....... 0x%p\n"
  5689. "%s dwContextHelpId... 0x%08lX\n"
  5690. "%s items............. %lu items in block of %lu\n",
  5691. szIndent, pwnd,
  5692. szIndent, dwContextHelpId,
  5693. szIndent, cItems, cAlloced);
  5694. }
  5695. GetFieldOffset(SYM(MENU), "rgItems", &dwOffset);
  5696. pitem = (ULONG_PTR)pMenu + dwOffset;
  5697. if (ReadPointer(FIXKP(pitem), &pitem)) {
  5698. i = 0;
  5699. SAFEWHILE (i < cItems) {
  5700. /*
  5701. * Get the menu item
  5702. */
  5703. _InitTypeRead(FIXKP(pitem), SYM(ITEM));
  5704. if (!(opts & OFLAG(i))) {
  5705. /*
  5706. * Print the info for this item.
  5707. */
  5708. if (!(opts & OFLAG(v))) {
  5709. Print("0x%p %s%lu: ID=0x%08lX hbmp=0x%p", pitem, szIndent, i, (INT)(WORD)ReadField(wID), (ULONG_PTR)ReadField(hbmp));
  5710. cch = (DWORD)ReadField(cch);
  5711. if (cch && CopyUnicodeString(pitem, SYM(ITEM), "lpstr", szBufW, (cch * sizeof(WCHAR)))) {
  5712. szBufW[cch] = 0;
  5713. Print(" %ws%\n", szBufW);
  5714. } else {
  5715. Print(", fType=%s", GetFlags(GF_MENUTYPE, (WORD)ReadField(fType), NULL, TRUE));
  5716. if (((UINT)ReadField(fType) & MF_SEPARATOR) == 0) {
  5717. Print(", lpstr=0x%p", ReadField(lpstr));
  5718. }
  5719. Print("\n");
  5720. }
  5721. } else {
  5722. Print("%s Item #%d @ 0x%p:\n", szIndent, i, pitem);
  5723. /*
  5724. * Print the details for this item.
  5725. */
  5726. Print("%s ID........... 0x%08lX (%lu)\n"
  5727. "%s lpstr.... 0x%p",
  5728. szIndent, (WORD)ReadField(wID), (WORD)ReadField(wID),
  5729. szIndent, ReadField(lpstr));
  5730. if (cch && CopyUnicodeString(pitem, SYM(ITEM), "lpstr", szBufW, (cch*sizeof(WCHAR)))) {
  5731. szBufW[cch] = 0;
  5732. Print(" %ws%\n", szBufW);
  5733. } else {
  5734. Print("\n");
  5735. }
  5736. Print("%s fType........ %s\n"
  5737. "%s fState....... %s\n"
  5738. "%s dwItemData... 0x%p\n",
  5739. szIndent, GetFlags(GF_MENUTYPE, (WORD)ReadField(fType), NULL, TRUE),
  5740. szIndent, GetFlags(GF_MENUSTATE, (WORD)ReadField(fState), NULL, TRUE),
  5741. szIndent, (ULONG_PTR)ReadField(dwItemData));
  5742. Print("%s checks....... on=0x%p, off=0x%p\n"
  5743. "%s location..... @(0n%lu, 0n%lu) size=(0n%lu, 0n%lu)\n",
  5744. szIndent, ReadField(hbmpChecked), ReadField(hbmpUnchecked),
  5745. szIndent, (DWORD)ReadField(xItem), (DWORD)ReadField(yItem), (DWORD)ReadField(cxItem), (DWORD)ReadField(cyItem));
  5746. Print("%s underline.... x=%lu, width=%lu\n"
  5747. "%s dxTab........ %lu\n"
  5748. "%s spSubMenu.... 0x%p\n",
  5749. szIndent, (DWORD)ReadField(ulX), (DWORD)ReadField(ulWidth),
  5750. szIndent, (DWORD)ReadField(dxTab),
  5751. szIndent, ReadField(spSubMenu));
  5752. }
  5753. }
  5754. /*
  5755. * If requested, traverse through sub-menus
  5756. */
  5757. if (opts & OFLAG(r)) {
  5758. pMenu = HorPtoP(ReadField(spSubMenu), TYPE_MENU);
  5759. if (pMenu) {
  5760. DumpMenu(uIndent + 8, opts, pMenu);
  5761. }
  5762. }
  5763. pitem += dwSize;
  5764. ++i;
  5765. }
  5766. }
  5767. }
  5768. /************************************************************************\
  5769. * Idm
  5770. *
  5771. * Dumps Menu structures
  5772. *
  5773. * 6/9/1995 Created SanfordS
  5774. \************************************************************************/
  5775. BOOL Idm(
  5776. DWORD opts,
  5777. ULONG64 param1)
  5778. {
  5779. PTR pvObject, phe;
  5780. BYTE bType;
  5781. if (param1 == 0) {
  5782. return FALSE;
  5783. }
  5784. pvObject = HorPtoP(FIXKP(param1), -1);
  5785. if (pvObject == 0) {
  5786. Print("dm: Could not convert 0x%p to an object.\n", pvObject);
  5787. return TRUE;
  5788. }
  5789. if (!getHEfromP(&phe, pvObject)) {
  5790. Print("dm: Could not get header for object 0x%p.\n", pvObject);
  5791. return TRUE;
  5792. }
  5793. GetFieldValue(phe, SYM(HANDLEENTRY), "bType", bType);
  5794. switch (bType) {
  5795. case TYPE_WINDOW:
  5796. Print("--- Dump Menu for %s object @ 0x%p ---\n", pszObjStr[bType], FIXKP(pvObject));
  5797. if (_InitTypeRead(pvObject, SYM(tagWND))) {
  5798. Print("dm: Could not read object at 0x%p.\n", pvObject);
  5799. return TRUE;
  5800. }
  5801. if (opts & OFLAG(s)) {
  5802. /*
  5803. * Display window's system menu
  5804. */
  5805. if ((pvObject = FIXKP(ReadField(spmenuSys))) == 0) {
  5806. Print("dm: This window does not have a system menu.\n");
  5807. return TRUE;
  5808. }
  5809. } else {
  5810. if ((DWORD)ReadField(style) & WS_CHILD) {
  5811. /*
  5812. * Child windows don't have menus
  5813. */
  5814. Print("dm: Child windows do not have menus.\n");
  5815. return TRUE;
  5816. }
  5817. if ((pvObject = FIXKP(ReadField(spmenu))) == 0) {
  5818. Print("dm: This window does not have a menu.\n");
  5819. return TRUE;
  5820. }
  5821. }
  5822. /* >>>> F A L L T H R O U G H <<<< */
  5823. case TYPE_MENU:
  5824. DumpMenu(0, opts, pvObject);
  5825. break;
  5826. default:
  5827. return FALSE;
  5828. }
  5829. return TRUE;
  5830. }
  5831. #ifdef KERNEL
  5832. /***************************************************************************\
  5833. * dmq - dump messages on queue
  5834. *
  5835. * dmq address - dumps messages in queue structure at address.
  5836. * dmq -a - dump messages for all queues
  5837. * dmq -c - count messages for all queues
  5838. *
  5839. * 11-13-91 DavidPe Created.
  5840. * 6/9/1995 SanfordS made to fit stdexts motif
  5841. * 11/05/2000 Hiroyama new 64bit clean code
  5842. \***************************************************************************/
  5843. typedef struct tagQSTAT {
  5844. DWORD dwInput, dwPosted, dwQueues, dwThreads;
  5845. DWORD opts;
  5846. } QSTAT, *PQSTAT;
  5847. /*
  5848. * PrintMessages
  5849. * N.b. resets InitTypeRead
  5850. */
  5851. BOOL PrintMessages(PTR pqmsgRead, PTR pti)
  5852. {
  5853. ULONG64 asmsg; // ASYNCSENDMSG
  5854. char *aszEvents[] = {
  5855. "MSG", // QEVENT_MESSAGE
  5856. "SHO", // QEVENT_SHOWWINDOW"
  5857. "CMD", // QEVENT_CANCLEMODE"
  5858. "SWP", // QEVENT_SETWINDOWPOS"
  5859. "UKS", // QEVENT_UPDATEKEYSTATE"
  5860. "DEA", // QEVENT_DEACTIVATE"
  5861. "ACT", // QEVENT_ACTIVATE"
  5862. "PST", // QEVENT_POSTMESSAGE"
  5863. "EXE", // QEVENT_EXECSHELL"
  5864. "CMN", // QEVENT_CANCELMENU"
  5865. "DSW", // QEVENT_DESTROYWINDOW"
  5866. "ASY", // QEVENT_ASYNCSENDMSG"
  5867. "HNG", // QEVENT_HUNGTHREAD"
  5868. "CMT", // QEVENT_CANCELMOUSEMOVETRK"
  5869. "NWE", // QEVENT_NOTIFYWINEVENT"
  5870. "RAC", // QEVENT_RITACCESSIBILITY"
  5871. "RSO", // QEVENT_RITSOUND"
  5872. "? ", // "?"
  5873. "? ", // "?"
  5874. "? " // "?"
  5875. };
  5876. #define NQEVENT (ARRAY_SIZE(aszEvents))
  5877. #if 0
  5878. Print("typ pqmsg hwnd msg wParam lParam time ExInfo dwQEvent pti\n");
  5879. Print("-------------------------------------------------------------------------------\n");
  5880. #else
  5881. Print("typ %-*s %-*s msg %-*s %-*s time %-*s dwQEvent pti\n",
  5882. PtrWidth(), "pqmsg",
  5883. PtrWidth(), "hwnd",
  5884. PtrWidth(), "wParam",
  5885. PtrWidth(), "lParam",
  5886. PtrWidth(), "ExInfo");
  5887. Print("----------------------------------------------------------------------------------\n");
  5888. #endif
  5889. SAFEWHILE (TRUE) {
  5890. _InitTypeRead(pqmsgRead, SYM(tagQMSG));
  5891. if (ReadField(dwQEvent) < NQEVENT) {
  5892. Print("%s %p ", aszEvents[ReadField(dwQEvent)], pqmsgRead);
  5893. } else {
  5894. Print("??? %p ", pqmsgRead);
  5895. }
  5896. switch (ReadField(dwQEvent)) {
  5897. case QEVENT_ASYNCSENDMSG:
  5898. asmsg = ReadField("msg.wParam");
  5899. _InitTypeRead(asmsg, SYM(ASYNCSENDMSG));
  5900. Print("%08p %04lx %08p %08p %08lx %08p %08lx %08p %c\n",
  5901. ReadField(hwnd), (DWORD)ReadField(message), ReadField(wParam), ReadField(lParam),
  5902. (DWORD)ReadField(msg.time), ReadField(ExtraInfo), (DWORD)ReadField(dwQEvent), ReadField(pti),
  5903. pti && ReadField(pti) == pti ? '*' : ' ');
  5904. break;
  5905. case 0:
  5906. default:
  5907. Print("%08p %04lx %08p %08p %08lx %08p %08lx %08p %c\n",
  5908. ReadField(msg.hwnd), (DWORD)ReadField(msg.message), ReadField(msg.wParam), ReadField(msg.lParam),
  5909. (DWORD)ReadField(msg.time), ReadField(ExtraInfo), (DWORD)ReadField(dwQEvent), ReadField(pti),
  5910. pti && ReadField(pti) == pti ? '*' : ' ');
  5911. break;
  5912. }
  5913. _InitTypeRead(pqmsgRead, SYM(tagQMSG));
  5914. if (ReadField(pqmsgNext) != NULL_PTR) {
  5915. if (pqmsgRead == ReadField(pqmsgNext)) {
  5916. Print("<ALERT!> loop found in message list!");
  5917. return FALSE;
  5918. }
  5919. pqmsgRead = ReadField(pqmsgNext);
  5920. } else {
  5921. return TRUE;
  5922. }
  5923. }
  5924. return TRUE;
  5925. }
  5926. /*
  5927. * DumpQMsg --- dumps or counts messages in a queue
  5928. * N.b. resets InitTypeRead
  5929. * - hiroyama
  5930. */
  5931. BOOL DumpQMsg(
  5932. PTR pq,
  5933. PQSTAT qs,
  5934. PTR pti)
  5935. {
  5936. PTR ptiTmp;
  5937. BOOL bMsgsPresent = FALSE;
  5938. _InitTypeRead(pq, SYM(tagQ));
  5939. // LATER: error handling in case pq is not accessible?
  5940. if ((qs->opts & OFLAG(c)) == 0) {
  5941. Print("Messages for queue 0x%p pti=%p\n", pq, pti);
  5942. }
  5943. if (pti) {
  5944. if (ReadField(ptiKeyboard) == pti || ReadField(ptiMouse) == pti) {
  5945. qs->dwQueues++;
  5946. }
  5947. }
  5948. if (ReadField(ptiKeyboard) != NULL_PTR) {
  5949. PTR pqmsgRead;
  5950. ptiTmp = ReadField(ptiKeyboard);
  5951. GetFieldValue(ptiTmp, SYM(tagTHREADINFO), "mlPost.pqmsgRead", pqmsgRead);
  5952. if (!(qs->opts & OFLAG(c)) && pqmsgRead) {
  5953. // If not counter only, and post messages exist, dump them all.
  5954. bMsgsPresent = TRUE;
  5955. Print("==== PostMessage queue ====\n");
  5956. PrintMessages(FIXKP(pqmsgRead), NULL_PTR);
  5957. }
  5958. } else {
  5959. Print("<ALERT!> ptiKeyboard is NULL for pq=%p!\n", pq);
  5960. }
  5961. _InitTypeRead(pq, SYM(tagQ));
  5962. if (!(qs->opts & OFLAG(c)) && ReadField(mlInput.pqmsgRead)) {
  5963. // If not counter only, and input messages exist, dump them all.
  5964. bMsgsPresent = TRUE;
  5965. Print( "==== Input queue ==========\n");
  5966. if (ReadField(mlInput.pqmsgRead) != NULL_PTR) {
  5967. PrintMessages(FIXKP(ReadField(mlInput.pqmsgRead)), pti);
  5968. }
  5969. }
  5970. _InitTypeRead(pq, SYM(tagQ));
  5971. if (qs->opts & OFLAG(c)) {
  5972. DWORD dwTimePosted;
  5973. DWORD dwTimeInput = 0;
  5974. DWORD dwOldest, dwNewest;
  5975. if (ReadField(mlInput.cMsgs)) {
  5976. qs->dwInput += (DWORD)ReadField(mlInput.cMsgs);
  5977. GetFieldValue(ReadField(mlInput.pqmsgRead), SYM(tagQMSG), "msg.time", dwOldest);
  5978. GetFieldValue(ReadField(mlInput.pqmsgWriteLast), SYM(tagQMSG), "msg.time", dwNewest);
  5979. dwTimeInput = dwNewest - dwOldest;
  5980. }
  5981. Print("%08p%c %8x %8x\t%08p",
  5982. pq,
  5983. ((ReadField(ptiKeyboard) != pti) && (ReadField(ptiMouse) != pti)) ? '*' : ' ',
  5984. (DWORD)ReadField(mlInput.cMsgs), dwTimeInput,
  5985. ReadField(ptiKeyboard));
  5986. //
  5987. // it would be good to print the ptiStatic too, maybe like this:
  5988. // e1b978a8 0 0 e1ba3368 0 0
  5989. // e1b9aca8* 0 0 e1b8b2e8 0 0
  5990. // (thread who's queue this is : e1a3ca28 0 0)
  5991. //
  5992. // Dump post message statics
  5993. dwTimePosted = 0;
  5994. _InitTypeRead(ptiTmp, SYM(tagTHREADINFO));
  5995. if (ReadField(mlPost.cMsgs)) {
  5996. qs->dwPosted += (DWORD)ReadField(mlPost.cMsgs);
  5997. GetFieldValue(ReadField(mlPost.pqmsgRead), SYM(tagQMSG), "msg.time", dwOldest);
  5998. GetFieldValue(ReadField(mlPost.pqmsgWriteLast), SYM(tagQMSG), "msg.time", dwNewest);
  5999. dwTimePosted = dwNewest - dwOldest;
  6000. }
  6001. Print(" %8x %8x\n", (DWORD)ReadField(mlPost.cMsgs), dwTimePosted);
  6002. } else {
  6003. if (bMsgsPresent) {
  6004. Print("\n");
  6005. }
  6006. }
  6007. return TRUE;
  6008. }
  6009. ULONG dmqCallback(
  6010. PTR pti,
  6011. PVOID pData)
  6012. {
  6013. PQSTAT qs = (PQSTAT)pData;
  6014. _InitTypeRead(pti, SYM(tagTHREADINFO));
  6015. DumpQMsg(ReadField(pq), qs, pti);
  6016. _InitTypeRead(pti, SYM(tagTHREADINFO));
  6017. if (ReadField(pqAttach)) {
  6018. Print(" -> pqAttach=%p", ReadField(pqAttach));
  6019. // LATER: dump pqAttach as well?
  6020. }
  6021. return FALSE;
  6022. }
  6023. BOOL Idmq(
  6024. DWORD opts,
  6025. ULONG64 param1)
  6026. {
  6027. try {
  6028. static const char separator[] = "=================";
  6029. PTR pq;
  6030. // firstly check the symbols etc.'s legitimacy
  6031. pq = GetGlobalPointer(VAR(gpqForeground));
  6032. if (param1 == NULL_PTR) {
  6033. if ((opts & OFLAG(a)) == 0) {
  6034. Print("uses gpqForeground\n");
  6035. }
  6036. }
  6037. if (opts & OFLAG(c)) {
  6038. Print("Summary of%s message queues (\"age\" is newest time - oldest time)\n",
  6039. param1 == NULL_PTR ? " all" : "");
  6040. //Print("Queue # Input age \t Thread # Posted age\n");
  6041. //Print("======== ======== ========\t======== ======== ========\n");
  6042. Print("%-*s %-*s %-*s\t%-*s %-*s %-*s\n",
  6043. PtrWidth(), "queue",
  6044. PtrWidth(), "# input",
  6045. PtrWidth(), "age",
  6046. PtrWidth(), "Thread",
  6047. PtrWidth(), "# posted",
  6048. PtrWidth(), "age");
  6049. Print("%*.*s %*.*s %*.*s\t%*.*s %*.*s %*.*s\n",
  6050. PtrWidth(), PtrWidth(), separator,
  6051. PtrWidth(), PtrWidth(), separator,
  6052. PtrWidth(), PtrWidth(), separator,
  6053. PtrWidth(), PtrWidth(), separator,
  6054. PtrWidth(), PtrWidth(), separator,
  6055. PtrWidth(), PtrWidth(), separator);
  6056. }
  6057. if (param1 == NULL_PTR) {
  6058. if (opts & OFLAG(t)) {
  6059. // pti is required with -t
  6060. return FALSE;
  6061. }
  6062. if (opts & (/*OFLAG(c) |*/ OFLAG(a))) {
  6063. /*
  6064. * do it for all the queues
  6065. */
  6066. QSTAT qs = { 0, };
  6067. qs.opts = opts & OFLAG(c);
  6068. ForEachPti(dmqCallback, &qs);
  6069. if (opts & OFLAG(c)) {
  6070. Print(" \n");
  6071. Print("Queues # Input \t Threads # Posted\n");
  6072. Print("======== ======== ========\t======== ========\n");
  6073. Print("%8x %8x \t%8x %8x\n",
  6074. qs.dwQueues, qs.dwInput, qs.dwThreads, qs.dwPosted);
  6075. }
  6076. return TRUE;
  6077. } else {
  6078. // use gpqForeground
  6079. if (pq == NULL_PTR) {
  6080. Print("no foreground queue (gpqForeground == NULL)!\n");
  6081. return TRUE;
  6082. }
  6083. }
  6084. } else {
  6085. // param1 is pq or pti
  6086. pq = param1;
  6087. }
  6088. if (opts & OFLAG(t)) {
  6089. // param1 is pti
  6090. QSTAT qs = { 0, };
  6091. qs.opts = opts & OFLAG(c);
  6092. _InitTypeRead(param1, SYM(tagTHREADINFO));
  6093. DumpQMsg(ReadField(pq), &qs, param1);
  6094. _InitTypeRead(param1, SYM(tagTHREADINFO));
  6095. if (ReadField(pqAttach)) {
  6096. Print("paAttach\n");
  6097. DumpQMsg(ReadField(pqAttach), &qs, param1);
  6098. }
  6099. } else {
  6100. // param1 is pq
  6101. PTR ptiKeyboard;
  6102. QSTAT qs = { 0, };
  6103. qs.opts = opts & OFLAG(c);
  6104. GetFieldValue(pq, SYM(tagQ), "ptiKeyboard", ptiKeyboard);
  6105. DumpQMsg(pq, &qs, ptiKeyboard);
  6106. }
  6107. } except (CONTINUE) {
  6108. }
  6109. return TRUE;
  6110. }
  6111. #endif // KERNEL
  6112. #ifdef OLD_DEBUGGER
  6113. #ifdef KERNEL
  6114. /***************************************************************************\
  6115. * dwe - dump winevents
  6116. *
  6117. * dwe - dumps all EVENTHOOKs.
  6118. * dwe <addr> - dumps EVENTHOOK at address.
  6119. * dwe -n - dumps all NOTIFYs.
  6120. * dwe -n <addr> - dumps NOTIFY at address.
  6121. *
  6122. * 1997-07-10 IanJa Created.
  6123. \***************************************************************************/
  6124. BOOL Idwe(
  6125. DWORD opts,
  6126. ULONG64 param1)
  6127. {
  6128. EVENTHOOK EventHook, *pEventHook;
  6129. NOTIFY Notify, *pNotify;
  6130. PVOID pobj;
  6131. char ach[100];
  6132. pobj = FIXKP(param1);
  6133. if (opts & OFLAG(n)) {
  6134. if (pobj) {
  6135. move(Notify, pobj);
  6136. sprintf(ach, "NOTIFY 0x%p\n", pobj);
  6137. Idso(0, ach);
  6138. return 1;
  6139. }
  6140. pNotify = GetGlobalPointer(VAR(gpPendingNotifies));
  6141. Print("Pending Notifications:\n");
  6142. gnIndent += 2;
  6143. SAFEWHILE (pNotify != NULL) {
  6144. sprintf(ach, "NOTIFY 0x%p\n", pNotify);
  6145. Idso(0, ach);
  6146. move(pNotify, &pNotify->pNotifyNext);
  6147. }
  6148. gnIndent -= 2;
  6149. return TRUE;
  6150. }
  6151. if (pobj) {
  6152. move(EventHook, pobj);
  6153. sprintf(ach, "EVENTHOOK 0x%p\n", pobj);
  6154. Idso(0, ach);
  6155. return 1;
  6156. }
  6157. pEventHook = GetGlobalPointer(VAR(gpWinEventHooks));
  6158. Print("WinEvent hooks:\n");
  6159. gnIndent += 2;
  6160. SAFEWHILE (pEventHook != NULL) {
  6161. sprintf(ach, "EVENTHOOK 0x%p\n", pEventHook);
  6162. Idso(0, ach);
  6163. move(pEventHook, &pEventHook->pehNext);
  6164. }
  6165. gnIndent -= 2;
  6166. Print("\n");
  6167. return TRUE;
  6168. }
  6169. #endif // KERNEL
  6170. #ifndef KERNEL
  6171. /************************************************************************\
  6172. * Idped
  6173. *
  6174. * Dumps Edit Control Structures (PEDs)
  6175. *
  6176. * 6/9/1995 Created SanfordS
  6177. \************************************************************************/
  6178. BOOL Idped(
  6179. DWORD opts,
  6180. ULONG64 param1)
  6181. {
  6182. PED ped;
  6183. ED ed;
  6184. DWORD pText;
  6185. UNREFERENCED_PARAMETER(opts);
  6186. ped = param1;
  6187. move(ed, ped);
  6188. move(pText, ed.hText);
  6189. Print("PED Handle: %lX\n", ped);
  6190. Print("hText %lX (%lX)\n", ed.hText, pText);
  6191. PRTFDW2(ed., cchAlloc, cchTextMax);
  6192. PRTFDW2(ed., cch, cLines);
  6193. PRTFDW2(ed., ichMinSel, ichMaxSel);
  6194. PRTFDW2(ed., ichCaret, iCaretLine);
  6195. PRTFDW2(ed., ichScreenStart, ichLinesOnScreen);
  6196. PRTFDW2(ed., xOffset, charPasswordChar);
  6197. PRTFDWDWP(ed., cPasswordCharWidth, hwnd);
  6198. PRTFDWP1(ed., pwnd);
  6199. PRTFRC(ed., rcFmt);
  6200. PRTFDWP1(ed., hwndParent);
  6201. PRTFPT(ed., ptPrevMouse);
  6202. PRTFDW1(ed., prevKeys);
  6203. BEGIN_PRTFFLG();
  6204. PRTFFLG(ed, fSingle);
  6205. PRTFFLG(ed, fNoRedraw);
  6206. PRTFFLG(ed, fMouseDown);
  6207. PRTFFLG(ed, fFocus);
  6208. PRTFFLG(ed, fDirty);
  6209. PRTFFLG(ed, fDisabled);
  6210. PRTFFLG(ed, fNonPropFont);
  6211. PRTFFLG(ed, fNonPropDBCS);
  6212. PRTFFLG(ed, fBorder);
  6213. PRTFFLG(ed, fAutoVScroll);
  6214. PRTFFLG(ed, fAutoHScroll);
  6215. PRTFFLG(ed, fNoHideSel);
  6216. PRTFFLG(ed, fDBCS);
  6217. PRTFFLG(ed, fFmtLines);
  6218. PRTFFLG(ed, fWrap);
  6219. PRTFFLG(ed, fCalcLines);
  6220. PRTFFLG(ed, fEatNextChar);
  6221. PRTFFLG(ed, fStripCRCRLF);
  6222. PRTFFLG(ed, fInDialogBox);
  6223. PRTFFLG(ed, fReadOnly);
  6224. PRTFFLG(ed, fCaretHidden);
  6225. PRTFFLG(ed, fTrueType);
  6226. PRTFFLG(ed, fAnsi);
  6227. PRTFFLG(ed, fWin31Compat);
  6228. PRTFFLG(ed, f40Compat);
  6229. PRTFFLG(ed, fFlatBorder);
  6230. PRTFFLG(ed, fSawRButtonDown);
  6231. PRTFFLG(ed, fInitialized);
  6232. PRTFFLG(ed, fSwapRoOnUp);
  6233. PRTFFLG(ed, fAllowRTL);
  6234. PRTFFLG(ed, fDisplayCtrl);
  6235. PRTFFLG(ed, fRtoLReading);
  6236. PRTFFLG(ed, fInsertCompChr);
  6237. PRTFFLG(ed, fReplaceCompChr);
  6238. PRTFFLG(ed, fNoMoveCaret);
  6239. PRTFFLG(ed, fResultProcess);
  6240. PRTFFLG(ed, fKorea);
  6241. PRTFFLG(ed, fInReconversion);
  6242. END_PRTFFLG();
  6243. PRTFDWDWP(ed., cbChar, chLines);
  6244. PRTFDWDWP(ed., format, lpfnNextWord);
  6245. PRTFDW1(ed., maxPixelWidth);
  6246. {
  6247. const char* p = "**INVALID**";
  6248. if (ed.undoType < UNDO_DELETE) {
  6249. p = GetFlags(GF_EDUNDO, 0, NULL, TRUE);
  6250. }
  6251. Print(DWSTR2 "\t" "%08x undoType (%s)\n", ed.hDeletedText, "hDeleteText", ed.undoType, p);
  6252. }
  6253. PRTFDW2(ed., ichDeleted, cchDeleted);
  6254. PRTFDW2(ed., ichInsStart, ichInsEnd);
  6255. PRTFDWPDW(ed., hFont, aveCharWidth);
  6256. PRTFDW2(ed., lineHeight, charOverhang);
  6257. PRTFDW2(ed., cxSysCharWidth, cySysCharHeight);
  6258. PRTFDWP2(ed., listboxHwnd, pTabStops);
  6259. PRTFDWP1(ed., charWidthBuffer);
  6260. // PRTFDW2(ed., hkl, wMaxNegA);
  6261. PRTFDW1(ed., wMaxNegA);
  6262. PRTFDW2(ed., wMaxNegAcharPos, wMaxNegC);
  6263. PRTFDW2(ed., wMaxNegCcharPos, wLeftMargin);
  6264. PRTFDW2(ed., wRightMargin, ichStartMinSel);
  6265. PRTFDWDWP(ed., ichStartMaxSel, pLpkEditCallout);
  6266. PRTFDWP2(ed., hCaretBitmap, hInstance);
  6267. PRTFDW2(ed., seed, fEncoded);
  6268. PRTFDW2(ed., iLockLevel, wImeStatus);
  6269. return TRUE;
  6270. }
  6271. #endif // !KERNEL
  6272. #endif // OLD_DEBUGGER
  6273. #ifndef KERNEL
  6274. /************************************************************************\
  6275. * Idci
  6276. *
  6277. * Dumps Client Info
  6278. *
  6279. * 6/15/1995 Created SanfordS
  6280. \************************************************************************/
  6281. BOOL Idci(
  6282. VOID)
  6283. {
  6284. PTR pteb = NULL_PTR;
  6285. GetTebAddress(&pteb);
  6286. if (pteb) {
  6287. ULONG pciOffset;
  6288. GetFieldOffset(SYM(TEB), "Win32ClientInfo", &pciOffset);
  6289. _InitTypeRead(pteb + pciOffset, SYM(CLIENTINFO));
  6290. Print("PCLIENTINFO @ 0x%p:\n", pteb + pciOffset);
  6291. // DWORD dwExpWinVer;
  6292. Print("\tdwExpWinVer %08lx\n", (ULONG)ReadField(dwExpWinVer));
  6293. // DWORD dwCompatFlags;
  6294. Print("\tdwCompatFlags %08lx\n", (ULONG)ReadField(dwCompatFlags));
  6295. // DWORD dwTIFlags;
  6296. Print("\tdwTIFlags %08lx\n", (ULONG)ReadField(dwTIFlags));
  6297. // PDESKTOPINFO pDeskInfo;
  6298. Print("\tpDeskInfo %p\n", ReadField(pDeskInfo));
  6299. // ULONG ulClientDelta;
  6300. Print("\tulClientDelta %p\n", ReadField(ulClientDelta));
  6301. // struct tagHOOK *phkCurrent;
  6302. Print("\tphkCurrent %p\n", ReadField(phkCurrent));
  6303. // DWORD fsHooks;
  6304. Print("\tfsHooks %08lx\n", (ULONG)ReadField(fsHooks));
  6305. // CALLBACKWND CallbackWnd;
  6306. Print("\tCallbackWnd.hwnd %p\n", ReadField(CallbackWnd.hwnd));
  6307. // DWORD cSpins;
  6308. Print("\tcSpins %08lx\n", (ULONG)ReadField(cSpins));
  6309. Print("\tCodePage %d\n", (ULONG)ReadField(CodePage));
  6310. } else {
  6311. Print("Unable to get TEB info.\n");
  6312. }
  6313. return TRUE;
  6314. }
  6315. #endif // !KERNEL
  6316. #ifdef KERNEL
  6317. /************************************************************************\
  6318. * Idpi
  6319. *
  6320. * Dumps ProcessInfo structs
  6321. *
  6322. * 6/9/1995 Created SanfordS
  6323. \************************************************************************/
  6324. ULONG
  6325. dpiCallback(
  6326. PTR ppi,
  6327. PVOID Data)
  6328. {
  6329. UNREFERENCED_PARAMETER(Data);
  6330. Idpi(0, ppi);
  6331. Print("\n");
  6332. return FALSE;
  6333. }
  6334. BOOL Idpi(
  6335. DWORD opts,
  6336. ULONG64 param1)
  6337. {
  6338. PTR pW32Process;
  6339. PTR ppi;
  6340. PTR pEProcess;
  6341. PTR pdv;
  6342. PTR ulUniqueProcessId;
  6343. /*
  6344. * If he just wants the current process, locate it.
  6345. */
  6346. if (opts & OFLAG(c)) {
  6347. Print("Current Process:\n");
  6348. GetCurrentProcessAddr(dwProcessor, 0, &param1);
  6349. if (param1 == 0) {
  6350. Print("Unable to get current process pointer.\n");
  6351. return FALSE;
  6352. }
  6353. if (GetFieldValue(param1, "nt!EPROCESS", "Win32Process", pW32Process)) {
  6354. Print("Unable to read _EPROCESS at %p\n", param1);
  6355. return FALSE;
  6356. }
  6357. param1 = pW32Process;
  6358. } else if (opts & OFLAG(p)) {
  6359. if (GetFieldValue(param1, "nt!EPROCESS", "Win32Process", param1)) {
  6360. Print("Can't get EPROCESS @ 0x%p\n", param1);
  6361. return FALSE;
  6362. }
  6363. } else if (param1 == 0) {
  6364. Print("**** NT ACTIVE WIN32 PROCESSINFO DUMP ****\n");
  6365. ForEachPpi(dpiCallback, NULL);
  6366. return TRUE;
  6367. }
  6368. ppi = FIXKP(param1);
  6369. if (GetFieldValue(ppi, SYM(PROCESSINFO), "Process", pEProcess)) {
  6370. Print("Can't get PROCESSINFO from %p.\n", ppi);
  6371. return FALSE;
  6372. }
  6373. if (GetFieldValue(pEProcess, "nt!EPROCESS", "UniqueProcessId", ulUniqueProcessId)) {
  6374. Print("Unable to read _EPROCESS at %p\n", pEProcess);
  6375. return FALSE;
  6376. }
  6377. Print("---PPROCESSINFO @ 0x%p for process 0x%p (%s):\n",
  6378. ppi,
  6379. ulUniqueProcessId,
  6380. ProcessName(ppi));
  6381. _InitTypeRead(ppi, SYM(PROCESSINFO));
  6382. Print("\tppiNext 0x%p\n", ReadField(ppiNext));
  6383. Print("\trpwinsta 0x%p\n", ReadField(rpwinsta));
  6384. Print("\thwinsta 0x%p\n", ReadField(hwinsta));
  6385. Print("\tamwinsta 0x%08lx\n", (ULONG)ReadField(amwinsta));
  6386. Print("\tptiMainThread 0x%p\n", ReadField(ptiMainThread));
  6387. Print("\tcThreads 0x%08lx\n", (ULONG)ReadField(cThreads));
  6388. Print("\trpdeskStartup 0x%p\n", ReadField(rpdeskStartup));
  6389. Print("\thdeskStartup 0x%p\n", ReadField(hdeskStartup));
  6390. Print("\tpclsPrivateList 0x%p\n", ReadField(pclsPrivateList));
  6391. Print("\tpclsPublicList 0x%p\n", ReadField(pclsPublicList));
  6392. Print("\tflags %s\n",
  6393. GetFlags(GF_W32PF, (DWORD)ReadField(W32PF_Flags), NULL, TRUE));
  6394. Print("\tdwHotkey 0x%08lx\n", (ULONG)ReadField(dwHotkey));
  6395. Print("\tpWowProcessInfo 0x%p\n", ReadField(pwpi));
  6396. Print("\tluidSession 0x%08lx:0x%08lx\n", (ULONG)ReadField(luidSession.HighPart),
  6397. (ULONG)ReadField(luidSession.LowPart));
  6398. Print("\tdwX,dwY (0x%x, 0x%x)\n", (ULONG)ReadField(usi.dwX), (ULONG)ReadField(usi.dwY));
  6399. Print("\tdwXSize,dwYSize (0x%x, 0x%x)\n", (ULONG)ReadField(usi.dwXSize), (ULONG)ReadField(usi.dwYSize));
  6400. Print("\tdwFlags 0x%08x\n", (ULONG)ReadField(usi.dwFlags));
  6401. Print("\twShowWindow 0x%04x\n", (ULONG)ReadField(usi.wShowWindow));
  6402. Print("\tpCursorCache 0x%p\n", ReadField(pCursorCache));
  6403. Print("\tdwLpkEntryPoints %s\n",
  6404. GetFlags(GF_LPK, (DWORD)ReadField(dwLpkEntryPoints), NULL, TRUE));
  6405. /*
  6406. * List desktop views
  6407. */
  6408. pdv = ReadField(pdvList);
  6409. Print("Desktop views:\n");
  6410. while (pdv != 0) {
  6411. _InitTypeRead(pdv, SYM(DESKTOPVIEW));
  6412. Print("\tpdesk = %p, ulClientDelta = %p\n", ReadField(pdesk), ReadField(ulClientDelta));
  6413. pdv = ReadField(pdvNext);
  6414. }
  6415. return TRUE;
  6416. }
  6417. #endif // KERNEL
  6418. #ifdef KERNEL
  6419. /***************************************************************************\
  6420. * dpm - dump popupmenu
  6421. *
  6422. * dpm address - dumps menu info for menu at address
  6423. *
  6424. * 02/13/1995 JohnC Created.
  6425. * 06/09/1995 SanfordS Made to fit stdexts motif.
  6426. \***************************************************************************/
  6427. BOOL Idpm(
  6428. DWORD opts,
  6429. PTR ppopupmenu)
  6430. {
  6431. UNREFERENCED_PARAMETER(opts);
  6432. ppopupmenu = FIXKP(ppopupmenu);
  6433. Print("PPOPUPMENU @ 0x%p\n", ppopupmenu);
  6434. BEGIN_PRTFFLG(ppopupmenu, SYM(POPUPMENU));
  6435. PRTFFLG(fIsMenuBar);
  6436. PRTFFLG(fHasMenuBar);
  6437. PRTFFLG(fIsSysMenu);
  6438. PRTFFLG(fIsTrackPopup);
  6439. PRTFFLG(fDroppedLeft);
  6440. PRTFFLG(fHierarchyDropped);
  6441. PRTFFLG(fRightButton);
  6442. PRTFFLG(fToggle);
  6443. PRTFFLG(fSynchronous);
  6444. PRTFFLG(fFirstClick);
  6445. PRTFFLG(fDropNextPopup);
  6446. PRTFFLG(fNoNotify);
  6447. PRTFFLG(fAboutToHide);
  6448. PRTFFLG(fShowTimer);
  6449. PRTFFLG(fHideTimer);
  6450. PRTFFLG(fDestroyed);
  6451. PRTFFLG(fDelayedFree);
  6452. PRTFFLG(fFlushDelayedFree);
  6453. PRTFFLG(fFreed);
  6454. PRTFFLG(fInCancel);
  6455. PRTFFLG(fTrackMouseEvent);
  6456. PRTFFLG(fSendUninit);
  6457. END_PRTFFLG();
  6458. PRTFDWP2(spwndNotify, spwndPopupMenu);
  6459. PRTFDWP2(spwndNextPopup, spwndPrevPopup);
  6460. PRTFDWP2(spmenu, spmenuAlternate);
  6461. PRTFDWP2(spwndActivePopup, ppopupmenuRoot);
  6462. PRTFDWPDW(ppmDelayedFree, posSelectedItem);
  6463. PRTFDW1(posDropped);
  6464. return TRUE;
  6465. }
  6466. #endif // KERNEL
  6467. #ifdef KERNEL
  6468. /***************************************************************************\
  6469. * dms - dump pMenuState
  6470. *
  6471. * dms address
  6472. *
  6473. * 05-15-96 Created GerardoB
  6474. \***************************************************************************/
  6475. BOOL Idms(
  6476. DWORD opts,
  6477. ULONG64 param1)
  6478. {
  6479. UNREFERENCED_PARAMETER(opts);
  6480. param1 = FIXKP(param1);
  6481. Print("PMENUSTATE @ 0x%p\n", param1);
  6482. BEGIN_PRTFFLG(FIXKP(param1), MENUSTATE);
  6483. PRTFFLG(fMenuStarted);
  6484. PRTFFLG(fIsSysMenu);
  6485. PRTFFLG(fInsideMenuLoop);
  6486. PRTFFLG(fButtonDown);
  6487. PRTFFLG(fInEndMenu);
  6488. PRTFFLG(fUnderline);
  6489. PRTFFLG(fButtonAlwaysDown);
  6490. PRTFFLG(fDragging);
  6491. PRTFFLG(fModelessMenu);
  6492. PRTFFLG(fInCallHandleMenuMessages);
  6493. PRTFFLG(fDragAndDrop);
  6494. PRTFFLG(fAutoDismiss);
  6495. PRTFFLG(fIgnoreButtonUp);
  6496. PRTFFLG(fMouseOffMenu);
  6497. PRTFFLG(fInDoDragDrop);
  6498. PRTFFLG(fActiveNoForeground);
  6499. PRTFFLG(fNotifyByPos);
  6500. END_PRTFFLG();
  6501. PRTFDWP1(pGlobalPopupMenu);
  6502. PRTFPT(ptMouseLast);
  6503. PRTFDW2(mnFocus, cmdLast);
  6504. PRTFDWP1(ptiMenuStateOwner);
  6505. return TRUE;
  6506. }
  6507. #endif // KERNEL
  6508. #ifdef KERNEL
  6509. /***************************************************************************\
  6510. * dq - dump queue
  6511. *
  6512. * dq address - dumps queue structure at address
  6513. * dq t address - dumps queue structure at address plus THREADINFO
  6514. *
  6515. * 06-20-91 ScottLu Created.
  6516. * 11-14-91 DavidPe Added THREADINFO option.
  6517. * 6/9/1995 SanfordS made to fit stdexts motif
  6518. \***************************************************************************/
  6519. ULONG
  6520. dqCallback(
  6521. PTR pti,
  6522. PVOID Data)
  6523. {
  6524. PTR pq;
  6525. GetFieldValue(pti, SYM(THREADINFO), "pq", pq);
  6526. Idq(PtrToUlong(Data), pq);
  6527. return FALSE;
  6528. }
  6529. BOOL Idq(
  6530. DWORD opts,
  6531. PTR pq)
  6532. {
  6533. char ach[80];
  6534. if (opts & OFLAG(a)) {
  6535. Print("Dumping all queues:\n");
  6536. ForEachPti(dqCallback, ULongToPtr(opts & ~OFLAG(a)));
  6537. return TRUE;
  6538. #ifdef SOME_OTHER_DELUSION
  6539. HANDLEENTRY he, *phe;
  6540. int i;
  6541. FOREACHHANDLEENTRY(phe, he, i)
  6542. if (he.bType == TYPE_INPUTQUEUE) {
  6543. Idq(opts & ~OFLAG(a), FIXKP(he.phead));
  6544. Print("\n");
  6545. }
  6546. NEXTEACHHANDLEENTRY()
  6547. return TRUE;
  6548. #endif
  6549. }
  6550. if (pq == 0) {
  6551. Print("Dumping foreground queue:\n");
  6552. pq = GetGlobalPointer(VAR(gpqForeground));
  6553. if (pq == 0) {
  6554. Print("no foreground queue (gpqForeground == NULL)!\n");
  6555. return TRUE;
  6556. }
  6557. } else {
  6558. pq = FIXKP(pq);
  6559. }
  6560. /*
  6561. * Print out simple thread info for pq->ptiKeyboard
  6562. */
  6563. _InitTypeRead(pq, SYM(tagQ));
  6564. if (ReadField(ptiKeyboard)) {
  6565. Idt(OFLAG(p), ReadField(ptiKeyboard));
  6566. }
  6567. /*
  6568. * Don't Print() with more than 16 arguments at once because it'll blow
  6569. * up.
  6570. */
  6571. Print("PQ @ 0x%p\n", pq);
  6572. Print(
  6573. "\tmlInput.pqmsgRead 0x%p\n"
  6574. "\tmlInput.pqmsgWriteLast 0x%p\n"
  6575. "\tmlInput.cMsgs 0x%08lx\n",
  6576. ReadField(mlInput.pqmsgRead),
  6577. ReadField(mlInput.pqmsgWriteLast),
  6578. (ULONG)ReadField(mlInput.cMsgs));
  6579. Print("\tptiSysLock 0x%p\n"
  6580. "\tidSysLock 0x%p\n"
  6581. "\tidSysPeek 0x%p\n",
  6582. ReadField(ptiSysLock),
  6583. ReadField(idSysLock),
  6584. ReadField(idSysPeek));
  6585. Print("\tptiMouse 0x%p\n"
  6586. "\tptiKeyboard 0x%p\n",
  6587. ReadField(ptiMouse),
  6588. ReadField(ptiKeyboard));
  6589. Print("\tspcurCurrent 0x%p\n"
  6590. "\tiCursorLevel 0x%08lx\n",
  6591. ReadField(spcurCurrent),
  6592. (ULONG)ReadField(iCursorLevel));
  6593. DebugGetWindowTextA(ReadField(spwndCapture), ach, ARRAY_SIZE(ach));
  6594. Print("\tspwndCapture 0x%p \"%s\"\n",
  6595. ReadField(spwndCapture), ach);
  6596. DebugGetWindowTextA(ReadField(spwndFocus), ach, ARRAY_SIZE(ach));
  6597. Print("\tspwndFocus 0x%p \"%s\"\n",
  6598. ReadField(spwndFocus), ach);
  6599. DebugGetWindowTextA(ReadField(spwndActive), ach, ARRAY_SIZE(ach));
  6600. Print("\tspwndActive 0x%p \"%s\"\n",
  6601. ReadField(spwndActive), ach);
  6602. DebugGetWindowTextA(ReadField(spwndActivePrev), ach, ARRAY_SIZE(ach));
  6603. Print("\tspwndActivePrev 0x%p \"%s\"\n",
  6604. ReadField(spwndActivePrev), ach);
  6605. Print("\tcodeCapture 0x%04lx\n"
  6606. "\tmsgDblClk 0x%04lx\n"
  6607. "\ttimeDblClk 0x%08lx\n",
  6608. (ULONG)ReadField(codeCapture),
  6609. (ULONG)ReadField(msgDblClk),
  6610. (ULONG)ReadField(timeDblClk));
  6611. Print("\thwndDblClk 0x%p\n",
  6612. ReadField(hwndDblClk));
  6613. Print("\tptDblClk { %d, %d }\n",
  6614. (ULONG)ReadField(ptDblClk.x),
  6615. (ULONG)ReadField(ptDblClk.y));
  6616. Print("\tQF_flags 0x%08lx %s\n"
  6617. "\tcThreads 0x%08lx\n"
  6618. "\tcLockCount 0x%08lx\n",
  6619. (ULONG)ReadField(QF_flags), GetFlags(GF_QF, (DWORD)ReadField(QF_flags), NULL, FALSE),
  6620. (DWORD) ReadField(cThreads),
  6621. (DWORD) ReadField(cLockCount));
  6622. Print("\tmsgJournal 0x%08lx\n"
  6623. "\tExtraInfo 0x%08lx\n",
  6624. (ULONG)ReadField(msgJournal),
  6625. (ULONG)ReadField(ExtraInfo));
  6626. /*
  6627. * Dump THREADINFO if user specified 't'.
  6628. */
  6629. if (opts & OFLAG(t)) {
  6630. Idti(0, ReadField(ptiKeyboard));
  6631. }
  6632. return TRUE;
  6633. }
  6634. #endif // KERNEL
  6635. /***************************************************************************\
  6636. * dsi dump serverinfo struct
  6637. *
  6638. * 02-27-92 ScottLu Created.
  6639. * 6/9/1995 SanfordS Made to fit stdexts motif.
  6640. \***************************************************************************/
  6641. BOOL Idsi(
  6642. DWORD opts)
  6643. {
  6644. try {
  6645. PTR psi;
  6646. UINT i;
  6647. char ach[80];
  6648. ULONG64 ulOffset;
  6649. PSERVERINFO pServerInfo; // dummy for ARRAY_SIZE
  6650. static const char* fnid[FNID_ARRAY_SIZE] = {
  6651. "FNID_SCROLLBAR", // xxxSBWndProc
  6652. "FNID_ICONTITLE", // xxxDefWindowProc
  6653. "FNID_MENU", // xxxMenuWindowProc
  6654. "FNID_DESKTOP", // xxxDesktopWndProc
  6655. "FNID_DEFWINDOWPROC", // xxxDefWindowProc
  6656. "FNID_MESSAGEWND", // xxxDefWindowProc
  6657. "FNID_SWITCH", // xxxSwitchWndProc
  6658. "FNID_BUTTON", // No server side proc
  6659. "FNID_COMBOBOX", // No server side proc
  6660. "FNID_COMBOLISTBOX", // No server side proc
  6661. "FNID_DIALOG", // No server side proc
  6662. "FNID_EDIT", // No server side proc
  6663. "FNID_LISTBOX", // No server side proc
  6664. "FNID_MDICLIENT", // No server side proc
  6665. "FNID_STATIC", // No server side proc
  6666. "FNID_IME", // No server side proc
  6667. "FNID_HKINLPCWPEXSTRUCT",
  6668. "FNID_HKINLPCWPRETEXSTRUCT",
  6669. "FNID_DEFFRAMEPROC", // No server side proc
  6670. "FNID_DEFMDICHILDPROC", // No server side proc
  6671. "FNID_MB_DLGPROC", // No server side proc
  6672. "FNID_MDIACTIVATEDLGPROC", // No server side proc
  6673. "FNID_SENDMESSAGE",
  6674. "FNID_SENDMESSAGEFF",
  6675. "FNID_SENDMESSAGEEX",
  6676. "FNID_CALLWINDOWPROC",
  6677. "FNID_SENDMESSAGEBSM",
  6678. "FNID_TOOLTIP", // xxxTooltipWndProc
  6679. "FNID_GHOST", // xxxGhostWndProc
  6680. "FNID_SENDNOTIFYMESSAGE",
  6681. "FNID_SENDMESSAGECALLBACK",
  6682. "0x2b9",
  6683. };
  6684. psi = GetGlobalPointer(SYM(gpsi));
  6685. if (psi == 0) {
  6686. return TRUE;
  6687. }
  6688. Print("PSERVERINFO @ 0x%p\n", psi);
  6689. _InitTypeRead(psi, SYM(SERVERINFO));
  6690. Print( "\tRIPFlags 0x%04lx %s\n", (DWORD)ReadField(dwRIPFlags), GetFlags(GF_RIP, (DWORD)ReadField(dwRIPFlags), NULL, FALSE));
  6691. Print( "\tSRVIFlags 0x%04lx %s\n", (DWORD)ReadField(wSRVIFlags), GetFlags(GF_SRVI, (DWORD)ReadField(wSRVIFlags), NULL, FALSE));
  6692. Print( "\tPUSIFlags 0x%08lx %s\n", (DWORD)ReadField(PUSIFlags), GetFlags(GF_SI, (DWORD)ReadField(PUSIFlags), NULL, FALSE));
  6693. Print( "\tcHandleEntries 0x%08p\n"
  6694. "\tcbHandleTable 0x%08p\n"
  6695. "\tnEvents 0x%08p\n",
  6696. ReadField(cHandleEntries),
  6697. ReadField(cbHandleTable),
  6698. ReadField(nEvents));
  6699. if (opts & OFLAG(p)) {
  6700. Print("\t" "mpFnidPfn:\n");
  6701. i = 0;
  6702. SAFEWHILE (i < FNID_ARRAY_SIZE) {
  6703. PTR pfn = GetArrayElementPtr(psi, SYM(SERVERINFO), i == 0 ? "mpFnidPfn" : NULL, i);
  6704. GetSym(pfn, ach, &ulOffset);
  6705. Print("%10c%-26s = %p %s", ' ', fnid[i], pfn, ach);
  6706. if (ulOffset) {
  6707. Print("+0x%x", (DWORD)ulOffset);
  6708. }
  6709. Print("\n");
  6710. ++i;
  6711. }
  6712. }
  6713. if (opts & OFLAG(w)) {
  6714. Print("\t" "aStoCidPfn:\n");
  6715. i = 0;
  6716. SAFEWHILE (i < ARRAY_SIZE(pServerInfo->aStoCidPfn)) {
  6717. PTR pfn = GetArrayElementPtr(psi, SYM(SERVERINFO), i == 0 ? "aStoCidPfn" : NULL, i);
  6718. GetSym(pfn, ach, &ulOffset);
  6719. Print("%10c%-20s = %p %s", ' ', fnid[i], pfn, ach);
  6720. if (ulOffset) {
  6721. Print("+0x%x", (DWORD)ulOffset);
  6722. }
  6723. Print("\n");
  6724. ++i;
  6725. }
  6726. }
  6727. if (opts & OFLAG(b)) {
  6728. ULONG cbWnd = GetTypeSize(SYM(WND));
  6729. Print("\t" "mpFnid_serverCBWndProc:\n");
  6730. i = 0;
  6731. SAFEWHILE (i < ARRAY_SIZE(pServerInfo->mpFnid_serverCBWndProc)) {
  6732. WORD cb = (WORD)GetArrayElement(psi, SYM(SERVERINFO), i == 0 ? "mpFnid_serverCBWndProc" : NULL, i, "WORD");
  6733. Print("%10c%-26s = %08lx", ' ', fnid[i], cb);
  6734. if (cb) {
  6735. Print(" = sizeof(WND) + 0x%x", cb - cbWnd);
  6736. }
  6737. Print("\n");
  6738. ++i;
  6739. }
  6740. }
  6741. if (opts & OFLAG(m)) {
  6742. /*
  6743. * Add entries to this table in alphabetical order with
  6744. * the prefix removed.
  6745. */
  6746. static const SYSMET_ENTRY aSysMet[SM_CMETRICS] = {
  6747. SMENTRY(ARRANGE),
  6748. SMENTRY(CXBORDER),
  6749. SMENTRY(CYBORDER),
  6750. SMENTRY(CYCAPTION),
  6751. SMENTRY(CLEANBOOT),
  6752. SMENTRY(CXCURSOR),
  6753. SMENTRY(CYCURSOR),
  6754. SMENTRY(DBCSENABLED),
  6755. SMENTRY(DEBUG),
  6756. SMENTRY(CXDLGFRAME),
  6757. SMENTRY(CYDLGFRAME),
  6758. SMENTRY(CXDOUBLECLK),
  6759. SMENTRY(CYDOUBLECLK),
  6760. SMENTRY(CXDRAG),
  6761. SMENTRY(CYDRAG),
  6762. SMENTRY(CXEDGE),
  6763. SMENTRY(CYEDGE),
  6764. SMENTRY(CXFRAME),
  6765. SMENTRY(CYFRAME),
  6766. SMENTRY(CXFULLSCREEN),
  6767. SMENTRY(CYFULLSCREEN),
  6768. SMENTRY(CXICON),
  6769. SMENTRY(CYICON),
  6770. SMENTRY(CXICONSPACING),
  6771. SMENTRY(CYICONSPACING),
  6772. SMENTRY(IMMENABLED),
  6773. SMENTRY(CYKANJIWINDOW),
  6774. SMENTRY(CXMAXIMIZED),
  6775. SMENTRY(CYMAXIMIZED),
  6776. SMENTRY(CXMAXTRACK),
  6777. SMENTRY(CYMAXTRACK),
  6778. SMENTRY(CYMENU),
  6779. SMENTRY(CXMENUCHECK),
  6780. SMENTRY(CYMENUCHECK),
  6781. SMENTRY(MENUDROPALIGNMENT),
  6782. SMENTRY(CXMENUSIZE),
  6783. SMENTRY(CYMENUSIZE),
  6784. SMENTRY(MIDEASTENABLED),
  6785. SMENTRY(CXMIN),
  6786. SMENTRY(CYMIN),
  6787. SMENTRY(CXMINIMIZED),
  6788. SMENTRY(CYMINIMIZED),
  6789. SMENTRY(CXMINSPACING),
  6790. SMENTRY(CYMINSPACING),
  6791. SMENTRY(CXMINTRACK),
  6792. SMENTRY(CYMINTRACK),
  6793. SMENTRY(CMONITORS),
  6794. SMENTRY(CMOUSEBUTTONS),
  6795. SMENTRY(MOUSEPRESENT),
  6796. SMENTRY(MOUSEWHEELPRESENT),
  6797. SMENTRY(NETWORK),
  6798. SMENTRY(PENWINDOWS),
  6799. SMENTRY(RESERVED1),
  6800. SMENTRY(RESERVED2),
  6801. SMENTRY(RESERVED3),
  6802. SMENTRY(RESERVED4),
  6803. SMENTRY(SAMEDISPLAYFORMAT),
  6804. SMENTRY(CXSCREEN),
  6805. SMENTRY(CYSCREEN),
  6806. SMENTRY(CXVSCROLL),
  6807. SMENTRY(CYHSCROLL),
  6808. SMENTRY(CYVSCROLL),
  6809. SMENTRY(CXHSCROLL),
  6810. SMENTRY(SECURE),
  6811. SMENTRY(SHOWSOUNDS),
  6812. SMENTRY(CXSIZE),
  6813. SMENTRY(CYSIZE),
  6814. SMENTRY(SLOWMACHINE),
  6815. SMENTRY(CYSMCAPTION),
  6816. SMENTRY(CXSMICON),
  6817. SMENTRY(CYSMICON),
  6818. SMENTRY(CXSMSIZE),
  6819. SMENTRY(CYSMSIZE),
  6820. SMENTRY(SWAPBUTTON),
  6821. SMENTRY(CYVTHUMB),
  6822. SMENTRY(CXHTHUMB),
  6823. SMENTRY(UNUSED_64),
  6824. SMENTRY(UNUSED_65),
  6825. SMENTRY(UNUSED_66),
  6826. SMENTRY(XVIRTUALSCREEN),
  6827. SMENTRY(YVIRTUALSCREEN),
  6828. SMENTRY(CXVIRTUALSCREEN),
  6829. SMENTRY(CYVIRTUALSCREEN),
  6830. // Windows 2000
  6831. SMENTRY(CMONITORS),
  6832. SMENTRY(SAMEDISPLAYFORMAT),
  6833. // Whistler
  6834. SMENTRY(SHUTTINGDOWN),
  6835. };
  6836. Print("\taiSysMet:\n");
  6837. i = 0;
  6838. SAFEWHILE (i < SM_CMETRICS) {
  6839. DWORD v = (DWORD)GetArrayElement(psi, SYM(SERVERINFO), i == 0 ? "aiSysMet" : NULL, aSysMet[i].iMetric, "DWORD");
  6840. Print( "\t\tSM_%-18s = 0x%08lx = %d\n", aSysMet[i].pstrMetric, v, v);
  6841. ++i;
  6842. }
  6843. }
  6844. if (opts & OFLAG(c)) {
  6845. static LPSTR aszSysColor[COLOR_MAX] = {
  6846. //012345678901234567890
  6847. "SCROLLBAR",
  6848. "BACKGROUND",
  6849. "ACTIVECAPTION",
  6850. "INACTIVECAPTION",
  6851. "MENU",
  6852. "WINDOW",
  6853. "WINDOWFRAME",
  6854. "MENUTEXT",
  6855. "WINDOWTEXT",
  6856. "CAPTIONTEXT",
  6857. "ACTIVEBORDER",
  6858. "INACTIVEBORDER",
  6859. "APPWORKSPACE",
  6860. "HIGHLIGHT",
  6861. "HIGHLIGHTTEXT",
  6862. "BTNFACE",
  6863. "BTNSHADOW",
  6864. "GRAYTEXT",
  6865. "BTNTEXT",
  6866. "INACTIVECAPTIONTEXT",
  6867. "BTNHIGHLIGHT",
  6868. "3DDKSHADOW",
  6869. "3DLIGHT",
  6870. "INFOTEXT",
  6871. "INFOBK",
  6872. "3DALTFACE",
  6873. "HOTLIGHT",
  6874. // new in Windows 2000
  6875. "GRADIENTACTIVECAPTION",
  6876. "GRADIENTINACTIVECAPTION",
  6877. "MENUHILIGHT",
  6878. "MENUBAR",
  6879. };
  6880. COLORREF colors[COLOR_MAX];
  6881. COLORREF colorsUnmatched[COLOR_MAX];
  6882. for (i = 0; i < COLOR_MAX; ++i) {
  6883. colors[i] = (COLORREF)GetArrayElement(psi, SYM(SERVERINFO), i == 0 ? "argbSystem" : NULL, i, SYM(COLORREF));
  6884. }
  6885. for (i = 0; i < COLOR_MAX; ++i) {
  6886. colorsUnmatched[i] = (COLORREF)GetArrayElement(psi, SYM(SERVERINFO), i == 0 ? "argbSystemUnmatched" : NULL, i, SYM(COLORREF));
  6887. }
  6888. Print("\targbSystem:\n\t\tCOLOR%28sSYSRGB\t\tUnmatched\tSYSHBR\n", "");
  6889. i = 0;
  6890. SAFEWHILE (i < COLOR_MAX) {
  6891. Print("\t\tCOLOR_%-25s: (%02x,%02x,%02x)\t(%02x,%02x,%02x)\t0x%08p\n",
  6892. aszSysColor[i],
  6893. GetRValue(colors[i]), GetGValue(colors[i]), GetBValue(colors[i]),
  6894. GetRValue(colorsUnmatched[i]), GetGValue(colorsUnmatched[i]), GetBValue(colorsUnmatched[i]),
  6895. (KHBRUSH)GetArrayElement(psi, SYM(SERVERINFO), i == 0 ? "ahbrSystem" : NULL, i, SYM(KHBRUSH)));
  6896. ++i;
  6897. }
  6898. }
  6899. if (opts & OFLAG(o)) {
  6900. #if 0 // LATER
  6901. OEMBITMAPINFO oembmi[OBI_COUNT];
  6902. for (i = 0; i < OBI_COUNT; ++i) {
  6903. }
  6904. Print("\toembmi @ 0x%p:\n\t\tx \ty \tcx \tcy\n", &psi->oembmi);
  6905. for (i = 0; i < OBI_COUNT; i++) {
  6906. Print("\tbm[%d]:\t%08x\t%08x\t%08x\t%08x\n",
  6907. i,
  6908. si.oembmi[i].x ,
  6909. si.oembmi[i].y ,
  6910. si.oembmi[i].cx,
  6911. si.oembmi[i].cy);
  6912. }
  6913. #else
  6914. Print("\tOEMINFO:\n");
  6915. #endif
  6916. _InitTypeRead(psi, SYM(SERVERINFO));
  6917. Print(
  6918. "\t\tPlanes = %d\n"
  6919. "\t\tBitsPixel = %d\n"
  6920. "\t\tBitCount = %d\n"
  6921. "\t\tdmLogPixels = %d\n"
  6922. "\t\trcScreen = (%d,%d)-(%d,%d) %dx%d\n"
  6923. ,
  6924. (BYTE)ReadField(Planes) ,
  6925. (BYTE)ReadField(BitsPixel) ,
  6926. (WORD)ReadField(BitCount) ,
  6927. (UINT)ReadField(dmLogPixels),
  6928. (LONG)ReadField(rcScreen.left), (LONG)ReadField(rcScreen.top),
  6929. (LONG)ReadField(rcScreen.right), (LONG)ReadField(rcScreen.bottom),
  6930. (LONG)ReadField(rcScreen.right)-(LONG)ReadField(si.rcScreen.left),
  6931. (LONG)ReadField(rcScreen.bottom)-(LONG)ReadField(si.rcScreen.top));
  6932. }
  6933. if (opts & OFLAG(v)) {
  6934. ULONG ulOffsetTmp; // req
  6935. GetFieldOffset(SYM(SERVERINFO), "tmSysFont", &ulOffsetTmp);
  6936. Print(
  6937. "\tptCursor {%d, %d}\n"
  6938. "\tgclBorder 0x%08lx\n"
  6939. "\tdtScroll 0x%08lx\n"
  6940. "\tdtLBSearch 0x%08lx\n"
  6941. "\tdtCaretBlink 0x%08lx\n"
  6942. "\tdwDefaultHeapBase 0x%08lx\n"
  6943. "\tdwDefaultHeapSize 0x%08lx\n"
  6944. "\twMaxLeftOverlapChars 0x%08lx\n"
  6945. "\twMaxRightOverlapchars 0x%08lx\n"
  6946. "\tuiShellMsg 0x%08lx\n"
  6947. "\tcxSysFontChar 0x%08lx\n"
  6948. "\tcySysFontChar 0x%08lx\n"
  6949. "\tcxMsgFontChar 0x%08lx\n"
  6950. "\tcyMsgFontChar 0x%08lx\n"
  6951. "\ttmSysFont 0x%p\n"
  6952. "\tatomIconSmProp 0x%04lx\n"
  6953. "\tatomIconProp 0x%04lx\n"
  6954. "\thIconSmWindows 0x%08lp\n"
  6955. "\thIcoWindows 0x%08lp\n"
  6956. "\thCaptionFont 0x%08lp\n"
  6957. "\thMsgFont 0x%08lp\n"
  6958. "\tatomContextHelpIdProp 0x%08lx\n",
  6959. (LONG)ReadField(ptCursor.x),
  6960. (LONG)ReadField(ptCursor.y),
  6961. (int)ReadField(gclBorder),
  6962. (UINT)ReadField(dtScroll),
  6963. (UINT)ReadField(dtLBSearch),
  6964. (UINT)ReadField(dtCaretBlink),
  6965. (DWORD)ReadField(dwDefaultHeapBase),
  6966. (DWORD)ReadField(dwDefaultHeapSize),
  6967. (int)ReadField(wMaxLeftOverlapChars),
  6968. (int)ReadField(wMaxRightOverlapChars),
  6969. (UINT)ReadField(uiShellMsg),
  6970. (int)ReadField(cxSysFontChar),
  6971. (int)ReadField(cySysFontChar),
  6972. (int)ReadField(cxMsgFontChar),
  6973. (int)ReadField(cyMsgFontChar),
  6974. psi + ulOffsetTmp,
  6975. (ATOM)ReadField(atomIconSmProp),
  6976. (ATOM)ReadField(atomIconProp),
  6977. ReadField(hIconSmWindows),
  6978. ReadField(hIcoWindows),
  6979. ReadField(hCaptionFont),
  6980. ReadField(hMsgFont),
  6981. (ATOM)ReadField(atomContextHelpIdProp));
  6982. }
  6983. if (opts & OFLAG(h)) {
  6984. PTR pshi = 0;
  6985. pshi = EvalExp(VAR(gSharedInfo));
  6986. if (pshi == 0) {
  6987. return TRUE;
  6988. }
  6989. _InitTypeRead(pshi, SYM(SHAREDINFO));
  6990. Print("\nSHAREDINFO @ 0x%p:\n", pshi);
  6991. Print("\taheList 0x%p\n", ReadField(aheList));
  6992. }
  6993. } except (CONTINUE) {
  6994. }
  6995. return TRUE;
  6996. }
  6997. #ifdef KERNEL
  6998. /***************************************************************************\
  6999. * dsms - dump send message structures
  7000. *
  7001. * dsms - dumps all send message structures
  7002. * dsms v - dumps all verbose
  7003. * dsms address - dumps specific sms
  7004. * dsms v address - dumps verbose
  7005. * dsms l [address] - dumps sendlist of sms
  7006. *
  7007. *
  7008. * 06-20-91 ScottLu Created.
  7009. * 6/9/1995 SanfordS made to fit stdexts motif
  7010. \***************************************************************************/
  7011. BOOL Idsms(
  7012. DWORD opts,
  7013. ULONG64 param1)
  7014. {
  7015. ULONG64 psms;
  7016. ULONG offsetPsmsNext;
  7017. ULONG offsetSender;
  7018. ULONG offsetReceiver;
  7019. UINT c = 0;
  7020. UINT cm = 0;
  7021. GetFieldOffset(SYM(tagSMS), "psmsNext", &offsetPsmsNext);
  7022. GetFieldOffset(SYM(tagSMS), "ptiSender", &offsetSender);
  7023. GetFieldOffset(SYM(tagSMS), "ptiReceiver", &offsetReceiver);
  7024. if ((opts & (OFLAG(m) | OFLAG(s) | OFLAG(r))) || (param1 == 0)) {
  7025. psms = GetGlobalPointer(VAR(gpsmsList));
  7026. if (psms == NULL_PTR) {
  7027. Print("No send messages currently in the list.\n");
  7028. return TRUE;
  7029. }
  7030. if (opts & OFLAG(c)) {
  7031. UINT i = 0;
  7032. // just count the messages
  7033. SAFEWHILE (psms != 0) {
  7034. UINT cPrev = c;
  7035. if ((i++ & 0xf) == 0) {
  7036. ShowProgress();
  7037. }
  7038. if (opts & OFLAG(s)) {
  7039. if (GetPointer(psms + offsetSender) == param1) {
  7040. ++c;
  7041. }
  7042. } else if (opts & OFLAG(r)) {
  7043. if (GetPointer(psms + offsetReceiver) == param1) {
  7044. ++c;
  7045. }
  7046. } else {
  7047. ++c;
  7048. }
  7049. if (c != cPrev && (c % 400) == 0) {
  7050. Print("%d (0x%lx)...\n", c, c);
  7051. }
  7052. psms = GetPointer(psms + offsetPsmsNext);
  7053. }
  7054. } else if (opts & OFLAG(m)) {
  7055. // show messages with msg == param1
  7056. SAFEWHILE (psms != NULL_PTR) {
  7057. UINT uMsg;
  7058. c++;
  7059. //move(sms, psms);
  7060. GetFieldValue(psms, SYM(tagSMS), "UINT", uMsg);
  7061. if (uMsg == (UINT)param1) {
  7062. cm++;
  7063. Idsms(opts & ~OFLAG(m), psms);
  7064. }
  7065. psms = GetPointer(psms + offsetPsmsNext);
  7066. }
  7067. Print("%d messages == 0x%x (out of a total of %d).\n", cm, (UINT)param1, c);
  7068. return TRUE;
  7069. } else {
  7070. SAFEWHILE (psms != NULL_PTR) {
  7071. if (param1 == NULL_PTR ||
  7072. ((opts & OFLAG(s)) && GetPointer(psms + offsetSender) == param1) ||
  7073. ((opts & OFLAG(r)) && GetPointer(psms + offsetReceiver) == param1)) {
  7074. c++;
  7075. DEBUGPRINT("calling Idsms(opts=%x, psms=%p)\n", opts, psms);
  7076. if (!Idsms(opts & ~(OFLAG(s) | OFLAG(r)), psms)) {
  7077. DEBUGPRINT("error!\n");
  7078. Print("%d (0x%lx) messages.\n", c, c);
  7079. return FALSE;
  7080. }
  7081. }
  7082. psms = GetPointer(psms + offsetPsmsNext);
  7083. }
  7084. }
  7085. Print("%d (0x%lx) messages.\n", c, c);
  7086. return TRUE;
  7087. }
  7088. psms = param1;
  7089. Print("PSMS @ 0x%p\n", psms);
  7090. _InitTypeRead(psms, SYM(tagSMS));
  7091. Print("SEND: ");
  7092. if (ReadField(ptiSender) != NULL_PTR) {
  7093. Idt(OFLAG(p), ReadField(ptiSender));
  7094. } else if (ReadField(ptiCallBackSender) != NULL_PTR) {
  7095. Print("*");
  7096. Idt(OFLAG(p), ReadField(ptiCallBackSender));
  7097. } else {
  7098. Print("NULL\n");
  7099. }
  7100. Print("RECV:");
  7101. if (ReadField(ptiReceiver) != NULL_PTR) {
  7102. Print(" ");
  7103. Idt(OFLAG(p), ReadField(ptiReceiver));
  7104. } else {
  7105. Print("NULL\n");
  7106. }
  7107. if (opts & OFLAG(v)) {
  7108. char ach[80];
  7109. UINT message = (UINT)ReadField(message);
  7110. Print("\tpsmsNext 0x%08p\n", ReadField(psmsNext));
  7111. if (IsChk()) {
  7112. Print("\tpsmsSendList 0x%p\n"
  7113. "\tpsmsSendNext 0x%p\n",
  7114. ReadField(psmsSendList),
  7115. ReadField(psmsSendNext));
  7116. }
  7117. Print("\tpsmsReceiveNext 0x%08p\n"
  7118. "\ttSent 0x%08lx\n"
  7119. "\tptiSender 0x%08p\n"
  7120. "\tptiCallBackSender 0x%08p\n"
  7121. "\tptiReceiver 0x%08p\n"
  7122. "\tlRet 0x%08p\n"
  7123. "\tflags %s\n"
  7124. "\twParam 0x%08p\n"
  7125. "\tlParam 0x%08p\n"
  7126. "\tmessage 0x%08lx %s\n",
  7127. ReadField(psmsReceiveNext),
  7128. (DWORD)ReadField(tSent),
  7129. ReadField(ptiSender),
  7130. ReadField(ptiCallBackSender),
  7131. ReadField(ptiReceiver),
  7132. ReadField(lRet),
  7133. GetFlags(GF_SMS, (WORD)ReadField(flags), NULL, TRUE),
  7134. ReadField(wParam),
  7135. ReadField(lParam),
  7136. message, GetWindowMessageNameInternal(message));
  7137. DebugGetWindowTextA(ReadField(spwnd), ach, ARRAY_SIZE(ach));
  7138. Print("\tspwnd 0x%08p \"%s\"\n", ReadField(spwnd), ach);
  7139. } else if (opts & OFLAG(w)) {
  7140. // a bit of verbose
  7141. char ach[80];
  7142. DebugGetWindowTextA(ReadField(spwnd), ach, ARRAY_SIZE(ach));
  7143. Print(" MSG: %08lx %08p %08p / lRet: %08p / tSend: %08lx\n",
  7144. (DWORD)ReadField(message), ReadField(wParam), ReadField(lParam),
  7145. ReadField(lRet), (DWORD)ReadField(tSent));
  7146. Print(" pwnd: %p \"%s\"\n", ReadField(spwnd), ach);
  7147. }
  7148. #ifdef LATER
  7149. if (IsChk()) {
  7150. if (opts & OFLAG(l)) {
  7151. DWORD idThread;
  7152. PTR psmsList; // PSMS
  7153. DWORD idThreadSender, idThreadReceiver;
  7154. CLIENT_ID Cid;
  7155. psmsList = ReadField(psmsSendList);
  7156. if (psmsList == NULL_PTR) {
  7157. Print("%p : Empty List\n", psms);
  7158. } else {
  7159. Print("%p : [tidSender](msg)[tidReceiver]\n", psms);
  7160. }
  7161. SAFEWHILE (psmsList != NULL_PTR) {
  7162. PTR ptiSender;
  7163. //move(sms, psmsList);
  7164. GetFieldValue(psmsList, SYM(tagSMS), ptiSender, ptiSender);
  7165. if (ptiSender == NULL_PTR) {
  7166. idThread = 0;
  7167. } else {
  7168. PTR pEThread;
  7169. GetFieldValue(ptiSender, SYM(THREADINFO), "pEThread", pETHread);
  7170. // up to here
  7171. GetEThreadData(ti.pEThread, EThreadCid, &Cid);
  7172. idThreadSender = PtrToUlong(Cid.UniqueThread);
  7173. }
  7174. if (sms.ptiReceiver == NULL_PTR) {
  7175. idThread = 0;
  7176. } else {
  7177. move(ti, sms.ptiReceiver);
  7178. GetEThreadData(ti.pEThread, EThreadCid, &Cid);
  7179. idThreadReceiver = PtrToUlong(Cid.UniqueThread);
  7180. }
  7181. Print("%p : [%x](%x)[%x]\n", psmsList, idThreadSender, sms.message,
  7182. idThreadReceiver);
  7183. if (psmsList == sms.psmsSendNext) {
  7184. Print("Loop in list?\n");
  7185. return FALSE;
  7186. }
  7187. psmsList = sms.psmsSendNext;
  7188. }
  7189. Print("\n");
  7190. }
  7191. }
  7192. #endif
  7193. return TRUE;
  7194. }
  7195. #endif // KERNEL
  7196. #ifdef KERNEL
  7197. /***************************************************************************\
  7198. * dt - dump thread
  7199. *
  7200. * dt - dumps simple thread info of all threads which have queues
  7201. * on server
  7202. * dt v - dumps verbose thread info of all threads which have queues
  7203. * on server
  7204. * dt id - dumps simple thread info of single server thread id
  7205. * dt v id - dumps verbose thread info of single server thread id
  7206. *
  7207. * 06-20-91 ScottLu Created.
  7208. * 6/9/1995 SanfordS made to fit stdexts motif
  7209. \***************************************************************************/
  7210. BOOL DumpThread(
  7211. DWORD opts,
  7212. PTR pEThread)
  7213. {
  7214. WCHAR ach[256];
  7215. PTR pq;
  7216. PTR ppi;
  7217. PTR pEThreadT;
  7218. PTR pti = NULL_PTR;
  7219. PTR pcti;
  7220. CLIENTTHREADINFO cti;
  7221. PTR psms;
  7222. ULONG64 ProcessId;
  7223. PTR pEProcess;
  7224. ULONG64 ThreadId;
  7225. GetFieldValue(pEThread, "nt!ETHREAD", "Tcb.Win32Thread", pti);
  7226. GetFieldValue(pEThread, "nt!ETHREAD", "Cid.UniqueProcess", ProcessId);
  7227. GetFieldValue(pEThread, "nt!ETHREAD", "Cid.UniqueThread", ThreadId);
  7228. GetFieldValue(pEThread, "nt!ETHREAD", "ThreadsProcess", pEProcess);
  7229. if (GetFieldValue(pti, "win32k!W32THREAD", "pEThread", pEThreadT)) {
  7230. if (!(opts & OFLAG(g))) {
  7231. Print(" s %-2d et 0x%p t 0x???????? q 0x???????? i %2x.%-3lx <unknown name>\n",
  7232. GetProcessSessionId(pEProcess),
  7233. pEThread,
  7234. (ULONG)ProcessId,
  7235. (ULONG)ThreadId);
  7236. }
  7237. return TRUE;
  7238. }
  7239. if (pEThreadT != pEThread || pti == 0) {
  7240. return FALSE;
  7241. } else { // Good thread
  7242. /*
  7243. * Print out simple thread info if this is in simple mode. Print
  7244. * out queue info if in verbose mode (printing out queue info
  7245. * also prints out simple thread info).
  7246. */
  7247. if (!(opts & OFLAG(v))) {
  7248. PWCHAR pwch;
  7249. GetAppName(pEThread, pti, ach, sizeof(ach));
  7250. pwch = wcsrchr(ach, L'\\');
  7251. if (pwch == NULL_PTR) {
  7252. pwch = ach;
  7253. } else {
  7254. pwch++;
  7255. }
  7256. GetFieldValue(pti, SYM(THREADINFO), "pq", pq);
  7257. GetFieldValue(pti, SYM(THREADINFO), "ppi", ppi);
  7258. Print(" s %-2d et 0x%p t 0x%p q 0x%p ppi 0x%p i %2x.%-3lx %ws\n",
  7259. GetProcessSessionId(pEProcess),
  7260. pEThread,
  7261. pti,
  7262. pq,
  7263. ppi,
  7264. (ULONG)ProcessId,
  7265. (ULONG)ThreadId,
  7266. pwch);
  7267. /*
  7268. * Dump thread input state if required
  7269. */
  7270. if (opts & OFLAG(s)) {
  7271. #define DT_INDENT "\t"
  7272. GetFieldValue(pti, SYM(THREADINFO), "pcti", pcti);
  7273. move(cti, pcti);
  7274. if (cti.fsWakeMask == 0) {
  7275. Print(DT_INDENT "Not waiting for USER input events.\n");
  7276. } else if ((cti.fsWakeMask & (QS_ALLINPUT | QS_EVENT)) == (QS_ALLINPUT | QS_EVENT)) {
  7277. Print(DT_INDENT "Waiting for any USER input event (== in GetMessage).\n");
  7278. } else if ((cti.fsWakeMask == (QS_SMSREPLY | QS_SENDMESSAGE))
  7279. || (cti.fsWakeMask == QS_SMSREPLY)) {
  7280. GetFieldValue(pti, SYM(THREADINFO), "psmsSent", psms);
  7281. _InitTypeRead(psms, SYM(SMS));
  7282. Print(DT_INDENT "Waiting on thread 0x%p to reply to this SendMessage:\n", ReadField(ptiReceiver));
  7283. Print(DT_INDENT "pwnd:0x%p message:%#lx wParam:0x%p lParam:0x%p\n",
  7284. ReadField(pwnd), (UINT)ReadField(message), ReadField(wParam), ReadField(lParam));
  7285. if (cti.fsChangeBits & QS_SMSREPLY) {
  7286. Print(DT_INDENT "The receiver thread has replied to the message.\n");
  7287. }
  7288. } else {
  7289. Print(DT_INDENT "Waiting for: %s\n",
  7290. GetFlags(GF_QS, (WORD)cti.fsWakeMask, NULL, TRUE));
  7291. }
  7292. }
  7293. } else {
  7294. Idti(0, pti);
  7295. Print("--------\n");
  7296. }
  7297. }
  7298. return TRUE;
  7299. }
  7300. typedef struct _THREAD_DUMP_CONTEXT {
  7301. DWORD opts;
  7302. ULONG64 ThreadToDump;
  7303. } THREAD_DUMP_CONTEXT;
  7304. ULONG
  7305. DumpThreadsCallback (
  7306. PFIELD_INFO NextThread,
  7307. PVOID Context)
  7308. {
  7309. PTR pEThread = NextThread->address;
  7310. ULONG64 ThreadId;
  7311. THREAD_DUMP_CONTEXT *pTDC = (THREAD_DUMP_CONTEXT *)Context;
  7312. PTR UserProbeAddress;
  7313. ULONG Result;
  7314. //
  7315. // Read the user probe address from the target system.
  7316. //
  7317. // N.B. The user probe address is constant on MIPS, Alpha, and the PPC.
  7318. // On the x86, it may not be defined for the target system if it
  7319. // does not contain the code to support 3gb of user address space.
  7320. //
  7321. UserProbeAddress = GetExpression("nt!MmUserProbeAddress");
  7322. if ((UserProbeAddress == 0) ||
  7323. (ReadMemory(UserProbeAddress,
  7324. &UserProbeAddress,
  7325. sizeof(UserProbeAddress),
  7326. &Result) == FALSE)) {
  7327. UserProbeAddress = 0x7fff0000;
  7328. }
  7329. /*
  7330. * ThreadToDump is either 0 (all windows threads) or its
  7331. * a TID ( < UserProbeAddress or its a pEThread.
  7332. */
  7333. GetFieldValue(pEThread, "nt!ETHREAD", "Cid.UniqueThread", ThreadId);
  7334. if (pTDC->ThreadToDump == 0 ||
  7335. (pTDC->ThreadToDump < UserProbeAddress &&
  7336. pTDC->ThreadToDump == ThreadId) ||
  7337. (pTDC->ThreadToDump >= UserProbeAddress &&
  7338. pTDC->ThreadToDump == pEThread)) {
  7339. if (!DumpThread(pTDC->opts, pEThread) && pTDC->ThreadToDump != 0) {
  7340. Print("Sorry, EThread %p is not a Win32 thread.\n",
  7341. pEThread);
  7342. }
  7343. if (pTDC->ThreadToDump != 0) {
  7344. return TRUE;
  7345. }
  7346. } // Chosen Thread
  7347. return FALSE;
  7348. }
  7349. VOID DumpProcessThreads(
  7350. DWORD opts,
  7351. PTR pEProcess,
  7352. ULONG64 ThreadToDump)
  7353. {
  7354. PTR pW32Process;
  7355. ULONG64 NextThread;
  7356. THREAD_DUMP_CONTEXT TDC = {
  7357. opts,
  7358. ThreadToDump
  7359. };
  7360. /*
  7361. * Dump threads of Win32 Processes only
  7362. */
  7363. if ((GetFieldValue(pEProcess, "nt!EPROCESS", "Win32Process", pW32Process))
  7364. || (pW32Process == 0)) {
  7365. return;
  7366. }
  7367. GetFieldValue(pEProcess, "nt!EPROCESS", "Pcb.ThreadListHead.Flink", NextThread);
  7368. ListType("nt!ETHREAD", NextThread, 1, "Tcb.ThreadListEntry.Flink", &TDC, DumpThreadsCallback);
  7369. }
  7370. ULONG
  7371. DumpProcessThreadsCallback (
  7372. PFIELD_INFO NextProcess,
  7373. PVOID Context)
  7374. {
  7375. THREAD_DUMP_CONTEXT *pTDC = (THREAD_DUMP_CONTEXT *)Context;
  7376. DumpProcessThreads(pTDC->opts, NextProcess->address, pTDC->ThreadToDump);
  7377. return FALSE;
  7378. }
  7379. BOOL Idt(
  7380. DWORD opts,
  7381. ULONG64 param1)
  7382. {
  7383. ULONG64 ThreadToDump;
  7384. ULONG64 NextProcess;
  7385. ULONG64 ProcessHead;
  7386. PTR pEThread;
  7387. PTR pti;
  7388. THREAD_DUMP_CONTEXT TDC;
  7389. ThreadToDump = param1;
  7390. /*
  7391. * If its a pti, validate it, and turn it into and idThread.
  7392. */
  7393. if (opts & OFLAG(p)) {
  7394. if (!param1) {
  7395. Print("Expected a pti parameter.\n");
  7396. return FALSE;
  7397. }
  7398. pti = FIXKP(param1);
  7399. if (pti == 0) {
  7400. Print("WARNING: bad pti given!\n");
  7401. pti = param1;
  7402. } else {
  7403. GetFieldValue(pti, SYM(tagTHREADINFO), "pEThread", pEThread);
  7404. if (!DumpThread(opts, pEThread)) {
  7405. /*
  7406. * This thread either doesn't have a pti or something
  7407. * is whacked out. Just skip it if we want all
  7408. * threads.
  7409. */
  7410. Print("Sorry, EThread %p is not a Win32 thread.\n",
  7411. pEThread);
  7412. return FALSE;
  7413. }
  7414. return TRUE;
  7415. }
  7416. }
  7417. /*
  7418. * If he just wants the current thread, located it.
  7419. */
  7420. if (opts & OFLAG(c)) {
  7421. Print("Current Thread:");
  7422. GetCurrentThreadAddr(dwProcessor, &ThreadToDump);
  7423. if (ThreadToDump == 0) {
  7424. Print("Unable to get current thread pointer.\n");
  7425. return FALSE;
  7426. }
  7427. pEThread = ThreadToDump;
  7428. if (!DumpThread(opts, pEThread)) {
  7429. /*
  7430. * This thread either doesn't have a pti or something
  7431. * is whacked out. Just skip it if we want all
  7432. * threads.
  7433. */
  7434. Print("Sorry, EThread %p is not a Win32 thread.\n",
  7435. pEThread);
  7436. return FALSE;
  7437. }
  7438. return TRUE;
  7439. } else if (ThreadToDump == 0) {
  7440. Print("**** NT ACTIVE WIN32 THREADINFO DUMP ****\n");
  7441. }
  7442. ProcessHead = EvalExp("PsActiveProcessHead");
  7443. if (!ProcessHead) {
  7444. Print("Unable to get value of PsActiveProcessHead\n");
  7445. return FALSE;
  7446. }
  7447. if (GetFieldValue(ProcessHead, "nt!LIST_ENTRY", "Flink", NextProcess)) {
  7448. Print("Unable to get value of PsActiveProcessHead\n");
  7449. return FALSE;
  7450. }
  7451. if (NextProcess == 0) {
  7452. Print("PsActiveProcessHead->Flink is NULL!\n");
  7453. return FALSE;
  7454. }
  7455. TDC.opts = opts;
  7456. TDC.ThreadToDump = ThreadToDump;
  7457. ListType("nt!EPROCESS", NextProcess, 1, "ActiveProcessLinks.Flink", &TDC, DumpProcessThreadsCallback);
  7458. if (opts & OFLAG(c)) {
  7459. Print("%p is not a windows thread.\n", ThreadToDump);
  7460. }
  7461. return TRUE;
  7462. }
  7463. #endif // KERNEL
  7464. #ifdef KERNEL
  7465. /***************************************************************************\
  7466. * dp - dump process
  7467. *
  7468. *
  7469. * 06-27-97 GerardoB Created.
  7470. \***************************************************************************/
  7471. BOOL DumpProcess(
  7472. DWORD opts,
  7473. PTR pEProcess)
  7474. {
  7475. WCHAR ach[256];
  7476. ULONG W32PF_Flags;
  7477. PTR ppi;
  7478. ULONG ulSessionId;
  7479. ULONG64 ulUniqueProcessId;
  7480. PTR pEProcessT;
  7481. GetFieldValue(pEProcess, "nt!EPROCESS", "Win32Process", ppi);
  7482. GetFieldValue(pEProcess, "nt!EPROCESS", "UniqueProcessId", ulUniqueProcessId);
  7483. _GetProcessSessionId(pEProcess, &ulSessionId);
  7484. if (GetFieldValue(ppi, "win32k!W32PROCESS", "Process", pEProcessT)) {
  7485. Print("sid %2d ep 0x%p p 0x???????? f 0x???????? i %3I64x <unknown name>\n",
  7486. ulSessionId,
  7487. pEProcess,
  7488. ulUniqueProcessId);
  7489. return TRUE;
  7490. }
  7491. if (pEProcessT != pEProcess || ppi == 0) {
  7492. return FALSE;
  7493. } else { // Good process
  7494. /*
  7495. * Print out simple process info if this is in simple mode.
  7496. */
  7497. if (!(opts & OFLAG(v))) {
  7498. PWCHAR pwch;
  7499. GetProcessName(pEProcess, ach);
  7500. pwch = wcsrchr(ach, L'\\');
  7501. if (pwch == NULL) {
  7502. pwch = ach;
  7503. } else {
  7504. pwch++;
  7505. }
  7506. GetFieldValue(ppi, "win32k!W32PROCESS", "W32PF_Flags", W32PF_Flags);
  7507. Print("sid %2d ep 0x%p p 0x%p f 0x%08lx i %3I64x %ws\n",
  7508. ulSessionId,
  7509. pEProcess,
  7510. ppi,
  7511. W32PF_Flags,
  7512. ulUniqueProcessId,
  7513. pwch);
  7514. } else {
  7515. Idpi(0, ppi);
  7516. Print("--------\n");
  7517. }
  7518. /*
  7519. * Dump all threads if required
  7520. */
  7521. if (opts & OFLAG(t)) {
  7522. DumpProcessThreads(opts, pEProcess, 0);
  7523. }
  7524. }
  7525. return TRUE;
  7526. }
  7527. typedef struct _PROCESS_DUMP_CONTEXT {
  7528. DWORD opts;
  7529. ULONG64 ProcessToDump;
  7530. } PROCESS_DUMP_CONTEXT;
  7531. ULONG
  7532. DumpProcessCallback(
  7533. PFIELD_INFO NextProcess,
  7534. PVOID Context)
  7535. {
  7536. ULONG64 pEProcess = NextProcess->address;
  7537. ULONG64 pW32Process;
  7538. ULONG64 ulUniqueProcessId;
  7539. PROCESS_DUMP_CONTEXT *pPDC = (PROCESS_DUMP_CONTEXT *)Context;
  7540. ULONG64 UserProbeAddress;
  7541. ULONG Result;
  7542. //
  7543. // Read the user probe address from the target system.
  7544. //
  7545. // N.B. The user probe address is constant on MIPS, Alpha, and the PPC.
  7546. // On the x86, it may not be defined for the target system if it
  7547. // does not contain the code to support 3gb of user address space.
  7548. //
  7549. UserProbeAddress = GetExpression("nt!MmUserProbeAddress");
  7550. if ((UserProbeAddress == 0) ||
  7551. (ReadMemory(UserProbeAddress,
  7552. &UserProbeAddress,
  7553. sizeof(UserProbeAddress),
  7554. &Result) == FALSE)) {
  7555. UserProbeAddress = 0x7fff0000;
  7556. }
  7557. /*
  7558. * Dump threads of Win32 Processes only
  7559. */
  7560. if (GetFieldValue(pEProcess, "nt!EPROCESS", "Win32Process", pW32Process) || pW32Process == 0) {
  7561. return FALSE;
  7562. }
  7563. GetFieldValue(pEProcess, "nt!EPROCESS", "UniqueProcessId", ulUniqueProcessId);
  7564. /*
  7565. * ProcessToDump is either 0 (all windows processes) or its
  7566. * a TID ( < UserProbeAddress or its a pEPRocess.
  7567. */
  7568. if (pPDC->ProcessToDump == 0 ||
  7569. (pPDC->ProcessToDump < UserProbeAddress &&
  7570. pPDC->ProcessToDump == ulUniqueProcessId) ||
  7571. (pPDC->ProcessToDump >= UserProbeAddress &&
  7572. pPDC->ProcessToDump == pEProcess)) {
  7573. if (!DumpProcess(pPDC->opts, pEProcess) && (pPDC->ProcessToDump != 0)) {
  7574. Print("Sorry, EProcess %p is not a Win32 process.\n",
  7575. pEProcess);
  7576. }
  7577. if (pPDC->ProcessToDump != 0) {
  7578. return TRUE;
  7579. }
  7580. }
  7581. return FALSE;
  7582. }
  7583. BOOL Idp(
  7584. DWORD opts,
  7585. ULONG64 param1)
  7586. {
  7587. ULONG64 ProcessToDump;
  7588. PTR ppi;
  7589. PTR pEProcess;
  7590. ULONG64 NextProcess;
  7591. ULONG64 ProcessHead;
  7592. PROCESS_DUMP_CONTEXT PDC;
  7593. ProcessToDump = param1;
  7594. /*
  7595. * If it's a ppi, validate it.
  7596. */
  7597. if (opts & OFLAG(p)) {
  7598. if (!param1) {
  7599. Print("Expected a ppi parameter.\n");
  7600. return FALSE;
  7601. }
  7602. ppi = FIXKP(param1);
  7603. if (ppi == 0) {
  7604. Print("WARNING: bad ppi given!\n");
  7605. ppi = param1;
  7606. } else {
  7607. GetFieldValue(ppi, "win32k!W32PROCESS", "Process", pEProcess);
  7608. if (!DumpProcess(opts, pEProcess)) {
  7609. Print("EProcess %p is not a Win32 process.\n", pEProcess);
  7610. return FALSE;
  7611. }
  7612. return TRUE;
  7613. }
  7614. }
  7615. /*
  7616. * If he just wants the current process, locate it.
  7617. */
  7618. if (opts & OFLAG(c)) {
  7619. Print("Current Process: ");
  7620. GetCurrentProcessAddr(dwProcessor, 0, &ProcessToDump);
  7621. if (ProcessToDump == 0) {
  7622. Print("Unable to get current process pointer.\n");
  7623. return FALSE;
  7624. }
  7625. pEProcess = ProcessToDump;
  7626. if (!DumpProcess(opts, pEProcess)) {
  7627. Print("Sorry, EProcess %p is not a Win32 process.\n", pEProcess);
  7628. return FALSE;
  7629. }
  7630. return TRUE;
  7631. /*
  7632. * else he must want all window threads.
  7633. */
  7634. } else if (ProcessToDump == 0) {
  7635. Print("**** NT ACTIVE WIN32 PROCESSINFO DUMP ****\n");
  7636. }
  7637. ProcessHead = EvalExp("PsActiveProcessHead");
  7638. if (!ProcessHead) {
  7639. Print("Unable to get value of PsActiveProcessHead\n");
  7640. return FALSE;
  7641. }
  7642. if (GetFieldValue(ProcessHead, "nt!LIST_ENTRY", "Flink", NextProcess)) {
  7643. Print("Unable to get value of PsActiveProcessHead\n");
  7644. return FALSE;
  7645. }
  7646. if (NextProcess == 0) {
  7647. Print("PsActiveProcessHead->Flink is NULL!\n");
  7648. return FALSE;
  7649. }
  7650. PDC.opts = opts;
  7651. PDC.ProcessToDump = ProcessToDump;
  7652. ListType("nt!EPROCESS", NextProcess, 1, "ActiveProcessLinks.Flink", &PDC, DumpProcessCallback);
  7653. if (opts & OFLAG(c)) {
  7654. Print("%p is not a windows process.\n", ProcessToDump);
  7655. }
  7656. return TRUE;
  7657. }
  7658. #endif // KERNEL
  7659. #ifdef KERNEL
  7660. /***************************************************************************\
  7661. * dtdb - dump TDB
  7662. *
  7663. * dtdb address - dumps TDB structure at address
  7664. *
  7665. * 14-Sep-1993 DaveHart Created.
  7666. * 6/9/1995 SanfordS made to fit stdexts motif
  7667. \***************************************************************************/
  7668. ULONG
  7669. dtdbCallback(
  7670. PTR pti,
  7671. PVOID Data)
  7672. {
  7673. PTR ptdb;
  7674. UNREFERENCED_PARAMETER(Data);
  7675. GetFieldValue(pti, SYM(THREADINFO), "ptdb", ptdb);
  7676. SAFEWHILE (ptdb) {
  7677. Idtdb(0, ptdb);
  7678. GetFieldValue(ptdb, SYM(TDB), "ptdbNext", ptdb);
  7679. }
  7680. return FALSE;
  7681. }
  7682. BOOL Idtdb(
  7683. DWORD opts,
  7684. ULONG64 param1)
  7685. {
  7686. PTR ptdb;
  7687. UNREFERENCED_PARAMETER(opts);
  7688. if (param1 == 0) {
  7689. Print("Dumping all ptdbs:\n");
  7690. ForEachPti(dtdbCallback, NULL);
  7691. return TRUE;
  7692. }
  7693. ptdb = param1;
  7694. if (ptdb == 0) {
  7695. Print("Must supply a TDB address.\n");
  7696. return FALSE;
  7697. }
  7698. _InitTypeRead(ptdb, SYM(TDB));
  7699. Print("TDB (non preemptive scheduler task database) @ 0x%p\n", ptdb);
  7700. Print("\tptdbNext 0x%p\n", ReadField(ptdbNext));
  7701. Print("\tnEvents 0x%08lx\n", (ULONG)ReadField(nEvents));
  7702. Print("\tnPriority 0x%08lx\n", (ULONG)ReadField(nPriority));
  7703. Print("\tpti 0x%p\n", ReadField(pti));
  7704. return TRUE;
  7705. }
  7706. #endif // KERNEL
  7707. #ifndef KERNEL
  7708. /************************************************************************\
  7709. * Icbp
  7710. *
  7711. * Breaks into the debugger in context of csrss.exe.
  7712. *
  7713. * fSuccess
  7714. *
  7715. * 6/1/98 JerrySh
  7716. \************************************************************************/
  7717. BOOL Icbp(
  7718. VOID)
  7719. {
  7720. DWORD dwProcessId;
  7721. DWORD dwThreadId;
  7722. BOOL fServerProcess;
  7723. USER_API_MSG m;
  7724. PACTIVATEDEBUGGERMSG a = &m.u.ActivateDebugger;
  7725. moveExpValue(&fServerProcess, VAR(gfServerProcess));
  7726. if (fServerProcess) {
  7727. Print("Already debugging server process!\n");
  7728. } else {
  7729. /*
  7730. * Get the process and thread ID of a CSRSS thread.
  7731. */
  7732. dwThreadId = GetWindowThreadProcessId(GetDesktopWindow(), &dwProcessId);
  7733. a->ClientId.UniqueProcess = LongToHandle(dwProcessId);
  7734. a->ClientId.UniqueThread = LongToHandle(dwThreadId);
  7735. /*
  7736. * Tell CSRSS to break on itself.
  7737. */
  7738. CsrClientCallServer((PCSR_API_MSG)&m,
  7739. NULL,
  7740. CSR_MAKE_API_NUMBER(USERSRV_SERVERDLL_INDEX, UserpActivateDebugger),
  7741. sizeof(*a));
  7742. }
  7743. return TRUE;
  7744. }
  7745. #endif // !KERNEL
  7746. #ifdef KERNEL
  7747. /***************************************************************************\
  7748. * dkl - dump keyboard layout
  7749. *
  7750. * dkl address - dumps keyboard layout structure at address
  7751. *
  7752. * 05/21/95 GregoryW Created.
  7753. \***************************************************************************/
  7754. const char* GetCharSetText(
  7755. const BYTE bCharSet)
  7756. {
  7757. static struct _tagBASECHARSET {
  7758. const char* pstrCS;
  7759. DWORD dwValue;
  7760. } const CrackCS[] = {
  7761. {"ANSI_CHARSET" ,0 },
  7762. {"DEFAULT_CHARSET" ,1 },
  7763. {"SYMBOL_CHARSET" ,2 },
  7764. {"SHIFTJIS_CHARSET" ,128 },
  7765. {"HANGEUL_CHARSET" ,129 },
  7766. {"GB2312_CHARSET" ,134 },
  7767. {"CHINESEBIG5_CHARSET" ,136 },
  7768. {"OEM_CHARSET" ,255 },
  7769. {"JOHAB_CHARSET" ,130 },
  7770. {"HEBREW_CHARSET" ,177 },
  7771. {"ARABIC_CHARSET" ,178 },
  7772. {"GREEK_CHARSET" ,161 },
  7773. {"TURKISH_CHARSET" ,162 },
  7774. {"THAI_CHARSET" ,222 },
  7775. {"EASTEUROPE_CHARSET" ,238 },
  7776. {"RUSSIAN_CHARSET" ,204 },
  7777. {"MAC_CHARSET" ,77 }
  7778. };
  7779. UINT i;
  7780. for (i = 0; i < ARRAY_SIZE(CrackCS); ++i) {
  7781. if (CrackCS[i].dwValue == bCharSet) {
  7782. break;
  7783. }
  7784. }
  7785. if (i < ARRAY_SIZE(CrackCS)) {
  7786. return CrackCS[i].pstrCS;
  7787. }
  7788. return "ILLEGAL VALUE";
  7789. }
  7790. BOOL DumpKF(
  7791. DWORD opts,
  7792. DWORD n,
  7793. PTR spkf,
  7794. BOOL fActive)
  7795. {
  7796. ULONG offTmp;
  7797. PTR pKbdTbl;
  7798. DWORD fLocaleFlags;
  7799. WCHAR awchKF[9]; // size should match KBDFILE::awchKF
  7800. WCHAR awchDllName[32]; // size should match KBDFILE::awchDllName
  7801. DWORD dwType, dwSubType;
  7802. PTR pDeadKey;
  7803. if (spkf == 0) {
  7804. Print(" spkf 0x%p (NONE!)\n", NULL_PTR);
  7805. return TRUE;
  7806. }
  7807. _InitTypeRead(spkf, SYM(tagKBDFILE));
  7808. Print(" %c" "spkf[%02x] 0x%p (cLockObj = %d)\n",
  7809. fActive ? '*' : ' ',
  7810. n, spkf, ReadField(head.cLockObj));
  7811. if (opts & OFLAG(v)) {
  7812. Print(" pkfNext 0x%p\n", ReadField(pkfNext));
  7813. GetFieldOffset(SYM(tagKBDFILE), "awchKF", &offTmp);
  7814. if (offTmp) {
  7815. tryMoveBlock(awchKF, spkf + offTmp, sizeof(awchKF));
  7816. awchKF[ARRAY_SIZE(awchKF) - 1] = 0;
  7817. Print(" awchKF[] L\"%ws\"\n", awchKF);
  7818. }
  7819. }
  7820. GetFieldOffset(SYM(tagKBDFILE), "awchDllName", &offTmp);
  7821. if (offTmp) {
  7822. tryMoveBlock(awchDllName, spkf + offTmp, sizeof(awchDllName));
  7823. awchDllName[ARRAY_SIZE(awchDllName) - 1] = 0;
  7824. Print(" DllName[] L\"%ws\"\n", awchDllName);
  7825. }
  7826. pKbdTbl = ReadField(pKbdTbl);
  7827. Print(" pKbdTbl 0x%p\n", pKbdTbl);
  7828. GetFieldValue(pKbdTbl, SYM(tagKbdLayer), "dwType", dwType);
  7829. GetFieldValue(pKbdTbl, SYM(tagKbdLayer), "dwSubType", dwSubType);
  7830. Print(" Type:Sub (%x:%x)\n", dwType, dwSubType);
  7831. GetFieldValue(pKbdTbl, SYM(tagKbdLayer), "pDeadKey", pDeadKey);
  7832. if (opts & OFLAG(v)) {
  7833. Print(" hBase 0x%08lx\n", ReadField(hBase));
  7834. /*
  7835. * Dump pKbdTbl
  7836. */
  7837. GetFieldValue(pKbdTbl, SYM(tagKbdLayer), "fLocaleFlags", fLocaleFlags);
  7838. Print(" pDeadKey: 0x%p\n", pDeadKey);
  7839. Print(" fLocaleFlags 0x%08lx\n", fLocaleFlags);
  7840. if (opts & OFLAG(d)) {
  7841. Iddk(OFLAG(i), pKbdTbl);
  7842. }
  7843. }
  7844. return TRUE;
  7845. }
  7846. typedef struct {
  7847. PTR hkl;
  7848. UINT n;
  7849. } KLCOUNT, *PKLCOUNT;
  7850. typedef struct {
  7851. DWORD opts;
  7852. KLCOUNT kl[128];
  7853. } KLCALLBACKINFO, *PKLCALLBACKINFO;
  7854. ULONG WDBGAPI ThreadKLCallback(PTR pti, PVOID Data)
  7855. {
  7856. PTR pkl;
  7857. PTR hkl, hklPrev;
  7858. PKLCALLBACKINFO pInfo = (PKLCALLBACKINFO)Data;
  7859. UINT i;
  7860. _InitTypeRead(pti, SYM(THREADINFO));
  7861. pkl = ReadField(spklActive);
  7862. hklPrev = ReadField(hklPrev);
  7863. Print(" pti 0x%p ", pti);
  7864. GetFieldValue(pkl, SYM(tagKL), "hkl", hkl);
  7865. Print(" spklActive %p hkl %08x (prev: %08x)\n", pkl, (DWORD)hkl, (DWORD)hklPrev);
  7866. /*
  7867. * Count the KL usage.
  7868. */
  7869. for (i = 0; i < ARRAY_SIZE(pInfo->kl); ++i) {
  7870. if (pInfo->kl[i].hkl == 0) {
  7871. pInfo->kl[i].hkl = hkl;
  7872. ++pInfo->kl[i].n;
  7873. break;
  7874. } else if (pInfo->kl[i].hkl == hkl) {
  7875. ++pInfo->kl[i].n;
  7876. break;
  7877. }
  7878. }
  7879. return FALSE;
  7880. }
  7881. ULONG WDBGAPI KLProcessCallback(
  7882. PTR ppi,
  7883. PVOID Data)
  7884. {
  7885. PKLCALLBACKINFO pInfo = (PKLCALLBACKINFO)Data;
  7886. PTR pEProcess;
  7887. WCHAR awchProcessName[MAX_PATH];
  7888. PTI_CONTEXT ptic;
  7889. W32PID W32Pid;
  7890. GetFieldValue(ppi, SYM(_W32PROCESS), "Process", pEProcess);
  7891. if (!GetProcessName(pEProcess, awchProcessName)) {
  7892. awchProcessName[0] = 0;
  7893. }
  7894. GetFieldValue(pEProcess, SYM(_W32PROCESS), "W32Pid", W32Pid);
  7895. Print("Process 0x%p (ppi 0x%p) [%ws]\n", pEProcess, ppi, awchProcessName);
  7896. ptic.CallbackRoutine = ThreadKLCallback;
  7897. ptic.Data = Data;
  7898. ForEachPtiCallback(ppi, &ptic);
  7899. return FALSE;
  7900. }
  7901. BOOL Idkl(
  7902. DWORD opts,
  7903. ULONG64 param1)
  7904. {
  7905. try {
  7906. PTR gpkl = NULL_PTR;
  7907. PTR pkl, pklAnchor;
  7908. PTR pkfActive;
  7909. UINT i, nTables;
  7910. UINT iBaseCharset;
  7911. DWORD dwFontSigs;
  7912. if (opts & OFLAG(k)) {
  7913. /*
  7914. * Dump all the thread and its KL information.
  7915. */
  7916. KLCALLBACKINFO info;
  7917. if (param1) {
  7918. return FALSE;
  7919. }
  7920. RtlZeroMemory(&info, sizeof info);
  7921. info.opts = opts & ~OFLAG(k);
  7922. ForEachPpi(KLProcessCallback, &info);
  7923. // Print the summary.
  7924. Print("\nSummary:\n");
  7925. for (i = 0; i < ARRAY_SIZE(info.kl) && info.kl[i].hkl; ++i) {
  7926. Print("%08x 0n%d\n", (DWORD)info.kl[i].hkl, info.kl[i].n);
  7927. }
  7928. return TRUE;
  7929. }
  7930. if (param1 == 0) {
  7931. BYTE bCharSet;
  7932. gpkl = GetGlobalPointer(VAR(gpkl));
  7933. if (opts & OFLAG(a)) {
  7934. Print("Using gspklBaseLayout\n");
  7935. pkl = GetGlobalPointer(VAR(gspklBaseLayout));
  7936. } else {
  7937. Print("Using gpkl\n");
  7938. pkl = gpkl;
  7939. }
  7940. moveExpValue(&bCharSet, VAR(gSystemCPCharSet));
  7941. Print("gpKL:%p gSystemCPCharSet:%s\n", gpkl, GetCharSetText(bCharSet));
  7942. } else {
  7943. pkl = FIXKP(param1);
  7944. }
  7945. if (pkl == NULL_PTR) {
  7946. return FALSE;
  7947. }
  7948. _InitTypeRead(pkl, SYM(tagKL));
  7949. Print("KL @ 0x%p (cLockObj = %d) %c\n", pkl, (DWORD)ReadField(head.cLockObj),
  7950. pkl == gpkl ? '*' : ' ');
  7951. Print(" hkl 0x%08p\n", ReadField(hkl));
  7952. Print(" KLID %08x\n", ReadField(dwKLID));
  7953. if (opts & OFLAG(v)) {
  7954. Print(" pklNext 0x%p\n", ReadField(pklNext));
  7955. Print(" pklPrev 0x%p\n", ReadField(pklPrev));
  7956. Print(" dwKL_Flags 0x%08p\n", ReadField(dwKL_Flags));
  7957. Print(" piiex 0x%p\n", ReadField(piiex));
  7958. GetFieldValue(pkl, SYM(tagKL), "dwFontSigs", dwFontSigs);
  7959. Print(" dwFontSigs %s\n", GetFlags(GF_CHARSETS, dwFontSigs, NULL, TRUE));
  7960. GetFieldValue(pkl, SYM(tagKL), "iBaseCharset", iBaseCharset);
  7961. Print(" iBaseCharset %s\n", GetCharSetText((BYTE)iBaseCharset));
  7962. }
  7963. _InitTypeRead(pkl, SYM(tagKL));
  7964. Print(" Codepage %d\n", (WORD)ReadField(CodePage));
  7965. pkfActive = ReadField(spkf);
  7966. DumpKF(opts, 0, ReadField(spkfPrimary), ReadField(spkfPrimary) == pkfActive);
  7967. _InitTypeRead(pkl, SYM(tagKL));
  7968. /*
  7969. * Dump extra tables
  7970. */
  7971. nTables = (UINT)ReadField(uNumTbl);
  7972. Print(" Extra Tables: %x\n", nTables);
  7973. if (nTables > 0) {
  7974. PTR ppkfExtra = ReadField(pspkfExtra);
  7975. for (i = 0; i < nTables && !IsCtrlCHit(); ++i) {
  7976. PTR pkf;
  7977. ReadPointer(ppkfExtra + GetTypeSize("PVOID") * i, &pkf);
  7978. DumpKF(opts, i + 1, pkf, pkf == pkfActive);
  7979. }
  7980. }
  7981. if (opts & OFLAG(a)) {
  7982. PTR pklNext;
  7983. opts &= ~OFLAG(a);
  7984. pklAnchor = pkl;
  7985. GetFieldValue(pkl, SYM(tagKL), "pklNext", pklNext);
  7986. SAFEWHILE (pklNext && pklNext != pklAnchor) {
  7987. pkl = pklNext;
  7988. if (!Idkl(opts, pkl)) {
  7989. return FALSE;
  7990. }
  7991. if (GetFieldValue(pkl, SYM(tagKL), "pklNext", pklNext)) {
  7992. break;
  7993. }
  7994. }
  7995. }
  7996. } except (CONTINUE) {
  7997. }
  7998. return TRUE;
  7999. }
  8000. /***************************************************************************\
  8001. * ddk - dump deadkey table
  8002. *
  8003. * ddk address - dumps deadkey table address
  8004. *
  8005. * 09/28/95 GregoryW Created.
  8006. \***************************************************************************/
  8007. BOOL Iddk(
  8008. DWORD opts,
  8009. ULONG64 param1)
  8010. {
  8011. try {
  8012. PTR pKbdTbl; // KBDTABLES
  8013. PTR pDeadKey; // DEADKEY
  8014. ULONG cbDeadKey;
  8015. if (param1 == NULL_PTR) {
  8016. Print("Expected address\n");
  8017. return FALSE;
  8018. }
  8019. cbDeadKey = GetTypeSize(SYM(DEADKEY));
  8020. if (cbDeadKey == 0) {
  8021. Print("cannot get sizeof(DEADKEY), invalid symbol?\n");
  8022. return TRUE;
  8023. }
  8024. pKbdTbl = param1;
  8025. GetFieldValue(pKbdTbl, SYM(KBDTABLES), "pDeadKey", pDeadKey);
  8026. if (pDeadKey == NULL_PTR) {
  8027. Print("No deadkey table for this layout\n");
  8028. return TRUE;
  8029. }
  8030. SAFEWHILE (TRUE) {
  8031. DWORD dwBoth;
  8032. WCHAR wchComposed;
  8033. USHORT uFlags;
  8034. _InitTypeRead(pDeadKey, SYM(DEADKEY));
  8035. dwBoth = DOWNCAST(DWORD, ReadField(dwBoth));
  8036. if (dwBoth == 0) {
  8037. break;
  8038. }
  8039. wchComposed = DOWNCAST(WCHAR, ReadField(wchComposed));
  8040. uFlags = DOWNCAST(USHORT, ReadField(uFlags));
  8041. Print("%*c d 0x%04x ch 0x%04x => 0x%04x, f=%x\n", (opts & OFLAG(i)) ? 8 : 0, ' ', HIWORD(dwBoth), LOWORD(dwBoth), wchComposed, uFlags);
  8042. pDeadKey += cbDeadKey;
  8043. }
  8044. } except (CONTINUE) {
  8045. }
  8046. return TRUE;
  8047. }
  8048. #endif
  8049. #ifdef KERNEL
  8050. ULONG dtiFromPpiCallback(
  8051. ULONG64 ppi,
  8052. PVOID Data)
  8053. {
  8054. ULONG64 pti;
  8055. UNREFERENCED_PARAMETER(Data);
  8056. GetFieldValue(ppi, SYM(PROCESSINFO), "ptiList", pti);
  8057. SAFEWHILE (pti != 0) {
  8058. Print("pti ==> 0x%p [ppi = 0x%p]\n", pti, ppi);
  8059. Idti(0, pti);
  8060. GetFieldValue(pti, SYM(THREADINFO), "ptiSibling", pti);
  8061. }
  8062. return FALSE;
  8063. }
  8064. /***************************************************************************\
  8065. * dti - dump THREADINFO
  8066. *
  8067. * dti address - dumps THREADINFO structure at address
  8068. *
  8069. * 11-13-91 DavidPe Created.
  8070. * 6/9/1995 SanfordS made to fit stdexts motif
  8071. \***************************************************************************/
  8072. BOOL Idti(
  8073. DWORD opts,
  8074. ULONG64 param1)
  8075. {
  8076. PTR pti, pwinsta;
  8077. CLIENTTHREADINFO cti;
  8078. PTR pThread;
  8079. PTR pEProcess;
  8080. UCHAR PriorityClass;
  8081. WCHAR szDesktop[256], szWindowStation[256];
  8082. UNREFERENCED_PARAMETER(opts);
  8083. if (param1 == 0) {
  8084. PTR pq;
  8085. if (opts & OFLAG(c)) {
  8086. // !dti -c: Use the current thread.
  8087. pti = GetGlobalPointer(VAR(gptiCurrent));
  8088. } else if (opts & OFLAG(f)) {
  8089. pq = GetGlobalPointer(VAR(gpqForeground));
  8090. if (pq == 0) {
  8091. Print("No foreground queue!\n");
  8092. return FALSE;
  8093. }
  8094. GetFieldValue(pq, SYM(Q), "ptiKeyboard", pti);
  8095. } else {
  8096. Print("**** NT ACTIVE WIN32 THREADINFO DUMP ****\n");
  8097. ForEachPpi(dtiFromPpiCallback, NULL);
  8098. return TRUE;
  8099. }
  8100. } else {
  8101. pti = FIXKP(param1);
  8102. }
  8103. if (pti == 0) {
  8104. return FALSE;
  8105. }
  8106. Idt(OFLAG(p), pti);
  8107. _InitTypeRead(pti, SYM(tagTHREADINFO));
  8108. move(cti, ReadField(pcti));
  8109. Print("PTHREADINFO @ 0x%p\n", pti);
  8110. Print("\tPtiLink.Flink 0x%p\n"
  8111. "\tptl 0x%p\n"
  8112. "\tptlW32 0x%p\n"
  8113. "\tppi 0x%p\n"
  8114. "\tpq 0x%p\n"
  8115. "\tspklActive 0x%p\n"
  8116. "\tmlPost.pqmsgRead 0x%p\n"
  8117. "\tmlPost.pqmsgWriteLast 0x%p\n"
  8118. "\tmlPost.cMsgs 0x%08lx\n",
  8119. ReadField(PtiLink.Flink),
  8120. ReadField(ptl),
  8121. ReadField(ptlW32),
  8122. ReadField(ppi),
  8123. ReadField(pq),
  8124. ReadField(spklActive),
  8125. ReadField(mlPost.pqmsgRead),
  8126. ReadField(mlPost.pqmsgWriteLast),
  8127. (ULONG)ReadField(mlPost.cMsgs));
  8128. Print("\tspwndDefaultIme 0x%p\n"
  8129. "\tspDefaultImc 0x%p\n"
  8130. "\thklPrev 0x%08lx\n",
  8131. ReadField(spwndDefaultIme),
  8132. ReadField(spDefaultImc),
  8133. ReadField(hklPrev));
  8134. Print("\trpdesk 0x%p",
  8135. ReadField(rpdesk));
  8136. // If the pti has a desktop, display it and windowstation.
  8137. if (ReadField(rpdesk)) {
  8138. GetObjectName(ReadField(rpdesk), szDesktop, ARRAY_SIZE(szDesktop));
  8139. GetFieldValue(ReadField(rpdesk), SYM(DESKTOP), "rpwinstaParent", pwinsta);
  8140. GetObjectName(pwinsta, szWindowStation, ARRAY_SIZE(szWindowStation));
  8141. Print(" (%ws\\%ws)", szWindowStation, szDesktop);
  8142. }
  8143. Print("\n");
  8144. Print("\thdesk 0x%08lx\n",
  8145. ReadField(hdesk));
  8146. Print("\tamdesk 0x%08lx\n",
  8147. (ULONG)ReadField(amdesk));
  8148. Print("\tpDeskInfo 0x%p\n"
  8149. "\tpClientInfo 0x%p\n",
  8150. ReadField(pDeskInfo),
  8151. ReadField(pClientInfo));
  8152. Print("\tTIF_flags %s\n",
  8153. GetFlags(GF_TIF, (DWORD)ReadField(TIF_flags), NULL, TRUE));
  8154. Print("\tsphkCurrent 0x%p\n"
  8155. "\tpEventQueueServer 0x%p\n"
  8156. "\thEventQueueClient 0x%p\n",
  8157. ReadField(sphkCurrent),
  8158. ReadField(pEventQueueServer),
  8159. ReadField(hEventQueueClient));
  8160. Print("\tfsChangeBits %s\n",
  8161. GetFlags(GF_QS, (WORD)cti.fsChangeBits, NULL, TRUE));
  8162. Print("\tfsChangeBitsRemoved %s\n",
  8163. GetFlags(GF_QS, (WORD)ReadField(fsChangeBitsRemoved), NULL, TRUE));
  8164. Print("\tfsWakeBits %s\n",
  8165. GetFlags(GF_QS, (WORD)cti.fsWakeBits, NULL, TRUE));
  8166. Print("\tfsWakeMask %s\n",
  8167. GetFlags(GF_QS, (WORD)cti.fsWakeMask, NULL, TRUE));
  8168. Print("\tcPaintsReady 0x%04x\n"
  8169. "\tcTimersReady 0x%04x\n"
  8170. "\ttimeLast 0x%08lx\n"
  8171. "\tptLast.x 0x%08lx\n"
  8172. "\tptLast.y 0x%08lx\n"
  8173. "\tidLast 0x%p\n",
  8174. (ULONG)ReadField(cPaintsReady),
  8175. (ULONG)ReadField(cTimersReady),
  8176. (ULONG)ReadField(timeLast),
  8177. (ULONG)ReadField(ptLast.x),
  8178. (ULONG)ReadField(ptLast.y),
  8179. ReadField(idLast));
  8180. Print("\texitCode 0x%08lx\n"
  8181. "\tpSBTrack 0x%p\n"
  8182. "\tpsmsSent 0x%p\n"
  8183. "\tpsmsCurrent 0x%p\n",
  8184. (ULONG)ReadField(exitCode),
  8185. ReadField(pSBTrack),
  8186. ReadField(psmsSent),
  8187. ReadField(psmsCurrent));
  8188. Print("\tfsHooks 0x%08lx\n"
  8189. "\taphkStart 0x%p l%x\n"
  8190. "\tsphkCurrent 0x%p\n",
  8191. (ULONG)ReadField(fsHooks),
  8192. ReadField(aphkStart), CWINHOOKS,
  8193. ReadField(sphkCurrent));
  8194. Print("\tpsmsReceiveList 0x%p\n",
  8195. ReadField(psmsReceiveList));
  8196. Print("\tptdb 0x%p\n"
  8197. "\tThread 0x%p\n",
  8198. ReadField(ptdb),
  8199. ReadField(pEThread));
  8200. pThread = ReadField(pEThread);
  8201. GetFieldValue(pThread, "nt!ETHREAD", "ThreadsProcess", pEProcess);
  8202. GetFieldValue(pEProcess, "nt!EPROCESS", "PriorityClass", PriorityClass);
  8203. Print("\t PriorityClass %d\n",
  8204. PriorityClass);
  8205. _InitTypeRead(pti, SYM(tagTHREADINFO));
  8206. Print("\tcWindows 0x%08lx\n"
  8207. "\tcVisWindows 0x%08lx\n"
  8208. "\tpqAttach 0x%p\n"
  8209. "\tiCursorLevel 0x%08lx\n",
  8210. (ULONG)ReadField(cWindows),
  8211. (ULONG)ReadField(cVisWindows),
  8212. ReadField(pqAttach),
  8213. (ULONG)ReadField(iCursorLevel));
  8214. Print("\tpMenuState 0x%p\n",
  8215. ReadField(pMenuState));
  8216. return TRUE;
  8217. }
  8218. #endif // KERNEL
  8219. #ifdef KERNEL
  8220. BOOL ScanThreadlocks(PTR pti, char chType, PTR pvSearch);
  8221. ULONG WDBGAPI DumpThreadLocksCallback(PTR pti, PVOID pOpt)
  8222. {
  8223. UNREFERENCED_PARAMETER(pOpt);
  8224. Idtl(OFLAG(t) | OFLAG(x), pti);
  8225. return 0;
  8226. }
  8227. ULONG WDBGAPI ScanThreadLocksCallback(PTR pti, PVOID pOpt)
  8228. {
  8229. ScanThreadlocks(pti, 'o', *(PTR*)pOpt);
  8230. ScanThreadlocks(pti, 'k', *(PTR*)pOpt);
  8231. return 0;
  8232. }
  8233. /***************************************************************************\
  8234. * dtl handle|pointer
  8235. *
  8236. * !dtl <addr> Dumps all THREAD locks for object at <addr>
  8237. * !dtl -t <pti> Dumps all THREAD locks made by thread <pti>
  8238. * !dtl Dumps all THREAD locks made by all threads
  8239. *
  8240. * 02/27/1992 ScottLu Created.
  8241. * 06/09/1995 SanfordS Made to fit stdexts motif.
  8242. \***************************************************************************/
  8243. BOOL Idtl(
  8244. DWORD opts,
  8245. ULONG64 param1)
  8246. {
  8247. PTR pti;
  8248. if (param1 == 0) {
  8249. Print("Dumping all thread locks:\n");
  8250. Print("pti pObj Caller\n");
  8251. ForEachPti(DumpThreadLocksCallback, NULL);
  8252. return TRUE;
  8253. }
  8254. if (opts & OFLAG(t)) {
  8255. pti = FIXKP(param1);
  8256. if (pti == 0) {
  8257. return FALSE;
  8258. }
  8259. /*
  8260. * Regular thread-locked objects.
  8261. */
  8262. if (!(opts & OFLAG(x))) { // x is not legal from user - internal only
  8263. Print("pti pObj Caller\n");
  8264. }
  8265. ScanThreadlocks(pti, 'o', 0);
  8266. ScanThreadlocks(pti, 'k', 0);
  8267. return TRUE;
  8268. }
  8269. if (!param1) {
  8270. return FALSE;
  8271. }
  8272. Print("Thread Locks for object %p:\n", param1);
  8273. Print("pti pObj Caller\n");
  8274. ForEachPti(ScanThreadLocksCallback, &param1);
  8275. Print("--- End Thread Lock List ---\n");
  8276. return TRUE;
  8277. }
  8278. /*
  8279. * Scans all threadlocked objects belonging to thread pti of type chType
  8280. * (o == regular objects, k == kernel objects, p == pool). Display each
  8281. * threadlock, or if pvSearch is non-NULL, just those locks on the object
  8282. * at pvSearch.
  8283. */
  8284. BOOL
  8285. ScanThreadlocks(
  8286. PTR pti,
  8287. char chType,
  8288. PTR pvSearch)
  8289. {
  8290. PTR ptl;
  8291. if (pti == 0) {
  8292. return FALSE;
  8293. }
  8294. if (_InitTypeRead(pti, SYM(THREADINFO))) {
  8295. Print("Idtl: Can't get pti data from %p.\n", (ULONG_PTR)pti);
  8296. return FALSE;
  8297. }
  8298. switch (chType) {
  8299. case 'o':
  8300. ptl = ReadField(ptl);
  8301. break;
  8302. case 'k':
  8303. ptl = ReadField(ptlW32);
  8304. break;
  8305. default:
  8306. Print("Internal error, bad chType '%c' in ScanThreadlocks\n", chType);
  8307. return FALSE;
  8308. }
  8309. SAFEWHILE (ptl) {
  8310. char ach[80];
  8311. ULONG64 dwOffset;
  8312. if (_InitTypeRead(ptl, SYM(TL))) {
  8313. Print("Idtl: Can't get ptl data from %p.\n", (ULONG_PTR)ptl);
  8314. return FALSE;
  8315. }
  8316. if (!pvSearch || ReadField(pobj) == pvSearch) {
  8317. Print("0x%p 0x%p", pti, ReadField(pobj));
  8318. GetSym(ReadField(pfnCaller), ach, &dwOffset);
  8319. Print(" %s", ach);
  8320. if (dwOffset) {
  8321. Print("+0x%x", (ULONG)dwOffset);
  8322. }
  8323. if (chType == 'k') {
  8324. GetSym(ReadField(pfnFree), ach, &dwOffset);
  8325. Print(" (%s)", ach);
  8326. if (dwOffset) {
  8327. Print("+0x%x", (ULONG)dwOffset);
  8328. }
  8329. }
  8330. Print("\n");
  8331. }
  8332. ptl = ReadField(next);
  8333. }
  8334. return TRUE;
  8335. }
  8336. #endif // KERNEL
  8337. #ifdef KERNEL
  8338. /************************************************************************\
  8339. * FindTimerByID
  8340. *
  8341. * Looks up a timer based upon its ID. Worker function for !dtmr.
  8342. *
  8343. * 04/10/2001 JasonSch Wrote it.
  8344. \************************************************************************/
  8345. ULONG64 FindTimerByID(
  8346. ULONG64 tmr)
  8347. {
  8348. ULONG64 ptmr;
  8349. ptmr = GetGlobalPointer(VAR(gptmrFirst));
  8350. SAFEWHILE (ptmr) {
  8351. _InitTypeRead(ptmr, SYM(TIMER));
  8352. if (ReadField(nID) == tmr) {
  8353. break;
  8354. }
  8355. ptmr = ReadField(ptmrNext);
  8356. }
  8357. return ptmr;
  8358. }
  8359. /************************************************************************\
  8360. * Idtmr
  8361. *
  8362. * Dumps timer structures.
  8363. *
  8364. * 06/09/1995 SanfordS Created.
  8365. * 10/18/2000 Mohamed Port to 64 bit.
  8366. * 04/10/2002 JasonSch Added -i option.
  8367. \************************************************************************/
  8368. BOOL Idtmr(
  8369. DWORD opts,
  8370. PTR ptmr)
  8371. {
  8372. PTR pti;
  8373. if (ptmr == 0) {
  8374. ULONG ulTimerCnt = 0;
  8375. ptmr = GetGlobalPointer(VAR(gptmrFirst));
  8376. SAFEWHILE (ptmr) {
  8377. ++ulTimerCnt;
  8378. Idtmr(0, ptmr);
  8379. Print("\n");
  8380. _InitTypeRead(ptmr, SYM(TIMER));
  8381. ptmr = ReadField(ptmrNext);
  8382. }
  8383. Print("0x%x total timers dumped.\n", ulTimerCnt);
  8384. return TRUE;
  8385. }
  8386. /*
  8387. * The -i option indicates that ptmr is an ID, not a pointer.
  8388. */
  8389. if (opts & OFLAG(i)) {
  8390. ULONG64 ptmrT = FindTimerByID(ptmr);
  8391. if (ptmrT == 0) {
  8392. Print("Couldn't find timer with id 0x%p\n", ptmr);
  8393. return TRUE;
  8394. }
  8395. ptmr = ptmrT;
  8396. }
  8397. _InitTypeRead(ptmr, SYM(TIMER));
  8398. Print("Timer %p:\n"
  8399. " ptmrNext = %p\n"
  8400. " pti = %p",
  8401. ptmr,
  8402. ReadField(ptmrNext),
  8403. ReadField(pti));
  8404. pti = ReadField(pti);
  8405. if (pti && _InitTypeRead(pti, SYM(THREADINFO))) {
  8406. WCHAR awch[64];
  8407. if (GetAppName(ReadField(pEThread), pti, awch, ARRAY_SIZE(awch))) {
  8408. ULONG handleProcess, handleThread;
  8409. PWCHAR pwch = wcsrchr(awch, L'\\');
  8410. if (pwch == NULL) {
  8411. pwch = awch;
  8412. } else {
  8413. pwch++;
  8414. }
  8415. GetFieldValue(ReadField(pEThread), "nt!ETHREAD", "Cid.UniqueThread", handleProcess);
  8416. GetFieldValue(ReadField(pEThread), "nt!ETHREAD", "Cid.UniqueThread", handleThread);
  8417. Print(" q %p i %2x.%-3lx %ws",
  8418. ReadField(pq),
  8419. handleProcess,
  8420. handleThread,
  8421. pwch);
  8422. }
  8423. }
  8424. _InitTypeRead(ptmr, SYM(TIMER));
  8425. Print("\n"
  8426. " spwnd = %p",
  8427. ReadField(spwnd));
  8428. if (ReadField(spwnd)) {
  8429. char ach[80];
  8430. DebugGetWindowTextA(ReadField(spwnd), ach, ARRAY_SIZE(ach));
  8431. Print(" \"%s\"", ach);
  8432. }
  8433. Print("\n"
  8434. " nID = %x\n"
  8435. " cmsCountdown = %x\n"
  8436. " cmsRate = %x\n"
  8437. " flags = %s\n"
  8438. " pfn = %p\n"
  8439. " ptiOptCreator = %p\n",
  8440. (ULONG) ReadField(nID),
  8441. (ULONG) ReadField(cmsCountdown),
  8442. (ULONG) ReadField(cmsRate),
  8443. GetFlags(GF_TMRF, (WORD)ReadField(flags), NULL, TRUE),
  8444. ReadField(pfn),
  8445. ReadField(ptiOptCreator));
  8446. return TRUE;
  8447. }
  8448. #endif // KERNEL
  8449. #ifdef OLD_DEBUGGER
  8450. /************************************************************************\
  8451. * Idu
  8452. *
  8453. * Dump unknown object. Does what it can figure out.
  8454. *
  8455. * 6/9/1995 Created SanfordS
  8456. \************************************************************************/
  8457. BOOL Idu(
  8458. DWORD opts,
  8459. ULONG64 param1)
  8460. {
  8461. HANDLEENTRY he, *phe;
  8462. int i;
  8463. DWORD dw;
  8464. UNREFERENCED_PARAMETER(opts);
  8465. if (param1 == 0) {
  8466. FOREACHHANDLEENTRY(phe, he, i)
  8467. if (he.bType != TYPE_FREE && tryDword(&dw, FIXKP(he.phead))) {
  8468. Idu(OFLAG(x), he.phead);
  8469. }
  8470. NEXTEACHHANDLEENTRY()
  8471. return TRUE;
  8472. }
  8473. param1 = HorPtoP(FIXKP(param1), -1);
  8474. if (param1 == 0) {
  8475. return FALSE;
  8476. }
  8477. if (!getHEfromP(NULL, &he, param1)) {
  8478. return FALSE;
  8479. }
  8480. Print("--- %s object @ 0x%p ---\n", pszObjStr[he.bType], FIXKP(param1));
  8481. switch (he.bType) {
  8482. case TYPE_WINDOW:
  8483. return Idw(0, param1);
  8484. case TYPE_MENU:
  8485. return Idm(0, param1);
  8486. #ifdef KERNEL
  8487. case TYPE_CURSOR:
  8488. return Idcur(0, param1);
  8489. case TYPE_HOOK:
  8490. return Idhk(OFLAG(a) | OFLAG(g), NULL);
  8491. case TYPE_DDECONV:
  8492. case TYPE_DDEXACT:
  8493. return Idde(0, param1);
  8494. #endif // KERNEL
  8495. case TYPE_MONITOR:
  8496. // LATER: - add dmon command
  8497. case TYPE_CALLPROC:
  8498. case TYPE_ACCELTABLE:
  8499. case TYPE_SETWINDOWPOS:
  8500. case TYPE_DDEACCESS:
  8501. default:
  8502. Print("not supported.\n", pszObjStr[he.bType]);
  8503. }
  8504. return TRUE;
  8505. }
  8506. #ifdef KERNEL
  8507. /***************************************************************************\
  8508. * dumphmgr - dumps object allocation counts for handle-table.
  8509. *
  8510. * 10-18-94 ChrisWil Created.
  8511. * 6/9/1995 SanfordS made to fit stdexts motif
  8512. * 06-18-97 MCostea made it work
  8513. \***************************************************************************/
  8514. BOOL Idumphmgr(
  8515. DWORD opts)
  8516. {
  8517. PERFHANDLEINFO aLocalHti[TYPE_CTYPES], aLocalPrevHti[TYPE_CTYPES];
  8518. PPERFHANDLEINFO pgahti;
  8519. LONG lTotalAlloc, lTotalMax, lTotalCurrent;
  8520. LONG lPrevTotalAlloc, lPrevTotalMax, lPrevTotalCurrent;
  8521. SIZE_T lTotalSize, lPrevTotalSize;
  8522. int idx;
  8523. pgahti = EvalExp(VAR(gaPerfhti));
  8524. if (!pgahti) {
  8525. Print("\n!dumphmgr works only with debug versions of win32k.sys\n\n");
  8526. return TRUE;
  8527. }
  8528. move(aLocalHti, pgahti);
  8529. pgahti = EvalExp(VAR(gaPrevhti));
  8530. if (!pgahti) {
  8531. return TRUE;
  8532. }
  8533. move(aLocalPrevHti, pgahti);
  8534. lTotalSize = lTotalAlloc = lTotalMax = lTotalCurrent = 0;
  8535. lPrevTotalSize = lPrevTotalAlloc = lPrevTotalMax = lPrevTotalCurrent = 0;
  8536. if (aLocalPrevHti[TYPE_WINDOW].lTotalCount) {
  8537. Print("\nThe snapshot values come under the current ones\n");
  8538. Print("Type Allocated Maximum Count Size\n");
  8539. Print("______________________________________________________________________________");
  8540. for (idx = 1; idx < TYPE_CTYPES; idx++) {
  8541. Print("\n%-15s %8d %-+6d %7d %-+5d %6d %-+5d %9d %-+d",
  8542. aszTypeNames[idx],
  8543. aLocalHti[idx].lTotalCount, aLocalHti[idx].lTotalCount - aLocalPrevHti[idx].lTotalCount,
  8544. aLocalHti[idx].lMaxCount, aLocalHti[idx].lMaxCount - aLocalPrevHti[idx].lMaxCount,
  8545. aLocalHti[idx].lCount, aLocalHti[idx].lCount - aLocalPrevHti[idx].lCount,
  8546. aLocalHti[idx].lSize, aLocalHti[idx].lSize - aLocalPrevHti[idx].lSize);
  8547. if (aLocalPrevHti[TYPE_WINDOW].lTotalCount) {
  8548. Print("\n %8d %7d %6d %9d",
  8549. aLocalPrevHti[idx].lTotalCount,
  8550. aLocalPrevHti[idx].lMaxCount,
  8551. aLocalPrevHti[idx].lCount,
  8552. aLocalPrevHti[idx].lSize);
  8553. lPrevTotalAlloc += aLocalPrevHti[idx].lTotalCount;
  8554. lPrevTotalMax += aLocalPrevHti[idx].lMaxCount;
  8555. lPrevTotalCurrent += aLocalPrevHti[idx].lCount;
  8556. lPrevTotalSize += aLocalPrevHti[idx].lSize;
  8557. }
  8558. lTotalAlloc += aLocalHti[idx].lTotalCount;
  8559. lTotalMax += aLocalHti[idx].lMaxCount;
  8560. lTotalCurrent += aLocalHti[idx].lCount;
  8561. lTotalSize += aLocalHti[idx].lSize;
  8562. }
  8563. Print("\n______________________________________________________________________________\n");
  8564. Print("Totals %8d %-+6d %7d %-+5d %6d %+-5d %9d %-+d\n",
  8565. lTotalAlloc, lTotalAlloc - lPrevTotalAlloc,
  8566. lTotalMax, lTotalMax - lPrevTotalMax,
  8567. lTotalCurrent, lTotalCurrent - lPrevTotalCurrent,
  8568. lTotalSize, lTotalSize - lPrevTotalSize);
  8569. Print(" %8d %7d %6d %9d\n",
  8570. lPrevTotalAlloc, lPrevTotalMax, lPrevTotalCurrent, lPrevTotalSize);
  8571. } else {
  8572. Print("Type Allocated Maximum Count Size\n");
  8573. Print("______________________________________________________");
  8574. for (idx = 1; idx < TYPE_CTYPES; idx++) {
  8575. Print("\n%-17s %9d %7d %6d %d",
  8576. aszTypeNames[idx],
  8577. aLocalHti[idx].lTotalCount,
  8578. aLocalHti[idx].lMaxCount,
  8579. aLocalHti[idx].lCount,
  8580. aLocalHti[idx].lSize);
  8581. lTotalAlloc += aLocalHti[idx].lTotalCount;
  8582. lTotalMax += aLocalHti[idx].lMaxCount;
  8583. lTotalCurrent += aLocalHti[idx].lCount;
  8584. lTotalSize += aLocalHti[idx].lSize;
  8585. }
  8586. Print("\n______________________________________________________\n");
  8587. Print("Current totals %9d %7d %6d %d\n",
  8588. lTotalAlloc, lTotalMax, lTotalCurrent, lTotalSize);
  8589. }
  8590. /*
  8591. * If the argument-list contains the Snap option,
  8592. * then copy the current counts to the previous ones
  8593. */
  8594. if (opts & OFLAG(s)) {
  8595. (lpExtensionApis->lpWriteProcessMemoryRoutine)(
  8596. (ULONG_PTR)&(pgahti[0]),
  8597. (PVOID)aLocalHti,
  8598. sizeof(aLocalHti),
  8599. NULL);
  8600. }
  8601. return TRUE;
  8602. }
  8603. #endif // KERNEL
  8604. #endif // OLD_DEBUGGER
  8605. /************************************************************************\
  8606. * dwrWorker
  8607. *
  8608. * Dumps pwnd structures compactly to show relationships.
  8609. *
  8610. * 6/9/1995 Created SanfordS
  8611. \************************************************************************/
  8612. BOOL dwrWorker(
  8613. PTR pwnd,
  8614. int tab)
  8615. {
  8616. PTR pcls;
  8617. PTR lpszAnsiClassName;
  8618. PTR pwndChild;
  8619. PTR pwndOwner;
  8620. ULONG atomClassName;
  8621. ULONG atomNVClassName;
  8622. if (pwnd == 0) {
  8623. return FALSE;
  8624. }
  8625. do {
  8626. pwnd = FIXKP(pwnd);
  8627. DebugGetWindowTextA(pwnd, gach1, ARRAY_SIZE(gach1));
  8628. GetFieldValue(pwnd, SYM(WND), "pcls", pcls);
  8629. GetFieldValue(pcls, SYM(CLS), "atomClassName", atomClassName);
  8630. GetFieldValue(pcls, SYM(CLS), "atomNVClassName", atomNVClassName);
  8631. GetFieldValue(pcls, SYM(CLS), "lpszAnsiClassName", lpszAnsiClassName);
  8632. if (atomNVClassName < 0xC000) {
  8633. switch (atomNVClassName) {
  8634. case WC_DIALOG:
  8635. strcpy(gach1, "WC_DIALOG");
  8636. break;
  8637. case DESKTOPCLASS:
  8638. strcpy(gach1, "DESKTOP");
  8639. break;
  8640. case SWITCHWNDCLASS:
  8641. strcpy(gach1, "SWITCHWND");
  8642. break;
  8643. case ICONTITLECLASS:
  8644. strcpy(gach1, "ICONTITLE");
  8645. break;
  8646. default:
  8647. if (atomNVClassName == 0) {
  8648. move(gach1, FIXKP(lpszAnsiClassName));
  8649. } else {
  8650. sprintf(gach2, "0x%04x", atomNVClassName);
  8651. }
  8652. }
  8653. } else {
  8654. DebugGetClassNameA(lpszAnsiClassName, gach2);
  8655. }
  8656. if (atomClassName && (atomClassName < 0xC000)) {
  8657. sprintf(gach3, "0x%04x", atomClassName);
  8658. }
  8659. Print("%08p%*s [%s|%s|%s]", pwnd, tab, "", gach1, gach2, gach3);
  8660. GetFieldValue(pwnd, SYM(WND), "spwndOwner", pwndOwner);
  8661. if (pwndOwner != 0) {
  8662. Print(" <- Owned by:%08x", FIXKP(pwndOwner));
  8663. }
  8664. Print("\n");
  8665. GetFieldValue(pwnd, SYM(WND), "spwndChild", pwndChild);
  8666. if (pwndChild != 0) {
  8667. dwrWorker(pwndChild, tab + 2);
  8668. }
  8669. GetFieldValue(pwnd, SYM(WND), "spwndNext", pwnd);
  8670. } SAFEWHILE (pwnd && tab > 0);
  8671. return TRUE;
  8672. }
  8673. /************************************************************************\
  8674. * Idw
  8675. *
  8676. * Dumps pwnd structures
  8677. *
  8678. * 6/9/1995 Created SanfordS
  8679. \************************************************************************/
  8680. BOOL Idw(
  8681. DWORD opts,
  8682. ULONG64 param1)
  8683. {
  8684. WW ww;
  8685. PTR lpfnWndProc;
  8686. RECT rcWindow;
  8687. RECT rcClient;
  8688. PTR pcls;
  8689. PTR pwnd = param1;
  8690. char ach[256];
  8691. ULONG64 dwOffset;
  8692. ULONG ix;
  8693. DWORD tempDWord;
  8694. DWORD dwWOW;
  8695. try {
  8696. if (opts & OFLAG(a)) {
  8697. #ifdef KERNEL
  8698. PTR pdesk;
  8699. PTR pDeskInfo;
  8700. PTR pwnd;
  8701. WCHAR wach[80];
  8702. if (param1 != 0) {
  8703. Print("window parameter ignored with -a option.\n");
  8704. }
  8705. FOREACHDESKTOP(pdesk)
  8706. if (!GetFieldValue(pdesk, SYM(DESKTOP), "pDeskInfo", pDeskInfo)) {
  8707. GetObjectName(pdesk, wach, ARRAY_SIZE(wach));
  8708. Print("\n----Windows for %ws desktop @ 0x%p:\n\n", wach, pdesk);
  8709. GetFieldValue(pDeskInfo, SYM(DESKTOPINFO), "spwnd", pwnd);
  8710. if (!Idw((opts & ~OFLAG(a)) | OFLAG(p), pwnd)) {
  8711. return FALSE;
  8712. }
  8713. }
  8714. NEXTEACHDESKTOP(pdesk)
  8715. #else // !KERNEL
  8716. PTR pteb = 0;
  8717. GetTebAddress(&pteb);
  8718. if (pteb) {
  8719. ULONG pciOffset;
  8720. PTR pdi;
  8721. GetFieldOffset(SYM(TEB), "Win32ClientInfo", &pciOffset);
  8722. GetFieldValue(pteb + pciOffset, SYM(CLIENTINFO), "pDeskInfo", pdi);
  8723. GetFieldValue(pdi, SYM(DESKTOPINFO), "spwnd", pwnd);
  8724. return Idw(opts & ~OFLAG(a) | OFLAG(p), FIXKP(pwnd));
  8725. }
  8726. #endif // !KERNEL
  8727. return TRUE;
  8728. }
  8729. /*
  8730. * t is like EnumThreadWindows.
  8731. */
  8732. if (opts & OFLAG(t)) {
  8733. #ifdef KERNEL
  8734. PTR pti, ptiWnd;
  8735. PTR pdesk;
  8736. PTR pdi;
  8737. /*
  8738. * Get the desktop's first child window
  8739. */
  8740. pti = param1;
  8741. if (GetFieldValue(pti, SYM(THREADINFO), "rpdesk", pdesk)
  8742. || GetFieldValue(pdesk, SYM(DESKTOP), "pDeskInfo", pdi)
  8743. || GetFieldValue(pdi, SYM(DESKTOPINFO), "spwnd", pwnd)
  8744. || GetFieldValue(pwnd, SYM(WND), "spwndChild", pwnd)) {
  8745. return FALSE;
  8746. }
  8747. /*
  8748. * Walk the sibling chain looking for pwnd owned by pti.
  8749. */
  8750. SAFEWHILE (pwnd) {
  8751. if (!GetFieldValue(pwnd, SYM(WND), "head.pti", ptiWnd) && (ptiWnd == pti)) {
  8752. if (!Idw(opts & ~OFLAG(t), pwnd)) {
  8753. return FALSE;
  8754. }
  8755. }
  8756. if (GetFieldValue(pwnd, SYM(WND), "spwndNext", pwnd)) {
  8757. return FALSE;
  8758. }
  8759. }
  8760. return TRUE;
  8761. #else // !KERNEL
  8762. Print("t parameter not supported for NTSD at this point\n");
  8763. #endif // !KERNEL
  8764. }
  8765. /*
  8766. * See if the user wants all top level windows.
  8767. */
  8768. if (param1 == 0 || opts & (OFLAG(p) | OFLAG(s))) {
  8769. /*
  8770. * Make sure there was also a window argument if p or s.
  8771. */
  8772. if (param1 == 0 && (opts & (OFLAG(p) | OFLAG(s)))) {
  8773. Print("Must specify window with '-p' or '-s' options.\n");
  8774. return FALSE;
  8775. }
  8776. if (param1 && (pwnd = HorPtoP(pwnd, TYPE_WINDOW)) == 0) {
  8777. return FALSE;
  8778. }
  8779. if (opts & OFLAG(p)) {
  8780. Print("pwndParent = 0x%p\n", pwnd);
  8781. if (GetFieldValue(FIXKP(pwnd), SYM(WND), "spwndChild", pwnd)) {
  8782. Print("<< Can't get WND >>\n");
  8783. return TRUE; // we don't need to have the flags explained!
  8784. }
  8785. SAFEWHILE (pwnd) {
  8786. if (!Idw(opts & ~OFLAG(p), pwnd)) {
  8787. return FALSE;
  8788. }
  8789. GetFieldValue(FIXKP(pwnd), SYM(WND), "spwndNext", pwnd);
  8790. }
  8791. return TRUE;
  8792. } else if (opts & OFLAG(s)) {
  8793. GetFieldValue(FIXKP(pwnd), SYM(WND), "spwndParent", pwnd);
  8794. return Idw((opts | OFLAG(p)) & ~OFLAG(s), pwnd);
  8795. } else {
  8796. #ifdef KERNEL
  8797. PTR pdesk = NULL_PTR;
  8798. PTR pDeskInfo, pwnd;
  8799. PTR pti, pq;
  8800. pq = GetGlobalPointer(VAR(gpqForeground));
  8801. GetFieldValue(pq, SYM(Q), "ptiKeyboard", pti);
  8802. GetFieldValue(pti, SYM(THREADINFO), "rpdesk", pdesk);
  8803. if (pdesk == 0) {
  8804. Print("Foreground thread doesn't have a desktop.\n");
  8805. Print("Using grpdeskRitInput ...\n");
  8806. pdesk = GetGlobalPointer(SYM(grpdeskRitInput));
  8807. if (pdesk == 0) {
  8808. Print("grpdeskRitInput is NULL!\n");
  8809. return FALSE;
  8810. }
  8811. GetFieldValue(pdesk, SYM(DESKTOP), "pDeskInfo", pDeskInfo);
  8812. GetFieldValue(pDeskInfo, SYM(DESKTOPINFO), "spwnd", pwnd);
  8813. } else {
  8814. GetFieldValue(pti, SYM(THREADINFO), "pDeskInfo", pDeskInfo);
  8815. GetFieldValue(pDeskInfo, SYM(DESKTOPINFO), "spwnd", pwnd);
  8816. }
  8817. Print("pwndDesktop = 0x%p\n", (ULONG_PTR)pwnd);
  8818. return Idw(opts | OFLAG(p), pwnd);
  8819. #else // !KERNEL
  8820. return Idw(opts | OFLAG(a), 0);
  8821. #endif // !KERNEL
  8822. }
  8823. }
  8824. if (param1 && (pwnd = HorPtoP(param1, TYPE_WINDOW)) == 0) {
  8825. Print("Idw: 0x%p is not a pwnd.\n", param1);
  8826. return FALSE;
  8827. }
  8828. if (opts & OFLAG(r)) {
  8829. dwrWorker(FIXKP(pwnd), 0);
  8830. return TRUE;
  8831. }
  8832. _InitTypeRead(pwnd, SYM(tagWND));
  8833. lpfnWndProc = ReadField(lpfnWndProc);
  8834. ww.state = (DWORD)ReadField(state);
  8835. ww.state2 = (DWORD)ReadField(state2);
  8836. ww.ExStyle = (DWORD)ReadField(ExStyle);
  8837. ww.style = (DWORD)ReadField(style);
  8838. #ifdef KERNEL
  8839. /*
  8840. * Print simple thread info.
  8841. */
  8842. if (ReadField(head.pti)) {
  8843. Idt(OFLAG(p), ReadField(head.pti));
  8844. }
  8845. #endif // KERNEL
  8846. /*
  8847. * Print pwnd.
  8848. */
  8849. Print("pwnd = 0x%p", pwnd);
  8850. /*
  8851. * Show z-ordering/activation relevant info
  8852. */
  8853. if (opts & OFLAG(z)) {
  8854. PTR pwndOwner;
  8855. if (ReadField(ExStyle) & WS_EX_TOPMOST) {
  8856. Print(" TOPMOST");
  8857. }
  8858. if (!(ReadField(style) & WS_VISIBLE)) {
  8859. Print(" HIDDEN");
  8860. }
  8861. if (ReadField(style) & WS_DISABLED) {
  8862. Print(" DISABLED");
  8863. }
  8864. pwndOwner = ReadField(spwndOwner);
  8865. if (pwndOwner != 0) {
  8866. DebugGetWindowTextA(pwndOwner, ach, ARRAY_SIZE(ach));
  8867. Print(" OWNER:0x%p \"%s\"", pwndOwner, ach);
  8868. }
  8869. }
  8870. Print("\n");
  8871. if (!(opts & OFLAG(v))) {
  8872. /*
  8873. * Print title string.
  8874. */
  8875. DebugGetWindowTextA(pwnd, ach, ARRAY_SIZE(ach));
  8876. Print("title = \"%s\"\n", ach);
  8877. /*
  8878. * Print wndproc symbol string.
  8879. */
  8880. if (IsWOWProc (lpfnWndProc)) {
  8881. UnMarkWOWProc(lpfnWndProc,dwWOW);
  8882. Print("wndproc = %04lx:%04lx (WOW) (%s)",
  8883. HIWORD(dwWOW),LOWORD(dwWOW),
  8884. TestWWF(&ww, WFANSIPROC) ? "ANSI" : "Unicode");
  8885. } else {
  8886. GetSym(lpfnWndProc, ach, &dwOffset);
  8887. Print("wndproc = 0x%p = \"%s\" (%s)", lpfnWndProc, ach,
  8888. TestWWF(&ww, WFANSIPROC) ? "ANSI" : "Unicode");
  8889. }
  8890. /*
  8891. * Display the class name/atom.
  8892. */
  8893. GetFieldValue(pwnd, SYM(tagWND), "pcls", pcls);
  8894. pcls = FIXKP(pcls);
  8895. _InitTypeRead(pcls, SYM(tagCLS));
  8896. DebugGetClassNameA(ReadField(lpszAnsiClassName), ach);
  8897. Print(" Class(V): 0x%04p, (NV): 0x%04p Name:\"%s\"\n", ReadField(atomClassName), ReadField(atomNVClassName), ach);
  8898. } else {
  8899. /*
  8900. * Get the PWND structure. Ignore class-specific data for now.
  8901. */
  8902. _InitTypeRead(pwnd, SYM(tagWND));
  8903. Print("\thandle 0x%p\n", ReadField(head.h));
  8904. DebugGetWindowTextA(ReadField(spwndNext), ach, ARRAY_SIZE(ach));
  8905. Print("\tspwndNext 0x%p \"%s\"\n", ReadField(spwndNext), ach);
  8906. DebugGetWindowTextA(ReadField(spwndPrev), ach, ARRAY_SIZE(ach));
  8907. Print("\tspwndPrev 0x%p \"%s\"\n", ReadField(spwndPrev), ach);
  8908. DebugGetWindowTextA(ReadField(spwndParent), ach, ARRAY_SIZE(ach));
  8909. Print("\tspwndParent 0x%p \"%s\"\n", ReadField(spwndParent), ach);
  8910. DebugGetWindowTextA(ReadField(spwndChild), ach, ARRAY_SIZE(ach));
  8911. Print("\tspwndChild 0x%p \"%s\"\n", ReadField(spwndChild), ach);
  8912. DebugGetWindowTextA(ReadField(spwndOwner), ach, ARRAY_SIZE(ach));
  8913. Print("\tspwndOwner 0x%p \"%s\"\n", ReadField(spwndOwner), ach);
  8914. GetFieldValue(pwnd, SYM(tagWND), "rcWindow", rcWindow);
  8915. Print("\trcWindow (%d,%d)-(%d,%d) %dx%d\n",
  8916. rcWindow.left, rcWindow.top,
  8917. rcWindow.right, rcWindow.bottom,
  8918. rcWindow.right - rcWindow.left,
  8919. rcWindow.bottom - rcWindow.top);
  8920. GetFieldValue(pwnd, SYM(tagWND), "rcClient", rcClient);
  8921. Print("\trcClient (%d,%d)-(%d,%d) %dx%d\n",
  8922. rcClient.left, rcClient.top,
  8923. rcClient.right, rcClient.bottom,
  8924. rcClient.right - rcClient.left,
  8925. rcClient.bottom - rcClient.top);
  8926. if (IsWOWProc (lpfnWndProc)) {
  8927. UnMarkWOWProc(lpfnWndProc, dwWOW);
  8928. Print("\tlpfnWndProc %04lx:%04lx (WOW) (%s)\n",
  8929. HIWORD(dwWOW),LOWORD(dwWOW),
  8930. TestWWF(&ww, WFANSIPROC) ? "ANSI" : "Unicode");
  8931. } else {
  8932. GetSym(lpfnWndProc, ach, &dwOffset);
  8933. Print("\tlpfnWndProc 0x%p (%s) %s\n", lpfnWndProc, ach,
  8934. TestWWF(&ww, WFANSIPROC) ? "ANSI" : "Unicode");
  8935. }
  8936. pcls = ReadField(pcls);
  8937. pcls = FIXKP(pcls);
  8938. _InitTypeRead(pcls, SYM(tagCLS));
  8939. DebugGetClassNameA(ReadField(lpszAnsiClassName), ach);
  8940. Print("\tpcls 0x%p (V):0x%04p (NV):0x%04p Name:\"%s\"\n",
  8941. pcls, ReadField(atomClassName), ReadField(atomNVClassName), ach);
  8942. _InitTypeRead(pwnd, SYM(tagWND));
  8943. Print("\thrgnUpdate 0x%p\n",
  8944. ReadField(hrgnUpdate));
  8945. DebugGetWindowTextA(ReadField(spwndLastActive), ach, ARRAY_SIZE(ach));
  8946. Print("\tspwndLastActive 0x%p \"%s\"\n",
  8947. ReadField(spwndLastActive), ach);
  8948. Print("\tppropList 0x%p\n"
  8949. "\tpSBInfo 0x%p\n",
  8950. ReadField(ppropList),
  8951. ReadField(pSBInfo));
  8952. if (ReadField(pSBInfo)) {
  8953. SBINFO asb;
  8954. moveBlock(&asb, FIXKP(ReadField(pSBInfo)), sizeof(asb));
  8955. Print("\t SBO_FLAGS = %s\n"
  8956. "\t SBO_HMIN = %d\n"
  8957. "\t SBO_HMAX = %d\n"
  8958. "\t SBO_HPAGE = %d\n"
  8959. "\t SBO_HPOS = %d\n"
  8960. "\t SBO_VMIN = %d\n"
  8961. "\t SBO_VMAX = %d\n"
  8962. "\t SBO_VPAGE = %d\n"
  8963. "\t SBO_VPOS = %d\n",
  8964. GetFlags(GF_SB, (WORD)asb.WSBflags, NULL, TRUE),
  8965. asb.Horz.posMin,
  8966. asb.Horz.posMax,
  8967. asb.Horz.page,
  8968. asb.Horz.pos,
  8969. asb.Vert.posMin,
  8970. asb.Vert.posMax,
  8971. asb.Vert.page,
  8972. asb.Vert.pos);
  8973. }
  8974. Print("\tspmenuSys 0x%p\n"
  8975. "\tspmenu/id 0x%p\n",
  8976. ReadField(spmenuSys),
  8977. ReadField(spmenu));
  8978. Print("\thrgnClip 0x%p\n",
  8979. ReadField(hrgnClip));
  8980. /*
  8981. * Print title string.
  8982. */
  8983. DebugGetWindowTextA(pwnd, ach, ARRAY_SIZE(ach));
  8984. Print("\tpName \"%s\"\n",
  8985. ach);
  8986. Print("\tdwUserData 0x%p\n",
  8987. (ULONG_PTR)ReadField(dwUserData));
  8988. Print("\tstate 0x%08lx\n"
  8989. "\tstate2 0x%08lx\n"
  8990. "\tExStyle 0x%08lx\n"
  8991. "\tstyle 0x%08lx\n"
  8992. "\tfnid 0x%08lx\n"
  8993. "\thImc 0x%08p\n"
  8994. "\tbFullScreen 0y%d\n"
  8995. "\thModule 0x%08lx\n"
  8996. #ifdef LAME_BUTTON
  8997. "\tpStackTrace 0x%p\n"
  8998. #endif // LAME_BUTTON
  8999. "\tpActCtx 0x%p\n",
  9000. ww.state,
  9001. ww.state2,
  9002. ww.ExStyle,
  9003. ww.style,
  9004. (DWORD)(WORD)ReadField(fnid),
  9005. ReadField(hImc),
  9006. TestWWF(&ww, WFFULLSCREENMASK),
  9007. ReadField(hModule),
  9008. #ifdef LAME_BUTTON
  9009. ReadField(pStackTrace),
  9010. #endif // LAME_BUTTON
  9011. ReadField(pActCtx));
  9012. }
  9013. /*
  9014. * Print out all the flags
  9015. */
  9016. if (opts & OFLAG(f)) {
  9017. int i;
  9018. WORD wFlag;
  9019. ULONG cbHead;
  9020. PBYTE pbyte = (PBYTE)(&(ww.state));
  9021. cbHead = GetTypeSize(SYM(THRDESKHEAD));
  9022. for (i = 0; i < ARRAY_SIZE(aWindowFlags); i++) {
  9023. wFlag = aWindowFlags[i].wFlag;
  9024. if (pbyte[HIBYTE(wFlag)] & LOBYTE(wFlag)) {
  9025. Print("\t%-18s\t%p:%02lx\n",
  9026. aWindowFlags[i].pszText,
  9027. pwnd + cbHead + HIBYTE(wFlag),
  9028. LOBYTE(wFlag));
  9029. }
  9030. }
  9031. }
  9032. if (opts & OFLAG(w)) {
  9033. ULONG cbwnd = GetTypeSize(SYM(WND));
  9034. ULONG cbwndExtra = (ULONG)ReadField(cbwndExtra);
  9035. Print("\t%d window bytes: ", cbwndExtra);
  9036. if (cbwndExtra) {
  9037. for (ix=0; ix < cbwndExtra; ix += 4) {
  9038. PTR pdw;
  9039. pdw = pwnd + cbwnd + ix;
  9040. move(tempDWord, pdw);
  9041. Print("%08x ", tempDWord);
  9042. }
  9043. }
  9044. Print("\n");
  9045. }
  9046. /*
  9047. * Print window properties.
  9048. */
  9049. if (opts & OFLAG(o)) {
  9050. PTR psi;
  9051. PTR ppropList;
  9052. ULONG iFirstFree;
  9053. ULONG cEntries;
  9054. ULONG cbProp;
  9055. ULONG cbOffset;
  9056. PTR pprop;
  9057. UINT i, j;
  9058. struct {
  9059. LPSTR pstrName;
  9060. ATOM atom;
  9061. BOOLEAN bGlobal;
  9062. LPSTR pstrSymbol;
  9063. } apropatom[] =
  9064. {
  9065. "Icon", 0, FALSE, "atomIconProp",
  9066. "IconSM", 0, FALSE, "atomIconSmProp",
  9067. "ContextHelpID",0, FALSE, "atomContextHelpIdProp",
  9068. "Checkpoint", 0, TRUE, VAR(atomCheckpointProp),
  9069. "Flash State", 0, TRUE, VAR(gaFlashWState),
  9070. "DDETrack", 0, TRUE, VAR(atomDDETrack),
  9071. "QOS", 0, TRUE, VAR(atomQOS),
  9072. "DDEImp", 0, TRUE, VAR(atomDDEImp),
  9073. "WNDOBJ", 0, TRUE, VAR(atomWndObj),
  9074. "IMELevel", 0, TRUE, VAR(atomImeLevel),
  9075. };
  9076. /*
  9077. * Get the atom values for internal properties and put them in apropatom.atom
  9078. */
  9079. psi = GetGlobalPointer(VAR(gpsi));
  9080. for (i = 0; i < ARRAY_SIZE(apropatom); i++) {
  9081. if (!apropatom[i].bGlobal) {
  9082. /*
  9083. * The atom is stored in psi.
  9084. */
  9085. GetFieldValue(psi, SYM(SERVERINFO), apropatom[i].pstrSymbol, apropatom[0].atom);
  9086. } else {
  9087. /*
  9088. * The atom is a global.
  9089. */
  9090. moveExpValue(&apropatom[i].atom, apropatom[i].pstrSymbol);
  9091. }
  9092. }
  9093. /*
  9094. * Print the property list structure.
  9095. */
  9096. GetFieldValue(pwnd, SYM(WND), "ppropList", ppropList);
  9097. if (!ppropList) {
  9098. Print("\tNULL Property List\n");
  9099. } else {
  9100. _InitTypeRead(ppropList, SYM(tagPROPLIST));
  9101. iFirstFree = (ULONG)ReadField(iFirstFree);
  9102. cEntries = (ULONG)ReadField(cEntries);
  9103. Print("\tProperty List @ 0x%p : %d Properties, %d total entries, %d free entries\n",
  9104. ppropList,
  9105. iFirstFree,
  9106. cEntries,
  9107. cEntries - iFirstFree);
  9108. /*
  9109. * Print each property.
  9110. */
  9111. GetFieldOffset(SYM(PROPLIST), "aprop", &cbOffset);
  9112. pprop = ppropList + cbOffset;
  9113. cbProp = GetTypeSize(SYM(tagPROP));
  9114. for (i = 0; !IsCtrlCHit() && i < iFirstFree; i++, pprop += cbProp) {
  9115. LPSTR pstrInternal;
  9116. _InitTypeRead(pprop, SYM(tagPROP));
  9117. /*
  9118. * Find name for internal property.
  9119. */
  9120. pstrInternal = "";
  9121. if (ReadField(fs) & PROPF_INTERNAL) {
  9122. for (j = 0; j < ARRAY_SIZE(apropatom); j++) {
  9123. if (ReadField(atomKey) == apropatom[j].atom) {
  9124. pstrInternal = apropatom[j].pstrName;
  9125. break;
  9126. }
  9127. }
  9128. }
  9129. Print("\tProperty %d\n", i);
  9130. Print("\t\tatomKey 0x%04x %s\n", (ULONG)ReadField(atomKey), pstrInternal);
  9131. Print("\t\tfs 0x%04x %s\n", (ULONG)ReadField(fs), GetFlags(GF_PROP, (DWORD)ReadField(fs), NULL, FALSE));
  9132. Print("\t\thData 0x%p (%I64d)\n", ReadField(hData), ReadField(hData));
  9133. #ifdef KERNEL
  9134. if (ReadField(fs) & PROPF_INTERNAL) {
  9135. if (j == 3) {
  9136. CHECKPOINT cp;
  9137. PTR pcp = ReadField(hData);
  9138. move(cp, pcp);
  9139. Print("\t\tCheckPoint:\n");
  9140. Print("\t\trcNormal (%d,%d),(%d,%d) %dx%d\n",
  9141. cp.rcNormal.left,
  9142. cp.rcNormal.top,
  9143. cp.rcNormal.right,
  9144. cp.rcNormal.bottom,
  9145. cp.rcNormal.right - cp.rcNormal.left,
  9146. cp.rcNormal.bottom - cp.rcNormal.top);
  9147. Print("\t\tptMin (%d,%d)\n", cp.ptMin.x, cp.ptMin.y);
  9148. Print("\t\tptMax (%d,%d)\n", cp.ptMax.x, cp.ptMax.y);
  9149. Print("\t\tfDragged:%d\n", cp.fDragged);
  9150. Print("\t\tfWasMaximizedBeforeMinimized:%d\n", cp.fWasMaximizedBeforeMinimized);
  9151. Print("\t\tfWasMinimizedBeforeMaximized:%d\n", cp.fWasMinimizedBeforeMaximized);
  9152. Print("\t\tfMinInitialized:%d\n", cp.fMinInitialized);
  9153. Print("\t\tfMaxInitiailized:%d\n", cp.fMaxInitialized);
  9154. }
  9155. }
  9156. #endif // ifdef KERNEL
  9157. Print("\n");
  9158. }
  9159. }
  9160. }
  9161. Print("---\n");
  9162. } except (CONTINUE) {
  9163. }
  9164. return TRUE;
  9165. }
  9166. #ifdef KERNEL
  9167. /***************************************************************************\
  9168. * dws - dump windows stations
  9169. * dws h - dump windows stations plus handle list
  9170. *
  9171. * Dump WindowStation
  9172. *
  9173. * 8-11-94 SanfordS Created
  9174. * 6/9/1995 SanfordS made to fit stdexts motif
  9175. \***************************************************************************/
  9176. BOOL Idws(
  9177. DWORD opts,
  9178. ULONG64 param1)
  9179. {
  9180. PTR pwinsta;
  9181. WCHAR ach[80];
  9182. PTR pHead;
  9183. PTR pNameBuffer;
  9184. ULONG ObjectHeaderOffset;
  9185. UCHAR NameInfoOffset;
  9186. PTR NameBuffer;
  9187. ULONG NameLength;
  9188. ULONG cOpen;
  9189. DWORD sid; // session id
  9190. UNREFERENCED_PARAMETER(opts);
  9191. if (param1 == 0) {
  9192. FOREACHWINDOWSTATION(pwinsta)
  9193. Idws(0, pwinsta);
  9194. Print("\n");
  9195. NEXTEACHWINDOWSTATION(pwinsta)
  9196. return TRUE;
  9197. }
  9198. pwinsta = param1;
  9199. GetFieldOffset("nt!OBJECT_HEADER", "Body", &ObjectHeaderOffset);
  9200. pHead = pwinsta - ObjectHeaderOffset;
  9201. GetFieldValue(pHead, "nt!OBJECT_HEADER", "NameInfoOffset", NameInfoOffset);
  9202. pNameBuffer = pHead - NameInfoOffset;
  9203. GetFieldValue(pNameBuffer, "nt!OBJECT_HEADER_NAME_INFO", "Name.Buffer", NameBuffer);
  9204. GetFieldValue(pNameBuffer, "nt!OBJECT_HEADER_NAME_INFO", "Name.Length", NameLength);
  9205. moveBlock(ach, FIXKP(NameBuffer), NameLength);
  9206. ach[NameLength / sizeof(WCHAR)] = L'\0';
  9207. GetFieldValue(pwinsta, SYM(tagWINDOWSTATION), "dwSessionId", sid);
  9208. Print("Windowstation: %ws @ 0x%p sid: 0n%d\n", ach, pwinsta, sid);
  9209. Print(" OBJECT_HEADER @ 0x%p\n", pHead);
  9210. GetFieldValue(pHead, "nt!OBJECT_HEADER", "HandleCount", cOpen);
  9211. Print(" HandleCount = 0n%d\n", cOpen);
  9212. GetFieldValue(pHead, "nt!OBJECT_HEADER", "PointerCount", cOpen);
  9213. Print(" PointerCount = 0n%d\n", cOpen);
  9214. _InitTypeRead(pwinsta, SYM(tagWINDOWSTATION));
  9215. Print(" pTerm = %p\n", ReadField(pTerm));
  9216. Print(" rpdeskList = %p\n", ReadField(rpdeskList));
  9217. Print(" dwFlags = %s\n", GetFlags(GF_WINDOWSTATIONFLAGS, (DWORD)ReadField(dwWSF_Flags), NULL, TRUE));
  9218. Print(" spklList = %p\n", ReadField(spklList));
  9219. Print(" ptiClipLock = %p\n", ReadField(ptiClipLock));
  9220. Print(" spwndClipOpen = %p\n", ReadField(spwndClipOpen));
  9221. Print(" spwndClipViewer = %p\n", ReadField(spwndClipViewer));
  9222. Print(" spwndClipOwner = %p\n", ReadField(spwndClipOwner));
  9223. Print(" pClipBase = %p\n", ReadField(pClipBase));
  9224. Print(" cNumClipFormats = 0x%0lx\n", (DWORD)ReadField(cNumClipFormats));
  9225. Print(" ptiDrawingClipboard= %p\n", ReadField(ptiDrawingClipboard));
  9226. Print(" fClipboardChanged = %d\n", ReadField(fClipboardChanged));
  9227. Print(" pGlobalAtomTable = %p\n", ReadField(pGlobalAtomTable));
  9228. Print(" luidUser = %0lx.%lx\n", (ULONG)ReadField(luidUser.HighPart),
  9229. (ULONG)ReadField(luidUser.LowPart));
  9230. return TRUE;
  9231. }
  9232. #endif
  9233. #ifdef OLD_DEBUGGER
  9234. #ifdef KERNEL
  9235. /************************************************************************\
  9236. * Idwpi
  9237. *
  9238. * Dumps WOWPROCESSINFO structs
  9239. *
  9240. * 6/9/1995 Created SanfordS
  9241. \************************************************************************/
  9242. BOOL Idwpi(
  9243. DWORD opts,
  9244. ULONG64 param1)
  9245. {
  9246. PWOWPROCESSINFO pwpi;
  9247. WOWPROCESSINFO wpi;
  9248. PPROCESSINFO ppi;
  9249. if (param1 == 0) {
  9250. FOREACHPPI(ppi)
  9251. Print("Process %p.\n", FIXKP(ppi));
  9252. move(pwpi, FIXKP(&ppi->pwpi));
  9253. SAFEWHILE (pwpi) {
  9254. Idwpi(0, pwpi);
  9255. Print("\n");
  9256. move(pwpi, FIXKP(&pwpi->pwpiNext));
  9257. }
  9258. NEXTEACHPPI()
  9259. return TRUE;
  9260. }
  9261. if (opts & OFLAG(p)) {
  9262. ppi = (PPROCESSINFO)FIXKP(param1);
  9263. move(pwpi, &ppi->pwpi);
  9264. if (pwpi == NULL) {
  9265. Print("No pwpis for this process.\n");
  9266. return TRUE;
  9267. }
  9268. SAFEWHILE (pwpi) {
  9269. Idwpi(0, pwpi);
  9270. Print("\n");
  9271. move(pwpi, &pwpi->pwpiNext);
  9272. }
  9273. return TRUE;
  9274. }
  9275. pwpi = (PWOWPROCESSINFO)FIXKP(param1);
  9276. move(wpi, pwpi);
  9277. Print("PWOWPROCESSINFO @ 0x%p\n", pwpi);
  9278. Print("\tpwpiNext 0x%08lx\n", wpi.pwpiNext);
  9279. Print("\tptiScheduled 0x%08lx\n", wpi.ptiScheduled);
  9280. Print("\tptdbHead 0x%08lx\n", wpi.ptdbHead);
  9281. Print("\tlpfnWowExitTask 0x%08lx\n", wpi.lpfnWowExitTask);
  9282. Print("\tpEventWowExec 0x%08lx\n", wpi.pEventWowExec);
  9283. Print("\thEventWowExecClient 0x%08lx\n", wpi.hEventWowExecClient);
  9284. Print("\tnSendLock 0x%08lx\n", wpi.nSendLock);
  9285. Print("\tnRecvLock 0x%08lx\n", wpi.nRecvLock);
  9286. Print("\tCSOwningThread 0x%08lx\n", wpi.CSOwningThread);
  9287. Print("\tCSLockCount 0x%08lx\n", wpi.CSLockCount);
  9288. return TRUE;
  9289. }
  9290. #endif // KERNEL
  9291. #ifdef KERNEL
  9292. BOOL DHAVerifyHeap(
  9293. PWIN32HEAP pHeap,
  9294. BOOL bVerbose)
  9295. {
  9296. DbgHeapHead Alloc, *pAlloc = pHeap->pFirstAlloc;
  9297. int sizeHead, counter = 0;
  9298. char szHeadOrTail[HEAP_CHECK_SIZE];
  9299. if (pAlloc == NULL) {
  9300. return FALSE;
  9301. }
  9302. sizeHead = pHeap->dwFlags & WIN32_HEAP_USE_GUARDS ?
  9303. sizeof(pHeap->szHead) : 0;
  9304. do {
  9305. if (!tryMove(Alloc, pAlloc)) {
  9306. Print("Failed to read pAlloc from %p\n", pAlloc);
  9307. return FALSE;
  9308. }
  9309. /*
  9310. * Check the mark, header and tail
  9311. */
  9312. if (Alloc.mark != HEAP_ALLOC_MARK) {
  9313. Print("!!! Bad mark found in allocation use !dso DbgHeapHead %p\n", pAlloc);
  9314. }
  9315. if (sizeHead) {
  9316. if (!tryMove(szHeadOrTail, (PBYTE)pAlloc-sizeof(szHeadOrTail))) {
  9317. Print("Failed to read szHead from %p\n", (PBYTE)pAlloc-sizeof(szHeadOrTail));
  9318. return FALSE;
  9319. }
  9320. if (!RtlEqualMemory(szHeadOrTail, pHeap->szHead, sizeHead)) {
  9321. Print("Head pattern corrupted for allocation %#p\n", pAlloc);
  9322. }
  9323. if (!tryMove(szHeadOrTail, (PBYTE)pAlloc + sizeof(DbgHeapHead) + Alloc.size)) {
  9324. Print("Failed to read szHead from %p\n", (PBYTE)pAlloc + sizeof(DbgHeapHead) + Alloc.size);
  9325. return FALSE;
  9326. }
  9327. if (!RtlEqualMemory(szHeadOrTail, pHeap->szTail, sizeHead)) {
  9328. Print("Tail pattern corrupted for allocation %#p\n", pAlloc);
  9329. }
  9330. }
  9331. if (bVerbose) {
  9332. Print("Allocation %#p, tag %04d size %08d\n", pAlloc, Alloc.tag, Alloc.size);
  9333. }
  9334. if (counter++ > 100) {
  9335. Print(".");
  9336. counter = 0;
  9337. }
  9338. pAlloc = Alloc.pNext;
  9339. } while (pAlloc != NULL);
  9340. if (bVerbose) {
  9341. Print("To dump an allocation use \"dt DBGHEAPHEAD address\"\n");
  9342. }
  9343. return TRUE;
  9344. }
  9345. /************************************************************************\
  9346. * Idha
  9347. *
  9348. * Walks the global array of heaps gWin32Heaps looking for an allocation that
  9349. * contain the address passed in. Then does a sanity check on the entire heap
  9350. * the allocations belongs to. DHAVerifyHeap is a helper procedure. Note that
  9351. * the passed in parameter is already mapped.
  9352. *
  9353. * 12/7/1998 Created MCostea
  9354. \************************************************************************/
  9355. BOOL Idha(
  9356. DWORD opts,
  9357. PVOID pointer)
  9358. {
  9359. int ind, counter;
  9360. SIZE_T sizeHead;
  9361. WIN32HEAP localgWin32Heaps[MAX_HEAPS];
  9362. if (pointer == 0 && (opts & OFLAG(a) ==0)) {
  9363. Print("Wrong usage: dha takes a pointer as a parameter\n");
  9364. return FALSE;
  9365. }
  9366. if (!tryMoveBlock(localgWin32Heaps, EvalExp(VAR(gWin32Heaps)), sizeof(localgWin32Heaps)))
  9367. {
  9368. Print("Can't read the heap globals fix symbols and !reload win32k.sys\n");
  9369. return TRUE;
  9370. }
  9371. /*
  9372. * Walk gWin32Heaps array and look for an allocation containing this pointer
  9373. */
  9374. for (ind = counter = 0; ind < MAX_HEAPS; ind++) {
  9375. /*
  9376. * Is the address in this heap?
  9377. */
  9378. if ((opts & OFLAG(a)) == 0) {
  9379. if ((PVOID)localgWin32Heaps[ind].heap > pointer ||
  9380. (PBYTE)localgWin32Heaps[ind].heap + localgWin32Heaps[ind].heapReserveSize < (PBYTE)pointer) {
  9381. continue;
  9382. }
  9383. }
  9384. Print("\nHeap number %d ", ind);
  9385. Print("at address %p, flags %d is ", localgWin32Heaps[ind].heap, localgWin32Heaps[ind].dwFlags);
  9386. if (localgWin32Heaps[ind].dwFlags & WIN32_HEAP_INUSE) {
  9387. DbgHeapHead Alloc, *pAlloc;
  9388. Print("in use\n");
  9389. if (localgWin32Heaps[ind].pFirstAlloc == NULL)
  9390. continue;
  9391. pAlloc = localgWin32Heaps[ind].pFirstAlloc;
  9392. if (localgWin32Heaps[ind].dwFlags & WIN32_HEAP_USE_GUARDS) {
  9393. sizeHead = sizeof(localgWin32Heaps[0].szHead);
  9394. Print(" has string quards szHead %s, szTail %s\n",
  9395. localgWin32Heaps[0].szHead,
  9396. localgWin32Heaps[0].szTail);
  9397. } else {
  9398. sizeHead = 0;
  9399. Print("no string quards\n");
  9400. }
  9401. if (opts & OFLAG(a)) {
  9402. if (DHAVerifyHeap(&localgWin32Heaps[ind], opts & OFLAG(v))) {
  9403. Print("WIN32HEAP at %p is healthy\n", localgWin32Heaps[ind].heap);
  9404. }
  9405. continue;
  9406. }
  9407. do {
  9408. if (!tryMove(Alloc, pAlloc)) {
  9409. Print("Failed to read pAlloc %p\n", pAlloc);
  9410. return TRUE;
  9411. }
  9412. if ((PBYTE)pAlloc - sizeHead < (PBYTE)pointer &&
  9413. (PBYTE)pAlloc + sizeof(DbgHeapHead) + Alloc.size + sizeHead > (PBYTE)pointer) {
  9414. /*
  9415. * Found the allocation
  9416. */
  9417. Print("Found allocation %p ", pAlloc);
  9418. if (pointer == (PBYTE)pAlloc + sizeof(DbgHeapHead)) {
  9419. Print("as the begining of a heap allocated block\n");
  9420. } else {
  9421. Print("inside a heap allocated block\n");
  9422. }
  9423. Print("tag %04d size %08d now verify the heap\n", Alloc.tag, Alloc.size);
  9424. /*
  9425. * Verify the entire heap for corruption
  9426. */
  9427. if (DHAVerifyHeap(&localgWin32Heaps[ind], opts & OFLAG(v))) {
  9428. Print("WIN32HEAP at %p is healthy\n", localgWin32Heaps[ind].heap);
  9429. }
  9430. return TRUE;
  9431. } else {
  9432. pAlloc = Alloc.pNext;
  9433. if (counter++ > 100) {
  9434. counter = 0;
  9435. Print(".");
  9436. }
  9437. }
  9438. } while (pAlloc != NULL);
  9439. } else {
  9440. Print("NOT in use\n");
  9441. }
  9442. }
  9443. Print("No heap contains this pointer %p\n", pointer);
  9444. return TRUE;
  9445. }
  9446. #endif // KERNEL
  9447. #endif // OLD_DEBUGGER
  9448. #ifdef KERNEL
  9449. /***************************************************************************\
  9450. * ddl - dump desktop log
  9451. *
  9452. * 12-03-97 CLupu Created
  9453. \***************************************************************************/
  9454. BOOL Iddl(
  9455. DWORD opts,
  9456. ULONG64 param1)
  9457. {
  9458. #ifdef LOGDESKTOPLOCKS
  9459. PTR pdesk, pLog, pObjHeader, pStack, ptr, dwOffset64;
  9460. ULONG dwOffset, dwTraceOffset, dwPVOIDSize, dwLogDSize;
  9461. OBJECT_HEADER Head;
  9462. BOOL bExtra = FALSE;
  9463. int i, ind, nLockCount, nLogCrt;
  9464. LONG HandleCount, PointerCount;
  9465. WORD type, tag;
  9466. CHAR symbol[160];
  9467. ULONG_PTR extra;
  9468. if (param1 == 0) {
  9469. Print("Use !ddl pdesk\n");
  9470. return TRUE;
  9471. }
  9472. pdesk = param1;
  9473. GetFieldOffset("nt!OBJECT_HEADER", "Body", &dwOffset);
  9474. pObjHeader = pdesk - dwOffset;
  9475. Print("Desktop locks:\n\n");
  9476. GetFieldValue(pObjHeader, "nt!OBJECT_HEADER", "HandleCount", HandleCount);
  9477. GetFieldValue(pObjHeader, "nt!OBJECT_HEADER", "PointerCount", PointerCount);
  9478. Print("# HandleCount = %d\n", HandleCount);
  9479. Print("# PointerCount = %d\n", PointerCount);
  9480. if (GetFieldValue(pdesk, SYM(DESKTOP), "nLockCount", nLockCount)) {
  9481. Print("Couldn't get PointerCount for pdesk %p\n", pdesk);
  9482. }
  9483. Print("# Log PointerCount = %d\n\n", nLockCount);
  9484. GetFieldValue(pdesk, SYM(DESKTOP), "pLog", pLog);
  9485. if (opts & OFLAG(v)) {
  9486. bExtra = TRUE;
  9487. }
  9488. dwLogDSize = GetTypeSize("LogD");
  9489. dwPVOIDSize = GetTypeSize("PVOID");
  9490. GetFieldOffset(SYM(LogD), "trace", &dwTraceOffset);
  9491. GetFieldValue(pdesk, SYM(DESKTOP), "nLogCrt", nLogCrt);
  9492. for (i = 0; i < nLogCrt; i++) {
  9493. if (IsCtrlCHit()) {
  9494. break;
  9495. }
  9496. GetFieldValue(pLog, "LogD", "tag", tag);
  9497. GetFieldValue(pLog, "LogD", "type", type);
  9498. GetFieldValue(pLog, "LogD", "extra", extra);
  9499. Print("%s Tag %6d Extra %8lx\n",
  9500. (type ? "LOCK " : "UNLOCK"),
  9501. tag, extra);
  9502. if (bExtra) {
  9503. Print("----------------------------------------------\n");
  9504. for (ind = 0; ind < 6; ind++) {
  9505. pStack = pLog + dwTraceOffset + dwPVOIDSize * ind;
  9506. ReadPointer(pStack, &ptr);
  9507. if (ptr == 0) {
  9508. break;
  9509. }
  9510. GetSym(ptr, symbol, &dwOffset64);
  9511. if (*symbol) {
  9512. Print("\t%s", symbol);
  9513. if (dwOffset64) {
  9514. Print(" +0x%x\n", (ULONG)dwOffset64);
  9515. }
  9516. }
  9517. }
  9518. Print("\n");
  9519. }
  9520. pLog += dwLogDSize;
  9521. }
  9522. return TRUE;
  9523. #else
  9524. Print("!ddl is available only on LOGDESKTOPLOCKS enabled builds of win32k.sys\n");
  9525. return FALSE;
  9526. UNREFERENCED_PARAMETER(opts);
  9527. UNREFERENCED_PARAMETER(param1);
  9528. #endif // LOGDESKTOPLOCKS
  9529. }
  9530. #endif // KERNEL
  9531. #ifdef KERNEL
  9532. /***************************************************************************\
  9533. * dcss - dump critical section stack
  9534. *
  9535. * Dump critical section stack
  9536. *
  9537. * 12-27-1996 CLupu Created
  9538. * 06-26-2001 JasonSch Made Win64-clean.
  9539. \***************************************************************************/
  9540. BOOL Idcss(
  9541. DWORD opts)
  9542. {
  9543. int nFrames;
  9544. PTR pStack;
  9545. UNREFERENCED_PARAMETER(opts);
  9546. moveExp(&pStack, SYM(gCritStack));
  9547. _InitTypeRead(pStack, SYM(CRITSTACK));
  9548. if ((nFrames = (int)ReadField(nFrames)) > 0) {
  9549. DumpThread(0, ReadField(thread));
  9550. #if 0
  9551. Print("\nthread : 0x%p\n", ReadField(thread));
  9552. #endif
  9553. Print("--- Critical section stack trace ---\n");
  9554. PrintStackTrace(ReadField(trace), nFrames);
  9555. }
  9556. return TRUE;
  9557. }
  9558. BOOL Idvs(
  9559. DWORD opts,
  9560. ULONG64 param1)
  9561. {
  9562. ULONG64 pSection;
  9563. ULONG64 pView;
  9564. BOOL bIncludeStackTrace = FALSE;
  9565. UNREFERENCED_PARAMETER(opts);
  9566. UNREFERENCED_PARAMETER(param1);
  9567. if (EvalExp(VAR(gpSections)) == 0) {
  9568. Print("!dvs is available if TRACE_MAP_VIEWS is defined\n");
  9569. return FALSE;
  9570. }
  9571. pSection = GetGlobalPointer(VAR(gpSections));
  9572. if (opts & OFLAG(s)) {
  9573. bIncludeStackTrace = TRUE;
  9574. }
  9575. while (pSection != 0) {
  9576. _InitTypeRead(pSection, SYM(tagWin32Section));
  9577. Print(">>--------------------------------------\n");
  9578. Print("Section %#p\n"
  9579. " pFirstView %#p\n"
  9580. " SectionObject %#p\n"
  9581. " SectionSize 0x%x\n"
  9582. " SectionTag 0x%x\n",
  9583. pSection,
  9584. ReadField(pFirstView),
  9585. ReadField(SectionObject),
  9586. ReadField(SectionSize),
  9587. ReadField(SectionTag));
  9588. if (bIncludeStackTrace) {
  9589. #ifdef MAP_VIEW_STACK_TRACE
  9590. PrintStackTrace(ReadField(trace), MAP_VIEW_STACK_TRACE_SIZE);
  9591. Print("\n");
  9592. #endif // MAP_VIEW_STACK_TRACE
  9593. }
  9594. pView = ReadField(pFirstView);
  9595. while (pView != 0) {
  9596. _InitTypeRead(pView, SYM(tagWin32MapView));
  9597. Print("Views: ---------------------------------\n"
  9598. " View %#p\n"
  9599. " pViewBase %#p\n"
  9600. " ViewSize %#p\n",
  9601. pView,
  9602. ReadField(pViewBase),
  9603. ReadField(View.ViewSize));
  9604. if (bIncludeStackTrace) {
  9605. #ifdef MAP_VIEW_STACK_TRACE
  9606. PrintStackTrace(ReadField(trace), MAP_VIEW_STACK_TRACE_SIZE);
  9607. Print("\n");
  9608. #endif // MAP_VIEW_STACK_TRACE
  9609. }
  9610. GetFieldValue(pView, SYM(tagWin32MapView), "pNext", pView);
  9611. }
  9612. GetFieldValue(pSection, SYM(tagWin32Section), "pNext", pSection);
  9613. }
  9614. return TRUE;
  9615. }
  9616. #ifdef OLD_DEBUGGER
  9617. BOOL Idfa(
  9618. DWORD opts,
  9619. ULONG64 param1)
  9620. {
  9621. ULONG64 dwOffset;
  9622. CHAR symbol[160];
  9623. int ind;
  9624. PVOID* pTrace;
  9625. PVOID trace;
  9626. DWORD dwAllocFailIndex;
  9627. DWORD* pdwAllocFailIndex;
  9628. PEPROCESS pep;
  9629. PEPROCESS* ppep;
  9630. PETHREAD pet;
  9631. PETHREAD* ppet;
  9632. UNREFERENCED_PARAMETER(opts);
  9633. UNREFERENCED_PARAMETER(param1);
  9634. if (EvalExp(VAR(gdwAllocFailIndex)) == NULL) {
  9635. Print("!dfa is available only in debug versions of win32k.sys\n");
  9636. return FALSE;
  9637. }
  9638. moveExp(&pdwAllocFailIndex, VAR(gdwAllocFailIndex));
  9639. if (!tryMove(dwAllocFailIndex, pdwAllocFailIndex)) {
  9640. Print("dfa failure");
  9641. return FALSE;
  9642. }
  9643. moveExp(&ppep, VAR(gpepRecorded));
  9644. if (!tryMove(pep, ppep)) {
  9645. Print("dfa failure");
  9646. return FALSE;
  9647. }
  9648. moveExp(&ppet, VAR(gpetRecorded));
  9649. if (!tryMove(pet, ppet)) {
  9650. Print("dfa failure");
  9651. return FALSE;
  9652. }
  9653. Print("Fail allocation index %d 0x%04x\n", dwAllocFailIndex, dwAllocFailIndex);
  9654. Print("pEProcess %#p pEThread %#p\n\n", pep, pet);
  9655. moveExp(&pTrace, VAR(gRecordedStackTrace));
  9656. for (ind = 0; ind < 12; ind++) {
  9657. if (!tryMove(trace, pTrace)) {
  9658. Print("dfa failure");
  9659. return FALSE;
  9660. }
  9661. if (trace == 0) {
  9662. break;
  9663. }
  9664. GetSym((PVOID)trace, symbol, &dwOffset);
  9665. if (*symbol) {
  9666. Print("\t%s", symbol);
  9667. if (dwOffset) {
  9668. Print("+%p\n", dwOffset);
  9669. }
  9670. }
  9671. pTrace++;
  9672. }
  9673. Print("\n");
  9674. return TRUE;
  9675. }
  9676. #endif // OLD_DEBUGGER
  9677. VOID PrintStackTrace(
  9678. PTR pStackTrace,
  9679. int tracesCount)
  9680. {
  9681. int traceInd;
  9682. ULONG64 dwOffset, pSymbol;
  9683. CHAR symbol[160];
  9684. DWORD dwPointerSize = GetTypeSize("PVOID");
  9685. for (traceInd = 0; traceInd < tracesCount; traceInd++) {
  9686. ReadPointer(pStackTrace, &pSymbol);
  9687. if (pSymbol == 0) {
  9688. break;
  9689. }
  9690. GetSym(pSymbol, symbol, &dwOffset);
  9691. if (*symbol) {
  9692. Print("\t%s", symbol);
  9693. if (dwOffset) {
  9694. Print("+%p\n", dwOffset);
  9695. } else {
  9696. Print("\n");
  9697. }
  9698. }
  9699. pStackTrace += dwPointerSize;
  9700. }
  9701. Print("\n");
  9702. }
  9703. /***************************************************************************\
  9704. * dpa - dump pool allocations
  9705. *
  9706. * Dump pool allocations.
  9707. *
  9708. * 12-27-96 CLupu Created
  9709. \***************************************************************************/
  9710. BOOL Idpa(
  9711. DWORD opts,
  9712. ULONG64 param1)
  9713. {
  9714. try {
  9715. PTR pAllocList;
  9716. DWORD dwPoolFlags;
  9717. DWORD dwSize = GetTypeSize(SYM(tagWin32PoolHead));
  9718. BOOL bIncludeStackTrace = FALSE;
  9719. moveExpValue(&dwPoolFlags, VAR(gdwPoolFlags));
  9720. if (!(dwPoolFlags & POOL_HEAVY_ALLOCS)) {
  9721. Print("win32k.sys doesn't have pool instrumentation !\n");
  9722. return FALSE;
  9723. }
  9724. if (opts & OFLAG(s)) {
  9725. if (dwPoolFlags & POOL_CAPTURE_STACK) {
  9726. bIncludeStackTrace = TRUE;
  9727. } else {
  9728. Print("win32k.sys doesn't have stack traces enabled for pool allocations\n");
  9729. }
  9730. }
  9731. moveExp(&pAllocList, VAR(gAllocList));
  9732. if (!pAllocList) {
  9733. Print("Could not get Win32AllocStats structure win32k!gAllocList\n");
  9734. return FALSE;
  9735. }
  9736. _InitTypeRead(pAllocList, SYM(tagWin32AllocStats));
  9737. if (opts & OFLAG(c)) {
  9738. Print("- pool instrumentation enabled for win32k.sys\n");
  9739. if (dwPoolFlags & POOL_CAPTURE_STACK) {
  9740. Print("- stack traces enabled for pool allocations\n");
  9741. } else {
  9742. Print("- stack traces disabled for pool allocations\n");
  9743. }
  9744. if (dwPoolFlags & POOL_KEEP_FAIL_RECORD) {
  9745. Print("- records of failed allocations enabled\n");
  9746. } else {
  9747. Print("- records of failed allocations disabled\n");
  9748. }
  9749. if (dwPoolFlags & POOL_KEEP_FREE_RECORD) {
  9750. Print("- records of free pool enabled\n");
  9751. } else {
  9752. Print("- records of free pool disabled\n");
  9753. }
  9754. Print("\n");
  9755. Print(" CrtM CrtA MaxM MaxA Head\n");
  9756. Print("------------|------------|------------|------------|------------|\n");
  9757. _InitTypeRead(pAllocList, SYM(Win32AllocStats));
  9758. Print(" 0x%08x 0x%08x 0x%08x 0x%08x 0x%I64x\n",
  9759. (ULONG)ReadField(dwCrtMem),
  9760. (ULONG)ReadField(dwCrtAlloc),
  9761. (ULONG)ReadField(dwMaxMem),
  9762. (ULONG)ReadField(dwMaxAlloc),
  9763. ReadField(pHead));
  9764. return TRUE;
  9765. }
  9766. _InitTypeRead(pAllocList, SYM(tagWin32AllocStats));
  9767. if (opts & OFLAG(f)) {
  9768. DWORD dwFailRecordCrtIndex, dwFailRecordTotalFailures;
  9769. DWORD dwFailRecords, Ind, dwFailuresToDump;
  9770. PTR pFailRecord, pFailRecordOrg;
  9771. if (!(dwPoolFlags & POOL_KEEP_FAIL_RECORD)) {
  9772. Print("win32k.sys doesn't have records of failed allocations!\n");
  9773. return TRUE;
  9774. }
  9775. dwFailRecordTotalFailures = (DWORD)EvalExp(VAR(gdwFailRecordTotalFailures));
  9776. if (dwFailRecordTotalFailures == 0) {
  9777. Print("No allocation failure in win32k.sys!\n");
  9778. return TRUE;
  9779. }
  9780. dwFailRecordCrtIndex = (DWORD)EvalExp(VAR(gdwFailRecordCrtIndex));
  9781. dwFailRecords = (DWORD)EvalExp(VAR(gdwFailRecords));
  9782. if (dwFailRecordTotalFailures < dwFailRecords) {
  9783. dwFailuresToDump = dwFailRecordTotalFailures;
  9784. } else {
  9785. dwFailuresToDump = dwFailRecords;
  9786. }
  9787. pFailRecord = GetGlobalPointer(VAR(gparrFailRecord));
  9788. if (!pFailRecord) {
  9789. Print("\nCouldn't get gparrFailRecord!\n");
  9790. return FALSE;
  9791. }
  9792. pFailRecordOrg = pFailRecord;
  9793. Print("\nFailures to dump : %d\n\n", dwFailuresToDump);
  9794. for (Ind = 0; Ind < dwFailuresToDump; Ind++) {
  9795. DWORD tag[2] = {0, 0};
  9796. if (dwFailRecordCrtIndex == 0) {
  9797. dwFailRecordCrtIndex = dwFailRecords - 1;
  9798. } else {
  9799. dwFailRecordCrtIndex--;
  9800. }
  9801. pFailRecord = pFailRecordOrg + dwFailRecordCrtIndex;
  9802. _InitTypeRead(pFailRecord, SYM(tagPOOLRECORD));
  9803. tag[0] = (DWORD)(DWORD_PTR)ReadField(ExtraData);
  9804. Print("Allocation for tag '%s' size 0x%x failed\n",
  9805. &tag,
  9806. (ULONG)ReadField(size));
  9807. PrintStackTrace(ReadField(pTrace), RECORD_STACK_TRACE_SIZE);
  9808. }
  9809. }
  9810. _InitTypeRead(pAllocList, SYM(tagWin32AllocStats));
  9811. if (opts & OFLAG(r)) {
  9812. DWORD dwFreeRecordCrtIndex, dwFreeRecordTotalFrees;
  9813. DWORD dwFreeRecords, Ind, dwFreesToDump;
  9814. PTR pFreeRecord, pFreeRecordOrg;
  9815. if (!(dwPoolFlags & POOL_KEEP_FREE_RECORD)) {
  9816. Print("win32k.sys doesn't have records of free pool !\n");
  9817. return FALSE;
  9818. }
  9819. dwFreeRecordTotalFrees = (DWORD)EvalExp(VAR(gdwFreeRecordTotalFrees));
  9820. if (dwFreeRecordTotalFrees == 0) {
  9821. Print("No free pool in win32k.sys !\n");
  9822. return FALSE;
  9823. }
  9824. dwFreeRecordCrtIndex = (DWORD)EvalExp(VAR(gdwFreeRecordCrtIndex));
  9825. dwFreeRecords = (DWORD)EvalExp(VAR(gdwFreeRecords));
  9826. if (dwFreeRecordTotalFrees < dwFreeRecords) {
  9827. dwFreesToDump = dwFreeRecordTotalFrees;
  9828. } else {
  9829. dwFreesToDump = dwFreeRecords;
  9830. }
  9831. pFreeRecord = GetGlobalPointer(VAR(gparrFreeRecord));
  9832. if (!pFreeRecord) {
  9833. Print("\nCouldn't get gparrFreeRecord!\n");
  9834. return FALSE;
  9835. }
  9836. pFreeRecordOrg = pFreeRecord;
  9837. Print("\nFrees to dump : %d\n\n", dwFreesToDump);
  9838. for (Ind = 0; Ind < dwFreesToDump; Ind++) {
  9839. if (dwFreeRecordCrtIndex == 0) {
  9840. dwFreeRecordCrtIndex = dwFreeRecords - 1;
  9841. } else {
  9842. dwFreeRecordCrtIndex--;
  9843. }
  9844. pFreeRecord = pFreeRecordOrg + dwFreeRecordCrtIndex;
  9845. /*
  9846. * Dump
  9847. */
  9848. _InitTypeRead(pFreeRecord, SYM(tagPOOLRECORD));
  9849. Print("Free pool for p %#p size 0x%x\n",
  9850. ReadField(ExtraData),
  9851. (ULONG)ReadField(size));
  9852. PrintStackTrace(ReadField(pTrace), RECORD_STACK_TRACE_SIZE);
  9853. }
  9854. }
  9855. _InitTypeRead(pAllocList, SYM(tagWin32AllocStats));
  9856. if (opts & OFLAG(v)) {
  9857. PTR ph = ReadField(pHead);
  9858. while (ph != 0) {
  9859. _InitTypeRead(ph, SYM(tagWin32PoolHead));
  9860. Print("p %#p pHead %#p size %x\n",
  9861. ph + dwSize, ph, (ULONG)ReadField(size));
  9862. if (bIncludeStackTrace) {
  9863. PrintStackTrace(ReadField(pTrace), RECORD_STACK_TRACE_SIZE);
  9864. }
  9865. ph = (ULONG_PTR)ReadField(pNext);
  9866. }
  9867. return TRUE;
  9868. }
  9869. _InitTypeRead(pAllocList, SYM(tagWin32AllocStats));
  9870. if (opts & OFLAG(p)) {
  9871. PTR ph;
  9872. DWORD dwSize = GetTypeSize(SYM(tagWin32PoolHead));
  9873. if (param1 == 0) {
  9874. return TRUE;
  9875. }
  9876. ph = ReadField(pHead);
  9877. while (ph != 0) {
  9878. if ((param1 - ph) >= ((ULONG)ReadField(size) + dwSize)) {
  9879. Print("p %#p pHead %#p size %x\n",
  9880. ph + 1, ph, (ULONG)ReadField(size));
  9881. PrintStackTrace(ReadField(pTrace), RECORD_STACK_TRACE_SIZE);
  9882. return TRUE;
  9883. }
  9884. ph = ReadField(pNext);
  9885. }
  9886. return TRUE;
  9887. }
  9888. } except (CONTINUE) {
  9889. }
  9890. return TRUE;
  9891. }
  9892. #endif // KERNEL
  9893. #ifdef OLD_DEBUGGER
  9894. /************************************************************************\
  9895. * Ifno
  9896. *
  9897. * Find Nearest Objects - helps in figureing out references
  9898. * to freed objects or stale pointers.
  9899. *
  9900. * 6/9/1995 Created SanfordS
  9901. \************************************************************************/
  9902. BOOL Ifno(
  9903. DWORD opts,
  9904. ULONG64 param1)
  9905. {
  9906. HANDLEENTRY he, heBest, heAfter, *phe;
  9907. DWORD i;
  9908. DWORD hBest, hAfter;
  9909. DWORD_PTR dw;
  9910. UNREFERENCED_PARAMETER(opts);
  9911. if (param1 == 0) {
  9912. Print("Expected an address.\n");
  9913. return FALSE;
  9914. }
  9915. dw = (DWORD_PTR)FIXKP(param1);
  9916. heBest.phead = NULL;
  9917. heAfter.phead = (PVOID)-1;
  9918. if (dw != (DWORD_PTR)param1) {
  9919. /*
  9920. * no fixups needed - he's looking the kernel address range.
  9921. */
  9922. FOREACHHANDLEENTRY(phe, he, i)
  9923. if ((DWORD_PTR)he.phead <= dw &&
  9924. heBest.phead < he.phead &&
  9925. he.bType != TYPE_FREE) {
  9926. heBest = he;
  9927. hBest = i;
  9928. }
  9929. if ((DWORD_PTR)he.phead > dw &&
  9930. heAfter.phead > he.phead &&
  9931. he.bType != TYPE_FREE) {
  9932. heAfter = he;
  9933. hAfter = i;
  9934. }
  9935. NEXTEACHHANDLEENTRY()
  9936. if (heBest.phead != NULL) {
  9937. Print("Nearest guy before %#p is a %s object located at %#p (i=%x).\n",
  9938. dw, aszTypeNames[heBest.bType], heBest.phead, hBest);
  9939. }
  9940. if (heAfter.phead != (PVOID)-1) {
  9941. Print("Nearest guy after %#p is a %s object located at %#p. (i=%x)\n",
  9942. dw, aszTypeNames[heAfter.bType], heAfter.phead, hAfter);
  9943. }
  9944. } else {
  9945. /*
  9946. * fixups are needed.
  9947. */
  9948. FOREACHHANDLEENTRY(phe, he, i)
  9949. if ((DWORD_PTR)FIXKP(he.phead) <= dw &&
  9950. heBest.phead < he.phead &&
  9951. he.bType != TYPE_FREE) {
  9952. heBest = he;
  9953. hBest = i;
  9954. }
  9955. if ((DWORD_PTR)FIXKP(he.phead) > dw &&
  9956. heAfter.phead > he.phead &&
  9957. he.bType != TYPE_FREE) {
  9958. heAfter = he;
  9959. hAfter = i;
  9960. }
  9961. NEXTEACHHANDLEENTRY()
  9962. if (heBest.phead != NULL) {
  9963. Print("Nearest guy before %#p is a %s object located at %#p (i=%x).\n",
  9964. dw, aszTypeNames[heBest.bType], FIXKP(heBest.phead), hBest);
  9965. }
  9966. if (heAfter.phead != (PVOID)-1) {
  9967. Print("Nearest guy after %#p is a %s object located at %#p. (i=%x)\n",
  9968. dw, aszTypeNames[heAfter.bType], FIXKP(heAfter.phead), hAfter);
  9969. }
  9970. }
  9971. return TRUE;
  9972. }
  9973. /************************************************************************\
  9974. * Ifrr
  9975. *
  9976. * Finds Range References - helpful for finding stale pointers.
  9977. *
  9978. * fSuccess
  9979. *
  9980. * 6/9/1995 Created SanfordS
  9981. \************************************************************************/
  9982. BOOL Ifrr(
  9983. DWORD opts,
  9984. ULONG64 param1,
  9985. ULONG64 param2,
  9986. ULONG64 param3,
  9987. ULONG64 param4)
  9988. {
  9989. DWORD_PTR pSrc1 = (DWORD_PTR)param1;
  9990. DWORD_PTR pSrc2 = (DWORD_PTR)param2;
  9991. DWORD_PTR pRef1 = (DWORD_PTR)param3;
  9992. DWORD_PTR pRef2 = (DWORD_PTR)param4;
  9993. DWORD_PTR dw;
  9994. DWORD_PTR buffer[PAGE_SIZE / sizeof(DWORD_PTR)];
  9995. UNREFERENCED_PARAMETER(opts);
  9996. if (pSrc2 < pSrc1) {
  9997. Print("Source range improper. Values reversed.\n");
  9998. dw = pSrc1;
  9999. pSrc1 = pSrc2;
  10000. pSrc2 = dw;
  10001. }
  10002. if (pRef2 == 0) {
  10003. pRef2 = pRef1;
  10004. }
  10005. if (pRef2 < pRef1) {
  10006. Print("Reference range improper. Values reversed.\n");
  10007. dw = pRef1;
  10008. pRef1 = pRef2;
  10009. pRef2 = dw;
  10010. }
  10011. pSrc1 &= MAXULONG_PTR - PAGE_SIZE + 1; // PAGE aligned
  10012. pSrc2 = (pSrc2 + (sizeof(DWORD_PTR)-1)) & (MAXULONG_PTR - (sizeof(DWORD_PTR)-1)); // dword_ptr aligned
  10013. Print("Searching range (%#p-%#p) for references to (%#p-%#p)...",
  10014. pSrc1, pSrc2, pRef1, pRef2);
  10015. for (; pSrc1 < pSrc2; pSrc1 += PAGE_SIZE) {
  10016. BOOL fSuccess;
  10017. if (!(pSrc1 & 0xFFFFFF)) {
  10018. Print("\nSearching %#p...", pSrc1);
  10019. }
  10020. fSuccess = tryMoveBlock(buffer, (PVOID)pSrc1, sizeof(buffer));
  10021. if (!fSuccess) {
  10022. /*
  10023. * Skip to next page
  10024. */
  10025. } else {
  10026. for (dw = 0; dw < ARRAY_SIZE(buffer); dw++) {
  10027. if (buffer[dw] >= pRef1 && buffer[dw] <= pRef2) {
  10028. Print("\n[%#p] = %#p ",
  10029. pSrc1 + dw * sizeof(DWORD_PTR),
  10030. buffer[dw]);
  10031. }
  10032. }
  10033. }
  10034. if (IsCtrlCHit()) {
  10035. Print("\nSearch aborted.\n");
  10036. return TRUE;
  10037. }
  10038. }
  10039. Print("\nSearch complete.\n");
  10040. return TRUE;
  10041. }
  10042. #ifdef KERNEL
  10043. //PGDI_DEVICE undefined
  10044. #if 0
  10045. VOID ddGdiDevice(
  10046. PGDI_DEVICE pGdiDevice)
  10047. {
  10048. Print("\t\tGDI_DEVICE\n");
  10049. Print("\t\tcRefCount = %d\n", pGdiDevice->cRefCount);
  10050. Print("\t\thDevInfo = 0x%.8x\n", pGdiDevice->hDevInfo);
  10051. Print("\t\thDev = 0x%.8x\n", pGdiDevice->hDev);
  10052. Print("\t\trcScreen = (%d,%d)-(%d,%d) %dx%d\n",
  10053. pGdiDevice->rcScreen.left, pGdiDevice->rcScreen.top,
  10054. pGdiDevice->rcScreen.right, pGdiDevice->rcScreen.bottom,
  10055. pGdiDevice->rcScreen.right - pGdiDevice->rcScreen.left,
  10056. pGdiDevice->rcScreen.bottom - pGdiDevice->rcScreen.top);
  10057. Print("\t\tDEVMODEW\n");
  10058. }
  10059. #endif
  10060. #endif
  10061. #endif // OLD_DEBUGGER
  10062. VOID
  10063. DumpMonitor(
  10064. ULONG64 param1,
  10065. LPSTR pstrPrefix)
  10066. {
  10067. DWORD dwMONFlags;
  10068. RECT rc;
  10069. _InitTypeRead(param1, SYM(MONITOR));
  10070. Print("%shead.h = 0x%.8x\n", pstrPrefix, ReadField(head.h));
  10071. Print("%shead.cLockObj = 0x%.8x\n", pstrPrefix, ReadField(head.cLockObj));
  10072. Print("%spMonitorNext = 0x%p\n", pstrPrefix, ReadField(pMonitorNext));
  10073. dwMONFlags = (DWORD)ReadField(dwMONFlags);
  10074. Print("%sdwMONFlags = 0x%.8x %s\n", pstrPrefix, dwMONFlags, GetFlags(GF_MON, dwMONFlags, NULL, FALSE));
  10075. GetFieldValue(param1, SYM(MONITOR), "rcMonitor", rc);
  10076. Print("%srcMonitor = (%d,%d)-(%d,%d) %dx%d\n",
  10077. pstrPrefix, rc.left, rc.top, rc.right, rc.bottom, rc.right - rc.left, rc.bottom - rc.top);
  10078. GetFieldValue(param1, SYM(MONITOR), "rcWork", rc);
  10079. Print("%srcWork = (%d,%d)-(%d,%d) %dx%d\n",
  10080. pstrPrefix, rc.left, rc.top, rc.right, rc.bottom, rc.right - rc.left, rc.bottom - rc.top);
  10081. Print("%shrgnMonitor = 0x%.8x\n", pstrPrefix, ReadField(hrgnMonitor));
  10082. Print("%scFullScreen = %d\n", pstrPrefix, (short)ReadField(cFullScreen));
  10083. Print("%scwndStack = %d\n", pstrPrefix, (short)ReadField(cWndStack));
  10084. #ifdef SUBPIXEL_MOUSE
  10085. {
  10086. DWORD dwOffset;
  10087. FIXPOINT xTxf[SM_POINT_CNT], yTxf[SM_POINT_CNT];
  10088. FIXPOINT slope[SM_POINT_CNT - 1], yint[SM_POINT_CNT - 1];
  10089. GetFieldOffset(SYM(MONITOR), "xTxf", &dwOffset);
  10090. move(xTxf, param1 + dwOffset);
  10091. GetFieldOffset(SYM(MONITOR), "yTxf", &dwOffset);
  10092. move(yTxf, param1 + dwOffset);
  10093. GetFieldOffset(SYM(MONITOR), "slope", &dwOffset);
  10094. move(slope, param1 + dwOffset);
  10095. GetFieldOffset(SYM(MONITOR), "yint", &dwOffset);
  10096. move(yint, param1 + dwOffset);
  10097. Print("%sxTxf = {", pstrPrefix);
  10098. for (dwOffset = 0; dwOffset < SM_POINT_CNT; ++dwOffset) {
  10099. Print("0x%I64x", xTxf[dwOffset]);
  10100. if (dwOffset != SM_POINT_CNT - 1) {
  10101. Print(", ");
  10102. }
  10103. }
  10104. Print("}\n");
  10105. Print("%syTxf = {", pstrPrefix);
  10106. for (dwOffset = 0; dwOffset < SM_POINT_CNT; ++dwOffset) {
  10107. Print("0x%I64x", yTxf[dwOffset]);
  10108. if (dwOffset != SM_POINT_CNT - 1) {
  10109. Print(", ");
  10110. }
  10111. }
  10112. Print("}\n");
  10113. Print("%sslope = {", pstrPrefix);
  10114. for (dwOffset = 0; dwOffset < SM_POINT_CNT - 1; ++dwOffset) {
  10115. Print("0x%I64x", slope[dwOffset]);
  10116. if (dwOffset != SM_POINT_CNT - 2) {
  10117. Print(", ");
  10118. }
  10119. }
  10120. Print("}\n");
  10121. Print("%syint = {", pstrPrefix);
  10122. for (dwOffset = 0; dwOffset < SM_POINT_CNT - 1; ++dwOffset) {
  10123. Print("0x%I64x", yint[dwOffset]);
  10124. if (dwOffset != SM_POINT_CNT - 2) {
  10125. Print(", ");
  10126. }
  10127. }
  10128. Print("}\n");
  10129. }
  10130. #endif // SUBPIXEL_MOUSE
  10131. }
  10132. BOOL Idmon(
  10133. DWORD opts,
  10134. ULONG64 param1)
  10135. {
  10136. UNREFERENCED_PARAMETER(opts);
  10137. if (param1 == NULL_PTR) {
  10138. return FALSE;
  10139. }
  10140. Print("Dumping MONITOR at %p\n", param1);
  10141. DumpMonitor(param1, "\t");
  10142. return TRUE;
  10143. }
  10144. BOOL Idy(
  10145. DWORD opts,
  10146. ULONG64 param1)
  10147. {
  10148. PTR pdi, gpdi, pMonitor, pshi;
  10149. PTR psi;
  10150. ULONG i;
  10151. BOOLEAN fBool;
  10152. ULONG cMonitors;
  10153. RECT rcScreen;
  10154. WORD dmLogPixels;
  10155. UNREFERENCED_PARAMETER(opts);
  10156. GETSHAREDINFO(pshi);
  10157. GetFieldValue((PTR)pshi, SYM(SHAREDINFO), "pDispInfo", gpdi);
  10158. if (param1) {
  10159. pdi = param1;
  10160. } else {
  10161. pdi = gpdi;
  10162. }
  10163. psi = GetGlobalPointer(VAR(gpsi));
  10164. GetFieldValue(psi, SYM(SERVERINFO), "rcScreen", rcScreen);
  10165. GetFieldValue(psi, SYM(SERVERINFO), "dmLogPixels", dmLogPixels);
  10166. _InitTypeRead(pdi, SYM(DISPLAYINFO));
  10167. cMonitors = (ULONG)ReadField(cMonitors);
  10168. Print("Dumping DISPLAYINFO at 0x%.8x\n", pdi);
  10169. Print("\thDev = 0x%.8x\n", ReadField(hDev));
  10170. Print("\thdcScreen = 0x%.8x\n", ReadField(hdcScreen));
  10171. Print("\thdcBits = 0x%.8x\n", ReadField(hdcBits));
  10172. Print("\thdcGray = 0x%.8x\n", ReadField(hdcGray));
  10173. Print("\thbmGray = 0x%.8x\n", ReadField(hbmGray));
  10174. Print("\tcxGray = %d\n", ReadField(cxGray));
  10175. Print("\tcyGray = %d\n", ReadField(cyGray));
  10176. Print("\tpdceFirst = 0x%.8x\n", ReadField(pdceFirst));
  10177. Print("\tpspbFirst = 0x%.8x\n", ReadField(pspbFirst));
  10178. Print("\tcMonitors (visible) = %d\n", cMonitors);
  10179. Print("\tpMonitorPrimary = 0x%.8x\n", RebaseSharedPtr(ReadField(pMonitorPrimary)));
  10180. Print("\tpMonitorFirst = 0x%.8x\n", RebaseSharedPtr(ReadField(pMonitorFirst)));
  10181. Print("\trcScreen = (%d,%d)-(%d,%d) %dx%d\n",
  10182. rcScreen.left, rcScreen.top,
  10183. rcScreen.right, rcScreen.bottom,
  10184. rcScreen.right - rcScreen.left,
  10185. rcScreen.bottom - rcScreen.top);
  10186. Print("\thrgnScreen = 0x%.8x\n", ReadField(hrgnScreen));
  10187. Print("\tdmLogPixels = %d\n", (WORD)ReadField(dmLogPixels));
  10188. Print("\tBitCountMax = %d\n", (WORD)ReadField(BitCountMax));
  10189. GetFieldValue(pdi, SYM(DISPLAYINFO), "fDesktopIsRect", fBool);
  10190. Print("\tfDesktopIsRect = %d\n", fBool);
  10191. GetFieldValue(pdi, SYM(DISPLAYINFO), "fAnyPalette", fBool);
  10192. Print("\tfAnyPalette = %d\n", fBool);
  10193. Print("\n");
  10194. if (pdi == gpdi) {
  10195. if (dmLogPixels != (WORD)ReadField(dmLogPixels)) {
  10196. Print("\n\n");
  10197. Print("ERROR - dmLogPixels doesn't match in gpsi (%d) and gpDispInfo (%d)\n",
  10198. dmLogPixels, (WORD)ReadField(dmLogPixels));
  10199. Print("\n\n");
  10200. }
  10201. }
  10202. for ( pMonitor = ReadField(pMonitorFirst), i = 1;
  10203. pMonitor;
  10204. GetFieldValue(pMonitor, SYM(MONITOR), "pMonitorNext", pMonitor), i++) {
  10205. pMonitor = RebaseSharedPtr(pMonitor);
  10206. Print("\tMonitor %d, pMonitor = 0x%.8x\n", i, pMonitor);
  10207. DumpMonitor(pMonitor, "\t\t");
  10208. Print("\n");
  10209. }
  10210. return TRUE;
  10211. }
  10212. #ifdef KERNEL
  10213. /***************************************************************************\
  10214. * kbd [queue]
  10215. *
  10216. * Loads a DLL containing more debugging extensions
  10217. *
  10218. * 10/27/92 IanJa Created.
  10219. * 6/9/1995 SanfordS made to fit stdexts motif
  10220. \***************************************************************************/
  10221. typedef struct {
  10222. int iVK;
  10223. LPSTR pszVK;
  10224. } VK, *PVK;
  10225. VK aVK[] = {
  10226. { VK_SHIFT, "SHIFT" },
  10227. { VK_LSHIFT, "LSHIFT" },
  10228. { VK_RSHIFT, "RSHIFT" },
  10229. { VK_CONTROL, "CONTROL" },
  10230. { VK_LCONTROL, "LCONTROL" },
  10231. { VK_RCONTROL, "RCONTROL" },
  10232. { VK_MENU, "MENU" },
  10233. { VK_LMENU, "LMENU" },
  10234. { VK_RMENU, "RMENU" },
  10235. { VK_NUMLOCK, "NUMLOCK" },
  10236. { VK_CAPITAL, "CAPITAL" },
  10237. { VK_LBUTTON, "LBUTTON" },
  10238. { VK_MBUTTON, "MBUTTON" },
  10239. { VK_RBUTTON, "RBUTTON" },
  10240. { VK_XBUTTON1, "XBUTTON1" },
  10241. { VK_XBUTTON2, "XBUTTON2" },
  10242. { VK_RETURN , "ENTER" },
  10243. { VK_KANA, "KANA/HANJA" },
  10244. { VK_OEM_8, "OEM_8" },
  10245. // { 0x52 , "R" }, // your key goes here
  10246. { 0, NULL }
  10247. };
  10248. ULONG WDBGAPI KbdPti(PTR pti, PVOID pOpt)
  10249. {
  10250. Ikbd(DOWNCAST(DWORD, pOpt), pti);
  10251. return 0;
  10252. }
  10253. BOOL Ikbd(
  10254. DWORD opts,
  10255. ULONG64 param1)
  10256. {
  10257. if (opts & OFLAG(a)) {
  10258. ForEachPti(KbdPti, ULongToPtr(opts & ~OFLAG(a)));
  10259. return TRUE;
  10260. }
  10261. try {
  10262. PTR pq;
  10263. PTR ptiKeyboard;
  10264. PBYTE pb, pbr;
  10265. int i;
  10266. BYTE afKeyState[CBKEYSTATE + CBKEYSTATERECENTDOWN];
  10267. PTR pgafAsyncKeyState;
  10268. BYTE afAsyncKeyState[CBKEYSTATE];
  10269. PTR pgafRawKeyState;
  10270. BYTE afRawKeyState[CBKEYSTATE];
  10271. UINT PhysModifiers;
  10272. BYTE vkey;
  10273. /*
  10274. * If 'u' was specified, make sure there was also an address
  10275. */
  10276. if (opts & OFLAG(u)) {
  10277. if (param1 == 0) {
  10278. Print("provide arg 2 of ProcessUpdateKeyEvent(), or WM_UPDATEKEYSTATE wParam\n");
  10279. return FALSE;
  10280. }
  10281. move(afKeyState, param1);
  10282. pb = afKeyState;
  10283. pbr = afKeyState + CBKEYSTATE;
  10284. Print("Key State: === NEW STATE ==== Asynchronous Physical\n");
  10285. } else {
  10286. if (opts & OFLAG(k)) {
  10287. vkey = (BYTE)param1;
  10288. param1 = NULL_PTR;
  10289. }
  10290. if (param1) {
  10291. pq = param1;
  10292. } else {
  10293. pq = GetGlobalPointer(VAR(gpqForeground));
  10294. }
  10295. /*
  10296. * Print out simple thread info for pq->ptiLock.
  10297. */
  10298. GetFieldValue(pq, SYM(tagQ), "ptiKeyboard", ptiKeyboard);
  10299. if (ptiKeyboard) {
  10300. Idt(OFLAG(p), ptiKeyboard);
  10301. }
  10302. GetFieldValue(pq, SYM(tagQ), "afKeyState", afKeyState);
  10303. pb = afKeyState;
  10304. pbr = afKeyState + CBKEYSTATE;
  10305. Print("Key State: QUEUE %p Asynchronous Raw\n", pq);
  10306. }
  10307. moveExp(&pgafAsyncKeyState, VAR(gafAsyncKeyState));
  10308. move(afAsyncKeyState, pgafAsyncKeyState);
  10309. moveExp(&pgafRawKeyState, VAR(gafRawKeyState));
  10310. move(afRawKeyState, pgafRawKeyState);
  10311. Print(" Down Toggle Recent Down Toggle Down Toggle\n");
  10312. if (opts & OFLAG(s)) {
  10313. for (vkey = 1; vkey < VK_UNKNOWN; ++vkey) {
  10314. Print("%02x %10.10s:\t%d %d %d %d %d %d %d\n",
  10315. vkey,
  10316. _GetVKeyName(vkey, 0),
  10317. TestKeyDownBit(pb, vkey) != 0,
  10318. TestKeyToggleBit(pb, vkey) != 0,
  10319. TestKeyRecentDownBit(pbr, vkey) != 0,
  10320. TestKeyDownBit(afAsyncKeyState, vkey) != 0,
  10321. TestKeyToggleBit(afAsyncKeyState, vkey) != 0,
  10322. TestKeyDownBit(afRawKeyState, vkey) != 0,
  10323. TestKeyToggleBit(afRawKeyState, vkey) != 0);
  10324. }
  10325. } else {
  10326. for (i = 0; aVK[i].pszVK != NULL; i++) {
  10327. Print("VK_%s:\t%d %d %d %d %d %d %d\n",
  10328. aVK[i].pszVK,
  10329. TestKeyDownBit(pb, aVK[i].iVK) != 0,
  10330. TestKeyToggleBit(pb, aVK[i].iVK) != 0,
  10331. TestKeyRecentDownBit(pbr, aVK[i].iVK) != 0,
  10332. TestKeyDownBit(afAsyncKeyState, aVK[i].iVK) != 0,
  10333. TestKeyToggleBit(afAsyncKeyState, aVK[i].iVK) != 0,
  10334. TestKeyDownBit(afRawKeyState, aVK[i].iVK) != 0,
  10335. TestKeyToggleBit(afRawKeyState, aVK[i].iVK) != 0);
  10336. }
  10337. if (opts & OFLAG(k)) {
  10338. Print("%s:\t%d %d %d %d %d %d %d\n",
  10339. GetVKeyName(vkey),
  10340. TestKeyDownBit(pb, vkey) != 0,
  10341. TestKeyToggleBit(pb, vkey) != 0,
  10342. TestKeyRecentDownBit(pbr, vkey) != 0,
  10343. TestKeyDownBit(afAsyncKeyState, vkey) != 0,
  10344. TestKeyToggleBit(afAsyncKeyState, vkey) != 0,
  10345. TestKeyDownBit(afRawKeyState, vkey) != 0,
  10346. TestKeyToggleBit(afRawKeyState, vkey) != 0);
  10347. }
  10348. }
  10349. moveExpValue(&PhysModifiers, VAR(gfsSASModifiersDown));
  10350. Print("PhysModifiers = %x\n", PhysModifiers);
  10351. } except(CONTINUE) {
  10352. }
  10353. return TRUE;
  10354. }
  10355. #endif // KERNEL
  10356. /************************************************************************\
  10357. * Itest
  10358. *
  10359. * Tests the basic stdexts macros and functions - a good check on the
  10360. * debugger extensions in general before you waste time debuging entensions.
  10361. *
  10362. * 6/9/1995 Created SanfordS
  10363. \************************************************************************/
  10364. BOOL Itest()
  10365. {
  10366. PTR p;
  10367. ULONG64 cch;
  10368. CHAR ach[80];
  10369. Print("Print test!\n");
  10370. SAFEWHILE (TRUE) {
  10371. Print("SAFEWHILE test... Hit Ctrl-C NOW!\n");
  10372. }
  10373. p = EvalExp(VAR(gpsi));
  10374. Print("EvalExp(%s) = %#p\n", VAR(gpsi), p);
  10375. GetSym(p, ach, &cch);
  10376. Print("GetSym(%#p) = %s\n", p, ach);
  10377. if (IsWinDbg()) {
  10378. Print("I think windbg is calling me.\n");
  10379. } else {
  10380. Print("I don't think windbg is calling me.\n");
  10381. }
  10382. Print("MoveBlock test...\n");
  10383. moveBlock(&p, EvalExp(VAR(gpsi)), sizeof(p));
  10384. Print("MoveBlock(%#p) = %#p.\n", EvalExp(VAR(gpsi)), p);
  10385. Print("moveExp test...\n");
  10386. moveExp(&p, VAR(gpsi));
  10387. Print("moveExp(%s) = %p.\n", VAR(gpsi), p);
  10388. Print("moveExpValue test...\n");
  10389. p = GetGlobalPointer(VAR(gpsi));
  10390. Print("moveExpValue(%s) = %#p.\n", VAR(gpsi), p);
  10391. Print("Basic tests complete.\n");
  10392. return TRUE;
  10393. }
  10394. /************************************************************************\
  10395. * Iuver
  10396. *
  10397. * Dumps versions of extensions and winsrv/win32k
  10398. *
  10399. * 6/15/1995 Created SanfordS
  10400. \************************************************************************/
  10401. BOOL Iuver()
  10402. {
  10403. try {
  10404. PTR psi, wSRVIFlags;
  10405. BOOL bExtsIs64 = (sizeof(VOID*) == 8);
  10406. #if DBG
  10407. Print("USEREXTS version: Checked %s.\n"
  10408. "WIN32K.SYS version: ", bExtsIs64 ? "ia64" : "x86");
  10409. #else
  10410. Print("USEREXTS version: Free %s.\n"
  10411. "WIN32K.SYS version: ", bExtsIs64 ? "ia64" : "x86");
  10412. #endif
  10413. psi = GetGlobalPointer(VAR(gpsi));
  10414. GetFieldValue(psi, SYM(SERVERINFO), "wSRVIFlags", wSRVIFlags);
  10415. Print((wSRVIFlags & SRVIF_CHECKED) ? "Checked" : "Free");
  10416. Print(" %s", IsPtr64() ? "ia64" : "x86");
  10417. Print(".\n");
  10418. } except (CONTINUE) {
  10419. }
  10420. return TRUE;
  10421. }
  10422. #ifdef KERNEL
  10423. #ifdef OBSOLETE
  10424. #define DUMPSTATUS(status) if (tryMoveExpValue(&Status, VAR(g ## status))) { \
  10425. Print("g%s = %lx\n", #status, Status); \
  10426. }
  10427. #define DUMPTIME(time) if (tryMoveExpValue(&Time, VAR(g ## time))) { \
  10428. Print("g%s = %lx\n", #time, Time); \
  10429. }
  10430. #else
  10431. #define DUMPSTATUS(status) moveExpValue(&Status, VAR(g ## status)); \
  10432. Print("g%s = %lx\n", #status, Status);
  10433. #define DUMPTIME(time) moveExpValue(&Time, VAR(g ## time)); \
  10434. Print("g%s = %lx\n", #time, Time);
  10435. #endif
  10436. /***************************************************************************\
  10437. * dinp - dump input diagnostics
  10438. * dinp -v verbose
  10439. * dinp -i show input records
  10440. *
  10441. * 04/13/98 IanJa Created.
  10442. \***************************************************************************/
  10443. int gnIndent;
  10444. BOOL Idinp(
  10445. DWORD opts,
  10446. ULONG64 param1)
  10447. {
  10448. try {
  10449. DWORD Time;
  10450. PTR pDeviceInfo;
  10451. ULONG64 v;
  10452. DWORD dw;
  10453. int i = 0;
  10454. DWORD nKbd = 0;
  10455. BOOL bVerbose = FALSE;
  10456. #if 0
  10457. {
  10458. NTSTATUS Status;
  10459. DUMPSTATUS(KbdIoctlLEDSStatus);
  10460. }
  10461. #endif
  10462. DUMPTIME(MouseProcessMiceInputTime);
  10463. DUMPTIME(MouseQueueMouseEventTime);
  10464. DUMPTIME(MouseUnqueueMouseEventTime);
  10465. if (opts & OFLAG(v)) {
  10466. bVerbose = TRUE;
  10467. }
  10468. pDeviceInfo = GetGlobalPointer(VAR(gpDeviceInfoList));
  10469. if (pDeviceInfo == NULL_PTR) {
  10470. Print("win32k!gpDeviceInfoList is NULL\n");
  10471. }
  10472. SAFEWHILE (pDeviceInfo) {
  10473. if (param1 && (param1 != pDeviceInfo)) {
  10474. // skip it
  10475. } else {
  10476. WCHAR awchBuffer[100];
  10477. DWORD cbBuffer;
  10478. BYTE type;
  10479. PTR h;
  10480. ULONG64 cLockObj;
  10481. _InitTypeRead(pDeviceInfo, SYM(tagDEVICEINFO));
  10482. Print("#%d: ", i);
  10483. type = (BYTE)ReadField(type);
  10484. switch (type) {
  10485. case DEVICE_TYPE_MOUSE:
  10486. Print("MOU");
  10487. break;
  10488. case DEVICE_TYPE_KEYBOARD:
  10489. Print("KBD");
  10490. ++nKbd;
  10491. break;
  10492. #ifdef DEVICE_TYPE_HID
  10493. case DEVICE_TYPE_HID:
  10494. Print("HID");
  10495. break;
  10496. #endif
  10497. default:
  10498. Print("%2d?", type);
  10499. }
  10500. h = ReadField(head.h);
  10501. cLockObj = ReadField(head.cLockObj);
  10502. Print(" @ 0x%p h:0x%p (lock:0x%x) ", pDeviceInfo, h, (DWORD)cLockObj);
  10503. v = ReadField(usActions);
  10504. if (v) {
  10505. Print("\n Pending action: %x %s", (USHORT)v,
  10506. GetFlags(GF_DIAF, (USHORT)v, NULL, TRUE));
  10507. }
  10508. v = ReadField(ustrName.Length);
  10509. if (v) {
  10510. cbBuffer = min((ULONG)v, sizeof(awchBuffer) - sizeof(WCHAR));
  10511. v = ReadField(ustrName.Buffer);
  10512. if (tryMoveBlock(awchBuffer, v, cbBuffer)) {
  10513. Print("\n %.*ws\n", cbBuffer / sizeof(WCHAR), awchBuffer);
  10514. } else {
  10515. Print("\n");
  10516. }
  10517. } else {
  10518. Print("\n NO-NAME!\n");
  10519. }
  10520. switch (type) {
  10521. case DEVICE_TYPE_KEYBOARD:
  10522. Print(" Type: %04x SubType: %04x (%x, %x)\n",
  10523. (DWORD)ReadField(keyboard.IdEx.Type),
  10524. (DWORD)ReadField(keyboard.IdEx.Subtype),
  10525. (DWORD)ReadField(keyboard.Attr.KeyboardIdentifier.Type),
  10526. (DWORD)ReadField(keyboard.Attr.KeyboardIdentifier.Subtype));
  10527. break;
  10528. }
  10529. if (bVerbose || (param1 == pDeviceInfo)) {
  10530. ULONG offset, offset2;
  10531. gnIndent += 2;
  10532. dso(SYM(tagGENERIC_DEVICE_INFO), pDeviceInfo, 0);
  10533. gnIndent += 2;
  10534. GetFieldOffset(SYM(tagDEVICEINFO), "iosb", &offset);
  10535. Print(" IOSB @ 0x%p\n", pDeviceInfo + offset);
  10536. dso(SYM(_IO_STATUS_BLOCK), pDeviceInfo + offset, 0);
  10537. gnIndent -= 2;
  10538. switch (type) {
  10539. case DEVICE_TYPE_MOUSE:
  10540. GetFieldOffset(SYM(tagDEVICEINFO), "mouse", &offset);
  10541. Print(" MOUSE_DEVICE_INFO @ 0x%p\n", pDeviceInfo + offset);
  10542. dso(SYM(tagMOUSE_DEVICE_INFO), pDeviceInfo + offset, 0);
  10543. gnIndent += 2;
  10544. GetFieldOffset(SYM(tagMOUSE_DEVICE_INFO), "Attr", &offset2);
  10545. Print(" Attr @ 0x%p\n", pDeviceInfo + offset + offset2);
  10546. dso(SYM(_MOUSE_ATTRIBUTES), pDeviceInfo + offset + offset2, 0);
  10547. gnIndent -= 2;
  10548. break;
  10549. case DEVICE_TYPE_KEYBOARD:
  10550. GetFieldOffset(SYM(tagDEVICEINFO), "keyboard", &offset);
  10551. Print(" KEYBOARD_DEVICE_INFO @ 0x%p\n", pDeviceInfo + offset);
  10552. dso(SYM(tagKEYBOARD_DEVICE_INFO), pDeviceInfo + offset, 0);
  10553. gnIndent += 2;
  10554. GetFieldOffset(SYM(tagKEYBOARD_DEVICE_INFO), "Attr", &offset2);
  10555. Print(" KEYBOARD_ATTRIBUTES @ 0x%p\n", pDeviceInfo + offset + offset2);
  10556. dso(SYM(_KEYBOARD_ATTRIBUTES), pDeviceInfo + offset + offset2, DBG_DUMP_RECUR_LEVEL(1));
  10557. gnIndent -= 2;
  10558. break;
  10559. #ifdef GENERIC_INPUT
  10560. case DEVICE_TYPE_HID:
  10561. {
  10562. PTR pTLCInfo;
  10563. GetFieldOffset(SYM(tagDEVICEINFO), "hid", &offset);
  10564. Print(" HID_DEVICE_INFO @ 0x%p\n", pDeviceInfo + offset);
  10565. dso(SYM(tagHID_DEVICE_INFO), pDeviceInfo + offset, 0);
  10566. GetFieldValue(pDeviceInfo, SYM(tagDEVICEINFO), "hid.pTLCInfo", pTLCInfo);
  10567. Print(" HID_TLC_INFO @ 0x%p\n", pTLCInfo);
  10568. dso(SYM(tagHID_TLC_INFO), pTLCInfo, 0);
  10569. }
  10570. break;
  10571. #endif
  10572. default:
  10573. Print("Unknown device type %d\n", type);
  10574. }
  10575. if ((opts & OFLAG(i))
  10576. #ifdef GENERIC_INPUT
  10577. && type != DEVICE_TYPE_HID
  10578. #endif
  10579. ) {
  10580. ULONG offset;
  10581. PTR pData;
  10582. ULONG64 Information;
  10583. ULONG64 sizeDataItem;
  10584. GetFieldOffset(SYM(tagDEVICEINFO), "keyboard.Data", &offset);
  10585. pData = pDeviceInfo + offset;
  10586. GetFieldValue(pDeviceInfo, SYM(tagDEVICEINFO), "iosb.Information", Information);
  10587. sizeDataItem = GetTypeSize(SYM(_KEYBOARD_INPUT_DATA));
  10588. Print(" Input Records:");
  10589. if (Information == 0) {
  10590. Print(" NONE\n");
  10591. } else {
  10592. UINT i;
  10593. Print("\n");
  10594. gnIndent += 2;
  10595. for (i = 0; i < Information / sizeDataItem; ++i) {
  10596. dso(SYM(_KEYBOARD_INPUT_DATA), pData, 0);
  10597. pData += sizeDataItem;
  10598. }
  10599. gnIndent -= 2;
  10600. }
  10601. }
  10602. gnIndent -= 2;
  10603. }
  10604. #ifdef GENERIC_INPUT
  10605. else if (type == DEVICE_TYPE_HID) {
  10606. PTR pHidDesc;
  10607. USHORT UsagePage, Usage;
  10608. GetFieldValue(pDeviceInfo, SYM(tagDEVICEINFO), "hid.pHidDesc", pHidDesc);
  10609. _InitTypeRead(pHidDesc, SYM(HIDDESC));
  10610. UsagePage = (USHORT)ReadField(hidpCaps.UsagePage);
  10611. Usage = (USHORT)ReadField(hidpCaps.Usage);
  10612. Print(" UsagePage:%04x Usage:%04x\n", UsagePage, Usage);
  10613. }
  10614. #endif
  10615. Print("\n");
  10616. }
  10617. GetFieldValue(pDeviceInfo, SYM(tagDEVICEINFO), "pNext", pDeviceInfo);
  10618. ++i;
  10619. }
  10620. // Now display input related sytem metrics
  10621. {
  10622. PTR psi;
  10623. ULONG offset;
  10624. static SYSMET_ENTRY aSysMet[] = {
  10625. SMENTRY(MOUSEPRESENT),
  10626. SMENTRY(MOUSEWHEELPRESENT),
  10627. SMENTRY(CMOUSEBUTTONS),
  10628. };
  10629. psi = GetGlobalPointer(VAR(gpsi));
  10630. GetFieldOffset(SYM(tagSERVERINFO), "aiSysMet", &offset);
  10631. for (i = 0; !IsCtrlCHit() && i < ARRAY_SIZE(aSysMet); ++i) {
  10632. int metric;
  10633. move(metric, psi + offset + aSysMet[i].iMetric * sizeof(int));
  10634. Print("SM_%-18s = 0x%08lx = %d\n",
  10635. aSysMet[i].pstrMetric,
  10636. metric,
  10637. metric);
  10638. }
  10639. }
  10640. moveExpValue(&dw, VAR(gnHid));
  10641. Print("#HID = 0x%x #Kbd = 0x%x\n", dw, nKbd);
  10642. } except (CONTINUE) {
  10643. }
  10644. return TRUE;
  10645. }
  10646. BOOL I_dinp(
  10647. DWORD opts,
  10648. ULONG64 param1)
  10649. {
  10650. #ifdef _IA64_
  10651. UNREFERENCED_PARAMETER(opts);
  10652. UNREFERENCED_PARAMETER(param1);
  10653. return FALSE;
  10654. #else
  10655. DWORD Time;
  10656. NTSTATUS Status;
  10657. PDEVICEINFO pDeviceInfo, *ppDeviceInfo;
  10658. int i = 0;
  10659. #if 0
  10660. char ach[100];
  10661. #endif
  10662. DWORD nKbd;
  10663. BOOL bVerbose = FALSE;
  10664. DUMPSTATUS(KbdIoctlLEDSStatus);
  10665. DUMPTIME(MouseProcessMiceInputTime);
  10666. DUMPTIME(MouseQueueMouseEventTime);
  10667. DUMPTIME(MouseUnqueueMouseEventTime);
  10668. if (opts & OFLAG(v)) {
  10669. bVerbose = TRUE;
  10670. }
  10671. ppDeviceInfo = (PDEVICEINFO*)EvalExp(VAR(gpDeviceInfoList));
  10672. while (tryMove(pDeviceInfo, (PTR)ppDeviceInfo) && pDeviceInfo) {
  10673. if (param1 && (param1 != (PTR)pDeviceInfo)) {
  10674. ; // skip it
  10675. } else if (pDeviceInfo != 0) {
  10676. DEVICEINFO DeviceInfo;
  10677. WCHAR awchBuffer[100];
  10678. DWORD cbBuffer;
  10679. Print("#%d: %p ", i, (PTR)pDeviceInfo);
  10680. if (tryMove(DeviceInfo, (PTR)pDeviceInfo)) {
  10681. if (DeviceInfo.type == DEVICE_TYPE_MOUSE) {
  10682. Print("MOU", i);
  10683. } else if (DeviceInfo.type == DEVICE_TYPE_KEYBOARD) {
  10684. Print("KBD");
  10685. } else {
  10686. Print("%2d?", DeviceInfo.type);
  10687. }
  10688. if (DeviceInfo.usActions) {
  10689. Print(" Pending action %x %s", DeviceInfo.usActions,
  10690. GetFlags(GF_DIAF, DeviceInfo.usActions, NULL, TRUE));
  10691. }
  10692. cbBuffer = min(DeviceInfo.ustrName.Length, sizeof(awchBuffer)-sizeof(WCHAR));
  10693. if (tryMoveBlock(awchBuffer, (PTR)DeviceInfo.ustrName.Buffer, cbBuffer)) {
  10694. awchBuffer[cbBuffer / sizeof(WCHAR)] = 0;
  10695. Print("\n %ws\n", awchBuffer);
  10696. } else {
  10697. Print("\n");
  10698. }
  10699. } else {
  10700. DeviceInfo.type = 0xFF;
  10701. }
  10702. #if 0
  10703. if (bVerbose || (param1 == (PTR)pDeviceInfo)) {
  10704. sprintf(ach, "GENERIC_DEVICE_INFO 0x%p", pDeviceInfo);
  10705. gnIndent += 2;
  10706. Idso(0, ach);
  10707. gnIndent += 2;
  10708. sprintf(ach, "IO_STATUS_BLOCK 0x%p",
  10709. (PBYTE)pDeviceInfo + FIELD_OFFSET(DEVICEINFO, iosb));
  10710. Idso(0, ach);
  10711. gnIndent -= 2;
  10712. if (DeviceInfo.type == DEVICE_TYPE_MOUSE) {
  10713. sprintf(ach, "MOUSE_DEVICE_INFO 0x%p",
  10714. (PBYTE)pDeviceInfo + FIELD_OFFSET(DEVICEINFO, mouse));
  10715. Idso(0, ach);
  10716. gnIndent += 2;
  10717. sprintf(ach, "MOUSE_ATTRIBUTES 0x%p",
  10718. (PBYTE)pDeviceInfo + FIELD_OFFSET(DEVICEINFO, mouse)
  10719. + FIELD_OFFSET(MOUSE_DEVICE_INFO, Attr));
  10720. Idso(0, ach);
  10721. gnIndent -= 2;
  10722. } else if (DeviceInfo.type == DEVICE_TYPE_KEYBOARD) {
  10723. sprintf(ach, "KEYBOARD_DEVICE_INFO 0x%p",
  10724. (PBYTE)pDeviceInfo + FIELD_OFFSET(DEVICEINFO, keyboard));
  10725. Idso(0, ach);
  10726. gnIndent += 2;
  10727. sprintf(ach, "KEYBOARD_ATTRIBUTES 0x%p",
  10728. (PBYTE)pDeviceInfo + FIELD_OFFSET(DEVICEINFO, keyboard)
  10729. + FIELD_OFFSET(KEYBOARD_DEVICE_INFO, Attr));
  10730. Idso(0, ach);
  10731. gnIndent -= 2;
  10732. } else {
  10733. Print("Unknown device type %d\n", DeviceInfo.type);
  10734. }
  10735. if (opts & OFLAG(i)) {
  10736. Print(" Input Records:");
  10737. if (DeviceInfo.iosb.Information == 0) {
  10738. Print(" NONE\n");
  10739. } else {
  10740. Print("\n");
  10741. gnIndent += 2;
  10742. sprintf(ach, "KEYBOARD_INPUT_DATA %p *%x",
  10743. &(pDeviceInfo->keyboard.Data[0]),
  10744. DeviceInfo.iosb.Information / sizeof(DeviceInfo.keyboard.Data[0]));
  10745. Idso(0, ach);
  10746. gnIndent -= 2;
  10747. }
  10748. }
  10749. gnIndent -= 2;
  10750. }
  10751. #endif
  10752. }
  10753. ppDeviceInfo = FIXKP(&pDeviceInfo->pNext);
  10754. i++;
  10755. }
  10756. // Now display input related sytem metrics
  10757. {
  10758. SERVERINFO si;
  10759. //PSERVERINFO psi;
  10760. PTR psi;
  10761. // #define SMENTRY(sm) {SM_##sm, #sm} (see above
  10762. /*
  10763. * Add mouse- and keyboard- related entries to this table
  10764. * with the prefix removed, in whatever order you think is rational
  10765. */
  10766. static SYSMET_ENTRY aSysMet[] = {
  10767. SMENTRY(MOUSEPRESENT),
  10768. SMENTRY(MOUSEWHEELPRESENT),
  10769. SMENTRY(CMOUSEBUTTONS),
  10770. };
  10771. psi = GetGlobalPointer(VAR(gpsi));
  10772. move(si, psi);
  10773. for (i = 0; i < ARRAY_SIZE(aSysMet); i++) {
  10774. Print( "SM_%-18s = 0x%08lx = %d\n",
  10775. aSysMet[i].pstrMetric,
  10776. si.aiSysMet[aSysMet[i].iMetric],
  10777. si.aiSysMet[aSysMet[i].iMetric]);
  10778. }
  10779. moveExpValue(&nKbd, VAR(gnKeyboards));
  10780. Print("gnKeyboards = %d\n", nKbd);
  10781. moveExpValue(&nKbd, VAR(gnMice));
  10782. Print("gnMice = %d\n", nKbd);
  10783. moveExpValue(&nKbd, VAR(gnHid));
  10784. Print("ghMice = %d\n", nKbd);
  10785. }
  10786. return TRUE;
  10787. #endif // _IA64_
  10788. }
  10789. #endif // KERNEL
  10790. #ifdef KERNEL
  10791. /***************************************************************************\
  10792. * hh - dump the flags in gdwHydraHint
  10793. *
  10794. * 05/20/98 MCostea Created.
  10795. \***************************************************************************/
  10796. BOOL Ihh(
  10797. DWORD opts,
  10798. ULONG64 param1)
  10799. {
  10800. DWORD dwHHint;
  10801. PTR pdwHH;
  10802. ULONG ulSessionId;
  10803. PTR pulASessionId;
  10804. int i, maxFlags;
  10805. char * aHHstrings[] = {
  10806. "HH_DRIVERENTRY 0x00000001",
  10807. "HH_USERINITIALIZE 0x00000002",
  10808. "HH_INITVIDEO 0x00000004",
  10809. "HH_REMOTECONNECT 0x00000008",
  10810. "HH_REMOTEDISCONNECT 0x00000010",
  10811. "HH_REMOTERECONNECT 0x00000020",
  10812. "HH_REMOTELOGOFF 0x00000040",
  10813. "HH_DRIVERUNLOAD 0x00000080",
  10814. "HH_GRECLEANUP 0x00000100",
  10815. "HH_USERKCLEANUP 0x00000200",
  10816. "HH_INITIATEWIN32KCLEANUP 0x00000400",
  10817. "HH_ALLDTGONE 0x00000800",
  10818. "HH_RITGONE 0x00001000",
  10819. "HH_RITCREATED 0x00002000",
  10820. "HH_LOADCURSORS 0x00004000",
  10821. "HH_KBDLYOUTGLOBALCLEANUP 0x00008000",
  10822. "HH_KBDLYOUTFREEWINSTA 0x00010000",
  10823. "HH_CLEANUPRESOURCES 0x00020000",
  10824. "HH_DISCONNECTDESKTOP 0x00040000",
  10825. "HH_DTQUITPOSTED 0x00080000",
  10826. "HH_DTQUITRECEIVED 0x00100000",
  10827. "HH_DTNONEWDESKTOP 0x00200000",
  10828. "HH_DTWAITONHANDLES 0x00400000",
  10829. };
  10830. UNREFERENCED_PARAMETER(opts);
  10831. if (param1) {
  10832. dwHHint = (DWORD)((DWORD_PTR)param1);
  10833. Print("gdwHydraHint is 0x%x:\n", dwHHint);
  10834. } else {
  10835. pdwHH = EvalExp(VAR(gdwHydraHint));
  10836. if (!tryMove(dwHHint, pdwHH)) {
  10837. Print("Can't get value of gdwHydraHint\n");
  10838. return FALSE;
  10839. }
  10840. pulASessionId = EvalExp(VAR(gSessionId));
  10841. if (!tryMove(ulSessionId, pulASessionId)) {
  10842. Print("Can't get value of gSessionId\n");
  10843. return FALSE;
  10844. }
  10845. Print("Session 0x%x \n gdwHydraHint is 0x%x:\n", ulSessionId, dwHHint);
  10846. }
  10847. i = 0;
  10848. maxFlags = ARRAY_SIZE(aHHstrings);
  10849. while (dwHHint) {
  10850. if (dwHHint & 0x01) {
  10851. if (i >= maxFlags) {
  10852. Print("\n Error: Unknown flags: userkdx.dll might be outdated\n");
  10853. return TRUE;
  10854. }
  10855. Print(" %s\n", aHHstrings[i]);
  10856. }
  10857. i++;
  10858. dwHHint >>= 1;
  10859. }
  10860. // TO DO: Dump the protocol
  10861. {
  10862. USHORT usProtocol = (USHORT)EvalExp(VAR(gProtocolType));
  10863. BOOL bRemoteSession = (BOOL)EvalExp(VAR(gbRemoteSession));
  10864. BOOL fRemotingConsole = (BOOL)EvalExp(VAR(gfRemotingConsole));
  10865. BOOL fSwitchInProgress = (BOOL)EvalExp(VAR(gfSwitchInProgress));
  10866. BOOL bExitInProgress = (BOOL)EvalExp(VAR(gfSessionSwitchBlock));
  10867. USHORT usPreviousProtocolType = (USHORT)EvalExp(VAR(gPreviousProtocolType));
  10868. //dt nt!_KUSER_SHARED_DATA ffdf0000 ActiveConsoleId
  10869. }
  10870. return TRUE;
  10871. }
  10872. #endif // KERNEL
  10873. /************************************************************************\
  10874. * Procedure: Idupm
  10875. *
  10876. * 04/29/98 GerardoB Created
  10877. \************************************************************************/
  10878. #ifdef KERNEL
  10879. BOOL Idupm(
  10880. VOID)
  10881. {
  10882. char ach[80];
  10883. DWORD dwMask;
  10884. int i;
  10885. WORD w = GF_UPM0;
  10886. Print("UserPreferencesMask:\n");
  10887. for (i = 0; i < SPI_BOOLMASKDWORDSIZE; i++) {
  10888. sprintf(ach, "win32k!gpdwCPUserPreferencesMask + %#lx", i * sizeof(DWORD));
  10889. moveExpValue(&dwMask, ach);
  10890. w = GF_UPM0 + i;
  10891. Print("Offset: %d - %#lx: %s\n",
  10892. i, dwMask, GetFlags(w, dwMask, NULL, TRUE));
  10893. }
  10894. return TRUE;
  10895. }
  10896. #endif // KERNEL
  10897. /************************************************************************\
  10898. * Procedure: Idimc
  10899. *
  10900. * HiroYama Created
  10901. *
  10902. \************************************************************************/
  10903. static struct /*NoName*/ {
  10904. const char* terse;
  10905. const char* verbose;
  10906. } gaIMCAttr[] = {
  10907. "IN", "INPUT",
  10908. "TC", "TARGET_CONVERTED",
  10909. "CV", "CONVERTED",
  10910. "TN", "TARGET_NOTCONVERTED",
  10911. "IE", "INPUT_ERROR",
  10912. "FC", "FIXEDCONVERTED",
  10913. };
  10914. const char* GetInxAttr(BYTE bAttr)
  10915. {
  10916. if (bAttr < ARRAY_SIZE(gaIMCAttr)) {
  10917. return gaIMCAttr[bAttr].terse;
  10918. }
  10919. return "**";
  10920. }
  10921. VOID _PrintInxAttr(
  10922. const char* title,
  10923. PTR pCompStr,
  10924. DWORD offset,
  10925. DWORD len)
  10926. {
  10927. DWORD i;
  10928. PTR pAttr = pCompStr + offset;
  10929. if (title == NULL) {
  10930. // Print a legend
  10931. Print(" ");
  10932. for (i = 0; i < ARRAY_SIZE(gaIMCAttr); ++i) {
  10933. if (i && i % 4 == 0) {
  10934. Print("\n");
  10935. Print(" ");
  10936. }
  10937. Print("%s:%s ", gaIMCAttr[i].terse, gaIMCAttr[i].verbose);
  10938. }
  10939. Print("\n");
  10940. return;
  10941. }
  10942. if (offset == 0 || len == 0) {
  10943. return;
  10944. }
  10945. Print(" %-12s (@ 0x%p) off:0x%x len:0x%x (in byte)\n",
  10946. title, pAttr, offset, len);
  10947. Print(" ");
  10948. i = 0;
  10949. SAFEWHILE (i < len) {
  10950. Print("|%s", GetInxAttr(GetByte(pAttr + i)));
  10951. ++i;
  10952. }
  10953. Print("|\n");
  10954. }
  10955. #define PrintInxAttr(name) \
  10956. _PrintInxAttr(#name, pCompStr, (DWORD)ReadField(dw ## name ## Offset), (DWORD)ReadField(dw ## name ## Len))
  10957. VOID _PrintInxClause(
  10958. const char* title,
  10959. PTR pCompStr,
  10960. DWORD offset,
  10961. DWORD len)
  10962. {
  10963. PTR pClause = pCompStr + offset;
  10964. DWORD i;
  10965. if (offset == 0 || len == 0) {
  10966. return;
  10967. }
  10968. Print(" %-12s (@ 0x%p) off:0x%x len:0x%x (0x%x dwords)\n",
  10969. title, pClause, offset, len, len / sizeof(DWORD));
  10970. Print(" ");
  10971. len /= sizeof(DWORD);
  10972. i = 0;
  10973. SAFEWHILE (i < len) {
  10974. Print("|0x%x", GetDWord(pClause + i));
  10975. ++i;
  10976. }
  10977. Print("|\n");
  10978. }
  10979. #define PrintInxClause(name) \
  10980. _PrintInxClause(#name, pCompStr, (DWORD)ReadField(dw ## name ## Offset), (DWORD)ReadField(dw ## name ## Len))
  10981. const char* GetInxStr(
  10982. WCHAR wchar,
  10983. BOOLEAN fUnicode)
  10984. {
  10985. static char ach[32];
  10986. if (wchar >= 0x20 && wchar <= 0x7e) {
  10987. sprintf(ach, "'%c'", wchar);
  10988. } else if (fUnicode) {
  10989. sprintf(ach, "U+%04x", wchar);
  10990. } else {
  10991. sprintf(ach, "%02x", (BYTE)wchar);
  10992. }
  10993. return ach;
  10994. }
  10995. VOID _PrintInxStr(
  10996. const char* title,
  10997. PTR pCompStr,
  10998. DWORD offset,
  10999. DWORD len,
  11000. BOOLEAN fUnicode)
  11001. {
  11002. DWORD i;
  11003. if (offset == 0 || len == 0) {
  11004. return;
  11005. }
  11006. Print(" %-12s (@ 0x%p) off:0x%x len:0x%x (0x%x cch)\n",
  11007. title, pCompStr + offset, offset, len, len / (fUnicode + 1));
  11008. Print(" ");
  11009. i = 0;
  11010. SAFEWHILE (i < len) {
  11011. WCHAR wchar;
  11012. if (fUnicode) {
  11013. wchar = GetWord(pCompStr + offset + i * sizeof(WCHAR));
  11014. } else {
  11015. wchar = GetByte(pCompStr + offset + i);
  11016. }
  11017. Print("|%s", GetInxStr(wchar, fUnicode));
  11018. ++i;
  11019. }
  11020. Print("|\n");
  11021. }
  11022. #define PrintInxStr(name) \
  11023. _PrintInxStr(#name, pCompStr, (DWORD)ReadField(dw ## name ## Offset), (DWORD)ReadField(dw ## name ## Len), fUnicode)
  11024. #define PrintInxElementA(name) \
  11025. do { \
  11026. PrintInxAttr(name ## Attr); \
  11027. PrintInxClause(name ## Clause); \
  11028. PrintInxStr(name ## Str); \
  11029. } while (0)
  11030. #define PrintInxElementB(name) \
  11031. do { \
  11032. PrintInxClause(name ## Clause); \
  11033. PrintInxStr(name ## Str); \
  11034. } while (0)
  11035. VOID _PrintInxFriendlyStr(
  11036. const char* title,
  11037. PTR pCompStr,
  11038. DWORD dwAttrOffset,
  11039. DWORD dwAttrLen,
  11040. DWORD dwClauseOffset,
  11041. DWORD dwClauseLen,
  11042. DWORD dwStrOffset,
  11043. DWORD dwStrLen,
  11044. BOOLEAN fUnicode)
  11045. {
  11046. DWORD i;
  11047. DWORD n;
  11048. DWORD dwClause;
  11049. Print(" %-11s", title);
  11050. if (dwStrOffset == 0 || dwStrLen == 0) {
  11051. Print("\n");
  11052. return;
  11053. }
  11054. for (i = 0, n = 0; i < dwStrLen; ++i) {
  11055. BYTE bAttr;
  11056. WCHAR wchar;
  11057. //move(dwClause, (PDWORD)(pCompStr + dwClauseOffset) + n);
  11058. dwClause = GetDWord(pCompStr + dwClauseOffset + n * sizeof(DWORD));
  11059. if (dwClause == i) {
  11060. ++n;
  11061. if (i) {
  11062. Print("| ");
  11063. }
  11064. }
  11065. if (fUnicode) {
  11066. wchar = GetWord(pCompStr + dwStrOffset + i * sizeof(WCHAR));
  11067. //move(wchar, (PWCHAR)((PBYTE)pCompStr + dwStrOffset) + i);
  11068. } else {
  11069. wchar = GetByte(pCompStr + dwStrOffset + i);
  11070. }
  11071. if (dwAttrOffset != ~0) {
  11072. //move(bAttr, pCompStr + dwAttrOffset + i);
  11073. bAttr = GetByte(pCompStr + dwAttrOffset + i);
  11074. Print("|%s:%s", GetInxAttr(bAttr), GetInxStr(wchar, fUnicode));
  11075. } else {
  11076. Print("|%s", GetInxStr(wchar, fUnicode));
  11077. }
  11078. }
  11079. Print("|\n");
  11080. if (dwClauseLen / sizeof(DWORD) != (n + 1)) {
  11081. Print(" ** dwClauseLen (0x%x) doesn't match to n (0x%x) **\n", dwClauseLen, (n + 1) * sizeof(DWORD));
  11082. }
  11083. if (dwAttrOffset != ~0 && dwAttrLen != dwStrLen) {
  11084. Print(" ** dwAttrLen (0x%x) doesn't match to dwStrLen (0x%x) **\n", dwAttrLen, dwStrLen);
  11085. }
  11086. }
  11087. #define PrintInxFriendlyStrA(name) \
  11088. _PrintInxFriendlyStr(#name, \
  11089. pCompStr, \
  11090. (DWORD)ReadField(dw ## name ## AttrOffset), \
  11091. (DWORD)ReadField(dw ## name ## AttrLen), \
  11092. (DWORD)ReadField(dw ## name ## ClauseOffset), \
  11093. (DWORD)ReadField(dw ## name ## ClauseLen), \
  11094. (DWORD)ReadField(dw ## name ## StrOffset), \
  11095. (DWORD)ReadField(dw ## name ## StrLen), \
  11096. fUnicode)
  11097. #define PrintInxFriendlyStrB(name) \
  11098. _PrintInxFriendlyStr(#name, \
  11099. pCompStr, \
  11100. ~0, \
  11101. 0, \
  11102. (DWORD)ReadField(dw ## name ## ClauseOffset), \
  11103. (DWORD)ReadField(dw ## name ## ClauseLen), \
  11104. (DWORD)ReadField(dw ## name ## StrOffset), \
  11105. (DWORD)ReadField(dw ## name ## StrLen), \
  11106. fUnicode)
  11107. BOOL Idimc(
  11108. DWORD opts,
  11109. ULONG64 param1)
  11110. {
  11111. try {
  11112. PTR pImc; // PIMC
  11113. PTR pClientImc; // PCLIENTIMC
  11114. PTR pInputContext; // PINPUTCONTEXT
  11115. PTR hInputContext;
  11116. BOOLEAN fUnicode = FALSE;
  11117. BOOLEAN fVerbose, fDumpInputContext, fShowIMCMinInfo, fShowModeSaver, fShowCompStrRaw;
  11118. if (param1 == 0) {
  11119. Print("!dimc -? for help\n");
  11120. return FALSE;
  11121. }
  11122. //
  11123. // If "All" option is specified, set all bits in opts
  11124. // except type specifiers.
  11125. //
  11126. if (opts & OFLAG(a)) {
  11127. opts |= ~(OFLAG(w) | OFLAG(c) | OFLAG(i) | OFLAG(u) | OFLAG(v));
  11128. }
  11129. fVerbose = (opts & OFLAG(v)) != 0;
  11130. fShowCompStrRaw = (opts & OFLAG(s)) != 0;
  11131. fDumpInputContext = (opts & OFLAG(d)) != 0;
  11132. fShowIMCMinInfo = (opts & OFLAG(h)) || fDumpInputContext;
  11133. fShowModeSaver = (opts & OFLAG(r)) != 0;
  11134. if (opts & OFLAG(w)) {
  11135. //
  11136. // Arg is hwnd or pwnd.
  11137. //
  11138. PTR pwnd;
  11139. if ((pwnd = HorPtoP(param1, TYPE_WINDOW)) == 0) {
  11140. return FALSE;
  11141. }
  11142. Print("pwnd=%p\n", pwnd);
  11143. GetFieldValue(pwnd, SYM(tagWND), "hImc", param1);
  11144. if (param1 == 0) {
  11145. Print("Could not read pwnd->hImc.\n");
  11146. return FALSE;
  11147. }
  11148. }
  11149. if (opts & OFLAG(c)) {
  11150. //
  11151. // Arg is client side IMC
  11152. //
  11153. pClientImc = param1;
  11154. goto LClientImc;
  11155. }
  11156. if (opts & OFLAG(i)) {
  11157. //
  11158. // Arg is pInputContext.
  11159. //
  11160. pInputContext = param1;
  11161. opts |= OFLAG(h); // otherwise, nothing will be displayed !
  11162. hInputContext = 0;
  11163. if (opts & OFLAG(u)) {
  11164. Print("Assuming Input Context is UNICODE.\n");
  11165. } else {
  11166. Print("Assuming Input Context is ANSI.\n");
  11167. }
  11168. goto LInputContext;
  11169. }
  11170. //
  11171. // Otherwise, Arg is hImc.
  11172. //
  11173. if ((pImc = HorPtoP(param1, TYPE_INPUTCONTEXT)) == 0) {
  11174. Print("Idimc: %p is not an input context.\n", param1);
  11175. return FALSE;
  11176. }
  11177. Print("pImc=%p\n", pImc);
  11178. InitTypeRead(pImc, win32k!IMC);
  11179. Print("pti:%p\n", ReadField(head.pti));
  11180. #ifdef KERNEL
  11181. // Print simple thread info.
  11182. if (ReadField(head.pti)) {
  11183. Idt(OFLAG(p), ReadField(head.pti));
  11184. }
  11185. #endif
  11186. InitTypeRead(pImc, win32k!IMC);
  11187. //
  11188. // Basic information
  11189. //
  11190. Print("pImc = %08p pti:%08p\n", pImc, FIXKP(ReadField(head.pti)));
  11191. Print(" handle %08p\n", ReadField(head.h));
  11192. Print(" dwClientImc %08p\n", ReadField(dwClientImcData));
  11193. Print(" hImeWnd %08p\n", ReadField(hImeWnd));
  11194. //
  11195. // Show client IMC
  11196. //
  11197. pClientImc = ReadField(dwClientImcData);
  11198. Print("pClientImc: %p\n", pClientImc);
  11199. LClientImc:
  11200. if (pClientImc == 0) {
  11201. Print("pClientImc is NULL.\n");
  11202. return TRUE;
  11203. }
  11204. InitTypeRead(pClientImc, user32!CLIENTIMC);
  11205. if (fVerbose) {
  11206. dso("user32!CLIENTIMC", pClientImc, 0);
  11207. } else {
  11208. Print("pClientImc @ 0x%p cLockObj:0x%x\n", ReadField(dwClientImcData), ReadField(cLockObj));
  11209. }
  11210. Print(" dwFlags %s\n", GetFlags(GF_CLIENTIMC, (DWORD)ReadField(dwFlags), NULL, TRUE));
  11211. fUnicode = !!(ReadField(dwFlags) & IMCF_UNICODE);
  11212. //
  11213. // Show InputContext
  11214. //
  11215. hInputContext = ReadField(hInputContext);
  11216. if (hInputContext) {
  11217. pInputContext = GetPointer(hInputContext);
  11218. } else {
  11219. pInputContext = 0;
  11220. }
  11221. LInputContext:
  11222. Print("InputContext 0x%08p (@ 0x%08p)", hInputContext, pInputContext);
  11223. if (pInputContext == 0) {
  11224. Print("\n");
  11225. return TRUE;
  11226. }
  11227. //
  11228. // if UNICODE specified by the option,
  11229. // set the flag accordingly
  11230. //
  11231. if (opts & OFLAG(u)) {
  11232. fUnicode = TRUE;
  11233. }
  11234. InitTypeRead(pInputContext, win32k!INPUTCONTEXT);
  11235. Print(" hwnd=%p\n", ReadField(hWnd));
  11236. if (fVerbose) {
  11237. dso(SYM(INPUTCONTEXT), pInputContext, 0);
  11238. }
  11239. //
  11240. // Decipher InputContext.
  11241. //
  11242. if (fShowIMCMinInfo) {
  11243. // COMPOSITIONSTRING
  11244. PTR hCompStr = 0;
  11245. PTR pCompStr = NULL_PTR;
  11246. // CANDIDATEINFO
  11247. PTR hCandInfo = 0;
  11248. PTR pCandInfo = NULL_PTR;
  11249. // GUIDELINE
  11250. PTR hGuideLine = 0;
  11251. PTR pGuideLine = NULL_PTR;
  11252. // TRANSMSGLIST
  11253. PTR hMsgBuf = 0;
  11254. PTR pMsgBuf = NULL_PTR;
  11255. DWORD i;
  11256. Print(" dwRefCount: 0x%x fdwDirty: %s\n",
  11257. (DWORD)ReadField(dwRefCount), GetFlags(GF_IMEDIRTY, (DWORD)ReadField(fdwDirty), NULL, TRUE));
  11258. Print(" Conversion: %s\n", GetFlags(GF_CONVERSION, (DWORD)ReadField(fdwConversion), NULL, TRUE));
  11259. Print(" Sentence: %s\n", GetFlags(GF_SENTENCE, (DWORD)ReadField(fdwSentence), NULL, TRUE));
  11260. Print(" fChgMsg: %d uSaveVKey: %02x %s\n",
  11261. (DWORD)ReadField(fChgMsg),
  11262. (DWORD)ReadField(uSavedVKey), GetVKeyName((UINT)ReadField(uSavedVKey)));
  11263. Print(" StatusWnd: (0x%x,0x%x) SoftKbd: (0x%x,0x%x)\n",
  11264. (LONG)ReadField(ptStatusWndPos.x), (LONG)ReadField(ptStatusWndPos.y),
  11265. (LONG)ReadField(ptSoftKbdPos.x), (LONG)ReadField(ptSoftKbdPos.y));
  11266. Print(" fdwInit: %s\n", GetFlags(GF_IMEINIT, (DWORD)ReadField(fdwInit), NULL, TRUE));
  11267. // Font
  11268. {
  11269. PINPUTCONTEXT pIC; // dummy for sizeof
  11270. LPCSTR fmt = " Font: '%s' %dpt wt:%d charset: %s\n";
  11271. BYTE ach[max(sizeof(pIC->lfFont.A.lfFaceName), sizeof(pIC->lfFont.W.lfFaceName))];
  11272. if (fUnicode) {
  11273. ULONG offset;
  11274. fmt = " Font: '%S' %dpt wt:%d charset: %s\n";
  11275. GetFieldOffset(SYM(INPUTCONTEXT), "lfFont.W.lfFaceName", &offset);
  11276. tryMoveBlock(ach, pInputContext + offset, sizeof(pIC->lfFont.W.lfFaceName));
  11277. // assuming WCHAR and alignment is consistent cross-platform...
  11278. } else {
  11279. ULONG offset;
  11280. GetFieldOffset(SYM(INPUTCONTEXT), "lfFont.A.lfFaceName", &offset);
  11281. tryMoveBlock(ach, pInputContext + offset, sizeof(pIC->lfFont.A.lfFaceName));
  11282. }
  11283. Print(fmt,
  11284. ach,
  11285. ReadField(lfFont.A.lfHeight),
  11286. ReadField(lfFont.A.lfWeight),
  11287. GetMaskedEnum(EI_CHARSETTYPE, (DWORD)ReadField(lfFont.A.lfCharSet), NULL));
  11288. }
  11289. // COMPOSITIONFORM
  11290. Print(" cfCompForm: %s pos:(0x%x,0x%x) rc:(0x%x,0x%x)-(0x%x,0x%x)\n",
  11291. GetFlags(GF_IMECOMPFORM, (DWORD)ReadField(cfCompForm.dwStyle), NULL, TRUE),
  11292. (DWORD)ReadField(cfCompForm.ptCurrentPos.x), (DWORD)ReadField(cfCompForm.ptCurrentPos.y),
  11293. (DWORD)ReadField(cfCompForm.rcArea.left), (DWORD)ReadField(cfCompForm.rcArea.top),
  11294. (DWORD)ReadField(cfCompForm.rcArea.right), (DWORD)ReadField(cfCompForm.rcArea.bottom));
  11295. if (hCompStr = ReadField(hCompStr)) {
  11296. if ((pCompStr = GetPointer(hCompStr)) == 0) {
  11297. Print("Could not get hCompStr=%p\n", hCompStr);
  11298. } else if (fVerbose) {
  11299. dso(SYM(COMPOSITIONSTRING), pCompStr, 0);
  11300. }
  11301. }
  11302. if (hCandInfo = ReadField(hCandInfo)) {
  11303. if ((pCandInfo = GetPointer(hCandInfo)) == 0) {
  11304. Print("Could not get hCandInfo=%p\n", hCandInfo);
  11305. } else if (fVerbose) {
  11306. dso(SYM(CANDIDATEINFO), pCandInfo, 0);
  11307. }
  11308. }
  11309. if (hGuideLine = ReadField(hGuideLine)) {
  11310. if ((pGuideLine = GetPointer(hGuideLine)) == 0) {
  11311. Print("Could not get hGuideLine=%p\n", hGuideLine);
  11312. } else if (fVerbose) {
  11313. dso(SYM(GUIDELINE), pGuideLine, 0);
  11314. }
  11315. }
  11316. if (hMsgBuf = ReadField(hMsgBuf)) {
  11317. if ((pMsgBuf = GetPointer(hMsgBuf)) == 0) {
  11318. Print("Could not get hMsgBuf=%p\n", hMsgBuf);
  11319. } else if (fVerbose) {
  11320. dso(SYM(TRANSMSGLIST), pMsgBuf, 0);
  11321. }
  11322. }
  11323. if (!fDumpInputContext && !fVerbose) {
  11324. Print(" CompStr @ 0x%p CandInfo @ 0x%p GuideL @ 0x%p \n",
  11325. pCompStr, pCandInfo, pGuideLine);
  11326. Print(" MsgBuf @ 0x%p (0x%x)\n", pMsgBuf, ReadField(dwNumMsgBuf));
  11327. }
  11328. if (fDumpInputContext) {
  11329. //
  11330. // Composition String
  11331. //
  11332. if (pCompStr) {
  11333. InitTypeRead(pCompStr, win32k!COMPOSITIONSTRING);
  11334. Print(" hCompositionString: %p (@ 0x%p) dwSize=0x%x\n",
  11335. hCompStr, pCompStr, (ULONG)ReadField(dwSize));
  11336. if (fShowCompStrRaw) {
  11337. _PrintInxAttr(NULL, /*NULL*/0, 0, 0);
  11338. PrintInxElementA(CompRead);
  11339. PrintInxElementA(Comp);
  11340. PrintInxElementB(ResultRead);
  11341. PrintInxElementB(Result);
  11342. }
  11343. Print(" CursorPos=0x%x DeltaStart=0x%x\n",
  11344. ReadField(dwCursorPos), ReadField(dwDeltaStart));
  11345. Print(" Private: (@ 0x%p) off:0x%x len:0x%x\n",
  11346. (PBYTE)pCompStr + ReadField(dwPrivateOffset),
  11347. ReadField(dwPrivateOffset), ReadField(dwPrivateSize));
  11348. Print("\n");
  11349. PrintInxFriendlyStrA(CompRead);
  11350. PrintInxFriendlyStrA(Comp);
  11351. PrintInxFriendlyStrB(ResultRead);
  11352. PrintInxFriendlyStrB(Result);
  11353. Print("\n");
  11354. } else {
  11355. Print(" pCompStr is NULL\n");
  11356. }
  11357. //
  11358. // Candidate Info
  11359. //
  11360. if (pCandInfo) {
  11361. DWORD CandInfo_dwCount;
  11362. InitTypeRead(pCandInfo, win32k!CANDIDATEINFO);
  11363. CandInfo_dwCount = (DWORD)ReadField(dwCount);
  11364. Print(" hCandidateInfo: %p (@ 0x%p) dwSize=0x%x dwCount=0x%x PrivOffset=0x%x PrivSize=0x%x\n",
  11365. hCandInfo, pCandInfo, ReadField(dwSize), ReadField(dwCount),
  11366. ReadField(dwPrivateOffset), ReadField(dwPrivateSize));
  11367. for (i = 0; i < CandInfo_dwCount; ++i) {
  11368. PTR pCandList;
  11369. DWORD j;
  11370. DWORD CandList_dwCount;
  11371. pCandList = pCandInfo + GetArrayElement(pCandInfo, SYM(CANDIDATEINFO), "dwOffset", i, "DWORD");
  11372. InitTypeRead(pCandList, win32k!CANDIDATELIST);
  11373. Print(" CandList[%02x] (@ 0x%p) %s count=%x sel=%x pgStart=%x pgSize=%x\n",
  11374. i, pCandList, GetMaskedEnum(EI_IMECANDIDATESTYLE, (DWORD)ReadField(dwStyle), NULL),
  11375. (DWORD)ReadField(dwCount),
  11376. (DWORD)ReadField(dwSelection), (DWORD)ReadField(dwPageStart), (DWORD)ReadField(dwPageSize));
  11377. CandList_dwCount = (DWORD)ReadField(dwCount);
  11378. if (ReadField(dwStyle) == IME_CAND_CODE && CandList_dwCount == 1) {
  11379. // Special case
  11380. Print(" Special case: DBCS char = %04x", (DWORD)GetArrayElement(pCandList, SYM(CANDIDATEINFO), "dwOffset", 0, "DWORD"));
  11381. } else if (CandList_dwCount > 1) {
  11382. DWORD dwSelection = (DWORD)ReadField(dwSelection);
  11383. for (j = 0; j < CandList_dwCount; ++j) {
  11384. DWORD k;
  11385. DWORD dwOffset;
  11386. dwOffset = (DWORD)GetArrayElement(pCandList, SYM(CANDIDATEINFO), "dwOffset", j, "DWORD");
  11387. Print(" %c%c[%02x] @ 0x%p ",
  11388. j == dwSelection ? '*' : ' ',
  11389. (j >= ReadField(dwPageStart) && j < ReadField(dwPageStart) + ReadField(dwPageSize) ? '+' : ' ',
  11390. j, pCandList + dwOffset));
  11391. for (k = 0; k < 0x100; ++k) { // limit upto 0xff cch
  11392. WCHAR wchar;
  11393. if (fUnicode) {
  11394. wchar = GetWord(pCandList + dwOffset + k * sizeof(wchar));
  11395. } else {
  11396. wchar = GetByte(pCandList + dwOffset + k);
  11397. }
  11398. if (wchar == 0) {
  11399. break;
  11400. }
  11401. Print("|%s", GetInxStr(wchar, fUnicode));
  11402. }
  11403. Print("|\n");
  11404. }
  11405. }
  11406. }
  11407. }
  11408. if (pGuideLine) {
  11409. //GUIDELINE GuideLine;
  11410. DWORD GuideLine_dwStrLen, GuideLine_dwStrOffset;
  11411. InitTypeRead(pGuideLine, user32!GUIDELINE);
  11412. GuideLine_dwStrLen = (DWORD)ReadField(dwStrLen);
  11413. GuideLine_dwStrOffset = (DWORD)ReadField(dwStrOffset);
  11414. Print(" hGuideLine: %p (@ 0x%p) dwSize=0x%x\n",
  11415. hGuideLine, pGuideLine, (DWORD)ReadField(dwSize));
  11416. Print(" level:%x index;%x privOffset:%x privSize:%x\n",
  11417. (DWORD)ReadField(dwLevel), (DWORD)ReadField(dwIndex),
  11418. (DWORD)ReadField(dwPrivateSize), (DWORD)ReadField(dwPrivateOffset));
  11419. if (GuideLine_dwStrOffset && GuideLine_dwStrLen) {
  11420. // String
  11421. Print(" str @ 0x%p ", (PBYTE)pGuideLine + (DWORD)ReadField(dwStrOffset));
  11422. for (i = 0; i < GuideLine_dwStrLen; ++i) {
  11423. WCHAR wchar;
  11424. if (fUnicode) {
  11425. wchar = GetWord(pGuideLine + GuideLine_dwStrOffset + i * sizeof(WCHAR));
  11426. } else {
  11427. wchar = GetByte(pGuideLine + GuideLine_dwStrOffset + i);
  11428. }
  11429. Print("|%s", GetInxStr(wchar, fUnicode));
  11430. }
  11431. Print("|\n");
  11432. }
  11433. }
  11434. if (pMsgBuf) {
  11435. DWORD dwNumMsgBuf;
  11436. InitTypeRead(pInputContext, user32!INPUTCONTEXT);
  11437. dwNumMsgBuf = (DWORD)ReadField(dwNumMsgBuf);
  11438. InitTypeRead(pMsgBuf, user32!TRANSMSGLIST);
  11439. Print(" hMsgBuf: %p (@ 0x%p) dwNumMsgBuf=0x%x uMsgCount=0x%x\n",
  11440. hMsgBuf, pMsgBuf, dwNumMsgBuf,
  11441. ReadField(uMsgCount));
  11442. if (dwNumMsgBuf) {
  11443. ULONG offset;
  11444. PTR pTransMsg; // PTRANSMSG
  11445. ULONG size;
  11446. GetFieldOffset("user32!TRANSMSGLIST", "TransMsg", &offset);
  11447. pTransMsg = pMsgBuf + offset;
  11448. size = GetTypeSize("user32!TRANSMSG");
  11449. Print(" | ## |msg | wParam | lParam |\n");
  11450. Print(" +----+----+--------+--------+\n");
  11451. for (i = 0; i < dwNumMsgBuf; ++i, pTransMsg += size) {
  11452. const char* pszMsg = "";
  11453. //DWORD j;
  11454. UINT message;
  11455. InitTypeRead(pTransMsg, user32!TRANSMSG);
  11456. message = (UINT)ReadField(message);
  11457. pszMsg = GetWindowMessageNameInternal(message);
  11458. #if 0
  11459. // Try to find a readable name of the window message
  11460. for (j = 0; j < ARRAY_SIZE(gaMsgs); ++j) {
  11461. if (gaMsgs[i].msg == message) {
  11462. pszMsg = gaMsgs[j].pszMsg;
  11463. break;
  11464. }
  11465. }
  11466. #endif
  11467. Print(" | %02x |%04x|%08x|%08x| %s\n",
  11468. i,
  11469. message, ReadField(wParam), ReadField(lParam), pszMsg);
  11470. }
  11471. Print(" +----+----+--------+--------+\n");
  11472. }
  11473. }
  11474. }
  11475. }
  11476. //
  11477. // Recursively display Mode Savers.
  11478. //
  11479. if (fShowModeSaver) {
  11480. PTR pModeSaver;
  11481. InitTypeRead(pInputContext, user32!INPUTCONTEXT);
  11482. pModeSaver = ReadField(pImeModeSaver);
  11483. //
  11484. // Private Mode Savers.
  11485. //
  11486. while (pModeSaver) {
  11487. InitTypeRead(pModeSaver, user32!IMEMODESAVER);
  11488. Print("ImeModeSaver @ 0x%p -- LangId=%04p fOpen=%d\n",
  11489. pModeSaver, ReadField(langId), (int)ReadField(fOpen));
  11490. Print(" fdwInit %s\n", GetFlags(GF_IMEINIT, (DWORD)ReadField(fdwInit), NULL, TRUE));
  11491. Print(" Conversion %s\n", GetFlags(GF_CONVERSION, (DWORD)ReadField(fdwConversion), NULL, TRUE));
  11492. Print(" Sentence %s\n", GetFlags(GF_SENTENCE, (DWORD)ReadField(fdwSentence), NULL, TRUE));
  11493. pModeSaver = ReadField(next);
  11494. }
  11495. }
  11496. } except (CONTINUE) {
  11497. }
  11498. return TRUE;
  11499. }
  11500. #if OLD_FORM
  11501. //////////////////////////////////////////////////////////
  11502. // OLD_FORM, that doesn't require the user mode symbol
  11503. //////////////////////////////////////////////////////////
  11504. VOID __PrintInxAttr(
  11505. const char* title,
  11506. PVOID pCompStr,
  11507. DWORD offset,
  11508. DWORD len)
  11509. {
  11510. DWORD i;
  11511. PBYTE pAttr = (PBYTE)pCompStr + offset;
  11512. if (title == NULL) {
  11513. // Print a legend
  11514. Print(" ");
  11515. for (i = 0; i < ARRAY_SIZE(gaIMCAttr); ++i) {
  11516. if (i && i % 4 == 0) {
  11517. Print("\n");
  11518. Print(" ");
  11519. }
  11520. Print("%s:%s ", gaIMCAttr[i].terse, gaIMCAttr[i].verbose);
  11521. }
  11522. Print("\n");
  11523. return;
  11524. }
  11525. if (offset == 0 || len == 0) {
  11526. return;
  11527. }
  11528. Print(" %-12s (@ 0x%p) off:0x%x len:0x%x (in byte)\n",
  11529. title, pAttr, offset, len);
  11530. Print(" ");
  11531. for (i = 0; i < len; ++i) {
  11532. BYTE bAttr;
  11533. move(bAttr, pAttr + i);
  11534. Print("|%s", GetInxAttr(bAttr));
  11535. }
  11536. Print("|\n");
  11537. }
  11538. #define _PrintInxAttr(name) \
  11539. __PrintInxAttr(#name, pCompStr, CompStr.dw ## name ## Offset, CompStr.dw ## name ## Len)
  11540. VOID __PrintInxClause(
  11541. const char* title,
  11542. PVOID pCompStr,
  11543. DWORD offset,
  11544. DWORD len)
  11545. {
  11546. PDWORD pClause = (PDWORD)((PBYTE)pCompStr + offset);
  11547. DWORD i;
  11548. if (offset == 0 || len == 0) {
  11549. return;
  11550. }
  11551. Print(" %-12s (@ 0x%p) off:0x%x len:0x%x (0x%x dwords)\n",
  11552. title, pClause, offset, len, len / sizeof(DWORD));
  11553. Print(" ");
  11554. len /= sizeof(DWORD);
  11555. for (i = 0; i < len; ++i) {
  11556. DWORD dwData;
  11557. move(dwData, pClause + i);
  11558. Print("|0x%x", dwData);
  11559. }
  11560. Print("|\n");
  11561. }
  11562. #define _PrintInxClause(name) \
  11563. __PrintInxClause(#name, pCompStr, CompStr.dw ## name ## Offset, CompStr.dw ## name ## Len)
  11564. #if 0
  11565. const char* GetInxStr(WCHAR wchar, BOOLEAN fUnicode)
  11566. {
  11567. static char ach[32];
  11568. if (wchar >= 0x20 && wchar <= 0x7e) {
  11569. sprintf(ach, "'%c'", wchar);
  11570. } else if (fUnicode) {
  11571. sprintf(ach, "U+%04x", wchar);
  11572. } else {
  11573. sprintf(ach, "%02x", (BYTE)wchar);
  11574. }
  11575. return ach;
  11576. }
  11577. #endif
  11578. VOID __PrintInxStr(
  11579. const char* title,
  11580. PVOID pCompStr,
  11581. DWORD offset,
  11582. DWORD len,
  11583. BOOLEAN fUnicode)
  11584. {
  11585. DWORD i;
  11586. if (offset == 0 || len == 0) {
  11587. return;
  11588. }
  11589. Print(" %-12s (@ 0x%p) off:0x%x len:0x%x (0x%x cch)\n",
  11590. title, (PBYTE)pCompStr + offset, offset, len, len / (fUnicode + 1));
  11591. Print(" ");
  11592. for (i = 0; i < len; ++i) {
  11593. WCHAR wchar;
  11594. if (fUnicode) {
  11595. move(wchar, (PWCHAR)((PBYTE)pCompStr + offset) + i);
  11596. }
  11597. else {
  11598. BYTE bchar;
  11599. move(bchar, (PBYTE)pCompStr + offset + i);
  11600. wchar = bchar;
  11601. }
  11602. Print("|%s", GetInxStr(wchar, fUnicode));
  11603. }
  11604. Print("|\n");
  11605. }
  11606. #define PrintInxStr(name) \
  11607. _PrintInxStr(#name, pCompStr, CompStr.dw ## name ## Offset, CompStr.dw ## name ## Len, fUnicode)
  11608. #define _PrintInxElementA(name) \
  11609. do { \
  11610. __PrintInxAttr(name ## Attr); \
  11611. __PrintInxClause(name ## Clause); \
  11612. __PrintInxStr(name ## Str); \
  11613. } while (0)
  11614. #define _PrintInxElementB(name) \
  11615. do { \
  11616. __PrintInxClause(name ## Clause); \
  11617. __PrintInxStr(name ## Str); \
  11618. } while (0)
  11619. VOID __PrintInxFriendlyStr(
  11620. const char* title,
  11621. PBYTE pCompStr,
  11622. DWORD dwAttrOffset,
  11623. DWORD dwAttrLen,
  11624. DWORD dwClauseOffset,
  11625. DWORD dwClauseLen,
  11626. DWORD dwStrOffset,
  11627. DWORD dwStrLen,
  11628. BOOLEAN fUnicode)
  11629. {
  11630. DWORD i;
  11631. DWORD n;
  11632. DWORD dwClause;
  11633. Print(" %-11s", title);
  11634. if (dwStrOffset == 0 || dwStrLen == 0) {
  11635. Print("\n");
  11636. return;
  11637. }
  11638. for (i = 0, n = 0; i < dwStrLen; ++i) {
  11639. BYTE bAttr;
  11640. WCHAR wchar;
  11641. move(dwClause, (PDWORD)(pCompStr + dwClauseOffset) + n);
  11642. if (dwClause == i) {
  11643. ++n;
  11644. if (i) {
  11645. Print("| ");
  11646. }
  11647. }
  11648. if (fUnicode) {
  11649. move(wchar, (PWCHAR)((PBYTE)pCompStr + dwStrOffset) + i);
  11650. }
  11651. else {
  11652. BYTE bchar;
  11653. move(bchar, (PBYTE)pCompStr + dwStrOffset + i);
  11654. wchar = bchar;
  11655. }
  11656. if (dwAttrOffset != ~0) {
  11657. move(bAttr, pCompStr + dwAttrOffset + i);
  11658. Print("|%s:%s", GetInxAttr(bAttr), GetInxStr(wchar, fUnicode));
  11659. }
  11660. else {
  11661. Print("|%s", GetInxStr(wchar, fUnicode));
  11662. }
  11663. }
  11664. Print("|\n");
  11665. if (dwClauseLen / sizeof(DWORD) != (n + 1)) {
  11666. Print(" ** dwClauseLen (0x%x) doesn't match to n (0x%x) **\n", dwClauseLen, (n + 1) * sizeof(DWORD));
  11667. }
  11668. if (dwAttrOffset != ~0 && dwAttrLen != dwStrLen) {
  11669. Print(" ** dwAttrLen (0x%x) doesn't match to dwStrLen (0x%x) **\n", dwAttrLen, dwStrLen);
  11670. }
  11671. }
  11672. #define __PrintInxFriendlyStrA(name) \
  11673. __PrintInxFriendlyStr(#name, \
  11674. (PBYTE)pCompStr, \
  11675. CompStr.dw ## name ## AttrOffset, \
  11676. CompStr.dw ## name ## AttrLen, \
  11677. CompStr.dw ## name ## ClauseOffset, \
  11678. CompStr.dw ## name ## ClauseLen, \
  11679. CompStr.dw ## name ## StrOffset, \
  11680. CompStr.dw ## name ## StrLen, \
  11681. fUnicode)
  11682. #define _PrintInxFriendlyStrB(name) \
  11683. __PrintInxFriendlyStr(#name, \
  11684. (PBYTE)pCompStr, \
  11685. ~0, \
  11686. 0, \
  11687. CompStr.dw ## name ## ClauseOffset, \
  11688. CompStr.dw ## name ## ClauseLen, \
  11689. CompStr.dw ## name ## StrOffset, \
  11690. CompStr.dw ## name ## StrLen, \
  11691. fUnicode)
  11692. BOOL I_dimc(DWORD opts, ULONG64 param1)
  11693. {
  11694. IMC imc;
  11695. PIMC pImc;
  11696. PCLIENTIMC pClientImc;
  11697. CLIENTIMC ClientImc;
  11698. PINPUTCONTEXT pInputContext;
  11699. INPUTCONTEXT InputContext;
  11700. HANDLE hInputContext;
  11701. BOOLEAN fUnicode = FALSE;
  11702. BOOLEAN fVerbose, fDumpInputContext, fShowIMCMinInfo, fShowModeSaver, fShowCompStrRaw;
  11703. char ach[32];
  11704. if (param1 == 0) {
  11705. Print("!dimc -? for help\n");
  11706. return FALSE;
  11707. }
  11708. //
  11709. // If "All" option is specified, set all bits in opts
  11710. // except type specifiers.
  11711. //
  11712. if (opts & OFLAG(a)) {
  11713. opts |= ~(OFLAG(w) | OFLAG(c) | OFLAG(i) | OFLAG(u));
  11714. }
  11715. fVerbose = !!(opts & OFLAG(v));
  11716. fShowCompStrRaw = (opts & OFLAG(s)) || fVerbose;
  11717. fDumpInputContext = (opts & OFLAG(d)) || fShowCompStrRaw || fVerbose;
  11718. fShowIMCMinInfo = (opts & OFLAG(h)) || fDumpInputContext || fVerbose;
  11719. fShowModeSaver = (opts & OFLAG(r)) || fVerbose;
  11720. if (opts & OFLAG(w)) {
  11721. //
  11722. // Arg is hwnd or pwnd.
  11723. //
  11724. PWND pwnd;
  11725. if ((pwnd = HorPtoP(param1, TYPE_WINDOW)) == 0) {
  11726. return FALSE;
  11727. }
  11728. Print("pwnd=%p\n", pwnd);
  11729. if (!tryMove(param1, &pwnd->hImc)) {
  11730. Print("Could not read pwnd->hImc.\n");
  11731. return FALSE;
  11732. }
  11733. }
  11734. if (opts & OFLAG(c)) {
  11735. //
  11736. // Arg is client side IMC
  11737. //
  11738. pClientImc = param1;
  11739. goto LClientImc;
  11740. }
  11741. if (opts & OFLAG(i)) {
  11742. //
  11743. // Arg is pInputContext.
  11744. //
  11745. pInputContext = param1;
  11746. opts |= OFLAG(h); // otherwise, nothing will be displayed !
  11747. hInputContext = 0;
  11748. if (opts & OFLAG(u)) {
  11749. Print("Assuming Input Context is UNICODE.\n");
  11750. }
  11751. else {
  11752. Print("Assuming Input Context is ANSI.\n");
  11753. }
  11754. goto LInputContext;
  11755. }
  11756. //
  11757. // Otherwise, Arg is hImc.
  11758. //
  11759. if ((pImc = HorPtoP(param1, TYPE_INPUTCONTEXT)) == 0) {
  11760. Print("Idimc: %x is not an input context.\n", param1);
  11761. return FALSE;
  11762. }
  11763. //move(imc, FIXKP(pImc));
  11764. move(imc, pImc);
  11765. #ifdef KERNEL
  11766. // Print simple thread info.
  11767. if (imc.head.pti) {
  11768. Idt(OFLAG(p), (PTR)imc.head.pti);
  11769. }
  11770. #endif
  11771. //
  11772. // Basic information
  11773. //
  11774. Print("pImc = %08lx pti:%08lx\n", pImc, FIXKP(imc.head.pti));
  11775. Print(" handle %08lx\n", imc.head.h);
  11776. Print(" dwClientImc %08lx\n", imc.dwClientImcData);
  11777. Print(" hImeWnd %08lx\n", imc.hImeWnd);
  11778. //
  11779. // Show client IMC
  11780. //
  11781. pClientImc = (PVOID)imc.dwClientImcData;
  11782. LClientImc:
  11783. if (pClientImc == NULL) {
  11784. Print("pClientImc is NULL.\n");
  11785. return TRUE;
  11786. }
  11787. move(ClientImc, pClientImc);
  11788. if (fVerbose) {
  11789. sprintf(ach, "CLIENTIMC %p", pClientImc);
  11790. Idso(0, ach);
  11791. }
  11792. else {
  11793. Print("pClientImc @ 0x%p cLockObj:0x%x\n", imc.dwClientImcData, ClientImc.cLockObj);
  11794. }
  11795. Print(" dwFlags %s\n", GetFlags(GF_CLIENTIMC, ClientImc.dwFlags, NULL, TRUE));
  11796. fUnicode = !!(ClientImc.dwFlags & IMCF_UNICODE);
  11797. //
  11798. // Show InputContext
  11799. //
  11800. hInputContext = ClientImc.hInputContext;
  11801. if (hInputContext) {
  11802. move(pInputContext, hInputContext);
  11803. }
  11804. else {
  11805. pInputContext = NULL;
  11806. }
  11807. LInputContext:
  11808. Print("InputContext %08lx (@ 0x%p)", hInputContext, pInputContext);
  11809. if (pInputContext == NULL) {
  11810. Print("\n");
  11811. return TRUE;
  11812. }
  11813. //
  11814. // if UNICODE specified by the option,
  11815. // set the flag accordingly
  11816. //
  11817. if (opts & OFLAG(u)) {
  11818. fUnicode = TRUE;
  11819. }
  11820. move(InputContext, pInputContext);
  11821. Print(" hwnd=%p\n", InputContext.hWnd);
  11822. if (fVerbose) {
  11823. sprintf(ach, "INPUTCONTEXT %p", pInputContext);
  11824. Idso(0, ach);
  11825. }
  11826. //
  11827. // Decipher InputContext.
  11828. //
  11829. if (fShowIMCMinInfo) {
  11830. PCOMPOSITIONSTRING pCompStr = NULL;
  11831. PCANDIDATEINFO pCandInfo = NULL;
  11832. PGUIDELINE pGuideLine = NULL;
  11833. PTRANSMSGLIST pMsgBuf = NULL;
  11834. DWORD i;
  11835. Print(" dwRefCount: 0x%x fdwDirty: %s\n",
  11836. InputContext.dwRefCount, GetFlags(GF_IMEDIRTY, InputContext.fdwDirty, NULL, TRUE));
  11837. Print(" Conversion: %s\n", GetFlags(GF_CONVERSION, InputContext.fdwConversion, NULL, TRUE));
  11838. Print(" Sentence: %s\n", GetFlags(GF_SENTENCE, InputContext.fdwSentence, NULL, TRUE));
  11839. Print(" fChgMsg: %d uSaveVKey: %02x %s\n",
  11840. InputContext.fChgMsg,
  11841. InputContext.uSavedVKey, GetVKeyName(InputContext.uSavedVKey));
  11842. Print(" StatusWnd: (0x%x,0x%x) SoftKbd: (0x%x,0x%x)\n",
  11843. InputContext.ptStatusWndPos.x, InputContext.ptStatusWndPos.y,
  11844. InputContext.ptSoftKbdPos.x, InputContext.ptSoftKbdPos.y);
  11845. Print(" fdwInit: %s\n", GetFlags(GF_IMEINIT, InputContext.fdwInit, NULL, TRUE));
  11846. // Font
  11847. {
  11848. LPCSTR fmt = " Font: '%s' %dpt wt:%d charset: %s\n";
  11849. if (fUnicode) {
  11850. fmt = " Font: '%S' %dpt wt:%d charset: %s\n";
  11851. }
  11852. Print(fmt,
  11853. InputContext.lfFont.A.lfFaceName,
  11854. InputContext.lfFont.A.lfHeight,
  11855. InputContext.lfFont.A.lfWeight,
  11856. GetMaskedEnum(EI_CHARSETTYPE, InputContext.lfFont.A.lfCharSet, NULL));
  11857. }
  11858. // COMPOSITIONFORM
  11859. Print(" cfCompForm: %s pos:(0x%x,0x%x) rc:(0x%x,0x%x)-(0x%x,0x%x)\n",
  11860. GetFlags(GF_IMECOMPFORM, InputContext.cfCompForm.dwStyle, NULL, TRUE),
  11861. InputContext.cfCompForm.ptCurrentPos.x, InputContext.cfCompForm.ptCurrentPos.y,
  11862. InputContext.cfCompForm.rcArea.left, InputContext.cfCompForm.rcArea.top,
  11863. InputContext.cfCompForm.rcArea.right, InputContext.cfCompForm.rcArea.bottom);
  11864. if (InputContext.hCompStr) {
  11865. if (!tryMove(pCompStr, InputContext.hCompStr)) {
  11866. Print("Could not get hCompStr=%08x\n", InputContext.hCompStr);
  11867. //return FALSE;
  11868. }
  11869. }
  11870. if (pCompStr && fVerbose) {
  11871. sprintf(ach, "COMPOSITIONSTRING %p", pCompStr);
  11872. Idso(0, ach);
  11873. }
  11874. if (InputContext.hCandInfo) {
  11875. if (!tryMove(pCandInfo, InputContext.hCandInfo)) {
  11876. Print("Could not get hCandInfo=%08x\n", InputContext.hCandInfo);
  11877. //return FALSE;
  11878. }
  11879. }
  11880. if (pCandInfo && fVerbose) {
  11881. sprintf(ach, "CANDIDATEINFO %p", pCandInfo);
  11882. Idso(0, ach);
  11883. }
  11884. if (InputContext.hGuideLine) {
  11885. if (!tryMove(pGuideLine, InputContext.hGuideLine)) {
  11886. Print("Could not get hGuideLine=%08x\n", InputContext.hGuideLine);
  11887. //return FALSE;
  11888. }
  11889. }
  11890. if (pGuideLine && fVerbose) {
  11891. sprintf(ach, "GUIDELINE %p", pGuideLine);
  11892. Idso(0, ach);
  11893. }
  11894. if (InputContext.hMsgBuf) {
  11895. if (!tryMove(pMsgBuf, InputContext.hMsgBuf)) {
  11896. Print("Could not get hMsgBuf=%08x\n", InputContext.hMsgBuf);
  11897. //return FALSE;
  11898. }
  11899. }
  11900. if (pMsgBuf && fVerbose) {
  11901. sprintf(ach, "TRANSMSGLIST %p", pMsgBuf);
  11902. Idso(0, ach);
  11903. }
  11904. if (!fDumpInputContext && !fVerbose) {
  11905. Print(" CompStr @ 0x%p CandInfo @ 0x%p GuideL @ 0x%p \n",
  11906. pCompStr, pCandInfo, pGuideLine);
  11907. Print(" MsgBuf @ 0x%p (0x%x)\n", pMsgBuf, InputContext.dwNumMsgBuf);
  11908. }
  11909. if (fDumpInputContext) {
  11910. //
  11911. // Composition String
  11912. //
  11913. if (pCompStr) {
  11914. COMPOSITIONSTRING CompStr;
  11915. move(CompStr, pCompStr);
  11916. Print(" hCompositionString: %p (@ 0x%p) dwSize=0x%x\n",
  11917. InputContext.hCompStr, pCompStr, CompStr.dwSize);
  11918. if (fShowCompStrRaw) {
  11919. __PrintInxAttr(NULL, NULL, 0, 0);
  11920. _PrintInxElementA(CompRead);
  11921. _PrintInxElementA(Comp);
  11922. _PrintInxElementB(ResultRead);
  11923. _PrintInxElementB(Result);
  11924. }
  11925. Print(" CursorPos=0x%x DeltaStart=0x%x\n",
  11926. CompStr.dwCursorPos, CompStr.dwDeltaStart);
  11927. Print(" Private: (@ 0x%p) off:0x%x len:0x%x\n",
  11928. (PBYTE)pCompStr + CompStr.dwPrivateOffset,
  11929. CompStr.dwPrivateOffset, CompStr.dwPrivateSize);
  11930. Print("\n");
  11931. _PrintInxFriendlyStrA(CompRead);
  11932. _PrintInxFriendlyStrA(Comp);
  11933. _PrintInxFriendlyStrB(ResultRead);
  11934. _PrintInxFriendlyStrB(Result);
  11935. Print("\n");
  11936. }
  11937. else {
  11938. Print(" pCompStr is NULL\n");
  11939. }
  11940. //
  11941. // Candidate Info
  11942. //
  11943. if (pCandInfo) {
  11944. CANDIDATEINFO CandInfo;
  11945. move(CandInfo, pCandInfo);
  11946. Print(" hCandidateInfo: %p (@ 0x%p) dwSize=0x%x dwCount=0x%x PrivOffset=0x%x PrivSize=0x%x\n",
  11947. InputContext.hCandInfo, pCandInfo, CandInfo.dwSize, CandInfo.dwCount,
  11948. CandInfo.dwPrivateOffset, CandInfo.dwPrivateSize);
  11949. for (i = 0; i < CandInfo.dwCount; ++i) {
  11950. PCANDIDATELIST pCandList;
  11951. CANDIDATELIST CandList;
  11952. DWORD j;
  11953. pCandList = (PCANDIDATELIST)((PBYTE)pCandInfo + CandInfo.dwOffset[i]);
  11954. move(CandList, pCandList);
  11955. Print(" CandList[%02x] (@ 0x%p) %s count=%x sel=%x pgStart=%x pgSize=%x\n",
  11956. i, pCandList, GetMaskedEnum(EI_IMECANDIDATESTYLE, CandList.dwStyle, NULL),
  11957. CandList.dwCount,
  11958. CandList.dwSelection, CandList.dwPageStart, CandList.dwPageSize);
  11959. if (CandList.dwStyle == IME_CAND_CODE && CandList.dwCount == 1) {
  11960. // Special case
  11961. Print(" Special case: DBCS char = %04x", CandList.dwOffset[0]);
  11962. }
  11963. else if (CandList.dwCount > 1) {
  11964. for (j = 0; j < CandList.dwCount; ++j) {
  11965. DWORD k;
  11966. DWORD dwOffset;
  11967. move(dwOffset, pCandList->dwOffset + j);
  11968. Print(" %c%c[%02x] @ 0x%p ",
  11969. j == CandList.dwSelection ? '*' : ' ',
  11970. (j >= CandList.dwPageStart && j < CandList.dwPageStart + CandList.dwPageSize) ? '+' : ' ',
  11971. j, (PBYTE)pCandList + dwOffset);
  11972. for (k = 0; k < 0x100; ++k) { // limit upto 0xff cch
  11973. WCHAR wchar;
  11974. if (fUnicode) {
  11975. move(wchar, (PWCHAR)((PBYTE)pCandList + dwOffset) + k);
  11976. }
  11977. else {
  11978. BYTE bchar;
  11979. move(bchar, (PBYTE)pCandList + dwOffset + k);
  11980. wchar = bchar;
  11981. }
  11982. if (wchar == 0) {
  11983. break;
  11984. }
  11985. Print("|%s", GetInxStr(wchar, fUnicode));
  11986. }
  11987. Print("|\n");
  11988. }
  11989. }
  11990. }
  11991. }
  11992. if (pGuideLine) {
  11993. GUIDELINE GuideLine;
  11994. move(GuideLine, pGuideLine);
  11995. Print(" hGuideLine: %p (@ 0x%p) dwSize=0x%x\n",
  11996. InputContext.hGuideLine, pGuideLine, GuideLine.dwSize);
  11997. Print(" level:%x index;%x privOffset:%x privSize:%x\n",
  11998. GuideLine.dwLevel, GuideLine.dwIndex,
  11999. GuideLine.dwPrivateSize, GuideLine.dwPrivateOffset);
  12000. if (GuideLine.dwStrOffset && GuideLine.dwStrLen) {
  12001. // String
  12002. Print(" str @ 0x%p ", (PBYTE)pGuideLine + GuideLine.dwStrOffset);
  12003. for (i = 0; i < GuideLine.dwStrLen; ++i) {
  12004. WCHAR wchar;
  12005. if (fUnicode) {
  12006. move(wchar, (PWCHAR)((PBYTE)pGuideLine + GuideLine.dwStrOffset) + i);
  12007. } else {
  12008. BYTE bchar;
  12009. move(bchar, (PBYTE)pGuideLine + GuideLine.dwStrOffset + i);
  12010. wchar = bchar;
  12011. }
  12012. Print("|%s", _GetInxStr(wchar, fUnicode));
  12013. }
  12014. Print("|\n");
  12015. }
  12016. }
  12017. if (pMsgBuf) {
  12018. TRANSMSGLIST TransMsgList;
  12019. move(TransMsgList, pMsgBuf);
  12020. Print(" hMsgBuf: %p (@ 0x%p) dwNumMsgBuf=0x%x uMsgCount=0x%x\n",
  12021. InputContext.hMsgBuf, pMsgBuf, InputContext.dwNumMsgBuf,
  12022. TransMsgList.uMsgCount);
  12023. if (InputContext.dwNumMsgBuf) {
  12024. PTRANSMSG pTransMsg = pMsgBuf->TransMsg;
  12025. Print(" | ## |msg | wParam | lParam |\n");
  12026. Print(" +----+----+--------+--------+\n");
  12027. for (i = 0; i < InputContext.dwNumMsgBuf; ++i, ++pTransMsg) {
  12028. const char* pszMsg = "";
  12029. TRANSMSG TransMsg;
  12030. //DWORD j;
  12031. move(TransMsg, pTransMsg);
  12032. #if 0
  12033. // Try to find a readable name of the window message
  12034. for (j = 0; j < ARRAY_SIZE(gaMsgs); ++j) {
  12035. if (gaMsgs[i].msg == TransMsg.message) {
  12036. pszMsg = gaMsgs[j].pszMsg;
  12037. break;
  12038. }
  12039. }
  12040. #else
  12041. pszMsg = GetWindowMessageNameInternal(TransMsg.message);
  12042. #endif
  12043. Print(" | %02x |%04x|%08x|%08x| %s\n",
  12044. i,
  12045. TransMsg.message, TransMsg.wParam, TransMsg.lParam, pszMsg);
  12046. }
  12047. Print(" +----+----+--------+--------+\n");
  12048. }
  12049. }
  12050. }
  12051. }
  12052. //
  12053. // Recursively display Mode Savers.
  12054. //
  12055. if (fShowModeSaver) {
  12056. PIMEMODESAVER pModeSaver = InputContext.pImeModeSaver;
  12057. //
  12058. // Private Mode Savers.
  12059. //
  12060. while (pModeSaver) {
  12061. IMEMODESAVER ImeModeSaver;
  12062. move(ImeModeSaver, pModeSaver);
  12063. Print("ImeModeSaver @ 0x%p -- LangId=0x%04x fOpen=0y%d\n",
  12064. pModeSaver, ImeModeSaver.langId, ImeModeSaver.fOpen);
  12065. Print(" fdwInit %s\n", GetFlags(GF_IMEINIT, ImeModeSaver.fdwInit, NULL, TRUE));
  12066. Print(" Conversion %s\n", GetFlags(GF_CONVERSION, ImeModeSaver.fdwConversion, NULL, TRUE));
  12067. Print(" Sentence %s\n", GetFlags(GF_SENTENCE, ImeModeSaver.fdwSentence, NULL, TRUE));
  12068. move(pModeSaver, &pModeSaver->next);
  12069. }
  12070. }
  12071. return TRUE;
  12072. }
  12073. #endif // OLD_FORM
  12074. #ifdef OLD_DEBUGGER
  12075. #ifndef KERNEL
  12076. /************************************************************************\
  12077. * Procedure: Ikc
  12078. *
  12079. * Dumps keyboard cues state for the window, and pertinent info on the
  12080. * parent KC state and the system settings related to this
  12081. *
  12082. * 06/11/98 MCostea Created
  12083. *
  12084. \************************************************************************/
  12085. BOOL Ikc(
  12086. DWORD opts,
  12087. ULONG64 param1)
  12088. {
  12089. WND wnd;
  12090. PWND pwnd, pwndParent;
  12091. char ach[80];
  12092. BOOL bHideFocus, bHideAccel;
  12093. SERVERINFO si;
  12094. PSERVERINFO psi;
  12095. if (param1 && (pwnd = HorPtoP(param1, TYPE_WINDOW)) == 0) {
  12096. Print("Idw: %p is not a pwnd.\n", param1);
  12097. return FALSE;
  12098. }
  12099. psi = GetGlobalPointer(VAR(gpsi));
  12100. move(si, psi);
  12101. if (si.bKeyboardPref) {
  12102. Print("gpsi->bKeyboardPref ON, KC mechanism is turned off\n");
  12103. }
  12104. if (!(si.PUSIFlags & (PUSIF_KEYBOARDCUES | PUSIF_UIEFFECTS) == PUSIF_KEYBOARDCUES | PUSIF_UIEFFECTS)) {
  12105. Print("Either the UI effects or PUSIF_KEYBOARDCUES are off\n");
  12106. }
  12107. if (!param1) {
  12108. return FALSE;
  12109. }
  12110. move(wnd, FIXKP(pwnd));
  12111. /*
  12112. * Print pwnd and title string.
  12113. */
  12114. DebugGetWindowTextA(pwnd, ach, ARRAY_SIZE(ach));
  12115. Print("pwnd = %08lx \"%s\"\n", pwnd, ach);
  12116. bHideAccel = TestWF(pwnd, WEFPUIACCELHIDDEN);
  12117. bHideFocus = TestWF(pwnd, WEFPUIFOCUSHIDDEN);
  12118. switch(wnd.fnid) {
  12119. case FNID_BUTTON :
  12120. {
  12121. Print("FNID_BUTTON");
  12122. }
  12123. goto printCues;
  12124. case FNID_LISTBOX :
  12125. {
  12126. Print("FNID_LISTBOX");
  12127. }
  12128. goto printCues;
  12129. case FNID_DIALOG :
  12130. {
  12131. Print("FNID_DIALOG");
  12132. }
  12133. goto printCues;
  12134. case FNID_STATIC :
  12135. {
  12136. Print("FNID_STATIC");
  12137. }
  12138. printCues:
  12139. Print(bHideAccel ? " Hide Accel" : " Show Accel");
  12140. Print(bHideFocus ? " Hide Focus" : " Show Focus");
  12141. break;
  12142. default:
  12143. Print("Not KC interesting FNID 0x%x", wnd.fnid);
  12144. break;
  12145. }
  12146. Print("\n");
  12147. pwndParent = wnd.spwndParent;
  12148. move(wnd, FIXKP(wnd.spwndParent));
  12149. if (wnd.fnid == FNID_DIALOG) {
  12150. Print("The parent is a dialog:\n");
  12151. Ikc(opts, pwndParent);
  12152. } else {
  12153. Print("The parent is not a dialog\n");
  12154. }
  12155. return TRUE;
  12156. }
  12157. #endif // KERNEL
  12158. #endif // OLD_DEBUGGER
  12159. #ifdef KERNEL
  12160. /************************************************************************\
  12161. * Procedure: Idimk -- dump IME Hotkeys
  12162. *
  12163. * 08/09/98 HiroYama Created
  12164. *
  12165. \************************************************************************/
  12166. #define IHK_ITEM(x) { x, #x }
  12167. BOOL Idimk(DWORD opts, ULONG64 param1)
  12168. {
  12169. try {
  12170. // PIMEHOTKEYOBJ
  12171. PTR pObj;
  12172. static const struct {
  12173. DWORD mask;
  12174. const char* name;
  12175. } masks[] = {
  12176. IHK_ITEM(MOD_IGNORE_ALL_MODIFIER),
  12177. IHK_ITEM(MOD_ON_KEYUP),
  12178. IHK_ITEM(MOD_RIGHT),
  12179. IHK_ITEM(MOD_LEFT),
  12180. IHK_ITEM(MOD_SHIFT),
  12181. IHK_ITEM(MOD_CONTROL),
  12182. IHK_ITEM(MOD_ALT),
  12183. };
  12184. int nHotKeys = 0;
  12185. UNREFERENCED_PARAMETER(opts);
  12186. if (param1 == 0) {
  12187. pObj = GetGlobalPointer(VAR(gpImeHotKeyListHeader));
  12188. if (!pObj) {
  12189. Print("No IME HotKeys. win32k!gpImeHotKeyListHeader is NULL.\n\n");
  12190. return TRUE;
  12191. }
  12192. Print("using win32k!gpImeHotKeyListHeader (@ 0x%p)\n", pObj);
  12193. } else {
  12194. pObj = FIXKP(param1);
  12195. }
  12196. SAFEWHILE (pObj) {
  12197. int i, n;
  12198. InitTypeRead(pObj, win32k!IMEHOTKEYOBJ);
  12199. Print("ImeHotKeyObj @ 0x%p\n", pObj);
  12200. Print(" pNext 0x%p\n", ReadField(pNext));
  12201. Print(" dwHotKeyID 0x%04x ", ReadField(hk.dwHotKeyID));
  12202. //
  12203. // Show hotkey ID by name
  12204. //
  12205. if (ReadField(hk.dwHotKeyID) >= IME_HOTKEY_DSWITCH_FIRST && ReadField(hk.dwHotKeyID) <= IME_HOTKEY_DSWITCH_LAST) {
  12206. Print(" Direct Switch to HKL 0x%p", ReadField(hk.hKL));
  12207. } else {
  12208. Print(" %s", GetMaskedEnum(EI_IMEHOTKEYTYPE, (DWORD)ReadField(hk.dwHotKeyID), NULL));
  12209. }
  12210. //
  12211. // Show VKey value by name
  12212. //
  12213. Print("\n uVKey 0x%02x %s\n", (UINT)ReadField(hk.uVKey), GetVKeyName((DWORD)ReadField(hk.uVKey)));
  12214. //
  12215. // Show bit mask by name
  12216. //
  12217. Print( " Modifiers 0x%04x ", ReadField(hk.uModifiers));
  12218. n = 0;
  12219. for (i = 0; i < ARRAY_SIZE(masks); ++i) {
  12220. if (masks[i].mask & ReadField(hk.uModifiers)) {
  12221. Print("%s%s", n ? " | " : "", masks[i].name);
  12222. ++n;
  12223. }
  12224. }
  12225. //
  12226. // Target HKL
  12227. //
  12228. Print("\n hKL 0x%p\n\n", ReadField(hk.hKL));
  12229. pObj = ReadField(pNext);
  12230. //
  12231. // If address is specified as an argument, just display one instance.
  12232. //
  12233. if (param1 != 0) {
  12234. break;
  12235. }
  12236. ++nHotKeys;
  12237. }
  12238. if (nHotKeys) {
  12239. Print("Number of IME HotKeys: 0x%04x\n", nHotKeys);
  12240. }
  12241. } except (CONTINUE) {
  12242. }
  12243. return TRUE;
  12244. }
  12245. #undef IHK_ITEM
  12246. #endif // KERNEL
  12247. #ifdef KERNEL
  12248. /************************************************************************\
  12249. * Procedure: Igflags
  12250. *
  12251. * Dumps NT Global Flags
  12252. *
  12253. * 08/11/98 Hiroyama Created
  12254. *
  12255. \************************************************************************/
  12256. #define DGF_ITEM(x) { x, #x }
  12257. BOOL Igflags(DWORD opts)
  12258. {
  12259. static const struct {
  12260. DWORD dwFlag;
  12261. const char* name;
  12262. } names[] = {
  12263. DGF_ITEM(FLG_STOP_ON_EXCEPTION),
  12264. DGF_ITEM(FLG_SHOW_LDR_SNAPS),
  12265. DGF_ITEM(FLG_DEBUG_INITIAL_COMMAND),
  12266. DGF_ITEM(FLG_STOP_ON_HUNG_GUI),
  12267. DGF_ITEM(FLG_HEAP_ENABLE_TAIL_CHECK),
  12268. DGF_ITEM(FLG_HEAP_ENABLE_FREE_CHECK),
  12269. DGF_ITEM(FLG_HEAP_VALIDATE_PARAMETERS),
  12270. DGF_ITEM(FLG_HEAP_VALIDATE_ALL),
  12271. DGF_ITEM(FLG_POOL_ENABLE_TAGGING),
  12272. DGF_ITEM(FLG_HEAP_ENABLE_TAGGING),
  12273. DGF_ITEM(FLG_USER_STACK_TRACE_DB),
  12274. DGF_ITEM(FLG_KERNEL_STACK_TRACE_DB),
  12275. DGF_ITEM(FLG_MAINTAIN_OBJECT_TYPELIST),
  12276. DGF_ITEM(FLG_HEAP_ENABLE_TAG_BY_DLL),
  12277. DGF_ITEM(FLG_ENABLE_CSRDEBUG),
  12278. DGF_ITEM(FLG_ENABLE_KDEBUG_SYMBOL_LOAD),
  12279. DGF_ITEM(FLG_DISABLE_PAGE_KERNEL_STACKS),
  12280. DGF_ITEM(FLG_HEAP_DISABLE_COALESCING),
  12281. DGF_ITEM(FLG_ENABLE_CLOSE_EXCEPTIONS),
  12282. DGF_ITEM(FLG_ENABLE_EXCEPTION_LOGGING),
  12283. DGF_ITEM(FLG_ENABLE_HANDLE_TYPE_TAGGING),
  12284. DGF_ITEM(FLG_HEAP_PAGE_ALLOCS),
  12285. DGF_ITEM(FLG_DEBUG_INITIAL_COMMAND_EX),
  12286. DGF_ITEM(FLG_DISABLE_DBGPRINT),
  12287. };
  12288. DWORD dwFlags;
  12289. int i, n = 0;
  12290. moveExpValue(&dwFlags, "NT!NtGlobalFlag");
  12291. if (opts & OFLAG(v)) {
  12292. Print("NT!NtGlobalFlag %08lx\n\n", dwFlags);
  12293. } else {
  12294. Print("NT!NtGlobalFlag 0x%lx\n", dwFlags);
  12295. }
  12296. dwFlags &= FLG_VALID_BITS;
  12297. for (i = 0; i < ARRAY_SIZE(names); ++i) {
  12298. BOOLEAN on = (dwFlags & names[i].dwFlag) != 0;
  12299. if (opts & OFLAG(v)) {
  12300. Print(" %c%-34s %c(%08x)\n", on ? '*' : ' ', names[i].name, on ? '*' : ' ', names[i].dwFlag);
  12301. } else {
  12302. if (n++ % 2 == 0) {
  12303. Print("\n");
  12304. }
  12305. Print(" %c%-29s ", on ? '*' : ' ', names[i].name + sizeof("FLG_") - 1);
  12306. }
  12307. }
  12308. if (!(opts & OFLAG(v))) {
  12309. Print("\n");
  12310. }
  12311. return TRUE;
  12312. }
  12313. #undef DGF_ITEM
  12314. #endif // KERNEL
  12315. /************************************************************************\
  12316. * Procedure: Ivkey
  12317. *
  12318. * Dumps virtual keys
  12319. *
  12320. * 08/11/98 Hiroyama Created
  12321. *
  12322. \************************************************************************/
  12323. VOID PrintVKey(
  12324. int i)
  12325. {
  12326. Print(" %02x %s\n", gVKeyDef[i].dwVKey, gVKeyDef[i].name);
  12327. }
  12328. BOOL Ivkey(
  12329. DWORD opts,
  12330. LPSTR pszName)
  12331. {
  12332. int i;
  12333. if ((opts & OFLAG(a)) || (opts & OFLAG(o))) {
  12334. //
  12335. // List all virtual keys.
  12336. //
  12337. int n = 0;
  12338. for (i = 0; i < 0x100; ++i) {
  12339. const char* name = GetVKeyName(i);
  12340. if (*name) {
  12341. char buf[128];
  12342. int len;
  12343. sprintf(buf, " %02x %-35s", i, name);
  12344. if (opts & OFLAG(a)) {
  12345. //
  12346. // If it exceeds the second column width, begin new line.
  12347. //
  12348. if ((len = strlen(buf)) >= 40 && n % 2 == 1) {
  12349. Print("\n");
  12350. n = 0;
  12351. }
  12352. Print(buf);
  12353. //
  12354. // If it's in the second column, begin new line.
  12355. //
  12356. if (++n % 2 == 0 || len >= 40) {
  12357. Print("\n");
  12358. n = 0;
  12359. }
  12360. } else {
  12361. Print("%s\n", buf);
  12362. }
  12363. }
  12364. }
  12365. Print("\n");
  12366. } else if (*pszName == 'V' || *pszName == 'v') {
  12367. //
  12368. // Search by VK name.
  12369. //
  12370. int nFound = 0;
  12371. int len = strlen(pszName);
  12372. if (len == 4) {
  12373. int ch = pszName[3];
  12374. if ((ch >= 'A' && ch <= 'Z') || (ch >= '0' && ch <= '9')) {
  12375. Print(" %02x %s\n", ch, pszName);
  12376. ++nFound;
  12377. }
  12378. }
  12379. for (i = 0; i < ARRAY_SIZE(gVKeyDef); ++i) {
  12380. if (_strnicmp(gVKeyDef[i].name, pszName, len) == 0) {
  12381. Print(" %02x %s\n", gVKeyDef[i].dwVKey, gVKeyDef[i].name);
  12382. ++nFound;
  12383. }
  12384. }
  12385. if (nFound == 0) {
  12386. Print("Could not find it.\n");
  12387. }
  12388. } else {
  12389. //
  12390. // Search by VK value.
  12391. //
  12392. NTSTATUS status;
  12393. DWORD dwVKey;
  12394. const char* name;
  12395. status = GetInteger(pszName, 16, &dwVKey, NULL);
  12396. if (!NT_SUCCESS(status)) {
  12397. return FALSE;
  12398. }
  12399. name = GetVKeyName(dwVKey);
  12400. if (*name) {
  12401. Print(" %02x %s\n", dwVKey, name);
  12402. } else {
  12403. Print("Could not find it.\n");
  12404. }
  12405. }
  12406. return TRUE;
  12407. }
  12408. /************************************************************************\
  12409. * Procedure: Idisi
  12410. *
  12411. * Dumps event injection union
  12412. *
  12413. * 09/??/98 Hiroyama Created
  12414. *
  12415. \************************************************************************/
  12416. BOOL I_disi(DWORD opts, ULONG64 param1)
  12417. {
  12418. PINPUT pObj;
  12419. INPUT input;
  12420. #ifdef _IA64_
  12421. if (!IsPtr64()) {
  12422. Print("not on this platform");
  12423. return TRUE;
  12424. }
  12425. #else
  12426. if (IsPtr64()) {
  12427. Print("not on this platform");
  12428. return TRUE;
  12429. }
  12430. #endif
  12431. UNREFERENCED_PARAMETER(opts);
  12432. if (param1 == 0) {
  12433. return FALSE;
  12434. }
  12435. pObj = (PINPUT)FIXKP(param1);
  12436. move(input, (PTR)pObj);
  12437. Print("INPUT @ 0x%p - size: 0x%x\n", pObj, sizeof(input));
  12438. switch (input.type) {
  12439. case INPUT_MOUSE:
  12440. {
  12441. MOUSEINPUT* pmi = &input.mi;
  12442. Print("type: Mouse Input(%x)\n", input.type);
  12443. Print(" dx %lx (%ld in dec.)\n", pmi->dx, pmi->dx);
  12444. Print(" dy %lx (%ld in dec.)\n", pmi->dx, pmi->dx);
  12445. Print(" mouseData %lx (%ld in dec.)\n", pmi->mouseData, pmi->mouseData);
  12446. Print(" dwFlags %lx (%s)\n", pmi->dwFlags, GetFlags(GF_MI, pmi->dwFlags, NULL, TRUE));
  12447. Print(" time %lx\n", pmi->time);
  12448. Print(" dwExtraInfo %lx\n", pmi->dwExtraInfo);
  12449. }
  12450. break;
  12451. case INPUT_KEYBOARD:
  12452. {
  12453. KEYBDINPUT* pki = &input.ki;
  12454. const char* name;
  12455. Print("type: Keyboard Input(%x)\n", input.type);
  12456. //
  12457. // Print Vkey
  12458. //
  12459. Print(" wVk %lx", pki->wVk);
  12460. name = GetVKeyName(pki->wVk);
  12461. if (*name) {
  12462. Print(" (%s)\n", name);
  12463. } else {
  12464. Print("\n");
  12465. }
  12466. //
  12467. // Print scan code: if KEYEVENTF_UNICODE, it's UNICODE value.
  12468. //
  12469. if (pki->dwFlags & KEYEVENTF_UNICODE) {
  12470. Print(" UNICODE %lx\n", pki->wScan);
  12471. } else {
  12472. Print(" wScan %lx\n", pki->wScan);
  12473. }
  12474. //
  12475. // Print and decrypt dwFlags
  12476. //
  12477. Print(" dwFlags %lx (%s)\n", pki->dwFlags, GetFlags(GF_KI, pki->dwFlags, NULL, TRUE));
  12478. Print(" time %lx\n", pki->time);
  12479. Print(" dwExtraInfo %lx\n", pki->dwExtraInfo);
  12480. }
  12481. break;
  12482. case INPUT_HARDWARE:
  12483. Print("type: HardwareEvent(%x)\n", input.type);
  12484. Print(" uMsg %lx\n", input.hi.uMsg);
  12485. Print(" wParamH:wParamL %x:%x\n", input.hi.wParamH, input.hi.wParamL);
  12486. break;
  12487. default:
  12488. Print("Invalid type information(0x%lx)\n", input.type);
  12489. break;
  12490. }
  12491. return TRUE;
  12492. }
  12493. /************************************************************************\
  12494. * Procedure: Iwm
  12495. *
  12496. * Decrypt window message number
  12497. *
  12498. * 09/??/98 Hiroyama Created
  12499. *
  12500. \************************************************************************/
  12501. BOOL IwmWorker(DWORD opts, LPSTR pszName, BOOL fInternalToo)
  12502. {
  12503. int len = strlen(pszName);
  12504. UNREFERENCED_PARAMETER(opts);
  12505. if (!(opts & OFLAG(a)) && *pszName == 0) {
  12506. return FALSE;
  12507. }
  12508. if (len >= 3 && pszName[2] == '_' || (opts & OFLAG(a))) {
  12509. //
  12510. // Search by WM name.
  12511. //
  12512. int i;
  12513. int nFound = 0;
  12514. for (i = 0; i < ARRAY_SIZE(gaMsgs); ++i) {
  12515. if (((opts & OFLAG(a)) || _strnicmp(gaMsgs[i].pszMsg, pszName, len) == 0) && (!gaMsgs[i].fInternal || fInternalToo)) {
  12516. Print(" %04x %s\n", gaMsgs[i].msg, gaMsgs[i].pszMsg);
  12517. ++nFound;
  12518. }
  12519. }
  12520. if (nFound == 0) {
  12521. Print("Could not find it.\n");
  12522. }
  12523. } else {
  12524. //
  12525. // Search by WM value.
  12526. //
  12527. DWORD value = (DWORD)EvalExp(pszName);
  12528. int i;
  12529. for (i = 0; i < ARRAY_SIZE(gaMsgs); ++i) {
  12530. if (gaMsgs[i].msg == value && (!gaMsgs[i].fInternal || fInternalToo)) {
  12531. Print(" %04x %s\n", gaMsgs[i].msg, gaMsgs[i].pszMsg);
  12532. break;
  12533. }
  12534. }
  12535. }
  12536. return TRUE;
  12537. }
  12538. BOOL Iwm(DWORD opts, LPSTR pszName)
  12539. {
  12540. return IwmWorker(opts, pszName, FALSE);
  12541. }
  12542. BOOL I_wm(DWORD opts, LPSTR pszName)
  12543. {
  12544. return IwmWorker(opts, pszName, TRUE);
  12545. }
  12546. //
  12547. // Dump Dialog Template
  12548. //
  12549. //
  12550. PBYTE SkipSz(UTCHAR *lpsz, UTCHAR* lpszCopy, UINT len)
  12551. {
  12552. UTCHAR c;
  12553. UINT n = 0;
  12554. lpszCopy[len - 1] = 0;
  12555. move(c, (PTR)lpsz);
  12556. if (c == 0xFF) {
  12557. if (lpszCopy) {
  12558. *lpszCopy = 0;
  12559. }
  12560. return (PBYTE)lpsz + 4;
  12561. }
  12562. do {
  12563. move(c, (PTR)lpsz);
  12564. ++lpsz;
  12565. if (++n < len) {
  12566. if (lpszCopy) {
  12567. *lpszCopy ++ = c;
  12568. }
  12569. }
  12570. } while (c != 0);
  12571. return (PBYTE)lpsz;
  12572. }
  12573. #ifndef NextWordBoundary
  12574. #define NextWordBoundary(p) ((PBYTE)(p) + ((ULONG_PTR)(p) & 1))
  12575. #endif
  12576. #ifndef NextDWordBoundary
  12577. #define NextDWordBoundary(p) ((PBYTE)(p) + ((ULONG_PTR)(-(LONG_PTR)(p)) & 3))
  12578. #endif
  12579. PBYTE WordSkipSz(UTCHAR *lpsz, UTCHAR* lpszCopy, UINT len)
  12580. {
  12581. PBYTE pb = SkipSz(lpsz, lpszCopy, len);
  12582. return NextWordBoundary(pb);
  12583. }
  12584. PBYTE DWordSkipSz(UTCHAR *lpsz, UTCHAR* lpszCopy, UINT len)
  12585. {
  12586. PBYTE pb = SkipSz(lpsz, lpszCopy, len);
  12587. return NextDWordBoundary(pb);
  12588. }
  12589. LPCSTR GetCharSetName(BYTE charset)
  12590. {
  12591. return GetMaskedEnum(EI_CHARSETTYPE, charset, NULL);
  12592. }
  12593. VOID ParseDialogFont(LPWORD* lplpstr, LPDLGTEMPLATE2 lpdt)
  12594. {
  12595. LOGFONT LogFont;
  12596. short tmp;
  12597. int fontheight, fheight;
  12598. PSERVERINFO gpsi;
  12599. BOOL fDesktopCharset = FALSE;
  12600. WORD dmLogPixels;
  12601. //
  12602. // fheight = fontheight = (SHORT)(*((WORD *) *lplpstr)++);
  12603. //
  12604. move(tmp, (PTR)*lplpstr);
  12605. ++*lplpstr;
  12606. fontheight = fheight = tmp;
  12607. if (fontheight == 0x7FFF) {
  12608. // a 0x7FFF height is our special code meaning use the message box font
  12609. Print("\
  12610. Font System Font (Messagebox font)\n");
  12611. return;
  12612. }
  12613. //
  12614. // The dialog template contains a font description! Use it.
  12615. //
  12616. // Fill the LogFont with default values
  12617. RtlZeroMemory(&LogFont, sizeof(LOGFONT));
  12618. moveExpValue(&gpsi, VAR(gpsi));
  12619. move(dmLogPixels, (ULONG64)&gpsi->dmLogPixels);
  12620. LogFont.lfHeight = -MultDiv(fontheight, dmLogPixels, 72);
  12621. if (lpdt->wDlgVer) {
  12622. WORD w;
  12623. BYTE b;
  12624. //
  12625. // LogFont.lfWeight = *((WORD FAR *) *lplpstr)++;
  12626. //
  12627. move(w, (PTR)*lplpstr);
  12628. ++*lplpstr;
  12629. LogFont.lfWeight = w;
  12630. //
  12631. // LogFont.lfItalic = *((BYTE FAR *) *lplpstr)++;
  12632. //
  12633. move(b, (PTR)*lplpstr);
  12634. ++((BYTE*)*lplpstr);
  12635. LogFont.lfItalic = b;
  12636. //
  12637. // LogFont.lfCharSet = *((BYTE FAR *) *lplpstr)++;
  12638. //
  12639. move(b, (PTR)*lplpstr);
  12640. ++((BYTE*)*lplpstr);
  12641. LogFont.lfCharSet = b;
  12642. } else {
  12643. // DIALOG statement, which only has a facename.
  12644. // The new applications are not supposed to use DIALOG statement,
  12645. // they should use DIALOGEX instead.
  12646. LogFont.lfWeight = FW_BOLD;
  12647. LogFont.lfCharSet = 0; //(BYTE)GET_DESKTOP_CHARSET();
  12648. fDesktopCharset = TRUE;
  12649. }
  12650. *lplpstr = (WORD*)DWordSkipSz(*lplpstr, LogFont.lfFaceName, ARRAY_SIZE(LogFont.lfFaceName));
  12651. Print("\
  12652. Font %dpt (%d), Weight: %d, %s Italic, %s,\n\
  12653. \"%ls\"\n",
  12654. fontheight, LogFont.lfHeight,
  12655. LogFont.lfWeight,
  12656. LogFont.lfItalic ? "" : "Not",
  12657. fDesktopCharset ? "DESKTOP_CHARSET" : GetCharSetName(LogFont.lfCharSet),
  12658. LogFont.lfFaceName);
  12659. }
  12660. LPCSTR GetCtrlStyle(WORD iClass, DWORD style)
  12661. {
  12662. WORD type = GF_WS;
  12663. switch (iClass) {
  12664. case ICLS_DIALOG:
  12665. type = GF_DS;
  12666. break;
  12667. case ICLS_STATIC:
  12668. type = GF_SS;
  12669. break;
  12670. case ICLS_EDIT:
  12671. type = GF_ES;
  12672. break;
  12673. case ICLS_BUTTON:
  12674. type = GF_BS;
  12675. break;
  12676. case ICLS_COMBOBOX:
  12677. type = GF_CBS;
  12678. break;
  12679. case ICLS_LISTBOX:
  12680. type = GF_LBS;
  12681. break;
  12682. case ICLS_SCROLLBAR:
  12683. type = GF_SBS;
  12684. break;
  12685. default:
  12686. break;
  12687. }
  12688. return GetFlags(type, style, NULL, FALSE);
  12689. }
  12690. BOOL I_ddlgt(DWORD opts, ULONG64 param1)
  12691. {
  12692. #if defined(_IA64_)
  12693. UNREFERENCED_PARAMETER(opts);
  12694. UNREFERENCED_PARAMETER(param1);
  12695. return FALSE;
  12696. #else
  12697. LPDLGTEMPLATE lpdt = (LPDLGTEMPLATE)FIXKP(param1);
  12698. DLGTEMPLATE2 dt;
  12699. LPDLGTEMPLATE2 lpdt2 = &dt;
  12700. BOOLEAN fNewDialogTemplate = FALSE;
  12701. UTCHAR* lpszMenu;
  12702. UTCHAR* lpszClass;
  12703. UTCHAR* lpszText;
  12704. UTCHAR* lpStr;
  12705. UTCHAR* lpCreateParams;
  12706. LPCSTR lpszIClassName;
  12707. WORD w;
  12708. DLGITEMTEMPLATE2 dit;
  12709. LPDLGITEMTEMPLATE lpdit;
  12710. UTCHAR menuName[64];
  12711. UTCHAR className[64];
  12712. UTCHAR text[64];
  12713. PSERVERINFO gpsi;
  12714. UNREFERENCED_PARAMETER(opts);
  12715. if (opts == 0 && param1 == 0) {
  12716. return FALSE;
  12717. }
  12718. move(w, (PTR)&((LPDLGTEMPLATE2)lpdt)->wSignature);
  12719. if (w == 0xffff) {
  12720. move(dt, (PTR)lpdt);
  12721. fNewDialogTemplate = TRUE;
  12722. } else {
  12723. dt.wDlgVer = 0;
  12724. dt.wSignature = 0;
  12725. dt.dwHelpID = 0;
  12726. move(dt.dwExStyle, (ULONG64)&lpdt->dwExtendedStyle);
  12727. move(dt.style, (ULONG64)&lpdt->style);
  12728. move(dt.cDlgItems, (ULONG64)&lpdt->cdit);
  12729. move(dt.x, (PTR)&lpdt->x);
  12730. move(dt.y, (PTR)&lpdt->y);
  12731. move(dt.cx, (PTR)&lpdt->cx);
  12732. move(dt.cy, (PTR)&lpdt->cy);
  12733. }
  12734. Print("DlgTemplate%s @ 0x%p version 0n%d\n", dt.wDlgVer ? "2" : "", lpdt, dt.wDlgVer);
  12735. if (!(opts & OFLAG(v))) {
  12736. Print("\
  12737. (%d, %d)-(%d,%d) [%d, %d](dec)\n\
  12738. Style %08lx ExStyle %08lx items 0x%x\n",
  12739. dt.x, dt.y, dt.x + dt.cx, dt.y + dt.cy, dt.cx, dt.cy,
  12740. dt.style, dt.dwExStyle, dt.cDlgItems);
  12741. } else {
  12742. Print("\
  12743. (%d,%d)-(%d,%d) [%d,%d] (dec) item: 0x%lx\n",
  12744. dt.x, dt.y, dt.x + dt.cx, dt.y + dt.cy,
  12745. dt.cx, dt.cy,
  12746. dt.cDlgItems);
  12747. Print("\
  12748. Style %08lx %s", dt.style, OFLAG(v) ? GetFlags(GF_DS, dt.style, NULL, FALSE) : "");
  12749. if ((dt.style & DS_SHELLFONT) == DS_SHELLFONT) {
  12750. Print(" [DS_SHELLFONT]");
  12751. }
  12752. Print("\n");
  12753. Print("\
  12754. ExStyle %08lx %s\n", dt.dwExStyle, GetFlags(GF_WSEX, dt.dwExStyle, NULL, FALSE));
  12755. }
  12756. // If there's a menu name string, load it.
  12757. lpszMenu = (LPWSTR)(((PBYTE)(lpdt)) + (dt.wDlgVer ? sizeof(DLGTEMPLATE2) : sizeof(DLGTEMPLATE)));
  12758. /*
  12759. * If the menu id is expressed as an ordinal and not a string,
  12760. * skip all 4 bytes to get to the class string.
  12761. */
  12762. move(w, (PTR)(WORD*)lpszMenu);
  12763. /*
  12764. * If there's a menu name string, load it.
  12765. */
  12766. if (w != 0) {
  12767. if (w == 0xffff) {
  12768. LPWORD lpwMenu = (LPWORD)((LPBYTE)lpszMenu + 2);
  12769. move(w, (PTR)lpwMenu);
  12770. Print("\
  12771. menu id %lx\n", w);
  12772. }
  12773. }
  12774. if (w == 0xFFFF) {
  12775. lpszClass = (LPWSTR)((LPBYTE)lpszMenu + 4);
  12776. } else {
  12777. lpszClass = (UTCHAR *)WordSkipSz(lpszMenu, menuName, ARRAY_SIZE(menuName));
  12778. Print("\
  12779. menu @ 0x%p \"%ls\"\n", lpszMenu, menuName);
  12780. }
  12781. //
  12782. // Class name
  12783. //
  12784. lpszText = (UTCHAR *)WordSkipSz(lpszClass, className, ARRAY_SIZE(className));
  12785. Print("\
  12786. class @ 0x%p \"%ls\"\n", lpszClass, className);
  12787. //
  12788. // Window text
  12789. //
  12790. lpStr = (UTCHAR *)WordSkipSz(lpszText, text, ARRAY_SIZE(text));
  12791. Print("\
  12792. text @ 0x%p \"%ls\"\n", lpszText, text);
  12793. //
  12794. // Font
  12795. //
  12796. if (dt.style & DS_SETFONT) {
  12797. ParseDialogFont(&lpStr, &dt);
  12798. }
  12799. lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(lpStr);
  12800. ///////////////////////////////////////////////////
  12801. // if "-r" option is not specified, bail out.
  12802. ///////////////////////////////////////////////////
  12803. if (!(opts & OFLAG(r))) {
  12804. return TRUE;
  12805. }
  12806. Print("\n");
  12807. /*
  12808. * Loop through the dialog controls, doing a CreateWindowEx() for each of
  12809. * them.
  12810. */
  12811. while (dt.cDlgItems-- != 0) {
  12812. WORD iClass = 0;
  12813. //
  12814. // Retrieve basic information.
  12815. //
  12816. if (dt.wDlgVer) {
  12817. move(dit, (PTR)lpdit);
  12818. } else {
  12819. dit.dwHelpID = 0;
  12820. move(dit.dwExStyle, (PTR)&lpdit->dwExtendedStyle);
  12821. move(dit.style, (PTR)&lpdit->style);
  12822. move(dit.x, (PTR)&lpdit->x);
  12823. move(dit.y, (PTR)&lpdit->y);
  12824. move(dit.cx, (PTR)&lpdit->cx);
  12825. move(dit.cy, (PTR)&lpdit->cy);
  12826. move(w, (PTR)&lpdit->id);
  12827. dit.dwID = w;
  12828. }
  12829. Print("\
  12830. #ID:0x%04x @ 0x%p HelpID:0x%04x (0n%d, 0n%d)-(0n%d, 0n%d) [0n%d, 0n%d]\n",
  12831. dit.dwID,
  12832. lpdit,
  12833. dit.dwHelpID,
  12834. dit.x, dit.y, dit.x + dit.cx, dit.y + dit.cy,
  12835. dit.cx, dit.cy);
  12836. //
  12837. // Skip DLGITEMTEMPLATE or DLGITEMTEMPLATE2
  12838. //
  12839. lpszClass = (LPWSTR)(((PBYTE)(lpdit)) + (dt.wDlgVer ? sizeof(DLGITEMTEMPLATE2) : sizeof(DLGITEMTEMPLATE)));
  12840. /*
  12841. * If the first WORD is 0xFFFF the second word is the encoded class name index.
  12842. * Use it to look up the class name string.
  12843. */
  12844. move(w, (PTR)lpszClass);
  12845. if (w == 0xFFFF) {
  12846. WORD wAtom;
  12847. lpszText = lpszClass + 2;
  12848. #ifdef ORG
  12849. lpszClass = (LPWSTR)(gpsi->atomSysClass[*(((LPWORD)lpszClass)+1) & ~CODEBIT]);
  12850. #endif
  12851. moveExpValue(&gpsi, VAR(gpsi));
  12852. move(iClass, (PTR)lpszClass + 1);
  12853. iClass &= ~CODEBIT;
  12854. if (*(lpszIClassName = GetMaskedEnum(EI_CLSTYPE, iClass, NULL)) == '\0') {
  12855. lpszIClassName = NULL;
  12856. }
  12857. move(wAtom, (PTR)&gpsi->atomSysClass[iClass]);
  12858. swprintf(className, L"#%lx", wAtom);
  12859. } else {
  12860. lpszText = (UTCHAR*)SkipSz(lpszClass, className, ARRAY_SIZE(className));
  12861. lpszIClassName = NULL;
  12862. }
  12863. Print("\
  12864. class @ 0x%p \"%ls\" ", lpszClass, className);
  12865. if (lpszIClassName) {
  12866. Print("= %s", lpszIClassName);
  12867. }
  12868. Print("\n");
  12869. lpszText = (UTCHAR*)NextWordBoundary(lpszText); // UINT align lpszText
  12870. // Our code in InternalCreateDialog does this.
  12871. // dit.dwExStyle |= WS_EX_NOPARENTNOTIFY;
  12872. //
  12873. /*
  12874. * Get pointer to additional data. lpszText can point to an encoded
  12875. * ordinal number for some controls (e.g. static icon control) so
  12876. * we check for that here.
  12877. */
  12878. move(w, (PTR)lpszText);
  12879. if (w == 0xFFFF) {
  12880. swprintf(text, L"#%lx", w);
  12881. lpCreateParams = (LPWSTR)((PBYTE)lpszText + 4);
  12882. } else {
  12883. lpCreateParams = (LPWSTR)(PBYTE)WordSkipSz(lpszText, text, ARRAY_SIZE(text));
  12884. }
  12885. Print("\
  12886. text @ 0x%p \"%ls\"\n", lpszText, text);
  12887. Print("\
  12888. style %08lx %s%s", dit.style,
  12889. (opts & OFLAG(v)) ? GetCtrlStyle(iClass, dit.style) : "",
  12890. (opts & OFLAG(v)) ? "\n" : "");
  12891. Print("\
  12892. ExStyle %08lx %s\n", dit.dwExStyle, (opts & OFLAG(v)) ? GetFlags(GF_WSEX, dit.dwExStyle, NULL, FALSE) : "");
  12893. /*
  12894. * Point at next item template
  12895. */
  12896. move(w, (PTR)lpCreateParams);
  12897. lpdit = (LPDLGITEMTEMPLATE)NextDWordBoundary(
  12898. (LPBYTE)(lpCreateParams + 1) + w);
  12899. Print("\n");
  12900. }
  12901. return TRUE;
  12902. #endif // _IA64_
  12903. }
  12904. #ifndef KERNEL
  12905. BOOL Idimedpi(DWORD opts, ULONG64 param1)
  12906. {
  12907. PTR pImeDpi; // IMEDPI
  12908. UNREFERENCED_PARAMETER(opts);
  12909. if (param1 == 0) {
  12910. pImeDpi = GetGlobalPointer("imm32!gpImeDpi");
  12911. }
  12912. else {
  12913. pImeDpi = FIXKP(param1);
  12914. }
  12915. while (pImeDpi) {
  12916. WCHAR wsz[80];
  12917. InitTypeRead(pImeDpi, imm32!IMEDPI);
  12918. Print("IMEDPI @ 0x%p hInst: 0x%p cLock: 0n%3d", pImeDpi, ReadField(hInst), (DWORD)ReadField(cLock));
  12919. CopyUnicodeString(pImeDpi, "imm32!IMEDPI", "wszUIClass", wsz, ARRAY_SIZE(wsz));
  12920. Print(" CodePage:%4d UI Class: \"%S\"\n", (DWORD)ReadField(dwCodePage), wsz);
  12921. if (opts & OFLAG(i)) {
  12922. DWORD dwOffset;
  12923. GetFieldOffset("imm32!IMEDPI", "ImeInfo", &dwOffset);
  12924. Print(" ImeInfo: @ 0x%p dwPrivateDataSize: %08x\n", dwOffset,
  12925. (DWORD)ReadField(ImeInfo.dwPrivateDataSize));
  12926. }
  12927. if (opts & OFLAG(v)) {
  12928. dso("imm32!IMEDPI", pImeDpi, 0);
  12929. }
  12930. Print("\n");
  12931. pImeDpi = ReadField(pNext);
  12932. }
  12933. return TRUE;
  12934. }
  12935. #endif // !KERNEL
  12936. /************************************************************************\
  12937. *
  12938. * Procedure: CopyUnicodeString
  12939. *
  12940. * 06/05/00 JStall Created (yeah, baby!)
  12941. *
  12942. \************************************************************************/
  12943. BOOL
  12944. CopyUnicodeString(
  12945. IN PTR pData,
  12946. IN char * pszStructName,
  12947. IN char * pszFieldName,
  12948. OUT WCHAR *pszDest,
  12949. IN ULONG cchMax)
  12950. {
  12951. ULONG Length;
  12952. PTR Buffer;
  12953. char szLengthName[256];
  12954. char szBufferName[256];
  12955. if (pData == 0) {
  12956. pszDest[0] = '\0';
  12957. return FALSE;
  12958. }
  12959. strcpy(szLengthName, pszFieldName);
  12960. strcat(szLengthName, ".Length");
  12961. strcpy(szBufferName, pszFieldName);
  12962. strcat(szBufferName, ".Buffer");
  12963. if (GetFieldValue(pData, pszStructName, szLengthName, Length) ||
  12964. GetFieldValue(pData, pszStructName, szBufferName, Buffer)) {
  12965. wcscpy(pszDest, L"<< Can't get name >>");
  12966. return FALSE;
  12967. }
  12968. if (Buffer == 0) {
  12969. wcscpy(pszDest, L"<null>");
  12970. } else {
  12971. ULONG cbText;
  12972. cbText = min(cchMax, Length + sizeof(WCHAR));
  12973. if (!(tryMoveBlock(pszDest, FIXKP(Buffer), cbText))) {
  12974. wcscpy(pszDest, L"<< Can't get value >>");
  12975. return FALSE;
  12976. }
  12977. }
  12978. return TRUE;
  12979. }
  12980. /************************************************************************\
  12981. *
  12982. * Procedure: Idhard
  12983. *
  12984. * 06/05/00 JStall Created (yeah, baby!)
  12985. *
  12986. \************************************************************************/
  12987. #ifdef KERNEL
  12988. BOOL Idhard(
  12989. VOID)
  12990. {
  12991. PTR phei, pheiNext, pthread;
  12992. WCHAR szText[256], szCaption[256];
  12993. int cErrors = 0;
  12994. DWORD dwClientId;
  12995. Print("Win32k hard error list:\n");
  12996. phei = GetGlobalPointer("winsrv!gphiList");
  12997. while (phei != 0) {
  12998. InitTypeRead(phei, winsrv!HARDERRORINFO);
  12999. pheiNext = ReadField(phiNext);
  13000. pthread = ReadField(pthread);
  13001. CopyUnicodeString(phei, "winsrv!HARDERRORINFO", "usCaption", szCaption, ARRAY_SIZE(szCaption));
  13002. CopyUnicodeString(phei, "winsrv!HARDERRORINFO", "usText", szText, ARRAY_SIZE(szText));
  13003. InitTypeRead(pthread, csrsrv!CSR_THREAD);
  13004. dwClientId = HandleToUlong((HANDLE) ReadField(ClientId.UniqueThread));
  13005. Print("0x%p: tid:0x%x '%S'- '%S'\n", phei, dwClientId, szCaption, szText);
  13006. phei = pheiNext;
  13007. cErrors++;
  13008. }
  13009. Print("%d queued errors\n", cErrors);
  13010. return TRUE;
  13011. }
  13012. typedef struct {
  13013. PTR thread;
  13014. ULONG64 time;
  13015. } KERNELTIME;
  13016. ULONG CpuHogCallback(
  13017. PFIELD_INFO NextProcess,
  13018. PVOID Context);
  13019. BOOL Ihogs(
  13020. DWORD dwOpts,
  13021. ULONG64 ul64Count)
  13022. {
  13023. KERNELTIME *pTimes;
  13024. TIME_FIELDS Times;
  13025. WCHAR appname[64];
  13026. PTR ProcessHead, NextProcess, Process;
  13027. THREAD_DUMP_CONTEXT TDC;
  13028. DWORD dwCount = (DWORD)ul64Count;
  13029. LARGE_INTEGER RunTime;
  13030. UNREFERENCED_PARAMETER(dwOpts);
  13031. // Default to dumping the top 10 threads
  13032. if (dwCount == 0) {
  13033. dwCount = 10;
  13034. }
  13035. pTimes = LocalAlloc(LPTR, dwCount * sizeof(KERNELTIME));
  13036. if (!pTimes) {
  13037. Print("Couldn't allocate memory for KERNELTIME buffer\n");
  13038. return TRUE;
  13039. }
  13040. ProcessHead = EvalExp("PsActiveProcessHead");
  13041. if (!ProcessHead) {
  13042. Print("Unable to get value of PsActiveProcessHead\n");
  13043. return FALSE;
  13044. }
  13045. if (GetFieldValue(ProcessHead, "nt!LIST_ENTRY", "Flink", NextProcess)) {
  13046. Print("Unable to get value of PsActiveProcessHead\n");
  13047. return FALSE;
  13048. }
  13049. if (NextProcess == 0) {
  13050. Print("PsActiveProcessHead->Flink is NULL!\n");
  13051. return FALSE;
  13052. }
  13053. TDC.opts = dwCount;
  13054. TDC.ThreadToDump = (ULONG_PTR)pTimes;
  13055. ListType("nt!EPROCESS", NextProcess, 1, "ActiveProcessLinks.Flink", &TDC, CpuHogCallback);
  13056. for (--dwCount; dwCount != -1; --dwCount) {
  13057. GetFieldValue(pTimes[dwCount].thread, "nt!ETHREAD", "ThreadsProcess", Process);
  13058. GetProcessName(Process, appname);
  13059. RunTime.QuadPart = pTimes[dwCount].time;
  13060. RtlTimeToElapsedTimeFields ( &RunTime, &Times);
  13061. Print("%d: thread %#p - %ws ==> %3ld:%02ld:%02ld.%04ld\n",TDC.opts - dwCount, pTimes[dwCount].thread, appname,
  13062. Times.Hour,
  13063. Times.Minute,
  13064. Times.Second,
  13065. Times.Milliseconds);
  13066. }
  13067. LocalFree(pTimes);
  13068. return TRUE;
  13069. }
  13070. VOID InsertTime(
  13071. KERNELTIME *pTimes,
  13072. DWORD cnt,
  13073. PTR thread,
  13074. ULONG64 time)
  13075. {
  13076. int i = cnt - 1;
  13077. for (; i >= 0; --i) {
  13078. if (time > pTimes[i].time) {
  13079. RtlMoveMemory(&pTimes[0], &pTimes[i], cnt);
  13080. pTimes[i].time = time;
  13081. pTimes[i].thread = thread;
  13082. break;
  13083. }
  13084. }
  13085. }
  13086. ULONG CpuHogCallback(
  13087. PFIELD_INFO NextProcess,
  13088. PVOID Context)
  13089. {
  13090. THREAD_DUMP_CONTEXT *pTDC = (THREAD_DUMP_CONTEXT *)Context;
  13091. KERNELTIME *pTimes = (KERNELTIME*)pTDC->ThreadToDump;
  13092. DWORD dwOffset;
  13093. ULONG64 thread, head, KernelTime;
  13094. TIME_FIELDS Times;
  13095. LARGE_INTEGER RunTime;
  13096. KDDEBUGGER_DATA64 KdDebuggerData;
  13097. static int counter = 0;
  13098. ULONG TimeIncrement = GetUlongFromAddress((GetDebuggerData(KDBG_TAG,
  13099. &KdDebuggerData, sizeof(KdDebuggerData)),
  13100. KdDebuggerData.KeTimeIncrement));
  13101. GetFieldOffset("nt!EPROCESS", "ThreadListHead", &dwOffset);
  13102. head = NextProcess->address + dwOffset;
  13103. ReadPointer(head, &thread);
  13104. GetFieldOffset("nt!ETHREAD", "ThreadListEntry", &dwOffset);
  13105. do {
  13106. ShowProgress();
  13107. thread -= dwOffset;
  13108. GetFieldValue(thread, "nt!ETHREAD", "Tcb.KernelTime", KernelTime);
  13109. RunTime.QuadPart = UInt32x32To64(KernelTime, TimeIncrement);
  13110. RtlTimeToElapsedTimeFields ( &RunTime, &Times);
  13111. InsertTime(pTimes, pTDC->opts, thread, RunTime.QuadPart);
  13112. // Get next thread in the list
  13113. ReadPointer(thread + dwOffset, &thread);
  13114. } SAFEWHILE (thread != head);
  13115. // Erase any symbol that might still be showing
  13116. Print("\r");
  13117. // Did we exit the loop because the user hit ^C?
  13118. if (thread != head) {
  13119. // Yes, so return TRUE to stop further callbacks
  13120. return TRUE;
  13121. }
  13122. return FALSE;
  13123. }
  13124. #endif // KERNEL
  13125. #ifdef KERNEL
  13126. /************************************************************************\
  13127. * Procedure: Idhid
  13128. *
  13129. * Dumps HID (Raw Input, aka Generic Input) information
  13130. *
  13131. * ??/??/2000 Hiroyama Created
  13132. \************************************************************************/
  13133. VOID DumpProcessHidRequest(
  13134. PTR pHidRequest)
  13135. {
  13136. _InitTypeRead(pHidRequest, SYM(tagPROCESS_HID_REQUEST));
  13137. Print(" (0x%x, 0x%x) @ 0x%p -> 0x%p pwnd: 0x%p sink: 0x%x\n",
  13138. (UINT)ReadField(usUsagePage), (UINT)ReadField(usUsage),
  13139. pHidRequest,
  13140. ReadField(pPORequest),
  13141. ReadField(spwndTarget),
  13142. (UINT)ReadField(fSinkable));
  13143. }
  13144. ULONG dhidCallback(
  13145. PTR ppi,
  13146. PVOID param)
  13147. {
  13148. DWORD opts = PtrToUlong(param);
  13149. PTR pHidTable;
  13150. ULONG64 maskRawInput;
  13151. static ULONG iSeq;
  13152. ShowProgress();
  13153. if (GetFieldValue(ppi, SYM(PROCESSINFO), "pHidTable", pHidTable)) {
  13154. Print("Cannot get pHidTable from ppi=%p\n", ppi);
  13155. return FALSE;
  13156. }
  13157. GetFieldValue(ppi, SYM(PROCESSINFO), "dwRawInputMask", maskRawInput);
  13158. if (pHidTable || maskRawInput) {
  13159. ULONG offset;
  13160. PTR pHidRequest;
  13161. PTR pStart;
  13162. Print(" \nHID for ppi: %p %s\n", ppi, ProcessName(ppi));
  13163. _InitTypeRead(pHidTable, SYM(tagPROCESS_HID_TABLE));
  13164. Print(" PROCESS_HID_TABLE @ 0x%p (sink: 0n%d)\n", pHidTable, (int)ReadField(nSinks));
  13165. Print(" Kbd: raw:0x%x sink:0x%x noleg:0x%x pwnd: 0x%p nohotkey:0x%x\n",
  13166. (DWORD)ReadField(fRawKeyboard), (DWORD)ReadField(fRawKeyboardSink), (DWORD)ReadField(fNoLegacyKeyboard),
  13167. ReadField(spwndTargetKbd),
  13168. (DWORD)ReadField(fNoHotKeys));
  13169. Print(" Mou: raw:%x sink:%x noleg:%x pwnd: %p capture:%x\n",
  13170. (DWORD)ReadField(fRawMouse), (DWORD)ReadField(fRawMouseSink), (DWORD)ReadField(fNoLegacyMouse),
  13171. ReadField(spwndTargetMouse), (DWORD)ReadField(fCaptureMouse));
  13172. if (opts & OFLAG(v)) {
  13173. dso(SYM(PROCESS_HID_TABLE), pHidTable, DBG_DUMP_RECUR_LEVEL(1));
  13174. }
  13175. GetFieldOffset(SYM(tagPROCESS_HID_TABLE), "InclusionList.Flink", &offset);
  13176. pStart = pHidTable + offset;
  13177. GetFieldValue(pHidTable, SYM(tagPROCESS_HID_TABLE), "InclusionList.Flink", pHidRequest);
  13178. if (pHidRequest == pStart) {
  13179. Print(" No Inclusion List\n");
  13180. } else {
  13181. Print(" Inclusion List:\n");
  13182. SAFEWHILE (pHidRequest && pHidRequest != pStart) {
  13183. DumpProcessHidRequest(pHidRequest);
  13184. /*
  13185. * N.b. DumpProcessHidRequest() sets the InitTypeRead
  13186. */
  13187. pHidRequest = ReadField(link.Flink);
  13188. }
  13189. }
  13190. GetFieldOffset(SYM(tagPROCESS_HID_TABLE), "UsagePageList.Flink", &offset);
  13191. pStart = pHidTable + offset;
  13192. GetFieldValue(pHidTable, SYM(tagPROCESS_HID_TABLE), "UsagePageList.Flink", pHidRequest);
  13193. if (pHidRequest != pStart) {
  13194. Print(" UsagePageOnly List\n");
  13195. SAFEWHILE (pHidRequest && pHidRequest != pStart) {
  13196. DumpProcessHidRequest(pHidRequest);
  13197. pHidRequest = ReadField(link.Flink);
  13198. }
  13199. } else {
  13200. Print(" No UsagePageOnly List\n");
  13201. }
  13202. GetFieldOffset(SYM(tagPROCESS_HID_TABLE), "ExclusionList.Flink", &offset);
  13203. pStart = pHidTable + offset;
  13204. GetFieldValue(pHidTable, SYM(tagPROCESS_HID_TABLE), "ExclusionList.Flink", pHidRequest);
  13205. if (pHidRequest != pStart) {
  13206. Print(" Exclusion List\n");
  13207. SAFEWHILE (pHidRequest && pHidRequest != pStart) {
  13208. DumpProcessHidRequest(pHidRequest);
  13209. if (ReadField(spwndTarget) != 0) {
  13210. Print(" spwndTarget is not NULL!\n");
  13211. }
  13212. pHidRequest = ReadField(link.Flink);
  13213. }
  13214. } else {
  13215. Print(" No Exclusion List\n");
  13216. }
  13217. }
  13218. return FALSE;
  13219. }
  13220. BOOL Idhid(DWORD opts, ULONG64 param1)
  13221. {
  13222. try {
  13223. PTR pHidRequest;
  13224. PTR pStart;
  13225. pStart = GetGlobalMemberAddress(SYM(gHidRequestTable), SYM(tagHID_REQUEST_TABLE), "TLCInfoList.Flink");
  13226. pHidRequest = GetPointer(pStart);
  13227. if (pHidRequest == NULL_PTR) {
  13228. Print("pHidRequest is NULL ???\n");
  13229. return TRUE;
  13230. }
  13231. if (pHidRequest != pStart) {
  13232. Print("HID_TLC_INFO:\n");
  13233. }
  13234. SAFEWHILE (pHidRequest && pHidRequest != pStart) {
  13235. _InitTypeRead(pHidRequest, SYM(tagHID_TLC_INFO));
  13236. Print(" (0x%x, 0x%x) @ 0x%p\n",
  13237. (UINT)(USHORT)ReadField(usUsagePage), (UINT)(USHORT)ReadField(usUsage),
  13238. pHidRequest);
  13239. Print(" [cDevices:0x%x] [DirectReq:0x%x] [UsagePReq:0x%x] [ExclReq:0x%x] [ExclOrphaned:0x%x]\n",
  13240. (UINT)ReadField(cDevices),
  13241. (UINT)ReadField(cDirectRequest),
  13242. (UINT)ReadField(cUsagePageRequest),
  13243. (UINT)ReadField(cExcludeRequest),
  13244. (UINT)ReadField(cExcludeOrphaned));
  13245. pHidRequest = ReadField(link.Flink);
  13246. }
  13247. pStart = GetGlobalMemberAddress(SYM(gHidRequestTable), SYM(tagHID_REQUEST_TABLE), "UsagePageList.Flink");
  13248. pHidRequest = GetPointer(pStart);
  13249. if (pHidRequest != pStart) {
  13250. Print("HID_PAGEONLY_REQUEST:\n");
  13251. }
  13252. SAFEWHILE (pHidRequest && pHidRequest != pStart) {
  13253. _InitTypeRead(pHidRequest, SYM(tagHID_PAGEONLY_REQUEST));
  13254. Print(" (0x%x, 0) @ 0x%p cRefCount: 0x%x\n",
  13255. (UINT)(USHORT)ReadField(usUsagePage),
  13256. pHidRequest,
  13257. (UINT)ReadField(cRefCount));
  13258. pHidRequest = ReadField(link.Flink);
  13259. }
  13260. if (opts & OFLAG(p)) {
  13261. if (param1) {
  13262. dhidCallback(param1, ULongToPtr(opts));
  13263. } else {
  13264. ForEachPpi(dhidCallback, ULongToPtr(opts));
  13265. }
  13266. } else {
  13267. PTR gpqForeground = GetGlobalPointer(SYM(gpqForeground));
  13268. if (gpqForeground == NULL_PTR) {
  13269. Print("gpqForeground is NULL\n");
  13270. } else {
  13271. PTR ptiMouse = NULL_PTR;
  13272. PTR spwndMouse;
  13273. GetFieldValue(gpqForeground, SYM(tagQ), "spwndCapture", spwndMouse);
  13274. if (spwndMouse) {
  13275. GetFieldValue(spwndMouse, SYM(tagWND), "head.pti", ptiMouse);
  13276. } else {
  13277. GetFieldValue(gpqForeground, SYM(tagQ), "ptiMouse", ptiMouse);
  13278. }
  13279. if (ptiMouse == NULL_PTR) {
  13280. Print("ptiMouse is NULL.\n");
  13281. } else {
  13282. PTR ppi;
  13283. GetFieldValue(ptiMouse, SYM(tagTHREADINFO), "ppi", ppi);
  13284. Print("\nForeground ppi: %p\n", ppi);
  13285. dhidCallback(ppi, ULongToPtr(opts));
  13286. }
  13287. }
  13288. }
  13289. pStart = EvalExp(VAR(gHidCounters));
  13290. if (pStart) {
  13291. Print(" \nHID counter @ 0x%p\n", pStart);
  13292. dso(SYM(tagHID_COUNTERS), pStart, 0);
  13293. }
  13294. if (IsChk()) {
  13295. pStart = EvalExp(VAR(gHidAllocCounters));
  13296. if (pStart) {
  13297. Print(" \nDebug Allocate counter @ 0x%p\n", pStart);
  13298. dso(SYM(HidAllocateCounter), pStart, 0);
  13299. Print("gcAllocHidTotal: 0x%x\n", (UINT)GetGlobalPointer(VAR(gcAllocHidTotal)));
  13300. }
  13301. }
  13302. } except (CONTINUE) {
  13303. Print("AV!\n");
  13304. }
  13305. return TRUE;
  13306. }
  13307. #endif // KERNEL
  13308. BOOL Ipred(DWORD opts, ULONG64 param1)
  13309. {
  13310. UINT i = 0;
  13311. UNREFERENCED_PARAMETER(opts);
  13312. while (i < 64) {
  13313. Print("%cp%-2d ", param1 & (1 << i) ? '*' : ' ', i);
  13314. if (++i % 8 == 0) {
  13315. Print("\n");
  13316. }
  13317. }
  13318. return TRUE;
  13319. }
  13320. #ifdef KERNEL
  13321. #ifdef TRACK_PNP_NOTIFICATION
  13322. /************************************************************************\
  13323. * Procedure: Idhnr
  13324. *
  13325. * Dumps PnP notification record
  13326. *
  13327. * 09/19/2000 Hiroyama Created
  13328. *
  13329. \************************************************************************/
  13330. /*
  13331. * Do not call GetDeviceType twice within a sequence point!
  13332. * This function uses a static variable for the return value.
  13333. */
  13334. const char* GetDeviceType(ULONG64 type)
  13335. {
  13336. static const char* devicetype[] = {
  13337. "mouse",
  13338. "keyboard",
  13339. "hid",
  13340. };
  13341. if (type >= ARRAY_SIZE(devicetype)) {
  13342. static char buf[32];
  13343. sprintf(buf, "<unknown type %x>", (DWORD)type);
  13344. return buf;
  13345. }
  13346. return devicetype[type];
  13347. }
  13348. BOOL Idhnr(DWORD opts, ULONG64 param1)
  13349. {
  13350. try {
  13351. PTR p, pStart;
  13352. PTR pTarget = 0;
  13353. PTR pTargetDeviceInfo = 0;
  13354. UCHAR szPathNameDevInfo[80] = "";
  13355. UINT iTarget = 0;
  13356. UINT iStartOffset = 0;
  13357. ULONG cbSize;
  13358. DWORD dwArraySize;
  13359. ULONG offsetPathName;
  13360. UINT iSeq, i;
  13361. GetFieldOffset(SYM(PNP_NOTIFICATION_RECORD), "szPathName", &offsetPathName);
  13362. if (offsetPathName == 0) {
  13363. Print("can't get offset to szPathName, make sure TRACK_PNP_NOTIFICATION is turned on.\n");
  13364. return TRUE;
  13365. }
  13366. if (opts & OFLAG(d)) {
  13367. if ((pTargetDeviceInfo = param1) == 0) {
  13368. return FALSE;
  13369. }
  13370. } else if (opts & OFLAG(p)) {
  13371. p = pTarget = param1;
  13372. if (pTarget) {
  13373. goto PrintHeader;
  13374. }
  13375. } else if (param1) {
  13376. iTarget = (UINT)param1;
  13377. opts |= OFLAG(v) | OFLAG(n);
  13378. }
  13379. if ((p = pStart = GetGlobalPointer(VAR(gpPnpNotificationRecord))) == 0) {
  13380. Print("can't get gPnpNotificationRecord\n");
  13381. return TRUE;
  13382. }
  13383. if ((cbSize = GetTypeSize(SYM(PNP_NOTIFICATION_RECORD))) == 0) {
  13384. Print("can't get sizeof(PNP_NOTIFICATION_RECORD)\n");
  13385. return TRUE;
  13386. }
  13387. moveExpValue(&dwArraySize, VAR(gdwPnpNotificationRecSize));
  13388. if (dwArraySize == 0) {
  13389. Print("can't get gdwPnpNotificationRecSize\n");
  13390. return TRUE;
  13391. }
  13392. /*
  13393. * Firstly, find out the lowest iSeq.
  13394. */
  13395. iSeq = UINT_MAX;
  13396. for (i = 0; !IsCtrlCHit() && i < dwArraySize; ++i) {
  13397. UINT iSeqTmp;
  13398. _InitTypeRead(p, SYM(PNP_NOTIFICATION_RECORD));
  13399. iSeqTmp = (UINT)ReadField(iSeq);
  13400. ShowProgress();
  13401. if (iSeqTmp < iSeq && iSeqTmp != 0) {
  13402. iSeq = iSeqTmp;
  13403. iStartOffset = i;
  13404. }
  13405. /*
  13406. * For device name search, remember the path name
  13407. * that matches to pDeviceInfo.
  13408. */
  13409. if (pTargetDeviceInfo && (opts & OFLAG(m)) &&
  13410. szPathNameDevInfo[0] == 0 && ReadField(pDeviceInfo) == pTargetDeviceInfo) {
  13411. move(szPathNameDevInfo, p + offsetPathName);
  13412. Print("\r\"%s\"\n", szPathNameDevInfo);
  13413. }
  13414. p = p + cbSize;
  13415. }
  13416. Print("\r");
  13417. /*
  13418. * Secondly, dump the records.
  13419. */
  13420. PrintHeader:
  13421. Print(" seq %-*c%-20s %-*s %-*s code\n",
  13422. opts & OFLAG(p) ? PtrWidth() + 2 : 1, ' ',
  13423. "type", PtrWidth(), "pDevInfo", PtrWidth(), "thread");
  13424. if (pTarget) {
  13425. goto PrintOne;
  13426. }
  13427. for (i = 0; !IsCtrlCHit() && i < dwArraySize; ++i) {
  13428. UINT iOffset = (i + iStartOffset) % dwArraySize;
  13429. BOOLEAN fDump = FALSE;
  13430. p = pStart + cbSize * iOffset;
  13431. PrintOne:
  13432. _InitTypeRead(p, SYM(PNP_NOTIFICATION_RECORD));
  13433. iSeq = (UINT)ReadField(iSeq);
  13434. if (pTargetDeviceInfo) {
  13435. if (iSeq) {
  13436. if (ReadField(pDeviceInfo) == pTargetDeviceInfo) {
  13437. fDump = TRUE;
  13438. } else if ((opts & OFLAG(m)) && szPathNameDevInfo[0]) {
  13439. /*
  13440. * Try to dump the deviceinfo of the same device path.
  13441. */
  13442. UCHAR szPathName[ARRAY_SIZE(szPathNameDevInfo)];
  13443. move(szPathName, p + offsetPathName);
  13444. if (strcmp(szPathName, szPathNameDevInfo) == 0) {
  13445. fDump = TRUE;
  13446. }
  13447. }
  13448. }
  13449. } else if (iTarget) {
  13450. if (iTarget == iSeq) {
  13451. /*
  13452. * Print just one by iSeq.
  13453. */
  13454. fDump = TRUE;
  13455. }
  13456. } else if (pTarget) {
  13457. /*
  13458. * Print just one record by address.
  13459. */
  13460. fDump = TRUE;
  13461. } else if (iSeq) {
  13462. /*
  13463. * Dump all valid records.
  13464. */
  13465. fDump = TRUE;
  13466. }
  13467. if (fDump) {
  13468. UINT type = (UINT)ReadField(type);
  13469. PTR pDeviceInfo = ReadField(pDeviceInfo);
  13470. UCHAR szPathName[80];
  13471. ULONG64 NotificationCode = ReadField(NotificationCode);
  13472. PTR pThread = ReadField(pKThread);
  13473. static const char* symbols[] = {
  13474. "CLASSNOTIFY",
  13475. "CREATEDEVICEINFO",
  13476. "FREEDEVICEINFO",
  13477. "PROCESSDEVICECHANGES",
  13478. "REQUESTDEVICECHANGE",
  13479. "DEVICENOTIFY",
  13480. "FREE_DEFERRED",
  13481. "CLOSEDEVICE",
  13482. "DEVNOTIFY_UNLISTED",
  13483. "UNREGISTER_NOTIFY",
  13484. "UNREG_REMOTE_CANCEL",
  13485. };
  13486. const char* name;
  13487. if (type < ARRAY_SIZE(symbols)) {
  13488. name = symbols[type];
  13489. } else {
  13490. name = "<unknown>";
  13491. }
  13492. if (opts & OFLAG(p)) {
  13493. Print("[%04x] %p %x %-20s %08p %p ", iSeq, p, type, name, pDeviceInfo, pThread);
  13494. } else {
  13495. Print("[%04x] %x %-20s %08p %p ", iSeq, type, name, pDeviceInfo, pThread);
  13496. }
  13497. switch (type) {
  13498. case PNP_NTF_DEVICENOTIFY:
  13499. case PNP_NTF_REQUESTDEVICECHANGE:
  13500. case PNP_NTF_FREEDEVICEINFO:
  13501. case PNP_NTF_FREEDEVICEINFO_DEFERRED:
  13502. case PNP_NTF_CLOSEDEVICE:
  13503. case PNP_NTF_DEVICENOTIFY_UNLISTED:
  13504. case PNP_NTF_UNREGISTER_NOTIFICATION:
  13505. case PNP_NTF_UNREGISTER_REMOTE_CANCELLED:
  13506. Print("%s\n", GetFlags(GF_DIAF, (DWORD)NotificationCode, NULL, TRUE));
  13507. break;
  13508. case PNP_NTF_PROCESSDEVICECHANGES:
  13509. case PNP_NTF_CREATEDEVICEINFO:
  13510. case PNP_NTF_CLASSNOTIFY:
  13511. Print("(%s)\n", GetDeviceType(NotificationCode));
  13512. break;
  13513. default:
  13514. Print("%08p\n", NotificationCode);
  13515. break;
  13516. }
  13517. if (opts & OFLAG(n)) {
  13518. move(szPathName, p + offsetPathName);
  13519. Print(" \"%s\"\n", szPathName);
  13520. }
  13521. if (opts & OFLAG(v)) {
  13522. ULONG offset;
  13523. GetFieldOffset(SYM(PNP_NOTIFICATION_RECORD), "type", &offset);
  13524. dso(SYM(PNP_NOTIFICATION_TYPE), p + offset, 0);
  13525. GetFieldOffset(SYM(PNP_NOTIFICATION_RECORD), "trace", &offset);
  13526. PrintStackTrace(p + offset, LOCKRECORD_STACK);
  13527. }
  13528. /*
  13529. * If it is a one-shot dump, exit the loop here.
  13530. */
  13531. if (iTarget || pTarget) {
  13532. break;
  13533. }
  13534. }
  13535. }
  13536. } except (CONTINUE) {
  13537. }
  13538. return TRUE;
  13539. }
  13540. #endif // TRACK_PNP_NOTIFICATION
  13541. #endif // KERNEL
  13542. BOOL Ichkfre(DWORD opts, ULONG64 param1)
  13543. {
  13544. UNREFERENCED_PARAMETER(param1);
  13545. if (opts & OFLAG(c)) {
  13546. gfChk = 1;
  13547. } else if (opts & OFLAG(f)) {
  13548. gfChk = 0;
  13549. } else if (opts & OFLAG(r)) {
  13550. gfChk = -1;
  13551. }
  13552. #ifdef KERNEL
  13553. Print("Win32k IsChk: %d\n", IsChk());
  13554. #else
  13555. Print("User32 IsChk: %d\n", IsChk());
  13556. #endif
  13557. return TRUE;
  13558. }
  13559. #ifdef KERNEL
  13560. /************************************************************************\
  13561. * Idghost
  13562. *
  13563. * Dump ghost thread associated information
  13564. *
  13565. * 12/05/2000 Created MSadek
  13566. \************************************************************************/
  13567. BOOL Idghost(
  13568. VOID)
  13569. {
  13570. PTR pGhost;
  13571. PTR pWnd;
  13572. PTR pWndGhost;
  13573. PTR pGhostThreadInfo;
  13574. PTR pEventScanGhosts;
  13575. PTR pCST;
  13576. LONG SignalGhost;
  13577. UINT i = 0;
  13578. UINT uID;
  13579. UINT uiThreadCount = 0;
  13580. // Dump ghost linked list data.
  13581. pGhost = GetGlobalPointer(SYM(gpghostFirst));
  13582. if (0 == pGhost) {
  13583. Print("Ghost global linked list is empty \n");
  13584. } else {
  13585. Print("Dumping ghost global linked list: \n");
  13586. do {
  13587. _InitTypeRead(pGhost, SYM(tagGHOST));
  13588. pWnd = ReadField(pwnd);
  13589. pWndGhost = ReadField(pwndGhost);
  13590. Print("Ghost entry #%i: \n\n", ++i);
  13591. Print("Ghosted window: %0lx\n", pWnd);
  13592. if (pWnd) {
  13593. Idw(0, pWnd);
  13594. }
  13595. Print("Ghost window: %0lx\n", pWndGhost);
  13596. if (pWndGhost) {
  13597. Idw(0, pWndGhost);
  13598. }
  13599. GetFieldValue(pGhost, SYM(tagGHOST), "pghostNext", pGhost);
  13600. } SAFEWHILE (pGhost);
  13601. }
  13602. // Dump ghost thread data.
  13603. pGhostThreadInfo = GetGlobalPointer(SYM(gptiGhost));
  13604. if (0 == pGhostThreadInfo) {
  13605. Print("No Ghost thread currently active\n");
  13606. } else {
  13607. Print("GhostThreadInfo 0x%p\n\n", pGhostThreadInfo);
  13608. Idti(0, pGhostThreadInfo);
  13609. }
  13610. // Dump the number of pending thread creation requests in CSR.
  13611. pCST = EvalExp(SYM(gCSTParam));
  13612. i = 0;
  13613. SAFEWHILE (i < CST_MAX_THREADS) {
  13614. uID = (UINT)GetArrayElement(pCST, SYM(CST_THREADS), "uID", i, "UINT");
  13615. if (CST_GHOST == uID) {
  13616. uiThreadCount++;
  13617. }
  13618. i++;
  13619. }
  13620. Print("Number of ghost threads waiting to be created in CSRSS is %i\n", uiThreadCount);
  13621. uiThreadCount = 0;
  13622. i = 0;
  13623. // Dump the number of pending thread creation requests in the shell process.
  13624. pCST = EvalExp(SYM(gCSTRemoteParam));
  13625. i = 0;
  13626. SAFEWHILE (i < CST_MAX_THREADS) {
  13627. uID = (UINT)GetArrayElement(pCST, SYM(CST_THREADS), "uID", i, "UINT");
  13628. if (CST_GHOST == uID) {
  13629. uiThreadCount++;
  13630. }
  13631. i++;
  13632. }
  13633. Print("Number of ghost threads waiting to be created in the shell process is %i\n", uiThreadCount);
  13634. // Dump the number of pending ghost windows created and freed since dirver last loaded.
  13635. Print("Number of ghost windows created and freed since driver last loaded is %i\n", GetGlobalPointer(SYM(guGhostUnlinked)));
  13636. // Dump signal state for gpEventScanGhosts
  13637. pEventScanGhosts = GetGlobalPointer(SYM(gpEventScanGhosts));
  13638. if (0 != pEventScanGhosts) {
  13639. Print("Scan Ghost event is 0x%p\n", pEventScanGhosts);
  13640. GetFieldValue(pEventScanGhosts, "nt!DISPATCHER_HEADER", "SignalState", SignalGhost);
  13641. if (SignalGhost) {
  13642. Print("Scan ghost event is signaled\n");
  13643. } else {
  13644. Print("Scan ghost event isn't signaled\n");
  13645. }
  13646. }
  13647. return TRUE;
  13648. }
  13649. /************************************************************************\
  13650. * dce
  13651. *
  13652. * Dump information about the DCE cache.
  13653. *
  13654. * 6/15/2001 Created JStall
  13655. \************************************************************************/
  13656. BOOL Idce(
  13657. DWORD opts,
  13658. ULONG64 param1)
  13659. {
  13660. try {
  13661. PTR gpDispInfo, pdceStart, pdceCur;
  13662. gpDispInfo = GetGlobalPointer(VAR(gpDispInfo));
  13663. if (gpDispInfo == 0) {
  13664. Print("ERROR: Unable to retreive win32!gpDispInfo\n");
  13665. } else {
  13666. _InitTypeRead(gpDispInfo, SYM(DISPLAYINFO));
  13667. pdceStart = ReadField(pdceFirst);
  13668. if (pdceStart == 0) {
  13669. Print("ERROR: Unable to retreive gpDispInfo->pdceFirst\n");
  13670. } else {
  13671. PTR pData;
  13672. DWORD dwData, cTotal, cFound;
  13673. BOOL fDisplay, fVerbose;
  13674. cTotal = cFound = 0;
  13675. fVerbose = opts & OFLAG(v);
  13676. pdceCur = pdceStart;
  13677. while (pdceCur != 0) {
  13678. fDisplay = FALSE;
  13679. _InitTypeRead(pdceCur, SYM(DCE));
  13680. if (param1 != 0) {
  13681. if (opts & OFLAG(c)) {
  13682. //
  13683. // pwndClip
  13684. //
  13685. pData = ReadField(pwndClip);
  13686. fDisplay = pData == param1;
  13687. } else if (opts & OFLAG(f)) {
  13688. //
  13689. // DCX flag filter
  13690. //
  13691. dwData = (DWORD) ReadField(DCX_flags);
  13692. fDisplay = (dwData & ((DWORD) param1)) != 0;
  13693. } else if (opts & OFLAG(h)) {
  13694. //
  13695. // HDC
  13696. //
  13697. pData = ReadField(hdc);
  13698. fDisplay = pData == param1;
  13699. } else if (opts & OFLAG(o)) {
  13700. //
  13701. // pwndOrg
  13702. //
  13703. pData = ReadField(pwndOrg);
  13704. fDisplay = pData == param1;
  13705. } else if (opts & OFLAG(r)) {
  13706. //
  13707. // hrgnClip
  13708. //
  13709. pData = ReadField(hrgnClip);
  13710. fDisplay = pData == param1;
  13711. } else if (opts & OFLAG(t)) {
  13712. //
  13713. // pti (THREADINFO)
  13714. //
  13715. pData = ReadField(ptiOwner);
  13716. fDisplay = pData == param1;
  13717. }
  13718. } else {
  13719. //
  13720. // No filter, so display information
  13721. //
  13722. fDisplay = TRUE;
  13723. }
  13724. if (fDisplay) {
  13725. if (fVerbose) {
  13726. PTR hdc, pwndOrg, pwndClip, hrgnClip, ptiOwner;
  13727. DWORD nFlags;
  13728. LPCSTR pszFlags;
  13729. char szOrg[256];
  13730. char szClip[256];
  13731. WCHAR szRawApp[80];
  13732. PWCHAR pszApp;
  13733. hdc = ReadField(hdc);
  13734. pwndOrg = ReadField(pwndOrg);
  13735. pwndClip = ReadField(pwndClip);
  13736. hrgnClip = ReadField(hrgnClip);
  13737. nFlags = (DWORD) ReadField(DCX_flags);
  13738. pszFlags = GetFlags(GF_DCXFLAGS, nFlags, NULL, TRUE);
  13739. ptiOwner = ReadField(ptiOwner);
  13740. szRawApp[0] = L'\0';
  13741. pszApp = szRawApp;
  13742. if (ptiOwner != 0) {
  13743. _InitTypeRead(ptiOwner, SYM(THREADINFO));
  13744. GetAppName(ReadField(pEThread), ptiOwner, szRawApp, sizeof(szRawApp));
  13745. pszApp = wcsrchr(szRawApp, L'\\');
  13746. if (pszApp == NULL_PTR) {
  13747. pszApp = szRawApp;
  13748. } else {
  13749. pszApp++;
  13750. }
  13751. }
  13752. DebugGetWindowTextA(pwndOrg, szOrg, ARRAY_SIZE(szOrg));
  13753. DebugGetWindowTextA(pwndClip, szClip, ARRAY_SIZE(szClip));
  13754. Print(
  13755. "DCE: 0x%p\n"
  13756. " HDC: 0x%p\n"
  13757. " pwndOrg: 0x%p \"%s\"\n"
  13758. " pwndClip: 0x%p \"%s\"\n"
  13759. " hrgnClip: 0x%p\n"
  13760. " ptiOwner: 0x%p \"%ws\"\n"
  13761. " nFlags: 0x%x\n"
  13762. " %s\n\n",
  13763. pdceCur,
  13764. hdc,
  13765. pwndOrg, szOrg,
  13766. pwndClip, szClip,
  13767. hrgnClip,
  13768. ptiOwner, pszApp,
  13769. nFlags,
  13770. pszFlags);
  13771. } else {
  13772. PTR hdc, pwndOrg;
  13773. char szOrg[256];
  13774. hdc = ReadField(hdc);
  13775. pwndOrg = ReadField(pwndOrg);
  13776. DebugGetWindowTextA(pwndOrg, szOrg, ARRAY_SIZE(szOrg));
  13777. Print("DCE: 0x%p HDC: 0x%p pwndOrg: 0x%p \"%s\"\n",
  13778. pdceCur, hdc, pwndOrg, szOrg);
  13779. }
  13780. cFound++;
  13781. }
  13782. // Get the next DCE
  13783. _InitTypeRead(pdceCur, SYM(DCE));
  13784. pdceCur = ReadField(pdceNext);
  13785. cTotal++;
  13786. }
  13787. Print(" Total 0x%x (%d) of 0x%x (%d) DCE's\n\n", cFound, cFound, cTotal, cTotal);
  13788. }
  13789. }
  13790. } except (CONTINUE) {
  13791. }
  13792. return TRUE;
  13793. }
  13794. #endif // KERNEL
  13795. #ifndef KERNEL
  13796. /************************************************************************\
  13797. * msft
  13798. *
  13799. * Dump Microsoft's current stock price.
  13800. *
  13801. * 12/13/2000 Created JasonSch
  13802. \************************************************************************/
  13803. BOOL Imsft(
  13804. VOID)
  13805. {
  13806. BOOL bResult;
  13807. DWORD dwBytesRead;
  13808. SYSTEMTIME systime;
  13809. CHAR buffer[256], *p;
  13810. HINTERNET hUrlHandle;
  13811. HINTERNET hInternet;
  13812. GetLocalTime(&systime);
  13813. if (systime.wMonth == 4 && systime.wDay == 1) {
  13814. static int n = 0;
  13815. if (n++ < 4) {
  13816. /*
  13817. * Let's pretend to be happy!
  13818. */
  13819. Print("MSFT: 120.5625,+80.1875,\"04/01/%d\",\"%d:%02d%s\"\n",
  13820. systime.wYear, systime.wHour % 12, systime.wMinute, systime.wHour >= 12 ? "PM" : "AM");
  13821. return TRUE;
  13822. }
  13823. }
  13824. hInternet = InternetOpenW(L"Jo Mama!",
  13825. INTERNET_OPEN_TYPE_PRECONFIG,
  13826. NULL,
  13827. NULL,
  13828. 0);
  13829. if (hInternet == NULL) {
  13830. return FALSE;
  13831. }
  13832. hUrlHandle = InternetOpenUrlW(hInternet,
  13833. L"http://quote.yahoo.com/download/quotes.csv?symbols=msft&format=sl1c1d1t1&ext=.txt",
  13834. NULL,
  13835. 0,
  13836. INTERNET_FLAG_RAW_DATA,
  13837. 0);
  13838. if (!hUrlHandle) {
  13839. return FALSE;
  13840. }
  13841. bResult = InternetReadFile(hUrlHandle,
  13842. buffer,
  13843. sizeof(buffer),
  13844. &dwBytesRead);
  13845. if (!bResult) {
  13846. InternetCloseHandle(hInternet);
  13847. return FALSE;
  13848. }
  13849. InternetCloseHandle(hUrlHandle);
  13850. InternetCloseHandle(hInternet);
  13851. /*
  13852. * Buffer will now have a string that looks like:
  13853. * "MSFT",58.375,+0.3125,"12/12/2000","4:01PM"
  13854. */
  13855. /*
  13856. * NULL-terminate buffer (remove \r\n, while we're at it).
  13857. */
  13858. buffer[dwBytesRead - 2] = 0;
  13859. p = &buffer[7]; // Skip '"MSFT",' part.
  13860. Print("MSFT: %s\n", p);
  13861. return TRUE;
  13862. }
  13863. #endif // !KERNEL
  13864. /************************************************************************\
  13865. * Idaccel
  13866. *
  13867. * Dumps accelerator tables.
  13868. *
  13869. * 04/02/2001 Created JasonSch
  13870. \************************************************************************/
  13871. BOOL Idaccel(
  13872. DWORD dwFlags,
  13873. PTR pAccelTable)
  13874. {
  13875. ULONG dwOffset, dwSize;
  13876. PTR phe;
  13877. UINT i, cnt;
  13878. UNREFERENCED_PARAMETER(dwFlags);
  13879. /*
  13880. * pAccelTable could actually be a handle.
  13881. */
  13882. if (HtoHE(pAccelTable, &phe)) {
  13883. GetFieldValue(phe, SYM(HANDLEENTRY), "phead", pAccelTable);
  13884. }
  13885. if (pAccelTable == 0) {
  13886. return FALSE;
  13887. }
  13888. if (_InitTypeRead(pAccelTable, SYM(ACCELTABLE))) {
  13889. Print("Couldn't read ACCELTABLE at %p\n", (ULONG_PTR)pAccelTable);
  13890. return FALSE;
  13891. }
  13892. cnt = (UINT)ReadField(cAccel);
  13893. GetFieldOffset(SYM(ACCELTABLE), "accel", &dwOffset);
  13894. dwSize = GetTypeSize(SYM(ACCEL));
  13895. pAccelTable += dwOffset;
  13896. for (i = 0; i < cnt; ++i) {
  13897. BYTE bVirt;
  13898. BOOL bPrintPlus = FALSE;
  13899. _InitTypeRead(pAccelTable, SYM(ACCEL));
  13900. bVirt = (BYTE)ReadField(fVirt);
  13901. Print("Flags: ");
  13902. if (bVirt & FVIRTKEY) {
  13903. Print("FVIRTKEY");
  13904. bPrintPlus = TRUE;
  13905. }
  13906. if (bVirt & FNOINVERT) {
  13907. if (bPrintPlus) {
  13908. Print(" + ");
  13909. }
  13910. Print("FNOINVERT");
  13911. }
  13912. if (bVirt & FLASTKEY) {
  13913. if (bPrintPlus) {
  13914. Print(" + ");
  13915. }
  13916. Print("FLASTKEY");
  13917. }
  13918. Print("\nKey: ");
  13919. if (bVirt & FALT) {
  13920. Print("ALT + ");
  13921. }
  13922. if (bVirt & FCONTROL) {
  13923. Print("CONTROL + ");
  13924. }
  13925. if (bVirt & FSHIFT) {
  13926. Print("SHIFT + ");
  13927. }
  13928. if (isprint((int)ReadField(key))) {
  13929. Print("'%c'\n", (char)ReadField(key));
  13930. } else {
  13931. Print("<unprintable> (0x%x)\n", (UINT)(WORD)ReadField(key));
  13932. }
  13933. Print("Cmd: 0x%x\n", (UINT)(WORD)ReadField(cmd));
  13934. pAccelTable += dwSize;
  13935. }
  13936. return TRUE;
  13937. }
  13938. #ifdef KERNEL
  13939. /************************************************************************\
  13940. * Idhproc
  13941. *
  13942. * Dumps a proc with this type of kernel handle.
  13943. * Similar to !handle 0 7 <eprocess> <type>
  13944. *
  13945. * 05/14 Created HiroYama
  13946. \************************************************************************/
  13947. #if 0
  13948. ULONG dhprocCallback(
  13949. PFIELD_INFO NextProcess,
  13950. PVOID Context)
  13951. {
  13952. static int progress;
  13953. ShowProgress();
  13954. return FALSE;
  13955. }
  13956. BOOL Idhproc(
  13957. DWORD dwFlags,
  13958. PTR ul)
  13959. {
  13960. PTR ProcessHead = EvalExp("PsActiveProcessHead");
  13961. PTR NextProcess;
  13962. THREAD_DUMP_CONTEXT tdc;
  13963. if (ProcessHead == NULL_PTR) {
  13964. Print("Unable to get value of PsActiveProcessHead\n");
  13965. return FALSE;
  13966. }
  13967. if (GetFieldValue(ProcessHead, "nt!LIST_ENTRY", "Flink", NextProcess)) {
  13968. Print("Unable to get value of PsActiveProcessHead\n");
  13969. return FALSE;
  13970. }
  13971. if (NextProcess == 0) {
  13972. Print("PsActiveProcessHead->Flink is NULL!\n");
  13973. return FALSE;
  13974. }
  13975. tdc.opts = dwFlags;
  13976. tdc.ThreadToDump = ul;
  13977. ListType("nt!EPROCESS", NextProcess, 1, "ActiveProcessLinks.Flink", &TDC, dhprocCallback);
  13978. return TRUE;
  13979. }
  13980. #endif
  13981. #endif // KERNEL
  13982. #ifdef LATER
  13983. #ifdef KERNEL
  13984. /************************************************************************\
  13985. * Procedure: Idwsl
  13986. *
  13987. * Dumps WinSta locking log
  13988. *
  13989. * 09/19/2000 Hiroyama Created
  13990. *
  13991. \************************************************************************/
  13992. BOOL Idwsl(
  13993. DWORD opts,
  13994. ULONG64 param1)
  13995. {
  13996. try {
  13997. PTR p, pStart;
  13998. PTR pTarget = 0;
  13999. PTR pTargetWinSta = NULL_PTR;
  14000. UCHAR szWinStaName[80] = "";
  14001. UINT iTarget = 0;
  14002. UINT iStartOffset = 0;
  14003. ULONG cbSize;
  14004. DWORD dwArraySize;
  14005. ULONG offsetWinStaName;
  14006. ULONG offsetImageFileName;
  14007. UINT iSeq, i;
  14008. if (opts & OFLAG(d)) {
  14009. if ((pTargetWinSta = param1) == NULL_PTR) {
  14010. return FALSE;
  14011. }
  14012. }
  14013. else if (opts & OFLAG(p)) {
  14014. p = pTarget = param1;
  14015. if (pTarget) {
  14016. goto PrintHeader;
  14017. }
  14018. }
  14019. else if (param1) {
  14020. iTarget = (UINT)param1;
  14021. opts |= OFLAG(v) | OFLAG(n);
  14022. }
  14023. offsetWinStaName = (ULONG)-1;
  14024. GetFieldOffset(SYM(WINSTA_RUNDOWN_RECORD), "szWinStaName", &offsetWinStaName);
  14025. if (offsetWinStaName == (ULONG)-1) {
  14026. Print("can't get offset to szWinStaName\n");
  14027. return TRUE;
  14028. }
  14029. GetFieldOffset(SYM(WINSTA_RUNDOWN_RECORD), "szImageFileName", &offsetImageFileName);
  14030. if (offsetImageFileName == 0) {
  14031. Print("can't get offset to szImageFileName\n");
  14032. return TRUE;
  14033. }
  14034. if ((p = pStart = EvalExp(SYM(gaWinStaRundownLog))) == NULL_PTR) {
  14035. Print("can't get gaWinStaRundownLog\n");
  14036. return TRUE;
  14037. }
  14038. if ((cbSize = GetTypeSize(SYM(WINSTA_RUNDOWN_RECORD))) == 0) {
  14039. Print("can't get sizeof(WINSTA_RUNDOWN_RECORD)\n");
  14040. return TRUE;
  14041. }
  14042. moveExpValue(&dwArraySize, VAR(gdwWinStaRecSize));
  14043. if (dwArraySize == 0) {
  14044. Print("can't get gdwWinStaRecSize\n");
  14045. return TRUE;
  14046. }
  14047. /*
  14048. * Firstly, find out the lowest iSeq.
  14049. */
  14050. iSeq = UINT_MAX;
  14051. for (i = 0; !IsCtrlCHit() && i < dwArraySize; ++i) {
  14052. UINT iSeqTmp;
  14053. _InitTypeRead(p, SYM(WINSTA_RUNDOWN_RECORD));
  14054. iSeqTmp = (UINT)ReadField(iSeq);
  14055. ShowProgress();
  14056. if (iSeqTmp < iSeq && iSeqTmp != 0) {
  14057. iSeq = iSeqTmp;
  14058. iStartOffset = i;
  14059. }
  14060. /*
  14061. * For device name search, remember the path name
  14062. * that matches to pDeviceInfo.
  14063. */
  14064. if (pTargetWinSta && (opts & OFLAG(m)) &&
  14065. szWinStaName[0] == 0 && ReadField(pwinsta) == pTargetWinSta) {
  14066. move(szWinStaName, p + offsetWinStaName);
  14067. Print("\r\"%s\"\n", szWinStaName);
  14068. }
  14069. p = p + cbSize;
  14070. }
  14071. Print("\r");
  14072. /*
  14073. * Secondly, dump the records.
  14074. */
  14075. PrintHeader:
  14076. #if 0
  14077. Print(" seq %-*c%-20s %-*s %-*s code\n",
  14078. opts & OFLAG(p) ? PtrWidth() + 2 : 1, ' ',
  14079. "type", PtrWidth(), "pDevInfo", PtrWidth(), "thread");
  14080. #endif
  14081. if (pTarget) {
  14082. goto PrintOne;
  14083. }
  14084. for (i = 0; !IsCtrlCHit() && i < dwArraySize; ++i) {
  14085. UINT iOffset = (i + iStartOffset) % dwArraySize;
  14086. BOOLEAN fDump = FALSE;
  14087. p = pStart + cbSize * iOffset;
  14088. PrintOne:
  14089. _InitTypeRead(p, SYM(WINSTA_RUNDOWN_RECORD));
  14090. iSeq = (UINT)ReadField(iSeq);
  14091. if (pTargetWinSta) {
  14092. if (iSeq) {
  14093. if (ReadField(pwinsta) == pTargetWinSta) {
  14094. fDump = TRUE;
  14095. }
  14096. else if ((opts & OFLAG(m)) && szWinStaName[0]) {
  14097. /*
  14098. * Try to dump the winsta of the same device path.
  14099. */
  14100. UCHAR szPathNameTmp[ARRAY_SIZE(szWinStaName)];
  14101. move(szPathNameTmp, p + offsetWinStaName);
  14102. if (strcmp(szWinStaName, szPathNameTmp) == 0) {
  14103. fDump = TRUE;
  14104. }
  14105. }
  14106. }
  14107. }
  14108. else if (iTarget) {
  14109. if (iTarget == iSeq) {
  14110. /*
  14111. * Print just one by iSeq.
  14112. */
  14113. fDump = TRUE;
  14114. }
  14115. }
  14116. else if (pTarget) {
  14117. /*
  14118. * Print just one record by address.
  14119. */
  14120. fDump = TRUE;
  14121. }
  14122. else if (opts & OFLAG(z)) {
  14123. /*
  14124. * Print only if the session id don't match.
  14125. */
  14126. if ((DWORD)ReadField(dwSessionIdWinSta) != (DWORD)ReadField(dwCurrentSessionId)) {
  14127. fDump = TRUE;
  14128. }
  14129. }
  14130. else if (iSeq) {
  14131. /*
  14132. * Dump all valid records.
  14133. */
  14134. fDump = TRUE;
  14135. }
  14136. if (fDump) {
  14137. UINT fReference = (UINT)ReadField(fReference);
  14138. PTR pwinsta = ReadField(pwinsta);
  14139. UCHAR szName[33];
  14140. //PTR NotificationCode = ReadField(NotificationCode);
  14141. PTR pThread = ReadField(pKThread);
  14142. if (opts & OFLAG(p)) {
  14143. Print("[0x%04x] @ 0x%p 0x%x ws 0x%08p t 0x%p ", iSeq, p, fReference, pwinsta, pThread);
  14144. } else {
  14145. Print("[0x%04x] 0x%x ws 0x%08p t 0x%p ", iSeq, fReference, pwinsta, pThread);
  14146. }
  14147. /*
  14148. * Print the windowstation name.
  14149. */
  14150. move(szName, p + offsetWinStaName);
  14151. Print(" %02x %-20s", (DWORD)ReadField(dwSessionIdWinSta), szName);
  14152. /*
  14153. * Print the process name.
  14154. */
  14155. move(szName, p + offsetImageFileName);
  14156. Print(" %02x %x.%x \"%s\"\n", (DWORD)ReadField(dwCurrentSessionId), (DWORD)ReadField(pid), (DWORD)ReadField(tid), szName);
  14157. /*
  14158. * If it is a one-shot dump, exit the loop here.
  14159. */
  14160. if (iTarget || pTarget) {
  14161. break;
  14162. }
  14163. }
  14164. }
  14165. } except (CONTINUE) {
  14166. }
  14167. return TRUE;
  14168. }
  14169. #endif // KERNEL
  14170. #endif // LATER
  14171. #ifdef KERNEL
  14172. /************************************************************************\
  14173. * Iheapff
  14174. *
  14175. * Looks for a particular address in our global list of freed heap.
  14176. *
  14177. * 07/02/2001 Created JasonSch
  14178. \************************************************************************/
  14179. BOOL Iheapff(
  14180. DWORD dwFlags,
  14181. PTR pHeapBlock)
  14182. {
  14183. DWORD dwHeapRecordMax, i, dwSize, dwOffset;
  14184. PTR pHeapRecords;
  14185. UNREFERENCED_PARAMETER(pHeapBlock);
  14186. UNREFERENCED_PARAMETER(dwFlags);
  14187. moveExpValue(&dwHeapRecordMax, SYM(gdwFreeHeapRecordCrtIndex));
  14188. dwSize = GetTypeSize(SYM(HEAPRECORD));
  14189. GetFieldOffset(SYM(HEAPRECORD), "trace", &dwOffset);
  14190. pHeapRecords = EvalExp(SYM(garrFreeHeapRecord));
  14191. for (i = 0; i < dwHeapRecordMax; ++i, pHeapRecords += dwSize) {
  14192. _InitTypeRead(pHeapRecords, SYM(HEAPRECORD));
  14193. if (ReadField(p) == pHeapBlock) {
  14194. Print("Found heap block 0x%p (Heap: 0x%p, Size: 0x%p)\n",
  14195. pHeapBlock,
  14196. ReadField(pheap),
  14197. ReadField(size));
  14198. PrintStackTrace(pHeapRecords + dwOffset, 6);
  14199. }
  14200. }
  14201. Print("==========================================================\n");
  14202. moveExpValue(&dwHeapRecordMax, SYM(gdwFreeHeapRecordTotalFrees));
  14203. Print("Total heap allocations freed thus far: 0x%x\n", dwHeapRecordMax);
  14204. return TRUE;
  14205. }
  14206. #endif
  14207. ULONG SortBy;
  14208. #define SORT_SIZE 1
  14209. #define SORT_PID 2
  14210. #define SORT_TAG 3
  14211. int __cdecl
  14212. HeapInfoSort(const void *e1,const void *e2)
  14213. {
  14214. LONG64 diff;
  14215. WORD tag1, tag2;
  14216. WORD subtag1, subtag2;
  14217. ULONG64 size1, size2;
  14218. ULONG64 pid1, pid2;
  14219. _InitTypeRead(*((PULONG64) e1), SYM(DbgHeapHead));
  14220. tag1 = LOWORD(ReadField(tag));
  14221. subtag1 = HIWORD(ReadField(tag));
  14222. size1 = ReadField(size);
  14223. pid1 = ReadField(pid);
  14224. _InitTypeRead(*((PULONG64) e2), SYM(DbgHeapHead));
  14225. tag2 = LOWORD(ReadField(tag));
  14226. subtag2 = HIWORD(ReadField(tag));
  14227. size2 = ReadField(size);
  14228. pid2 = ReadField(pid);
  14229. switch (SortBy) {
  14230. case SORT_SIZE:
  14231. diff = size1 - size2;
  14232. break;
  14233. case SORT_PID:
  14234. diff = pid1 - pid2;
  14235. break;
  14236. case SORT_TAG:
  14237. diff = tag1 - tag2;
  14238. if (diff == 0) {
  14239. diff = subtag1 - subtag2;
  14240. }
  14241. break;
  14242. }
  14243. return (int) diff;
  14244. }
  14245. /************************************************************************\
  14246. * Idheap
  14247. *
  14248. * Dumps a win32Heap
  14249. *
  14250. * 08/15/2001 Created MSadek
  14251. \************************************************************************/
  14252. BOOL Idheap(
  14253. DWORD opts,
  14254. ULONG64 param1,
  14255. ULONG64 param2)
  14256. {
  14257. if (((opts & OFLAG(o)) && param2 == 0 ) || param1 == 0) {
  14258. Print("Wrong usage0: dheap takes a pointer as a parameter\n");
  14259. return FALSE;
  14260. }
  14261. try {
  14262. PTR pheap;
  14263. PTR pFirstAlloc;
  14264. ULONG64 cAllocations = 0;
  14265. ULONG64 cActualAllocations = 0;
  14266. ULONG64 cTotalHeap = 0, cTotalHeapRead = 0;
  14267. ULONG64 cClass = 0;
  14268. ULONG64 pid;
  14269. ULONG64 i = 0;
  14270. ULONG64 *pHeapDebugInfo = NULL;
  14271. BOOL bWarning = FALSE;
  14272. DWORD dwDbgInfoSize = GetTypeSize(SYM(DbgHeapHead));
  14273. WORD tag;
  14274. if (opts & OFLAG(o)) {
  14275. pheap = param2;
  14276. } else {
  14277. pheap = param1;
  14278. }
  14279. Print("\n***IMPORTANT***: If you are not dumping a desktop heap, the tag and subtag information is wrong.\n\n");
  14280. if (!opts || ((opts & (OFLAG(o))) && !(opts & (OFLAG(p) | OFLAG(t) | OFLAG(s))))) {
  14281. Print("\t%-10s%-10s%-18s%-18s%-10s%-10s\n","Heap Block", "Size","Tag","Subtag","Process","StackTrace");
  14282. Print("\t============================================================================\n");
  14283. }
  14284. _InitTypeRead(pheap, SYM(tagWIN32HEAP));
  14285. pFirstAlloc = ReadField(pFirstAlloc);
  14286. cActualAllocations = ReadField(crtAllocations);
  14287. cTotalHeap = ReadField(crtMemory);
  14288. do {
  14289. _InitTypeRead(pFirstAlloc, SYM(DbgHeapHead));
  14290. if (ReadField(pNext)) {
  14291. cAllocations++;
  14292. cTotalHeapRead += ReadField(size);
  14293. if (!opts || ((opts & (OFLAG(o))) && !(opts & (OFLAG(p) | OFLAG(t) | OFLAG(s))) && param1 == ReadField(pid))) {
  14294. Print("\t%-10x", pFirstAlloc + dwDbgInfoSize);
  14295. Print("%-10x", ReadField(size));
  14296. Print("%-18s", aszHeapTags[LOWORD(ReadField(tag))]);
  14297. Print("%-18s", aszHeapSubtags[HIWORD(ReadField(tag))]);
  14298. Print("%-10x", ReadField(pid));
  14299. Print("%-10x\n", ReadField(trace));
  14300. } else {
  14301. ShowProgress();
  14302. }
  14303. }
  14304. } while (pFirstAlloc = ReadField(pNext));
  14305. if (cActualAllocations > cAllocations) {
  14306. bWarning = TRUE;
  14307. }
  14308. if (!(opts & (OFLAG(p) | OFLAG(t) | OFLAG(s)))) {
  14309. goto PrintFooter;
  14310. } else if(opts & OFLAG(p)) {
  14311. SortBy= SORT_PID;
  14312. } else if(opts & OFLAG(t)) {
  14313. SortBy= SORT_TAG;
  14314. } else if(opts & OFLAG(s)) {
  14315. SortBy= SORT_SIZE;
  14316. }
  14317. pHeapDebugInfo = malloc((SIZE_T)(cAllocations * sizeof(ULONG64)));
  14318. if (!pHeapDebugInfo) {
  14319. Print("Couldn't allocate memory for heap info buffer\n");
  14320. return FALSE;
  14321. }
  14322. _InitTypeRead(pheap, SYM(tagWIN32HEAP));
  14323. pFirstAlloc = ReadField(pFirstAlloc);
  14324. for (i = 0; i < cAllocations; i++) {
  14325. ShowProgress();
  14326. pHeapDebugInfo[i] = pFirstAlloc;
  14327. _InitTypeRead(pFirstAlloc, SYM(DbgHeapHead));
  14328. pFirstAlloc = ReadField(pNext);
  14329. }
  14330. qsort((void *) pHeapDebugInfo, (size_t)cAllocations, (size_t)sizeof(ULONG64), HeapInfoSort);
  14331. for (i = 0; i < cAllocations; i++) {
  14332. _InitTypeRead(pHeapDebugInfo[i], SYM(DbgHeapHead));
  14333. if (((opts & OFLAG(s) && !(opts & OFLAG(o))) || ((opts & OFLAG(o)) && param1 == ReadField(pid)))) {
  14334. if (i == 0) {
  14335. Print("\t%-10s%-10s%-18s%-18s%-10s%-10s\n","Heap Block", "Size","Tag","Subtag","Process","StackTrace");
  14336. Print("\t============================================================================\n");
  14337. }
  14338. Print("\t%-10x", pHeapDebugInfo[i] + dwDbgInfoSize);
  14339. Print("%-10x", ReadField(size));
  14340. Print("%-18s", aszHeapTags[LOWORD(ReadField(tag))]);
  14341. Print("%-18s", aszHeapSubtags[HIWORD(ReadField(tag))]);
  14342. Print("%-10x", ReadField(pid));
  14343. Print("%-10x\n", ReadField(trace));
  14344. } else if (!(opts & OFLAG(o))){
  14345. if (i == 0) {
  14346. if (SortBy== SORT_PID) {
  14347. Print("\t%-10s%-15s%\n","Process", "Total Heap Size");
  14348. Print("\t=========================\n");
  14349. pid = ReadField(pid);
  14350. } else {
  14351. Print("\t%-18s%-15s%\n","Tag", "Total Heap Size");
  14352. Print("\t=================================\n");
  14353. tag = LOWORD(ReadField(tag));
  14354. }
  14355. }
  14356. if (SortBy== SORT_PID) {
  14357. if (pid == ReadField(pid)) {
  14358. cClass += (ULONG64)ReadField(size);
  14359. }
  14360. if (pid != ReadField(pid) || i == cAllocations - 1) {
  14361. Print("\t%-10x", pid);
  14362. Print("%-15x\n", cClass);
  14363. cClass = (ULONG64)ReadField(size);
  14364. if (pid != ReadField(pid) && i == cAllocations - 1) {
  14365. Print("\t%-10x", ReadField(pid));
  14366. Print("%-15x\n", cClass);
  14367. }
  14368. pid = ReadField(pid);
  14369. }
  14370. } else {
  14371. if (tag == LOWORD(ReadField(tag))) {
  14372. cClass += (ULONG64)ReadField(size);
  14373. }
  14374. if (tag != LOWORD(ReadField(tag)) || i == cAllocations - 1) {
  14375. Print("\t%-18s", aszHeapTags[tag]);
  14376. Print("%-15x\n", cClass);
  14377. cClass = (ULONG64)ReadField(size);
  14378. if (tag != LOWORD(ReadField(tag)) && i == cAllocations - 1) {
  14379. Print("\t%-18s", aszHeapTags[LOWORD(ReadField(tag))]);
  14380. Print("%-15x\n", cClass);
  14381. }
  14382. tag = LOWORD(ReadField(tag));
  14383. }
  14384. }
  14385. }
  14386. }
  14387. PrintFooter:
  14388. Print("\nTotal heap allocated (excluding headers): %dKb", cTotalHeap/1024, cTotalHeap);
  14389. Print(" in %d allocations.\n", cActualAllocations);
  14390. if(bWarning) {
  14391. Print("\n**WARNING**:Some of the heap memory is paged out.\n");
  14392. }
  14393. if (pHeapDebugInfo) {
  14394. free(pHeapDebugInfo);
  14395. }
  14396. } except(CONTINUE) {
  14397. }
  14398. return TRUE;
  14399. }
  14400. /************************************************************************\
  14401. * Ifcsrp
  14402. *
  14403. * Finds the CSR_PROCESS for the given PID.
  14404. *
  14405. * 09/13/2001 Created JasonSch
  14406. \************************************************************************/
  14407. BOOL Ifcsrp(
  14408. DWORD dwFlags,
  14409. ULONG64 pid)
  14410. {
  14411. PTR pProcess;
  14412. ULONG dwOffset;
  14413. GetFieldOffset("csrsrv!_CSR_PROCESS", "ListLink", &dwOffset);
  14414. UNREFERENCED_PARAMETER(dwFlags);
  14415. pProcess = GetGlobalPointer("csrsrv!CsrRootProcess");
  14416. SAFEWHILE (pProcess) {
  14417. _InitTypeRead(pProcess, "csrsrv!_CSR_PROCESS");
  14418. if (ReadField(ClientId.UniqueProcess) == pid) {
  14419. Print("Found specified CSR_PROCESS at 0x%p\n", pProcess);
  14420. break;
  14421. }
  14422. pProcess = (PTR)((PBYTE)ReadField(ListLink) - dwOffset);
  14423. }
  14424. return TRUE;
  14425. }
  14426. #ifdef KERNEL
  14427. typedef struct {
  14428. PTR ppi;
  14429. PTR pDesktop;
  14430. } PPI_DESKTOP, *PPPI_DESKTOP;
  14431. ULONG Findd_PtiCallback(
  14432. PTR pti,
  14433. PVOID pData)
  14434. {
  14435. PTR pDesktop;
  14436. PPPI_DESKTOP p = (PPPI_DESKTOP)pData;
  14437. ShowProgress();
  14438. GetFieldValue(pti, SYM(THREADINFO), "rpDesk", pDesktop);
  14439. if (p->pDesktop == pDesktop) {
  14440. Print("Pti 0x%p [ppi = 0x%p] using desktop 0x%p", pti, p->ppi, p->pDesktop);
  14441. }
  14442. return TRUE;
  14443. }
  14444. ULONG Findd_PpiCallback(
  14445. PTR ppi,
  14446. PVOID ppDesktop)
  14447. {
  14448. PPI_DESKTOP p = {ppi, *((PTR*)ppDesktop)};
  14449. ShowProgress();
  14450. ForEachPti(Findd_PtiCallback, &p);
  14451. return TRUE;
  14452. }
  14453. BOOL Ifindd(
  14454. DWORD dwOpts,
  14455. PTR pDesktop)
  14456. {
  14457. UNREFERENCED_PARAMETER(dwOpts);
  14458. ForEachPpi(Findd_PpiCallback, (PVOID)&pDesktop);
  14459. return TRUE;
  14460. }
  14461. #endif
  14462. /************************************************************************\
  14463. * Idcmu
  14464. *
  14465. * Dumps a rough estimate of the total amount of memory used by console
  14466. * screen buffers. Note that this currently just looks at the current
  14467. * screen buffer for each console. It should be augmented to look at all
  14468. * of them.
  14469. *
  14470. * 04/29/2002 Created JasonSch
  14471. \************************************************************************/
  14472. BOOL Idcmu(
  14473. DWORD opts)
  14474. {
  14475. ULONG64 pConsole, pConsoles, pScreenBuffer;
  14476. ULONG cConsoleHandles, cActualConsoleCount, i, PtrSize, CoordOffset;
  14477. ULONG dwTotalSize = 0, x, y;
  14478. PtrSize = GetTypeSize("PVOID");
  14479. pConsoles = GetGlobalPointer("winsrv!ConsoleHandles");
  14480. moveExpValue(&cConsoleHandles, "winsrv!NumberOfConsoleHandles");
  14481. for (i = 0, cActualConsoleCount = 0; i < cConsoleHandles; ++i) {
  14482. pConsole = GetPointer(pConsoles);
  14483. if (pConsole == 0) {
  14484. pConsoles += PtrSize;
  14485. continue;
  14486. }
  14487. ++cActualConsoleCount;
  14488. GetFieldValue(pConsole,
  14489. "winsrv!_CONSOLE_INFORMATION",
  14490. "CurrentScreenBuffer",
  14491. pScreenBuffer);
  14492. GetFieldOffset("winsrv!_SCREEN_INFORMATION", "ScreenBufferSize", &CoordOffset);
  14493. _InitTypeRead(pScreenBuffer + CoordOffset, "COORD");
  14494. x = (ULONG)(WORD)ReadField(X);
  14495. y = (ULONG)(WORD)ReadField(Y);
  14496. dwTotalSize += x * y * 2;
  14497. if (opts & OFLAG(v)) {
  14498. Print("Console @ 0x%p has buffer size (0x%x, 0x%x)\n", pConsole, x, y);
  14499. }
  14500. pConsoles += PtrSize;
  14501. }
  14502. Print("There are 0x%x consoles using roughly %d bytes\n",
  14503. cActualConsoleCount,
  14504. dwTotalSize);
  14505. return TRUE;
  14506. }
  14507. LPWSTR _ReadCountedWideString(
  14508. ULONG64 pAddress,
  14509. ULONG cbSize)
  14510. {
  14511. LPWSTR pwstr;
  14512. pwstr = LocalAlloc(LPTR, (cbSize + 1) * sizeof(WCHAR));
  14513. if (pwstr) {
  14514. ULONG result;
  14515. ReadMemory(pAddress,
  14516. pwstr,
  14517. cbSize * sizeof(WCHAR),
  14518. &result);
  14519. pwstr[cbSize] = 0;
  14520. }
  14521. return pwstr;
  14522. }
  14523. ULONG _DumpConsoleAliasCallback(
  14524. PFIELD_INFO pFieldInfo,
  14525. PVOID Context)
  14526. {
  14527. LPWSTR lpwszAliasSource, lpwszAliasTarget;
  14528. UNREFERENCED_PARAMETER(Context);
  14529. _InitTypeRead(pFieldInfo->address, "winsrv!_ALIAS");
  14530. lpwszAliasSource = _ReadCountedWideString(ReadField(Source),
  14531. (ULONG)ReadField(SourceLength));
  14532. lpwszAliasTarget = _ReadCountedWideString(ReadField(Target),
  14533. (ULONG)ReadField(TargetLength));
  14534. Print("\t%ws ==> %ws (@ 0x%p)\n",
  14535. lpwszAliasSource,
  14536. lpwszAliasTarget,
  14537. pFieldInfo->address);
  14538. LocalFree(lpwszAliasSource);
  14539. LocalFree(lpwszAliasTarget);
  14540. return FALSE;
  14541. }
  14542. ULONG _DumpConsoleAliasListCallback(
  14543. PFIELD_INFO pFieldInfo,
  14544. PVOID Context)
  14545. {
  14546. LPWSTR lpwszExeName;
  14547. UNREFERENCED_PARAMETER(Context);
  14548. _InitTypeRead(pFieldInfo->address, "winsrv!_EXE_ALIAS_LIST");
  14549. //
  14550. // TODO: Print doesn't support %.*XXX.
  14551. //
  14552. // Print("Alias .exe ==> %.*ws", (ULONG)ReadField(ExeLength), ReadField(ExeName));
  14553. lpwszExeName = _ReadCountedWideString(ReadField(ExeName),
  14554. (ULONG)ReadField(ExeLength));
  14555. Print("Alias list @ 0x%p for %ws\n", pFieldInfo->address, lpwszExeName);
  14556. LocalFree(lpwszExeName);
  14557. ListType("winsrv!_ALIAS",
  14558. ReadField(AliasList),
  14559. 1,
  14560. "ListLink.Flink",
  14561. NULL,
  14562. _DumpConsoleAliasCallback);
  14563. Print("\n");
  14564. return FALSE;
  14565. }
  14566. BOOL Idcalias(
  14567. DWORD dwOpts,
  14568. ULONG64 pConsole)
  14569. {
  14570. UNREFERENCED_PARAMETER(dwOpts);
  14571. //
  14572. // NULL pConsole means dump aliases for all consoles.
  14573. //
  14574. if (pConsole == 0) {
  14575. ULONG64 pConsoles;
  14576. ULONG cConsoleHandles, cActualConsoleCount, i, PtrSize;
  14577. PtrSize = GetTypeSize("PVOID");
  14578. pConsoles = GetGlobalPointer("winsrv!ConsoleHandles");
  14579. moveExpValue(&cConsoleHandles, "winsrv!NumberOfConsoleHandles");
  14580. for (i = 0, cActualConsoleCount = 0;
  14581. i < cConsoleHandles;
  14582. pConsoles += PtrSize,
  14583. ++i) {
  14584. pConsole = GetPointer(pConsoles);
  14585. if (pConsole == 0) {
  14586. continue;
  14587. }
  14588. ++cActualConsoleCount;
  14589. Idcalias(dwOpts, pConsole);
  14590. }
  14591. } else {
  14592. ULONG64 pExeAliasList;
  14593. GetFieldValue(pConsole,
  14594. "winsrv!_CONSOLE_INFORMATION",
  14595. "ExeAliasList",
  14596. pExeAliasList);
  14597. Print("Aliases for Console 0x%p\n", pConsole);
  14598. ListType("winsrv!_EXE_ALIAS_LIST",
  14599. pExeAliasList,
  14600. 1,
  14601. "ListLink.Flink",
  14602. NULL,
  14603. _DumpConsoleAliasListCallback);
  14604. }
  14605. return TRUE;
  14606. }