Condividi tramite


Vincoli per le routine di completamento

Nota

Per garantire affidabilità e prestazioni ottimali, usare i driver minifilter del file system con il supporto di Filter Manager anziché i driver di filtro del file system legacy. Per convertire il driver legacy in un driver minifilter, vedere Linee guida per la conversione dei driver di filtro legacy.

Le linee guida seguenti illustrano brevemente come evitare errori di programmazione comuni nelle routine di completamento del driver di filtro del file system legacy.

Poiché le routine di completamento possono essere chiamate in IRQL DISPATCH_LEVEL, sono soggetti ai vincoli seguenti:

  • Le routine di completamento non possono chiamare in modo sicuro routine in modalità kernel che richiedono un irQL inferiore, ad esempio IoDeleteDevice o ObQueryNameString.

  • Qualsiasi struttura di dati usata nelle routine di completamento deve essere allocata dal pool non con pagine.

  • Le routine di completamento non possono essere rese paginabili.

  • Le routine di completamento non possono acquisire risorse, mutex o mutex veloci. Tuttavia, possono acquisire blocchi di spin.

Controllo del flag PendingReturned

  • A meno che la routine di completamento segnali un evento, deve controllare il flag Irp-PendingReturned>. Se questo flag è impostato, la routine di completamento deve chiamare IoMarkIrpPending per contrassegnare l'IRP come in sospeso.

  • Se una routine di completamento segnala un evento, non deve chiamare IoMarkIrpPending.

Vincoli per la restituzione dello stato

  • Una routine di completamento del driver di filtro del file system deve restituire STATUS_SUCCESS o STATUS_MORE_PROCESSING_REQUIRED. Tutti gli altri valori NTSTATUS vengono reimpostati in STATUS_SUCCESS da Gestione I/O.

Vincoli per la restituzione di STATUS_MORE_PROCESSING_REQUIRED

Esistono tre casi in cui le routine di completamento devono restituire STATUS_MORE_PROCESSING_REQUIRED:

  • Quando la routine di invio corrispondente è in attesa della routine di completamento per segnalare un evento. In questo caso, è importante restituire STATUS_MORE_PROCESSING_REQUIRED per impedire al gestore di I/O di completare prematuramente l'IRP dopo il ritorno della routine di completamento.

  • Quando la routine di completamento ha inviato l'IRP a una coda di lavoro e la routine di invio corrispondente è stata restituita STATUS_PENDING. In questo caso, è anche importante restituire STATUS_MORE_PROCESSING_REQUIRED per impedire a Gestione I/O di completare prematuramente l'IRP dopo che la routine di completamento restituisce.

  • Quando lo stesso driver ha creato l'IRP chiamando IoAllocateIrp o IoBuildAsynchronousFsdRequest. Poiché il driver non ha ricevuto l'IRP da un driver di livello superiore, può liberare in modo sicuro l'IRP nella routine di completamento. Dopo la routine di completamento chiama IoFreeIrp, deve restituire STATUS_MORE_PROCESSING_REQUIRED per indicare che non è necessaria un'ulteriore elaborazione di completamento.

Una routine di completamento non può restituire STATUS_MORE_PROCESSING_REQUIRED per un'operazione di oplock. Le operazioni di oplock non possono essere pennate (pubblicate in una coda di lavoro) e le routine di invio non possono restituire STATUS_PENDING per loro.

Vincoli per la registrazione di IRP in una coda di lavoro

  • Se una routine di completamento inserisce irP in una coda di lavoro, deve chiamare IoMarkIrpPending prima di pubblicare ogni IRP nella coda di lavoro. In caso contrario, l'IRP potrebbe essere dequeued, completato da un'altra routine driver e liberato dal sistema prima che la chiamata a IoMarkIrpPending si verifichi, causando così un arresto anomalo.