diff options
Diffstat (limited to 'private/mvdm/bde/bdeheap.c')
-rw-r--r-- | private/mvdm/bde/bdeheap.c | 311 |
1 files changed, 311 insertions, 0 deletions
diff --git a/private/mvdm/bde/bdeheap.c b/private/mvdm/bde/bdeheap.c new file mode 100644 index 000000000..f9deed96d --- /dev/null +++ b/private/mvdm/bde/bdeheap.c @@ -0,0 +1,311 @@ +#include <precomp.h> +#pragma hdrstop + + +BOOL bWalkOnly = FALSE; + +ULONG +GetHeapBase( + VOID + ) +{ + WORD selector; + SELECTORINFO si; + + //BUGBUG SLIMY SLIMY! Look around for a selector that appears to be + // the kernel heap + + for (selector=0x1bf; selector<0x1ff; selector+=8) { + + GetInfoFromSelector(selector, PROT_MODE, &si); + if ((!si.bSystem) && (!si.bCode) && (si.Limit>0xffff)) { + break; + } + si.Base = 0; + } + + return(si.Base + GetIntelBase()); + +} + + + +void +GetFileNameFromOwner( + LPSTR filename, + LPSTR OwnerName + ) +{ +} + + +VOID +GetSegmentOwnerInfo( + HEAPENTRY *he + ) +{ + BOOL b; + NEHEADER owner; + ULONG base; + UCHAR len; + int i; + ULONG offset; + WORD wTemp; + + he->SegmentNumber = -1; + he->OwnerName[0] = 0; + if (he->gnode.pga_owner == 0) { + strcpy(he->OwnerName, "free"); + return; + } else if (he->gnode.pga_owner>=0xFFF8) { + strcpy(he->OwnerName, "sentinel"); + return; + } + + + base = GetInfoFromSelector(he->gnode.pga_owner, PROT_MODE, NULL) + + GetIntelBase(); + + b = ReadProcessMem( + hCurrentProcess, + (LPVOID)base, + &owner, + sizeof(owner), + NULL + ); + + if (b) { + if (owner.ne_magic == 0x454e) { + + len = ReadByteSafe(base+owner.ne_restab); + if (len>8) { + len=8; + } + ReadProcessMem(hCurrentProcess, + (LPVOID) (base+owner.ne_restab+1), + he->OwnerName, + 8, + NULL + ); + + he->OwnerName[len] = 0; + if (!_stricmp(he->OwnerName, "kernel")) { + strcpy(he->FileName, "krnl386"); + } else { + strcpy(he->FileName, he->OwnerName); + } + + offset = owner.ne_segtab; + + for (i=0; i<owner.ne_cseg; i++) { + wTemp = ReadWordSafe(base+offset+8); //get handle + if (wTemp == he->gnode.pga_handle) { + he->SegmentNumber = i; + break; + } + offset += 10; + } + + } + } + +} + +BOOL +CheckGlobalHeap( + ) +{ + PGHI32 pghi; + DWORD offset; + DWORD count; + DWORD p; + GNODE32 gnode; + PBYTE pFault = NULL; + BOOL bError = FALSE; + + pghi = (PGHI32)GetHeapBase(); + offset = (DWORD) ReadWord(&pghi->hi_first); + + // + // If we get here, the caller wants us to scan the heap + // + + count = ReadWord(&pghi->hi_count); + + while ((offset != 0) && (count)) { + + p = (DWORD)pghi + offset; + + if (!ReadGNode32(p, &gnode)) { + + PRINTF("Error reading global heap!\n"); + return FALSE; + + } + + count--; + if (offset == gnode.pga_next) { + return TRUE; + } + offset = gnode.pga_next; + } + + PRINTF("Error: Kernel heap is corrupt!\n"); + return FALSE; +} + + +BOOL +FindHeapEntry( + HEAPENTRY *he, + BOOL bFindAny + ) +{ + PGHI32 pghi; + DWORD offset; + DWORD MaxEntries, count; + DWORD p; + PBYTE pFault = NULL; + BOOL bError = FALSE; + + pghi = (PGHI32)GetHeapBase(); + + // + // The caller has requested that we return the next heap + // entry since the last invocation, or the first entry. + // + + if (he->CurrentEntry == 0) { + + // get first entry + offset = (DWORD) ReadWord(&pghi->hi_first); + + } else { + if (he->CurrentEntry == he->NextEntry) { + return FALSE; + } + + // get next entry + offset = he->NextEntry; + + } + + he->CurrentEntry = offset; + + if (he->Selector == 0) { + + p = (DWORD)pghi + offset; + if (!ReadGNode32(p, &he->gnode)) { + + PRINTF("Error reading global heap!\n"); + return FALSE; + + } + + he->NextEntry = he->gnode.pga_next; + GetSegmentOwnerInfo(he); + return TRUE; + } + + // + // If we get here, the caller wants us to scan the heap + // + + MaxEntries = ReadWord(&pghi->hi_count); + count = 0; + + while ((offset != 0) && (count <= MaxEntries)) { + + p = (DWORD)pghi + offset; + + if (!ReadGNode32(p, &he->gnode)) { + + PRINTF("Error reading global heap!\n"); + return FALSE; + + } else { + + if (bFindAny) { + WORD sel = he->Selector; + + if (((sel|1)==((WORD)he->gnode.pga_handle|1)) || + ((sel|1)==((WORD)he->gnode.pga_owner|1))) { + he->NextEntry = he->gnode.pga_next; + GetSegmentOwnerInfo(he); + return TRUE; + } + + } else { + if ((he->Selector|1)==((WORD)he->gnode.pga_handle|1)) { + he->NextEntry = he->gnode.pga_next; + GetSegmentOwnerInfo(he); + return TRUE; + } + } + } + + count++; + if (offset == he->gnode.pga_next) { + break; + } + offset = he->gnode.pga_next; + he->CurrentEntry = offset; + } + + return FALSE; +} + + + +//************************************************************* +// dumpgheap xxx +// where xxx is the 16-bit protect mode selector of the +// Kernel global heap info. +// +//************************************************************* + + +VOID +DumpGHeap( + VOID + ) +{ + VDMCONTEXT ThreadContext; + int mode; + HEAPENTRY he = {0}; + SELECTORINFO si; + + mode = GetContext( &ThreadContext ); + + if (GetNextToken()) { + he.Selector = (WORD) EXPRESSION( lpArgumentString ); + } + + PRINTF("Arena Base Limit Hnd Own Fl Module Type Resid"); + PRINTF("\n"); + + PRINTF("===== ======== ======== ==== ==== == ======== ==== ====="); + PRINTF("\n"); + + while (FindHeapEntry(&he, TRUE)) { + + PRINTF("%.5x", he.CurrentEntry); + PRINTF(" %.8x", he.gnode.pga_address); + PRINTF(" %.8X", he.gnode.pga_size); + PRINTF(" %.4X", he.gnode.pga_handle); + PRINTF(" %.4X", he.gnode.pga_owner); + PRINTF(" %.2X", he.gnode.pga_flags); + PRINTF(" %8s", he.OwnerName); + + GetInfoFromSelector((WORD)(he.gnode.pga_handle | 1), PROT_MODE, &si); + + PRINTF(" %s", si.bCode ? "Code" : "Data"); + + if (he.SegmentNumber != -1) { + PRINTF(" %d", he.SegmentNumber); + } + PRINTF("\n"); + + } + +} |