上篇《Windows 驱动开发 - 3》我们使用了PnP,现在还差WMI。
WMI:Windows Management Interface
WMI 提供预装的类架构,允许使用脚本语言(VBS)、C#、VB .NET 或 C++ 编写的脚本或应用程序监视和配置计算机中的应用程序、系统或网络组件以及硬件。
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 );
(1) 实例化已用设备
(2) 当需要的时候触发事件
(3) 统计报告
(4) 更新状态
(5) 注销后删除设备 (正常或意外删除)
支持内核模式 ETW / 跟踪
wdf使用WdfDeviceCreateDeviceInterface为WMI提供接口。
NTSTATUS WdfDeviceCreateDeviceInterface( [in] WDFDEVICE Device, [in] const GUID *InterfaceClassGUID, [in, optional] PCUNICODE_STRING ReferenceString );
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.c
/*++ 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; }