首页
社区
课程
招聘
[求助]键盘过滤驱动导致R3假死
发表于: 2014-5-6 15:09 5408

[求助]键盘过滤驱动导致R3假死

2014-5-6 15:09
5408
写的键盘驱动都是抄袭网上的,做了一点小修改,只是为了屏蔽特定按键。通过IOCTL与R3通信,现在遇到问题是:能够实现屏蔽与开启功能,但是R3一旦调用DeviceIoControl函数成功与驱动同喜 并且返回后,R3不能退出。一直在哪儿,任务管理器等均无法结束此进程。特此求教,谢谢
详细代码在附件中,谢谢帮忙解决下
void TestKbdFilter( char c )
{
	HANDLE hsys = INVALID_HANDLE_VALUE;
	DWORD	dwRet = 0;
	hsys = CreateFile( _T("\\\\.\\KbdFilter"), GENERIC_READ | GENERIC_WRITE, 0, nullptr, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
	if ( hsys == INVALID_HANDLE_VALUE )
	{
		cout<<GetLastError()<<endl;
		return;
	}

	if ( c == 'a' )
	{
		DeviceIoControl( hsys, IOCTL_DISABLE_KBD, nullptr, 0, nullptr, 0, &dwRet, NULL );
		cout<<"\t已开启键盘过滤,只能输入 字母 数字 退格键."<<endl;
	}
	else if ( c== 'b' )
	{
		DeviceIoControl( hsys, IOCTL_ENABLE_KBD, nullptr, 0, nullptr, 0, &dwRet, NULL );
		cout<<"\t键盘过滤已关闭."<<endl;
	}
	CloseHandle( hsys );
}

#include "KbdFilter.h"
BOOLEAN g_bDisableKbd = FALSE;

NTSTATUS DriverEntry( IN PDRIVER_OBJECT KeyDriverObject, IN PUNICODE_STRING RegistryPath )
{
	
	UNICODE_STRING	KeyDeviceName; 
	PDRIVER_OBJECT	KeyDriver; 
	PDEVICE_OBJECT	UsbDeviceObject;
	PDEVICE_OBJECT	pDevObjOut;
	NTSTATUS		ntStatus; 
	//ULONG i; 

	UNICODE_STRING	ustrLinkName;
	UNICODE_STRING	ustrDevName;
	PDEVICE_OBJECT	pDevObj;

	PDEVICE_EXTENSION	pDevExt = NULL;

	//
	// 这里没有过滤其他例程,仅处理了按键操作。这样处理会禁止
	// 休眠。因在锁定时不允许休眠,所以也就无须处理其他例程
	//
	
	//
	// 保存设备名,调试使用
	//
	
	WCHAR szDeviceName[MAXLEN + MAXLEN] = {0};

	//
	// 先尝试获得 USB 键盘设备对象,如果成功则挂接 USB 键盘
	//
	// 注意:因为 USB 键盘设备名不固定,且即使得到名称也无法
	// 使用 IoGetDeviceObjectPointer() 函数根据设备名称得到其
	// 设备对象,所以这里我们只能自己枚举 USB 设备栈,并得到
	// USB 键盘设备来进行挂接
	//


	ntStatus = GetUsbKeybordDevice( &UsbDeviceObject );
	if ( NT_SUCCESS( ntStatus ) && UsbDeviceObject != NULL )
	{
		//
		// 调试使用,USB 键盘设备 kbdhid 没有设备名只有驱动名
		// 所以这里打印为空
		//
		RtlInitUnicodeString( &KeyDeviceName, szDeviceName );  // USB KEYBOARD
		KdPrint( ( "KeyDeviceName:%S.\r\n", KeyDeviceName.Buffer ) );

		//
		// 挂接 USB 键盘设备
		//
		ntStatus = AttachUSBKeyboardDevice( UsbDeviceObject, KeyDriverObject, &pDevObjOut );
		if ( !NT_SUCCESS( ntStatus ) )
		{
			KdPrint( ( "Attach USB Keyboard Device to failed!\r\n" ) );
			return STATUS_INSUFFICIENT_RESOURCES;
		}
		KdPrint( ( "pDevExt->TargetDevice = 0x%x.\r\n", ( (PDEVICE_EXTENSION)pDevObjOut->DeviceExtension )->TargetDevice ) );
	}
	else
	{
		//
		// 如果没有 USB 键盘,则尝试挂接 PS/2 键盘设备
		// 
		RtlInitUnicodeString( &KeyDeviceName, PS2KEYBOARDNAME ); 
		ntStatus = AttachPS2KeyboardDevice( &KeyDeviceName, KeyDriverObject, &KeyDriver, &pDevObjOut );
		if ( !NT_SUCCESS( ntStatus ) || KeyDriver == NULL )
		{
			KdPrint( ( "Attach PS2 Keyboard Device to failed!\r\n" ) ) ;
			return STATUS_INSUFFICIENT_RESOURCES;
		}
		KdPrint( ( "pDevExt->TargetDevice = 0x%x.\r\n", ( (PDEVICE_EXTENSION)pDevObjOut->DeviceExtension )->TargetDevice ) );
	}

	KeyDriverObject->MajorFunction[IRP_MJ_CREATE]			= DispatchCreate;
	KeyDriverObject->MajorFunction[IRP_MJ_CLOSE]			= DispatchClose;
	KeyDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]	= DispatchIoctl;
	KeyDriverObject->MajorFunction[IRP_MJ_READ]				= KeyReadPassThrough; 
	KeyDriverObject->DriverUnload							= KeyDriverUnload; 

	//创建驱动映射名称,用来辅助通信
	RtlInitUnicodeString(&ustrDevName, DEVICE_NAME);
	ntStatus = IoCreateDevice(KeyDriverObject, sizeof(DEVICE_EXTENSION), &ustrDevName, FILE_DEVICE_UNKNOWN, 0, FALSE, &pDevObj);
	KdPrint( ( "[Driver] Device Name %S.\r\n",ustrDevName.Buffer ) );
	if(!NT_SUCCESS(ntStatus))
	{
		KdPrint( ( "[Driver] IoCreateDevice = 0x%x\r\n", ntStatus ) );
		return ntStatus;
	}
	RtlCopyMemory( pDevObj->DeviceExtension, pDevObjOut->DeviceExtension, sizeof(DEVICE_EXTENSION) );
	RtlInitUnicodeString(&ustrLinkName, LINK_NAME);
	ntStatus = IoCreateSymbolicLink(&ustrLinkName, &ustrDevName);  
	if(!NT_SUCCESS(ntStatus))
	{
		KdPrint( ( "[Driver] IoCreateSymbolicLink = 0x%x.\r\n", ntStatus ) );
		IoDeleteDevice(pDevObj);  
		return ntStatus;
	}
	KdPrint( ( "[Driver] SymbolicLink:%S.\r\n",ustrLinkName.Buffer ) );
	return STATUS_SUCCESS;
} 

