FsRtlCancellableWaitForMultipleObjects 函式 (ntifs.h)
FsRtlCancellableWaitForMultipleObjects 例程會在一或多個發送器對象上執行可取消的等候作業(可以終止的等候)。
語法
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
);
參數
[in] Count
要等候的物件數目。
[in] ObjectArray
發送器物件的指標陣列指標(事件、Mutex、信號、線程和定時器),呼叫端會提供記憶體。
[in] WaitType
WaitAll,這表示所有指定的對象在滿足等候之前必須達到訊號狀態;或 WaitAny,這表示任何一個對象必須在滿足等候之前達到訊號狀態。
[in, optional] Timeout
選擇性逾時值的指標。 此參數會以 100 奈秒為單位指定等候完成的絕對或相對時間。
如果 逾時 指向零值(也就是 *Timeout == 0),例程會傳回而不等候。 如果呼叫端提供 NULL 指標(也就是 Timeout == NULL),則例程會無限期等候,直到任何或所有發送器對象都設定為訊號狀態為止。
正值會指定絕對時間,相對於 1601 年 1 月 1 日。 負值會指定相對於目前時間的間隔。 絕對到期時間會追蹤系統時間中的任何變更;相對到期時間不會受到系統時間變更的影響。
如果指定了 逾時,如果指定間隔到期時未符合任何指定的等候條件,則會自動滿足等候。
零的逾時值(也就是 *逾時 == 0)可讓您測試一組等候條件,並在可以立即滿足等候時有條件地執行任何其他動作,就像取得 Mutex 一樣。
[in, optional] WaitBlockArray
如果 Count<= THREAD_WAIT_OBJECTS,WaitBlockArray 可以是 NULL。 否則,此參數必須指向 sizeof(KWAIT_BLOCK * Count)
位元組的記憶體緩衝區。 例程會在執行等候作業時使用此緩衝區進行記錄保留。
[in, optional] Irp
與用戶發出的 I/O 作業對應的原始 IRP 指標,而且可由使用者取消。 呼叫端必須確保 IRP 在這段例程期間會保持有效,而且 IRP 不得有取消例程集(例如,IoSetCancelRoutine 不得在 IRP 上呼叫)。 請注意,呼叫端必須持有 IRP,無法傳遞至較低層級的驅動程式。
傳回值
FsRtlCancellableWaitForMultipleObjects 可以傳回下列其中一個值:
傳回值只會指出等候的狀態。 如果適用,應該直接從處理原始使用者模式 IRP 的過程中產生的另一個 IRP 取得 I/O 要求的實際狀態。
請注意,NT_SUCCESS巨集會針對STATUS_CANCELLED傳回 FALSE (“failure”),並針對所有其他狀態值傳回STATUS_THREAD_IS_TERMINATING狀態值和 TRUE (“success”)。
言論
FsRtlCancellableWaitForMultipleObjects 例程會在發送器物件上執行可取消的等候作業。 如果使用者或應用程式終止線程,或 CancelSynchronousIo 在與線程相關聯的線程 IRP (同步 IRP) 上張貼取消要求,則會取消等候。
FsRtlCancellableWaitForMultipleObjects 例程是針對從 Windows Vista 開始 I/O 完成/取消 指導方針的支援所設計。 這些指導方針的目標是允許使用者(或應用程式)快速終止應用程式。 接著,這需要應用程式能夠快速終止執行 I/O 的線程,以及任何目前的 I/O 作業。 此例程提供一種方式,讓使用者線程封鎖核心中的 I/O 完成、發送器物件或同步處理變數,以允許立即取消等候。 如果線程由使用者或應用程式終止,此例程也允許線程的等候終止。
例如,重新導向器可能需要建立一或多個次要 IRP,才能處理使用者模式 IRP,並同步等候次要 IRP 完成。 這樣做的其中一種方法是設定事件,該事件將由次要 IRP 的完成例程發出訊號,然後等候事件發出訊號。 然後,若要執行可取消的等候作業,FsRtlCancellableWaitForMultipleObjects 會呼叫傳入與次要 IRP 相關聯的事件,以及原始的使用者模式 IRP。 如果發生擱置終止事件,或取消原始使用者模式 IRP,線程等候事件發出訊號會取消。
請注意,終止等候不會自動取消呼叫端所發出的任何 I/O 作業, 必須由呼叫端分開處理。
每個線程物件都有一個內建的等候區塊陣列,可用來同時等候數個物件。 可能的話,應該在等候多重作業中使用內建的等候區塊陣列,因為不需要配置額外的等候區塊記憶體,之後才解除分配。 不過,如果必須同時等候的物件數目大於內建等候區塊的數目,請使用 WaitBlockArray 參數來指定等候作業中要使用的替代等候區塊集。 驅動程式只需要為 waitBlockArray 配置足夠大的記憶體緩衝區。 緩衝區不需要初始化,而且驅動程式可以將它視為不透明結構。 一旦例程傳回,就可以釋放緩衝區。
如果 Count 大於 MAXIMUM_WAIT_OBJECTS,或如果 WaitBlockArray 為 NULL 且 Count 大於 THREAD_WAIT_OBJECTS,則系統會發出 錯誤檢查0xC:MAXIMUM_WAIT_OBJECTS_EXCEEDED。
當傳遞至 FsRtlCancellableWaitForMultipleObjects 的 ObjectArray 參數為 mutex 時,就會套用特殊考慮。 如果等候的發送器對像是 mutex,則 APC 傳遞與等候期間所有其他發送器物件相同。 不過,一旦 FsRtlCancellableWaitForMultipleObjects 會傳回STATUS_SUCCESS,而線程實際上會保留 mutex,只會傳遞特殊的內核模式 APC。 已停用核心模式和使用者模式的所有其他 APC 傳遞。 在釋放 mutex 之前,對 APC 傳遞的限制會持續存在。
Mutex 只能以遞歸方式取得MINLONG時間。 如果超過此限制,例程會引發STATUS_MUTANT_LIMIT_EXCEEDED例外狀況。
FsRtlCancellableWaitForMultipleObjects 必須在 IRQL PASSIVE_LEVEL呼叫,如果選擇性 Irp 參數指向有效的 IRP。 如果未使用 Irp 參數,則可以在 IRQL 呼叫例程,或小於或等於 APC_LEVEL。 呼叫端可以視需要呼叫 KeEnterCriticalRegion 或 FsRtlEnterFileSystem 例程來停用一般核心 APC。 不過,不得停用特殊核心 APC。
FsRtlCancellableWaitForMultipleObjects 如果 IRQL 大於或等於 APC_LEVEL,且 Irp 參數指向有效的 IRP,則會判斷提示偵錯組建。
要求
要求 | 價值 |
---|---|
最低支援的用戶端 | Windows Vista |
目標平臺 | 普遍 |
標頭 | ntifs.h (include Ntifs.h) |
連結庫 | NtosKrnl.lib |
DLL | NtosKrnl.exe |
IRQL | 請參閱一節。 |
DDI 合規性規則 | HwStorPortProhibitedDIS(storport)、PowerIrpDDis(wdm)、SpNoWait(storport) |