⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 heap.c

📁 不错的东西 请查看 WINCE OS
💻 C
📖 第 1 页 / 共 5 页
字号:
//
// Copyright (c) Microsoft Corporation.  All rights reserved.
//
//
// This source code is licensed under Microsoft Shared Source License
// Version 1.0 for Windows CE.
// For a copy of the license visit http://go.microsoft.com/fwlink/?LinkId=3223.
//
#include <windows.h>
#include <coredll.h>
#include "heap.h"
#include <celogcoredll.h>
#include "lmemdebug.h"

// Make sure that no macro are redirecting LocalAlloc & HeapAlloc
#undef LocalAlloc
#undef HeapAlloc

#ifndef FREE_POINTER_AT_LAST_FREE
#define FREE_POINTER_AT_LAST_FREE
#endif

#ifdef MEMTRACKING
DWORD dwHeapMemType;
#endif

#define PAGE_SIZE (UserKInfo[KINX_PAGESIZE])
#define HEAP_MAX_ALLOC 0x40000000   // Maximum allocation request is 1GB.

DWORD PageMask;
LPVOID PSlot;       // Address of the current process's "memory slot"
HANDLE hProcessHeap;
pheap phpListAll;
CRITICAL_SECTION csHeapList;

#ifdef HEAP_STATISTICS
#define NUM_ALLOC_BUCKETS 64
#define BUCKET_VIRTUAL (NUM_ALLOC_BUCKETS - 1)
#define BUCKET_LARGE   (NUM_ALLOC_BUCKETS - 2)
LONG lNumAllocs[NUM_ALLOC_BUCKETS];
#endif

PFN_HeapCreate ptrHeapCreate = Int_HeapCreate;
PFN_HeapDestroy ptrHeapDestroy = Int_HeapDestroy;
PFN_HeapAlloc ptrHeapAlloc = Int_HeapAlloc;
PFN_HeapAllocTrace ptrHeapAllocTrace;
PFN_HeapReAlloc ptrHeapReAlloc = Int_HeapReAlloc;
PFN_HeapSize ptrHeapSize = Int_HeapSize;
PFN_HeapFree ptrHeapFree = Int_HeapFree;
extern PFN_CloseHandle v_pfnCloseHandle;
extern PFN_CreateEventW v_pfnCreateEventW;
extern PFN_LMEMAddTrackedItem v_pfnLMEMAddTrackedItem;
extern PFN_LMEMRemoveTrackedItem v_pfnLMEMRemoveTrackedItem;
extern PFN_SetAllocAdditionalData v_pfnSetAllocAdditionalData;

static LONG fFullyCompacted;