/////////////////////////////////////////////////////////////////
// 函数类型 : 系统函数
// 函数模块 : 键盘过滤模块
////////////////////////////////////////////////////////////////
// 功能 : 尝试取消队列里的异步 IRP,如果失败则等待用户按键,
//        卸载键盘过滤驱动
// 注意 : 取消 IRP 操作在 2000 系统上可以成功,在 XP / 2003 上
//        则需要等待用户按键,以后有待完善
/////////////////////////////////////////////////////////////////

VOID KeyDriverUnload( PDRIVER_OBJECT KeyDriver )
{
	PDEVICE_EXTENSION KeyExt;
	PIRP Irp;
	NTSTATUS ntStatus;
	UNICODE_STRING strLink;
	PDEVICE_OBJECT TargetDevice;
	KeyExt = ( PDEVICE_EXTENSION )KeyDriver->DeviceObject->DeviceExtension; 
	TargetDevice = KeyExt->TargetDevice;
	KdPrint ( ( "Unload routine - IRPs : [%d] .\r\n", KeyExt->IrpsInProgress ) );

	IoDetachDevice( KeyExt->TargetDevice );

	//
	// 如果还有 IRP 未完成,且当前 IRP 有效则尝试取消这个 IRP
	//
	if ( KeyExt->IrpsInProgress > 0 && TargetDevice->CurrentIrp != NULL )
	{
		if ( CancelKeyboardIrp( TargetDevice->CurrentIrp ) )
		{
			//
			// 成功则直接退出删除键盘过滤设备
			//
			KdPrint( ( "CancelKeyboardIrp() is ok.\r\n" ) );
			goto __End;
		}
	}

	//
	// 如果取消失败,则一直等待按键
	//
	while ( KeyExt->IrpsInProgress > 0 )
	{
		KdPrint( ( "Irp Count:%d.\r\n", KeyExt->IrpsInProgress ) );
	}

__End:
	KdPrint ( ( "DeleteSymbolicLink.\r\n" ) );
	RtlInitUnicodeString(&strLink, LINK_NAME);
	IoDeleteSymbolicLink(&strLink);
	IoDeleteDevice( KeyDriver->DeviceObject );

	KdPrint( ("Unload KbdLck sys.\r\n" ) );
	return ;
} 

