各位大神,本人照着Windows驱动开发技术详解上的分层驱动的例子,驱动A为普通的驱动,驱动B负责IoAttachDeviceToDeviceStack到驱动A上,按照书上的说法,驱动B处于高层的设备链上,应该先退出,驱动A后退出,结果: 驱动B能退出,驱动A一直不能退出,即DebugView一直无法显示调用DriverUnload例程:
驱动A为最普通的helloworld驱动,
正常情况下能调用DriverUnload,但是有驱动B挂载的时候就无法退出;
驱动B的源码为:
DriverEntry:
NtStatus = CreateDevice(pDriverObject);
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pDriverObject->pDeviceObject->DeviceExtension;
if (!NT_SUCCESS(NtStatus))
{
DbgPrint("LayerDriverB CreateDevice Device[%wZ] failed \r\n",pDevExt->usDeviceName);
return NtStatus;
}
//----------------------Attach Target Device-------------------------//
UNICODE_STRING usTarDeviceName;
RtlInitUnicodeString(&usTarDeviceName, L"\\Device\\DDKLayerDeviceA");
PFILE_OBJECT pFileObj = NULL;
PDEVICE_OBJECT pDevTar = NULL;
NtStatus = IoGetDeviceObjectPointer(&usTarDeviceName,FILE_ALL_ACCESS,&pFileObj,&pDevTar);
if (!NT_SUCCESS(NtStatus))
{
IoDeleteSymbolicLink(&pDevExt->usDosDeviceName);
IoDeleteDevice(pDevExt->pDeviceObj);
DbgPrint("LayerDriverB IoAttachDeviceToDeviceStack Device[%wZ] failed \r\n",&usTarDeviceName);
return NtStatus;
}
PDEVICE_OBJECT pFilterDev = pDevExt->pDeviceObj;
PDEVICE_OBJECT pTarDevice = IoAttachDeviceToDeviceStack(pFilterDev,pDevTar);
if (NULL == pTarDevice)
{
ObReferenceObject(pFileObj);
IoDeleteSymbolicLink(&pDevExt->usDosDeviceName);
IoDeleteDevice(pDevExt->pDeviceObj);
DbgPrint("LayerDriverB IoAttachDeviceToDeviceStack Device[%wZ] failed \r\n",&usTarDeviceName);
return STATUS_INSUFFICIENT_RESOURCES;
}
pDevExt->pTargetObj = pTarDevice;
pFilterDev->DeviceType = pTarDevice->DeviceType;
pFilterDev->Characteristics = pTarDevice->Characteristics;
pFilterDev->Flags &= ~DO_DEVICE_INITIALIZING;
pFilterDev->Flags |= pTarDevice->Flags&(DO_BUFFERED_IO | DO_DIRECT_IO);
ObReferenceObject(pFileObj);
DbgPrint("LayerDriverB IoAttachDeviceToDeviceStack Device[%wZ] success \r\n",&usTarDeviceName);
LayerDriverB_Unload:
PDEVICE_OBJECT pNextObj;
DbgPrint(("DriverB:Enter B DriverUnload\n"));
pNextObj = pDriverObject->pDeviceObject;
while (pNextObj != NULL)
{
DbgPrint("Current Driver[%wZ] \r\n",&pNextObj->pDriverObject->DriverName);
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)pNextObj->DeviceExtension;
//从设备栈中弹出
IoDetachDevice( pDevExt->pTargetObj);
//删除该设备对象
IoDeleteDevice( pDevExt->pDeviceObj );
IoDeleteSymbolicLink(&pDevExt->usDosDeviceName);
DbgPrint("Device[%wZ] has been deleted \r\n",&pDevExt->usDosDeviceName);
pNextObj = pNextObj->NextDevice;
}
按道理来说,肯定是驱动A的引用计数没到1,所以当驱动A退出(卸载服务)的时候没有调用unload例程,但是驱动B的代码都检查很多遍了,没找到哪些地方的问题,求各位大神帮帮忙~
[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课