?? lmem.c
字號(hào):
@parm DWORD | dwFlags | HEAP_NO_SERIALIZE and HEAP_ZERO_MEM supported
@parm DWORD | dwBytes | Desired size of block
*/
LPVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, DWORD dwBytes) {
LPVOID p;
DEBUGMSG(DBGLMEM, (L"HeapAlloc %8.8lx %8.8lx %8.8lx\r\n", hHeap,dwFlags,dwBytes));
if((dwFlags & ~(HEAP_NO_SERIALIZE | HEAP_ZERO_MEMORY)) || !hHeap) {
DEBUGMSG(DBGLMEM, (L" HeapAlloc %8.8lx %8.8lx %8.8lx ==> %8.8lx\r\n", hHeap,dwFlags,dwBytes,0));
SetLastError(ERROR_INVALID_PARAMETER);
return NULL;
}
EnterCriticalSection(&hcs);
if (!(p=FixedHeapAlloc((pheap)hHeap,dwBytes,(dwFlags & HEAP_ZERO_MEMORY?1:0))))
SetLastError(ERROR_NOT_ENOUGH_MEMORY);
#ifdef MEMTRACKING
if (p)
AddTrackedItem(((pheap)hHeap)->dwMemType,p,TCB,GetCurrentProcessId(),FixedHeapSize((pheap)hHeap,p),0,0);
#endif
CELOG_HeapAlloc(hHeap, dwFlags, dwBytes, (DWORD) p);
DEBUGMSG(DBGLMEM, (L" HeapAlloc %8.8lx %8.8lx %8.8lx ==> %8.8lx\r\n", hHeap,dwFlags,dwBytes,p));
DEBUGCHK(!p || ((FixedHeapSize((pheap)hHeap,p) >= dwBytes) && (FixedHeapSize((pheap)hHeap,p) != (DWORD)-1)));
LeaveCriticalSection(&hcs);
return p;
}
/*
@doc BOTH EXTERNAL
@func BOOL | HeapFree | Frees a HeapAlloc'ed block of memory
@parm HANDLE | hHeap | Handle returned from CreateHeap()
@parm DWORD | dwFlags | HEAP_NO_SERIALIZE only
@parm LPVOID | lpMem | Pointer to memory block
*/
BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
BOOL retval;
DEBUGMSG(DBGLMEM, (L"HeapFree %8.8lx %8.8lx %8.8lx\r\n",hHeap,dwFlags,lpMem));
if ((dwFlags & ~HEAP_NO_SERIALIZE) || !hHeap || !lpMem) {
DEBUGMSG(DBGLMEM, (L" HeapFree %8.8lx %8.8lx %8.8lx ==> %8.8lx\r\n", hHeap,dwFlags,lpMem,0));
SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
EnterCriticalSection(&hcs);
CELOG_HeapFree(hHeap, dwFlags, (DWORD)lpMem);
retval = FixedHeapFree((pheap)hHeap,lpMem);
#ifdef MEMTRACKING
if (retval)
DeleteTrackedItem(((pheap)hHeap)->dwMemType, lpMem);
#endif
DEBUGMSG(DBGLMEM, (L"HeapFree %8.8lx %8.8lx %8.8lx ==> %8.8lx\r\n",hHeap,dwFlags,lpMem,retval));
LeaveCriticalSection(&hcs);
return retval;
}
/*
@doc BOTH EXTERNAL
@func DWORD | HeapSize | Returns the size of a HeapAlloc'ed block of memory
@parm HANDLE | hHeap | Heap from which memory was alloc'ed
@parm DWORD | dwFlags | can be HEAP_NO_SERIALIZE
@parm LPVOID | lpMem | handle of local memory object to get size of
@comm Follows the Win32 reference description without restrictions
or modifications.
*/
DWORD WINAPI HeapSize(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
UINT retval;
DEBUGMSG(DBGLMEM, (L"HeapSize %8.8lx\r\n",lpMem));
if (dwFlags & ~HEAP_NO_SERIALIZE) {
DEBUGMSG(DBGLMEM, (L" HeapSize %8.8lx: Invalid parameter\r\n"));
SetLastError(ERROR_INVALID_PARAMETER);
return (DWORD)-1;
}
EnterCriticalSection(&hcs);
retval = FixedHeapSize(hHeap,lpMem);
DEBUGMSG(DBGLMEM, (L" HeapSize %8.8lx ==> %8.8lx\r\n",lpMem,retval));
LeaveCriticalSection(&hcs);
return retval;
}
/*
@doc BOTH EXTERNAL
@func BOOL | HeapDestroy | Destroys a heap and releases its memory
@parm HANDLE | hHeap | Handle returned from CreateHeap()
*/
BOOL WINAPI HeapDestroy(HANDLE hHeap) {
pheap pHeap = (heap *)hHeap;
pheap pHeapTrav, pHeapNext;
vaheapalloc *pva, *pvanext;
LPBYTE pMem;
#ifdef MEMTRACKING
LPVOID ptr;
#endif
DEBUGMSG(DBGLMEM, (L"HeapDestroy %8.8lx\r\n",hHeap));
if(!hHeap) {
SetLastError(ERROR_INVALID_PARAMETER);
DEBUGMSG(DBGLMEM, (L" HeapDestroy %8.8lx ==> %8.8lx\r\n", hHeap,0));
return FALSE;
}
CELOG_HeapDestroy(hHeap);
EnterCriticalSection(&hcs);
pva = pHeap->pVallocs;
while (pva) {
pvanext = pva->pnext;
#if MEMTRACKING
DeleteTrackedItem(pHeap->dwMemType, pva->pBase);
#endif
VirtualFree(pva->pBase,0,MEM_RELEASE);
FixedHeapFree(hHeap,pva);
pva = pvanext;
}
if (ProcessHeap.pNextHeap == pHeap)
ProcessHeap.pNextHeap = pHeap->pNextHeap;
else {
pHeapTrav = ProcessHeap.pNextHeap;
while (pHeapTrav->pNextHeap != pHeap)
pHeapTrav = pHeapTrav->pNextHeap;
pHeapTrav->pNextHeap = pHeap->pNextHeap;
}
pHeapTrav = pHeap;
while (pHeapTrav) {
pHeapNext = pHeapTrav->pGrowthHeap;
if (pHeapTrav->pMem) {
#ifdef MEMTRACKING
ptr = pHeapTrav->pMem;
do {
if (HEAPTOPTR(ptr) != pHeapTrav) { // don't free heap itself
if (!IsSigValid(pHeapTrav,ptr,1))
DEBUGCHK(0);
if (ISINUSE(ptr))
DeleteTrackedItem(pHeapTrav->dwMemType, HEAPTOPTR(ptr));
}
} while ((ptr = NEXTBLOCK(pHeapTrav, ptr)) != pHeapTrav->pMem);
#endif
pMem = pHeapTrav->pMem;
VirtualFree(pMem,pHeap->dwMaximumSize,MEM_DECOMMIT);
VirtualFree(pMem, 0, MEM_RELEASE);
}
pHeapTrav = pHeapNext;
}
LocalFree(pHeap);
#ifdef MEMTRACKING
DeleteTrackedItem(dwHeapMemType, hHeap);
#endif
LeaveCriticalSection(&hcs);
return TRUE;
}
void CompactAllHeaps(void) {
pheap pHeap, pHeap2;
EnterCriticalSection(&hcs);
for (pHeap = &ProcessHeap; pHeap; pHeap = pHeap->pNextHeap)
for (pHeap2 = pHeap; pHeap2; pHeap2 = pHeap2->pGrowthHeap)
FixedHeapCompact(pHeap2);
LeaveCriticalSection(&hcs);
}
/*
@doc BOTH EXTERNAL
@func HANDLE | GetProcessHeap | Obtains a handle to the heap of the
calling process
*/
HANDLE WINAPI GetProcessHeap(VOID) {
return (HANDLE)&ProcessHeap;
}
BOOL FillInOneHeap(THSNAP *pSnap, heap *pBaseHeap, TH32HEAPENTRY **ppNext) {
heap *pHeap;
LPBYTE ptr;
vaheapalloc *vaptr;
for (pHeap = pBaseHeap; pHeap; pHeap = pHeap->pGrowthHeap) {
if (ptr = pHeap->pMem) {
do {
if (!(*ppNext = (TH32HEAPENTRY *)THGrow(pSnap,sizeof(TH32HEAPENTRY))))
return FALSE;
(*ppNext)->heapentry.dwSize = sizeof(TH32HEAPENTRY);
(*ppNext)->heapentry.hHandle = (HANDLE)ptr;
(*ppNext)->heapentry.dwAddress = (DWORD)ptr;
(*ppNext)->heapentry.dwBlockSize = HDRSIZE + ITEMSIZE(ptr);
(*ppNext)->heapentry.dwFlags = ISFREE(ptr) ? LF32_FREE : ISDEAD(ptr) ? LF32_FREE | LF32_DECOMMIT : LF32_FIXED;
(*ppNext)->heapentry.dwLockCount = ISINUSE(ptr) ? 1 : 0;
(*ppNext)->heapentry.dwResvd = 0;
(*ppNext)->heapentry.th32ProcessID = GetCurrentProcessId();
(*ppNext)->heapentry.th32HeapID = (DWORD)pBaseHeap;
ppNext = &(*ppNext)->pNext;
} while ((ptr = NEXTBLOCK(pHeap, ptr)) != pHeap->pMem);
}
}
for (vaptr = pBaseHeap->pVallocs; vaptr; vaptr = vaptr->pnext) {
if (!(*ppNext = (TH32HEAPENTRY *)THGrow(pSnap,sizeof(TH32HEAPENTRY))))
return FALSE;
(*ppNext)->heapentry.dwSize = sizeof(TH32HEAPENTRY);
(*ppNext)->heapentry.hHandle = (HANDLE)vaptr->pBase;
(*ppNext)->heapentry.dwAddress = (DWORD)vaptr->pBase;
(*ppNext)->heapentry.dwBlockSize = vaptr->dwSize;
(*ppNext)->heapentry.dwFlags = LF32_FIXED | LF32_BIGBLOCK;
(*ppNext)->heapentry.dwLockCount = 1;
(*ppNext)->heapentry.dwResvd = 0;
(*ppNext)->heapentry.th32ProcessID = GetCurrentProcessId();
(*ppNext)->heapentry.th32HeapID = (DWORD)pBaseHeap;
ppNext = &(*ppNext)->pNext;
}
*ppNext = 0;
return TRUE;
}
BOOL GetHeapSnapshot(THSNAP *pSnap, BOOL bMainOnly, LPVOID *pDataPtr) {
heap *pHeap;
// Must set permissions since we're in a callback and it's possible pSnap is in an intermediate process
// context we can no longer see. We don't need to restore the old permissions, since when we return
// from this function, they'll be restored by the system
SetProcPermissions((DWORD)-1);
EnterCriticalSection(&hcs);
if (bMainOnly) {
if (!FillInOneHeap(pSnap,&ProcessHeap,(TH32HEAPENTRY **)pDataPtr)) {
LeaveCriticalSection(&hcs);
return FALSE;
}
} else {
TH32HEAPLIST **ppNext;
ppNext = (TH32HEAPLIST **)pDataPtr;
for (pHeap = &ProcessHeap; pHeap; pHeap = pHeap->pNextHeap) {
if (!(*ppNext = (TH32HEAPLIST *)THGrow(pSnap,sizeof(TH32HEAPLIST)))) {
LeaveCriticalSection(&hcs);
return FALSE;
}
(*ppNext)->heaplist.dwSize = sizeof(HEAPLIST32);
(*ppNext)->heaplist.th32ProcessID = GetCurrentProcessId();
(*ppNext)->heaplist.th32HeapID = (DWORD)pHeap;
(*ppNext)->heaplist.dwFlags = pHeap == &ProcessHeap ? HF32_DEFAULT : 0;
if (!FillInOneHeap(pSnap,pHeap,&(*ppNext)->pHeapEntry)) {
LeaveCriticalSection(&hcs);
return FALSE;
}
ppNext = &(*ppNext)->pNext;
}
*ppNext = 0;
}
LeaveCriticalSection(&hcs);
return TRUE;
}
?? 快捷鍵說(shuō)明
復(fù)制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號(hào)
Ctrl + =
減小字號(hào)
Ctrl + -