FsRtlCancellableWaitForMultipleObjects-Funktion (ntifs.h)

Die FsRtlCancellableWaitForMultipleObjects-Routine führt einen abbruchfähigen Wartevorgang (eine Wartezeit, die beendet werden kann) für ein oder mehrere Dispatcherobjekte aus.

Syntax

NTSTATUS FsRtlCancellableWaitForMultipleObjects(
  [in]           ULONG          Count,
  [in]           PVOID []       ObjectArray,
  [in]           WAIT_TYPE      WaitType,
  [in, optional] PLARGE_INTEGER Timeout,
  [in, optional] PKWAIT_BLOCK   WaitBlockArray,
  [in, optional] PIRP           Irp
);

Parameter

[in] Count

Die Anzahl der Objekte, auf die gewartet werden soll.

[in] ObjectArray

Ein Zeiger auf ein Array von Zeigern auf Verteilerobjekte (Ereignisse, Mutexe, Semaphore, Threads und Timer), für die der Aufrufer den Speicher bereitstellt.

[in] WaitType

Entweder WaitAll, was angibt, dass alle angegebenen Objekte einen signalierten Zustand erreichen müssen, bevor die Wartezeit erfüllt ist; oder WaitAny, die angibt, dass eines der Objekte einen Signalzustand erreichen muss, bevor die Wartezeit erfüllt ist.

[in, optional] Timeout

Ein Zeiger auf einen optionalen Timeoutwert. Dieser Parameter gibt die absolute oder relative Zeit in 100 Nanosekundeneinheiten an, zu der die Wartezeit abgeschlossen werden soll.

Wenn Timeout auf einen Nullwert (d. h. *Timeout == 0) zeigt, wird die Routine ohne Warten zurückgegeben. Wenn der Aufrufer einen NULL-Zeiger (d. h. Timeout == NULL) bereitstellt, wartet die Routine unbegrenzt, bis eines oder alle Dispatcherobjekte auf den signalierten Zustand festgelegt sind.

Ein positiver Wert gibt eine absolute Zeit im Verhältnis zum 1. Januar 1601 an. Ein negativer Wert gibt ein Intervall relativ zur aktuellen Zeit an. Absolute Ablaufzeiten verfolgen alle Änderungen in der Systemzeit; relative Ablaufzeiten werden von Systemzeitänderungen nicht beeinflusst.

Wenn Timeout angegeben wird, wird die Wartezeit automatisch erfüllt, wenn keine der angegebenen Wartebedingungen erfüllt ist, wenn das angegebene Intervall abläuft.

Mit einem Timeoutwert von 0 (d. h. *Timeout == 0) können Sie eine Reihe von Wartebedingungen testen und alle zusätzlichen Aktionen bedingt ausführen, wenn die Wartezeit sofort erfüllt werden kann, wie beim Abrufen eines Mutex.

[in, optional] WaitBlockArray

Wenn Count<= THREAD_WAIT_OBJECTS, kann WaitBlockArray NULL sein. Andernfalls muss dieser Parameter auf einen Speicherpuffer von sizeof(KWAIT_BLOCK * Count) Bytes verweisen. Die Routine verwendet diesen Puffer für die Aufzeichnungsverwaltung während der Ausführung des Wartevorgangs.

[in, optional] Irp

Ein Zeiger auf den ursprünglichen IRP, der dem E/A-Vorgang entspricht, der vom Benutzer ausgegeben wurde und vom Benutzer abgebrochen werden kann. Der Aufrufer muss sicherstellen, dass das IRP für die Dauer dieser Routine gültig bleibt und dass für die IRP keine Abbruchroutine festgelegt sein darf (z. B. darf IoSetCancelRoutine nicht auf dem IRP aufgerufen worden sein). Beachten Sie, dass der IRP vom Aufrufer gehalten werden muss. Er kann nicht an einen Treiber auf niedrigerer Ebene übergeben werden.

Rückgabewert

FsRtlCancellableWaitForMultipleObjects kann einen der folgenden Werte zurückgeben:

