Dal codice di esempio al driver di produzione - Cosa modificare negli esempi

In questo argomento vengono descritte le modifiche importanti che devono essere apportate ai driver di esempio WDK prima di rilasciare i driver di dispositivo in base al codice di esempio.

Oltre alle modifiche descritte qui, tutti i driver devono usare le procedure consigliate descritte in Creazione di driver reliable Kernel-Mode e in Procedure consigliate per lo sviluppo di driver di Surface Team. Tutti i driver devono inoltre rispettare le linee guida fornite in Guida alla sicurezza dei driver.

Esempi di driver WDK - Identificatori univoci

Windows Driver Kit (WDK) contiene un'ampia gamma di driver di esempio che illustrano tecniche utili per lo sviluppo di driver. È possibile usare questi esempi come base per i propri driver, ma prima di rilasciare il driver, è necessario modificare alcuni aspetti specifici del dispositivo dell'esempio, oltre al codice operativo ovvio, da applicare in modo univoco al proprio dispositivo e driver. Gli autori di driver a volte ignorano questi dettagli.

Gli elementi esatti che è necessario modificare variano da un campione a quello successivo, ma in generale identificano un dispositivo, un'interfaccia o un driver specifici. Ad esempio, se il driver di esempio contiene uno dei seguenti elementi, è necessario modificarli per applicarli al driver e al dispositivo:

  • Identificatori univoci globali (GUID)

  • Nomi di collegamento simbolici

  • Nome dell'oggetto dispositivo

  • Tag del pool

  • Definizioni di codice di controllo I/O (IOCTL)

  • Nomi di tutti i file copiati nella cartella di sistema

  • ID dispositivo Plug and Play, ID hardware e ID compatibili

  • Nome del servizio driver

  • Descrizione del dispositivo

  • File di risorse

Dimenticando di apportare queste modifiche, l'installazione non riesce, i conflitti con altri dispositivi e driver nel sistema e le difficoltà nel debug, insieme ad altri errori.

Ad esempio, se viene visualizzato un errore simile ...\toastDrv\kmdf\toastmon\wdftoastmon.inx(18-18): error 1284: Class "Sample" is reserved for use by Microsoft. a questo indica che il nome "Sample" deve essere modificato in un nome univoco per il driver di esempio.

GUID

I driver usano GUID per identificare classi di installazione dei dispositivi, classi di interfaccia dispositivo, eventi PnP personalizzati, eventi WMI (Windows Management Instrumentation) personalizzati e provider di traccia WPP (Windows PreProcessor). Alcuni GUID sono definiti da Microsoft e altri sono definiti dai fornitori di dispositivi e driver.

I GUID della classe di installazione del dispositivo, i GUID della classe dell'interfaccia del dispositivo e i GUID WMI per i dispositivi comuni e i dati WMI sono definiti nel WDK o nei file di intestazione pubblica da usare da qualsiasi driver. Non è consigliabile modificare questi GUID.

Ad esempio, se si implementa un mouse, si continuerà a usare GUID_DEVINTERFACE_MOUSE, definito nel file di intestazione WDK Ntddmou.h, come classe dell'interfaccia del dispositivo. Tuttavia, se si definisce una nuova classe di installazione del dispositivo, è necessario generare un nuovo GUID della classe di installazione del dispositivo e un nuovo nome della classe di installazione del dispositivo e possibilmente anche un nuovo GUID della classe dell'interfaccia del dispositivo. Il GUID della classe di installazione e il GUID della classe dell'interfaccia del dispositivo devono essere valori univoci; non possono condividere un GUID.

Per la maggior parte dei driver basati su campioni, è necessario modificare solo i GUID definiti nell'intestazione locale o nel file di origine di un esempio e sono quindi specifici per l'esempio. Tali GUID possono includere quanto segue:

  • Eventi PnP personalizzati

  • Eventi WMI personalizzati

  • Classi di interfaccia del dispositivo per dispositivi nuovi o personalizzati

  • Provider di traccia WPP

