上篇《Windows 驱动开发 - 3》我们使用了PnP,现在还差WMI。
WMI:Windows Management Interface
WMI 提供预装的类架构,允许使用脚本语言(VBS)、C#、VB .NET 或 C++ 编写的脚本或应用程序监视和配置计算机中的应用程序、系统或网络组件以及硬件。
一、WMI
虽然WDF帮你完成很多工作,但是你还必须自己触发事件和实例化回调函数。
在WDM中使用 wmilib.sys 静态注册很容易,但难以动态注册。
但是在WDF中这些很容易实现。
1. IRP_MJ_SYSTEM_CONTROL
WDF完全掌控IRP_MJ_SYSTEM_CONTROL。
IRP_MJ_SYSTEM_CONTROL:系统内部产生的控制信息,类似于内核调用DeviceControl函数
注意:使用DeviceControl系统最低要求为xp。
- BOOL WINAPI DeviceIoControl(
- _In_ HANDLE hDevice,
- _In_ DWORD dwIoControlCode,
- _In_opt_ LPVOID lpInBuffer,
- _In_ DWORD nInBufferSize,
- _Out_opt_ LPVOID lpOutBuffer,
- _In_ DWORD nOutBufferSize,
- _Out_opt_ LPDWORD lpBytesReturned,
- _Inout_opt_ LPOVERLAPPED lpOverlapped
- );
2. 模式
(1) 实例化已用设备
(2) 当需要的时候触发事件
(3) 统计报告
(4) 更新状态
(5) 注销后删除设备 (正常或意外删除)
3. ETW / 跟踪
支持内核模式 ETW / 跟踪
二、WDF和WMI
wdf使用WdfDeviceCreateDeviceInterface为WMI提供接口。
- NTSTATUS WdfDeviceCreateDeviceInterface(
- [in] WDFDEVICE Device,
- [in] const GUID *InterfaceClassGUID,
- [in, optional] PCUNICODE_STRING ReferenceString
- );
其中GUID,请参见“Using GUIDs in Drivers”
GUID声明(需要使用头文件initguid.h):
- DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe
- 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84);
- // {573E8C73-0CB4-4471-A1BF-FAB26C31D384}
- /*++
- Step2: This steps shows:
- 1) How to create a context with the WDFDEVICE object
- 2) How to initialize the USB device.
- 3) How to register an interface so that app can open
- an handle to the device.
- --*/
- #include "ntddk.h"
- #include "wdf.h"
- #include "prototypes.h"
- #pragma warning(disable:4200) // suppress nameless struct/union warning
- #pragma warning(disable:4201) // suppress nameless struct/union warning
- #pragma warning(disable:4214) // suppress bit field types other than int warning
- #include "usbdi.h"
- #pragma warning(default:4200)
- #pragma warning(default:4201)
- #pragma warning(default:4214)
- #include "wdfusb.h"
- #include "initguid.h"
- DEFINE_GUID(GUID_DEVINTERFACE_OSRUSBFX2, // Generated using guidgen.exe
- 0x573e8c73, 0xcb4, 0x4471, 0xa1, 0xbf, 0xfa, 0xb2, 0x6c, 0x31, 0xd3, 0x84);
- // {573E8C73-0CB4-4471-A1BF-FAB26C31D384}
- typedef struct _DEVICE_CONTEXT {
- WDFUSBDEVICE UsbDevice;
- WDFUSBINTERFACE UsbInterface;
- } DEVICE_CONTEXT, *PDEVICE_CONTEXT;
- WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext)
- NTSTATUS
- DriverEntry(
- IN PDRIVER_OBJECT DriverObject,
- IN PUNICODE_STRING RegistryPath
- )
- {
- WDF_DRIVER_CONFIG config;
- NTSTATUS status;
- KdPrint(("DriverEntry of Step2\n"));
- WDF_DRIVER_CONFIG_INIT(&config, EvtDeviceAdd);
- status = WdfDriverCreate(DriverObject,
- RegistryPath,
- WDF_NO_OBJECT_ATTRIBUTES,
- &config,
- WDF_NO_HANDLE
- );
- if (!NT_SUCCESS(status)) {
- KdPrint(("WdfDriverCreate failed 0x%x\n", status));
- }
- return status;
- }
- NTSTATUS
- EvtDeviceAdd(
- IN WDFDRIVER Driver,
- IN PWDFDEVICE_INIT DeviceInit
- )
- {
- WDF_OBJECT_ATTRIBUTES attributes;
- NTSTATUS status;
- WDFDEVICE device;
- PDEVICE_CONTEXT pDevContext;
- WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks;
-
- UNREFERENCED_PARAMETER(Driver);
- WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks);
- pnpPowerCallbacks.EvtDevicePrepareHardware = EvtDevicePrepareHardware;
- WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
- WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
- status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
- if (!NT_SUCCESS(status)) {
- KdPrint(("WdfDeviceCreate failed 0x%x\n", status));
- return status;
- }
- pDevContext = GetDeviceContext(device);
- status = WdfDeviceCreateDeviceInterface(device,
- (LPGUID) &GUID_DEVINTERFACE_OSRUSBFX2,
- NULL);// Reference String
- if (!NT_SUCCESS(status)) {
- KdPrint(("WdfDeviceCreateDeviceInterface failed 0x%x\n", status));
- return status;
- }
- return status;
- }
- NTSTATUS
- EvtDevicePrepareHardware(
- IN WDFDEVICE Device,
- IN WDFCMRESLIST ResourceList,
- IN WDFCMRESLIST ResourceListTranslated
- )
- {
- NTSTATUS status;
- PDEVICE_CONTEXT pDeviceContext;
- WDF_USB_DEVICE_SELECT_CONFIG_PARAMS configParams;
- UNREFERENCED_PARAMETER(ResourceList);
- UNREFERENCED_PARAMETER(ResourceListTranslated);
- pDeviceContext = GetDeviceContext(Device);
- //
- // Create the USB device if it is not already created.
- //
- if (pDeviceContext->UsbDevice == NULL) {
- status = WdfUsbTargetDeviceCreate(Device,
- WDF_NO_OBJECT_ATTRIBUTES,
- &pDeviceContext->UsbDevice);
- if (!NT_SUCCESS(status)) {
- KdPrint(("WdfUsbTargetDeviceCreate failed 0x%x\n", status));
- return status;
- }
- }
-
- WDF_USB_DEVICE_SELECT_CONFIG_PARAMS_INIT_SINGLE_INTERFACE(&configParams);
- status = WdfUsbTargetDeviceSelectConfig(pDeviceContext->UsbDevice,
- WDF_NO_OBJECT_ATTRIBUTES,
- &configParams);
- if(!NT_SUCCESS(status)) {
- KdPrint(("WdfUsbTargetDeviceSelectConfig failed 0x%x\n", status));
- return status;
- }
- pDeviceContext->UsbInterface =
- configParams.Types.SingleInterface.ConfiguredUsbInterface;
- return status;
- }