wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
阅读:1936回复:8

键盘过滤驱动的问题

楼主#
更多 发布于:2003-09-22 21:15
为何我的程序可以挂接键盘,都正常,但退出以后,再按键盘系统就会崩溃呢??
Russinovich采用WDM方式,很不方便,改写为动态装卸载,可卸在后按键盘就兰屏,我SOFTICE调试发现是没有去除挂接,系统还是会调用已经释放的代码,导致页异常.难道是IODETACHDEVICE有问题吗??
//======================================================================
//======================================================================
//
// Ctrl2cap
//
// Copyright (C) 1996-1999 Mark Russinovich
//
// Hook onto the keyboard I/O path and massage the input stream
// converting caps-locks into controls. This example works on
// NT 4 and Win2K and the Win2K version is very losely based on the
// i8042 port filter driver sample, kbfiltr, from the Win2K DDK.
//
// For every function I list whether the function gets called
// under NT 4, WIN2K, or both.
//
// File: ctrl2cap.c
//
//======================================================================
#include \"ntddk.h\"
#include <ntddkbd.h>
#include \"stdarg.h\"
#include \"stdio.h\"
#include \"ctrl2cap.h\"
#include \"ntddkbd.h\"
//----------------------------------------------------------------------
//
// DriverEntry
//
// Installable driver initialization. Here we just set ourselves up.
//
// Called: NT4, WIN2K
//
//----------------------------------------------------------------------
NTSTATUS DriverEntry(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
ULONG i;
NTSTATUS status;
DbgPrint ((\"Ctrl2cap.SYS: entering DriverEntry\\n\"));

//
// Fill in all the dispatch entry points with the pass through function
// and the explicitly fill in the functions we are going to intercept
//
for (i = 0; i < IRP_MJ_MAXIMUM_FUNCTION; i++)
{

DriverObject->MajorFunction = Ctrl2capDispatchGeneral;
}

//
// Our read function is where we do our real work.
//
DriverObject->MajorFunction[IRP_MJ_READ] = Ctrl2capDispatchRead;

//
// Power IRPs are the only ones we have to handle specially under
// Win2k since they require the special PoCallDriver and
// PoStartNextPowerIrp function calls.
//
DriverObject->MajorFunction [IRP_MJ_POWER] = Ctrl2capPower;

//
// The only reason we need to handle PnP IRPs is to know when
// a device we\'ve attached to disappears (is removed).
//
DriverObject->MajorFunction [IRP_MJ_PNP] = Ctrl2capPnP;

//
// Under Win2K we get told about the presence of keyboard
// devices through our AddDevice entry point.
//
DriverObject->DriverUnload = Ctrl2capUnload;
status =Ctrl2capAddDevice(DriverObject, RegistryPath);;

return status;;
}

//----------------------------------------------------------------------
//
// Ctrl2capAddDevice
//
// The PnP Manager calls us for each keyboard present on the system.
// We attach to each one so that we can flip caps lock to controls.
//
// Called: WIN2K
//
//----------------------------------------------------------------------
NTSTATUS
Ctrl2capAddDevice(
IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
)
{
NTSTATUS status = 0;
UNICODE_STRING uniNtNameString, linkString;
PMyFilter_DeviceExtension pMyFilter_DeviceExtension;
PDEVICE_OBJECT pFilterDeviceObject = NULL;
PDEVICE_OBJECT pTargetDeviceObject = NULL;
PFILE_OBJECT pTargetFileObject = NULL;
PDEVICE_OBJECT pLowerDeviceObject = NULL;

DbgPrint((\"MyAttach.\\n\"));

RtlInitUnicodeString(&uniNtNameString, MYTEST_DEVICE_NAME);

status = IoGetDeviceObjectPointer(
IN &uniNtNameString,
IN FILE_READ_ATTRIBUTES,
OUT &pTargetFileObject,
OUT &pTargetDeviceObject
);
if(!NT_SUCCESS(status))
{
DbgPrint((\"MyAttach: Couldn\'t get the MyTest Device Object\\n\"));
pTargetFileObject = NULL;
pTargetDeviceObject = NULL;
return( status );
}

//
// Create a filter device and attach it to the device stack.
//
RtlInitUnicodeString(&uniNtNameString, MYFILTER__DEVICE_NAME);

status = IoCreateDevice(
IN DriverObject,
IN sizeof(MyFilter_DeviceExtension),
IN &uniNtNameString,
IN pTargetDeviceObject->DeviceType,
IN pTargetDeviceObject->Characteristics,
IN FALSE,
OUT &pFilterDeviceObject
);
if (!NT_SUCCESS(status))
{

DbgPrint((\"MyAttach: Couldn\'t create the MyFilter Filter Device Object\\n\"));
ObDereferenceObject(pTargetFileObject);
pTargetFileObject = NULL;
pTargetDeviceObject = NULL;
return (status);
}

pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject, pTargetDeviceObject);
if(!pLowerDeviceObject)
{
DbgPrint((\"MyAttach: Couldn\'t attach to MyTest Device Object\\n\"));
IoDeleteDevice(pFilterDeviceObject);
pFilterDeviceObject = NULL;
ObDereferenceObject(pTargetFileObject);
pTargetFileObject = NULL;
pTargetDeviceObject = NULL;
return( status );
}

pMyFilter_DeviceExtension = (PMyFilter_DeviceExtension)(pFilterDeviceObject->DeviceExtension);
MyFilter_InitDeviceExtension(
IN pMyFilter_DeviceExtension,
IN pFilterDeviceObject,
IN pTargetDeviceObject,
IN pTargetFileObject,
IN 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) ;

return status;
}

NTSTATUS
MyFilter_InitDeviceExtension(
IN PMyFilter_DeviceExtension pMyFilter_DeviceExtension,
IN PDEVICE_OBJECT pFilterDeviceObject,
IN PDEVICE_OBJECT pTargetDeviceObject,
IN PFILE_OBJECT pTargetFileObject,
IN PDEVICE_OBJECT pLowerDeviceObject
)
{
memset(pMyFilter_DeviceExtension, 0, sizeof(MyFilter_DeviceExtension));
pMyFilter_DeviceExtension->NodeSize = sizeof(MyFilter_DeviceExtension);
pMyFilter_DeviceExtension->pFilterDeviceObject = pFilterDeviceObject;
KeInitializeSpinLock(&(pMyFilter_DeviceExtension->IoRequestsSpinLock));
KeInitializeEvent(&(pMyFilter_DeviceExtension->IoInProgressEvent), NotificationEvent, FALSE);
pMyFilter_DeviceExtension->TargetDeviceObject = pTargetDeviceObject;
pMyFilter_DeviceExtension->TargetFileObject = pTargetFileObject;
pMyFilter_DeviceExtension->LowerDeviceObject = pLowerDeviceObject;

return( STATUS_SUCCESS );
}
//----------------------------------------------------------------------
//
// Ctrl2capPnP
//
// We have to handle PnP IRPs so that we detach from target
// devices when appropriate.
//
// Called: WIN2K
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capPnP(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PMyFilter_DeviceExtension pMyFilter_DeviceExtension;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
KIRQL oldIrql;
KEVENT event;

pMyFilter_DeviceExtension = (PMyFilter_DeviceExtension)(DeviceObject->DeviceExtension);
irpStack = IoGetCurrentIrpStackLocation(Irp);

switch (irpStack->MinorFunction) {
case IRP_MN_REMOVE_DEVICE:
DbgPrint((\"IRP_MN_REMOVE_DEVICE\\n\"));
//
// Detach from the target device after passing the IRP
// down the devnode stack.
//
IoSkipCurrentIrpStackLocation(Irp);
IoCallDriver(pMyFilter_DeviceExtension->LowerDeviceObject, Irp);

IoDetachDevice(pMyFilter_DeviceExtension->LowerDeviceObject);
IoDeleteDevice(DeviceObject);

status = STATUS_SUCCESS;
break;

case IRP_MN_SURPRISE_REMOVAL:
DbgPrint((\"IRP_MN_SURPRISE_REMOVAL\\n\"));
//
// Same as a remove device, but don\'t call IoDetach or IoDeleteDevice.
//
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pMyFilter_DeviceExtension->LowerDeviceObject, Irp);
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:
DbgPrint((\"OTHER_IRP\\n\"));
//
// Pass these through untouched
//
IoSkipCurrentIrpStackLocation(Irp);
status = IoCallDriver(pMyFilter_DeviceExtension->LowerDeviceObject, Irp);
break;
}

return status;
}


//----------------------------------------------------------------------
//
// Ctrl2capPower
//
// We have to handle Power IRPs specially.
//
// Called: WIN2K
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capPower(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
PMyFilter_DeviceExtension pMyFilter_DeviceExtension;

pMyFilter_DeviceExtension = (PMyFilter_DeviceExtension)DeviceObject->DeviceExtension;

//
// Let the next power IRP out of the gate
//
PoStartNextPowerIrp( Irp );

//
// Pass this power IRP to the keyboard class driver
//
IoSkipCurrentIrpStackLocation( Irp );

return PoCallDriver(pMyFilter_DeviceExtension->LowerDeviceObject, Irp );
}

// WIN2K


//----------------------------------------------------------------------
//
// Ctrl2capReadComplete
//
// Gets control after a read operation has completed.
//
// Called: WIN2K, NT4
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capReadComplete(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
)
{
PIO_STACK_LOCATION IrpSp;
PKEYBOARD_INPUT_DATA KeyData;
int numKeys, i;

//
IrpSp = IoGetCurrentIrpStackLocation( Irp );
if( NT_SUCCESS( Irp->IoStatus.Status ) ) {

//
// Do caps-lock down and caps-lock up. Note that
// just frobbing the MakeCode handles both the up-key
// and down-key cases since the up/down information is specified
// seperately in the Flags field of the keyboard input data
// (0 means key-down, 1 means key-up).
//
KeyData = Irp->AssociatedIrp.SystemBuffer;
numKeys = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);

for( i = 0; i < numKeys; i++ ) {

DbgPrint((\"ScanCode: %x \", KeyData.MakeCode ));
DbgPrint((\"%s\\n\", KeyData.Flags ? \"Up\" : \"Down\" ));

if( KeyData.MakeCode == CAPS_LOCK) {

KeyData.MakeCode = LCONTROL;
}
}
}

//
// Mark the Irp pending if required
//
if( Irp->PendingReturned ) {

IoMarkIrpPending( Irp );
}
return Irp->IoStatus.Status;
}


//----------------------------------------------------------------------
//
// Ctrl2capDispatchRead
//
// Sets up to look at the read request completion so that we can
// massage the input queue on IO completion.
//
// Called: WIN2K, NT4
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capDispatchRead(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp )
{
NTSTATUS RC = STATUS_SUCCESS;
PMyFilter_DeviceExtension pMyFilter_DeviceExtension;
PIO_STACK_LOCATION currentIrpStack;
PIO_STACK_LOCATION nextIrpStack;

//
// Gather our variables.
//
if (Irp->CurrentLocation == 1)
{
ULONG ReturnedInformation = 0;

DbgPrint((\"Dispatch encountered bogus current location\\n\"));

RC = STATUS_INVALID_DEVICE_REQUEST;
Irp->IoStatus.Status = RC;
Irp->IoStatus.Information = ReturnedInformation;
IoCompleteRequest(Irp, IO_NO_INCREMENT);

return(RC);
}

pMyFilter_DeviceExtension = (PMyFilter_DeviceExtension)DeviceObject->DeviceExtension;
currentIrpStack = IoGetCurrentIrpStackLocation(Irp);
nextIrpStack = IoGetNextIrpStackLocation(Irp);

//
// Push params down for keyboard class driver.
//
*nextIrpStack = *currentIrpStack;

//
// Set the completion callback, so we can \"frob\" the keyboard data.
//
IoSetCompletionRoutine( Irp, Ctrl2capReadComplete,
DeviceObject, TRUE, TRUE, TRUE );

//
// Return the results of the call to the keyboard class driver.
//
return IoCallDriver( pMyFilter_DeviceExtension->LowerDeviceObject, Irp );
}


//----------------------------------------------------------------------
//
// Ctrl2capDispatchGeneral
//
// This handles several functions we are not interested in
// along to the keyboard class driver.
//
// Called: WIN2K, NT4
//
//----------------------------------------------------------------------
NTSTATUS Ctrl2capDispatchGeneral(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp
)
{
//
// Pass the IRP to the target without touching the IRP
//

DbgPrint((\"Other Diapatch!\"));
IoSkipCurrentIrpStackLocation(Irp);
#ifdef WINNT4 // WIN2K
//
// This is the equivalent of the IoSkipCurrentIrpStackLocation macro,
// which doesn\'t exist in the NT 4 DDK.
//
Irp->CurrentLocation++;
Irp->Tail.Overlay.CurrentStackLocation++;
#endif // WIN2K
return IoCallDriver(((PMyFilter_DeviceExtension) DeviceObject->DeviceExtension)->LowerDeviceObject, Irp);
}

//----------------------------------------------------------------------
//
// Ctrl2capUnload
//
// Our Win2K PnP unload function. We don\'t need to do anything.
//
// Called: WIN2K
//
//----------------------------------------------------------------------

VOID
Ctrl2capUnload(IN PDRIVER_OBJECT DriverObject)
{
PDEVICE_OBJECT DeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PMyFilter_DeviceExtension pMyFilter_DeviceExtension;

UNREFERENCED_PARAMETER(DriverObject);
DbgPrint((\"DriverEntry unLoading...\\n\"));

DeviceObject = DriverObject->DeviceObject;
MyDetach(DeviceObject);
ASSERT(NULL == DriverObject->DeviceObject);
return;
}




VOID
MyDetach(IN PDEVICE_OBJECT pDeviceObject)
{
PMyFilter_DeviceExtension pMyFilter_DeviceExtension;
BOOLEAN NoRequestsOutstanding = FALSE;

pMyFilter_DeviceExtension = (PMyFilter_DeviceExtension)pDeviceObject->DeviceExtension;

try
{
try
{
IoDetachDevice(pMyFilter_DeviceExtension->TargetDeviceObject);//LowerDeviceObject,TargetDeviceObject);

if(pMyFilter_DeviceExtension->TargetFileObject)
ObDereferenceObject(pMyFilter_DeviceExtension->TargetFileObject);
pMyFilter_DeviceExtension->TargetFileObject = NULL;
pMyFilter_DeviceExtension->TargetDeviceObject = NULL;
IoDeleteDevice(pDeviceObject);
pMyFilter_DeviceExtension->pFilterDeviceObject = NULL;
DbgPrint((\"Detach Finished\\n\"));
}
except (EXCEPTION_EXECUTE_HANDLER){}
}
finally{}
return;
}

最新喜欢:

EddidEddid hartonoharton...
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
沙发#
发布于:2003-09-22 21:16
头文件
//======================================================================
//
// Ctrl2cap.h
//
// Copyright (C) 1996-1999 Mark Russinovich
//
// Hook onto the keyboard I/O path and massage the input stream
// converting caps-locks into controls. This example works on
// NT 4 and Win2K and the Win2K version is very losely based on the
// i8042 port filter driver sample, kbfiltr, from the Win2K DDK.
//
//======================================================================

//
// Define scan codes of interest here. For scan code tables, see
// \"The Undocumented PC\", by Frank Van Gullwe, Addison-Wesley 1994.
//
#define MYTEST_DEVICE_NAME L\"\\\\Device\\\\KeyboardClass0\"
#define MYFILTER__DEVICE_NAME L\"\\\\Device\\\\MyFilter\"

#define KEY_UP         1
#define KEY_DOWN       0

#define LCONTROL       ((USHORT)0x1D)
#define CAPS_LOCK      ((USHORT)0x3A)

//
// Print macro that only turns on when checked builds are on
//
#if DBG
#define DbgPrint(arg) DbgPrint arg
#else
#define DbgPrint(arg)
#endif

//
// Undocumented NT 4 function to print to the startup screen
//
NTSYSAPI
NTSTATUS
NTAPI
ZwDisplayString( PUNICODE_STRING String );


//
// Our device extension definition
//
typedef struct _MyFilter_DEVICE_EXTENSION
{
    //
    // The top of the stack before this filter was added.  AKA the location
    // to which all IRPS should be directed.
    //
    ULONG NodeSize; // 这个结构的大小
PDEVICE_OBJECT pFilterDeviceObject; // 过滤设备对象
KSPIN_LOCK IoRequestsSpinLock; // 同时调用时的保护锁
KEVENT IoInProgressEvent; // 进程间同步处理
PDEVICE_OBJECT TargetDeviceObject; // 绑定的设备对象
PFILE_OBJECT    TargetFileObject; // 绑定设备的文件对象
PDEVICE_OBJECT  LowerDeviceObject; // 绑定前底层设备对象
//PDEVICE_OBJECT  TopOfStack;

} MyFilter_DeviceExtension, *PMyFilter_DeviceExtension;

//
// Forwards
//
NTSTATUS DriverEntry(
    IN PDRIVER_OBJECT  DriverObject,
    IN PUNICODE_STRING RegistryPath
    );

NTSTATUS
Ctrl2capAddDevice(
    IN PDRIVER_OBJECT DriverObject,
IN PUNICODE_STRING RegistryPath
    );

NTSTATUS Ctrl2capPnP(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    );

NTSTATUS Ctrl2capPower(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    );

VOID
Ctrl2capUnload(
   IN PDRIVER_OBJECT Driver
   );

NTSTATUS Ctrl2capInit(
    IN PDRIVER_OBJECT DriverObject
    );

NTSTATUS Ctrl2capDispatchRead(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP Irp
    );

static NTSTATUS Ctrl2capDispatchGeneral(
    IN PDEVICE_OBJECT DeviceObject,
    IN PIRP           Irp
    );


void MyDetach(IN PDEVICE_OBJECT pDeviceObject);

NTSTATUS MyCompletion(
IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp,
IN PVOID Context
);

NTSTATUS MyFilter_InitDeviceExtension(
IN PMyFilter_DeviceExtension pMyFilter_DeviceExtension,
IN PDEVICE_OBJECT pFilterDeviceObject,
IN PDEVICE_OBJECT pTargetDeviceObject,
IN PFILE_OBJECT pTargetFileObject,
IN PDEVICE_OBJECT pLowerDeviceObject
);

花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
arthurtu
驱动巨牛
驱动巨牛
  • 注册日期2001-11-08
  • 最后登录2020-12-19
  • 粉丝0
  • 关注0
  • 积分26分
  • 威望161点
  • 贡献值0点
  • 好评度35点
  • 原创分0分
  • 专家分0分
  • 社区居民
板凳#
发布于:2003-09-22 21:49
可能卸载时候,还有irp没有完成?
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
地板#
发布于:2003-09-23 11:18
那么该如何解决呢???晕......
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
else
驱动小牛
驱动小牛
  • 注册日期2002-10-21
  • 最后登录2004-06-12
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
地下室#
发布于:2003-09-23 12:20
参考Filemon,用一个计数器来记载有多少Irp还没有完成。

过滤驱动本来就不应该卸载,如果别人还有个过滤驱动加载在你上边
这时卸载估计会死翘翘
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
5楼#
发布于:2003-09-23 23:06
我的意思能否象链表那样动态的添加和删除呢??
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
wowocock
VIP专家组
VIP专家组
  • 注册日期2002-04-08
  • 最后登录2016-01-09
  • 粉丝16
  • 关注2
  • 积分601分
  • 威望1651点
  • 贡献值1点
  • 好评度1227点
  • 原创分1分
  • 专家分0分
6楼#
发布于:2003-09-25 13:13
我用SOFTICE调试发现问题出在,可能驱动卸在的时候还有没有完成IRP,然后系统完成IRP后就返回到已经释放的代码初,导致页异常.该如何解决??
花开了,然后又会凋零,星星是璀璨的,可那光芒也会消失。在这样 一瞬间,人降生了,笑者,哭着,战斗,伤害,喜悦,悲伤憎恶,爱。一切都只是刹那间的邂逅,而最后都要归入死亡的永眠
webstartlove
驱动牛犊
驱动牛犊
  • 注册日期2002-07-01
  • 最后登录2004-04-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2004-03-04 19:54
请问一下你这个键盘过滤驱动程序是不是只能挂接ps/2键盘,不能挂接USB键盘是吗?
xxcat1220
驱动牛犊
驱动牛犊
  • 注册日期2004-01-19
  • 最后登录2010-12-20
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
8楼#
发布于:2004-03-05 11:27
过滤驱动通常是不建议卸载的,有没有irp没完成比较难确定
游客

返回顶部