Freigeben über


PreviousMode

Wenn eine Benutzermodusanwendung die Nt - oder Zw-Version einer systemeigenen Systemdienstroutine aufruft, fängt der Systemaufrufmechanismus den aufrufenden Thread im Kernelmodus ab. Um anzugeben, dass die Parameterwerte im Benutzermodus entstanden sind, legt der Traphandler für den Systemaufruf das Feld PreviousMode im Threadobjekt des Aufrufers auf UserMode fest. Die Systemdienstroutine überprüft das Feld PreviousMode des aufrufenden Threads, um zu ermitteln, ob die Parameter aus einer Benutzermodusquelle stammen.

Wenn ein Kernelmodustreiber eine systemeigene Systemdienstroutine aufruft und Parameterwerte an die Routine übergibt, die aus einer Kernelmodusquelle stammen, muss der Treiber sicherstellen, dass das Feld PreviousMode im aktuellen Threadobjekt auf KernelMode festgelegt ist.

Ein Kernelmodustreiber kann im Kontext eines beliebigen Threads ausgeführt werden, und das Feld PreviousMode dieses Threads kann auf UserMode festgelegt werden. In dieser Situation kann ein Kernelmodustreiber die Zw-Version einer systemeigenen Systemdienstroutine aufrufen, um die Routine darüber zu informieren, dass die Parameterwerte aus einer vertrauenswürdigen Kernelmodusquelle stammen. Der Zw-Aufruf geht an eine dünne Wrapperfunktion, die den PreviousMode-Wert im aktuellen Threadobjekt außer Kraft setzt. Die Wrapperfunktion legt PreviousMode auf KernelMode fest und ruft die Nt-Version der Routine auf. Wenn die Nt-Version der Routine zurückgegeben wird, stellt die Wrapperfunktion den ursprünglichen PreviousMode-Wert des Threadobjekts wieder her und gibt zurück.

Ein Kernelmodustreiber kann die Nt-Version einer systemeigenen Systemdienstroutine direkt aufrufen. Wenn ein Kernelmodustreiber eine E/A-Anforderung verarbeitet, die entweder im Benutzermodus oder im Kernelmodus entstehen kann, kann der Treiber die Nt-Version der Routine aufrufen, sodass der PreviousMode-Wert des aktuellen Threads während des Aufrufs unverändert bleibt. Die NtXxx-Routine überprüft den PreviousMode-Wert des aufrufenden Threads, um zu bestimmen, ob die Parameterwerte von einer Benutzermodusanwendung oder einer Kernelmoduskomponente stammen, und behandelt sie entsprechend.

Ein Fehler kann auftreten, wenn ein Kernelmodustreiber eine NtXxx-Routine aufruft und der PreviousMode-Wert im aktuellen Threadobjekt nicht genau angibt, ob die Parameterwerte aus einem Benutzermodus oder einer Kernelmodusquelle stammen.

Angenommen, ein Kernelmodustreiber wird im Kontext eines beliebigen Threads ausgeführt, und der PreviousMode-Wert für diesen Thread ist auf UserMode festgelegt. Wenn der Treiber ein Kernelmodusdateihandle an die NtClose-Routine übergibt, überprüft diese Routine den Wert PreviousMode und beschließt, dass das Handle ein Benutzermodushandle sein muss. Wenn NtClose das Handle in der Handle-Tabelle im Benutzermodus nicht findet, gibt es den STATUS_INVALID_HANDLE Fehlercode zurück. In der Zwischenzeit gibt der Treiber das Kernelmodushandle aus, das nie geschlossen wurde.

Ein anderes Beispiel: Wenn die Parameter für eine NtXxx-Routine einen Eingabe- oder Ausgabepuffer enthalten, und wenn PreviousMode = UserMode, die Routine die ProbeForRead - oder ProbeForWrite-Routine aufruft, um den Puffer zu überprüfen. Wenn der Puffer im Systemspeicher anstatt im Benutzermodusspeicher zugeordnet wurde, löst die ProbeForXxx-Routine eine Ausnahme aus, und die NtXxx-Routine gibt den STATUS_ACCESS_VIOLATION Fehlercode zurück.

Wenn dies erforderlich ist, kann ein Treiber die ExGetPreviousMode-Routine aufrufen, um den PreviousMode-Wert aus dem aktuellen Threadobjekt abzurufen. Oder der Treiber kann das Feld RequestorMode aus der IRP-Struktur lesen, die den angeforderten E/A-Vorgang beschreibt. Das Feld RequestorMode enthält eine Kopie des PreviousMode-Werts aus dem Thread, der den Vorgang angefordert hat.