Declarar funciones mediante tipos de roles de función para controladores WDM

Nota:

A partir Windows 10 versión 2004, Static Driver Verifier (SDV) ya no requiere anotaciones para identificar los tipos de rol de las rutinas de envío 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 roles 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 en 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 predefinida DRIVER_UNLOAD de tipo de rol. La declaración de tipo de rol de función debe aparecer antes de la definición de 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 WDM

DRIVER_INITIALIZE

DriverEntry

DRIVER_STARTIO

StartIO

DRIVER_UNLOAD

Descargar

DRIVER_ADD_DEVICE

AddDevice

Dispatch_type(tipo) DRIVER_DISPATCH

Rutinas de envío utilizadas por el controlador. Consulte Escribir rutinas de distribución.

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 de 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 de ISR mediante el mismo objeto DPC.

KSERVICE_ROUTINE

InterruptService

La rutina InterruptService (ISR) proporciona servicios a 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 de PowerCompletion completa el procesamiento de un 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

Rutina

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

La rutina solo se debe declarar de esta manera si el controlador llama a ExQueueWorkItem para agregar el elemento de trabajo a una cola del sistema.

Declarar rutinas de distribución de controladores

A partir de Windows 10 versión 2004, las declaraciones de tipo de rol de función para las rutinas de envío se refinan automáticamente con su categoría IRP 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 roles mediante el uso del 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 envío 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 de 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 verficiación de SDV en el controlador no funcionará según lo previsto si no se usa uno de estos dos métodos.

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

Como es necesario en el lenguaje de programación C, los tipos de parámetro que se usan en la definición de función deben coincidir con los tipos de parámetro del prototipo de función o, en este caso, con 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 IO_COMPLETION_ROUTINE de rol de función:

IO_COMPLETION_ROUTINE myCompletionRoutine;

Al implementar myCompletionRoutine, los tipos de parámetro deben coincidir con los que usa IO_COMPLETION_ROUTINE, es decir, PDEVICE_OBJECT, PIRP y PVOID (consulte La rutina de IoCompletion para obtener sintaxis).

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

Ejecutar Code Analysis para que los controladores comprueben las declaraciones de función

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