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.
Articoli correlati
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