WDF驱动开发(1)- 一个简单的WDF驱动(non-pnp)

最近因为工作关系,接触了一下WDF驱动开发。

WDF驱动其实是微软公司提供的一套驱动开发的框架。有了这个框架之后,开发驱动会简单一些。WDF本身是从WDM基础上封装而成的。WDF里面封装了很多对象,如WDFDRIVER等。如果要学习使用WDF来开发驱动,个人感觉还是需要WDM的一些基础,不然很多东西挺难理解的。

写了一个简单的WDF驱动(非pnp),基本步骤如下:

创建framework 驱动对象

几乎任何一个WDF驱动一开始就要创建一个framework的驱动对象,这个对象是所有其他对象的parent对象。

 

        //初始化WDF_DRIVER_CONFIG
	WDF_DRIVER_CONFIG_INIT(
							   &cfg,
							   NULL //不提供adddevice函数							);

	cfg.DriverInitFlags = WdfDriverInitNonPnpDriver;  //非pnp驱动
	cfg.DriverPoolTag   = (ULONG)'PEPU';  
	cfg.EvtDriverUnload = EvtDriverUnload;  //卸载函数

	//
	//创建一个framework的驱动对象。
	status = WdfDriverCreate(DriverObject,RegistryPath,WDF_NO_OBJECT_ATTRIBUTES,&cfg,&drv);
	if(!NT_SUCCESS(status))
	{
		goto DriverEntry_Complete;
	}

	KdPrint(("Create wdf driver object successfully\n"));

这样,一个framework的驱动对象就创建好了。

创建一个设备(control device)

1. 要创建一个control device,首先得先分配一块内存

	//分配一块内存
	device_init = WdfControlDeviceInitAllocate(drv,&SDDL_DEVOBJ_SYS_ALL_ADM_RWX_WORLD_RW_RES_R);  
	if( device_init == NULL )  
	{    
		status = STATUS_INSUFFICIENT_RESOURCES;    
		goto DriverEntry_Complete;  
	}

WdfControlDeviceInitAllocate函数分配了一块内存给结构WDFDEVICE_INIT,这个结构在创建control device的时候会被用到。更多细节看MSDN:http://msdn.microsoft.com/en-us/library/windows/hardware/ff545841(v=vs.85).aspx

2. 然后给这个设备绑定一个设备名字,注意这个设备名字只能被内核模式下的代码所看到,比如其他的内核驱动,用户模式代码是看不到的。

就好象是WDM里面的IoCreateDevice函数的第三个参数。

	//设备名字,如: L"\\Device\\MyWDF_Device",只能被其他的内核驱动看到。
	RtlInitUnicodeString(&ustring, MYWDF_KDEVICE);  

	//将这个设备名字存入DEVICE_INIT结构中
	status = WdfDeviceInitAssignName(device_init,&ustring);

	if(!NT_SUCCESS(status))
	{
		goto DriverEntry_Complete;
	}

	KdPrint((
  • 3
    点赞
  • 53
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,下面是一个简单WDF驱动程序代码,可以访问PCIe配置空间: ```cpp #include <ntddk.h> #include <wdf.h> DRIVER_INITIALIZE DriverEntry; EVT_WDF_DRIVER_UNLOAD OnDriverUnload; EVT_WDF_DRIVER_DEVICE_ADD OnDeviceAdd; EVT_WDF_DEVICE_CONTEXT_CLEANUP OnDeviceCleanup; typedef struct _DEVICE_CONTEXT { WDFDEVICE Device; } DEVICE_CONTEXT, *PDEVICE_CONTEXT; WDF_DECLARE_CONTEXT_TYPE_WITH_NAME(DEVICE_CONTEXT, GetDeviceContext) NTSTATUS DriverEntry(_In_ PDRIVER_OBJECT DriverObject, _In_ PUNICODE_STRING RegistryPath) { NTSTATUS status; WDF_DRIVER_CONFIG config; WDF_DRIVER_CONFIG_INIT(&config, OnDeviceAdd); config.EvtDriverUnload = OnDriverUnload; status = WdfDriverCreate(DriverObject, RegistryPath, WDF_NO_OBJECT_ATTRIBUTES, &config, WDF_NO_HANDLE); if (!NT_SUCCESS(status)) { KdPrint(("WdfDriverCreate failed with status 0x%x\n", status)); return status; } return STATUS_SUCCESS; } VOID OnDriverUnload(_In_ WDFDRIVER Driver) { UNREFERENCED_PARAMETER(Driver); KdPrint(("Driver unloaded\n")); } NTSTATUS OnDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit) { NTSTATUS status; WDF_OBJECT_ATTRIBUTES attributes; PDEVICE_CONTEXT deviceContext; WDFDEVICE device; UNREFERENCED_PARAMETER(Driver); WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT); status = WdfDeviceCreate(&DeviceInit, &attributes, &device); if (!NT_SUCCESS(status)) { KdPrint(("WdfDeviceCreate failed with status 0x%x\n", status)); return status; } deviceContext = GetDeviceContext(device); // Access PCIe configuration space ULONG pciConfigSpaceAddress = 0x80000000; // example address, replace with your own ULONG data = 0; status = WdfDeviceQueryProperty(device, DevicePropertyPciConfigSpace, sizeof(pciConfigSpaceAddress), &pciConfigSpaceAddress, &data, sizeof(data), NULL); if (!NT_SUCCESS(status)) { KdPrint(("WdfDeviceQueryProperty failed with status 0x%x\n", status)); return status; } // do something with the data return STATUS_SUCCESS; } VOID OnDeviceCleanup(_In_ WDFOBJECT Object) { UNREFERENCED_PARAMETER(Object); KdPrint(("Device cleanup\n")); } ``` 这个驱动程序创建一个设备,并在设备创建时访问PCIe配置空间。在 `OnDeviceAdd` 回调函数中,使用 `WdfDeviceQueryProperty` 函数查询设备的PCIe配置空间,获取相应的数据,然后进行处理即可。其中,`DevicePropertyPciConfigSpace` 参数用于指定查询PCIe配置空间的属性,`pciConfigSpaceAddress` 参数用于指定配置空间地址。这里仅作为一个示例,实际应用中需要根据具体情况修改代码。 需要注意的是,在驱动程序中访问PCIe配置空间需要管理员权限,因此必须以管理员身份运行驱动程序。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值