/////////////////////////////////////////////////////////////////
// 函数类型 : 自定义工具函数
// 函数模块 : 键盘过滤模块
/////////////////////////////////////////////////////////////////
// 功能 : 取消 IRP 操作
// 注意 : 这个函数仅是为配合在 UNLOAD 例程使用,其他例程中不能
//        使用此方法来取消 IRP
/////////////////////////////////////////////////////////////////

BOOLEAN CancelKeyboardIrp( IN PIRP Irp )
{
	if ( Irp == NULL )
	{
		KdPrint( ( "CancelKeyboardIrp: Irp error.\r\n" ) );
		return FALSE;
	}


	//
	// 如果正在取消或没有取消例程则直接返回 FALSE
	//
	if ( Irp->Cancel || Irp->CancelRoutine == NULL )
	{
		KdPrint( ( "Can't Cancel the irp.SystemBuffer\r\n" ) );
		return FALSE;
	}

	if ( FALSE == IoCancelIrp( Irp ) )
	{
		KdPrint( ( "IoCancelIrp() to failed.\r\n" ) );
		return FALSE;
	}

	//
	// 取消后重设此例程为空
	//
	IoSetCancelRoutine( Irp, NULL );

	return TRUE;
}

/////////////////////////////////////////////////////////////////
// 函数类型 : 自定义工具函数
// 函数模块 : 设备栈信息模块
/////////////////////////////////////////////////////////////////
// 功能 : 遍历 DEVICE_OBJECT 中 AttachedDevice 域,找到 USB 键盘
//        设备上名为 kbdhid 的过滤驱动(Upper Filter Driver)
// 修改内容 : 为匹配 USB 键盘驱动做了相应的修改
/////////////////////////////////////////////////////////////////

BOOLEAN GetAttachedDeviceInfo( IN PDEVICE_OBJECT DevObj )
{
	UNICODE_STRING usKbdDevName;
	PDEVICE_OBJECT DeviceObject;
	BOOLEAN bFound = FALSE;
	RtlInitUnicodeString( &usKbdDevName, KDBDEVICENAME );

	if ( DevObj == NULL )
	{
		KdPrint( ( "DevObj is NULL!\r\n" ) );
		return FALSE;
	}

	DeviceObject = DevObj->AttachedDevice;

	while ( DeviceObject )
	{
		//
		// 一些 OBJECT 的名称都存在分页区,虽然大部分时候不会被交换出去,但
		// 有一次足够了。这算是经验之谈
		//
		if ( MmIsAddressValid( DeviceObject->DriverObject->DriverName.Buffer ) )
		{
			KdPrint( ( "Attached Driver Name:%S,Attached Driver Address:0x%x,Attached DeviceAddress:0x%x.\r\n",
				DeviceObject->DriverObject->DriverName.Buffer,
				DeviceObject->DriverObject,
				DeviceObject ) );

			//
			// 找到 USB 键盘驱动的 kbdhid 设备了么?找到了就不继续了
			//

			if ( RtlCompareUnicodeString( &DeviceObject->DriverObject->DriverName, &usKbdDevName, FALSE ) == 0 )
			{
				KdPrint( ( "Found kbdhid Device.\r\n" ) );
				bFound = TRUE;
				break;
			}
		}

		DeviceObject = DeviceObject->AttachedDevice;
	}

	return bFound;
}