L'uso di un GUID definito per un altro driver può causare conflitti se entrambi i driver vengono caricati nello stesso sistema. Ad esempio, se due driver diversi usano lo stesso GUID per registrare un'interfaccia del dispositivo, i client che tentano di aprire l'interfaccia del dispositivo potrebbero aprire inavvertitamente il dispositivo errato.

L'estratto seguente è tratto dal file Driver.h incluso in tutti gli esempi di driver Tostapane. Definisce il GUID dell'interfaccia del dispositivo per i dispositivi Tostapane:

DEFINE_GUID(GUID_TOASTER_INTERFACE_STANDARD, \
            0xe0b27630, 0x5434, 0x11d3, 0xb8, 0x90, 0x0, 0xc0, \
            0x4f, 0xad, 0x51, 0x71);
// {E0B27630-5434-11d3-B890-00C04FAD5171}

Se si usa questo file nel proprio driver, assicurarsi di sostituire il GUID di esempio (illustrato sopra come testo grassetto) con il GUID dell'interfaccia per il proprio dispositivo. Per creare un GUID, usare lo strumento Crea GUID in Microsoft Visual Studio o Guidgen.exe, entrambi inclusi in Microsoft Windows Software Development Kit (SDK). È quindi possibile associare il GUID a una costante simbolica nel file di intestazione del driver, come illustrato nell'esempio.

Potrebbe anche essere necessario creare nuovi GUID per gli eventi WMI del driver. Gli esempi di driver Tostapane definiscono il GUID seguente per la notifica dell'arrivo del dispositivo tostapane:


DEFINE_GUID (TOASTER_NOTIFY_DEVICE_ARRIVAL_EVENT, \
             0x1cdaff1, 0xc901, 0x45b4, 0xb3, 0x59, 0xb5, 0x54, \
             0x27, 0x25, 0xe2, 0x9c);
// {01CDAFF1-C901-45b4-B359-B5542725E29C}

È necessario creare un nuovo GUID per ogni evento WMI nel driver.

Se il driver di esempio usa la traccia software WPP, generare un nuovo GUID del provider di traccia per tutti i driver in base all'esempio. Ad esempio, il file di intestazione Trace.h dell'esempio Osrusbfx2 in %WinDDK%\Src\Kmdf\Osrusbfx2\Final definisce un GUID di controllo come indicato di seguito:

#define WPP_CONTROL_GUIDS \
    WPP_DEFINE_CONTROL_GUID( \
           OsrUsbFxTraceGuid,(d23a0c5a,d307,4f0e,ae8e,E2A355AD5DAB), \
        WPP_DEFINE_BIT(DBG_INIT)          /* bit  0 = 0x00000001 */ \
        WPP_DEFINE_BIT(DBG_PNP)           /* bit  1 = 0x00000002 */ \
        WPP_DEFINE_BIT(DBG_POWER)         /* bit  2 = 0x00000004 */ \
        WPP_DEFINE_BIT(DBG_WMI)           /* bit  3 = 0x00000008 */ \
        WPP_DEFINE_BIT(DBG_CREATE_CLOSE)  /* bit  4 = 0x00000010 */ \
        WPP_DEFINE_BIT(DBG_IOCTL)         /* bit  5 = 0x00000020 */ \
        WPP_DEFINE_BIT(DBG_WRITE)         /* bit  6 = 0x00000040 */ \
        WPP_DEFINE_BIT(DBG_READ)          /* bit  7 = 0x00000080 */ \
       )

Nel driver personalizzato sostituire il testo grassetto con un nome specifico del driver e il GUID creato.

Se l'esempio definisce un nome di collegamento simbolico, sostituire il nome nell'esempio con un nome applicabile al driver. Tuttavia, non modificare nomi di collegamento noti, ad esempio \DosDevices\COM1. In generale, se il nome del collegamento è molto simile al nome di esempio (ad esempio \DosDevices\CancelSamp) è necessario modificarlo.

