Windows驱动的设备PNP和电源设置

2019-07-13 22:51发布

                      加班,还是悠着点吧,毕竟,多加班没好处!                  今天,介绍下,关于PNP的操作,也就是即插即用。我们知道Windows支持PNP,但是,设备首先要声明,设备本身是支持的。
     上一章,我们讲了很多关于WdfDeviceInitXXXXXX的函数。那些都是在创建设备对象之前,调用的。设置属性,以参数的形式传给创建设备对象的函数。
      而我们的PNP的操作都是在设备对象创建后,声明的。这也合乎情理。还没有设备,怎么说支持。                 这边,我先把这些函数列举一下,在重点介绍下PNP的操作。                 VOID   WdfDeviceSetAlignmentRequirement(
                                          IN WDFDEVICE  Device,
                                          IN ULONG  AlignmentRequirement
                  );
                                 VOID   WdfDeviceSetBusInformationForChildren(
                                          IN WDFDEVICE  Device,
                                          IN PPNP_BUS_INFORMATION  BusInformation
                  );                  VOID     WdfDeviceSetCharacteristics(
                                          IN WDFDEVICE  Device,
                                          IN ULONG  DeviceCharacteristics
                  );                 VOID      WdfDeviceSetDeviceInterfaceState(
                                           IN WDFDEVICE  Device,
                                           IN CONST GUID*  InterfaceClassGUID,
                                           IN OPTIONAL PCUNICODE_STRING  ReferenceString,
                                           IN BOOLEAN  IsInterfaceEnabled
                   );                 VOID    WdfDeviceSetDeviceState(
                                          IN WDFDEVICE  Device,
                                          IN PWDF_DEVICE_STATE  DeviceState
                   );                   VOID   WdfDeviceSetFailed(
                                          IN WDFDEVICE  Device,
                                          IN WDF_DEVICE_FAILED_ACTION  FailedAction
                   );                   VOID    WdfDeviceSetSpecialFileSupport(
                                         IN WDFDEVICE  Device,
                                         IN WDF_SPECIAL_FILE_TYPE  FileType,
                                         IN BOOLEAN  FileTypeIsSupported
                   );                   VOID    WdfDeviceSetStaticStopRemove(
                                         IN WDFDEVICE  Device,
                                         IN BOOLEAN  Stoppable
                   );                   NTSTATUS    WdfDeviceStopIdle(
                                         IN WDFDEVICE  Device,
                                         IN BOOLEAN  WaitForD0
                   );                   NTSTATUS   WdfDeviceWdmDispatchPreprocessedIrp(
                                          WDFDEVICE  Device,
                                          PIRP  Irp
                     );                    PDEVICE_OBJECT   WdfDeviceWdmGetAttachedDevice(
                                          IN WDFDEVICE  Device
                     );                    PDEVICE_OBJECT    WdfDeviceWdmGetDeviceObject(
                                          IN WDFDEVICE hDevice
                     );                    PDEVICE_OBJECT    WdfDeviceWdmGetPhysicalDevice(
                                          IN WDFDEVICE  Device
                     );                     这里重点介绍如下两个函数:                    VOID   WdfDeviceSetPnpCapabilities(
                                     IN WDFDEVICE  Device,
                                     IN PWDF_DEVICE_PNP_CAPABILITIES  PnpCapabilities
                       );                     设置设备的PNP属性:我们来看WDF_DEVICE_PNP_CAPABILITIES:                      typedef struct _WDF_DEVICE_PNP_CAPABILITIES {
                                       ULONG Size;
                                      WDF_TRI_STATE LockSupported;
                                      WDF_TRI_STATE EjectSupported;
                                      WDF_TRI_STATE Removable;
                                      WDF_TRI_STATE DockDevice;
                                      WDF_TRI_STATE UniqueID;
                                      WDF_TRI_STATE SilentInstall;
                                      WDF_TRI_STATE SurpriseRemovalOK;
                                      WDF_TRI_STATE HardwareDisabled;
                                      WDF_TRI_STATE NoDisplayInUI;
                                      ULONG Address;
                                      ULONG UINumber;
                                    } WDF_DEVICE_PNP_CAPABILITIES, *PWDF_DEVICE_PNP_CAPABILITIES;                     typedef enum _WDF_TRI_STATE {
                                     WdfUseDefault,
                                    WdfFalse,
                                    WdfTrue
                                    } WDF_TRI_STATE, *PWDF_TRI_STATE;                     需要用宏来初始化:                    WDF_DEVICE_PNP_CAPABILITIES  pnpCaps;                   WDF_DEVICE_PNP_CAPABILITIES_INIT(&pnpCaps);
                                    pnpCaps.SurpriseRemovalOK = WdfTrue;                   WdfDeviceSetPnpCapabilities(
                            device,
                            &pnpCaps
                            );
                  相信做个WDM驱动,就应该知道这些属性代表什么,MSDN中有详细的说明。这里不解释了。                   还有一个函数:设置电源状态的WdfDeviceSetPowerCapabilities‘                   VOID       WdfDeviceSetPowerCapabilities(
                                  IN WDFDEVICE  Device,
                                  IN PWDF_DEVICE_POWER_CAPABILITIES  PowerCapabilities                                    );                   再看下电源能力的结构体:                   typedef struct _WDF_DEVICE_POWER_CAPABILITIES {
                                 ULONG Size;
                                 WDF_TRI_STATE DeviceD1;
                                 WDF_TRI_STATE DeviceD2;
                                 WDF_TRI_STATE WakeFromD0;
                                 WDF_TRI_STATE WakeFromD1;
                                 WDF_TRI_STATE WakeFromD2;
                                 WDF_TRI_STATE WakeFromD3;
                                DEVICE_POWER_STATE DeviceState[PowerSystemMaximum];
                                DEVICE_POWER_STATE DeviceWake;
                                SYSTEM_POWER_STATE SystemWake;
                                ULONG D1Latency;
                                ULONG D2Latency;
                               ULONG D3Latency;
                               DEVICE_POWER_STATE IdealDxStateForSx;
                               } WDF_DEVICE_POWER_CAPABILITIES, *PWDF_DEVICE_POWER_CAPABILITIES;
                                      typedef enum _DEVICE_POWER_STATE {
                              PowerDeviceUnspecified = 0,
                              PowerDeviceD0,
                              PowerDeviceD1,
                              PowerDeviceD2,
                              PowerDeviceD3,
                              PowerDeviceMaximum
                            } DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;                                        
        typedef enum _DEVICE_POWER_STATE {
             PowerDeviceUnspecified = 0,
             PowerDeviceD0,
             PowerDeviceD1,
             PowerDeviceD2,
             PowerDeviceD3,
             PowerDeviceMaximum
             } DEVICE_POWER_STATE, *PDEVICE_POWER_STATE;           
             我们来看用宏来初始化代码:                     WDF_DEVICE_POWER_CAPABILITIES powerCaps;                     WDF_DEVICE_POWER_CAPABILITIES_INIT(&powerCaps);
                    powerCaps.DeviceD1 = WdfTrue;
                    powerCaps.WakeFromD1 = WdfTrue;
                    powerCaps.DeviceWake = PowerDeviceD1;
                    powerCaps.DeviceState[PowerSystemWorking] = PowerDeviceD1;
                    powerCaps.DeviceState[PowerSystemSleeping1] = PowerDeviceD1;
                    powerCaps.DeviceState[PowerSystemSleeping2] = PowerDeviceD2;
                    powerCaps.DeviceState[PowerSystemSleeping3] = PowerDeviceD2;
                    powerCaps.DeviceState[PowerSystemHibernate] = PowerDeviceD3;
                    powerCaps.DeviceState[PowerSystemShutdown] = PowerDeviceD3;                     WdfDeviceSetPowerCapabilities(
                              device,
                              &powerCaps
                              );