[求助]WDM驱动处理IRP_MN_REMOVE_DEVICE意外IRQL_NOT_LESS_OR_EQUAL

csx007700 2013-04-30 10:02:57
如题,我写了一个WDM模型过滤驱动程序,注册表同时挂接在Mouclass和Kbdclass的LowerFilter上。系统启动的时候收到了一个IRP_MJ_PNP,IRP_MN_QUERY_REMOVE_DEVICE的IRP,然后我就删除创建的设备对象,但是这个过程中就直接BSOD了,原因IRQL_NOT_LESS_OR_EQUAL。我看了半天实在找不出来到底哪里升了IRQL,甚至我在每两行代码间都加入了if(KeGetCurrentIrql()>PASSIVE_LEVEL){__asm int 3},但是都断不下来。代码如下。

NTSTATUS
WKC_PnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
DebugTracePrint(
DEBUG_NORMAL_INFO,
"WKC_PnP",
("Function entered."));
PIO_STACK_LOCATION irpSp = IoGetCurrentIrpStackLocation(Irp);
PWKC_DEVICE_EXTENSION pExt = ((PWKC_DEVICE_EXTENSION)DeviceObject->DeviceExtension);
NTSTATUS status;

ASSERT(pExt);

switch (irpSp->MinorFunction){

case IRP_MN_START_DEVICE:
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;

case IRP_MN_QUERY_REMOVE_DEVICE:
Irp->IoStatus.Status = STATUS_SUCCESS;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;

case IRP_MN_REMOVE_DEVICE:

status = WKC_ForwardIrpSynchronous(DeviceObject, Irp);

DetachDevice(DeviceObject);//此处出错

Irp->IoStatus.Status = STATUS_SUCCESS;

IoCompleteRequest(Irp, IO_NO_INCREMENT);
return STATUS_SUCCESS;

case IRP_MN_QUERY_PNP_DEVICE_STATE:
status = WKC_ForwardIrpSynchronous(DeviceObject, Irp);
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
return status;
}

return WKC_DefaultHandler(DeviceObject, Irp);
}

NTSTATUS WKC_ForwardIrpSynchronous(
IN PDEVICE_OBJECT pDeviceObject,
IN PIRP pIrp
)
{
PWKC_DEVICE_EXTENSION devExtension;
KEVENT pEvent;
NTSTATUS status;

DebugTracePrint(
DEBUG_NORMAL_INFO,
"WKC_ForwardIrpSynchronous",
("Synchronizing IRP."));

KeInitializeEvent(&pEvent, NotificationEvent, FALSE);

devExtension = (PWKC_DEVICE_EXTENSION) pDeviceObject->DeviceExtension;

IoCopyCurrentIrpStackLocationToNext(pIrp);

IoSetCompletionRoutine(pIrp, WKC_IrpCompletion, &pEvent, TRUE, TRUE, TRUE);

status = IoCallDriver(devExtension->pTargetDeviceObject, pIrp);

if (status == STATUS_PENDING) {
KeWaitForSingleObject(&pEvent, Executive, KernelMode, FALSE, NULL);
status = pIrp->IoStatus.Status;
}

DebugTracePrint(
DEBUG_NORMAL_INFO,
"WKC_ForwardIrpSynchronous",
(" IRP Synchronize finished."));

return status;
}

VOID
DetachDevice(
IN PDEVICE_OBJECT pDeviceObject
)
{
PWKC_DEVICE_EXTENSION devExtension;

BOOLEAN NoRequestsOutstanding = FALSE;

DebugTracePrint(
DEBUG_NORMAL_INFO,
"DetachDevice",
("Function enterd."));

devExtension = (PWKC_DEVICE_EXTENSION)pDeviceObject->DeviceExtension;
__try {
__try {
IoDetachDevice(devExtension->pTargetDeviceObject);

devExtension->pTargetDeviceObject = NULL;

IoDeleteDevice(pDeviceObject);

devExtension->pFilterDeviceObject = NULL; //此处出错

DebugTracePrint(
DEBUG_NORMAL_INFO,
"DetachDevice",
("Detach Finished."));
}
__except (EXCEPTION_EXECUTE_HANDLER){
DebugTracePrint(
DEBUG_ERROR,
"DetachDevice",
("Something wrong occured when detach the device. SEH handled."));
}
}
__finally{}
return;
}


以下是Windbg分析

*******************************************************************************
* *
* Bugcheck Analysis *
* *
*******************************************************************************

IRQL_NOT_LESS_OR_EQUAL (a)
An attempt was made to access a pageable (or completely invalid) address at an
interrupt request level (IRQL) that is too high. This is usually
caused by drivers using improper addresses.
If a kernel debugger is available get the stack backtrace.
Arguments:
Arg1: 00000000, memory referenced
Arg2: 00000002, IRQL
Arg3: 00000001, bitfield :
bit 0 : value 0 = read operation, 1 = write operation
bit 3 : value 0 = not an execute operation, 1 = execute operation (only on chips which support this level of status)
Arg4: 80524f8c, address which referenced memory

