写的键盘驱动都是抄袭网上的,做了一点小修改,只是为了屏蔽特定按键。通过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直播授课