BOOL WINAPI LMemInit(void)
{
    HMODULE hLMemDebug;
    FARPROC ptrProc;

    PageMask = UserKInfo[KINX_PAGESIZE] - 1;
    DEBUGMSG(DBGFIXHP, (L"LMemInit\r\n"));
    // Uncomment the line below for "mapped heaps"
    PSlot = (char*)MapPtrUnsecure(&PSlot, GetCurrentProcess()) - (DWORD)&PSlot;

    // Check to see if there is a LMemDebug library.
    hLMemDebug = (HMODULE)LoadDriver(LMEMDEBUG_DLL);
    if (NULL != hLMemDebug) {
        RETAILMSG (1, (TEXT("Loaded LMemDebug in process\r\n")));

        // Fetch the debug alloc functions.
        ptrProc = GetProcAddress(hLMemDebug, TEXT("HeapCreate"));
        if (ptrProc) {
            ptrHeapCreate = (PFN_HeapCreate)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("HeapDestroy"));
        if (ptrProc) {
            ptrHeapDestroy = (PFN_HeapDestroy)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("HeapAlloc"));
        if (ptrProc) {
            ptrHeapAlloc = (PFN_HeapAlloc)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("HeapAllocTrace"));
        if (ptrProc) {
            ptrHeapAllocTrace = (PFN_HeapAllocTrace)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("HeapReAlloc"));
        if (ptrProc) {
            ptrHeapReAlloc = (PFN_HeapReAlloc)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("HeapFree"));
        if (ptrProc) {
            ptrHeapFree = (PFN_HeapFree)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("HeapSize"));
        if (ptrProc) {
            ptrHeapSize = (PFN_HeapSize)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("CloseHandle"));
        if (ptrProc) {
            v_pfnCloseHandle = (PFN_CloseHandle)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("CreateEventW"));
        if (ptrProc) {
            v_pfnCreateEventW = (PFN_CreateEventW)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("LMEMAddTrackedItem"));
        if (ptrProc) {
            v_pfnLMEMAddTrackedItem = (PFN_LMEMAddTrackedItem)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("LMEMRemoveTrackedItem"));
        if (ptrProc) {
            v_pfnLMEMRemoveTrackedItem = (PFN_LMEMRemoveTrackedItem)ptrProc;
        }
        ptrProc = GetProcAddress(hLMemDebug, TEXT("SetAllocAdditionalData"));
        if (ptrProc) {
            v_pfnSetAllocAdditionalData = (PFN_SetAllocAdditionalData)ptrProc;
        }
    }
#ifdef MEMTRACKING
    dwHeapMemType = RegisterTrackedItem(L"Heaps");
#endif
    InitializeCriticalSection(&csHeapList);
    if ((hProcessHeap = HeapCreate(0, 0, 0)) == NULL)
        return FALSE;
    ((pheap)hProcessHeap)->flOptions |= HEAP_IS_PROC_HEAP;
#ifdef MEMTRACKING
    ((pheap)hProcessHeap)->dwMemType = RegisterTrackedItem(L"Local Memory");
#endif
    if (IsCeLogStatus(CELOGSTATUS_ENABLED_GENERAL)) {
        CELOG_HeapCreate(HEAP_IS_PROC_HEAP, 0, CE_FIXED_HEAP_MAXSIZE, hProcessHeap);
    }
    DEBUGMSG(DBGFIXHP, (L"   LMemInit: Done   PSlot = %08x hProcessHeap = %08x\r\n", PSlot, hProcessHeap));
#ifdef HEAP_STATISTICS
    NKDbgPrintfW (L"Heap Statistics at 0x%08X", (DWORD) lNumAllocs | (DWORD) PSlot);
#endif
    return TRUE;
}


void LMemDeInit (void)
{
    // restore everything back to default since LMEMDebug has already been freed
    ptrHeapCreate = Int_HeapCreate;
    ptrHeapDestroy = Int_HeapDestroy;
    ptrHeapAlloc = Int_HeapAlloc;
    ptrHeapAllocTrace;
    ptrHeapReAlloc = Int_HeapReAlloc;
    ptrHeapSize = Int_HeapSize;
    ptrHeapFree = Int_HeapFree;
    v_pfnCloseHandle = NULL;
    v_pfnCreateEventW = NULL;
    v_pfnLMEMAddTrackedItem = NULL;
    v_pfnLMEMRemoveTrackedItem = NULL;
    v_pfnSetAllocAdditionalData = NULL;

}

#if defined(MEMTRACKING) && defined(MEM_ACCOUNT)
void TrackerCallback (DWORD dwFlags, DWORD dwType, HANDLE hItem, DWORD dwProc, BOOL fDeleted,
    DWORD dwSize, DWORD dw1, DWORD dw2) {
    PBYTE p = (PBYTE)hItem;
    if (!fDeleted && *(int*)p == 0x8482906) {
        NKDbgPrintfW (L"%a %i", p+4, *(int*)(p+20));
        if (!memcmp (p+4, "String", 7))
            NKDbgPrintfW (L"  :\"%s\"", p+24);
    }
    NKDbgPrintfW (L"\r\n");
}
#define TCB TrackerCallback
#else
#define TCB NULL
#endif

