IO_COMPLETION_ROUTINE funzione di callback (wdm.h)

La routine IoCompletion completa l'elaborazione delle operazioni di I/O.

Sintassi

IO_COMPLETION_ROUTINE IoCompletionRoutine;

NTSTATUS IoCompletionRoutine(
  [in]           PDEVICE_OBJECT DeviceObject,
  [in]           PIRP Irp,
  [in, optional] PVOID Context
)
{...}

Parametri

[in] DeviceObject

Puntatore fornito dal chiamante a una struttura DEVICE_OBJECT . Si tratta dell'oggetto dispositivo per il dispositivo di destinazione, creato in precedenza dalla routine AddDevice del driver.

[in] Irp

Puntatore fornito dal chiamante a una struttura IRP che descrive l'operazione di I/O.

[in, optional] Context

Puntatore fornito dal chiamante alle informazioni sul contesto specifiche del driver, fornite in precedenza quando si chiama IoSetCompletionRoutine o IoSetCompletionRoutineEx. Le informazioni sul contesto devono essere archiviate in memoria non paginata, poiché è possibile chiamare una routine IoCompletion in DISPATCH_LEVEL. Per ulteriori informazioni, vedere la sezione Osservazioni successiva.

Valore restituito

Se la routine IoCompletion determina che è necessaria un'elaborazione aggiuntiva per l'IRP, deve restituire STATUS_MORE_PROCESSING_REQUIRED. Per ulteriori informazioni, vedere la sezione Osservazioni successiva. In caso contrario, deve restituire STATUS_SUCCESS. Il gestore I/O controlla solo la presenza o l'assenza di STATUS_MORE_PROCESSING_REQUIRED.

Commenti

La routine IoCompletion di un driver viene eseguita in un contesto arbitrario o DPC e in un irQL minore o uguale a DISPATCH_LEVEL. Poiché il codice scritto per l'esecuzione in DISPATCH_LEVEL verrà eseguito anche a livelli inferiori, le routine IoCompletion devono essere progettate per l'esecuzione in DISPATCH_LEVEL. Tuttavia, poiché queste routine non sono garantite per l'esecuzione in DISPATCH_LEVEL, non devono chiamare routine di sistema che richiedono effettivamente l'esecuzione in DISPATCH_LEVEL. Per altre informazioni sui irQLs, vedere Gestione delle priorità hardware.

Per registrare una routine IoCompletion per un'IRP specifica, un driver deve chiamare IoSetCompletionRoutine o IoSetCompletionRoutineEx, che archivia l'indirizzo della routine IoCompletion nella posizione dello stack I/O del driver inferiore successivo. Pertanto, un driver di livello più basso non può registrare una routine IoCompletion . Un driver chiama in genere IoSetCompletionRoutine o IoSetCompletionRoutineEx da una delle routine di invio, ogni volta che viene ricevuto un'istanza di IRP . La maggior parte dei driver, inclusi tutti i driver PnP, può usare IoSetCompletionRoutine per registrare la routine IoCompletion . I driver non PnP che possono essere scaricati prima dell'esecuzione della routine IoCompletion devono usare invece IoSetCompletionRoutineEx.

Quando un driver completa un'IRP, chiama IoCompleteRequest, che a sua volta chiama la routine IoCompletion di ogni driver di livello superiore, dal più alto al massimo fino a quando non sono state chiamate tutte le routine IoCompletion superiori o finché una routine restituisce STATUS_MORE_PROCESSING_REQUIRED.

Quando si crea l'IRP, allocare una posizione dello stack per il driver corrente e tutti i driver inferiori. Se non si allocano percorsi di stack sufficienti, il puntatore DeviceObject potrebbe essere impostato su NULL quando viene chiamata la routine di completamento. È possibile evitare di allocare un percorso di stack aggiuntivo per il driver corrente se si usa il campo Contesto per passare le informazioni a IoCompletion anziché basarsi sul parametro DeviceObject .

Se una routine IoCompletion restituisce STATUS_MORE_PROCESSING_REQUIRED, la chiamata del driver inferiore a IoCompleteRequest restituisce immediatamente. In questo caso, un driver di livello superiore dovrà chiamare IoCompleteRequest per completare l'IRP .

Per altre informazioni sull'implementazione delle routine di IoCompletion , vedere Completamento degli indirizzi DI accesso.

Esempio

Per definire una routine di callback IoCompletion , è prima necessario specificare una dichiarazione di funzione che identifica il tipo di routine di callback che si sta definendo. Windows fornisce un set di tipi di funzione di callback per i driver. La dichiarazione di una funzione usando i tipi di funzione callback consente l'analisi del codice per i driver, il verifica driver statico (SDV) e altri strumenti di verifica trovano errori ed è un requisito per la scrittura di driver per il sistema operativo Windows.

Ad esempio, per definire una routine di callback IoCompletion denominata MyIoCompletion, usare il tipo di IO_COMPLETION_ROUTINE, come illustrato nell'esempio di codice seguente:

IO_COMPLETION_ROUTINE MyIoCompletion;

Implementare quindi la routine di callback come indicato di seguito:

_Use_decl_annotations_
NTSTATUS
  MyIoCompletion(
    PDEVICE_OBJECT  DeviceObject,
    PIRP  Irp,
    PVOID  Context
    )
  {
      // Function body
  }

Il tipo di funzione IO_COMPLETION_ROUTINE è definito nel file di intestazione Wdm.h. Per identificare in modo più accurato gli errori quando si eseguono gli strumenti di analisi del codice, assicurarsi di aggiungere l'annotazione _Use_decl_annotations_ alla definizione della funzione. L'annotazione _Use_decl_annotations_ garantisce che vengano usate le annotazioni applicate al tipo di funzione IO_COMPLETION_ROUTINE nel file di intestazione. Per altre informazioni sui requisiti per le dichiarazioni di funzione, vedere Dichiarazione di funzioni tramite tipi di ruolo per i driver WDM. Per informazioni su _Use_decl_annotations_, vedere Annotazione del comportamento della funzione.

Requisiti

Requisito Valore
Piattaforma di destinazione Desktop
Intestazione wdm.h (include Wdm.h, Ntddk.h, Ntifs.h)
IRQL Chiamato in IRQL <= DISPATCH_LEVEL (vedere la sezione Osservazioni).