VirtualAllocEx-Funktion (memoryapi.h)

Reserviert, commitsiert oder ändert den Zustand einer Speicherregion im virtuellen Adressraum eines angegebenen Prozesses. Die Funktion initialisiert den Speicher, den sie ordnet, auf Null.

Informationen zum Angeben des NUMA-Knotens für den physischen Arbeitsspeicher finden Sie unter VirtualAllocExNuma.

Syntax

LPVOID VirtualAllocEx(
  [in]           HANDLE hProcess,
  [in, optional] LPVOID lpAddress,
  [in]           SIZE_T dwSize,
  [in]           DWORD  flAllocationType,
  [in]           DWORD  flProtect
);

Parameter

[in] hProcess

Das Handle für einen Prozess. Die Funktion weist Arbeitsspeicher innerhalb des virtuellen Adressraums dieses Prozesses zu.

Das Handle muss über das zugriffsrecht PROCESS_VM_OPERATION verfügen. Weitere Informationen finden Sie unter Prozesssicherheit und Zugriffsrechte.

[in, optional] lpAddress

Der Zeiger, der eine gewünschte Startadresse für den Bereich der Seiten angibt, die Sie zuordnen möchten.

Wenn Sie Arbeitsspeicher reservieren, rundet die Funktion diese Adresse auf das nächste Vielfache der Zuordnungsgranularität ab.

Wenn Sie bereits reservierten Arbeitsspeicher committen, rundet die Funktion diese Adresse auf die nächste Seitengrenze ab. Verwenden Sie die GetSystemInfo-Funktion , um die Größe einer Seite und die Granularität der Zuordnung auf dem Hostcomputer zu bestimmen.

Wenn lpAddressNULL ist, bestimmt die Funktion, wo die Region zugeordnet werden soll.

Wenn sich diese Adresse innerhalb einer Enclave befindet, die Sie nicht durch Aufrufen von InitializeEnclave initialisiert haben, weist VirtualAllocEx eine Seite mit Nullen für die Enclave an dieser Adresse zu. Die Seite muss zuvor nicht festgelegt sein und wird nicht mit der EEXTEND-Anweisung des Intel Software Guard Extensions-Programmiermodells gemessen.

Wenn die Adresse in einer Enklave, die Sie initialisiert haben, fehlschlägt der Zuordnungsvorgang mit dem ERROR_INVALID_ADDRESS Fehler. Dies gilt für Enclaves, die keine dynamische Speicherverwaltung unterstützen (z. B. SGX1). SGX2-Enklaven erlauben die Zuordnung, und die Seite muss von der Enklave akzeptiert werden, nachdem sie zugewiesen wurde.

[in] dwSize

Die Größe des zu zuweisenden Speicherbereichs in Bytes.

Wenn lpAddressNULL ist, rundet die Funktion dwSize bis zur nächsten Seitengrenze ab.

Wenn lpAddress nicht NULL ist, weist die Funktion alle Seiten zu, die mindestens ein Bytes im Bereich von lpAddress bis lpAddress+dwSize enthalten. Dies bedeutet beispielsweise, dass ein 2-Byte-Bereich, der eine Seitengrenze überspannt, dazu führt, dass die Funktion beide Seiten zuordnet.

[in] flAllocationType

Der Typ der Speicherzuordnung. Dieser Parameter muss einen der folgenden Werte enthalten.

Wert Bedeutung
MEM_COMMIT
0x00001000
Weist Speichergebühren (aus der Gesamtgröße des Arbeitsspeichers und den Auslagerungsdateien auf dem Datenträger) für die angegebenen reservierten Speicherseiten zu. Die Funktion garantiert auch, dass der Inhalt null ist, wenn der Aufrufer später zunächst auf den Speicher zugreift. Die tatsächlichen physischen Seiten werden erst zugeordnet, wenn/bis auf die virtuellen Adressen tatsächlich zugegriffen wird.

Um Seiten in einem Schritt zu reservieren und zu commiten, rufen Sie VirtualAllocEx mit MEM_COMMIT | MEM_RESERVEauf.

Der Versuch, einen bestimmten Adressbereich zu committen, indem MEM_COMMIT ohne MEM_RESERVE und eine lpAddress ohne NULL angegeben wird, schlägt fehl, es sei denn, der gesamte Bereich wurde bereits reserviert. Der resultierende Fehlercode ist ERROR_INVALID_ADDRESS.

Ein Versuch, eine Seite zu committen, die bereits committet wurde, führt nicht dazu, dass die Funktion fehlschlägt. Dies bedeutet, dass Sie Seiten commiten können, ohne zuerst den aktuellen Verpflichtungsstatus jeder Seite zu bestimmen.

Wenn lpAddress eine Adresse innerhalb einer Enclave angibt, muss flAllocationTypeMEM_COMMIT sein.

