summaryrefslogtreecommitdiffstats
path: root/private/mvdm/bde/bdeheap.c
diff options
context:
space:
mode:
Diffstat (limited to 'private/mvdm/bde/bdeheap.c')
-rw-r--r--private/mvdm/bde/bdeheap.c311
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");
+
+ }
+
+}