L'uso dello stesso collegamento simbolico di un altro driver ha lo stesso effetto dell'uso del GUID dell'interfaccia del dispositivo errato, perché le interfacce del dispositivo sono essenzialmente collegamenti simbolici.

Il driver filtro tostapane KMDF in %WinDDK\Src\Kmdf\Pane\Filter crea un nome di collegamento simbolico che usa una stringa definita come segue nel file di intestazione Filter.h:

#define SYMBOLIC_NAME_STRING     L"\\DosDevices\\ToasterFilter"

Modificare la stringa in grassetto in modo più accurato per descrivere il proprio driver.

Nome oggetto dispositivo

Se l'esempio crea un nome per l'oggetto dispositivo, è necessario modificare il nome quando si adatta il codice di esempio.

Il driver Del filtro tostapane KMDF assegna al driver il nome dell'oggetto dispositivo nel file di intestazione Filter.h come indicato di seguito:

#define NTDEVICE_NAME_STRING      L\\Device\\ToasterFilter

Come per il nome del collegamento simbolico, è necessario modificare la stringa per descrivere il driver.

Tenere presente che gli oggetti dispositivo denominati possono rappresentare un rischio per la sicurezza. Gli oggetti dispositivo fisico (PDO) devono avere nomi e la maggior parte dei nomi di questo tipo viene generata dal sistema anziché assegnata in modo esplicito da un driver. Gli altri oggetti dispositivo devono essere denominati solo se rappresentano oggetti dispositivo di controllo, usati per la comunicazione sideband tra un'applicazione e un driver. Sia il framework del driver in modalità kernel (KMDF) che il modello di driver Windows (WDM) consentono di consentire a Windows di generare il nome. Questo approccio garantisce che il nome dell'oggetto dispositivo sia univoco e che gli utenti senza privilegi non possano accedervi. Per informazioni dettagliate, vedere Controllo dell'accesso allo spazio dei nomi dei dispositivi e controllo dell'accesso ai dispositivi nei driver KMDF.

Tag del pool

Un tag del pool è un valore letterale uno-a-quattro caratteri che identifica un'allocazione di memoria specifica e può facilitare il debug.

Molti dei driver di esempio definiscono un tag del pool nel file di intestazione del driver, come nella riga seguente daPane.h:

#define TOASTER_POOL_TAG (ULONG) 'saoT'

Il driver definisce il tag all'indietro perché il debugger lo visualizza in ordine inverso. Di conseguenza, questo tag viene visualizzato come Toas nell'output del debugger. Anziché usare il tag definito dall'esempio, modificare la stringa in modo da identificare in modo univoco il codice.

Il file Pooltag.txt elenca i tag del pool usati dai componenti e dai driver in modalità kernel forniti con Windows. Pooltag.txt viene installato con WDK in %winddk%\Tools\Other<i>platform\Poolmon, dove platform è amd64, i386 o ia64. Non usare alcun tag visualizzato in questo elenco.

Definizioni IOCTL

Modificare i codici di controllo di I/O definiti dall'esempio per usare un nome, un tipo di dispositivo, un codice di funzione, un tipo di trasferimento e un tipo di accesso appropriati per il dispositivo e il driver.

Ad esempio, l'esempio Osrusbfx2 include la definizione seguente per IOCTL_OSRUSBFX2_READ_SWITCHES:

#define IOCTL_OSRUSBFX2_READ_SWITCHES   
                    CTL_CODE(FILE_DEVICE_OSRUSBFX2, \
                             IOCTL_INDEX + 6, \
                             METHOD_BUFFERED, \
                             FILE_READ_ACCESS)

Un driver basato su esempio per un dispositivo diverso richiede modifiche a questa definizione.

Nomi file

In INF o INX modificare i nomi del driver, il co-programma di installazione fornito dal fornitore e tutti gli altri file copiati dalla procedura di installazione nella cartella di sistema. Questi nomi di file vengono in genere visualizzati nelle sezioni [SourceDisksFiles] e [ClassInstall32] delle voci INF e CopyFiles .

