Del código de ejemplo al controlador de producción: qué cambiar en los ejemplos

En este tema se describen los cambios importantes que deben realizarse en los controladores de ejemplo de WDK antes de liberar controladores de dispositivo basados en el código de ejemplo.

Además de los cambios descritos aquí, todos los controladores deben usar los procedimientos recomendados descritos en Crear controladores de Kernel-Mode confiables y en los procedimientos recomendados de desarrollo de controladores de Surface Team Driver. Todos los conductores también deben cumplir las directrices proporcionadas en Guía de seguridad del conductor.

Ejemplos de controladores de WDK: identificadores únicos

El Kit de controladores de Windows (WDK) contiene una amplia variedad de controladores de ejemplo que muestran técnicas útiles para el desarrollo de controladores. Puede usar estos ejemplos como base para sus propios controladores, pero antes de liberar el controlador, debe cambiar ciertos aspectos específicos del dispositivo del ejemplo , más allá del código operativo obvio, para aplicar de forma única a su propio dispositivo y controlador. Los escritores de controladores a veces pasan por alto estos detalles.

Los elementos exactos que debe cambiar varían de una muestra a la siguiente, pero en general identifican un dispositivo, una interfaz o un controlador específicos. Por ejemplo, si el controlador de ejemplo contiene cualquiera de los siguientes elementos, debe cambiarlos para que se apliquen al controlador y al dispositivo:

  • Identificadores únicos globales (GUID)

  • Nombres simbólicos de vínculos

  • Nombre del objeto de dispositivo

  • Etiquetas de grupo

  • Definiciones de código de control de E/S (IOCTL)

  • Nombres de los archivos que se copian en la carpeta del sistema

  • Plug and Play id. de dispositivo, id. de hardware e identificadores compatibles

  • Nombre del servicio de controlador

  • Descripción del dispositivo

  • Archivo de recursos

Olvidarse de realizar estos cambios puede provocar errores en la instalación, conflictos con otros dispositivos y controladores en el sistema y dificultades en la depuración, junto con otros errores.

Por ejemplo, si recibe un error como ...\toastDrv\kmdf\toastmon\wdftoastmon.inx(18-18): error 1284: Class "Sample" is reserved for use by Microsoft. este indica que el nombre "Sample" debe cambiarse a un nombre único para el controlador de ejemplo.

GUID

Los controladores usan GUID para identificar clases de configuración de dispositivos, clases de interfaz de dispositivo, eventos PnP personalizados, eventos de Instrumental de administración de Windows (WMI) personalizados y proveedores de seguimiento de PreProcesador de Windows (WPP). Microsoft define algunos GUID y otros los definen los proveedores de dispositivos y controladores.

Los GUID de clase de configuración de dispositivos, los GUID de clase de interfaz de dispositivo y los GUID de WMI para dispositivos comunes y datos WMI se definen en el WDK o en archivos de encabezado públicos para que los use cualquier controlador. No debe cambiar estos GUID.

Por ejemplo, si va a implementar un mouse, seguirá usando GUID_DEVINTERFACE_MOUSE, que se define en el archivo de encabezado WDK Ntddmou.h, como clase de interfaz de dispositivo. Sin embargo, si define una nueva clase de configuración de dispositivo, debe generar un nuevo GUID de clase de configuración de dispositivo y el nombre de clase de configuración, y posiblemente también un nuevo GUID de clase de interfaz de dispositivo. El GUID de la clase de instalación y el GUID de la clase de interfaz de dispositivo deben ser valores únicos; no pueden compartir un GUID.

Para la mayoría de los controladores basados en muestras, solo debe cambiar los GUID definidos en el encabezado local o el archivo de origen de un ejemplo y, por tanto, son específicos del ejemplo. Estos GUID pueden incluir lo siguiente:

  • Eventos PnP personalizados

  • Eventos WMI personalizados

  • Clases de interfaz de dispositivo para dispositivos nuevos o personalizados

  • Proveedores de seguimiento de WPP

