Scrittura di routine di callback pre-operazione

Un driver minifilter usa una o più routine di callback pre-operazione per filtrare le operazioni di I/O. Le routine di callback di pre-operazione sono simili alle routine di invio usate nel modello di filtro legacy.

Un minifilter registra una routine di callback pre-operazione per un particolare tipo di operazione di I/O archiviando il punto di ingresso della routine di callback nel membro OperationRegistration della struttura FLT_REGISTRATION . Il minifilter passa questo membro a FltMgr come parametro a FltRegisterFilter nella routine DriverEntry .

I minifilter ricevono solo questi tipi di operazioni di I/O per cui hanno registrato una routine di callback pre-operazione o post-operazione. Un minifilter può registrare una routine di callback pre-operazione per un determinato tipo di operazione di I/O senza registrare una routine di callback post-operazione e viceversa.

Ogni routine di callback di pre-operazione è definita come segue:

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

Quando FltMgr chiama la routine di callback pre-operazione di un minifilter per un'operazione di I/O specificata, il minifilter controlla temporaneamente l'operazione di I/O. Il minifiltro mantiene questo controllo fino a quando non è possibile:

  • Restituisce un valore di stato diverso da FLT_PREOP_PENDING dalla routine di callback pre-operazione.

  • Chiama FltCompletePendedPreOperation da una routine di lavoro che ha elaborato un'operazione precedentemente pennata nella routine di callback pre-operazione.

La tabella seguente elenca alcuni possibili scenari di utilizzo della routine di callback di un minifilter e fornisce i dettagli di implementazione e il valore restituito per ogni scenario.

Scenario di utilizzo Implementazione Valore restituito
La routine non è rilevante per l'operazione e non richiede lo stato finale dell'operazione o non ha un callback post-operazione. Passare l'operazione di I/O e indicare a FltMgr di non chiamare il callback post-operazione del minifilter al completamento. FLT_PREOP_SUCCESS_NO_CALLBACK
La routine richiede lo stato finale dell'operazione. Passare l'operazione attraverso e indicare a FltMgr di chiamare la routine di callback post-operazione del minifilter. FLT_PREOP_SUCCESS_WITH_CALLBACK
Il minifilter deve completare o continuare l'elaborazione di questa operazione in futuro. Inserire l'operazione in uno stato in sospeso. Usare FltCompletePendedPreOperation per completare l'operazione in un secondo momento. Potrebbe esserci una gara accettabile tra la routine di pre-operazione che restituisce FLT_PREOP_PENDING e FltCompletePendingOperation chiamato. FltMgr gestisce questo scenario senza input dal driver. FLT_PREOP_PENDING
L'elaborazione post-operazione deve verificarsi nel contesto dello stesso thread chiamato dalla routine di invio. Questa condizione garantisce un irQL coerente e mantiene lo stato della variabile locale. Sincronizzare l'operazione con il post-operazione. FLT_PREOP_SYNCHRONIZE
La routine di callback pre-operazione deve completare l'operazione. Arrestare l'elaborazione per l'operazione e assegnare il valore NTSTATUS finale. FLT_PREOP_COMPLETE

Routine di callback irQL e pre-operazione

FltMgr non ha modo di sapere cosa potrebbe fare un minifilter nel callback pre-operazione (o qualsiasi callback). Quindi FltMgr non ha modo di sapere se una chiamata al callback pre-op del miniport potrebbe causare un problema. (Ci sono cose che è possibile eseguire in modo sicuro in IRQL con privilegi elevati e cose che non è possibile). Pertanto, è necessario che il minifiltro sia consapevole di IRQL e gestirlo in modo appropriato. Un minifilter può chiamare in modo sicuro e economico KeGetCurrentIRQL per situazioni in cui deve conoscere irQL in corrispondenza del quale è stato chiamato.

Le informazioni seguenti sulla routine di callback pre-operazione di un minifilter sono utili per sapere:

  • È possibile chiamare un callback pre-operazione in IRQL = PASSIVE_LEVEL o IRQL = APC_LEVEL. La maggior parte dei callback di pre-operazione viene chiamata in IRQL = PASSIVE_LEVEL, nel contesto del thread che ha generato la richiesta di I/O. Solo una manciata di callback di pre-operazione potrebbe essere chiamata in IRQL = APC_LEVEL.

  • Per le operazioni basate su IRP, il callback di pre-operazione di un minifilter può essere chiamato nel contesto di un thread di lavoro di sistema se un driver di filtro o minifilter superiore esegue l'operazione per l'elaborazione dal thread di lavoro. Un callback di pre-operazione è l'equivalente della routine di invio di un filtro legacy, quindi è possibile conoscere il contesto irQL e thread della routine di invio di un filtro legacy .

  • Gli oggetti di contesto non possono essere recuperati nelle routine post-operazione in IRQL > APC_LEVEL. Ottenere invece l'oggetto contesto durante una routine di pre-operazione e passarlo alla routine post-operazione o eseguire l'elaborazione post-operazione in IRQL <= APC_LEVEL. Per altre informazioni sui contesti, vedere Gestione dei contesti.

Passaggio di un'operazione di I/O nello stack di istanze minifilter

Completamento di un'operazione di I/O in una routine di callback preoperazione

Rimozione di un'operazione di I/O veloce in una routine di callback preoperazione

In sospeso un'operazione di I/O in una routine di callback preoperazione