L'esempio seguente è tratto dal file INX per l'esempio di tostapane in primo piano kmDF, disponibile in %WinDDK%\src\kmdf\Pane\Func\Featured. I nomi di file che devono essere modificati vengono visualizzati in grassetto:

[ClassInstall32]
Addreg=ToasterClassReg
CopyFiles=ToasterClassInstallerCopyFileshighlight

[ToasterClassReg]
...
HKR,,Installer32,,"tostrcls.dll,ToasterClassInstaller"
...

[ToasterClassInstallerCopyFiles]
tostrcls.dll									    
...

Per adattare questa parte del file per un driver diverso, è necessario modificare "tostrcls.dll" con il nome file del programma di installazione della classe e modificare la stringa "PaneClassInstaller" per descrivere il programma di installazione. Queste modifiche assicurano che la procedura di installazione copia il file di co-programma di installazione corretto e che la chiave del Registro di sistema registra il nome file corretto.

Non modificare il nome dei co-installer forniti in WDK o con Windows, ad esempio KMDF, UMDF e co-installer WinUSB.

Altre modifiche sono necessarie più avanti nella sezione Installazione del dispositivo del file, come illustrato in questo esempio:

[Toaster_Device.NT]
CopyFiles=Toaster_Device.NT.Copy

[Toaster_Device.NT.Copy]
wdffeatured.sys

In questo esempio il nome del file con grassetto viene modificato con il nome del file del driver generato.

Quando il programma di installazione copia i file di catalogo INF e driver, li rinomina, quindi non è strettamente necessario modificare i nomi nel pacchetto driver. Tuttavia, è in genere consigliabile assicurarsi che i nomi di file INF e catalogo siano simili al nome del file del driver.

ID dispositivo PnP, ID hardware e ID compatibili

Il programma di installazione usa l'ID dispositivo insieme agli ID hardware e agli ID compatibili per selezionare l'INF da usare per l'installazione del dispositivo.

L'ID dispositivo è una stringa definita dal fornitore che identifica in modo univoco un dispositivo specifico. Ogni dispositivo ha esattamente un ID dispositivo. Il driver del bus segnala l'ID dispositivo durante l'enumerazione e il programma di installazione lo usa per associare il dispositivo al file INF corretto. L'ID dispositivo è definito nella sezione [Produttore] dell'INF.

Nell'esempio seguente viene illustrato l'ID dispositivo per il dispositivo OSR USB Fx2, come specificato nel file Osrusbfx2.inx:

[Manufacturer]
%MfgName%=Microsoft,NT$ARCH$

; For Win2K
[Microsoft]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002
...

; For XP and later
[Microsoft.NT$ARCH$]
%USB\VID_045E&PID_930A.DeviceDesc%=osrusbfx2.Dev, 
        USB\VID_0547&PID_1002

Per adattare questa direttiva INF per il proprio driver, sostituire l'ID dispositivo visualizzato in grassetto con l'ID dispositivo per il proprio dispositivo. È anche necessario modificare il nome del produttore nel nome dell'azienda.

L'ID hardware e l'ID compatibile sono id meno specifici usati dall'installazione se non è in grado di corrispondere all'ID dispositivo a un INF. Se INF può supportare altri dispositivi, è necessario modificare questi valori oltre all'ID dispositivo. L'esempio seguente dal driver Del Tostapane in primo piano kmDF mostra un ID hardware:


[Manufacturer]
%StdMfg%=Standard,NT$ARCH$

; For Win2K
[Standard]
; DisplayName                   Section           DeviceId
; -----------                   -------           --------
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

; For XP and later
[Standard.NT$ARCH$]
%ToasterDevice.DeviceDesc%=Toaster_Device, 
         {b85b7c50-6a01-11d2-b841-00c04fad5171}\MsToaster

Per adattare questa direttiva INF per il proprio driver, sostituire l'ID hardware con l'ID dispositivo del driver e modificare "MsToaster" in una stringa più descrittiva.