El uso de un GUID definido para otro controlador puede provocar conflictos si ambos controladores se cargan en el mismo sistema. Por ejemplo, si dos controladores diferentes usan el mismo GUID para registrar una interfaz de dispositivo, los clientes que intentan abrir la interfaz del dispositivo podrían abrir accidentalmente el dispositivo incorrecto.

El siguiente extracto procede del archivo Driver.h que se incluye en todos los ejemplos del controlador de toaster. Define el GUID de la interfaz del dispositivo para dispositivos toaster:

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

Si usa este archivo en su propio controlador, asegúrese de reemplazar el GUID de ejemplo (mostrado anteriormente como texto en negrita) por el GUID de interfaz para su propio dispositivo. Para crear un GUID, use la herramienta Crear GUID en Microsoft Visual Studio o Guidgen.exe, ambos incluidos en el Kit de desarrollo de software (SDK) de Microsoft Windows. A continuación, puede asociar el GUID a una constante simbólica en el archivo de encabezado del controlador, como se muestra en el ejemplo.

Es posible que también sea necesario crear nuevos GUID para los eventos WMI del controlador. Los ejemplos del controlador de tostadora definen el siguiente GUID para la notificación de la llegada del dispositivo del tostador:


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

Debe crear un nuevo GUID para cada evento WMI del controlador.

Si el controlador de ejemplo usa el seguimiento de software de WPP, genere un nuevo GUID del proveedor de seguimiento para los controladores que base en el ejemplo. Por ejemplo, el archivo de encabezado Trace.h del ejemplo de Osrusbfx2 en %WinDDK%\Src\Kmdf\Osrusbfx2\Final define un GUID de control de la siguiente manera:

#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 */ \
       )

En su propio controlador, reemplazaría el texto en negrita por un nombre específico del controlador y el GUID que creó.

Si el ejemplo define un nombre de vínculo simbólico, reemplace el nombre del ejemplo por un nombre que se aplique a su propio controlador. Sin embargo, no cambie los nombres de vínculo conocidos, como \DosDevices\COM1. En general, si el nombre del vínculo es bastante similar al nombre de ejemplo (como \DosDevices\CancelSamp), debe cambiarlo.

El uso del mismo vínculo simbólico que otro controlador tiene el mismo efecto que el uso del GUID de interfaz de dispositivo incorrecto, ya que las interfaces de dispositivo son esencialmente vínculos simbólicos.

El controlador del filtro del sistema KMDF en %WinDDK\Src\Kmdf\Toaster\Filter crea un nombre de vínculo simbólico que usa una cadena definida como se indica a continuación en el archivo de encabezado Filter.h:

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

Cambie la cadena en negrita para describir con más precisión su propio controlador.

Nombre del objeto de dispositivo

Si el ejemplo crea un nombre para el objeto de dispositivo, debe cambiar el nombre al adaptar el código de ejemplo.

El controlador del filtro del sistema KMDF nombra su objeto de dispositivo en el archivo de encabezado Filter.h de la siguiente manera:

#define NTDEVICE_NAME_STRING      L\\Device\\ToasterFilter

Al igual que con el nombre simbólico del vínculo, debe cambiar la cadena para describir el controlador.

Recuerde que los objetos de dispositivo con nombre pueden representar un riesgo de seguridad. Los objetos de dispositivo físico (PPO) deben tener nombres y la mayoría de estos nombres se generan por el sistema en lugar de asignarlos explícitamente a un controlador. Solo se debe asignar un nombre a otros objetos de dispositivo si representan objetos de dispositivo de control, que se usan para la comunicación de banda lateral entre una aplicación y un controlador. Tanto el marco de controlador en modo kernel (KMDF) como el modelo de controlador de Windows (WDM) permiten que Windows genere el nombre. Este enfoque garantiza que el nombre del objeto de dispositivo sea único y que los usuarios sin privilegios no puedan acceder a él. Para obtener más información, consulte Controlar el acceso al espacio de nombres del dispositivo y controlar el acceso a dispositivos en los controladores de KMDF.

Etiquetas de grupo

Una etiqueta de grupo es un literal de uno a cuatro caracteres que identifica una asignación de memoria específica y puede ayudar en la depuración.