Debugging Details:
------------------

*** No owner thread found for resource 80552f60
*** No owner thread found for resource 80552f60
*** No owner thread found for resource 80552f60

WRITE_ADDRESS: 00000000

CURRENT_IRQL: 2

FAULTING_IP:
nt!PoRegisterDeviceForIdleDetection+46
80524f8c 8901 mov dword ptr [ecx],eax

DEFAULT_BUCKET_ID: DRIVER_FAULT

BUGCHECK_STR: 0xA

PROCESS_NAME: System

TRAP_FRAME: f8af5a8c -- (.trap 0xfffffffff8af5a8c)
ErrCode = 00000002
eax=8208ef18 ebx=8055ac08 ecx=00000000 edx=00000000 esi=820822a4 edi=820822b4
eip=80524f8c esp=f8af5b00 ebp=f8af5b10 iopl=0 nv up ei pl nz na po nc
cs=0008 ss=0010 ds=0023 es=0023 fs=0030 gs=0000 efl=00010202
nt!PoRegisterDeviceForIdleDetection+0x46:
80524f8c 8901 mov dword ptr [ecx],eax ds:0023:00000000=????????
Resetting default scope

LOCK_ADDRESS: 80552fe0 -- (!locks 80552fe0)

Resource @ nt!IopDeviceTreeLock (0x80552fe0) Shared 1 owning threads
Threads: 821b7640-01<*>
1 total locks, 1 locks currently held

PNP_TRIAGE:
Lock address : 0x80552fe0
Thread Count : 1
Thread address: 0x821b7640
Thread wait : 0x5da

LAST_CONTROL_TRANSFER: from 804f8b9d to 80528bdc

STACK_TEXT:
f8af5640 804f8b9d 00000003 f8af599c 00000000 nt!RtlpBreakWithStatusInstruction
f8af568c 804f978a 00000003 00000000 80524f8c nt!KiBugCheckDebugBreak+0x19
f8af5a6c 80541683 0000000a 00000000 00000002 nt!KeBugCheck2+0x574
f8af5a6c 80524f8c 0000000a 00000000 00000002 nt!KiTrap0E+0x233
f8af5b10 80649d0e 820821d8 00000000 00000000 nt!PoRegisterDeviceForIdleDetection+0x46
f8af5b34 804f1915 820821d8 8218a170 f8af5b7c nt!PoRunDownDeviceObject+0x1c
f8af5b44 f892b3d2 820821d8 81d40c64 8218a170 nt!IoDeleteDevice+0x4d
f8af5b7c f892bd6b 820821d8 00000002 00000001 Subci_WinKernelCaptor!DetachDevice+0x92 [d:\projects\bciseries\subci_winkernelcaptor\attachmanage.cpp @ 325]
f8af5b9c 804ef119 820821d8 81d40b40 f8af5c28 Subci_WinKernelCaptor!WKC_PnP+0xeb [d:\projects\bciseries\subci_winkernelcaptor\dispatchroutines.cpp @ 338]
f8af5bac 80588fc9 8208ef18 8208ef18 00000002 nt!IopfCallDriver+0x31
f8af5bd8 805890ed 820821d8 f8af5c04 00000000 nt!IopSynchronousCall+0xb7
f8af5c2c 804f6e86 8208ef18 00000002 00000000 nt!IopRemoveDevice+0x93
f8af5c54 8058ac06 e14ea8c8 0000001f e1691888 nt!IopRemoveLockedDeviceNode+0x160
f8af5c6c 8058ac6d 8208e3c0 00000002 e1691888 nt!IopDeleteLockedDeviceNode+0x34
f8af5ca0 805908dd 8208ef18 02691888 00000002 nt!IopDeleteLockedDeviceNodes+0x3f
f8af5d34 80590ba0 f8af5d70 806d3778 e16578b0 nt!PiProcessQueryRemoveAndEject+0x76b
f8af5d50 80590ce6 f8af5d70 82134200 8055c0fc nt!PiProcessTargetDeviceEvent+0x2a
f8af5d74 80535c02 82134200 00000000 821b7640 nt!PiWalkDeviceList+0xea
f8af5dac 805c7160 82134200 00000000 00000000 nt!ExpWorkerThread+0x100
f8af5ddc 80542dd2 80535b02 00000001 00000000 nt!PspSystemThreadStartup+0x34
00000000 00000000 00000000 00000000 00000000 nt!KiThreadStartup+0x16


STACK_COMMAND: kb

FOLLOWUP_IP:
Subci_WinKernelCaptor!DetachDevice+92 [d:\projects\bciseries\subci_winkernelcaptor\attachmanage.cpp @ 325]
f892b3d2 8b4de0 mov ecx,dword ptr [ebp-20h]

FAULTING_SOURCE_CODE:
321: devExtension->pTargetDeviceObject = NULL;
322:
323: IoDeleteDevice(pDeviceObject);
324:
> 325: devExtension->pFilterDeviceObject = NULL;
326:
327: DebugTracePrint(
328: DEBUG_NORMAL_INFO,
329: "DetachDevice",
330: ("Detach Finished."));


