Dirs. DIRS= sys
Sys:
/**---------------------------------------------------------------------------------------------------**/ Device.c
#include \
#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, PCISample_EvtDeviceAdd) #pragma alloc_text(PAGE, InitializeDMA)
#pragma alloc_text(PAGE, PCISample_EvtDevicePrepareHardware) #pragma alloc_text(PAGE, PCISample_EvtDeviceReleaseHardware) #endif
NTSTATUS
PCISample_EvtDeviceAdd(
IN WDFDRIVER Driver, IN PWDFDEVICE_INIT DeviceInit ) {
NTSTATUS status;
WDF_PNPPOWER_EVENT_CALLBACKS pnpPowerCallbacks; WDF_OBJECT_ATTRIBUTES deviceAttributes; WDFDEVICE device; PDEVICE_CONTEXT pDeviceContext; WDF_INTERRUPT_CONFIG interruptConfig; WDF_IO_QUEUE_CONFIG ioQueueConfig;
PAGED_CODE(); //采用WdfDeviceIoDirect方式
WdfDeviceInitSetIoType(DeviceInit, WdfDeviceIoDirect); //初始化即插即用和电源管理例程配置结构
WDF_PNPPOWER_EVENT_CALLBACKS_INIT(&pnpPowerCallbacks); //设置即插即用基本例程
pnpPowerCallbacks.EvtDevicePrepareHardware = PCISample_EvtDevicePrepareHardware; pnpPowerCallbacks.EvtDeviceReleaseHardware = PCISample_EvtDeviceReleaseHardware;
//注册即插即用和电源管理例程
WdfDeviceInitSetPnpPowerEventCallbacks(DeviceInit, &pnpPowerCallbacks);
WDF_OBJECT_ATTRIBUTES_INIT_CONTEXT_TYPE(&deviceAttributes, DEVICE_CONTEXT); //
// Set WDFDEVICE synchronization scope. By opting for device level // synchronization scope, all the queue and timer callbacks are // synchronized with the device-level spinlock. //
deviceAttributes.SynchronizationScope = WdfSynchronizationScopeDevice;
status = WdfDeviceCreate(&DeviceInit, &deviceAttributes, &device); if (!NT_SUCCESS(status)) { return status; }
pDeviceContext = GetDeviceContext(device); //设置中断服务例程和延迟过程调用
WDF_INTERRUPT_CONFIG_INIT(&interruptConfig,
PCISample_EvtInterruptIsr, PCISample_EvtInterruptDpc); //创建中断对象
status = WdfInterruptCreate(device,
&interruptConfig,
WDF_NO_OBJECT_ATTRIBUTES, &pDeviceContext->Interrupt); if (!NT_SUCCESS (status)) { return status; }
status = InitializeDMA(device);
if (!NT_SUCCESS(status)) { return status; }
WDF_IO_QUEUE_CONFIG_INIT_DEFAULT_QUEUE(&ioQueueConfig, WdfIoQueueDispatchSequential);
ioQueueConfig.EvtIoWrite = PCISample_EvtIoWrite; ioQueueConfig.EvtIoRead = PCISample_EvtIoRead;
status = WdfIoQueueCreate(device, &ioQueueConfig, WDF_NO_OBJECT_ATTRIBUTES, NULL);
if (!NT_SUCCESS(status)) { return status; }
status = WdfDeviceCreateDeviceInterface(device, (LPGUID)&PCISample_DEVINTERFACE_GUID, NULL); if (!NT_SUCCESS(status)) { }
return status; }
NTSTATUS InitializeDMA(
IN WDFDEVICE Device ) {
NTSTATUS status; PDEVICE_CONTEXT pDeviceContext; WDF_DMA_ENABLER_CONFIG dmaConfig;
PAGED_CODE();
pDeviceContext = GetDeviceContext(Device);
//
// DMA_TRANSFER_ELEMENTS must be 16-byte aligned //
//设置DMA数据缓冲区地址边界:16字节对齐
WdfDeviceSetAlignmentRequirement( Device, FILE_OCTA_ALIGNMENT );
//
// Create a new DMA Enabler instance. // //创建一个DMA适配器 WDF_DMA_ENABLER_CONFIG_INIT( &dmaConfig, WdfDmaProfilePacket, MAXNLEN ); status = WdfDmaEnablerCreate( Device,
&dmaConfig,
WDF_NO_OBJECT_ATTRIBUTES, &pDeviceContext->DmaEnabler ); if (!NT_SUCCESS (status)) { DbgPrint(\ return status; } // // Create a new DmaTransaction. // //创建一个DMA传输 status = WdfDmaTransactionCreate( pDeviceContext->DmaEnabler,
WDF_NO_OBJECT_ATTRIBUTES,
&pDeviceContext->DmaTransaction ); if(!NT_SUCCESS(status)) { DbgPrint(\ }
return status; }
NTSTATUS
PCISample_EvtDevicePrepareHardware( IN WDFDEVICE Device,
IN WDFCMRESLIST ResourceList,
IN WDFCMRESLIST ResourceListTranslated ) {
PDEVICE_CONTEXT pDeviceContext; ULONG i; PCM_PARTIAL_RESOURCE_DESCRIPTOR descriptor;
PAGED_CODE();
DbgPrint(\
pDeviceContext = GetDeviceContext(Device); pDeviceContext->MemBaseAddress = NULL;
//
// Parse the resource list and save the resource information. //
for (i=0; i < WdfCmResourceListGetCount(ResourceListTranslated); i++) {
descriptor = WdfCmResourceListGetDescriptor(ResourceListTranslated, i);
switch (descriptor->Type) {
case CmResourceTypeMemory: //MmMapIoSpace将物理地址转换成系统内核模式地址 pDeviceContext->MemBaseAddress = MmMapIoSpace( descriptor->u.Memory.Start, descriptor->u.Memory.Length, MmNonCached); pDeviceContext->MemLength = descriptor->u.Memory.Length;
break;
default: break; }
}
DbgPrint(\
return STATUS_SUCCESS; }
NTSTATUS
PCISample_EvtDeviceReleaseHardware( IN WDFDEVICE Device,
IN WDFCMRESLIST ResourceListTranslated ) {
PDEVICE_CONTEXT pDeviceContext;
PAGED_CODE();
DbgPrint(\
pDeviceContext = GetDeviceContext(Device); if(pDeviceContext->MemBaseAddress) { //MmUnmapIoSpace解除物理地址与系统内核模式地址的关联 MmUnmapIoSpace(pDeviceContext->MemBaseAddress,