MEM_RESERVE
0x00002000
Reserviert einen Bereich des virtuellen Adressraums des Prozesses, ohne den tatsächlichen physischen Speicher im Arbeitsspeicher oder in der Auslagerungsdatei auf dem Datenträger zuzuweisen.

Sie committen reservierte Seiten, indem Sie VirtualAllocEx erneut mit MEM_COMMIT aufrufen. Um Seiten in einem Schritt zu reservieren und zu commiten, rufen Sie VirtualAllocEx mit MEM_COMMIT | MEM_RESERVEauf.

Andere Speicherbelegungsfunktionen wie malloc und LocalAlloc können den reservierten Speicher erst verwenden, wenn er freigegeben wurde.

MEM_RESET
0x00080000
Gibt an, dass Daten im von lpAddress und dwSize angegebenen Speicherbereich nicht mehr von Interesse sind. Die Seiten sollten nicht aus der Auslagerungsdatei gelesen oder in diese geschrieben werden. Der Speicherblock wird jedoch später wieder verwendet, sodass er nicht dekommittiert werden sollte. Dieser Wert kann nicht mit anderen Werten verwendet werden.

Die Verwendung dieses Werts garantiert nicht, dass der Bereich, der mit MEM_RESET betrieben wird, Nullen enthält. Wenn der Bereich Nullen enthalten soll, heben Sie den Arbeitsspeicher auf, und legen Sie ihn dann erneut zurück.

Wenn Sie MEM_RESET verwenden, ignoriert die VirtualAllocEx-Funktion den Wert von fProtect. Sie müssen fProtect jedoch trotzdem auf einen gültigen Schutzwert festlegen, z. B. PAGE_NOACCESS.

VirtualAllocEx gibt einen Fehler zurück, wenn Sie MEM_RESET verwenden und der Speicherbereich einer Datei zugeordnet ist. Eine freigegebene Ansicht ist nur akzeptabel, wenn sie einer Auslagerungsdatei zugeordnet ist.

MEM_RESET_UNDO
0x1000000
MEM_RESET_UNDO sollte nur für einen Adressbereich aufgerufen werden, auf den MEM_RESET zuvor erfolgreich angewendet wurde. Es gibt an, dass die Daten in dem angegebenen Speicherbereich, der von lpAddress und dwSize angegeben wird, für den Aufrufer von Interesse sind und versucht, die Auswirkungen von MEM_RESET rückgängig zu machen. Wenn die Funktion erfolgreich ist, bedeutet dies, dass alle Daten im angegebenen Adressbereich intakt sind. Wenn die Funktion fehlschlägt, wurden mindestens einige Daten im Adressbereich durch Nullen ersetzt.

Dieser Wert kann nicht mit anderen Werten verwendet werden. Wenn MEM_RESET_UNDO für einen Adressbereich aufgerufen wird, der zuvor nicht MEM_RESET wurde, ist das Verhalten nicht definiert. Wenn Sie MEM_RESET angeben, ignoriert die VirtualAllocEx-Funktion den Wert von flProtect. Sie müssen flProtect jedoch trotzdem auf einen gültigen Schutzwert festlegen, z. B. PAGE_NOACCESS.

Windows Server 2008 R2, Windows 7, Windows Server 2008, Windows Vista, Windows Server 2003 und Windows XP: Das MEM_RESET_UNDO-Flag wird erst unterstützt, wenn Windows 8 und Windows Server 2012.

 

Dieser Parameter kann auch die folgenden Werte angeben, wie angegeben.

Wert Bedeutung
MEM_LARGE_PAGES
0x20000000
Ordnet Arbeitsspeicher mithilfe von Unterstützung für große Seiten zu.

Die Größe und Ausrichtung müssen ein Vielfaches des großformatigen Minimums sein. Verwenden Sie zum Abrufen dieses Werts die GetLargePageMinimum-Funktion .

Wenn Sie diesen Wert angeben, müssen Sie auch MEM_RESERVE und MEM_COMMIT angeben.

MEM_PHYSICAL
0x00400000
Reserviert einen Adressbereich, der zum Zuordnen von AWE-Seiten ( Address Windowing Extensions ) verwendet werden kann.

Dieser Wert muss mit MEM_RESERVE und keinem anderen Wert verwendet werden.

MEM_TOP_DOWN
0x00100000
Ordnet Arbeitsspeicher an der höchstmöglichen Adresse zu. Dies kann langsamer sein als reguläre Zuordnungen, insbesondere wenn viele Zuordnungen vorhanden sind.

[in] flProtect

Der Speicherschutz für die Region der zuzuordnenden Seiten. Wenn die Seiten committet werden, können Sie eine der Speicherschutzkonstanten angeben.