/////////////////////////////////////////////////////////////////
// 函数类型 : 自定义工具函数
// 函数模块 : 设备栈信息模块
/////////////////////////////////////////////////////////////////
// 功能 : 从 DEVICE_OBJECT 中得到设备与驱动名称并打印地址
// 注意 : 函数功能只是打印信息,不同环境使用中应该会做修改
// 修改内容 : 打印出 USB 键盘驱动的设备名称,仅作调试使用
/////////////////////////////////////////////////////////////////

VOID GetDeviceObjectInfo( IN PDEVICE_OBJECT DevObj )
{
	POBJECT_HEADER ObjectHeader;
	POBJECT_HEADER_NAME_INFO ObjectNameInfo; 

	if ( DevObj == NULL )
	{
		KdPrint( ( "DevObj is NULL!\r\n" ) );
		return;
	}

	//
	// 得到对象头
	//
	ObjectHeader = OBJECT_TO_OBJECT_HEADER( DevObj );

	if ( ObjectHeader )
	{
		//
		// 查询设备名称并打印
		//
		ObjectNameInfo = OBJECT_HEADER_TO_NAME_INFO( ObjectHeader );

		if ( ObjectNameInfo && ObjectNameInfo->Name.Buffer )
		{
			KdPrint( ( "Device Name:%S - Device Address:0x%x.\r\n", ObjectNameInfo->Name.Buffer, DevObj ) );

			//
			// 复制 USB 键盘设备名到一个全局 BUFFER 里,为调试时显示
			// 用,没有实际的功能用途
			//
			RtlCopyUnicodeString( &usUsbDevName, &ObjectNameInfo->Name );
		}

		//
		// 对于没有名称的设备,则打印 NULL
		//
		else if ( DevObj->DriverObject )
		{
			KdPrint( ( "Driver Name:%S - Device Name:%S - Driver Address:0x%x - Device Address:0x%x.\r\n",
				DevObj->DriverObject->DriverName.Buffer,
				L"NULL",
				DevObj->DriverObject,
				DevObj ) );
		}
	}
}

/////////////////////////////////////////////////////////////////
// 函数类型 : 自定义工具函数
// 函数模块 : 键盘过滤模块
/////////////////////////////////////////////////////////////////
// 功能 : 得到 USB 驱动 hidusb 的驱动对象,并遍历以上所有设备
//        对象,过滤出 USB 键盘设备,将其设备对象返回
/////////////////////////////////////////////////////////////////

