Windows 驱动开发 - 2

    上一篇《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来实现功能。

Windows 驱动开发 - 2_第1张图片


一、WDF_PNPPOWER_EVENT_CALLBACKS结构

    此结构包括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;



1. 初始化

    使用WDF_PNPPOWER_EVENT_CALLBACKS_INIT方法初始WDF_PNPPOWER_EVENT_CALLBACKS变量。

VOID WDF_PNPPOWER_EVENT_CALLBACKS_INIT(
  _Out_ PWDF_PNPPOWER_EVENT_CALLBACKS Callbacks
);

2. 使能功能

    指定回调函数名称;例如,我们使能准备硬件:

pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;


3. 赋值Device Init

     因为DeviceInit是一个“占位符”,需要赋予他数值才可以。所以我们使用方法WdfDeviceInitSetPnpPowerEventCallbacks:

VOID WdfDeviceInitSetPnpPowerEventCallbacks(
  [in] PWDFDEVICE_INIT               DeviceInit,
  [in] PWDF_PNPPOWER_EVENT_CALLBACKS PnpPowerEventCallbacks
);

    把处理过的pnpPowerCallbacks结构变量地址传递给DeviceInit指针。

WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);

    现在经过PnP的处理,我们的驱动可以工作了:)


参考文献:

    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



你可能感兴趣的:(Windows 驱动开发 - 2)