Accesso ai buffer utente in una routine di callback di preoperazione
Una routine di callback di preoperazione di un driver minifilter deve trattare un buffer in un'operazione di I/O basata su IRP come segue:
Controllare se esiste un MDL per il buffer. Il puntatore MDL è reperibile nel parametro MdlAddress o OutputMdlAddress nel FLT_PARAMETERS per l'operazione. I driver minifilter possono chiamare FltDecodeParameters per eseguire una query per il puntatore MDL.
Un metodo per ottenere un MDL valido consiste nel cercare il flag IRP_MN_MDL nel membro MinorFunction del blocco di parametri di I/O, FLT_IO_PARAMETER_BLOCK, nei dati di callback. Nell'esempio seguente viene illustrato come verificare la presenza del flag IRP_MN_MDL.
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; if (FlagOn(CallbackData->Iopb->MinorFunction, IRP_MN_MDL)) { ReadMdl = &CallbackData->Iopb->Parameters.Read.MdlAddress; }
Tuttavia, il flag IRP_MN_MDL può essere impostato solo per le operazioni di lettura e scrittura. È consigliabile usare FltDecodeParameters per recuperare un MDL, perché la routine verifica la presenza di un MDL valido per qualsiasi operazione. Nell'esempio seguente viene restituito solo il parametro MDL, se valido.
NTSTATUS status; PMDL *ReadMdl = NULL; PVOID ReadAddress = NULL; status = FltDecodeParameters(CallbackData, &ReadMdl, NULL, NULL, NULL);
Se esiste un MDL per il buffer, chiamare MmGetSystemAddressForMdlSafe per ottenere l'indirizzo di sistema per il buffer e quindi usare questo indirizzo per accedere al buffer.
Continuando dall'esempio precedente, il codice seguente ottiene l'indirizzo di sistema.
if (*ReadMdl != NULL) { ReadAddress = MmGetSystemAddressForMdlSafe(*ReadMdl, NormalPagePriority); if (ReadAddress == NULL) { CallbackData->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES; CallbackData->IoStatus.Information = 0; } }
Se non è presente alcun file MDL per il buffer, usare l'indirizzo del buffer per accedere al buffer. Per garantire che un indirizzo del buffer dello spazio utente sia valido, il driver minifilter deve usare una routine, ad esempio ProbeForRead o ProbeForWrite, racchiudendo tutti i riferimenti al buffer in try/tranne i blocchi.
Una routine di callback di preoperazione deve trattare un buffer in un'operazione di I/O veloce come segue:
Usare l'indirizzo del buffer per accedere al buffer perché un'operazione di I/O veloce non può avere un MDL.
Per garantire che un indirizzo del buffer dello spazio utente sia valido, il driver minifilter deve usare una routine, ad esempio ProbeForRead o ProbeForWrite, racchiudendo tutti i riferimenti al buffer in try/tranne i blocchi.
Per le operazioni che possono essere veloci di I/O o basate su IRP, tutti i riferimenti al buffer devono essere racchiusi tra i blocchi try/eccetto i blocchi. Anche se non è necessario racchiudere questi riferimenti per le operazioni basate su IRP che usano operazioni di I/O memorizzate nel buffer, il tentativo ad/eccezione dei blocchi è una precauzione sicura.