Nota
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare ad accedere o a cambiare directory.
L'accesso a questa pagina richiede l'autorizzazione. Puoi provare a cambiare directory.
I driver costituiscono una percentuale significativa del codice totale eseguito in modalità kernel. Un driver in modalità kernel è, in effetti, un componente del sistema operativo. Pertanto, i driver affidabili e sicuri contribuiscono in modo significativo alla attendibilità complessiva del sistema operativo. Per creare un driver affidabile in modalità kernel, seguire queste linee guida:
Proteggere correttamente gli oggetti dispositivo.
L'accesso utente ai driver e ai dispositivi di un sistema è controllato dai descrittori di sicurezza assegnati dal sistema agli oggetti dispositivo. Nella maggior parte dei casi, il sistema imposta i parametri di sicurezza del dispositivo quando viene installato un dispositivo. Per altre informazioni, vedere Creazione di installazioni di dispositivi sicuri. A volte è opportuno che un driver svolga un ruolo nel controllo dell'accesso al suo dispositivo. Per altre informazioni, vedere Protezione degli oggetti dispositivo.
Convalidare correttamente gli oggetti dei dispositivi.
Se un driver crea più tipi di oggetti dispositivo, deve controllare il tipo ricevuto in ogni IRP. Per altre informazioni, vedere Errore di convalida degli oggetti dispositivo.
Usare le funzioni "safe string".
Quando si modificano le stringhe, un driver deve usare funzioni stringa sicure anziché le funzioni stringa fornite con librerie di runtime del linguaggio C/C++. Per ulteriori informazioni, vedere Utilizzo delle Funzioni di Stringa Sicure.
Convalidare gli handle degli oggetti.
I driver che ricevono handle di oggetto come input devono verificare che gli handle siano validi, siano accessibili e siano del tipo previsto. Per altre informazioni sull'uso degli handle di oggetti, vedere gli argomenti seguenti:
Supportare correttamente i multiprocessori.
Non presupporre mai che il driver venga eseguito solo su sistemi a processore singolo. Per informazioni sulle tecniche di programmazione che è possibile usare per assicurarsi che il driver funzioni correttamente nei sistemi multiprocessore, vedere gli argomenti seguenti:
Gestire correttamente lo stato del driver.
È importante verificare sempre che il driver sia nello stato in cui si presuppone che si trovi. Ad esempio, se il driver riceve un IRP, sta già gestendo un IRP dello stesso tipo? Se il driver non verifica questa situazione, il primo IRP potrebbe essere perso. Per ulteriori informazioni, vedere Mancata verifica dello stato di un driver.
Convalidare i valori di input IRP.
È essenziale, sia dal punto di vista dell'affidabilità che della sicurezza, convalidare tutti i valori associati a un IRP, ad esempio gli indirizzi e le lunghezze del buffer. Negli argomenti seguenti vengono fornite informazioni sulla convalida dei valori di input IRP:
DispatchReadWrite utilizzando I/O con buffering
DispatchReadWrite utilizzando I/O diretto
Errori in I/O diretto
Gestire correttamente lo stack di I/O.
Quando si passano i pacchetti di richiesta I/O allo stack di driver, è importante che i driver chiamino IoSkipCurrentIrpStackLocation o IoCopyCurrentIrpStackLocationToNext per preparare lo stack di I/O del driver successivo. Non scrivere codice che copia direttamente una posizione dello stack di I/O nella successiva.
Gestire correttamente le operazioni di completamento di IRP.
Un driver non deve mai completare un IRP con valore di stato STATUS_SUCCESS, a meno che supporti ed elabori effettivamente l'IRP. Per informazioni sui modi corretti per gestire le operazioni di completamento IRP, vedere Completamento IRP.
Gestire correttamente le operazioni di annullamento di IRP.
Le operazioni di annullamento possono essere difficili da scrivere correttamente perché in genere vengono eseguite in modo asincrono. I problemi nel codice che gestisce le operazioni di annullamento possono andare inosservati per molto tempo, perché questo codice in genere non viene eseguito di frequente in un sistema in esecuzione.
Assicurarsi di leggere e comprendere tutte le informazioni fornite in Annullamento degli IRP. Prestare particolare attenzione alla sincronizzazione dell'annullamento degli IRP e ai punti da tenere in considerazione quando si annullano gli IRP.
Un modo per evitare i problemi di sincronizzazione associati alle operazioni di annullamento consiste nell'implementare una coda IRP sicura per l'annullamento. Una coda IRP sicura all'annullamento è una coda gestita dal driver che è stata introdotta per Windows XP e versioni successive del sistema operativo, ma è anche compatibile con le versioni precedenti.
Gestire correttamente le operazioni di pulizia e chiusura di IRP.
Assicurati di comprendere la differenza tra le richieste IRP_MJ_CLEANUP e IRP_MJ_CLOSE. Le richieste di pulizia arrivano dopo che un'applicazione chiude tutti gli handle di un oggetto file, ma a volte prima che tutte le richieste di I/O siano state completate. Le richieste di chiusura arrivano dopo che tutte le richieste di I/O per l'oggetto file sono state completate o annullate. Per altre informazioni, vedere gli argomenti seguenti:
DispatchCreate, DispatchClose e DispatchCreateClose Routine
Errori durante la gestione delle operazioni di pulizia e chiusura
Per ulteriori informazioni sulla gestione corretta dei pacchetti di richiesta di I/O, vedere Errori aggiuntivi nella gestione dei pacchetti di richiesta di I/O.
Uso di Driver Verifier
Driver Verifier è lo strumento più importante che è possibile usare per garantire l'affidabilità del driver. Driver Verifier può verificare la presenza di un'ampia gamma di problemi comuni relativi ai driver, tra cui alcuni di quelli descritti in questa sezione. Tuttavia, l'uso di Driver Verifier non sostituisce la progettazione attenta e ponderata del software.