基本框架:
#include<ntddk.h>
#include<wdf.h>
#define IOCTL_TEST CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ALL_ACCESS)
#define DEVICE_NAME L"\\Device\\WDF_DeviceName"
#define SYMBOL_NAME L"\\??\\WDF_DeviceSymbolLink"
VOID EvDriverUnLoad(IN WDFDRIVER driver)
{
KdPrint(("驱动卸载"));
}
NTSTATUS DriverEntry(IN PDRIVER_OBJECT driverObject,IN PUNICODE_STRING registryPath)
{
NTSTATUS status;
WDF_DRIVER_CONFIG config;
WDFDRIVER driver;
KdPrint(("驱动加载\n"));
//初始化WDF驱动配置
WDF_DRIVER_CONFIG_INIT(&config, NULL);
config.DriverInitFlags = WdfDriverInitNonPnpDriver;
config.EvtDriverUnload = EvDriverUnLoad;
//创建WDF驱动
status = WdfDriverCreate(driverObject, registryPath, WDF_NO_OBJECT_ATTRIBUTES,&config,&driver);//3.驱动属性,4.驱动配置,5.用于保存驱动句柄
if (!NT_SUCCESS(status))
{
KdPrint(("驱动框架创建失败!\n"));
return STATUS_UNSUCCESSFUL;
}
status = CreateIoDevice(driver);
return status;
}
创建IO设备:
NTSTATUS CreateIoDevice(WDFDRIVER driver)
{
NTSTATUS status;
WDFDEVICE device;
PWDFDEVICE_INIT deviceInit;
UNICODE_STRING deviceName = RTL_CONSTANT_STRING(DEVICE_NAME);
UNICODE_STRING symbolLinkicName = RTL_CONSTANT_STRING(SYMBOL_NAME);
WDF_FILEOBJECT_CONFIG fileConfie;
WDF_IO_QUEUE_CONFIG ioConfig;
WDFQUEUE queue;
//附加依赖wdmsec.lib,设置设备访问权限
deviceInit = WdfControlDeviceInitAllocate(driver, &SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R);//2.安全描述符定义语言 SYS_ALL:系统有所有权限 ADM_RWX:管理员读写执行权限 WORLD_RW:所有用户读写权限 RES_R:受限用户只读权限
if (NULL == deviceInit)
{
status = STATUS_INSUFFICIENT_RESOURCES;
}
status = WdfDeviceInitAssignName(deviceInit, &deviceName);
if (!NT_SUCCESS(status))
{
KdPrint(("设备名分配失败%x\n", status));
}
//指定事件处理回调函数
WDF_FILEOBJECT_CONFIG_INIT(&fileConfie, EvDeviceFileCreate, EvFileClose, EvFileCleanup);
//初始化文件配置
WdfDeviceInitSetFileObjectConfig(deviceInit, &fileConfie, WDF_NO_OBJECT_ATTRIBUTES);
//初始化IO队列
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioConfig, WdfIoQueueDispatchSequential);
//指定设备控制函数
ioConfig.EvtIoDeviceControl = EvtIoDeviceControl;
status = WdfDeviceCreate(&deviceInit, WDF_NO_OBJECT_ATTRIBUTES, &device);
if (!NT_SUCCESS(status))
{
KdPrint(("设备创建失败%x", status));
return status;
}
//创建IO队列
status = WdfIoQueueCreate(device, &ioConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue);
if (!NT_SUCCESS(status))
{
KdPrint(("IO队列创建失败%x", status));
return status;
}
status = WdfDeviceCreateSymbolicLink(device, &symbolLinkicName);
if (!NT_SUCCESS(status))
{
KdPrint(("符号链接创建失败%x", status));
return status;
}
//完成设备创建
WdfControlFinishInitializing(device);
return STATUS_SUCCESS;
}
基本IO控制:
VOID EvDeviceFileCreate(IN WDFDEVICE device,IN WDFREQUEST request,IN WDFFILEOBJECT fileObject)
{
WdfRequestComplete(request, STATUS_SUCCESS);
}
VOID EvFileClose(IN WDFFILEOBJECT fileObject)
{
}
VOID EvFileCleanup(IN WDFFILEOBJECT fileObject)
{
}
VOID EvtIoDeviceControl(IN WDFQUEUE queue,IN WDFREQUEST request,IN size_t outputBufferLength,IN size_t inputBufferLength,IN ULONG ioControlCode)
{
PVOID buffer=NULL;
size_t length=0;
NTSTATUS status;
switch (ioControlCode)
{
case IOCTL_TEST:
{
if (inputBufferLength)
{
//获取输入缓冲区
status=WdfRequestRetrieveInputBuffer(request, 4/*获取的长度*/, &buffer, &length);
if (NT_SUCCESS(status))
{
UINT32 data = *(PUINT32)buffer;
KdPrint(("输入的数据:%d",data));
//获取输出缓冲区
status=WdfRequestRetrieveOutputBuffer(request, 4/*获取的长度*/, &buffer, &length);
if (NT_SUCCESS(status))
{
*(PUINT32)buffer = data*2;
WdfRequestCompleteWithInformation(request, STATUS_SUCCESS, 4);
return;
}
}
}
break;
}
default:
break;
}
WdfRequestCompleteWithInformation(request, STATUS_INVALID_PARAMETER, 0);
}
ring3层使用:
#include<windows.h>
#include<winioctl.h>
//CTL_CODE(文件类型,0x800,访问方式,权限)
#define IOCTL_TEST CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ALL_ACCESS)
void CtestDlg::OnBnClickedButtonLoad()
{
// TODO: 在此添加控件通知处理程序代码
HANDLE deviceHandle = CreateFile(
TEXT("\\??\\WDF_DeviceSymbolLink"),
GENERIC_READ | GENERIC_WRITE | GENERIC_EXECUTE,
FILE_SHARE_READ | FILE_SHARE_WRITE,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL
);
if (deviceHandle == INVALID_HANDLE_VALUE)
{
return;
}
DWORD input,output,dwret;
input=GetDlgItemInt(IDC_EDIT1);
DeviceIoControl(deviceHandle, IOCTL_TEST,&input,sizeof(input),&output,sizeof(output),&dwret,NULL);
SetDlgItemInt(IDC_EDIT1, output);
CloseHandle(deviceHandle);
}