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

📄 lmem.c

📁 可用于嵌入式编程学习
💻 C
📖 第 1 页 / 共 2 页
字号:
    @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;
}

⌨️ 快捷键说明

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