/*
    @doc BOTH EXTERNAL

    @func HLOCAL | LocalAlloc | Allocates a block of memory from the local heap
    @parm UINT | uFlags | flags for alloc operation
    @parm UINT | uBytes | desired size of block

    @comm Only fixed memory is supported, thus LMEM_MOVEABLE is invalid.
*/
HLOCAL WINAPI LocalAlloc(UINT uFlags, UINT uBytes) {
    LPVOID p;
    if(uFlags & ~LMEM_VALID_FLAGS) {
        DEBUGMSG(DBGLMEM, (L"   LocalAlloc %8.8lx %8.8lx ==> %8.8lx (invalid parameter)\r\n",uBytes,uFlags,0));
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }
    p = ptrHeapAlloc(hProcessHeap, (uFlags & LMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0, uBytes);
    DEBUGMSG(DBGLMEM, (L"   LocalAlloc %8.8lx %8.8lx ==> %8.8lx [%8.8lx]\r\n",uBytes,uFlags,p,Int_HeapSize(hProcessHeap,0,p)));
    return (HLOCAL)p;
}
HLOCAL WINAPI LocalAllocTrace(UINT uFlags, UINT uBytes, UINT dwLineNum, PCHAR szFilename) {
    LPVOID p;
    if(uFlags & ~LMEM_VALID_FLAGS) {
        DEBUGMSG(DBGLMEM, (L"   LocalAllocTrace %8.8lx %8.8lx ==> %8.8lx (invalid parameter)\r\n",uBytes,uFlags,0));
        SetLastError(ERROR_INVALID_PARAMETER);
        return NULL;
    }
    p = HeapAllocTrace(hProcessHeap, (uFlags & LMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0, uBytes, dwLineNum, szFilename);
    DEBUGMSG(DBGLMEM, (L"   LocalAllocTrace %8.8lx %8.8lx ==> %8.8lx [%8.8lx]\r\n",uBytes,uFlags,p,Int_HeapSize(hProcessHeap,0,p)));
    return (HLOCAL)p;
}


/*
    @doc BOTH EXTERNAL

    @func HLOCAL | LocalRealloc | Realloc's a LocalAlloc'ed block of memory
    @parm HLOCAL | hMem | handle of local memory object to realloc
    @parm UINT | uBytes | desired new size of block
    @parm UINT | uFlags | flags for realloc operation

    @comm Follows the Win32 reference description without restrictions
    or modifications.
*/
HLOCAL WINAPI LocalReAlloc(HLOCAL hMem, UINT uBytes, UINT uFlags) {
    LPVOID retval;
    UINT newflags;
    if((uFlags & ~(LMEM_VALID_FLAGS | LMEM_MODIFY )) ||
        ((uFlags & LMEM_DISCARDABLE) && !(uFlags & LMEM_MODIFY))) {
        DEBUGMSG(DBGLMEM, (L"   LocalRealloc %8.8lx %8.8lx %8.8lx ==> %8.8lx (invalid parameter)\r\n",hMem,uBytes,uFlags,0));
        SetLastError(ERROR_INVALID_PARAMETER);
        return(NULL);
    }
    newflags = ((uFlags & LMEM_ZEROINIT) ? HEAP_ZERO_MEMORY : 0) | ((uFlags & LMEM_MOVEABLE) ? 0 : HEAP_REALLOC_IN_PLACE_ONLY);
    retval = HeapReAlloc(hProcessHeap, newflags, hMem, uBytes);
    DEBUGMSG(DBGLMEM, (L"   LocalRealloc %8.8lx %8.8lx %8.8lx ==> %8.8lx [%8.8lx]\r\n",hMem,uBytes,uFlags,retval,Int_HeapSize(hProcessHeap,0,retval)));
    return (HLOCAL)retval;
}

/*
    @doc BOTH EXTERNAL

    @func UINT | LocalSize | Returns the size of a LocalAlloc'ed block of memory
    @parm HLOCAL | hMem | handle of local memory object to get size of

    @comm Follows the Win32 reference description without restrictions
    or modifications.
*/
UINT WINAPI LocalSize(HLOCAL hMem) {
    UINT retval;
    if ((retval = ptrHeapSize(hProcessHeap,0,hMem)) == (DWORD)-1)
        retval = 0;
    DEBUGMSG(DBGLMEM, (L"   LocalSize %8.8lx ==> %8.8lx\r\n",hMem,retval));
    return retval;
}

/*
    @doc BOTH EXTERNAL

    @func HLOCAL | LocalFree | Frees a LocalAlloc'ed block of memory
    @parm HLOCAL | hMem | handle of local memory object to free

    @comm Follows the Win32 reference description without restrictions
    or modifications.
*/
HLOCAL WINAPI LocalFree(HLOCAL hMem) {
    HLOCAL retval;
    if (retval = (!hMem || ptrHeapFree(hProcessHeap,0,(LPVOID)hMem)) ? NULL : hMem)
        SetLastError(ERROR_INVALID_PARAMETER);
    DEBUGMSG(DBGLMEM, (L"   LocalFree %8.8lx ==> %8.8lx\r\n",hMem,retval));
    return retval;
}


#if HEAP_SENTINELS
/** CheckSentinels() - verify allocated heap block sentinels
 */
BOOL CheckSentinels(pitem pit, BOOL bStopOnErr)
{
    int chSig = 0xA5;
    PBYTE pTail = (char*)(pit+1) + pit->cbTrueSize;
    int cbTail = (pit->size&~1) - sizeof(item) - pit->cbTrueSize;

    if (pit->dwSig != ALLOCSIGHEAD) {
        RETAILMSG(1, (L"CheckSentinels: Bad head signature @0x%08X  --> 0x%08X SHDB 0x%08X\r\n",
                pit, pit->dwSig, ALLOCSIGHEAD));
#ifdef DEBUG
        if (bStopOnErr)
            DebugBreak();
#endif
        return FALSE;
    }
    while (cbTail--) {
        if (*pTail != chSig) {
            RETAILMSG(1, (L"CheckSentinels: Bad tail signature item: 0x%08X  @0x%08X -> 0x%02x SHDB 0x%02x\r\n",
                    pit, pTail, *pTail, chSig));
#ifdef DEBUG
            if (bStopOnErr)
                DebugBreak();
#endif
            return FALSE;
        }
        ++pTail;
        chSig = chSig+1 & 0xFF;
    }
    return TRUE;
}

/** SetSentinels() - set allocated heap block sentinels
 */
void SetSentinels(pitem pit, int cbRequest)
{
    int chSig = 0xA5;
    int cbTail = (pit->size&~1) - cbRequest - sizeof(item);
    PBYTE pTail = (PBYTE)(pit+1) + cbRequest;

    DEBUGCHK((int)(pit->size - sizeof(pitem)) >= cbRequest+cbTail);
    pit->cbTrueSize = cbRequest;
    pit->dwSig = ALLOCSIGHEAD;
    while (cbTail--)
        *pTail++ = chSig++;
}

/** CheckFreeSentinels() - verify free heap block sentinels
 */
BOOL CheckFreeSentinels(pitem pit, BOOL bStopOnErr)
{
    PBYTE pTail = (PBYTE)(pit+1);
    int cbTail = sizeof(item) - pit->size;

    if (pit->dwSig != FREESIGHEAD) {
        RETAILMSG(1, (L"CheckFreeSentinels: Bad head signature @0x%08X  --> 0x%08X SHDB 0x%08X\r\n",
                pit, pit->dwSig, FREESIGHEAD));
#ifdef DEBUG
        if (bStopOnErr)
            DebugBreak();
#endif
        return FALSE;
    }
    if (pit->size > -(int)sizeof(item) || (pit->size & ALIGNBYTES-1) != 0) {
        RETAILMSG(1, (L"CheckFreeSentinels: Bogus size @0x%08X  --> 0x%08X \r\n", pit, pit->size));
#ifdef DEBUG
        if (bStopOnErr)
            DebugBreak();
#endif
        return FALSE;
    }
    return TRUE;
}

/** SetSentinels() - set heap block sentinels
 */
void SetFreeSentinels(pitem pit)
{
    PBYTE pTail = (PBYTE)(pit+1);
    int cbTail = -pit->size - sizeof(item);

    DEBUGCHK(pit->size <= -(int)sizeof(item) && (pit->size & ALIGNBYTES-1) == 0);
    pit->dwSig = FREESIGHEAD;
    pit->cbTrueSize = cbTail;
}
#endif

static LPVOID AllocMemShare (LPVOID pAddr, DWORD cbSize, DWORD fdwAction, LPDWORD pdwUnused)
{
    return CeVirtualSharedAlloc ((MEM_RESERVE & fdwAction)? NULL : pAddr, cbSize, fdwAction);
}

static LPVOID AllocMemVirt (LPVOID pAddr, DWORD cbSize, DWORD fdwAction, LPDWORD pdwUnused)
{

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -