/*++ Copyright (c) 1990 Microsoft Corporation Module Name: ntsdexts.c Abstract: This function contains miscellaneous DOS VDMEXTS functions Author: Neil Sandlin (NeilSa) 29-Jul-1996 Wrote it Revision History: --*/ #include #pragma hdrstop #include VOID ddh( CMD_ARGLIST ) /* Dump DOS Heap */ { DWORD selector; BYTE Sig; WORD Size; WORD Owner; int count = 0; char Module[9]; CMD_INIT(); if (!GetNextToken()) { WORD wSegment, wSelector; LONG lOffset; int Mode; if (!FindAddress("arena_head", Module, &wSegment, &wSelector, &lOffset, &Mode, FALSE)) { PRINTF("Can't find symbol ntdos!arena_head\n"); return; } if (!READMEM((LPVOID)(GetIntelBase()+(wSelector<<4)+lOffset), &wSelector, 2)) { PRINTF("Error reading ntdos!arena_head\n"); return; } selector = wSelector; } else { selector = (DWORD) EXPRESSION(lpArgumentString); } PRINTF("DOS memory chain dump\n\n"); PRINTF(" Addr Sig Size Owner\n"); PRINTF("--------- --- ---- --------\n"); while (1) { if (selector > 0x10000) { PRINTF("%08x: Segment value out of range (> 1MB)\n", selector); break; } if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)), &Sig, 1)) { PRINTF("%04x:0000: \n", selector); break; } if ((Sig != 'M') && (Sig != 'Z')) { PRINTF("%04x:0000: \n", selector); break; } if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)+1), &Owner, 2)) { PRINTF("%04x:0001: \n", selector); break; } if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)+3), &Size, 2)) { PRINTF("%04x:0003: \n", selector); break; } PRINTF("%04x:0000: %c %.04X ", selector, Sig, Size); if (Owner == 0) { PRINTF(" Free\n"); } else if (Owner<=8) { PRINTF(" System\n"); } else { if (!READMEM((LPVOID)(GetIntelBase()+((Owner-1)<<4)+8), Module, 8)) { PRINTF("%04x:0008: \n", selector); break; } Module[8] = 0; PRINTF(" %s\n", Module); } if ((Sig == 'Z') && (selector>0x9ffe)) { break; } selector += Size; selector ++; } } BOOL DumpSFT( USHORT index, BOOL Verbose ) { USHORT usSFN = index; ULONG pSfFlat; ULONG pSftFlat; DOSSF DosSf; DOSSFT DosSft; USHORT usSFTCount; ULONG ulSFLink; if (!ReadMemExpression("ntvdm!pSFTHead", &pSfFlat, sizeof(pSfFlat))) { return FALSE; } if (!READMEM((LPVOID)(pSfFlat), &DosSf, sizeof(DosSf))) { PRINTF("%08x: \n", pSfFlat); return FALSE; } // Find the right SFT group while (usSFN >= (usSFTCount = DosSf.SFCount)){ usSFN = usSFN - usSFTCount; ulSFLink = DosSf.SFLink; if (LOWORD(ulSFLink) == 0xffff) return FALSE; pSfFlat = (((ULONG)(HIWORD(ulSFLink))<<4) + LOWORD(ulSFLink)) + GetIntelBase(); if (!READMEM((LPVOID)(+pSfFlat), &DosSf, sizeof(DosSf))) { PRINTF("%08x: \n", pSfFlat); return FALSE; } } // Get the begining of SFT pSftFlat = (ULONG)&(((PDOSSF)pSfFlat)->SFTable); pSftFlat += usSFN*sizeof(DOSSFT); if (!READMEM((LPVOID)(pSftFlat), &DosSft, sizeof(DosSft))) { PRINTF("%08x: \n", pSftFlat); return FALSE; } PRINTF("%.2X(%.8X) %.4X %.4X %.2X %.4X %.8X %.4X %.8X\n", (UCHAR)index, pSftFlat, DosSft.SFT_Ref_Count, DosSft.SFT_Mode, DosSft.SFT_Attr, DosSft.SFT_Flags, DosSft.SFT_Devptr, DosSft.SFT_PID, DosSft.SFT_NTHandle); if (Verbose) { PRINTF(" %.4X %.4X %.8X %.8X %.8X\n", DosSft.SFT_Time, DosSft.SFT_Date, DosSft.SFT_Size, DosSft.SFT_Position, DosSft.SFT_Chain); } return TRUE; } VOID dsft( CMD_ARGLIST ) /* Dump DOS system SFT */ { USHORT i; CMD_INIT(); PRINTF("SFT Ref Mode At Flgs Devptr PID NTHandle\n"); if (GetNextToken()) { DumpSFT((USHORT) EXPRESSION(lpArgumentString), FALSE); return; } for (i=0; i<255; i++) { if (!DumpSFT(i, FALSE)) { break; } } } VOID dfh( CMD_ARGLIST ) /* Dump File handle */ { DOSPDB DosPdb; BOOL bDumpAll = TRUE; BOOL bUseCurrentPDB = TRUE; USHORT pdb; ULONG ppdb; UCHAR Fh; ULONG pJfn; UCHAR SftIndex; CMD_INIT(); if (GetNextToken()) { if (*lpArgumentString == '*') { SkipToNextWhiteSpace(); } else { Fh = (UCHAR)EvaluateToken(); bDumpAll = FALSE; } if (GetNextToken()) { pdb = (USHORT)EvaluateToken(); bUseCurrentPDB = FALSE; } } if (bUseCurrentPDB) { if (!ReadMemExpression("ntvdm!puscurrentpdb", &ppdb, sizeof(ppdb))) { return; } if (!READMEM((LPVOID)(ppdb), &pdb, sizeof(pdb))) { PRINTF("\n", ppdb); return; } } if (!READMEM((LPVOID)(GetIntelBase()+((ULONG)(pdb)<<4)), &DosPdb, sizeof(DosPdb))) { PRINTF(" (%x)\n", pdb,(GetIntelBase()+((ULONG)(pdb)<<4))); return; } if (!bDumpAll && (Fh >= DosPdb.PDB_JFN_Length)) { PRINTF("\n", Fh, DosPdb.PDB_JFN_Length); return; } pJfn = GetIntelBase() + ((ULONG)(HIWORD(DosPdb.PDB_JFN_Pointer))<<4) + LOWORD(DosPdb.PDB_JFN_Pointer); #if 0 PRINTF("%.8X %.8X %.8X\n", GetIntelBase(), (ULONG)(HIWORD(DosPdb.PDB_JFN_Pointer))<<4, (ULONG)LOWORD(DosPdb.PDB_JFN_Pointer)); PRINTF("pdb=%.4X pjfn=%.8X ljfn=%.4X Flat=%.8X\n", pdb, DosPdb.PDB_JFN_Pointer, DosPdb.PDB_JFN_Length, pJfn); #endif PRINTF("fh SFT Ref Mode At Flgs Devptr PID NTHandle\n"); if (bDumpAll) { for (Fh = 0; Fh < DosPdb.PDB_JFN_Length; Fh++) { if (!READMEM((LPVOID)(pJfn + Fh), &SftIndex, sizeof(SftIndex))) { PRINTF("\n", pJfn + Fh); return; } if (SftIndex != 0xff) { PRINTF("%.2X ", Fh); DumpSFT((USHORT)SftIndex, FALSE); } } } else { if (!READMEM((LPVOID)(pJfn + Fh), &SftIndex, sizeof(SftIndex))) { PRINTF("\n", pJfn + Fh); return; } if (SftIndex != 0xff) { PRINTF("%.2X ", Fh); DumpSFT((USHORT)SftIndex, FALSE); } else { PRINTF("Handle %.2X is not open\n", Fh); } } } BOOL DumpEnvironment(WORD segEnv, int mode) { char rgchEnv[32768]; char *pch; char *pchLimit; if (!READMEM((LPVOID)(GetIntelBase() + GetInfoFromSelector(segEnv, mode, NULL)), rgchEnv, sizeof(rgchEnv))) { PRINTF("\n", segEnv, GetIntelBase() + (segEnv << 4)); return FALSE; } // // Dump each string in environment block until // double-null termination. // pch = rgchEnv; pchLimit = rgchEnv + sizeof(rgchEnv); while (pch < pchLimit && *pch) { if (!strchr(pch, '=')) { PRINTF("\n"); return FALSE; } PRINTF(" %s\n", pch); pch += strlen(pch) + 1; } if (pch >= pchLimit) { PRINTF("\n", pch); return FALSE; } // // pch now points at the second null of the double-null termination, // advance past this null and dump the magic word that follows and // the EXE path after that. // pch++; if (pch >= pchLimit - 1) { PRINTF("\n", pch); return FALSE; } if (1 != *(WORD UNALIGNED *)pch) { PRINTF("\nMagic word after double-null IS NOT ONE, dump halted: 0x%x\n", *(WORD UNALIGNED *)pch); return FALSE; } pch += sizeof(WORD); if ( (pch + strlen(pch) + 1) > pchLimit) { PRINTF("\n", pch); return FALSE; } PRINTF("EXE path: <%s>\n", pch); return TRUE; } VOID denv( CMD_ARGLIST ) /* Dump environment block for current DOS process or given environment selector !denv Examples: !denv - Dumps environment for current DOS process !denv 0 145d - Dumps DOS environment at &145d:0 (145d from PDB_environ of DOS process) !denv 1 16b7 - Dumps DOS environment at #16b7:0 (16b7 from !dt -v segEnvironment) */ { DOSPDB DosPdb; BOOL bUseCurrentPDB = TRUE; USHORT pdb; USHORT segEnv; ULONG ppdb; int mode = PROT_MODE; CMD_INIT(); if (GetNextToken()) { mode = (int)EvaluateToken(); if (GetNextToken()) { segEnv = (USHORT)EvaluateToken(); bUseCurrentPDB = FALSE; } } if (bUseCurrentPDB) { if (!ReadMemExpression("ntvdm!puscurrentpdb", &ppdb, sizeof(ppdb))) { return; } if (!READMEM((LPVOID)(GetIntelBase()+ppdb), &pdb, sizeof(pdb))) { PRINTF("\n", ppdb); return; } PRINTF("Current PDB is 0x%x\n", pdb); if (!READMEM((LPVOID)(GetIntelBase()+((ULONG)(pdb)<<4)), &DosPdb, sizeof(DosPdb))) { PRINTF("\n", pdb); return; } segEnv = DosPdb.PDB_environ; // // Guess mode for current PDB's PDB_environ (could be real or PM depending // on where we are in dosx). // if ( (segEnv & 0x7) == 0x7 ) { mode = PROT_MODE; } else { mode = V86_MODE; } } PRINTF("Environment %s is 0x%x\n", mode ? "selector" : "segment", segEnv); if (segEnv) { DumpEnvironment(segEnv, mode); } }