驱动程序无法获取 I/O DMA 适配器
Driver is unable to get I/O DMA Adapter
我的没有 Scatter/Gather 功能的 PCI 总线主控设备驱动程序调用 IoGetDmaAdapter()
,但因 0xFFFFFFFFC0000005 Access Violation
而失败。这会导致 BSOD。
我是这样设置的:
RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
deviceDescription.Master = TRUE; // this is a bus-master device without scatter/gather ability
deviceDescription.Dma32BitAddresses = TRUE; // this device is unable to perform 64-bit addressing
deviceDescription.InterfaceType = InterfaceTypeUndefined;
KdBreakPoint();
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2;
IoGetDmaAdapter(deviceObject, &deviceDescription, &fakeRegs);
这是我的 Windows 内核调试会话:
MyDriver!AllocateHardWareResource+0x313:
fffff803`319626a3 488b8424e8000000 mov rax,qword ptr [rsp+0E8h]
MyDriver!AllocateHardWareResource+0x324:
fffff803`319626b4 488d442478 lea rax,[rsp+78h]
MyDriver!AllocateHardWareResource+0x34d:
fffff803`319626dd 8b442450 mov eax,dword ptr [rsp+50h]
MyDriver!AllocateHardWareResource+0x358:
fffff803`319626e8 c684248900000001 mov byte ptr [rsp+89h],1
MyDriver!AllocateHardWareResource+0x360:
fffff803`319626f0 c784248000000002000000 mov dword ptr [rsp+80h],2
MyDriver!AllocateHardWareResource+0x36b:
fffff803`319626fb 4c8d44244c lea r8,[rsp+4Ch]
KDTARGET: Refreshing KD connection
KDTARGET: Refreshing KD connection
*** Fatal System Error: 0x0000007e
(0xFFFFFFFFC0000005,0x0000000000000000,0xFFFF9400DE25D4B8,0xFFFF9400DE25CCF0)
WARNING: This break is not a step/trace completion.
The last command has been cleared to prevent
accidental continuation of this unrelated event.
Check the event, location and thread before resuming.
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
在 Guard_Dispatch_iCall_NOP 崩溃之前,我看到以下调用堆栈:
HalpGetCacheCoherency + 6D
HalGetAdapterV2 + A8
IoGetDmaAdapter + C0
IoGetDmaAdapter + C0
IoGetDmaAdapter + C0
My Call-Site
我检查过物理设备对象的地址与最初提供给我的 AddDevice 处理程序的地址相同。
我应该如何礼貌地询问以避免来自 Windows Kernel I/O Manager 的 "Sorry Dave, I can't do that"?
当我的驱动程序调用 IoGetDmaAdapter() 时,驱动程序通过 IRP_MN_QUERY_INTERFACE 接收到两个接口查询:GUID_BUS_INTERFACE_STANDARD 和 GUID_DMA_CACHE_COHERENCY_INTERFACE。
GUID_DMA_CACHE_COHERENCY_INTERFACE 是 Windows 10 或 Server 2016 的新功能。
GUID_DMA_CACHE_COHERENCY_INTERFACE 查询通常应该传递给堆栈中的下一个驱动程序。我犯了一个错误,将状态设置为成功,但应该不理会它。
我的没有 Scatter/Gather 功能的 PCI 总线主控设备驱动程序调用 IoGetDmaAdapter()
,但因 0xFFFFFFFFC0000005 Access Violation
而失败。这会导致 BSOD。
我是这样设置的:
RtlZeroMemory(&deviceDescription, sizeof(DEVICE_DESCRIPTION));
deviceDescription.Master = TRUE; // this is a bus-master device without scatter/gather ability
deviceDescription.Dma32BitAddresses = TRUE; // this device is unable to perform 64-bit addressing
deviceDescription.InterfaceType = InterfaceTypeUndefined;
KdBreakPoint();
deviceDescription.Version = DEVICE_DESCRIPTION_VERSION2;
IoGetDmaAdapter(deviceObject, &deviceDescription, &fakeRegs);
这是我的 Windows 内核调试会话:
MyDriver!AllocateHardWareResource+0x313:
fffff803`319626a3 488b8424e8000000 mov rax,qword ptr [rsp+0E8h]
MyDriver!AllocateHardWareResource+0x324:
fffff803`319626b4 488d442478 lea rax,[rsp+78h]
MyDriver!AllocateHardWareResource+0x34d:
fffff803`319626dd 8b442450 mov eax,dword ptr [rsp+50h]
MyDriver!AllocateHardWareResource+0x358:
fffff803`319626e8 c684248900000001 mov byte ptr [rsp+89h],1
MyDriver!AllocateHardWareResource+0x360:
fffff803`319626f0 c784248000000002000000 mov dword ptr [rsp+80h],2
MyDriver!AllocateHardWareResource+0x36b:
fffff803`319626fb 4c8d44244c lea r8,[rsp+4Ch]
KDTARGET: Refreshing KD connection
KDTARGET: Refreshing KD connection
*** Fatal System Error: 0x0000007e
(0xFFFFFFFFC0000005,0x0000000000000000,0xFFFF9400DE25D4B8,0xFFFF9400DE25CCF0)
WARNING: This break is not a step/trace completion.
The last command has been cleared to prevent
accidental continuation of this unrelated event.
Check the event, location and thread before resuming.
Break instruction exception - code 80000003 (first chance)
A fatal system error has occurred.
在 Guard_Dispatch_iCall_NOP 崩溃之前,我看到以下调用堆栈:
HalpGetCacheCoherency + 6D
HalGetAdapterV2 + A8
IoGetDmaAdapter + C0
IoGetDmaAdapter + C0
IoGetDmaAdapter + C0
My Call-Site
我检查过物理设备对象的地址与最初提供给我的 AddDevice 处理程序的地址相同。
我应该如何礼貌地询问以避免来自 Windows Kernel I/O Manager 的 "Sorry Dave, I can't do that"?
当我的驱动程序调用 IoGetDmaAdapter() 时,驱动程序通过 IRP_MN_QUERY_INTERFACE 接收到两个接口查询:GUID_BUS_INTERFACE_STANDARD 和 GUID_DMA_CACHE_COHERENCY_INTERFACE。
GUID_DMA_CACHE_COHERENCY_INTERFACE 是 Windows 10 或 Server 2016 的新功能。
GUID_DMA_CACHE_COHERENCY_INTERFACE 查询通常应该传递给堆栈中的下一个驱动程序。我犯了一个错误,将状态设置为成功,但应该不理会它。