写一个wdf驱动程序,能够访问pcie配置空间
时间: 2024-05-09 18:16:03 浏览: 50
好的,下面是一个简单的 wdf 驱动程序,可以访问 PCIe 配置空间。
```c
#include <ntddk.h>
#include <wdf.h>
DRIVER_INITIALIZE DriverEntry;
EVT_WDF_DRIVER_UNLOAD OnDriverUnload;
EVT_WDF_DRIVER_DEVICE_ADD OnDeviceAdd;
EVT_WDF_OBJECT_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);
return status;
}
void OnDriverUnload(_In_ WDFDRIVER Driver) {
UNREFERENCED_PARAMETER(Driver);
}
NTSTATUS OnDeviceAdd(_In_ WDFDRIVER Driver, _Inout_ PWDFDEVICE_INIT DeviceInit) {
UNREFERENCED_PARAMETER(Driver);
NTSTATUS status;
WDF_OBJECT_ATTRIBUTES attributes;
WDFDEVICE device;
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&attributes, DEVICE_CONTEXT);
status = WdfDeviceCreate(&DeviceInit, &attributes, &device);
if (!NT_SUCCESS(status)) {
KdPrint(("Failed to create device (0x%08X)\n", status));
return status;
}
PDEVICE_CONTEXT context = GetDeviceContext(device);
context->Device = device;
return status;
}
void OnDeviceCleanup(_In_ WDFOBJECT Device) {
UNREFERENCED_PARAMETER(Device);
}
NTSTATUS AccessPcieConfigSpace(_In_ WDFDEVICE Device) {
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_CONTEXT context = GetDeviceContext(Device);
// 获取设备对象的 PCI 对象
WDFDEVICE parentDevice = WdfPdoGetParent(Device);
WDFMEMORY configSpaceMemory = NULL;
ULONG configSpaceSize = 4096;
// 分配内存来接收配置空间
status = WdfMemoryCreate(
WDF_NO_OBJECT_ATTRIBUTES,
NonPagedPoolNx,
0,
configSpaceSize,
&configSpaceMemory,
NULL);
if (!NT_SUCCESS(status)) {
KdPrint(("Failed to allocate memory for config space (0x%08X)\n", status));
goto Cleanup;
}
// 读取配置空间
PHYSICAL_ADDRESS configSpaceBaseAddress = { 0 };
configSpaceBaseAddress.QuadPart = WdfDeviceGetBusData(parentDevice, PCI_WHICHSPACE_CONFIG, WdfPdoGetAddress(Device), WdfMemoryGetBuffer(configSpaceMemory, NULL), configSpaceSize);
// 检查是否读取成功
if (configSpaceBaseAddress.QuadPart == 0) {
KdPrint(("Failed to read config space\n"));
status = STATUS_UNSUCCESSFUL;
goto Cleanup;
}
// 输出配置空间
for (ULONG i = 0; i < configSpaceSize; i += 4) {
ULONG value = *(PULONG)((PUCHAR)WdfMemoryGetBuffer(configSpaceMemory, NULL) + i);
KdPrint(("Config space offset 0x%04X: 0x%08X\n", i, value));
}
Cleanup:
if (configSpaceMemory != NULL) {
WdfObjectDelete(configSpaceMemory);
}
return status;
}
```
这个驱动程序的主要逻辑在 `AccessPcieConfigSpace` 函数中。它分配一个内存对象来接收 PCIe 配置空间,然后使用 `WdfDeviceGetBusData` 函数读取配置空间。读取到的配置空间存储在内存对象中,并可以使用 `WdfMemoryGetBuffer` 函数获取。
要在驱动程序中调用此函数,请在 `OnDeviceAdd` 函数的末尾添加以下代码:
```c
status = AccessPcieConfigSpace(device);
if (!NT_SUCCESS(status)) {
KdPrint(("Failed to access PCIe config space (0x%08X)\n", status));
}
```
当设备被添加时,此代码将调用 `AccessPcieConfigSpace` 函数,并打印出读取到的 PCIe 配置空间。请注意,此代码仅用于演示目的,您需要根据自己的需求修改它。
阅读全文