Nome del servizio driver

Aggiornare il nome del servizio nella direttiva AddService in INF a un valore appropriato per il driver. Se il nome del servizio driver è in conflitto con quello di un altro driver nel sistema, il driver non verrà installato o caricato.

Il driver Di primo piano del Servizio di gestione delle chiavi in primo piano assegna al servizio il seguente:


[Toaster_Device.NT.Services]
AddService = wdffeatured, %SPSVCINST_ASSOCSERVICE%,
     wdffeatured_Service_Inst
      

Il nome del servizio è la prima voce nella direttiva AddService . Per adattare l'INF del tostapane in primo piano, si modifica la stringa grassetto in una stringa più adatta per il driver. Nell'esempio, la voce wdffeatured_Service_Inst fa semplicemente riferimento a una sezione definita da INF, quindi la modifica non è critica.

Device Description

La descrizione del dispositivo è costituita da diverse stringhe che sono in genere definite nella sezione [Strings] dell'INF e vengono usate in varie posizioni in tutta l'area INF. Ad esempio, l'esempio di tostapane in primo piano kmDF definisce le stringhe seguenti nel file WdfFeatured.inx:

[Strings]
SPSVCINST_ASSOCSERVICE   = 0x00000002
MSFT                     = "Microsoft"
StdMfg                   = "(Standard system devices)"
ClassName                = "Toaster"
DiskId1                  = "Toaster Device Installation Disk #1"
ToasterDevice.DeviceDesc = "Microsoft WDF Featured Toaster"
Toaster.SVCDESC          = "Microsoft WDF Toaster Featured Device Driver"

Per modificare questo file per installare il proprio driver, è necessario modificare le stringhe in grassetto per riflettere le informazioni relative all'azienda, al dispositivo e al driver.

Se il nome della società viene visualizzato anche in una sezione [Produttore] in INF, è necessario modificare anche il nome.

File di risorse

I driver e altri componenti, ad esempio co-installer specifici di esempio, dispongono anche di file di risorse (rc), che definiscono stringhe specifiche del driver, tra cui il nome del prodotto, la versione del file e il nome dell'azienda. Modificare queste stringhe in valori appropriati per il pacchetto driver.

Riepilogo- Cosa fare?

Prima di rilasciare un driver basato su un esempio WDK, sostituire qualsiasi informazione specifica di esempio nei file di origine, l'INF e qualsiasi altra risorsa usata per creare un driver personalizzato. Le modifiche necessarie variano da un esempio a un altro, ma in genere includono tutte le informazioni che identificano in modo univoco il driver di esempio o il relativo dispositivo. Di seguito sono riportate le modifiche che è necessario apportare:

  • Generare e usare GUID specifici del driver, se appropriato.

  • Aggiornare il nome del collegamento simbolico.

  • Aggiornare il nome dell'oggetto dispositivo o usare un nome generato automaticamente.

  • Usare i tag del pool che identificano il driver e non sono in conflitto con i tag noti.

  • Definire i codici IOCTL appropriati per il driver e il dispositivo.

  • Aggiornare i nomi di tutti i file copiati nella cartella di sistema.

  • Inserire l'ID dispositivo Plug and Play corretto, gli ID hardware e gli ID compatibili in INF.

  • Aggiornare il nome del servizio del driver in INF.

  • Modificare la descrizione del dispositivo.

  • Modificare le stringhe specifiche del driver nel file di risorse.

  • Rispettare le procedure consigliate per la sicurezza e l'affidabilità

Informazioni aggiuntive

Libri

Sviluppo di driver con Windows Driver Foundation, di Penny Orwick e Guy Smith

Argomenti WDK

Definizione ed esportazione di nuovi GUID

Controllo dell'accesso ai dispositivi nei driver KMDF

Sviluppo, test e distribuzione di driver

Creazione di driver reliable Kernel-Mode

Procedure consigliate per lo sviluppo di driver del team di Surface

Linee guida per la sicurezza dei driver

Scrivere il primo driver