Muchos de los controladores de ejemplo definen una etiqueta de grupo en el archivo de encabezado del controlador, como en la siguiente línea de Toaster.h:

#define TOASTER_POOL_TAG (ULONG) 'saoT'

El controlador define la etiqueta hacia atrás porque el depurador la muestra en orden inverso. Por lo tanto, esta etiqueta aparece como Toas en la salida del depurador. En lugar de usar la etiqueta que define el ejemplo, cambie la cadena para identificar de forma única su propio código.

El archivo Pooltag.txt enumera las etiquetas de grupo usadas por los componentes y controladores en modo kernel que se proporcionan con Windows. Pooltag.txt se instala con el WDK en %winddk%\Tools\Other<i>platform\Poolmon, donde platform es amd64, i386 o ia64. No use ninguna de las etiquetas que aparecen en esta lista.

Definiciones de IOCTL

Cambie los códigos de control de E/S definidos por ejemplo para usar un nombre, un tipo de dispositivo, un código de función, un tipo de transferencia y un tipo de acceso adecuados para el dispositivo y el controlador.

Por ejemplo, el ejemplo Osrusbfx2 incluye la siguiente definición para IOCTL_OSRUSBFX2_READ_SWITCHES:

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

Un controlador basado en ejemplo para un dispositivo diferente requeriría modificaciones en esta definición.

Nombres de archivo

En INF o INX, cambie los nombres del controlador, el co-instalador proporcionado por el proveedor y cualquier otro archivo que el procedimiento de instalación copie en la carpeta del sistema. Estos nombres de archivo suelen aparecer en las secciones [SourceDisksFiles] y [ClassInstall32] de las entradas INF y copyFiles .

El ejemplo siguiente procede del archivo INX para el ejemplo de tostadora destacada de KMDF, que está disponible en %WinDDK%\src\kmdf\Toaster\Func\Featured. Los nombres de archivo que se deben cambiar se muestran en negrita:

[ClassInstall32]
Addreg=ToasterClassReg
CopyFiles=ToasterClassInstallerCopyFileshighlight

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

[ToasterClassInstallerCopyFiles]
tostrcls.dll									    
...

Para adaptar esta parte del archivo para un controlador diferente, cambiaría "tostrcls.dll" al nombre de archivo del instalador de clase y cambiaría la cadena "ToasterClassInstaller" para describir su propio instalador. Estos cambios garantizan que el procedimiento de instalación copie el archivo coinstaladores correcto y que la clave del Registro registre el nombre de archivo correcto.

No cambie el nombre de los co-instaladores que se proporcionan en el WDK o con Windows, como kmdf, UMDF y co-instaladores de WinUSB.

Se requieren cambios adicionales más adelante en la sección Instalación de dispositivos del archivo, como se muestra en este ejemplo:

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

[Toaster_Device.NT.Copy]
wdffeatured.sys

En este ejemplo, cambiaría el nombre de archivo en negrita por el nombre del archivo de controlador generado.

Cuando el programa de instalación copia los archivos de catálogo de controladores y INF, los cambia de nombre, por lo que no es estrictamente necesario cambiar sus nombres en el paquete de controladores. Sin embargo, generalmente es una buena idea asegurarse de que los nombres de archivo INF y de catálogo son similares al nombre de archivo del controlador.

Id. de dispositivo PnP, id. de hardware e identificadores compatibles

El programa de instalación usa el identificador de dispositivo junto con los identificadores de hardware y los identificadores compatibles para seleccionar el INF que se va a usar para la instalación del dispositivo.

El identificador de dispositivo es una cadena definida por el proveedor que identifica de forma única un dispositivo específico. Cada dispositivo tiene exactamente un identificador de dispositivo. El controlador de bus informa del identificador de dispositivo durante la enumeración y el programa de instalación lo usa para que coincida con el dispositivo con el archivo INF correcto. El identificador de dispositivo se define en la sección [Fabricante] del INF.

En el ejemplo siguiente se muestra el identificador del dispositivo OSR USB Fx2, tal como se especifica en el archivo 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