Wenn lpAddress eine Adresse innerhalb einer Enclave angibt, darf flProtect keinen der folgenden Werte sein:

  • PAGE_NOACCESS
  • PAGE_GUARD
  • PAGE_NOCACHE
  • PAGE_WRITECOMBINE

Bei der Zuweisung von dynamischem Arbeitsspeicher für eine Enclave muss der flProtect-ParameterPAGE_READWRITE oder PAGE_EXECUTE_READWRITE sein.

Rückgabewert

Wenn die Funktion erfolgreich ist, ist der Rückgabewert die Basisadresse des zugeordneten Bereichs der Seiten.

Wenn bei der Funktion ein Fehler auftritt, ist der Rückgabewert NULL. Um erweiterte Fehlerinformationen zu erhalten, rufen Sie GetLastError auf.

Hinweise

Jede Seite verfügt über einen zugeordneten Seitenzustand. Die VirtualAllocEx-Funktion kann die folgenden Vorgänge ausführen:

  • Committen einer Region mit reservierten Seiten
  • Reservieren einer Region mit kostenlosen Seiten
  • Gleichzeitiges Reservieren und Committen einer Region mit kostenlosen Seiten
VirtualAllocEx kann keine reservierte Seite reservieren. Es kann einen Commit für eine Seite ausführen, die bereits committet wurde. Dies bedeutet, dass Sie einen Bereich von Seiten committen können, unabhängig davon, ob sie bereits committet wurden, und die Funktion nicht fehlschlägt.

Sie können VirtualAllocEx verwenden, um einen Seitenblock zu reservieren und dann zusätzliche Aufrufe an VirtualAllocEx durchzuführen, um einzelne Seiten aus dem reservierten Block zu committen. Dadurch kann ein Prozess einen Bereich des virtuellen Adressraums reservieren, ohne physischen Speicher zu verwenden, bis er benötigt wird.

Wenn der lpAddress-Parameter nicht NULL ist, verwendet die Funktion die Parameter lpAddress und dwSize , um den Bereich der zuzuordnenden Seiten zu berechnen. Der aktuelle Zustand des gesamten Seitenbereichs muss mit dem Typ der Zuordnung kompatibel sein, der durch den flAllocationType-Parameter angegeben wird. Andernfalls schlägt die Funktion fehl, und keine der Seiten wird zugeordnet. Diese Kompatibilitätsanforderung schließt das Commit einer bereits committeten Seite nicht aus. Weitere Informationen finden Sie in der obigen Liste.

Um dynamisch generierten Code auszuführen, verwenden Sie VirtualAllocEx , um Arbeitsspeicher zuzuweisen, und die VirtualProtectEx-Funktion , um PAGE_EXECUTE Zugriff zu gewähren.

Die VirtualAllocEx-Funktion kann verwendet werden, um einen AWE-Speicherbereich ( Address Windowing Extensions ) innerhalb des virtuellen Adressraums eines angegebenen Prozesses zu reservieren. Dieser Bereich des Arbeitsspeichers kann dann verwendet werden, um physische Seiten in und aus virtuellem Arbeitsspeicher zuzuordnen, wie von der Anwendung benötigt. Die werte MEM_PHYSICAL und MEM_RESERVE müssen im AllocationType-Parameter festgelegt werden. Der MEM_COMMIT Wert darf nicht festgelegt werden. Der Seitenschutz muss auf PAGE_READWRITE festgelegt werden.

Die VirtualFreeEx-Funktion kann eine committete Seite deaktivieren und den Speicher der Seite freigeben, oder sie kann gleichzeitig die Deaktivierung und Freigabe einer committeten Seite ausführen. Es kann auch eine reservierte Seite freigeben, was sie zu einer kostenlosen Seite macht.

Beim Erstellen einer region, die ausführbar ist, trägt das aufrufende Programm die Verantwortung für die Sicherstellung der Cachekohärenz über einen entsprechenden Aufruf von FlushInstructionCache , nachdem der Code festgelegt wurde. Andernfalls können Versuche, Code aus dem neu ausführbaren Bereich auszuführen, zu unvorhersehbaren Ergebnissen führen.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows XP [Desktop-Apps | UWP-Apps]
Unterstützte Mindestversion (Server) Windows Server 2003 [Desktop-Apps | UWP-Apps]
Zielplattform Windows
Kopfzeile memoryapi.h (einschließlich Windows.h, Memoryapi.h)
Bibliothek onecore.lib
DLL Kernel32.dll

Siehe auch

Speicherverwaltungsfunktionen

ReadProcessMemory

Funktionen des virtuellen Speichers

VirtualAllocExNuma

VirtualFreeEx

VirtualLock

VirtualProtect

Virtualquery

WriteProcessMemory