阅读:2162回复:0
ctrl2cap里卸载驱动导致蓝屏怎么解决(已解决)
照抄了一遍ctrl2cap,可以卸载的时候一到IoDeleteDevice就会蓝屏,错误码是IRQL_NOT_LESS_OR_EQUAL
原来是iocreatedevice的时候扩展设备的大小写成了指针的大小 这个论坛很冷清。。。内核方面人真的很少吗 相关代码 __try { __try { IoDetachDevice(devExt->pLowerDeviceObject); // 把扩展设备数据结构中的指针置空 devExt->pTargetDeviceObject = NULL; // 实质上删除的是过滤设备,见kbfUnload if (pDeviceObject!=NULL) IoDeleteDevice(pDeviceObject); ----> 一到这里就蓝屏 devExt->pFilterDeviceObject = NULL; KdPrint(("解除成功\n")); } __except(EXCEPTION_EXECUTE_HANDLER){} } __finally{} 那位高手能帮我看一下源码哪里有问题吗?代码长了点。。。不好意思 我的源码 // // @file kbfilter.c // // @author bymars // // @date 2010/6/9 // 抄代码 #include <wdm.h> #include <ntddkbd.h> #include "kbfilter.h" #define KBD_DRIVER_NAME L"\\Driver\\Kbdclass" #define KEY_UP 1 #define KEY_DOWN 0 #define LCONTROL ((USHORT)0x1D) #define CAPS_LOCK ((USHORT)0x3A) typedef struct _KB_DEV_EXT { // 大小 ULONG NodeSize; // 过滤设备对象 PDEVICE_OBJECT pFilterDeviceObject; // 保护锁 KSPIN_LOCK IoRequestsSpinLock; // 进程同步处理 KEVENT IoInProgressEvent; // 绑定的目标设备 PDEVICE_OBJECT pTargetDeviceObject; // 过滤设备下一个设备 // 因为每次绑定设备最终会帮定这个设备栈的最上面的设备 PDEVICE_OBJECT pLowerDeviceObject; } KB_DEV_EXT, *PKB_DEV_EXT; // 键盘扫描码处理 // 001,010,100 #define S_SHIFT 1 #define S_CAPS 2 #define S_NUM 4 // 默认numlock是打开的 static int kb_status = S_NUM; void __stdcall print_keystroke(UCHAR sch) { UCHAR ch = 0; int off = 0; // 按下键盘 if ((sch & 0x80) == 0) //make { if ((sch < 0x47) || ((sch >= 0x47 && sch < 0x54) && (kb_status & S_NUM))) // Num Lock { ch = asciiTbl[off+sch]; } switch (sch) { case 0x3A: kb_status ^= S_CAPS; break; case 0x2A: case 0x36: kb_status |= S_SHIFT; break; case 0x45: kb_status ^= S_NUM; } } else // 按键弹起,只处理左右shift { if (sch == 0xAA || sch == 0xB6) kb_status &= ~S_SHIFT; } if (ch >= 0x20 && ch < 0x7F) { DbgPrint("%C \n",ch); } } // 初始化设备扩展 NTSTATUS kbfDevExtInit( IN PKB_DEV_EXT devExt, IN PDEVICE_OBJECT pFilterDeviceObject, IN PDEVICE_OBJECT pTargetDeviceObject, IN PDEVICE_OBJECT pLowerDeviceObject ) { memset (devExt, 0, sizeof( KB_DEV_EXT )); devExt->NodeSize = sizeof( KB_DEV_EXT ); devExt->pFilterDeviceObject = pFilterDeviceObject; KeInitializeSpinLock(&(devExt->IoRequestsSpinLock)); KeInitializeEvent(&(devExt->IoInProgressEvent), NotificationEvent, FALSE); devExt->pTargetDeviceObject = pTargetDeviceObject; devExt->pLowerDeviceObject = pLowerDeviceObject; return STATUS_SUCCESS; } // 这个函数存在,但文档中没公开,声明之后可以用 NTSTATUS ObReferenceObjectByName( PUNICODE_STRING ObjectName, ULONG Attributes, PACCESS_STATE AccessState, ACCESS_MASK DesiredAccess, POBJECT_TYPE ObjectType, KPROCESSOR_MODE AccessMode, PVOID ParseContext, PVOID *Object ); // 暂时不知道什么意思 extern POBJECT_TYPE IoDriverObjectType; ULONG keyCount = 0; // 全局变量 gDriverObject = DriverObject; PDRIVER_OBJECT gDriverObject = NULL; // 绑定kbdclass下面的所有设备 NTSTATUS kbfAttachDevice( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { NTSTATUS status = 0; UNICODE_STRING uniNtNameString; PKB_DEV_EXT devExt; PDEVICE_OBJECT pFilterDeviceObject = NULL; PDEVICE_OBJECT pTargetDeviceObject = NULL; PDEVICE_OBJECT pLowerDeviceObject = NULL; PDRIVER_OBJECT KbdDriverObject = NULL; KdPrint(("MyAttach\n")); RtlInitUnicodeString(&uniNtNameString, KBD_DRIVER_NAME); status = ObReferenceObjectByName( &uniNtNameString, OBJ_CASE_INSENSITIVE, NULL, 0, IoDriverObjectType, KernelMode, NULL, &KbdDriverObject ); if( !NT_SUCCESS(status) ) { KdPrint(("MyAttach: 不能打开设备对象kbdclass")); return status; } else { // 调用引用系列函数后都要解除,书上貌似笔误了 ObDereferenceObject(KbdDriverObject); } // 设备链的第一个设备,第一个目标设备 pTargetDeviceObject = KbdDriverObject->DeviceObject; // 遍历设备链 while( pTargetDeviceObject ) { // 生成过滤设备,使用扩展设备 status = IoCreateDevice( IN DriverObject, IN sizeof(PKB_DEV_EXT), IN NULL, IN pTargetDeviceObject->DeviceType, IN pTargetDeviceObject->Characteristics, IN FALSE, OUT &pFilterDeviceObject ); if( !NT_SUCCESS(status) ) { KdPrint(("MyAttach: 不能创建过滤设备")); return status; } // 创建成功,绑定目标设备,得到的是目标设备所在设备栈最上面的设备 // 也就是过滤设备下面那个设备 pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject, pTargetDeviceObject); if( !pLowerDeviceObject ) { KdPrint(("MyAttach: 绑定失败,删除过滤设备...")); IoDeleteDevice(pFilterDeviceObject); pFilterDeviceObject = NULL; return STATUS_UNSUCCESSFUL; } // 生成设备扩展,强制转换成PC2P_DEV_EXT类型,实际是确定这个指针的长度 devExt = (PKB_DEV_EXT)(pFilterDeviceObject->DeviceExtension); kbfDevExtInit(devExt,pFilterDeviceObject, pTargetDeviceObject, pLowerDeviceObject); // 收尾工作 pFilterDeviceObject->DeviceType = pLowerDeviceObject->DeviceType; pFilterDeviceObject->Characteristics = pLowerDeviceObject->Characteristics; pFilterDeviceObject->StackSize = pLowerDeviceObject->StackSize + 1; pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE); // 取下一个设备 pTargetDeviceObject = pTargetDeviceObject->NextDevice; } return status; } // 解除绑定 VOID kbfDetach(IN PDEVICE_OBJECT pDeviceObject) { PKB_DEV_EXT devExt; // 没用到啊 BOOLEAN NoRequestsOutstanding = FALSE; devExt = (PKB_DEV_EXT)pDeviceObject->DeviceExtension; __try { __try { IoDetachDevice(devExt->pLowerDeviceObject); // 把扩展设备数据结构中的指针置空 devExt->pTargetDeviceObject = NULL; // 实质上删除的是过滤设备,见kbfUnload if (pDeviceObject!=NULL) IoDeleteDevice(pDeviceObject); devExt->pFilterDeviceObject = NULL; KdPrint(("解除成功\n")); } __except(EXCEPTION_EXECUTE_HANDLER){} } __finally{} return; } // 延时 #define DELAY_ONE_MICROSECOND (-10) #define DELAY_ONE_MILLISECOND (DELAY_ONE_MICROSECOND*1000) #define DELAY_ONE_SECOND (DELAY_ONE_MILLISECOND*1000) VOID kbfUnload(IN PDRIVER_OBJECT DriverObject) { PDEVICE_OBJECT DeviceObject; // 没用到 PDEVICE_OBJECT OldDeviceObject; PKB_DEV_EXT devExt; LARGE_INTEGER delay; PRKTHREAD CurrentThread; #if DBG __asm int 3 #endif // 定义延时 delay = RtlConvertLongToLargeInteger(100 * DELAY_ONE_MILLISECOND); CurrentThread = KeGetCurrentThread(); // 降低进程优先级 KeSetPriorityThread(CurrentThread, LOW_REALTIME_PRIORITY); UNREFERENCED_PARAMETER(DriverObject); KdPrint(("正在卸载。。。")); // DriverObject->DeviceObject实质上是过滤设备 // IoCreatDevice(DriverObject, ... , &pFilterDeviceObject) // 就是生成DeviceObject下的一个设备 DeviceObject = DriverObject->DeviceObject; // 遍历解绑 while( DeviceObject ) { kbfDetach(DeviceObject); DeviceObject = DeviceObject->NextDevice; } // 没有完全解绑,错误 ASSERT(NULL == DriverObject->DeviceObject); // 延时直到keyCount为零 // 每当一个read请求出现时keyCount++,完成之后keyCount-- // 由于之前过滤设备全部解绑删除,新的irp不会再发给过滤设备 // 此时只要处理最后一个等待的就可以了 while( keyCount ) { KeDelayExecutionThread(KernelMode, FALSE, &delay); } KdPrint(("卸载完成^-^")); return; } // MajorFunction // 其他irp直接跳过 NTSTATUS kbfDispatchGeneral( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PKB_DEV_EXT devExt; devExt = (PKB_DEV_EXT)DeviceObject->DeviceExtension; KdPrint(("其他irp")); // 此函数的意义在于用IoCallDriver()时,设备栈的下一个设备得到 // 和当前设备相同的irp IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->pLowerDeviceObject, Irp); } // 未完待续 //power irp 稍微有些不同 NTSTATUS kbfPower( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PKB_DEV_EXT devExt; devExt = (PKB_DEV_EXT)DeviceObject->DeviceExtension; PoStartNextPowerIrp(Irp); IoSkipCurrentIrpStackLocation(Irp); return PoCallDriver(devExt->pLowerDeviceObject, Irp); } // pnp 即插即用 NTSTATUS kbfPnP( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PKB_DEV_EXT devExt; PIO_STACK_LOCATION irpSp; NTSTATUS status = STATUS_SUCCESS; KIRQL oldIrql; KEVENT event; devExt = (PKB_DEV_EXT)DeviceObject->DeviceExtension; irpSp = IoGetCurrentIrpStackLocation(Irp); // 个人理解 // pnp是major function // pnp下还有minor function switch( irpSp->MinorFunction ) { case IRP_MN_REMOVE_DEVICE: KdPrint(("IRP_MN_REMOVE_DEVICE\n")); IoSkipCurrentIrpStackLocation(Irp); IoCallDriver(devExt->pLowerDeviceObject, Irp); // 180行,解绑的是pTargetDeviceObject, why IoDetachDevice(devExt->pLowerDeviceObject); IoDeleteDevice(DeviceObject); status = STATUS_SUCCESS; break; default : IoSkipCurrentIrpStackLocation(Irp); status = IoCallDriver(devExt->pLowerDeviceObject, Irp); break; } return status; } // 回调函数,read irp 完成后调用此函数 NTSTATUS kbfReadComplete( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { PIO_STACK_LOCATION irpSp; ULONG buf_len = 0; PUCHAR buf = NULL; size_t i, numKeys; // 按键数据结构 PKEYBOARD_INPUT_DATA keyData; irpSp = IoGetCurrentIrpStackLocation( Irp ); if( NT_SUCCESS(Irp->IoStatus.Status) ) { buf = Irp->AssociatedIrp.SystemBuffer; keyData = (PKEYBOARD_INPUT_DATA)buf; // 缓冲区长度一般保存在information中 buf_len = Irp->IoStatus.Information; numKeys = buf_len / sizeof(KEYBOARD_INPUT_DATA); // 此处可以处理buf中的扫描码 // for( i = 0; i < buf_len ; i++ ) // { // KdPrint(("键盘记录: %2x\r\n", buf)); // } // 扫描码处理方法之二 for( i = 0; i < numKeys ; i++ ) { KdPrint(("\n")); KdPrint(("numKeys: %d", numKeys)); KdPrint(("ScanCode: %x", keyData->MakeCode)); KdPrint(("%s\n", keyData->Flags?"Up":"Down")); print_keystroke((UCHAR)keyData->MakeCode); // if( keyData->MakeCode == CAPS_LOCK ) // { // keyData->MakeCode = LCONTROL; // } } } keyCount--; if( Irp->PendingReturned ) { IoMarkIrpPending( Irp ); } return Irp->IoStatus.Status; } // read marjor fountion NTSTATUS kbfDispatchRead( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { NTSTATUS status = STATUS_SUCCESS; PKB_DEV_EXT devExt; PIO_STACK_LOCATION irpSp; KEVENT waitEvent; // 后面的都不太懂 // MSDN -- A driver can use an event object to wait while // the next-lower driver processes an IRP set up by the waiting driver. KeInitializeEvent(&waitEvent, NotificationEvent, FALSE); // 这是个什么错误 if( Irp->CurrentLocation == 1 ) { KdPrint(("错误的current location\n")); status = STATUS_INVALID_DEVICE_REQUEST; Irp->IoStatus.Status = status; Irp->IoStatus.Information = 0; IoCompleteRequest(Irp, IO_NO_INCREMENT); return status; } // 读请求等待,计数器加一 keyCount++; devExt = (PKB_DEV_EXT)DeviceObject->DeviceExtension; // 设置回调函数,等待读请求完成。 irpSp = IoGetCurrentIrpStackLocation(Irp); // IoSkipCurrentIrpStackLocation // MSDN -- copies the IRP stack parameters from the current I/O stack // location to the stack location of the next-lower driver IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine(Irp, kbfReadComplete, DeviceObject, TRUE, TRUE, TRUE); return IoCallDriver(devExt->pLowerDeviceObject, Irp); } NTSTATUS DriverEntry( IN PDRIVER_OBJECT DriverObject, IN PUNICODE_STRING RegistryPath) { ULONG i; NTSTATUS status; KdPrint(("进入入口函数\n")); // 其他分发函数 for( i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++ ) { DriverObject->MajorFunction = kbfDispatchGeneral; } // read irp DriverObject->MajorFunction[IRP_MJ_READ] = kbfDispatchRead; // power irp DriverObject->MajorFunction[IRP_MJ_POWER] = kbfPower; // pnp irp DriverObject->MajorFunction[IRP_MJ_PNP] = kbfPnP; // 卸载函数 DriverObject->DriverUnload = kbfUnload; // 全局变量 gDriverObject = DriverObject; // 绑定所有设备 status = kbfAttachDevice(DriverObject,RegistryPath); return status; } |
|