WDF驱动框架,简单IO(METHOD_BUFFERED)

基本框架:

#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);

}
发布了23 篇原创文章 · 获赞 51 · 访问量 1万+

猜你喜欢

转载自blog.csdn.net/weixin_44286745/article/details/104781226
wdf