NTSTATUS GetUsbKeybordDevice( OUT PDEVICE_OBJECT* UsbDeviceObject )
{
	UNICODE_STRING DriverName;
	PDRIVER_OBJECT DriverObject = NULL;
	PDEVICE_OBJECT DeviceObject = NULL;
	BOOLEAN bFound = FALSE;

	RtlInitUnicodeString( &DriverName, USBKEYBOARDNAME );

	ObReferenceObjectByName( &DriverName,
		OBJ_CASE_INSENSITIVE,
		NULL,
		0,
		( POBJECT_TYPE )IoDriverObjectType,
		KernelMode,
		NULL,
		&DriverObject );

	if ( DriverObject == NULL )
	{
		KdPrint( ( "Not found USB Keyboard Device hidusb!\r\n" ) );
		return STATUS_UNSUCCESSFUL;
	}
	else 
	{
		ObDereferenceObject(DriverObject);
	}

	DeviceObject = DriverObject->DeviceObject;

	while ( DeviceObject )
	{
		GetDeviceObjectInfo( DeviceObject );

		if ( DeviceObject->AttachedDevice )
		{
			//
			// 查找 USB 键盘设备
			//
			if ( GetAttachedDeviceInfo( DeviceObject ) )
			{
				bFound = TRUE;
				goto __End;
			}
		}

		DeviceObject = DeviceObject->NextDevice;
	}

__End:

	if ( bFound )
	{
		//
		// 找到则返回 USB 键盘设备对象
		//
		*UsbDeviceObject = DeviceObject;
	}
	else
	{
		*UsbDeviceObject = NULL;
	}

	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////////////
// 函数类型 : 自定义工具函数
// 函数模块 : 键盘过滤模块
////////////////////////////////////////////////////////////////
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
//        信息,返回附加后的驱动对象
// 注意 : 此函数仅挂接 USB 键盘设备
/////////////////////////////////////////////////////////////////

NTSTATUS AttachUSBKeyboardDevice( IN PDEVICE_OBJECT UsbDeviceObject, IN PDRIVER_OBJECT  DriverObject, OUT PDEVICE_OBJECT *pDevObjOut )
{
	PDEVICE_OBJECT DeviceObject; 
	PDEVICE_OBJECT TargetDevice; 
	PDEVICE_EXTENSION DevExt;
	NTSTATUS ntStatus;

	//
	// 创建过滤设备对象
	//
	ntStatus = IoCreateDevice( DriverObject,
		sizeof( DEVICE_EXTENSION ),
		NULL,
		FILE_DEVICE_UNKNOWN,
		0,
		FALSE,
		&DeviceObject ); 

	if ( !NT_SUCCESS( ntStatus ) )
	{
		KdPrint( ( "IoCreateDevice() 0x%x!\r\n", ntStatus ) );
		return ntStatus;
	} 
	*pDevObjOut = DeviceObject;
	DevExt = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension;

	//
	// 初始化自旋锁
	//
	KeInitializeSpinLock( &DevExt->SpinLock );

	//
	// 初始化 IRP 计数器
	//
	DevExt->IrpsInProgress = 0;

	//
	// 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
	//

	TargetDevice = IoAttachDeviceToDeviceStack( DeviceObject, UsbDeviceObject ); 
	if ( !TargetDevice )
	{
		IoDeleteDevice( DeviceObject ); 
		KdPrint( ( "IoAttachDeviceToDeviceStack() 0x%x!\r\n", ntStatus ) );
		return STATUS_INSUFFICIENT_RESOURCES;
	} 

	//
	// 保存过滤设备信息
	//
	DevExt->DeviceObject = DeviceObject; 
	DevExt->TargetDevice = TargetDevice;

	//
	// 设置过滤设备相关信息与标志
	//
	DeviceObject->Flags |= ( DO_BUFFERED_IO | DO_POWER_PAGABLE );
	DeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////////////
// 函数类型 : 自定义工具函数
// 函数模块 : 键盘过滤模块
////////////////////////////////////////////////////////////////
// 功能 : 创建过滤设备将其附加到需要跟踪的设备上,保存设备相关
//        信息,返回附加后的驱动对象
// 注意 : 此函数仅挂接 PS/2 键盘设备
/////////////////////////////////////////////////////////////////

NTSTATUS AttachPS2KeyboardDevice(   IN UNICODE_STRING	*DeviceName,			// 需要跟踪的设备名
									IN PDRIVER_OBJECT	DriverObject,			// 过滤驱动也就是本驱动的驱动对象
									OUT PDRIVER_OBJECT	*FilterDriverObject,	// 返回附加后的驱动对象
									OUT PDEVICE_OBJECT	*pDevObjOut )			// 过滤驱动设备对象
{
	PDEVICE_OBJECT DeviceObject; 
	PDEVICE_OBJECT FilterDeviceObject;
	PDEVICE_OBJECT TargetDevice; 
	PFILE_OBJECT FileObject; 
	PDEVICE_EXTENSION DevExt;

	NTSTATUS ntStatus; 

	//
	// 根据设备名称找到需要附加的设备对象
	//
	ntStatus = IoGetDeviceObjectPointer( DeviceName,
		FILE_ALL_ACCESS,
		&FileObject,
		&DeviceObject ); 

	if ( !NT_SUCCESS( ntStatus ) )
	{
		KdPrint( ( "IoGetDeviceObjectPointer() 0x%x.\r\n", ntStatus ) );
		return ntStatus;
	} 

	//
	// 创建过滤设备对象
	//
	ntStatus = IoCreateDevice( DriverObject,
		sizeof( DEVICE_EXTENSION ),
		NULL,
		FILE_DEVICE_KEYBOARD,
		0,
		FALSE,
		&FilterDeviceObject ); 

	if ( !NT_SUCCESS( ntStatus ) )
	{
		ObDereferenceObject( FileObject ); 
		KdPrint( ( "IoCreateDevice() 0x%x!\r\n", ntStatus ) );
		return ntStatus;
	} 

	//
	// 得到设备扩展结构,以便下面保存过滤设备信息
	//

	*pDevObjOut = FilterDeviceObject;
	DevExt = ( PDEVICE_EXTENSION ) FilterDeviceObject->DeviceExtension;

	//
	// 初始化自旋锁
	//
	KeInitializeSpinLock( &DevExt->SpinLock );

	//
	// 初始化 IRP 计数器
	//
	DevExt->IrpsInProgress = 0;

	//
	// 将过滤设备对象附加在目标设备对象之上,并返回附加后的原设备对象
	//
	TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject, DeviceObject ); 
	if ( !TargetDevice )
	{
		ObDereferenceObject( FileObject ); 
		IoDeleteDevice( FilterDeviceObject ); 
		KdPrint( ( "IoAttachDeviceToDeviceStack() 0x%x!\r\n", ntStatus ) );
		return STATUS_INSUFFICIENT_RESOURCES;
	} 

	//
	// 保存过滤设备信息
	//
	DevExt->DeviceObject = FilterDeviceObject; 
	DevExt->TargetDevice = TargetDevice; 
	DevExt->pFilterFileObject = FileObject;

	//
	// 设置过滤设备相关信息与标志
	//
	FilterDeviceObject->DeviceType = TargetDevice->DeviceType; 
	FilterDeviceObject->Characteristics = TargetDevice->Characteristics; 
	FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
	FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO | DO_BUFFERED_IO ) ); 

	//
	// 返回附加后的驱动对象
	//
	*FilterDriverObject = TargetDevice->DriverObject;

	ObDereferenceObject( FileObject ); 

	return STATUS_SUCCESS;
}