Rückgabecode Beschreibung
STATUS_SUCCESS Der Aufrufer, der WaitAll für den WaitType-Parameter angegeben hat, und alle Dispatcherobjekte im ObjectArray-Array wurden auf den signalierten Zustand festgelegt.
STATUS_TIMEOUT Ein Timeout ist aufgetreten, bevor der angegebene Satz von Wartebedingungen erfüllt wurde. Dieser Wert kann zurückgegeben werden, wenn der angegebene Satz von Wartebedingungen nicht sofort erfüllt werden kann und timeout auf 0 festgelegt ist.
STATUS_WAIT_0 bis STATUS_WAIT_63 Der aufrufer angegebene WaitAny für WaitType und eines der Dispatcherobjekte im ObjectArray-Array wurde auf den signalierten Zustand festgelegt. Die unteren sechs Bits des Rückgabewerts codieren den nullbasierten Index des Objekts, das die Wartezeit erfüllt hat.
STATUS_ABANDONED_WAIT_0 bis STATUS_ABANDONED_WAIT_63 Der Aufrufer hat versucht, auf einen Mutex zu warten, der verlassen wurde. Die unteren sechs Bits des Rückgabewerts codieren den nullbasierten Index des Mutex im ObjectArray-Array .
STATUS_CANCELLED Die Wartezeit wurde durch eine ausstehende Abbruchanforderung für den angegebenen IRP unterbrochen. Beachten Sie, dass dieser Wert nur zurückgegeben wird, wenn ein gültiger IRP an FsRtlCancellableWaitForMultipleObjects übergeben wird und das IRP von CancelSynchronousIo abgebrochen wurde.
STATUS_THREAD_IS_TERMINATING Die Wartezeit wurde unterbrochen, weil der Thread von einer Anwendung oder dem Benutzer beendet wurde.

Der Rückgabewert gibt nur die status der Wartezeit an. Falls zutreffend, sollte die tatsächliche status der E/A-Anforderung direkt von einem anderen IRP abgerufen werden, das bei der Verarbeitung des ursprünglichen Benutzermodus-IRP generiert wurde.

Beachten Sie, dass das NT_SUCCESS-Makro FALSE ("Fehler") für die STATUS_CANCELLED- und STATUS_THREAD_IS_TERMINATING status-Werte und TRUE ("success") für alle anderen status-Werte zurückgibt.

Hinweise

Die FsRtlCancellableWaitForMultipleObjects-Routine führt einen abbruchfähigen Wartevorgang für Dispatcherobjekte aus. Wenn der Thread vom Benutzer oder von der Anwendung beendet wird, oder wenn CancelSynchronousIo eine Abbruchanforderung für eine dem Thread zugeordnete IRP (synchrone IRP) sendet, wird die Wartezeit abgebrochen.

Die FsRtlCancellableWaitForMultipleObjects-Routine wurde für die Unterstützung der E/A-Vervollständigungs-/Abbruchrichtlinien ab Windows Vista entwickelt. Ziel dieser Richtlinien ist es, Benutzern (oder Anwendungen) das schnelle Beenden von Anwendungen zu ermöglichen. Dies wiederum erfordert, dass Anwendungen in der Lage sind, Threads, die E/A sowie alle aktuellen E/A-Vorgänge ausführen, schnell zu beenden. Diese Routine bietet eine Möglichkeit für Benutzerthreads, im Kernel für E/A-Vervollständigung, Dispatcherobjekte oder Synchronisierungsvariablen zu blockieren (d. h. warten), sodass die Wartezeit problemlos abgebrochen werden kann. Diese Routine ermöglicht auch, dass das Warten des Threads beendet wird, wenn der Thread von einem Benutzer oder einer Anwendung beendet wird.

Beispielsweise muss ein Redirector möglicherweise eine oder mehrere sekundäre IRPs erstellen, um eine Benutzermodus-IRP zu verarbeiten und synchron auf den Abschluss der sekundären IRPs zu warten. Eine Möglichkeit besteht darin, ein Ereignis einzurichten, das von der Abschlussroutine des sekundären IRP signalisiert wird, und dann auf das Signal des Ereignisses zu warten. Um dann einen abbruchfähigen Wartevorgang auszuführen, wird FsRtlCancellableWaitForMultipleObjects als Übergabe des Ereignisses aufgerufen, das dem sekundären IRP zugeordnet ist, sowie das ursprüngliche Benutzermodus-IRP. Das Warten des Threads auf das Signal des Ereignisses wird abgebrochen, wenn ein Ausstehendes Beendigungsereignis auftritt oder wenn die ursprüngliche Benutzermodus-IRP abgebrochen wird.

