枚举堆
下面的示例演示如何使用 HeapWalk 函数枚举堆。
首先,该示例使用 HeapCreate 函数创建专用堆。 然后,它使用 HeapLock 锁定堆,以便其他线程在枚举堆时无法访问该堆。 然后,该示例使用指向PROCESS_HEAP_ENTRY结构的指针调用 HeapWalk,并循环访问堆,将每个条目打印到控制台。
枚举完成后,该示例使用 HeapUnlock 解锁堆,以便其他线程可以访问它。 最后,该示例调用 HeapDestroy 来销毁专用堆。
#include <windows.h>
#include <tchar.h>
#include <stdio.h>
int __cdecl _tmain()
{
DWORD LastError;
HANDLE hHeap;
PROCESS_HEAP_ENTRY Entry;
//
// Create a new heap with default parameters.
//
hHeap = HeapCreate(0, 0, 0);
if (hHeap == NULL) {
_tprintf(TEXT("Failed to create a new heap with LastError %d.\n"),
GetLastError());
return 1;
}
//
// Lock the heap to prevent other threads from accessing the heap
// during enumeration.
//
if (HeapLock(hHeap) == FALSE) {
_tprintf(TEXT("Failed to lock heap with LastError %d.\n"),
GetLastError());
return 1;
}
_tprintf(TEXT("Walking heap %#p...\n\n"), hHeap);
Entry.lpData = NULL;
while (HeapWalk(hHeap, &Entry) != FALSE) {
if ((Entry.wFlags & PROCESS_HEAP_ENTRY_BUSY) != 0) {
_tprintf(TEXT("Allocated block"));
if ((Entry.wFlags & PROCESS_HEAP_ENTRY_MOVEABLE) != 0) {
_tprintf(TEXT(", movable with HANDLE %#p"), Entry.Block.hMem);
}
if ((Entry.wFlags & PROCESS_HEAP_ENTRY_DDESHARE) != 0) {
_tprintf(TEXT(", DDESHARE"));
}
}
else if ((Entry.wFlags & PROCESS_HEAP_REGION) != 0) {
_tprintf(TEXT("Region\n %d bytes committed\n") \
TEXT(" %d bytes uncommitted\n First block address: %#p\n") \
TEXT(" Last block address: %#p\n"),
Entry.Region.dwCommittedSize,
Entry.Region.dwUnCommittedSize,
Entry.Region.lpFirstBlock,
Entry.Region.lpLastBlock);
}
else if ((Entry.wFlags & PROCESS_HEAP_UNCOMMITTED_RANGE) != 0) {
_tprintf(TEXT("Uncommitted range\n"));
}
else {
_tprintf(TEXT("Block\n"));
}
_tprintf(TEXT(" Data portion begins at: %#p\n Size: %d bytes\n") \
TEXT(" Overhead: %d bytes\n Region index: %d\n\n"),
Entry.lpData,
Entry.cbData,
Entry.cbOverhead,
Entry.iRegionIndex);
}
LastError = GetLastError();
if (LastError != ERROR_NO_MORE_ITEMS) {
_tprintf(TEXT("HeapWalk failed with LastError %d.\n"), LastError);
}
//
// Unlock the heap to allow other threads to access the heap after
// enumeration has completed.
//
if (HeapUnlock(hHeap) == FALSE) {
_tprintf(TEXT("Failed to unlock heap with LastError %d.\n"),
GetLastError());
}
//
// When a process terminates, allocated memory is reclaimed by the operating
// system so it is not really necessary to call HeapDestroy in this example.
// However, it may be advisable to call HeapDestroy in a longer running
// application.
//
if (HeapDestroy(hHeap) == FALSE) {
_tprintf(TEXT("Failed to destroy heap with LastError %d.\n"),
GetLastError());
}
return 0;
}
以下输出显示了新创建的堆的典型结果。
Walking heap 0X00530000...
Region
4096 bytes committed
258048 bytes uncommitted
First block address: 0X00530598
Last block address: 0X00570000
Data portion begins at: 0X00530000
Size: 1416 bytes
Overhead: 0 bytes
Region index: 0
Block
Data portion begins at: 0X005307D8
Size: 2056 bytes
Overhead: 16 bytes
Region index: 0
Uncommitted range
Data portion begins at: 0X00531000
Size: 258048 bytes
Overhead: 0 bytes
Region index: 0