原文出处:http://www.cnblogs.com/jacklu/p/4687325.html
如果你觉得这篇博客对你的项目有用,请引用以下论文:
Meng Shengwei, Lu Jianjie. Design of a PCIe Interface Card Control Software Based on WDF. Fifth International Conference on Instrumentation and Measurement, Computer, Communication and Control. IEEE, 2016:767-770.
本篇文章将对PCIe驱动程序的部分源文件代码作详细解释与说明。完整代码,有偿提供~整个WDF驱动程序工程共包含4个头文件(已经在上篇文章中讲解)和3个.c文件(Driver.c Device.c Queue.c)
Driver.c
在看复杂的代码前,先给出程序流程图
1 #include "driver.h" 2 #include "driver.tmh" 3 4 #ifdef ALLOC_PRAGMA 5 #pragma alloc_text (INIT, DriverEntry) 6 #pragma alloc_text (PAGE, Spw_PCIeEvtDeviceAdd) 7 #pragma alloc_text (PAGE, Spw_PCIeEvtDriverContextCleanup) 8 #endif 9 10 11 NTSTATUS 12 DriverEntry( 13 IN PDRIVER_OBJECT DriverObject, 14 IN PUNICODE_STRING RegistryPath 15 ) 16 { 17 WDF_DRIVER_CONFIG config; 18 //WDFDRIVER driver;//???? 19 NTSTATUS status = STATUS_SUCCESS; 20 WDF_OBJECT_ATTRIBUTES attributes; 21 22 // 23 // Initialize WPP Tracing 24 // 25 WPP_INIT_TRACING( DriverObject, RegistryPath ); 26 27 TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); 28 29 // 30 // Register a cleanup callback so that we can call WPP_CLEANUP when 31 // the framework driver object is deleted during driver unload. 32 // 33 34 WDF_OBJECT_ATTRIBUTES_INIT(&attributes); 35 36 attributes.EvtCleanupCallback = Spw_PCIeEvtDriverContextCleanup; 37 38 WDF_DRIVER_CONFIG_INIT(&config, 39 Spw_PCIeEvtDeviceAdd 40 ); 41 42 status = WdfDriverCreate(DriverObject, 43 RegistryPath, 44 &attributes, 45 &config, 46 WDF_NO_HANDLE 47 ); 48 49 if (!NT_SUCCESS(status)) { 50 TraceEvents(TRACE_LEVEL_ERROR, TRACE_DRIVER, "WdfDriverCreate failed %!STATUS!", status); 51 WPP_CLEANUP(DriverObject); 52 return status; 53 } 54 55 TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); 56 57 return status; 58 } 59 60 61 NTSTATUS 62 Spw_PCIeEvtDeviceAdd( 63 _In_ WDFDRIVER Driver, 64 _Inout_ PWDFDEVICE_INIT DeviceInit 65 ) 66 { 67 NTSTATUS status = STATUS_SUCCESS; 68 WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; 69 WDF_OBJECT_ATTRIBUTES deviceAttributes; 70 WDFDEVICE device; 71 PDEVICE_CONTEXT deviceContext; 72 73 WDFQUEUE queue; 74 WDF_IO_QUEUE_CONFIG queueConfig; 75 76 /*+++++Interrupt 77 WDF_INTERRUPT_CONFIG interruptConfig; 78 -----*/ 79 // WDF_IO_QUEUE_CONFIG ioQueueConfig; 80 81 UNREFERENCED_PARAMETER(Driver); 82 83 PAGED_CODE(); 84 85 //采用WdfDeviceIoDirect方式 86 WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect);//WdfDeviceIoBuffered???重要吗? 87 //When the I/O manager sends a request for buffered I/O, the IRP contains an internal copy of the caller's buffer 88 //rather than the caller's buffer itself. The I/O manager copies data from the caller's buffer to the internal buffer 89 //during a write request or from the internal buffer to the caller's buffer when the driver completes a read 90 //request. 91 //The WDF driver receives a WDF request object, which in turn contains an embedded WDF memory object. 92 //The memory object contains the address of the buffer on which the driver should operate. 93 94 95 96 // status = Spw_PCIeCreateDevice(DeviceInit); 97 98 //初始化即插即用和电源管理例程配置结构 99 WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); 100 101 //设置即插即用基本例程 102 pnpPowerCallbacks.EvtDevicePrepareHardware = Spw_PCIeEvtDevicePrepareHardware; 103 pnpPowerCallbacks.EvtDeviceReleaseHardware = Spw_PCIeEvtDeviceReleaseHardware; 104 pnpPowerCallbacks.EvtDeviceD0Entry = Spw_PCIeEvtDeviceD0Entry; 105 pnpPowerCallbacks.EvtDeviceD0Exit = Spw_PCIeEvtDeviceD0Exit; 106 107 //注册即插即用和电源管理例程 108 WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks); 109 110 111 WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); 112 113 114 //deviceAttributes.EvtCleanupCallback = Spw_PCIeEvtDriverContextCleanup; 115 // 116 // Set WDFDEVICE synchronization scope. By opting for device level 117 // synchronization scope, all the queue and timer callbacks are 118 // synchronized with the device-level spinlock. 119 // 120 deviceAttributes.SynchronizationScope = WdfSynchronizationScopeDevice; 121 122 status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); 123 if (!NT_SUCCESS(status)) { 124 return status; 125 } 126 deviceContext = GetDeviceContext(device);///???? 127 //deviceContext->Device = device;