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.

789 lines
21 KiB

  1. /******************************Module*Header*******************************\
  2. * Module Name: debug.c
  3. *
  4. * This file is for debugging tools and extensions.
  5. *
  6. * Created: 24-Jan-1992
  7. * Author: John Colleran
  8. *
  9. * History:
  10. * Feb 17 92 Matt Felton (mattfe) lots of additional exentions for filtering
  11. * Jul 13 92 (v-cjones) Added API & MSG profiling debugger extensions, fixed
  12. * other extensions to handle segment motion correctly,
  13. * & cleaned up the file in general
  14. * Jan 3 96 Neil Sandlin (neilsa) integrated this routine into vdmexts
  15. *
  16. * Copyright (c) 1992 Microsoft Corporation
  17. \**************************************************************************/
  18. #include "precomp.h"
  19. #pragma hdrstop
  20. #include <wmdisp32.h>
  21. #include <wcuricon.h>
  22. #include <wucomm.h>
  23. INT cAPIThunks;
  24. //
  25. // WARNING: The following code was copied from WOWTBL.C
  26. //
  27. typedef struct {
  28. WORD kernel;
  29. WORD dkernel;
  30. WORD user;
  31. WORD duser;
  32. WORD gdi;
  33. WORD dgdi;
  34. WORD keyboard;
  35. WORD sound;
  36. WORD shell;
  37. WORD winsock;
  38. WORD toolhelp;
  39. WORD mmedia;
  40. WORD commdlg;
  41. #ifdef FE_IME
  42. WORD winnls;
  43. #endif // FE_IME
  44. #ifdef FE_SB
  45. WORD wifeman;
  46. #endif // FE_SB
  47. } TABLEOFFSETS;
  48. typedef TABLEOFFSETS UNALIGNED *PTABLEOFFSETS;
  49. TABLEOFFSETS tableoffsets;
  50. INT TableOffsetFromName(PSZ szTab);
  51. INT ModFromCallID(INT iFun)
  52. {
  53. PTABLEOFFSETS pto = &tableoffsets;
  54. LPVOID lpAddress;
  55. GETEXPRADDR(lpAddress, "wow32!tableoffsets");
  56. READMEM(lpAddress, &tableoffsets, sizeof(TABLEOFFSETS));
  57. if (iFun < pto->user)
  58. return MOD_KERNEL;
  59. if (iFun < pto->gdi)
  60. return MOD_USER;
  61. if (iFun < pto->keyboard)
  62. return MOD_GDI;
  63. if (iFun < pto->sound)
  64. return MOD_KEYBOARD;
  65. if (iFun < pto->shell)
  66. return MOD_SOUND;
  67. if (iFun < pto->winsock)
  68. return MOD_SHELL;
  69. if (iFun < pto->toolhelp)
  70. return MOD_WINSOCK;
  71. if (iFun < pto->mmedia)
  72. return MOD_TOOLHELP;
  73. if (iFun < pto->commdlg) {
  74. return(MOD_MMEDIA);
  75. }
  76. #if defined(FE_SB)
  77. #if defined(FE_IME)
  78. if (iFun < pto->winnls)
  79. return MOD_COMMDLG;
  80. if (iFun < pto->wifeman)
  81. return MOD_WINNLS;
  82. if (iFun < cAPIThunks)
  83. return MOD_WIFEMAN;
  84. #else
  85. if (iFun < pto->wifeman)
  86. return MOD_COMMDLG;
  87. if (iFun < cAPIThunks)
  88. return MOD_WIFEMAN;
  89. #endif
  90. #elif defined(FE_IME)
  91. if (iFun < pto->winnls)
  92. return MOD_COMMDLG;
  93. if (iFun < cAPIThunks)
  94. return MOD_WINNLS;
  95. #else
  96. if (iFun < cAPIThunks)
  97. return MOD_COMMDLG;
  98. #endif
  99. return -1;
  100. }
  101. PSZ apszModNames[] = { "Kernel",
  102. "User",
  103. "Gdi",
  104. "Keyboard",
  105. "Sound",
  106. "Shell",
  107. "Winsock",
  108. "Toolhelp",
  109. "MMedia",
  110. "Commdlg"
  111. #ifdef FE_IME
  112. ,"WinNLS"
  113. #endif
  114. #ifdef FE_SB
  115. ,"WifeMan"
  116. #endif
  117. };
  118. INT nModNames = NUMEL(apszModNames);
  119. PSZ GetModName(INT iFun)
  120. {
  121. INT nMod;
  122. nMod = ModFromCallID(iFun);
  123. if (nMod == -1) {
  124. return "BOGUS!!";
  125. }
  126. nMod = nMod >> 12; // get the value into the low byte
  127. return apszModNames[nMod];
  128. }
  129. INT GetOrdinal(INT iFun)
  130. {
  131. INT nMod;
  132. nMod = ModFromCallID(iFun);
  133. if (nMod == -1) {
  134. return 0;
  135. }
  136. return (iFun - TableOffsetFromName(apszModNames[nMod >> 12]));
  137. }
  138. INT TableOffsetFromName(PSZ szTab)
  139. {
  140. INT i;
  141. PTABLEOFFSETS pto = &tableoffsets;
  142. for (i = 0; i < NUMEL(apszModNames); i++) {
  143. if (!strcmp(szTab, apszModNames[i]))
  144. break;
  145. }
  146. if (i >= NUMEL(apszModNames))
  147. return 0;
  148. switch (i << 12) {
  149. case MOD_KERNEL:
  150. return pto->kernel;
  151. case MOD_USER:
  152. return pto->user;
  153. case MOD_DGDI:
  154. return pto->gdi;
  155. case MOD_KEYBOARD:
  156. return pto->keyboard;
  157. case MOD_SOUND:
  158. return pto->sound;
  159. case MOD_SHELL:
  160. return pto->shell;
  161. case MOD_WINSOCK:
  162. return pto->winsock;
  163. case MOD_TOOLHELP:
  164. return pto->toolhelp;
  165. case MOD_MMEDIA:
  166. return pto->mmedia;
  167. case MOD_COMMDLG:
  168. return(pto->commdlg);
  169. #ifdef FE_IME
  170. case MOD_WINNLS:
  171. return pto->winnls;
  172. #endif
  173. #ifdef FE_SB
  174. case MOD_WIFEMAN:
  175. return pto->wifeman;
  176. #endif
  177. default:
  178. return(-1);
  179. }
  180. }
  181. /********* local functions for WOWPROFILE support *********/
  182. /******* function protoypes for local functions for WOWPROFILE support *******/
  183. BOOL WDGetAPIProfArgs(LPSZ lpszArgStr,
  184. INT iThkTblMax,
  185. PPA32 ppaThkTbls,
  186. LPSZ lpszTab,
  187. BOOL *bTblAll,
  188. LPSZ lpszFun,
  189. int *iFunInd);
  190. BOOL WDGetMSGProfArgs(LPSZ lpszArgStr,
  191. LPSZ lpszMsg,
  192. int *iMsgNum);
  193. INT WDParseArgStr(LPSZ lpszArgStr, CHAR **argv, INT iMax);
  194. BOOL WDGetAPIProfArgs(LPSZ lpszArgStr,
  195. INT iThkTblMax,
  196. PPA32 ppaThkTbls,
  197. LPSZ lpszTab,
  198. BOOL *bTblAll,
  199. LPSZ lpszFun,
  200. int *iFunInd) {
  201. /*
  202. * Decomposes & interprets argument string to apiprofdmp extension.
  203. * INPUT:
  204. * lpszArgStr - ptr to input arg string
  205. * iThkTblMax - # tables in the thunk tables
  206. * ppaThkTbls - ptr to the thunk tables
  207. * OUTPUT:
  208. * lpszTab - ptr to table name
  209. * bTblAll - 0 => dump specific table, 1 => dump all tables
  210. * lpszFun - ptr to API name
  211. * iFunInd - -1 => dump specific API name
  212. * 0 => dump all API entires in table
  213. * >0 => dump specific API number (decimal)
  214. * RETURN: 0 => OK, 1 => input error (show Usage)
  215. *
  216. * legal forms: !wow32.apiprofdmp
  217. * !wow32.apiprofdmp user
  218. * !wow32.apiprofdmp user createwindow
  219. * !wow32.apiprofdmp user 41
  220. * !wow32.apiprofdmp createwindow
  221. * !wow32.apiprofdmp 41
  222. */
  223. INT i, nArgs;
  224. CHAR *argv[2];
  225. nArgs = WDParseArgStr(lpszArgStr, argv, 2);
  226. /* if no arguments dump all entries in all tables */
  227. if( nArgs == 0 ) {
  228. *iFunInd = 0; // specify dump all API entires in the table
  229. *bTblAll = 1; // specify dump all tables
  230. return(0);
  231. }
  232. /* see if 1st arg is a table name */
  233. *bTblAll = 1; // specify dump all tables
  234. for (i = 0; i < nModNames; i++) {
  235. if (!lstrcmpi(apszModNames[i], argv[0])) {
  236. lstrcpy(lpszTab, apszModNames[i]);
  237. *bTblAll = 0; // specify dump specific table
  238. /* if we got a table name match & only one arg, we're done */
  239. if( nArgs == 1 ) {
  240. *iFunInd = 0; // specify dump all API entries in the table
  241. return(0);
  242. }
  243. break;
  244. }
  245. }
  246. #if 0
  247. for(i = 0; i < iThkTblMax; i++) {
  248. CHAR temp[40], *TblEnt[2], szTabName[40];
  249. PA32 awThkTbl;
  250. /* get table name string from thunk tables */
  251. READMEM_XRETV(awThkTbl, &ppaThkTbls[i], 0);
  252. READMEM_XRETV(szTabName, awThkTbl.lpszW32, 0);
  253. /* get rid of trailing spaces from table name string */
  254. lstrcpy(temp, szTabName);
  255. WDParseArgStr(temp, TblEnt, 1);
  256. /* if we found a table name that matches the 1st arg...*/
  257. if( !lstrcmpi(argv[0], TblEnt[0]) ) {
  258. lstrcpy(lpszTab, szTabName);
  259. *bTblAll = 0; // specify dump specific table
  260. /* if we got a table name match & only one arg, we're done */
  261. if( nArgs == 1 ) {
  262. *iFunInd = 0; // specify dump all API entries in the table
  263. return(0);
  264. }
  265. break;
  266. }
  267. }
  268. #endif
  269. /* if 2 args && the 1st doesn't match a table name above => bad input */
  270. if( (nArgs > 1) && (*bTblAll) ) {
  271. return(1);
  272. }
  273. /* set index to API spec */
  274. nArgs--;
  275. /* try to convert API spec to a number */
  276. *iFunInd = atoi(argv[nArgs]);
  277. lstrcpy(lpszFun, argv[nArgs]);
  278. /* if API spec is not a number => it's a name */
  279. if( *iFunInd == 0 ) {
  280. *iFunInd = -1; // specify API search by name
  281. }
  282. /* else if API number is bogus -- complain */
  283. else if( *iFunInd < 0 ) {
  284. return(1);
  285. }
  286. return(0);
  287. }
  288. BOOL WDGetMSGProfArgs(LPSZ lpszArgStr,
  289. LPSZ lpszMsg,
  290. int *iMsgNum) {
  291. /*
  292. * Decomposes & interprets argument string to msgprofdmp extension.
  293. * INPUT:
  294. * lpszArgStr - ptr to input arg string
  295. * OUTPUT:
  296. * lpszMsg - ptr to message name
  297. * iMsgNum - -1 => dump all message entries in the table
  298. * -2 => lpszMsg contains specific MSG name
  299. * >=0 => dump specific message number
  300. * RETURN: 0 => OK, 1 => input error (show Usage)
  301. */
  302. INT nArgs;
  303. CHAR *argv[2];
  304. nArgs = WDParseArgStr(lpszArgStr, argv, 1);
  305. /* if no arguments dump all entries in all tables */
  306. if( nArgs == 0 ) {
  307. *iMsgNum = -1; // specify dump all MSG entires in the table
  308. return(0);
  309. }
  310. if( !_strnicmp(argv[0], "HELP",5) )
  311. return(1);
  312. /* try to convert MSG spec to a number */
  313. *iMsgNum = atoi(argv[0]);
  314. lstrcpy(lpszMsg, argv[0]);
  315. /* if MSG spec is not a number => it's a name */
  316. if( *iMsgNum == 0 ) {
  317. *iMsgNum = -2; // specify lpszMsg contains name to search for
  318. }
  319. /* else if MSG number is bogus -- complain */
  320. else if( *iMsgNum < 0 ) {
  321. return(1);
  322. }
  323. return(0);
  324. }
  325. /******* API profiler table functions ********/
  326. /* init some common strings */
  327. CHAR szAPI[] = "API# API Name";
  328. CHAR szMSG[] = "MSG # MSG Name";
  329. CHAR szTITLES[] = "# Calls Tot. tics tics/call";
  330. CHAR szDASHES[] = "----------------------------------- ------- --------------- ---------------";
  331. CHAR szTOOBIG[] = "too large for table.";
  332. CHAR szNOTUSED[] = "Unused table index.";
  333. CHAR szRNDTRIP[] = "Round trip message profiling";
  334. CHAR szCLEAR[] = "Remember to clear the message profile tables.";
  335. VOID
  336. apiprofclr(
  337. CMD_ARGLIST
  338. )
  339. {
  340. int iTab, iFun, iEntries;
  341. INT iThkTblMax;
  342. W32 awAPIEntry;
  343. PW32 pawAPIEntryTbl;
  344. PA32 awThkTbl;
  345. PPA32 ppaThkTbls;
  346. CHAR szTable[20];
  347. CMD_INIT();
  348. ASSERT_CHECKED_WOW_PRESENT;
  349. GETEXPRVALUE(iThkTblMax, "wow32!iThunkTableMax", INT);
  350. GETEXPRVALUE(ppaThkTbls, "wow32!pawThunkTables", PPA32);
  351. PRINTF("Clearing:");
  352. for(iTab = 0; iTab < iThkTblMax; iTab++) {
  353. READMEM_XRET(awThkTbl, &ppaThkTbls[iTab]);
  354. READMEM_XRET(szTable, awThkTbl.lpszW32);
  355. PRINTF(" %s", szTable);
  356. pawAPIEntryTbl = awThkTbl.lpfnA32;
  357. READMEM_XRET(iEntries, awThkTbl.lpiFunMax);
  358. for(iFun = 0; iFun < iEntries; iFun++) {
  359. READMEM_XRET(awAPIEntry, &pawAPIEntryTbl[iFun]);
  360. awAPIEntry.cCalls = 0L;
  361. awAPIEntry.cTics = 0I64;
  362. WRITEMEM_XRET(&pawAPIEntryTbl[iFun], awAPIEntry);
  363. }
  364. }
  365. PRINTF("\n");
  366. return;
  367. }
  368. VOID
  369. apiprofdmp(
  370. CMD_ARGLIST
  371. )
  372. {
  373. BOOL bTblAll, bFound;
  374. int i, iFun, iFunInd;
  375. INT iThkTblMax;
  376. W32 awAPIEntry;
  377. PW32 pawAPIEntryTbl;
  378. PA32 awThkTbl;
  379. PPA32 ppaThkTbls;
  380. CHAR szTab[20], szFun[40], szTable[20], szFunName[40];
  381. CMD_INIT();
  382. ASSERT_CHECKED_WOW_PRESENT;
  383. GETEXPRVALUE(iThkTblMax, "wow32!iThunkTableMax", INT);
  384. GETEXPRVALUE(ppaThkTbls, "wow32!pawThunkTables", PPA32);
  385. GETEXPRVALUE(cAPIThunks, "wow32!cAPIThunks", INT);
  386. GETEXPRVALUE(i, "wow32!nModNames", INT);
  387. if (i != nModNames) {
  388. PRINTF("Error: mismatch of nModNames in apiprofdmp.\nExtension is out of date\n");
  389. return;
  390. }
  391. if( WDGetAPIProfArgs(lpArgumentString,
  392. iThkTblMax,
  393. ppaThkTbls,
  394. szTab,
  395. &bTblAll,
  396. szFun,
  397. &iFunInd) ) {
  398. helpAPIProfDmp();
  399. return;
  400. }
  401. bFound = FALSE;
  402. #if 0
  403. for(iTab = 0; iTab < iThkTblMax; iTab++) {
  404. READMEM_XRET(awThkTbl, &ppaThkTbls[iTab]);
  405. READMEM_XRET(szTable, awThkTbl.lpszW32);
  406. /* if dump all tables || dump this specific table */
  407. if( bTblAll || !lstrcmp(szTab, szTable) ) {
  408. pawAPIEntryTbl = awThkTbl.lpfnA32;
  409. #endif
  410. for (i = 0; i < nModNames; i++) {
  411. READMEM_XRET(awThkTbl, &ppaThkTbls[0]);
  412. lstrcpy(szTable, apszModNames[i]);
  413. /* if dump all tables || dump this specific table */
  414. if (bTblAll || !lstrcmpi(szTab, apszModNames[i])) {
  415. INT nFirst, nLast;
  416. nFirst = TableOffsetFromName(apszModNames[i]);
  417. if (i < nModNames - 1)
  418. nLast = TableOffsetFromName(apszModNames[i+1]) - 1;
  419. else
  420. nLast = cAPIThunks - 1;
  421. pawAPIEntryTbl = awThkTbl.lpfnA32;
  422. /* if dump a specific API number */
  423. if( iFunInd > 0 ) {
  424. PRINTF("\n>>>> %s\n", szTable);
  425. PRINTF("%s %s\n%s\n", szAPI, szTITLES, szDASHES);
  426. //if( iFunInd >= *(awThkTbl.lpiFunMax) ) {
  427. if( iFunInd > nLast - nFirst ) {
  428. PRINTF("Index #%d %s.\n", GetOrdinal(iFunInd), szTOOBIG);
  429. }
  430. else {
  431. bFound = TRUE;
  432. // READMEM_XRET(awAPIEntry, &pawAPIEntryTbl[iFunInd]);
  433. READMEM_XRET(awAPIEntry, &pawAPIEntryTbl[nFirst + iFunInd]);
  434. READMEM_XRET(szFunName, awAPIEntry.lpszW32);
  435. if( szFunName[0] ) {
  436. PRINTF("%4d %30s ", GetOrdinal(iFunInd), szFunName);
  437. }
  438. else {
  439. PRINTF("%4d %30s ", GetOrdinal(iFunInd), szNOTUSED);
  440. }
  441. PRINTF("%7ld %15I64d ", awAPIEntry.cCalls, awAPIEntry.cTics);
  442. if(awAPIEntry.cCalls) {
  443. PRINTF("%15I64d\n", awAPIEntry.cTics/awAPIEntry.cCalls);
  444. } else {
  445. PRINTF("%15ld\n", 0L);
  446. }
  447. }
  448. }
  449. /* else if dump an API by name */
  450. else if ( iFunInd == -1 ) {
  451. // READMEM_XRET(iEntries, awThkTbl.lpiFunMax);
  452. // for(iFun = 0; iFun < iEntries; iFun++) {
  453. for(iFun = nFirst; iFun <= nLast; iFun++) {
  454. READMEM_XRET(awAPIEntry, &pawAPIEntryTbl[iFun]);
  455. READMEM_XRET(szFunName, awAPIEntry.lpszW32);
  456. if ( !lstrcmpi(szFun, szFunName) ) {
  457. PRINTF("\n>>>> %s\n", szTable);
  458. PRINTF("%s %s\n%s\n", szAPI, szTITLES, szDASHES);
  459. PRINTF("%4d %30s %7ld %15I64d ",
  460. GetOrdinal(iFun),
  461. szFunName,
  462. awAPIEntry.cCalls,
  463. awAPIEntry.cTics);
  464. if(awAPIEntry.cCalls) {
  465. PRINTF("%15I64d\n", awAPIEntry.cTics/awAPIEntry.cCalls);
  466. } else {
  467. PRINTF("%15ld\n", 0L);
  468. }
  469. return;
  470. }
  471. }
  472. }
  473. /* else dump all the API's in the table */
  474. else {
  475. PRINTF("\n>>>> %s\n", szTable);
  476. PRINTF("%s %s\n%s\n", szAPI, szTITLES, szDASHES);
  477. bFound = TRUE;
  478. // READMEM_XRET(iEntries, awThkTbl.lpiFunMax);
  479. // for(iFun = 0; iFun < iEntries; iFun++) {
  480. for(iFun = nFirst; iFun <= nLast; iFun++) {
  481. READMEM_XRET(awAPIEntry, &pawAPIEntryTbl[iFun]);
  482. READMEM_XRET(szFunName, awAPIEntry.lpszW32);
  483. if(awAPIEntry.cCalls) {
  484. PRINTF("%4d %30s %7ld %15I64d %15I64d\n",
  485. GetOrdinal(iFun),
  486. szFunName,
  487. awAPIEntry.cCalls,
  488. awAPIEntry.cTics,
  489. awAPIEntry.cTics/awAPIEntry.cCalls);
  490. }
  491. }
  492. if( !bTblAll ) {
  493. return;
  494. }
  495. }
  496. }
  497. }
  498. if( !bFound ) {
  499. PRINTF("\nCould not find ");
  500. if( !bTblAll ) {
  501. PRINTF("%s ", szTab);
  502. }
  503. PRINTF("API: %s\n", szFun);
  504. helpAPIProfDmp();
  505. }
  506. return;
  507. }
  508. /******* MSG profiler table functions ********/
  509. VOID
  510. msgprofclr(
  511. CMD_ARGLIST
  512. )
  513. {
  514. int iMsg;
  515. INT iMsgMax;
  516. M32 awM32;
  517. PM32 paw32Msg;
  518. CMD_INIT();
  519. ASSERT_CHECKED_WOW_PRESENT;
  520. GETEXPRVALUE(iMsgMax, "wow32!iMsgMax", INT);
  521. GETEXPRVALUE(paw32Msg, "wow32!paw32Msg", PM32);
  522. PRINTF("Clearing Message profile table");
  523. for(iMsg = 0; iMsg < iMsgMax; iMsg++) {
  524. READMEM_XRET(awM32, &paw32Msg[iMsg]);
  525. awM32.cCalls = 0L;
  526. awM32.cTics = 0I64;
  527. WRITEMEM_XRET(&paw32Msg[iMsg], awM32);
  528. }
  529. PRINTF("\n");
  530. return;
  531. }
  532. VOID
  533. msgprofdmp(
  534. CMD_ARGLIST
  535. )
  536. {
  537. int iMsg, iMsgNum;
  538. INT iMsgMax;
  539. BOOL bFound;
  540. M32 aw32Msg;
  541. PM32 paw32Msg;
  542. CHAR szMsg[40], *argv[2], szMsg32[40], szMsgName[40];
  543. CMD_INIT();
  544. ASSERT_CHECKED_WOW_PRESENT;
  545. GETEXPRVALUE(iMsgMax, "wow32!iMsgMax", INT);
  546. GETEXPRVALUE(paw32Msg, "wow32!paw32Msg", PM32);
  547. if( WDGetMSGProfArgs(lpArgumentString, szMsg, &iMsgNum) ) {
  548. helpMsgProfDmp();
  549. return;
  550. }
  551. PRINTF("%s %s\n%s\n", szMSG, szTITLES, szDASHES);
  552. if( iMsgNum > iMsgMax ) {
  553. PRINTF("MSG #%4d %s.\n", iMsgNum, szTOOBIG);
  554. return;
  555. }
  556. bFound = 0;
  557. for(iMsg = 0; iMsg < iMsgMax; iMsg++) {
  558. READMEM_XRET(aw32Msg, &paw32Msg[iMsg]);
  559. READMEM_XRET(szMsgName, aw32Msg.lpszW32);
  560. /* if specific msg name, parse name from "WM_MSGNAME 0x00XX" format */
  561. if( iMsgNum == -2 ) {
  562. lstrcpy(szMsg32, szMsgName);
  563. WDParseArgStr(szMsg32, argv, 1);
  564. }
  565. /* if 'all' msgs || specific msg # || specific msg name */
  566. if( (iMsgNum == -1) || (iMsg == iMsgNum) ||
  567. ( (iMsgNum == -2) && (!lstrcmp(szMsg, argv[0])) ) ) {
  568. bFound = 1;
  569. if(aw32Msg.cCalls) {
  570. PRINTF("0x%-4X %28s %7ld %15I64d %15I64d\n",
  571. iMsg,
  572. szMsgName,
  573. aw32Msg.cCalls,
  574. aw32Msg.cTics,
  575. aw32Msg.cTics/aw32Msg.cCalls);
  576. }
  577. /* else if MSG wasn't sent & we're not dumping the whole table */
  578. else if( iMsgNum != -1 ) {
  579. PRINTF("0x%-4X %28s %7ld %15ld %15ld\n",
  580. iMsgNum,
  581. szMsgName,
  582. 0L,
  583. 0L,
  584. 0L);
  585. }
  586. /* if we're not dumping the whole table, we're done */
  587. if( iMsgNum != -1 ) {
  588. return;
  589. }
  590. }
  591. }
  592. if( !bFound ) {
  593. PRINTF("\nCould not find MSG: %s\n", szMsg);
  594. helpMsgProfDmp();
  595. }
  596. return;
  597. }
  598. void
  599. msgprofrt(
  600. CMD_ARGLIST
  601. )
  602. {
  603. INT fWMsgProfRT;
  604. LPVOID lpAddress;
  605. CMD_INIT();
  606. ASSERT_CHECKED_WOW_PRESENT;
  607. GETEXPRADDR(lpAddress, "wow32!fWMsgProfRT");
  608. READMEM_XRET(fWMsgProfRT, lpAddress);
  609. fWMsgProfRT = 1 - fWMsgProfRT;
  610. WRITEMEM_XRET(lpAddress, fWMsgProfRT);
  611. if( fWMsgProfRT ) {
  612. PRINTF("\n%s ENABLED.\n%s\n\n", szRNDTRIP, szCLEAR);
  613. }
  614. else {
  615. PRINTF("\n%s DISABLED.\n%s\n\n", szRNDTRIP, szCLEAR);
  616. }
  617. return;
  618. }