撰寫作業前回呼例程

迷你篩選驅動程式會使用一或多個 預先作業回呼例程 來篩選 I/O 作業。 作業前回呼例程 類似於 舊版篩選模型中所使用的分派例程

迷你篩選會藉由將回呼例程的進入點儲存在FLT_REGISTRATION結構的 OperationRegistration 成員中,為特定類型的 I/O 作業註冊預先作業回呼例程。 迷你篩選會將此成員傳遞至 FltMgr 做為其 DriverEntry 例程中的 FltRegisterFilter 參數。

迷你篩選只會接收他們已註冊作業前或作業後回呼例程的 I/O 作業類型。 迷你篩選可以註冊特定 I/O 作業類型的預先作業回呼例程,而不註冊 作業後回呼例程,反之亦然。

每個預先作業回呼例程的定義如下:

typedef FLT_PREOP_CALLBACK_STATUS 
(*PFLT_PRE_OPERATION_CALLBACK) ( 
    IN OUT PFLT_CALLBACK_DATA Data, 
    IN PCFLT_RELATED_OBJECTS FltObjects, 
    OUT PVOID *CompletionContext 
    ); 

當 FltMgr 針對指定的 I/O 作業呼叫迷你篩選的預先作業回呼例程時,迷你篩選會暫時控制 I/O 作業。 迷你篩選會保留此控件,直到下列其中一項:

  • 從其預先作業回呼例程傳回FLT_PREOP_PENDING以外的狀態值。

  • 從工作例程呼叫 FltCompletePendedPreOperation ,該例程已處理先前在其作業前回呼例程中加上畫筆的作業。

下表列出小型篩選預先作業回呼例程的一些可能使用案例,並提供每個案例的實作詳細數據和傳回值。

使用案例 實作 傳回的值
例程與作業無關,而且不需要作業的最終狀態,或沒有作業後回呼。 透過 傳遞 I/O 作業,並告知 FltMgr 不要在完成時呼叫迷你篩選的後續作業回呼。 FLT_PREOP_SUCCESS_NO_CALLBACK
例程需要作業的最終狀態。 透過 傳遞作業,並告知 FltMgr 呼叫迷你篩選的後續作業回呼例程。 FLT_PREOP_SUCCESS_WITH_CALLBACK
迷你篩選必須在未來完成或繼續處理此作業。 將作業放入擱置狀態。 使用 FltCompletePendedPreOperation 稍後完成作業。 在傳回FLT_PREOP_PENDING的作業前例程與呼叫 FltCompletePendingOperation 之間可能會有可接受的競爭。 FltMgr 會處理此案例,而不需要驅動程序的輸入。 FLT_PREOP_PENDING
後續作業處理必須在呼叫分派例程的相同線程內容中發生。 此條件可確保一致的 IRQL,並維護您的局部變數狀態。 將作業與後續作業同步處理。 FLT_PREOP_SYNCHRONIZE
作業前回呼例程必須完成作業。 停止處理作業,並指派最終 NTSTATUS 值。 FLT_PREOP_COMPLETE

IRQL 和作業前回呼例程

FltMgr 無法得知迷你篩選在其預先作業回呼 (或任何回呼) 中可能會執行的動作。 因此 FltMgr 無法得知對迷你埠預先作業回呼的呼叫是否可能造成問題。 (您可以在提升許可權的 IRQL 上安全地執行一些動作,以及您無法) 的專案。 因此,由迷你篩選瞭解 IRQL 並適當地處理。 迷你篩選可以安全地且便宜地呼叫 KeGetCurrentIRQL ,以瞭解其呼叫所在的 IRQL。

關於迷你篩選預先作業回呼例程 IRQL 的下列資訊,有助於瞭解:

  • 您可以在 IRQL = PASSIVE_LEVEL或 IRQL = APC_LEVEL呼叫作業前回呼。 在產生 I/O 要求的線程內容中,大部分的作業前回呼是在 IRQL = PASSIVE_LEVEL呼叫。 在 IRQL = APC_LEVEL,只能呼叫少數預先作業回呼。

  • 如果是 IRP 型作業,如果較高的篩選或迷你篩選驅動程式將作業寫入背景工作線程進行處理,則可以在系統背景工作線程的內容中呼叫迷你篩選工具的預先作業回呼。 作業前回呼相當於舊版篩選的分派例程,因此瞭解 舊版篩選的分派例程的 IRQL 和線程內容 可能會很有説明。

  • 在 IRQL > APC_LEVEL 的作業後例程中,無法擷取內容物件。 相反地,在作業前例程期間取得內容物件,並將它傳遞至作業後例程,或在 IRQL <= APC_LEVEL執行後續作業處理。 如需內容的詳細資訊,請參閱 管理內容

將 I/O 作業向下傳遞迷你篩選實例堆疊

在預先操作回呼例程中完成 I/O 作業

不允許預先操作回呼例程中的快速 I/O 作業

暫止預先操作回呼例程中的 I/O 作業