Para adaptar esta directiva INF para su propio controlador, reemplace el identificador de dispositivo que se muestra en negrita por el identificador de dispositivo para su propio dispositivo. También debe cambiar el nombre del fabricante por el nombre de su empresa.

El identificador de hardware y el identificador compatible son identificadores menos específicos que el programa de instalación usa si no puede coincidir el identificador de dispositivo con un INF. Si inf puede admitir otros dispositivos, debe cambiar estos valores además del identificador de dispositivo. En el ejemplo siguiente del controlador de tostadora destacado de KMDF se muestra un identificador de 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

Para adaptar esta directiva INF para su propio controlador, reemplace el identificador de hardware por el identificador de dispositivo del controlador y cambie "MsToaster" a una cadena más descriptiva.

Nombre del servicio de controlador

Actualice el nombre del servicio en la directiva AddService de INF a un valor adecuado para el controlador. Si el nombre del servicio de controlador entra en conflicto con el de otro controlador del sistema, el controlador no se instalará ni cargará.

El controlador de tostadora destacado de KMDF denomina su servicio de la siguiente manera:


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

El nombre del servicio es la primera entrada de la directiva AddService . Para adaptar el INF de la tostadora destacada, cambiaría la cadena en negrita a una cadena más adecuada para el controlador. En el ejemplo, la entrada wdffeatured_Service_Inst simplemente hace referencia a una sección definida por INF, por lo que cambiarla no es crítica.

Device Description (Descripción del dispositivo)

La descripción del dispositivo consta de varias cadenas que normalmente se definen en la sección [Cadenas] del INF y se usan en varios lugares de todo el INF. Por ejemplo, el ejemplo de tostadora destacada de KMDF define las siguientes cadenas en el archivo 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"

Para modificar este archivo para instalar su propio controlador, debe cambiar las cadenas en negrita para reflejar información sobre su empresa, dispositivo y controlador.

Si el nombre de la empresa también aparece en una sección [Fabricante] del INF, también debe cambiar el nombre.

Archivo de recursos

Los controladores y otros componentes, como los co-instaladores específicos de ejemplo, también tienen archivos de recursos (.rc), que definen cadenas específicas del controlador, incluido el nombre del producto, la versión del archivo y el nombre de la empresa. Cambie estas cadenas a los valores adecuados para el paquete de controladores.

Resumen: ¿Qué debe hacer?

Antes de liberar un controlador basado en un ejemplo de WDK, reemplace cualquier información específica de ejemplo en los archivos de origen, el INF y cualquier otro recurso que usó para crear su propio controlador. Los cambios necesarios varían de una muestra a otra, pero generalmente incluyen cualquier información que identifique de forma única el controlador de ejemplo o su dispositivo. Los siguientes son típicos de los cambios que debe realizar:

  • Genere y use GUID específicos del controlador cuando corresponda.

  • Actualice el nombre del vínculo simbólico.

  • Actualice el nombre del objeto de dispositivo o use un nombre generado automáticamente.

  • Use etiquetas de grupo que identifiquen el controlador y no entren en conflicto con ninguna etiqueta conocida.

  • Defina los códigos IOCTL adecuados para el controlador y el dispositivo.

  • Actualice los nombres de los archivos que se copian en la carpeta del sistema.

  • Inserte el identificador de dispositivo, los identificadores de hardware y los identificadores compatibles correctos Plug and Play en inf.

  • Actualice el nombre del servicio del controlador en inf.

  • Cambie la descripción del dispositivo.

  • Modifique las cadenas específicas del controlador en el archivo de recursos.

  • Cumplir los procedimientos recomendados para la seguridad y la confiabilidad

Información adicional

Libros

Desarrollo de controladores con Windows Driver Foundation, de Penny Orwick y Guy Smith

Temas de WDK

Definición y exportación de nuevos GUID

Controlar el acceso a dispositivos en controladores KMDF

Desarrollo, pruebas e implementación de controladores

Creación de controladores de reliable Kernel-Mode

Procedimientos recomendados de desarrollo de controladores de Surface Team

Guía de seguridad del controlador

Escribir el primer controlador