summaryrefslogblamecommitdiffstats
path: root/private/mvdm/bde/bdeheap.c
blob: f9deed96dc9f98346346320794b4f64d406430b5 (plain) (tree)






















































































































































































































































































































                                                                             
#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");

    }

}