PDD_SURFCB_LOCK Rückruffunktion (ddrawint.h)

Die DdLock-Rückruffunktion sperrt einen angegebenen Bereich des Oberflächenspeichers und stellt einen gültigen Zeiger auf einen Speicherblock bereit, der einer Oberfläche zugeordnet ist.

Syntax

PDD_SURFCB_LOCK PddSurfcbLock;

DWORD PddSurfcbLock(
  PDD_LOCKDATA unnamedParam1
)
{...}

Parameter

unnamedParam1

Verweist auf eine DD_LOCKDATA-Struktur , die die informationen enthält, die zum Ausführen der Sperrung erforderlich sind.

Rückgabewert

DdLock gibt einen der folgenden Rückrufcodes zurück:

Hinweise

DdLock sollte den ddRVal-Member der DD_LOCKDATA-Struktur bei lpLock auf DDERR_WASSTILLDRAWING festlegen und DDHAL_DRIVER_HANDLED zurückgeben, wenn ein Blit oder Flip ausgeführt wird.

Sofern vom dwFlags-Member von DD_LOCKDATA nicht anders angegeben, kann der Treiber im lpSurfData-Member von DD_LOCKDATA einen Speicherzeiger an den oberen Rand der Oberfläche zurückgeben. Wenn der Treiber seine eigene Adresse für die Oberfläche berechnen muss, kann er sich auf den Zeiger verlassen, der im fpProcess-Member von DD_LOCKDATA als prozessspezifischer Zeiger auf die Benutzermoduszuordnung seines Framepuffers mit DirectDraw-Zugriff übergeben wird.

Eine Sperre bietet keinen exklusiven Zugriff auf den angeforderten Speicherblock. Das heißt, mehrere Threads können dieselbe Oberfläche gleichzeitig sperren. Es liegt in der Verantwortung der Anwendung, den Zugriff auf den Speicherblock zu synchronisieren, dessen Zeiger abgerufen wird.

Ein Treiber, der auf einem NT-basierten Betriebssystem ausgeführt wird, sollte von seiner DdLock-Funktion keinen Zeiger auf den Systemspeicher zurückgeben, es sei denn, die DdCreateSurface-Funktion des Treibers hat diesen Arbeitsspeicher zuvor mit dem flag PLEASE_ALLOC_USERMEM zugeordnet. Wenn PLEASE_ALLOC_USERMEM nicht verwendet wurde, können Anwendungen Fehler erhalten, wenn sie versuchten, auf diesen Arbeitsspeicher zuzugreifen. Weitere Informationen finden Sie unter Nt Kernels Implementierung von DDLOCK_NOSYSLOCK .

DdLock kann mit einem deaktivierten PDEV aufgerufen werden. Ein PDEV wird durch Aufrufen der DrvAssertMode-Funktion des Anzeigetreibers deaktiviert oder aktiviert. Weitere Informationen finden Sie unter Verwalten von PDEVs .

Implementierung von DDLOCK_NOSYSLOCK im NT-Kernel

Anwendungen können die ApIs (Application Programming Interfaces) von DirectDraw und Direct3D verwenden, um lange Sperren für Videospeicherressourcen zu erhalten. Solche Sperren werden als "NOSYSLOCK"-Sperren bezeichnet. Diese Sperren funktionieren anders als typische Videospeichersperren, wie in den folgenden Absätzen beschrieben.

Nachdem die DirectDraw-Runtime die DdLock-Funktion eines Treibers mit dem im dwFlags-Element von DD_LOCKDATA angegebenen DDLOCK_NOSYSLOCK-Flag aufruft, untersucht die Laufzeit den Zeiger auf den vom Treiber zurückgegebenen Oberflächeninhalt. Anstatt den vom Treiber zurückgegebenen Zeiger direkt an eine Anwendung zu übergeben, erstellt die Runtime eine zweite Benutzermoduszuordnung des Videospeichers (sowohl lokal als auch nicht lokal) und berechnet die entsprechende virtuelle Adresse innerhalb dieser Zuordnung. Diese virtuelle Adresse wird als Aliaszeiger auf die Speichersperre bezeichnet. Die Runtime übergibt diesen Aliassperrzeiger an die Anwendung. Die Anwendung verwendet diesen Aliassperrzeiger, um direkt in den Videospeicher zu lesen und zu schreiben. Weder die Anwendung noch der Treiber wissen, dass sie einen anderen Zeiger für gesperrten Speicher verwendet.