Beachten Sie, dass das Beenden der Wartezeit nicht automatisch alle E/A-Vorgänge abbricht, die vom Aufrufer ausgegeben werden. Dies muss separat vom Aufrufer behandelt werden.

Jedes Threadobjekt verfügt über ein integriertes Array von Warteblöcken, die verwendet werden können, um auf mehrere Objekte gleichzeitig zu warten. Wenn möglich, sollte das integrierte Array von Warteblöcken in einem mehrfachen Wartevorgang verwendet werden, da kein zusätzlicher Warteblockspeicher zugeordnet und später aufgehoben werden muss. Wenn jedoch die Anzahl der Objekte, auf die gleichzeitig gewartet werden muss, größer ist als die Anzahl der integrierten Warteblöcke, verwenden Sie den WaitBlockArray-Parameter , um einen alternativen Satz von Warteblöcken anzugeben, die im Wartevorgang verwendet werden sollen. Treiber müssen nur einen ausreichend großen Speicherpuffer für WaitBlockArray zuweisen. Der Puffer muss nicht initialisiert werden, und die Treiber können ihn als undurchsichtige Struktur behandeln. Der Puffer kann freigegeben werden, sobald die Routine zurückgegeben wird.

Wenn Count größer als MAXIMUM_WAIT_OBJECTS ist oder WaitBlockArray NULL und Count größer als THREAD_WAIT_OBJECTS ist, gibt das System Fehlerprüfung 0xC: MAXIMUM_WAIT_OBJECTS_EXCEEDED aus.

Ein besonderer Aspekt gilt, wenn der an FsRtlCancellableWaitForMultipleObjects übergebene ObjectArray-Parameter ein Mutex ist. Wenn das Verteilerobjekt, auf das gewartet wird, ein Mutex ist, ist die APC-Übermittlung identisch mit allen anderen Verteilerobjekten während der Wartezeit. Sobald FsRtlCancellableWaitForMultipleObjects jedoch mit STATUS_SUCCESS zurückgibt und der Thread tatsächlich den Mutex enthält, werden nur spezielle Kernelmodus-APCs bereitgestellt. Die Übermittlung aller anderen APCs, sowohl im Kernelmodus als auch im Benutzermodus, ist deaktiviert. Diese Einschränkung für die Bereitstellung von APCs bleibt bestehen, bis der Mutex freigegeben wird.

Ein Mutex kann nur zu MINLONG-Zeiten rekursiv erworben werden. Wenn dieser Grenzwert überschritten wird, löst die Routine eine STATUS_MUTANT_LIMIT_EXCEEDED Ausnahme aus.

FsRtlCancellableWaitForMultipleObjects muss am IRQL-PASSIVE_LEVEL aufgerufen werden, wenn der optionale Irp-Parameter auf einen gültigen IRP zeigt. Wenn der Irp-Parameter nicht verwendet wird, kann die Routine bei IRQL kleiner oder gleich APC_LEVEL aufgerufen werden. Normale Kernel-APCs können bei Bedarf vom Aufrufer deaktiviert werden, indem die Routinen KeEnterCriticalRegion oder FsRtlEnterFileSystem aufgerufen werden. Spezielle Kernel-APCs dürfen jedoch nicht deaktiviert werden.

FsRtlCancellableWaitForMultipleObjects bestätigt bei Debugbuilds, wenn die IRQL größer oder gleich APC_LEVEL ist und der Irp-Parameter auf eine gültige IRP zeigt.

Anforderungen

Anforderung Wert
Unterstützte Mindestversion (Client) Windows Vista
Zielplattform Universell
Header ntifs.h (include Ntifs.h)
Bibliothek NtosKrnl.lib
DLL NtosKrnl.exe
IRQL Weitere Informationen finden Sie im Abschnitt mit den Hinweisen.
DDI-Complianceregeln HwStorPortProhibitedDIs(storport), PowerIrpDDis(wdm), SpNoWait(storport)

Weitere Informationen

ExInitializeFastMutex

FsRtlCancellableWaitForSingleObject

KeInitializeEvent

KeInitializeMutex

KeInitializeSemaphor

KeInitializeTimer

KeWaitForMultipleObjects

KeWaitForSingleObject

KeWaitForMutexObject