windows-nt/Source/XPSP1/NT/base/mvdm/vdmexts/dos.c
2020-09-26 16:20:57 +08:00

437 lines
10 KiB
C

/*++
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 <precomp.h>
#pragma hdrstop
#include <doswow.h>
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: <Error Reading Memory>\n", selector);
break;
}
if ((Sig != 'M') && (Sig != 'Z')) {
PRINTF("%04x:0000: <Invalid DOS heap block>\n", selector);
break;
}
if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)+1), &Owner, 2)) {
PRINTF("%04x:0001: <Error Reading Memory>\n", selector);
break;
}
if (!READMEM((LPVOID)(GetIntelBase()+(selector<<4)+3), &Size, 2)) {
PRINTF("%04x:0003: <Error Reading Memory>\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: <Error Reading Memory>\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: <Error Reading Memory>\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: <Error Reading Memory>\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: <Error Reading Memory>\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("<Error Reading puscurrentpdb at %.8x>\n", ppdb);
return;
}
}
if (!READMEM((LPVOID)(GetIntelBase()+((ULONG)(pdb)<<4)), &DosPdb, sizeof(DosPdb))) {
PRINTF("<Error Reading PDB at &%.4x:0000> (%x)\n", pdb,(GetIntelBase()+((ULONG)(pdb)<<4)));
return;
}
if (!bDumpAll && (Fh >= DosPdb.PDB_JFN_Length)) {
PRINTF("<File handle %.2x out of range (0:%.02X)>\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("<Error Reading JFT at %.8x>\n", pJfn + Fh);
return;
}
if (SftIndex != 0xff) {
PRINTF("%.2X ", Fh);
DumpSFT((USHORT)SftIndex, FALSE);
}
}
} else {
if (!READMEM((LPVOID)(pJfn + Fh),
&SftIndex, sizeof(SftIndex))) {
PRINTF("<Error Reading JFT at %.8x>\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("<Error Reading Environment at &%.4x:0 (%.8x)>\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("<malformed environment string, halting dump>\n");
return FALSE;
}
PRINTF(" %s\n", pch);
pch += strlen(pch) + 1;
}
if (pch >= pchLimit) {
PRINTF("<Environment exceeded 32k, dump halted>\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("<Environment exceeded 32k, dump halted>\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("<Environment exceeded 32k, dump halted>\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 <bPMode> <segEnv>
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("<Error Reading puscurrentpdb at %.8x>\n", ppdb);
return;
}
PRINTF("Current PDB is 0x%x\n", pdb);
if (!READMEM((LPVOID)(GetIntelBase()+((ULONG)(pdb)<<4)), &DosPdb, sizeof(DosPdb))) {
PRINTF("<Error Reading PDB at &%.4x:0000>\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);
}
}