PCI/PCIe接口卡Windows驱动程序(4)
本篇文章将对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; 128 // 129 // 初始化Context这个结构里的所有成员. 130 // 131 //deviceContext->PrivateDeviceData = 0; 132 /*++++++Interrupt & DMA 133 //设置中断服务例程和延迟过程调用 134 WDF_INTERRUPT_CONFIG_INIT(&interruptConfig, 135 PCISample_EvtInterruptIsr, 136 PCISample_EvtInterruptDpc); 137 138 //创建中断对象 139 status = WdfInterruptCreate(device, 140 &interruptConfig, 141 WDF_NO_OBJECT_ATTRIBUTES, 142 &pDeviceContext->Interrupt); 143 if (!NT_SUCCESS (status)) { 144 return status; 145 } 146 147 status = InitializeDMA(device); 148 149 if (!NT_SUCCESS(status)) { 150 return status; 151 } 152 -----*/ 153 //WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&queueConfig, WdfIoQueueDispatchSequential); 154 //Initialize the Queue 155 // queueConfig.EvtIoDefault = Spw_PCIeEvtIoDefault; 156 // queueConfig.EvtIoWrite = Spw_PCIeEvtIoWrite; 157 //queueConfig.EvtIoRead = Spw_PCIeEvtIoRead; 158 // queueConfig.EvtIoStop = Spw_PCIeEvtIoStop; 159 //The driver must initialize the WDF_IO_QUEUE_CONFIG structure 160 //by calling WDF_IO_QUEUE_CONFIG_INIT or WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE. 161 //用default初始化default 队列,用另一个初始化非default队列 162 WDF_IO_QUEUE_CONFIG_INIT( 163 &queueConfig, 164 WdfIoQueueDispatchSequential 165 ); 166 167 queueConfig.EvtIoDeviceControl = Spw_PCIeEvtIoDeviceControl; 168 169 170 status = WdfIoQueueCreate(device, &queueConfig, WDF_NO_OBJECT_ATTRIBUTES, &queue); 171 if (!NT_SUCCESS(status)) { 172 return status; 173 } 174 175 //对于非默认队列,必须指定要分发的I/O请求类型 176 //The WdfDeviceConfigureRequestDispatching method causes the framework to queue a specified type of I/O requests to a specified I/O queue. 177 status = WdfDeviceConfigureRequestDispatching( 178 device, 179 queue, 180 WdfRequestTypeDeviceControl 181 ); 182 if (!NT_SUCCESS(status)) { 183 return status; 184 } 185 //创建驱动程序接口与应用程序通信 186 status = WdfDeviceCreateDeviceInterface( 187 device, 188 (LPGUID)&GUID_DEVINTERFACE_Spw_PCIe, 189 NULL // ReferenceString 190 ); 191 if (!NT_SUCCESS(status)) { 192 return status; 193 } 194 /* 195 if (NT_SUCCESS(status)) { 196 // 197 // Initialize the I/O Package and any Queues 198 // 199 status = Spw_PCIeQueueInitialize(device); 200 } 201 */ 202 //deviceContext->MemLength = MAXNLEN; 203 204 //TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Exit"); 205 206 return status; 207 } 208 209 VOID 210 Spw_PCIeEvtDriverContextCleanup( 211 _In_ WDFOBJECT DriverObject 212 ) 213 /*++ 214 Routine Description: 215 216 Free all the resources allocated in DriverEntry. 217 218 Arguments: 219 220 DriverObject - handle to a WDF Driver object. 221 222 Return Value: 223 224 VOID. 225 226 --*/ 227 { 228 UNREFERENCED_PARAMETER(DriverObject); 229 230 PAGED_CODE (); 231 232 TraceEvents(TRACE_LEVEL_INFORMATION, TRACE_DRIVER, "%!FUNC! Entry"); 233 234 //没有必要清除WDFINTERRUPT对象,因为框架会自动清除 235 // Stop WPP Tracing 236 // 237 WPP_CLEANUP( WdfDriverWdmGetDriverObject(DriverObject) ); 238 239 }
温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/69098.html