SYMBOL_STACK_INDEX: 7

SYMBOL_NAME: Subci_WinKernelCaptor!DetachDevice+92

FOLLOWUP_NAME: MachineOwner

MODULE_NAME: Subci_WinKernelCaptor

IMAGE_NAME: Subci_WinKernelCaptor.sys

DEBUG_FLR_IMAGE_TIMESTAMP: 517fcac7

FAILURE_BUCKET_ID: 0xA_Subci_WinKernelCaptor!DetachDevice+92

BUCKET_ID: 0xA_Subci_WinKernelCaptor!DetachDevice+92

Followup: MachineOwner
---------


LOCK_ADDRESS: 80552fe0 -- (!locks 80552fe0)
Resource @ nt!IopDeviceTreeLock (0x80552fe0) Shared 1 owning threads
实在是看不出这个锁是哪里来的。IRP_MJ_PNP的派遣函数和WKC_ForwardIrpSynchronous基本上是VisualDDK生成的,完全郁闷了,不知道怎么办。是不是鼠标或者键盘的IRP_MN_QUERY_REMOVE_DEVICE要特殊处理,还是什么别的情况?

还请各位大牛帮我一把……快把一个五一假期郁闷完了……
...全文
345 6 打赏 收藏 转发到动态 举报
写回复
用AI写文章
6 条回复
切换为时间正序
请发表友善的回复…
发表回复
olivertang 2013-05-06
  • 打赏
  • 举报
回复
switch (irpStack->MinorFunction) { case IRP_MN_SURPRISE_REMOVAL: // // Same as a remove device, but don't call IoDetach or IoDeleteDevice // // Remove code here IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(devExt->pTargetDevice, Irp); break; case IRP_MN_REMOVE_DEVICE: // remove code here IoSkipCurrentIrpStackLocation(Irp); IoCallDriver(devExt->pTargetDevice, Irp); IoDetachDevice(devExt->pTargetDevice); IoDeleteDevice(DeviceObject); status = STATUS_SUCCESS; break; case IRP_MN_START_DEVICE: case IRP_MN_QUERY_REMOVE_DEVICE: case IRP_MN_QUERY_STOP_DEVICE: case IRP_MN_CANCEL_REMOVE_DEVICE: case IRP_MN_CANCEL_STOP_DEVICE: case IRP_MN_FILTER_RESOURCE_REQUIREMENTS: case IRP_MN_STOP_DEVICE: case IRP_MN_QUERY_DEVICE_RELATIONS: case IRP_MN_QUERY_INTERFACE: case IRP_MN_QUERY_CAPABILITIES: case IRP_MN_QUERY_DEVICE_TEXT: case IRP_MN_QUERY_RESOURCES: case IRP_MN_QUERY_RESOURCE_REQUIREMENTS: case IRP_MN_READ_CONFIG: case IRP_MN_WRITE_CONFIG: case IRP_MN_EJECT: case IRP_MN_SET_LOCK: case IRP_MN_QUERY_ID: case IRP_MN_QUERY_PNP_DEVICE_STATE: default: // // Here the filter driver might modify the behavior of these IRPS // Please see PlugPlay documentation for use of these IRPs. // IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(devExt->pTargetDevice, Irp); break; } return status;
星星眼 2013-05-05
  • 打赏
  • 举报
回复
case IRP_MN_REMOVE_DEVICE: 这里你设置了完成例程,把WKC_IrpCompletion这个函数贴出来我看看。
曹大夯 2013-05-05
  • 打赏
  • 举报
回复
你再那个IRP里面IoAttachDevice的? 可以试着在去调用IoDetachDevice。 但是不要去调用IoDeleteDevice(pDeviceObject);
csx007700 2013-05-03
  • 打赏
  • 举报
回复
自己顶一下……没人回复了么……
csx007700 2013-05-02
  • 打赏
  • 举报
回复
引用 1 楼 Huntercao 的回复:
Filter驱动处理IRP_MN_REMOVE_DEVICE信息要非常小心。因为本身并没有对应物理设备,所以在IRP_MN_REMOVE_DEVICE德时候,应该不用做什么事。将对应的IRP直接交给下层驱动去处理就好了。
原来是这样啊……也就是说不用IoDeleteDevice喽?那么需要Detach吗?我调试了一下如果不Detach的话会导致后来的绑定都失败啊……
曹大夯 2013-05-02
  • 打赏
  • 举报
回复
Filter驱动处理IRP_MN_REMOVE_DEVICE信息要非常小心。因为本身并没有对应物理设备,所以在IRP_MN_REMOVE_DEVICE德时候,应该不用做什么事。将对应的IRP直接交给下层驱动去处理就好了。

21,597

社区成员

发帖
与我相关
我的任务
社区描述
硬件/嵌入开发 驱动开发/核心开发
社区管理员
  • 驱动开发/核心开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