Compartir a través de


Declaración de funciones mediante el uso de tipos de roles de función para controladores WDM

Nota:

A partir de la versión 2004 de Windows 10, el comprobador de controladores estáticos (SDV) ya no requiere anotaciones para identificar los tipos de roles de rutinas de distribución para los controladores WDM. Siga las instrucciones de la sección Inicializaciones básicas y avanzadas de esta página.

Para informar a SDV sobre los puntos de entrada del controlador al analizar un controlador WDM, debe declarar funciones mediante declaraciones de tipo de rol de función. Los tipos de rol de función se definen en Wdm.h. Cada punto de entrada de la rutina DriverEntry del controlador WDM debe declararse especificando el tipo de rol correspondiente. Los tipos de rol son definiciones de tipo predefinidas que corresponden a los puntos de entrada reconocidos de un controlador WDM.

Por ejemplo, para crear una declaración de tipo de rol de función para la rutina Unload de un controlador denominada CsampUnload, use la definición de tipo de rol predefinida typedef DRIVER_UNLOAD. La declaración de tipo de rol de función debe aparecer antes de la definición de la función.

DRIVER_UNLOAD CsampUnload;

La definición de la función CsampUnload permanece sin cambios:

VOID
CsampUnload(
    IN PDRIVER_OBJECT DriverObject
    )
{
    ...
}

SDV reconoce los tipos de puntos de entrada que se muestran en la tabla siguiente.

Tipo de rol de función WDM Rutina de WDM

DRIVER_INITIALIZE

DriverEntry

DRIVER_STARTIO

StartIO

DRIVER_UNLOAD

Descargar

DRIVER_ADD_DEVICE

AddDevice

Dispatch_type( tipo ) DRIVER_DISPATCH

Las rutinas de envío usadas por el controlador. Consulte Escritura de rutinas de envío.

IO_COMPLETION_ROUTINE

IoCompletion

La rutina ioCompletion se establece llamando a IoSetCompletionRoutine o IoSetCompletionRoutineEx y pasando el puntero de función a la rutina IoCompletion como segundo parámetro.

DRIVER_CANCEL

Cancelar

La rutina Cancel se establece llamando a IoSetCancelRoutine y pasando el puntero de función a la rutina de cancelación del IRP como segundo parámetro a la función.

IO_DPC_ROUTINE

DpcForIsr

La rutina DpcForIsr se registra llamando a IoInitializeDpcRequest y pasando el puntero de función a la rutina DpcForIsr como segundo parámetro. Para poner en cola el DPC, llame a IoQueueDpc desde la rutina ISR mediante el mismo objeto DPC.

KDEFERRED_ROUTINE

CustomDpc

La rutina CustomDpc se establece llamando a KeInitializeDpc y pasando el puntero de función a CustomDpc como segundo parámetro. Para poner en cola CustomDpc para el controlador, llame a KeInsertQueueDpc desde la rutina ISR mediante el mismo objeto DPC.

KSERVICE_ROUTINE

InterruptService

La rutina InterruptService (ISR) ofrece una interrupción del dispositivo y programa el procesamiento posterior a la interrupción de los datos recibidos, si es necesario.

REQUEST_POWER_COMPLETE

La rutina de devolución de llamada PowerCompletion completa el procesamiento de una IRP de energía. Si el controlador necesita realizar tareas adicionales después de que todos los demás controladores hayan completado el IRP, el controlador registra una rutina de devolución de llamada de PowerCompletion durante la llamada a la rutina PoRequestPowerIrp que asigna el IRP.

WORKER_THREAD_ROUTINE

Routine

Routine es la rutina de devolución de llamada que se especifica en el segundo parámetro para la función ExInitializeWorkItem.

Routine solo debe declararse de esta manera si el controlador llama a ExQueueWorkItem para agregar el elemento de trabajo a una cola del sistema.

Declaración de rutinas de envío de controladores

A partir de la versión 2004 de Windows 10, las declaraciones de tipo de rol de función para las rutinas de distribución se refinan con su categoría IRP automáticamente en función de la inicialización de la tabla DriverObject->MajorFunction en la rutina DriverEntry de un controlador WDM.

Un controlador Foo debe realizar declaraciones de rol mediante el estilo básico o avanzado de declaración para ser compatible con SDV.

Inicializaciones básicas y avanzadas

El estilo básico se puede ver en el ejemplo siguiente (tenga en cuenta que los nombres de rutina de distribución FooCreate y FooCleanup son solo ejemplos, se puede usar cualquier nombre adecuado):

DriverObject->MajorFunction[IRP_MJ_CREATE] = FooCreate; //Basic style
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCleanup;

Se puede adoptar un enfoque más avanzado para acortar la lista necesaria. Aunque se usa la misma rutina de envío para más de una categoría IRP, un controlador puede codificar dos inicializaciones de esta manera:

DriverObject->MajorFunction[IRP_MJ_CREATE] = 
DriverObject->MajorFunction[IRP_MJ_CLEANUP] = FooCreateCleanup; // Advanced style for a multi-role dispatch routine 

Para que un controlador pueda ejecutar SDV correctamente, el controlador solo debe usar el estilo básico o avanzado mostrado anteriormente. La comprobación de SDV en el controlador no funcionará según lo esperado si no se usa uno de estos dos métodos.

Parámetros de función y tipos de rol de función

Según sea necesario en el lenguaje de programación C, los tipos de parámetros que use en la definición de función deben coincidir con los tipos de parámetro del prototipo de función o, en este caso, el tipo de rol de función. SDV depende de las firmas de función para el análisis y omite las funciones cuyas firmas no coinciden.

Por ejemplo, debe declarar una rutina de IoCompletion mediante el tipo de rol de función IO_COMPLETION_ROUTINE:

IO_COMPLETION_ROUTINE myCompletionRoutine;

Al implementar myCompletionRoutine, los tipos de parámetro deben coincidir con los usados por IO_COMPLETION_ROUTINE, es decir, PDEVICE_OBJECT, PIRP y PVOID (consulte Rutina de IoCompletion para ver la sintaxis).

NTSTATUS
myCompletionRoutine(
 PDEVICE_OBJECT  DeviceObject,
 PIRP  Irp,
 PVOID  Context
 )
{
}

Ejecución del análisis de código para controladores para comprobar las declaraciones de función

Para ayudarle a determinar si el código fuente está preparado, ejecute Análisis de código para controladores. El análisis de código para controladores comprueba las declaraciones de tipo de rol de función y puede ayudar a identificar las declaraciones de función que podrían haberse perdido o advertirle cuando los parámetros de la definición de función no coinciden con los del tipo de rol de función.