[写得很乱,不想再写了,原来的意思是想用界面控制驱动,动态替换按键,[因为有些键盘坏了,有些键不能用,比如wsx这几个键,暂时没好键盘,按虚拟键又麻烦的情况下,更改上面的FX键换它。]
差不多完成。。。链表及替换未写,这个很快就可以实现了,链表初始化分配内存,并把应用层(应用层里已把char转成ushort数组存在缓冲区中。格式1E 10 ...)的扫描码保存到结构中,就OK了。不过这样通迅好麻烦。
具体过程:先在DriverEntry入口函数把MJ的数组指向是生成一个新的设备[不是过滤设备]的各种分发函数,有设备名,还有MJ里设置控制IO的API,然后在应用层把扫描码要替换扫描码这种格式填上,点OK就发送到设备中,然后在这个设备的CONTROL IRP里创建一个新的设备,这个设备就是用来过滤键盘的设备。并更改driver里的分发函数地址成为有过滤后的IRP。卸载的话要判断是否是过滤设备。从而分开删除。
键盘过滤暂时到此,,,下一步不知是先看进程方面还是文件驱动。。
驱动代码:
#include <ntddk.h>
#include <ntddkbd.h>
#include <windef.h>
#include "control.h"
typedef struct _MY_LIST
{
USHORT uyMakeCode;//原来的扫描码
USHORT uhMakeCode;//替换后的扫描码
LIST_ENTRY ListEntry; //
}MY_LIST,*PMY_LIST;
typedef struct _FILTER_DEVICE_EXTEN
{
BOOL FilterFlags;
PDEVICE_OBJECT pFilterDeviceObject;//过滤设备
PDEVICE_OBJECT pTagerDeviceObject;//要绑定的设备对象
PDEVICE_OBJECT pLowDeviceObject;//绑定之后的下一个设备,在过滤设备下面
// KSPIN_LOCK Lockspin;//调用时的保护锁
// KEVENT ProcessEvent;//进程间同步
UNICODE_STRING DeviceSymoblic;
LIST_ENTRY ListHead;//list table head
}FILTER_DEVICE_EXTEN,*PFILTER_DEVICE_EXTEN;
ULONG gC2pKeyCount = 0;
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING puServiceRegPath);
VOID FilterUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS AllIrpOther(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);
NTSTATUS FilterPower(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);//IRP_MJ_POWER要调用一个PoCallDriver与PoStartNextPowerIrp
NTSTATUS FilterPnp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);//IRP_MJ_PNP还要一个PNP(即插即用)分发函数
NTSTATUS AttachDeviceObject(PDRIVER_OBJECT pDriverObject,PDEVICE_OBJECT *pOutDeviceObject);
NTSTATUS FilterReadIrp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);//read irp
NTSTATUS FilterCompletionRoutine(IN PDEVICE_OBJECT pCRDeviceObject,IN PIRP pCRIrp,IN PVOID Context);
NTSTATUS DeviceControlIrp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);//control irp
NTSTATUS TestCreateDevice(IN PDRIVER_OBJECT pDriverObject);
VOID TestUnload(IN PDRIVER_OBJECT pDriverObject);
VOID OkTestUnload(IN PDRIVER_OBJECT pDriverObject);
NTSTATUS TestCreate(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp);
#pragma alloc_text (INIT, DriverEntry)
#pragma alloc_text (PAGE, FilterUnload)
#pragma alloc_text (PAGE, AllIrpOther)
#pragma alloc_text (PAGE, FilterPower)
#pragma alloc_text (PAGE, FilterPnp)
#pragma alloc_text (INIT, AttachDeviceObject)
#pragma alloc_text (PAGE, FilterReadIrp)
#pragma alloc_text (PAGE, FilterCompletionRoutine)
#pragma alloc_text (PAGE, DeviceControlIrp)
#pragma alloc_text (INIT, TestCreateDevice)
#pragma alloc_text (PAGE, TestUnload)
#pragma alloc_text (PAGE, OkTestUnload)
#pragma alloc_text (PAGE, TestCreate)
NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,IN PUNICODE_STRING puServiceRegPath)
{
// NTSTATUS status=STATUS_SUCCESS;
// int i;
// for (i=0;i<IRP_MJ_MAXIMUM_FUNCTION+1;i++)
// {
// pDriverObject->MajorFunction[i]=AllIrpOther;
// }
// pDriverObject->DriverUnload=FilterUnload;//卸载函数
// pDriverObject->MajorFunction[IRP_MJ_POWER]=FilterPower;
// pDriverObject->MajorFunction[IRP_MJ_PNP]=FilterPnp;
// pDriverObject->MajorFunction[IRP_MJ_READ]=FilterReadIrp;
pDriverObject->MajorFunction[IRP_MJ_CREATE]=TestCreate;
pDriverObject->DriverUnload=TestUnload;//卸载函数
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL]=DeviceControlIrp;
// return AttachDeviceObject(pDriverObject);
return TestCreateDevice(pDriverObject);
}
/************************************************************************/
/* 其它直接用IoCallDriver把IRP传到下一层驱动中 */
/************************************************************************/
NTSTATUS AllIrpOther(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
PFILTER_DEVICE_EXTEN pFilterExten;
KdPrint(("Other IRP!\n"));
pFilterExten=(PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
IoSkipCurrentIrpStackLocation(pIrp);
return IoCallDriver(pFilterExten->pTagerDeviceObject,pIrp);
}
/************************************************************************/
/*生成过滤设备并绑定键盘设备及保存各种设备地址在扩展设备中 */
/************************************************************************/
NTSTATUS AttachDeviceObject(PDRIVER_OBJECT pDriverObject,PDEVICE_OBJECT *pOutDeviceObject)
{
NTSTATUS status;
UNICODE_STRING uKbdKeyName,DeviceName,DeviceSysmbolic;
PFILTER_DEVICE_EXTEN pFilterExten;
PDEVICE_OBJECT pFilterDevice;
PDEVICE_OBJECT pTargetDevice;
PDEVICE_OBJECT pLowDevice;
PFILE_OBJECT pFileOb;
RtlInitUnicodeString(&DeviceName,L"");
RtlInitUnicodeString(&DeviceSysmbolic,L"");
RtlInitUnicodeString(&uKbdKeyName, L"");
status=IoGetDeviceObjectPointer(&uKbdKeyName,FILE_ALL_ACCESS,&pFileOb,&pTargetDevice);
if (!NT_SUCCESS(status))
{
KdPrint(("Get Keyboard Error !\n"));
return status;
} else
{
ObDereferenceObject(pFileOb);//成功 根据设备名得到设备对象指针及文件对象指针
// IoDeleteDevice(pTargetDevice);
}
//pFileOb->DeviceObject 这个才是真正想要的设备对象地址
status=IoCreateDevice(pDriverObject,
sizeof(FILTER_DEVICE_EXTEN),
&DeviceName,
pTargetDevice->Type,
pTargetDevice->Characteristics,
TRUE,
&pFilterDevice);
if (!NT_SUCCESS(status))
{
KdPrint(("Create Error\n"));
// ObDereferenceObject(pFileOb);
IoDeleteDevice(pTargetDevice);
return status;
}
status=IoCreateSymbolicLink(&DeviceSysmbolic,&DeviceName);
if (!NT_SUCCESS(status))
{
KdPrint(("Create Symbolic Error\n"));
IoDeleteDevice(pFilterDevice);
// ObDereferenceObject(pFileOb);
IoDeleteDevice(pTargetDevice);
return status;
}
pLowDevice=IoAttachDeviceToDeviceStack(pFilterDevice,pTargetDevice);
if (!pLowDevice)
{
KdPrint(("Create Attach Error\n"));
IoDeleteSymbolicLink(&DeviceSysmbolic);
IoDeleteDevice(pFilterDevice);
// ObDereferenceObject(pFileOb);
IoDeleteDevice(pTargetDevice);
return STATUS_UNSUCCESSFUL;
}
pFilterExten=(PFILTER_DEVICE_EXTEN)pFilterDevice->DeviceExtension;
RtlZeroMemory(pFilterExten,sizeof(FILTER_DEVICE_EXTEN));//zero memory
pFilterExten->pFilterDeviceObject=pFilterDevice;
pFilterExten->pTagerDeviceObject=pTargetDevice;
pFilterExten->DeviceSymoblic=DeviceSysmbolic;
pFilterExten->pLowDeviceObject=pLowDevice;
pFilterExten->FilterFlags=TRUE;//TRUE表示是过滤设备 FALSE表示控制设备
pFilterDevice->DeviceType=pLowDevice->DeviceType;
pFilterDevice->Characteristics=pLowDevice->Characteristics;
pFilterDevice->StackSize=pLowDevice->StackSize+1;
pFilterDevice->Flags |= pLowDevice->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE) ;
*pOutDeviceObject=pFilterDevice;//把生成的设备对象指针保存
return STATUS_SUCCESS;
}
/************************************************************************/
/* IRP_MJ_POWER */
/************************************************************************/
NTSTATUS FilterPower(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
PFILTER_DEVICE_EXTEN pFilterExten;
pFilterExten =(PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
PoStartNextPowerIrp( pIrp );
IoSkipCurrentIrpStackLocation( pIrp );
return PoCallDriver(pFilterExten->pLowDeviceObject, pIrp );
}
/************************************************************************/
/* IRP_MJ_PNP */
/************************************************************************/
NTSTATUS FilterPnp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
PFILTER_DEVICE_EXTEN pFilterExten;
PIO_STACK_LOCATION irpStack;
NTSTATUS status = STATUS_SUCCESS;
// 获得真实设备。
pFilterExten = (PFILTER_DEVICE_EXTEN)(pDeviceObject->DeviceExtension);
irpStack = IoGetCurrentIrpStackLocation(pIrp);
switch (irpStack->MinorFunction)
{
case IRP_MN_REMOVE_DEVICE:
KdPrint(("IRP_MN_REMOVE_DEVICE\n"));
// 首先把请求发下去
IoSkipCurrentIrpStackLocation(pIrp);
IoCallDriver(pFilterExten->pLowDeviceObject, pIrp);
// 然后解除绑定。
IoDetachDevice(pFilterExten->pLowDeviceObject);
// 删除我们自己生成的虚拟设备。
IoDeleteDevice(pDeviceObject);
status = STATUS_SUCCESS;
break;
default:
// 对于其他类型的IRP,全部都直接下发即可。
IoSkipCurrentIrpStackLocation(pIrp);
status = IoCallDriver(pFilterExten->pLowDeviceObject, pIrp);
}
return status;
}
/************************************************************************/
/* UnLoad */
/************************************************************************/
VOID FilterUnload(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pDeviceObject;
PDEVICE_OBJECT OldDeviceObject;
PFILTER_DEVICE_EXTEN pFilterExten;
LARGE_INTEGER lDelay;
PKTHREAD CurrentThread;
//delay some time
lDelay = RtlConvertLongToLargeInteger(-1000000);
CurrentThread = KeGetCurrentThread();
// 把当前线程设置为低实时模式,以便让它的运行尽量少影响其他程序。
KeSetPriorityThread(CurrentThread, LOW_REALTIME_PRIORITY);
UNREFERENCED_PARAMETER(pDriverObject);
KdPrint(("DriverEntry unLoading...\n"));
pDeviceObject = pDriverObject->DeviceObject;//从驱动对象得到{dy}个设备对象
while (pDeviceObject)//pDeviceObject is not NULL
{
pFilterExten=(PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
if (pFilterExten->FilterFlags)//filter device object
{
IoDeleteSymbolicLink(&pFilterExten->DeviceSymoblic);
IoDetachDevice(pFilterExten->pLowDeviceObject); //过滤驱动要删除绑定
pDeviceObject=pDeviceObject->NextDevice;
IoDeleteDevice(pFilterExten->pFilterDeviceObject);
} else
{
IoDeleteSymbolicLink(&pFilterExten->DeviceSymoblic);
pDeviceObject=pDeviceObject->NextDevice;
IoDeleteDevice(pFilterExten->pFilterDeviceObject);
}
}
while (gC2pKeyCount)
{
KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
}
KdPrint(("DriverEntry unLoad OK!\n"));
return;
}
/************************************************************************/
/* read irp */
/************************************************************************/
NTSTATUS FilterReadIrp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
NTSTATUS status;
PFILTER_DEVICE_EXTEN pFilterExten;
//PIO_STACK_LOCATION currentIrpStack;
// KEVENT waitEvent;
status= STATUS_SUCCESS;
// KeInitializeEvent( &waitEvent, NotificationEvent, FALSE );
if (pIrp->CurrentLocation == 1)
{
KdPrint(("Dispatch encountered bogus current location\n"));
status = STATUS_INVALID_DEVICE_REQUEST;
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest(pIrp, IO_NO_INCREMENT);
return(status);
}
// 全局变量键计数器加1
gC2pKeyCount++;
// 得到设备扩展。目的是之后为了获得下一个设备的指针。
pFilterExten=(PFILTER_DEVICE_EXTEN)pDeviceObject->DeviceExtension;
// 设置回调函数并把IRP传递下去。 之后读的处理也就结束了。
// 剩下的任务是要等待读请求完成。
//currentIrpStack = IoGetCurrentIrpStackLocation(pIrp);
IoCopyCurrentIrpStackLocationToNext(pIrp);
IoSetCompletionRoutine( pIrp, FilterCompletionRoutine,
pDeviceObject, TRUE, TRUE, TRUE );
return IoCallDriver( pFilterExten->pLowDeviceObject, pIrp );
}
NTSTATUS FilterCompletionRoutine(IN PDEVICE_OBJECT pCRDeviceObject,IN PIRP pCRIrp,IN PVOID Context)
{
PIO_STACK_LOCATION IrpSp;
ULONG buf_len;
PUCHAR buf;
size_t i,numKeys;
PKEYBOARD_INPUT_DATA KeyData;
buf = NULL;
buf_len = 0;
IrpSp = IoGetCurrentIrpStackLocation( pCRIrp );
// 如果这个请求是成功的。很显然,如果请求失败了,这么获取
// 进一步的信息是没意义的。
if( NT_SUCCESS( pCRIrp->IoStatus.Status ) )
{
// 获得读请求完成后输出的缓冲区
buf = pCRIrp->AssociatedIrp.SystemBuffer;
KeyData = (PKEYBOARD_INPUT_DATA)buf;
// 获得这个缓冲区的长度。一般的说返回值有多长都保存在
// Information中。
buf_len = pCRIrp->IoStatus.Information;
numKeys = buf_len / sizeof(KEYBOARD_INPUT_DATA);
//… 这里可以做进一步的处理。我这里很简单的打印出所有的扫
// 描码。
//for(i=0;i<buf_len;++i)
for(i=0;i<numKeys;++i)
{
if (KeyData[i].Flags)
{
DbgPrint("ScanCode: %x ", KeyData[i].MakeCode );
}
if (KeyData[i].MakeCode==0x43)
{
KeyData[i].MakeCode=0x10;
}
}
}
gC2pKeyCount--;
if( pCRIrp->PendingReturned )
{
IoMarkIrpPending( pCRIrp );
}
return pCRIrp->IoStatus.Status;
}
NTSTATUS DeviceControlIrp(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
NTSTATUS status;
PIO_STACK_LOCATION pIoStackLocation;
ULONG uControlCode,uInBufferLength;
PCHAR pInBufferChar;
PUSHORT pUshort;
PDRIVER_OBJECT pDriverObject;
PDEVICE_OBJECT pOutFilterObject;
int i;
status=STATUS_SUCCESS;
pIoStackLocation=IoGetCurrentIrpStackLocation(pIrp);//get IO_STACK_LOCATION
uControlCode=pIoStackLocation->Parameters.DeviceIoControl.IoControlCode;//get controlcode
uInBufferLength=pIoStackLocation->Parameters.DeviceIoControl.InputBufferLength;//get in buffer length
switch(uControlCode)
{
case CTIO_EXE_SYS:
{
pUshort=(PUSHORT)pIrp->AssociatedIrp.SystemBuffer;
// pDeviceObject->DriverObject->DriverUnload=OkTestUnload;//更改驱动的卸载函数
// pDeviceObject->DriverObject->MajorFunction[IRP_MJ_CLOSE]=TestCreate;
while (*pUshort)
{
KdPrint(("%x\n",*pUshort));
pUshort++;
}
pDriverObject=pDeviceObject->DriverObject; //driver object
status=AttachDeviceObject(pDriverObject,&pOutFilterObject);
if (!NT_SUCCESS(status))
{
KdPrint(("Device Io Control AttachDevice Error !\n"));
break;//exit switch
}
/////////////////////////////////////////////////////////////////////////////
// for (i=0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
// {
// pDeviceObject->DriverObject->MajorFunction[i]=AllIrpOther;
// }
pDeviceObject->DriverObject->DriverUnload=FilterUnload;//卸载函数
pDeviceObject->DriverObject->MajorFunction[IRP_MJ_POWER]=FilterPower;
pDeviceObject->DriverObject->MajorFunction[IRP_MJ_PNP]=FilterPnp;
pDeviceObject->DriverObject->MajorFunction[IRP_MJ_READ]=FilterReadIrp;
/////////////////////////////////////////////////////////////////////////////
break;//exit switch
}
default:
status = STATUS_INVALID_VARIANT;
}
pIrp->IoStatus.Status = status;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return status;
}
VOID TestUnload(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pUnloadDevice;
PFILTER_DEVICE_EXTEN pUnloadExten;
KdPrint(("Unload \n"));
pUnloadDevice=pDriverObject->DeviceObject;
while (pUnloadDevice)
{
pUnloadExten=(PFILTER_DEVICE_EXTEN)pUnloadDevice->DeviceExtension;
IoDeleteSymbolicLink(&pUnloadExten->DeviceSymoblic);
pUnloadDevice=pUnloadDevice->NextDevice;
IoDeleteDevice(pUnloadExten->pFilterDeviceObject);
}
}
VOID OkTestUnload(IN PDRIVER_OBJECT pDriverObject)
{
PDEVICE_OBJECT pUnloadDevice;
PFILTER_DEVICE_EXTEN pUnloadExten;
KdPrint(("ok test Unload \n"));
pUnloadDevice=pDriverObject->DeviceObject;
while (pUnloadDevice)
{
pUnloadExten=(PFILTER_DEVICE_EXTEN)pUnloadDevice->DeviceExtension;
IoDeleteSymbolicLink(&pUnloadExten->DeviceSymoblic);
pUnloadDevice=pUnloadDevice->NextDevice;
IoDeleteDevice(pUnloadExten->pFilterDeviceObject);
}
}
NTSTATUS TestCreateDevice(IN PDRIVER_OBJECT pDriverObject)
{
NTSTATUS status;
PDEVICE_OBJECT pcDeviceObject;
PFILTER_DEVICE_EXTEN pDeviceExten;
UNICODE_STRING ucDeviceName,usDeviceSymbolic;
RtlInitUnicodeString(&ucDeviceName,L"");
RtlInitUnicodeString(&usDeviceSymbolic,L"");
status=IoCreateDevice(pDriverObject,sizeof(FILTER_DEVICE_EXTEN),&ucDeviceName,
FILE_DEVICE_UNKNOWN,0,FALSE,&pcDeviceObject);
if (!NT_SUCCESS(status))
{
KdPrint(("create error\n"));
return status;
}
status=IoCreateSymbolicLink(&usDeviceSymbolic,&ucDeviceName);
if (!NT_SUCCESS(status))
{
KdPrint(("create symbolic error\n"));
IoDeleteDevice(pcDeviceObject);
return status;
}
pDeviceExten=(PFILTER_DEVICE_EXTEN)pcDeviceObject->DeviceExtension;
RtlZeroMemory(pDeviceExten,sizeof(FILTER_DEVICE_EXTEN));
pDeviceExten->DeviceSymoblic=usDeviceSymbolic;
pDeviceExten->pFilterDeviceObject=pcDeviceObject;
pDeviceExten->FilterFlags=FALSE;
pcDeviceObject->Flags |= DO_BUFFERED_IO;
return status;
}
NTSTATUS TestCreate(IN PDEVICE_OBJECT pDeviceObject,IN PIRP pIrp)
{
KdPrint(("Create\n"));
pIrp->IoStatus.Status = STATUS_SUCCESS;
pIrp->IoStatus.Information = 0;
IoCompleteRequest( pIrp, IO_NO_INCREMENT );
return pIrp->IoStatus.Status;
}
应用层代码:
按钮button
void CAppppDlg::OnButton1()
{
// TODO: Add your control notification handler code here
CString str;
GetDlgItemText(IDC_EDIT1,str);
char *pBuffer = (LPTSTR)(LPCTSTR)str;
int i=strlen(pBuffer);
int ilen=sizeof(USHORT)*(i+2);
PUSHORT pMenp=(PUSHORT)malloc(ilen);
memset(pMenp,0,i+2);
_asm
{
xor eax,eax
mov edx,0
mov ebx,1//标志
mov esi,[pBuffer] //字符串地址
mov edi,[pMenp] //要写入的目的地址
mov ecx,0
comstart:
mov al,BYTE PTR [esi]
cmp al,41h
jge completesm
cmp al,39h
jle completenum
completesm:
cmp al,46h
jle comsmok
completenum:
cmp al,30h
jge comnumok
comnumok:
sub al,30h
cmp ebx,1
jz editnumok
or al,dl //高位与低位相或结果放在al中
mov BYTE PTR [edi],al
add edi,2
inc esi
inc ebx
inc ecx
cmp ecx,i
jz exitloop
jmp comstart
comsmok:
sub al,41h
add al,10 //这里转为十六进制
cmp ebx,1
jz editsmok
or al,dl //高位与低位相或结果放在al中
mov BYTE PTR [edi],al
add edi,2
inc esi
inc ebx
inc ecx
cmp ecx,i
jz exitloop
jmp comstart
editnumok:
mov dl,al
shl dl,4
inc esi
dec ebx
inc ecx
cmp ecx,i
jz exitloop
jmp comstart
editsmok:
mov dl,al
shl dl,4
inc esi
dec ebx
inc ecx
cmp ecx,i
jz exitloop
jmp comstart
exitloop:
}
HANDLE hFile=CreateFile("",
GENERIC_READ | GENERIC_WRITE,
0,
NULL,
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL );
if (hFile == INVALID_HANDLE_VALUE)
{
char *outformat="%d";
char outnum[4];
wsprintfA(outnum,outformat,GetLastError());
::MessageBox(NULL,outnum,outnum,0);
return;
}
DWORD dwOutput;
DeviceIoControl(hFile,
CTIO_EXE_SYS,
pMenp,
ilen,
NULL,
0,
&dwOutput,
NULL);
CloseHandle(hFile);
free(pMenp);
}