上一篇《Windows 驱动开发 - 1》我们已经实现一个WDF“骨架”。但是,他什么也没有干。。。
WDF对象分为3类:方法、事件和属性。
在上节中WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd);
VOID WDF_DRIVER_CONFIG_INIT( _Out_ PWDF_DRIVER_CONFIG Config, _In_opt_ PFN_WDF_DRIVER_DEVICE_ADD );初始化 WDF_DRIVER_CONFIG,并且回调EvtDriverDeviceAdd事件。
typedef struct _WDF_DRIVER_CONFIG { ULONG Size; PFN_WDF_DRIVER_DEVICE_ADD EvtDriverDeviceAdd; PFN_WDF_DRIVER_UNLOAD EvtDriverUnload; ULONG DriverInitFlags; ULONG DriverPoolTag; } WDF_DRIVER_CONFIG, *PWDF_DRIVER_CONFIG;
接下来我们需要通知计算机准备硬件!
我们知道大部分IRP都是通过PnP/电源管理、I/O和WMI来实现功能。
此结构包括PnP/Power事件,详细参见"WDF_PNPPOWER_EVENT_CALLBACKS structure"。
typedef struct _WDF_PNPPOWER_EVENT_CALLBACKS { ULONG Size; PFN_WDF_DEVICE_D0_ENTRY EvtDeviceD0Entry; PFN_WDF_DEVICE_D0_ENTRY_POST_INTERRUPTS_ENABLED EvtDeviceD0EntryPostInterruptsEnabled; PFN_WDF_DEVICE_D0_EXIT EvtDeviceD0Exit; PFN_WDF_DEVICE_D0_EXIT_PRE_INTERRUPTS_DISABLED EvtDeviceD0ExitPreInterruptsDisabled; PFN_WDF_DEVICE_PREPARE_HARDWARE EvtDevicePrepareHardware; PFN_WDF_DEVICE_RELEASE_HARDWARE EvtDeviceReleaseHardware; PFN_WDF_DEVICE_SELF_MANAGED_IO_CLEANUP EvtDeviceSelfManagedIoCleanup; PFN_WDF_DEVICE_SELF_MANAGED_IO_FLUSH EvtDeviceSelfManagedIoFlush; PFN_WDF_DEVICE_SELF_MANAGED_IO_INIT EvtDeviceSelfManagedIoInit; PFN_WDF_DEVICE_SELF_MANAGED_IO_SUSPEND EvtDeviceSelfManagedIoSuspend; PFN_WDF_DEVICE_SELF_MANAGED_IO_RESTART EvtDeviceSelfManagedIoRestart; PFN_WDF_DEVICE_SURPRISE_REMOVAL EvtDeviceSurpriseRemoval; PFN_WDF_DEVICE_QUERY_REMOVE EvtDeviceQueryRemove; PFN_WDF_DEVICE_QUERY_STOP EvtDeviceQueryStop; PFN_WDF_DEVICE_USAGE_NOTIFICATION EvtDeviceUsageNotification; PFN_WDF_DEVICE_RELATIONS_QUERY EvtDeviceRelationsQuery; PFN_WDF_DEVICE_USAGE_NOTIFICATION_EX EvtDeviceUsageNotificationEx; } WDF_PNPPOWER_EVENT_CALLBACKS, *PWDF_PNPPOWER_EVENT_CALLBACKS;
声明结构变量:
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
使用WDF_PNPPOWER_EVENT_CALLBACKS_INIT方法初始WDF_PNPPOWER_EVENT_CALLBACKS变量。
VOID WDF_PNPPOWER_EVENT_CALLBACKS_INIT( _Out_ PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks );
指定回调函数名称;例如,我们使能准备硬件:
pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
因为DeviceInit是一个“占位符”,需要赋予他数值才可以。所以我们使用方法WdfDeviceInitSetPnpPowerEventCallbacks:
VOID WdfDeviceInitSetPnpPowerEventCallbacks( [in] PWDFDEVICE_INIT DeviceInit, [in] PWDF_PNPPOWER_EVENT_CALLBACKS PnpPowerEventCallbacks );
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
参考文献:
1. Architecture of the Kernel-Mode Driver Framework -Microsoft
2. How to Develop a KMDF Driver [517 KB] - Microsoft
3. How to Port a WDM Driver to KMDF [749 KB] - Microsoft