/////////////////////////////////////////////////////////////////
// 函数类型 : 自定义工具函数
// 函数模块 : 键盘过滤模块
////////////////////////////////////////////////////////////////
// 功能 : 键盘过滤驱动的 IRP_MJ_READ 派遣例程,所有按键将触发
//        这个 IRP 的完成
/////////////////////////////////////////////////////////////////

NTSTATUS KeyReadPassThrough( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp )
{
	NTSTATUS status; 
	KIRQL IrqLevel;

	PDEVICE_OBJECT pDeviceObject;
	PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension; 
	IoCopyCurrentIrpStackLocationToNext( Irp );

	//
	// 将 IRP 计数器加一,为支持 SMP 使用自旋锁
	//
	KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
	InterlockedIncrement( &KeyExtension->IrpsInProgress );
	KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );
	IoSetCompletionRoutine( Irp, KeyReadCompletion, DeviceObject, TRUE, TRUE, TRUE ); 
	return IoCallDriver( KeyExtension->TargetDevice, Irp );
} 

/////////////////////////////////////////////////////////////////
// 函数类型 :系统回调函数
// 函数模块 : 键盘过滤模块
////////////////////////////////////////////////////////////////
// 功能 : 获得键盘按键,用无效扫描码替换,以达到屏蔽键盘的目的
/////////////////////////////////////////////////////////////////

