Source code of Windows XP (NT5)
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.

436 lines
10 KiB

  1. /*++
  2. Copyright (c) 1990 Microsoft Corporation
  3. Module Name:
  4. ntsdexts.c
  5. Abstract:
  6. This function contains miscellaneous DOS VDMEXTS functions
  7. Author:
  8. Neil Sandlin (NeilSa) 29-Jul-1996 Wrote it
  9. Revision History:
  10. --*/
  11. #include <precomp.h>
  12. #pragma hdrstop
  13. #include <doswow.h>
  14. VOID
  15. ddh(
  16. CMD_ARGLIST
  17. )
  18. /*
  19. Dump DOS Heap
  20. */
  21. {
  22. DWORD selector;
  23. BYTE Sig;
  24. WORD Size;
  25. WORD Owner;
  26. int count = 0;
  27. char Module[9];
  28. CMD_INIT();
  29. if (!GetNextToken()) {
  30. WORD wSegment, wSelector;
  31. LONG lOffset;
  32. int Mode;
  33. if (!FindAddress("arena_head",
  34. Module, &wSegment, &wSelector, &lOffset, &Mode, FALSE)) {
  35. PRINTF("Can't find symbol ntdos!arena_head\n");
  36. return;
  37. }
  38. if (!READMEM((LPVOID)(GetIntelBase()+(wSelector<<4)+lOffset), &wSelector, 2)) {
  39. PRINTF("Error reading ntdos!arena_head\n");
  40. return;
  41. }
  42. selector = wSelector;
  43. } else {
  44. selector = (DWORD) EXPRESSION(lpArgumentString);
  45. }
  46. PRINTF("DOS memory chain dump\n\n");
  47. PRINTF(" Addr Sig Size Owner\n");
  48. PRINTF("--------- --- ---- --------\n");
  49. while (1) {
  50. if (selector > 0x10000) {
  51. PRINTF("%08x: Segment value out of range (> 1MB)\n", selector);
  52. break;
  53. }
  54. if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)), &Sig, 1)) {
  55. PRINTF("%04x:0000: <Error Reading Memory>\n", selector);
  56. break;
  57. }
  58. if ((Sig != 'M') && (Sig != 'Z')) {
  59. PRINTF("%04x:0000: <Invalid DOS heap block>\n", selector);
  60. break;
  61. }
  62. if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)+1), &Owner, 2)) {
  63. PRINTF("%04x:0001: <Error Reading Memory>\n", selector);
  64. break;
  65. }
  66. if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)+3), &Size, 2)) {
  67. PRINTF("%04x:0003: <Error Reading Memory>\n", selector);
  68. break;
  69. }
  70. PRINTF("%04x:0000: %c %.04X ", selector, Sig, Size);
  71. if (Owner == 0) {
  72. PRINTF(" Free\n");
  73. } else if (Owner<=8) {
  74. PRINTF(" System\n");
  75. } else {
  76. if (!READMEM((LPVOID)(GetIntelBase()+((Owner-1)<<4)+8), Module, 8)) {
  77. PRINTF("%04x:0008: <Error Reading Memory>\n", selector);
  78. break;
  79. }
  80. Module[8] = 0;
  81. PRINTF(" %s\n", Module);
  82. }
  83. if ((Sig == 'Z') && (selector>0x9ffe)) {
  84. break;
  85. }
  86. selector += Size;
  87. selector ++;
  88. }
  89. }
  90. BOOL
  91. DumpSFT(
  92. USHORT index,
  93. BOOL Verbose
  94. )
  95. {
  96. USHORT usSFN = index;
  97. ULONG pSfFlat;
  98. ULONG pSftFlat;
  99. DOSSF DosSf;
  100. DOSSFT DosSft;
  101. USHORT usSFTCount;
  102. ULONG ulSFLink;
  103. if (!ReadMemExpression("ntvdm!pSFTHead", &pSfFlat, sizeof(pSfFlat))) {
  104. return FALSE;
  105. }
  106. if (!READMEM((LPVOID)(pSfFlat), &DosSf, sizeof(DosSf))) {
  107. PRINTF("%08x: <Error Reading Memory>\n", pSfFlat);
  108. return FALSE;
  109. }
  110. // Find the right SFT group
  111. while (usSFN >= (usSFTCount = DosSf.SFCount)){
  112. usSFN = usSFN - usSFTCount;
  113. ulSFLink = DosSf.SFLink;
  114. if (LOWORD(ulSFLink) == 0xffff)
  115. return FALSE;
  116. pSfFlat = (((ULONG)(HIWORD(ulSFLink))<<4) + LOWORD(ulSFLink)) + GetIntelBase();
  117. if (!READMEM((LPVOID)(+pSfFlat), &DosSf, sizeof(DosSf))) {
  118. PRINTF("%08x: <Error Reading Memory>\n", pSfFlat);
  119. return FALSE;
  120. }
  121. }
  122. // Get the begining of SFT
  123. pSftFlat = (ULONG)&(((PDOSSF)pSfFlat)->SFTable);
  124. pSftFlat += usSFN*sizeof(DOSSFT);
  125. if (!READMEM((LPVOID)(pSftFlat), &DosSft, sizeof(DosSft))) {
  126. PRINTF("%08x: <Error Reading Memory>\n", pSftFlat);
  127. return FALSE;
  128. }
  129. PRINTF("%.2X(%.8X) %.4X %.4X %.2X %.4X %.8X %.4X %.8X\n",
  130. (UCHAR)index,
  131. pSftFlat,
  132. DosSft.SFT_Ref_Count,
  133. DosSft.SFT_Mode,
  134. DosSft.SFT_Attr,
  135. DosSft.SFT_Flags,
  136. DosSft.SFT_Devptr,
  137. DosSft.SFT_PID,
  138. DosSft.SFT_NTHandle);
  139. if (Verbose) {
  140. PRINTF(" %.4X %.4X %.8X %.8X %.8X\n",
  141. DosSft.SFT_Time,
  142. DosSft.SFT_Date,
  143. DosSft.SFT_Size,
  144. DosSft.SFT_Position,
  145. DosSft.SFT_Chain);
  146. }
  147. return TRUE;
  148. }
  149. VOID
  150. dsft(
  151. CMD_ARGLIST
  152. )
  153. /*
  154. Dump DOS system SFT
  155. */
  156. {
  157. USHORT i;
  158. CMD_INIT();
  159. PRINTF("SFT Ref Mode At Flgs Devptr PID NTHandle\n");
  160. if (GetNextToken()) {
  161. DumpSFT((USHORT) EXPRESSION(lpArgumentString), FALSE);
  162. return;
  163. }
  164. for (i=0; i<255; i++) {
  165. if (!DumpSFT(i, FALSE)) {
  166. break;
  167. }
  168. }
  169. }
  170. VOID
  171. dfh(
  172. CMD_ARGLIST
  173. )
  174. /*
  175. Dump File handle
  176. */
  177. {
  178. DOSPDB DosPdb;
  179. BOOL bDumpAll = TRUE;
  180. BOOL bUseCurrentPDB = TRUE;
  181. USHORT pdb;
  182. ULONG ppdb;
  183. UCHAR Fh;
  184. ULONG pJfn;
  185. UCHAR SftIndex;
  186. CMD_INIT();
  187. if (GetNextToken()) {
  188. if (*lpArgumentString == '*') {
  189. SkipToNextWhiteSpace();
  190. } else {
  191. Fh = (UCHAR)EvaluateToken();
  192. bDumpAll = FALSE;
  193. }
  194. if (GetNextToken()) {
  195. pdb = (USHORT)EvaluateToken();
  196. bUseCurrentPDB = FALSE;
  197. }
  198. }
  199. if (bUseCurrentPDB) {
  200. if (!ReadMemExpression("ntvdm!puscurrentpdb", &ppdb, sizeof(ppdb))) {
  201. return;
  202. }
  203. if (!READMEM((LPVOID)(ppdb), &pdb, sizeof(pdb))) {
  204. PRINTF("<Error Reading puscurrentpdb at %.8x>\n", ppdb);
  205. return;
  206. }
  207. }
  208. if (!READMEM((LPVOID)(GetIntelBase()+((ULONG)(pdb)<<4)), &DosPdb, sizeof(DosPdb))) {
  209. PRINTF("<Error Reading PDB at &%.4x:0000> (%x)\n", pdb,(GetIntelBase()+((ULONG)(pdb)<<4)));
  210. return;
  211. }
  212. if (!bDumpAll && (Fh >= DosPdb.PDB_JFN_Length)) {
  213. PRINTF("<File handle %.2x out of range (0:%.02X)>\n", Fh, DosPdb.PDB_JFN_Length);
  214. return;
  215. }
  216. pJfn = GetIntelBase() + ((ULONG)(HIWORD(DosPdb.PDB_JFN_Pointer))<<4) +
  217. LOWORD(DosPdb.PDB_JFN_Pointer);
  218. #if 0
  219. PRINTF("%.8X %.8X %.8X\n", GetIntelBase(), (ULONG)(HIWORD(DosPdb.PDB_JFN_Pointer))<<4, (ULONG)LOWORD(DosPdb.PDB_JFN_Pointer));
  220. PRINTF("pdb=%.4X pjfn=%.8X ljfn=%.4X Flat=%.8X\n", pdb, DosPdb.PDB_JFN_Pointer, DosPdb.PDB_JFN_Length, pJfn);
  221. #endif
  222. PRINTF("fh SFT Ref Mode At Flgs Devptr PID NTHandle\n");
  223. if (bDumpAll) {
  224. for (Fh = 0; Fh < DosPdb.PDB_JFN_Length; Fh++) {
  225. if (!READMEM((LPVOID)(pJfn + Fh),
  226. &SftIndex, sizeof(SftIndex))) {
  227. PRINTF("<Error Reading JFT at %.8x>\n", pJfn + Fh);
  228. return;
  229. }
  230. if (SftIndex != 0xff) {
  231. PRINTF("%.2X ", Fh);
  232. DumpSFT((USHORT)SftIndex, FALSE);
  233. }
  234. }
  235. } else {
  236. if (!READMEM((LPVOID)(pJfn + Fh),
  237. &SftIndex, sizeof(SftIndex))) {
  238. PRINTF("<Error Reading JFT at %.8x>\n", pJfn + Fh);
  239. return;
  240. }
  241. if (SftIndex != 0xff) {
  242. PRINTF("%.2X ", Fh);
  243. DumpSFT((USHORT)SftIndex, FALSE);
  244. } else {
  245. PRINTF("Handle %.2X is not open\n", Fh);
  246. }
  247. }
  248. }
  249. BOOL DumpEnvironment(WORD segEnv, int mode)
  250. {
  251. char rgchEnv[32768];
  252. char *pch;
  253. char *pchLimit;
  254. if (!READMEM((LPVOID)(GetIntelBase() + GetInfoFromSelector(segEnv, mode, NULL)),
  255. rgchEnv, sizeof(rgchEnv))) {
  256. PRINTF("<Error Reading Environment at &%.4x:0 (%.8x)>\n", segEnv, GetIntelBase() + (segEnv << 4));
  257. return FALSE;
  258. }
  259. //
  260. // Dump each string in environment block until
  261. // double-null termination.
  262. //
  263. pch = rgchEnv;
  264. pchLimit = rgchEnv + sizeof(rgchEnv);
  265. while (pch < pchLimit && *pch) {
  266. if (!strchr(pch, '=')) {
  267. PRINTF("<malformed environment string, halting dump>\n");
  268. return FALSE;
  269. }
  270. PRINTF(" %s\n", pch);
  271. pch += strlen(pch) + 1;
  272. }
  273. if (pch >= pchLimit) {
  274. PRINTF("<Environment exceeded 32k, dump halted>\n", pch);
  275. return FALSE;
  276. }
  277. //
  278. // pch now points at the second null of the double-null termination,
  279. // advance past this null and dump the magic word that follows and
  280. // the EXE path after that.
  281. //
  282. pch++;
  283. if (pch >= pchLimit - 1) {
  284. PRINTF("<Environment exceeded 32k, dump halted>\n", pch);
  285. return FALSE;
  286. }
  287. if (1 != *(WORD UNALIGNED *)pch) {
  288. PRINTF("\nMagic word after double-null IS NOT ONE, dump halted: 0x%x\n", *(WORD UNALIGNED *)pch);
  289. return FALSE;
  290. }
  291. pch += sizeof(WORD);
  292. if ( (pch + strlen(pch) + 1) > pchLimit) {
  293. PRINTF("<Environment exceeded 32k, dump halted>\n", pch);
  294. return FALSE;
  295. }
  296. PRINTF("EXE path: <%s>\n", pch);
  297. return TRUE;
  298. }
  299. VOID
  300. denv(
  301. CMD_ARGLIST
  302. )
  303. /*
  304. Dump environment block for current DOS process or given environment selector
  305. !denv <bPMode> <segEnv>
  306. Examples:
  307. !denv - Dumps environment for current DOS process
  308. !denv 0 145d - Dumps DOS environment at &145d:0 (145d from PDB_environ of DOS process)
  309. !denv 1 16b7 - Dumps DOS environment at #16b7:0 (16b7 from !dt -v segEnvironment)
  310. */
  311. {
  312. DOSPDB DosPdb;
  313. BOOL bUseCurrentPDB = TRUE;
  314. USHORT pdb;
  315. USHORT segEnv;
  316. ULONG ppdb;
  317. int mode = PROT_MODE;
  318. CMD_INIT();
  319. if (GetNextToken()) {
  320. mode = (int)EvaluateToken();
  321. if (GetNextToken()) {
  322. segEnv = (USHORT)EvaluateToken();
  323. bUseCurrentPDB = FALSE;
  324. }
  325. }
  326. if (bUseCurrentPDB) {
  327. if (!ReadMemExpression("ntvdm!puscurrentpdb", &ppdb, sizeof(ppdb))) {
  328. return;
  329. }
  330. if (!READMEM((LPVOID)(GetIntelBase()+ppdb), &pdb, sizeof(pdb))) {
  331. PRINTF("<Error Reading puscurrentpdb at %.8x>\n", ppdb);
  332. return;
  333. }
  334. PRINTF("Current PDB is 0x%x\n", pdb);
  335. if (!READMEM((LPVOID)(GetIntelBase()+((ULONG)(pdb)<<4)), &DosPdb, sizeof(DosPdb))) {
  336. PRINTF("<Error Reading PDB at &%.4x:0000>\n", pdb);
  337. return;
  338. }
  339. segEnv = DosPdb.PDB_environ;
  340. //
  341. // Guess mode for current PDB's PDB_environ (could be real or PM depending
  342. // on where we are in dosx).
  343. //
  344. if ( (segEnv & 0x7) == 0x7 ) {
  345. mode = PROT_MODE;
  346. } else {
  347. mode = V86_MODE;
  348. }
  349. }
  350. PRINTF("Environment %s is 0x%x\n", mode ? "selector" : "segment", segEnv);
  351. if (segEnv) {
  352. DumpEnvironment(segEnv, mode);
  353. }
  354. }