Creazione di driver di esportazione
Un driver di esportazione è una DLL in modalità kernel che può essere caricata da un'ampia gamma di altri componenti specifici dell'hardware o specifici dello stack di dispositivi, ma non presenta alcune delle caratteristiche di un driver completo in modalità kernel. In particolare, un driver di esportazione non dispone di una tabella dispatch, non ha una posizione nello stack di driver e non ha una voce nel database del gestore di controllo del servizio che lo definisce come servizio di sistema. Anche se un driver di esportazione non dispone di una tabella dispatch, può fornire routine di invio a un driver standard. Il driver standard inserisce le routine dispatch nella propria tabella dispatch. Un driver di esportazione ha una routine driverEntry stub che non viene mai chiamata.
I driver di esportazione in modalità kernel sono particolarmente adatti per implementare la parte di una coppia di driver indipendentemente dalle caratteristiche hardware e dello stack sottostanti.
Windows include diversi driver di esportazione caricati da altri driver, ad esempio:
- Driver della porta SCSI
- Driver di classe nastro
- Il driver controller IDE sono tutti driver di esportazione forniti dal sistema
I driver Standard possono anche funzionare come driver di esportazione. Affinché un driver funzioni in entrambi i modi, deve essere compilato come driver di esportazione e caricato come driver normale.
Compilazione di un driver di esportazione
Per creare un driver di esportazione in Visual Studio, seguire questa procedura:
- Creare un nuovo progetto da un modello, ad esempio Driver WDM vuoto.
- Aggiungere un file di definizione del modulo al progetto, ad esempio:
LIBRARY mydriver.sys
EXPORTS
DllInitialize PRIVATE
DllUnload PRIVATE
Il punto di ingresso per una DLL in modalità kernel è sempre DllInitialize. Il sistema chiama una routine DllInitialize in modalità kernel immediatamente dopo il caricamento della DLL. I driver di esportazione devono fornire routine DllInitialize . È possibile usare la routine DllInitialize per acquisire o inizializzare le risorse richieste da altre routine nella DLL.
Non è possibile specificare il punto di ingresso usando la macro DLLENTRY .
NTSTATUS DllInitialize(
_In_ PUNICODE_STRING RegistryPath
);
RegistryPath è un puntatore a una stringa Unicode con conteggiata che specifica il percorso della chiave del Registro di sistema della DLL ,HKEY_LOCAL_MACHINE\CurrentControlSet\Services\DllName. Le routine DLL possono usare questa chiave per archiviare informazioni specifiche della DLL. Il buffer a cui punta RegistryPath viene liberato dopo la chiusura di DllInitialize . Pertanto, se la DLL usa la chiave, DllInitialize deve duplicare il nome della chiave.
Il processo di compilazione genera una libreria di esportazione con estensione lib e un driver di esportazione con estensione .sys.
Importazione di funzioni da un driver di esportazione
Per importare le funzioni esportate da un driver di esportazione, è necessario dichiarare le funzioni usando la macro DECLSPEC_IMPORT, definita in Ntdef.h. Ad esempio:
DECLSPEC_IMPORT int LoadPrinterDriver (int arg1);
Questa macro viene risolta in una dichiarazione di classe di archiviazione __declspec(dllimport) su tali piattaforme, se necessario e su nessuna delle piattaforme in cui non è necessario.
Nel driver di esportazione la funzione da esportare deve essere dichiarata con la macro DECLSPEC_EXPORT. Questa macro viene risolta in una dichiarazione di classe di archiviazione __declspec(dllexport) su tali piattaforme, se necessario e su nessuna delle piattaforme in cui non è necessario. Se un driver di esportazione fornisce una routine dispatch a un driver standard, tale routine non deve essere esportata.
Caricamento e scaricamento di un driver di esportazione
I driver di esportazione devono essere installati nella directory %Windir%\System32\Drivers. A partire da Windows 2000, il sistema operativo mantiene un conteggio dei riferimenti che indica il numero di volte in cui le funzioni del driver di esportazione sono state importate da altri driver. Il sistema decrementa questo conteggio ogni volta che uno dei driver di importazione scarica. Quando il conteggio dei riferimenti scende a zero, il sistema scarica il driver di esportazione. Tuttavia, il driver di esportazione deve contenere il punto di ingresso standard e scaricare routine, DllInitialize e DllUnload oppure il sistema operativo non attiverà questo meccanismo di conteggio dei riferimenti.
Il sistema chiama una routine DllUnload in modalità kernel quando scarica la DLL.
NTSTATUS DllUnload(void);
I driver di esportazione devono fornire routine DllUnload. È possibile usare la routine DllUnload per rilasciare tutte le risorse usate dalle routine nella DLL.