NTSTATUS KeyReadCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context )
{
	
	PIO_STACK_LOCATION IrpSp;
	PKEYBOARD_INPUT_DATA KeyData;	
	PDEVICE_EXTENSION KeyExtension = ( PDEVICE_EXTENSION )DeviceObject->DeviceExtension; 
	int numKeys, i;
	KIRQL IrqLevel;
	
	IrpSp = IoGetCurrentIrpStackLocation( Irp );

	if ( Irp->IoStatus.Status != STATUS_SUCCESS )
	{
		KdPrint( ( "ntStatus:0x%x", Irp->IoStatus.Status ) );
		goto __RoutineEnd;
	}

	//
	// 系统在 SystemBuffer 中保存按键信息
	//
	KeyData = Irp->AssociatedIrp.SystemBuffer;
	if ( KeyData == NULL )
	{
		KdPrint( ( "KeyData is NULL.\r\n" ) );
		goto __RoutineEnd;
	}

	//
	// 得到按键数
	//
	numKeys = (int)(Irp->IoStatus.Information / sizeof( KEYBOARD_INPUT_DATA ));
	if ( numKeys < 0 )
	{
		KdPrint( ( "numKeys less zero.\r\n" ) );
		goto __RoutineEnd;
	}

	//
	// 使用 0 无效扫描码替换,屏蔽预定义的按键
	//
	for ( i = 0; i < numKeys; i++ )
	{
		if( g_bDisableKbd )
		{
			if ( IsFilterKey( KeyData[i].MakeCode ) )
			{
				KdPrint( ( "This key [0x%02x] is disabled.\r\n", KeyData[i].MakeCode ) );
				KeyData[i].MakeCode = 0;
			}
			else
			{
				KdPrint( ( "Key - ScanCode[0x%02x].\r\n", KeyData[i].MakeCode ) );
			}
		}
	}
__RoutineEnd : 

	if ( Irp->PendingReturned )
	{
		IoMarkIrpPending( Irp );
	} 
	//
	// 将 IRP 计数器减一,为支持 SMP 使用自旋锁
	//
	KeAcquireSpinLock( &KeyExtension->SpinLock, &IrqLevel );
	InterlockedDecrement( &KeyExtension->IrpsInProgress );
	KeReleaseSpinLock( &KeyExtension->SpinLock, IrqLevel );

	return Irp->IoStatus.Status ;
} 

NTSTATUS DispatchCreate(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	UNREFERENCED_PARAMETER(pDevObj);
	UNREFERENCED_PARAMETER(pIrp);
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	KdPrint( ("[Driver] IRP_MJ_CREATE.\r\n") );
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}

NTSTATUS DispatchClose(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	UNREFERENCED_PARAMETER(pDevObj);
	UNREFERENCED_PARAMETER(pIrp);
	pIrp->IoStatus.Status = STATUS_SUCCESS;
	pIrp->IoStatus.Information = 0;
	KdPrint( ("[Driver] IRP_MJ_CLOSE.\r\n") );
	IoCompleteRequest(pIrp, IO_NO_INCREMENT);
	return STATUS_SUCCESS;
}


NTSTATUS DispatchIoctl(PDEVICE_OBJECT pDevObj, PIRP pIrp)
{
	PIO_STACK_LOCATION pIrpStack;
	ULONG uIoControlCode;
	ULONG uOutSize;

	UNREFERENCED_PARAMETER(pDevObj);

	pIrpStack = IoGetCurrentIrpStackLocation(pIrp);
	uIoControlCode = pIrpStack->Parameters.DeviceIoControl.IoControlCode;

	switch(uIoControlCode)
	{
	case IOCTL_ENABLE_KBD:
		{
			KdPrint( ("Keyboard enable.\r\n") );
			g_bDisableKbd = FALSE;
			break;
		}
	case IOCTL_DISABLE_KBD:
		{
			KdPrint( ("Keyboard disable.\r\n") );
			g_bDisableKbd = TRUE;
			break;
		}
	}
	return STATUS_SUCCESS;
}



// 返回 TRUE 表示过滤此 key 
BOOLEAN IsFilterKey( USHORT uMakeCode )
{
	USHORT uKeys = sizeof(gAllowedKeyArr) / sizeof(gAllowedKeyArr[0]);
	USHORT i = 0;
	for ( i = 0; i < uKeys; i++ )
	{
		if ( uMakeCode == gAllowedKeyArr[i] )
		{
			return FALSE;
		}
	}
	return TRUE;
}

[培训]内核驱动高级班,冲击BAT一流互联网大厂工作,每周日13:00-18:00直播授课

上传的附件:
收藏
免费 0
支持
分享
最新回复 (3)
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
2
都是下载附件看,然后没有回复了。。。求解决啊,谢谢
2014-5-7 11:45
0
雪    币: 1
活跃值: (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
3
此贴终结。。
2014-5-7 18:07
0
雪    币: 53
活跃值: (42)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
4
解决了吗?我以前遇到过IRP还在传递结束停止不了驱动
2014-5-9 16:16
0
游客
登录 | 注册 方可回帖
返回
//