Abrufen von Prozess-Heaps

In diesem Beispiel wird die Verwendung der GetProcessHeaps-Funktion veranschaulicht, um Handle zum Standardprozess-Heap und alle privaten Heaps abzurufen, die für den aktuellen Prozess aktiv sind.

Im Beispiel wird zweimal GetProcessHeaps aufgerufen, um zuerst die Größe des benötigten Puffers zu berechnen und erneut die Handle in den Puffer abzurufen. Der Puffer wird aus dem Standardprozess-Heap zugewiesen, indem der von GetProcessHeap zurückgegebene Handle verwendet wird. Im Beispiel wird die Startadresse jeder Heap auf die Konsole gedruckt. Anschließend wird die HeapFree-Funktion verwendet, um für den Puffer zugewiesenen Arbeitsspeicher freizugeben.

Die Anzahl der Heaps in einem Prozess kann variieren. Ein Prozess verfügt immer über mindestens einen Heap – den Standardprozess-Heap – und es hat möglicherweise eine oder mehrere private Heaps, die von der Anwendung oder von DLLs erstellt werden, die in den Adressraum des Prozesses geladen werden.

Beachten Sie, dass eine Anwendung heap-Funktionen nur auf seinem Standardprozess-Heap oder auf privaten Heaps aufrufen sollte, die die Anwendung erstellt hat; Das Aufrufen von Heapfunktionen auf einem privaten Heap, der von einer anderen Komponente gehört, kann zu einem nicht definierten Verhalten führen.

#include <windows.h>
#include <tchar.h>
#include <stdio.h>
#include <intsafe.h>

int __cdecl _tmain()
{
    DWORD NumberOfHeaps;
    DWORD HeapsIndex;
    DWORD HeapsLength;
    HANDLE hDefaultProcessHeap;
    HRESULT Result;
    PHANDLE aHeaps;
    SIZE_T BytesToAllocate;

    //
    // Retrieve the number of active heaps for the current process
    // so we can calculate the buffer size needed for the heap handles.
    //
    NumberOfHeaps = GetProcessHeaps(0, NULL);
    if (NumberOfHeaps == 0) {
        _tprintf(TEXT("Failed to retrieve the number of heaps with LastError %d.\n"),
                 GetLastError());
        return 1;
    }

    //
    // Calculate the buffer size.
    //
    Result = SIZETMult(NumberOfHeaps, sizeof(*aHeaps), &BytesToAllocate);
    if (Result != S_OK) {
        _tprintf(TEXT("SIZETMult failed with HR %d.\n"), Result);
        return 1;
    }

    //
    // Get a handle to the default process heap.
    //
    hDefaultProcessHeap = GetProcessHeap();
    if (hDefaultProcessHeap == NULL) {
        _tprintf(TEXT("Failed to retrieve the default process heap with LastError %d.\n"),
                 GetLastError());
        return 1;
    }

    //
    // Allocate the buffer from the default process heap.
    //
    aHeaps = (PHANDLE)HeapAlloc(hDefaultProcessHeap, 0, BytesToAllocate);
    if (aHeaps == NULL) {
        _tprintf(TEXT("HeapAlloc failed to allocate %d bytes.\n"),
                 BytesToAllocate);
        return 1;
    }

    // 
    // Save the original number of heaps because we are going to compare it
    // to the return value of the next GetProcessHeaps call.
    //
    HeapsLength = NumberOfHeaps;

    //
    // Retrieve handles to the process heaps and print them to stdout. 
    // Note that heap functions should be called only on the default heap of the process
    // or on private heaps that your component creates by calling HeapCreate.
    //
    NumberOfHeaps = GetProcessHeaps(HeapsLength, aHeaps);
    if (NumberOfHeaps == 0) {
        _tprintf(TEXT("Failed to retrieve heaps with LastError %d.\n"),
                 GetLastError());
        return 1;
    }
    else if (NumberOfHeaps > HeapsLength) {

        //
        // Compare the latest number of heaps with the original number of heaps.
        // If the latest number is larger than the original number, another
        // component has created a new heap and the buffer is too small.
        //
        _tprintf(TEXT("Another component created a heap between calls. ") \
                 TEXT("Please try again.\n"));
        return 1;
    }

    _tprintf(TEXT("Process has %d heaps.\n"), HeapsLength);
    for (HeapsIndex = 0; HeapsIndex < HeapsLength; ++HeapsIndex) {
        _tprintf(TEXT("Heap %d at address: %#p.\n"),
                 HeapsIndex,
                 aHeaps[HeapsIndex]);
    }
  
    //
    // Release memory allocated from default process heap.
    //
    if (HeapFree(hDefaultProcessHeap, 0, aHeaps) == FALSE) {
        _tprintf(TEXT("Failed to free allocation from default process heap.\n"));
    }

    return 0;
}