mirror of https://github.com/tongzx/nt5src
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
436 lines
10 KiB
/*++
|
|
|
|
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);
|
|
}
|
|
}
|