Später, zur Zeit des Moduswechsels, bemerkt die DirectDraw-Laufzeit alle ausstehenden Aliassperrzeiger. Anstatt darauf zu warten, dass die Aliassperre wie bei einer typischen Videospeichersperre abgeschlossen ist, ordnet die Laufzeit die Benutzermoduszuordnung des Videospeichers neu zu und ermöglicht den Moduswechsel. Die Laufzeit ordnet die Benutzermoduszuordnungen einer einzelnen Dummyseite neu zu. Die Anwendung liest und schreibt weiterhin auf diese Dummyseite, andernfalls sind änderungen nicht bekannt. Die Runtime muss dann Aliassperrzeiger sauber, indem die DdUnlock-Funktion des Treibers aufgerufen wird. Die Runtime kann Aliassperrzeiger sauber, da die Anwendung nicht mehr in den Videospeicher schreibt. Da dieser sauber zur Zeit des Moduswechsels auftritt, besteht der nächste Schritt in der Sequenz darin, Oberflächen zu verlieren, was bedeutet, dass die Objekte pro Oberfläche des Treibers zerstört werden. Anders ausgedrückt: Die Runtime ruft die DdDestroySurface-Funktion des Treibers für alle Oberflächen auf, einschließlich Oberflächen, die von der Anwendung weiterhin als gesperrt betrachtet werden. Tatsächlich liest und schreibt die Anwendung weiterhin auf eine Dummyseite des Systemspeichers.

Dieser gesamte Prozess funktioniert nur, wenn der von DdLock zurückgegebene Speicherzeiger eine Zuordnung des Videospeichers ist. Bei dieser Videospeicherzuordnung kann es sich entweder um die Benutzermoduszuordnung des nicht lokalen Videospeichers handeln, der von der DirectDraw-Kernelmoduslaufzeit durchgeführt wird, oder um die Zuordnung, die von der DdMapMemory-Funktion des Treibers bereitgestellt wird. Wenn der Speicherzeiger nicht einer dieser Zuordnungen zugeordnet werden kann, ordnet die Laufzeit die Sperre nicht neu zu. Der Modusschalter wird fortgesetzt, was bedeutet, dass das Surface-Objekt des Treibers durch Aufrufe der DdUnlock - bzw. DdDestroySurface-Funktionen des Treibers entsperrt und zerstört wird. Der Treiber gibt dann in der Regel jeden Systemspeicher frei, den der Treiber zur Sperrzeit zugeordnet hat. Da die Anwendung noch in diesen Arbeitsspeicher schreibt, tritt eine Zugriffsverletzung auf.

Folglich sollte ein Treiber nicht versuchen, Systemspeicherzeiger aus seiner DdLock-Funktion zurückzugeben, es sei denn, die DdCreateSurface-Funktion dieses Treibers hat diesen Arbeitsspeicher zuvor mit dem PLEASE_ALLOC_USERMEM-Flag zugewiesen. Die DirectDraw-Runtime besitzt auf diese Weise zugeordneten Arbeitsspeicher und kann die Freigabe dieses Arbeitsspeichers verzögern, bis die Anwendung den Arbeitsspeicher entsperrt. Daher kann die DdLock-Funktion des Treibers Zeiger auf den auf diese Weise zugeordneten Arbeitsspeicher zurückgeben, ohne dass die Anwendung abstürzt.

Anforderungen

Anforderung Wert
Zielplattform Desktop
Kopfzeile ddrawint.h (einschließlich Winddi.h)

Weitere Informationen

DD_LOCKDATA

DdMapMemory

DdUnlock