Miscellaneous Heap Functions

[Previous] [Next]

In addition to the heap functions I've already mentioned, Windows offers several more. In this section, I'll just briefly mention them.

The ToolHelp functions (mentioned at the end of Chapter 4) allow you to enumerate a process's heaps as well as the allocations within those heaps. For more information, look up the following functions in the Platform SDK documentation: Heap32First, Heap32Next, Heap32ListFirst, and Heap32ListNext. What's great about the ToolHelp functions is that they are available in both Windows 98 and Windows 2000.

The remaining heap functions discussed in this section exist only in Windows 2000.

Since a process can have multiple heaps within its address space, the GetProcessHeaps function allows you to get the handles of the existing heaps:

 DWORD GetProcessHeaps( DWORD dwNumHeaps, PHANDLE pHeaps); 

To call GetProcessHeaps, you must first allocate an array of HANDLEs and then call the function as follows:

 HANDLE hHeaps[25]; DWORD dwHeaps = GetProcessHeaps(25, hHeaps); if (dwHeaps > 25) { // More heaps are in this process than we expected. } else { // hHeaps[0] through hHeap[dwHeaps - 1] // identify the existing heaps. } 

Note that the handle of your process's default heap is also included in the array of heap handles when this function returns. The HeapValidate function validates the integrity of a heap:

 BOOL HeapValidate( HANDLE hHeap, DWORD fdwFlags, LPCVOID pvMem); 

You will usually call this function by passing a heap handle, a flag of 0 (the only other legal flag is HEAP_NO_SERIALIZE), and NULL for pvMem. This function will then walk the blocks within the heap, making sure that no blocks are corrupt. To make the function execute faster, you might want to pass the address of a specific block for the pvMem parameter. Doing so causes the function to check the validity of only the single block.

To coalesce free blocks within a heap and also decommit any pages of storage that do not contain allocated heap blocks, you can call

 UINT HeapCompact( HANDLE hHeap, DWORD fdwFlags); 

Normally, you'll pass 0 for the fdwFlags parameter, but you can also pass HEAP_NO_SERIALIZE.

The next two functions, HeapLock and HeapUnlock, are used together:

 BOOL HeapLock(HANDLE hHeap); BOOL HeapUnlock(HANDLE hHeap); 

These functions are for thread synchronization purposes. When you call HeapLock, the calling thread becomes the owner of the specified heap. If any other thread calls a heap function (specifying the same heap handle), the system will suspend the calling thread and not allow it to wake until the heap is unlocked by calling HeapUnlock.

Functions such as HeapAlloc, HeapSize, HeapFree, and so on call HeapLock and HeapUnlock internally to make sure that access to the heap is serialized. It would be unusual for you ever to have to call HeapLock or HeapUnlock yourself.

The final heap function is HeapWalk:

 BOOL HeapWalk( HANDLE hHeap, PPROCESS_HEAP_ENTRY pHeapEntry); 

This function is useful for debugging purposes only. It allows you to walk the contents of a heap. You will call this function multiple times. Each time, you'll pass in the address of a PROCESS_HEAP_ENTRY structure that you must allocate and initialize:

 typedef struct _PROCESS_HEAP_ENTRY { PVOID lpData; DWORD cbData; BYTE cbOverhead; BYTE iRegionIndex; WORD wFlags; union { struct { HANDLE hMem; DWORD dwReserved[ 3 ]; } Block; struct { DWORD dwCommittedSize; DWORD dwUnCommittedSize; LPVOID lpFirstBlock; LPVOID lpLastBlock; } Region; }; } PROCESS_HEAP_ENTRY, *LPPROCESS_HEAP_ENTRY, *PPROCESS_HEAP_ENTRY; 

When you start enumerating the blocks in the heap, you ll have to set the lpData member to NULL. This tells HeapWalk to initialize the members inside the structure. You can examine the members of the structure after each successful call to HeapWalk. To get to the next block in the heap, you just call HeapWalk again, passing the same heap handle and the address of the PROCESS_HEAP_ENTRY structure you passed on the previous call. When HeapWalk returns FALSE, there are no more blocks in the heap. See the Platform SDK documentation for a description of the members in the structure.

You will probably want to use the HeapLock and HeapUnlock functions around your HeapWalk loop so that other threads cannot allocate and free blocks of memory inside the heap while you re walking it.



Programming Applications for Microsoft Windows
Programming Applications for Microsoft Windows (Microsoft Programming Series)
ISBN: 1572319968
EAN: 2147483647
Year: 1999
Pages: 193

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net