您的位置:首页 > 其它

Windows 驱动开发 - 4

2015-05-26 12:35 211 查看
上篇《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.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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: