近来在学驱动开发,自己写了一个简单地驱动程序,截取键盘按键,另外写的应用程序会显示按键。下面是驱动部分的关键代码,完整代码点击:猛戳这里
/**************************************************************/
#include "KeyFilter.h"
/************************************************************************
* 函数名称:DriverEntry
* 功能描述:初始化驱动程序,定位和申请硬件资源,创建内核对象
* 参数列表:
pDriverObject:从I/O管理器中传进来的驱动对象
pRegistryPath:驱动程序在注册表的中的路径
* 返回 值:返回初始化驱动状态
*************************************************************************/
#pragma INITCODE
extern "C" NTSTATUS DriverEntry(IN PDRIVER_OBJECT pDriverObject,
IN PUNICODE_STRING pRegistryPath)
{
KdPrint(("Enter DriverEntry\n"));
pDriverObject->DriverExtension->AddDevice = KeyFilterAddDevice;
pDriverObject->MajorFunction[IRP_MJ_PNP] = KeyFilterPnp;
pDriverObject->MajorFunction[IRP_MJ_DEVICE_CONTROL] = KeyFilterDeviceIoCtl;
pDriverObject->MajorFunction[IRP_MJ_CREATE] = KeyFilterDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_CLOSE] = KeyFilterDispatchRoutine;
pDriverObject->MajorFunction[IRP_MJ_READ] = KeyFilterRead;
pDriverObject->MajorFunction[IRP_MJ_WRITE] = KeyFilterDispatchRoutine;
pDriverObject->DriverUnload = KeyFilterUnload;
pDriverObject->DriverStartIo = KeyFilterStartIO;
KdPrint(("Leave DriverEntry\n"));
return STATUS_SUCCESS;
}
/************************************************************************
* 函数名称:KeyFilterAddDevice
* 功能描述:添加新设备
* 参数列表:
DriverObject:从I/O管理器中传进来的驱动对象
PhysicalDeviceObject:从I/O管理器中传进来的物理设备对象
* 返回 值:返回添加新设备状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS KeyFilterAddDevice(IN PDRIVER_OBJECT DriverObject,
IN PDEVICE_OBJECT PhysicalDeviceObject)
{
PAGED_CODE();
_asm int 3;
NTSTATUS status;
PDEVICE_OBJECT PDeviceObject;
UNICODE_STRING strnum;
UNICODE_STRING devName;
UNICODE_STRING kbdclassname;
UNICODE_STRING symLinkName;
//PDRIVER_OBJECT kbdDriver;
PDEVICE_OBJECT kbdDevice;
int index = 0;
PDEVICE_EXTENSION pdx;
WCHAR DevnameBase[100] = L"\\Device\\KeyFilterDevice";
KdPrint(("Enter KeyFilterAddDevice\n"));
//
PFILE_OBJECT FileObject = NULL;
RtlInitUnicodeString(&kbdclassname,L"\\Device\\KeyboardClass0");
//通过classname得到设备对象
status = IoGetDeviceObjectPointer(&kbdclassname,FILE_ALL_ACCESS,&FileObject,&kbdDevice);
if (!NT_SUCCESS(status))
{
KdPrint(("ObReferenceObjectByName error,0x%x\n",status));
return status;
}
do{
RtlInitUnicodeString(&strnum,L"strnum");
RtlIntegerToUnicodeString(index,10,&strnum);
RtlInitUnicodeString(&devName,DevnameBase);
RtlAppendUnicodeStringToString(&devName,&strnum);
//创建设备
status = IoCreateDevice(
DriverObject,
sizeof(DEVICE_EXTENSION),
&devName,
kbdDevice->DeviceType,
kbdDevice->Characteristics,
FALSE,
&PDeviceObject);
if( !NT_SUCCESS(status))
break;
pdx = (PDEVICE_EXTENSION)PDeviceObject->DeviceExtension;
pdx->NextStackDevice = IoAttachDeviceToDeviceStack(PDeviceObject, kbdDevice);
if (pdx->NextStackDevice == NULL)
{
KdPrint(("IoAttachDeviceToDeviceStack failed,error = %x\n",status));
IoDeleteDevice( PDeviceObject );
break;
}
pdx->PDeviceObject = PDeviceObject;
//创建符号链接
RtlInitUnicodeString(&symLinkName,L"\\??\\KeyFilterSymLinkName");
RtlAppendUnicodeStringToString(&symLinkName,&strnum);
status = IoCreateSymbolicLink(&symLinkName,&devName);
if( !NT_SUCCESS(status))
{
IoDeleteSymbolicLink(&pdx->ustrSymLinkName);
break;
}
//保存设备名和符号链接名
RtlCopyUnicodeString(&pdx->ustrDeviceName,&devName);
RtlCopyUnicodeString(&pdx->ustrSymLinkName,&symLinkName);
PDeviceObject->Flags |= kbdDevice->Flags & (DO_BUFFERED_IO | DO_POWER_PAGABLE);
PDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;//将Flag上的DO_DEVICE_INITIALIZING位清零,保证设备初始化完毕,必须的。
}while(FALSE);
ObDereferenceObject(FileObject);
ObDereferenceObject(kbdDevice);
//初始化自旋锁
KeInitializeSpinLock(&pdx->ListSpinLock);
//初始化链表
InitializeListHead(&pdx->linkListHead);
KdPrint(("Leave KeyFilterAddDevice\n"));
return STATUS_SUCCESS;
}
#pragma PAGEDCODE
void KeyFilterCancelIRP(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
KdPrint(("Enter HelloWDMOnCancelIRP\n"));
if (Irp == fdo->CurrentIrp)
{
KIRQL oldirql = Irp->CancelIrql;
//释放cancel自旋锁
IoReleaseCancelSpinLock(Irp->CancelIrql);
//继续下一个IRP
IoStartNextPacket(fdo, TRUE);
//降低IRQL
KeLowerIrql(oldirql);
}
else
{//还没有被执行,还在队列中
KeRemoveEntryDeviceQueue(&fdo->DeviceQueue, &Irp->Tail.Overlay.DeviceQueueEntry);
//释放cancel自旋锁
IoReleaseCancelSpinLock(Irp->CancelIrql);
}
Irp->IoStatus.Status = STATUS_CANCELLED;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
KdPrint(("Leave HelloWDMOnCancelIRP\n"));
}
//************************************
// Method: KeyFilterDeviceIoCtlStartio
// Qualifier: IRP_MJ_DEVICE_CONTROL 处理函数
//************************************
NTSTATUS KeyFilterDeviceIoCtlStartio(IN PDEVICE_OBJECT fdo,IN PIRP Irp)
{
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
NTSTATUS status = STATUS_SUCCESS;
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
ULONG readLen = stack->Parameters.Read.Length;
PDEVICE_EXTENSION pDevExt = (PDEVICE_EXTENSION)fdo->DeviceExtension;
KdPrint(("++++++enter KeyFilterDeviceIoCtlStartio\n"));
switch (code)
{
case IOCTL_SHOWKEYFILTER:
KdPrint(("IOCTL_SHOWKEYFILTER KeyFilterDeviceIoCtlStartio\n"));
if (IsListEmpty(&pDevExt->linkListHead))//队列为空,完成irp
{
KdPrint(("list is empty.\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0;
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
else//队列中有数据,取出数据
{
KdPrint(("list have data\n"));
PLIST_ENTRY pEntry;
PMYDATASTRUCT pData;
memset(Irp->AssociatedIrp.SystemBuffer,0,readLen);
int index = 0;
USHORT buffer[MAX_KEY_COUNT*2] = {0};
//获取自旋锁
KIRQL oldIrql;
KeAcquireSpinLock(&pDevExt->ListSpinLock,&oldIrql);
KdPrint(("******>> DeviceIoCtlStartio spinlock\n"));
//取出链表中数据
while(!IsListEmpty(&pDevExt->linkListHead))
{
pEntry = RemoveTailList(&pDevExt->linkListHead);
pData = CONTAINING_RECORD(pEntry,MYDATASTRUCT,ListEntry);
buffer[index] = pData->ScanCode;
buffer[index+1] = pData->Flags;
index += 2;
}
KeReleaseSpinLock(&pDevExt->ListSpinLock,oldIrql);
KdPrint(("<<****** DeviceIoCtlStartio spinlock\n"));
KdPrint(("+++++++++ list count is %d\n",index/2));
//将取出的数据写入输出buffer
RtlCopyMemory(Irp->AssociatedIrp.SystemBuffer,(void *)buffer,sizeof(USHORT)*index);
ExFreePool(pData);
//完成irp
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = index*sizeof(USHORT);
IoCompleteRequest(Irp, IO_NO_INCREMENT);
}
break;
default:
KeyFilterDispatchRoutine(fdo,Irp);
}
KdPrint(("++++++leave KeyFilterDeviceIoCtlStartio\n"));
return Irp->IoStatus.Status;
}
#pragma LOCKEDCODE
//************************************
// Method: KeyFilterStartIO
// Qualifier: startio函数
//************************************
void KeyFilterStartIO(IN PDEVICE_OBJECT fdo, IN PIRP Irp)
{
KIRQL oldirql;
KdPrint(("++++++Enter KeyFilterStartIO, IRP address\n"));
//自旋锁会将当前运行级别提高到DISPATCH_LEVEL,驱动程序如果想调用IoSetCancelRoutine,那么就得先获取这个lock,具体参考
//http://msdn.microsoft.com/en-us/library/windows/hardware/ff548196(v=vs.85).aspx
IoAcquireCancelSpinLock(&oldirql);
//fdo->CurrentIrp就是驱动当前正在处理的IRP。
if (Irp != fdo->CurrentIrp || Irp->Cancel)
{//如果Irp不是当前处理的IRP,或者这个Irp是想取消的,那么直接返回,啥也不做。
IoReleaseCancelSpinLock(oldirql);
KdPrint(("Do nothing\n"));
return;
}
else
{//正在处理该IRP
KdPrint(("Forbit to use CancelRoutine\n"));
IoSetCancelRoutine(Irp, NULL);//不允许调用取消例程
IoReleaseCancelSpinLock(oldirql);
}
//可以根据需要处理IRP
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
if (stack->MajorFunction == IRP_MJ_READ)//读请求
{
KeyFilterReadStartio(fdo,Irp);
}
else if (stack->MajorFunction == IRP_MJ_DEVICE_CONTROL )//DEVICE_CONTROL
{
KeyFilterDeviceIoCtlStartio(fdo,Irp);
}
else//其他请求
{
KeyFilterDispatchRoutine(fdo,Irp);
}
//在队列中读取下一个IRP,并且进行StartIO.
IoStartNextPacket(fdo, TRUE);
KdPrint(("++++++Leave KeyFilterStartIO, IRP address: 0x%x\n", Irp));
}
//************************************
// Method: KeyFilterRead
// Qualifier: 读派遣函数
// Parameter: IN PDEVICE_OBJECT fdo 设备对象
// Parameter: IN PIRP Irp IO请求包
//************************************
NTSTATUS KeyFilterRead(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
NTSTATUS status = STATUS_PENDING;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoMarkIrpPending(Irp);//将IRP设置为挂起状态(异步IRP)
KdPrint(("start to call IoStartPacket, IRP\n"));
IoStartPacket(fdo, Irp, 0, KeyFilterCancelIRP);
KdPrint(("end call IoStartPacket, IRP\n"));
return status;
}
#pragma LOCKEDCODE
//************************************
// Method: KeyFilterReadCompletion
// Qualifier: 读完成回调函数
//************************************
NTSTATUS KeyFilterReadCompletion(PDEVICE_OBJECT fdo,PIRP Irp,PVOID Context)
{
KdPrint(("enter KeyFilterReadCompletion\n"));
PKEYBOARD_INPUT_DATA KeyData;
int KeyNum;
//得到设备扩展
PDEVICE_EXTENSION pDeviceExtension = (PDEVICE_EXTENSION)fdo->DeviceExtension;
//得到当前堆栈
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
//得到需要读设备的字节数
ULONG ReadLen = stack->Parameters.Read.Length;
if (NT_SUCCESS(Irp->IoStatus.Status))
{
//得到按键信息
KeyData = (PKEYBOARD_INPUT_DATA)Irp->AssociatedIrp.SystemBuffer;
//按键个数
KeyNum = Irp->IoStatus.Information / sizeof(KEYBOARD_INPUT_DATA);
KIRQL oldIrql;
for (int i = 0; i < KeyNum;i++)
{
KdPrint(("Scancode : %x ",KeyData[i].MakeCode));
KdPrint(("%s \n",KeyData[i].Flags ? "Up":"Down"));
PMYDATASTRUCT pData;
pData = (PMYDATASTRUCT)ExAllocatePool(NonPagedPool,sizeof(MYDATASTRUCT));
pData->ScanCode = KeyData[i].MakeCode;
pData->Flags = KeyData[i].Flags;
//得到 spinlock
KeAcquireSpinLock(&pDeviceExtension->ListSpinLock,&oldIrql);
KdPrint(("********>> ReadCompletion spinlock\n"));
InsertHeadList(&pDeviceExtension->linkListHead,&pData->ListEntry);
//释放 end spinlock
KeReleaseSpinLock(&pDeviceExtension->ListSpinLock,oldIrql);
KdPrint(("<<******** ReadCompletion spinlock\n"));
}
}
if (Irp->PendingReturned)
{
IoMarkIrpPending(Irp);
}
KdPrint(("leave KeyFilterReadCompletion\n"));
return Irp->IoStatus.Status;
}
//************************************
// Method: KeyFilterReadStartio
// Qualifier: 处理读请求
//************************************
NTSTATUS KeyFilterReadStartio(PDEVICE_OBJECT fdo,PIRP Irp/*,PVOID Context*/)
{
PDEVICE_EXTENSION DeviceExtension;
KdPrint(("enter KeyFilterReadStartio\n"));
DeviceExtension = (PDEVICE_EXTENSION)fdo->DeviceExtension;
IoCopyCurrentIrpStackLocationToNext(Irp);
//设置回调函数
IoSetCompletionRoutine(Irp,
KeyFilterReadCompletion,
NULL,
TRUE,
TRUE,
TRUE);
return IoCallDriver(DeviceExtension->NextStackDevice,Irp);
}
//************************************
// Method: KeyFilterDeviceIoCtl
// Qualifier: DeviceIOControl 派遣函数
// Parameter: PDEVICE_OBJECT fdo 功能设备对象
// Parameter: PIRP Irp 从IO请求包
// Parameter: PVOID Context 上下文传过来的参数
//************************************
NTSTATUS KeyFilterDeviceIoCtl(PDEVICE_OBJECT fdo,PIRP Irp)
{
NTSTATUS status = STATUS_SUCCESS;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
PDEVICE_EXTENSION DeviceExt = (PDEVICE_EXTENSION)fdo->DeviceExtension;
ULONG code = stack->Parameters.DeviceIoControl.IoControlCode;
switch(code)
{
case IOCTL_SHOWKEYFILTER://应用程序发过来的得到按键消息的请求
KdPrint(("enter KeyFilterDeviceIoCtl: 0x%x\n", Irp));
status = STATUS_PENDING;
Irp->IoStatus.Status = status;
Irp->IoStatus.Information = 0;
IoMarkIrpPending(Irp);//将IRP设置为挂起状态(异步IRP)
IoStartPacket(fdo, Irp, 0, KeyFilterCancelIRP);
KdPrint(("leave KeyFilterDeviceIoCtl: 0x%x\n", Irp));
break;
default:
break;
}
return status;
}
NTSTATUS KeyFilterUnHandleIrp(PDEVICE_OBJECT DeviceObject, PIRP Irp)
{
KdPrint(("Irp: %d\n", IoGetCurrentIrpStackLocation(Irp)->MajorFunction));
IoSkipCurrentIrpStackLocation(Irp);
return IoCallDriver(((PDEVICE_EXTENSION)DeviceObject->DeviceExtension)->NextStackDevice, Irp);
}
/************************************************************************
* 函数名称:DefaultPnpHandler
* 功能描述:对PNP IRP进行缺省处理
* 参数列表:
pdx:设备对象的扩展
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS DefaultPnpHandler(PDEVICE_EXTENSION pdx, PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter DefaultPnpHandler\n"));
IoSkipCurrentIrpStackLocation(Irp);
KdPrint(("Leave DefaultPnpHandler\n"));
return IoCallDriver(pdx->NextStackDevice, Irp);
}
/************************************************************************
* 函数名称:HandleRemoveDevice
* 功能描述:对IRP_MN_REMOVE_DEVICE IRP进行处理
* 参数列表:
fdo:功能设备对象
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS HandleRemoveDevice(PDEVICE_EXTENSION pdx, PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter HandleRemoveDevice\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
NTSTATUS status = DefaultPnpHandler(pdx, Irp);
IoDeleteSymbolicLink(&(UNICODE_STRING)pdx->ustrSymLinkName);
PLIST_ENTRY pEntry;
PMYDATASTRUCT pData;
//获取自旋锁
KIRQL oldIrql;
KeAcquireSpinLock(&pdx->ListSpinLock,&oldIrql);
KdPrint(("******>> DeviceIoCtlStartio spinlock\n"));
//取出链表中数据
while(!IsListEmpty(&pdx->linkListHead))
{
pEntry = RemoveTailList(&pdx->linkListHead);
pData = CONTAINING_RECORD(pEntry,MYDATASTRUCT,ListEntry);
}
KeReleaseSpinLock(&pdx->ListSpinLock,oldIrql);
ExFreePool(pData);
//调用IoDetachDevice()把fdo从设备栈中脱开:
if (pdx->NextStackDevice)
IoDetachDevice(pdx->NextStackDevice);
//删除fdo:
IoDeleteDevice(pdx->PDeviceObject);
KdPrint(("Leave HandleRemoveDevice\n"));
return status;
}
/************************************************************************
* 函数名称:KeyFilterPnp
* 功能描述:对即插即用IRP进行处理
* 参数列表:
fdo:功能设备对象
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS KeyFilterPnp(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
PAGED_CODE();
KdPrint(("Enter KeyFilterPnp\n"));
NTSTATUS status = STATUS_SUCCESS;
PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) fdo->DeviceExtension;
PIO_STACK_LOCATION stack = IoGetCurrentIrpStackLocation(Irp);
static NTSTATUS (*fcntab[])(PDEVICE_EXTENSION pdx, PIRP Irp) =
{
DefaultPnpHandler, // IRP_MN_START_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_REMOVE_DEVICE
HandleRemoveDevice, // IRP_MN_REMOVE_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_REMOVE_DEVICE
DefaultPnpHandler, // IRP_MN_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_CANCEL_STOP_DEVICE
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_RELATIONS
DefaultPnpHandler, // IRP_MN_QUERY_INTERFACE
DefaultPnpHandler, // IRP_MN_QUERY_CAPABILITIES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCES
DefaultPnpHandler, // IRP_MN_QUERY_RESOURCE_REQUIREMENTS
DefaultPnpHandler, // IRP_MN_QUERY_DEVICE_TEXT
DefaultPnpHandler, // IRP_MN_FILTER_RESOURCE_REQUIREMENTS
DefaultPnpHandler, //
DefaultPnpHandler, // IRP_MN_READ_CONFIG
DefaultPnpHandler, // IRP_MN_WRITE_CONFIG
DefaultPnpHandler, // IRP_MN_EJECT
DefaultPnpHandler, // IRP_MN_SET_LOCK
DefaultPnpHandler, // IRP_MN_QUERY_ID
DefaultPnpHandler, // IRP_MN_QUERY_PNP_DEVICE_STATE
DefaultPnpHandler, // IRP_MN_QUERY_BUS_INFORMATION
DefaultPnpHandler, // IRP_MN_DEVICE_USAGE_NOTIFICATION
DefaultPnpHandler, // IRP_MN_SURPRISE_REMOVAL
};
ULONG fcn = stack->MinorFunction;
if (fcn >= arraysize(fcntab))
{ // 未知的子功能代码
status = DefaultPnpHandler(pdx, Irp); // some function we don't know about
return status;
}
#if DBG
static char* fcnname[] =
{
"IRP_MN_START_DEVICE",
"IRP_MN_QUERY_REMOVE_DEVICE",
"IRP_MN_REMOVE_DEVICE",
"IRP_MN_CANCEL_REMOVE_DEVICE",
"IRP_MN_STOP_DEVICE",
"IRP_MN_QUERY_STOP_DEVICE",
"IRP_MN_CANCEL_STOP_DEVICE",
"IRP_MN_QUERY_DEVICE_RELATIONS",
"IRP_MN_QUERY_INTERFACE",
"IRP_MN_QUERY_CAPABILITIES",
"IRP_MN_QUERY_RESOURCES",
"IRP_MN_QUERY_RESOURCE_REQUIREMENTS",
"IRP_MN_QUERY_DEVICE_TEXT",
"IRP_MN_FILTER_RESOURCE_REQUIREMENTS",
"",
"IRP_MN_READ_CONFIG",
"IRP_MN_WRITE_CONFIG",
"IRP_MN_EJECT",
"IRP_MN_SET_LOCK",
"IRP_MN_QUERY_ID",
"IRP_MN_QUERY_PNP_DEVICE_STATE",
"IRP_MN_QUERY_BUS_INFORMATION",
"IRP_MN_DEVICE_USAGE_NOTIFICATION",
"IRP_MN_SURPRISE_REMOVAL",
};
KdPrint(("PNP Request (%s)\n", fcnname[fcn]));
#endif // DBG
status = (*fcntab[fcn])(pdx, Irp);
KdPrint(("Leave KeyFilterPnp\n"));
return status;
}
/************************************************************************
* 函数名称:KeyFilterDispatchRoutine
* 功能描述:对缺省IRP进行处理
* 参数列表:
fdo:功能设备对象
Irp:从IO请求包
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
NTSTATUS KeyFilterDispatchRoutine(IN PDEVICE_OBJECT fdo,
IN PIRP Irp)
{
//PAGED_CODE();
KdPrint(("Enter KeyFilterDispatchRoutine\n"));
Irp->IoStatus.Status = STATUS_SUCCESS;
Irp->IoStatus.Information = 0; // no bytes xfered
IoCompleteRequest( Irp, IO_NO_INCREMENT );
KdPrint(("Leave KeyFilterDispatchRoutine\n"));
return STATUS_SUCCESS;
}
/************************************************************************
* 函数名称:KeyFilterUnload
* 功能描述:负责驱动程序的卸载操作
* 参数列表:
DriverObject:驱动对象
* 返回 值:返回状态
*************************************************************************/
#pragma PAGEDCODE
void KeyFilterUnload(IN PDRIVER_OBJECT DriverObject)
{
PAGED_CODE();
KdPrint(("Enter KeyFilterUnload\n"));
KdPrint(("Leave KeyFilterUnload\n"));
}
应用程序部分代码:
void CShowInputKeyDlg::OnBnClickedStart()
{
// TODO: Add your control notification handler code here
CString ldebug;
do
{
mParamStruct.mHdevice = CreateFile(L"\\\\.\\KeyFilterSymLinkName0",
GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_WRITE|FILE_SHARE_READ, // share mode none
NULL, // no security
OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL,
NULL ); // no template
if (mParamStruct.mHdevice == INVALID_HANDLE_VALUE)
{
CString ldebug;
ldebug.Format(_T("--------------Failed to obtain file handle to device error : %d"),GetLastError());
OutputDebugString(ldebug);
break;
}
mParamStruct.mHwndMain = GetSafeHwnd();
mThreadHandle = (HANDLE)_beginthreadex(NULL,0,ReadThread,(void*)&mParamStruct,0,NULL);
} while (FALSE);
}
新建的线程函数为:
UINT CALLBACK ReadThread(LPVOID para)
{
PPARAM_STRUCT lParamStruct = (PPARAM_STRUCT)para;
BOOL lbRet = TRUE;
DWORD ReturnLen = 0;
USHORT readBuffer[MAX_KEY_COUNT*2] = {0};
CString ldebug;
do
{
HANDLE lhDevice = lParamStruct->mHdevice;
HWND lHwnd = lParamStruct->mHwndMain;
if (lhDevice == NULL || lHwnd == NULL)
{
break;
}
OutputDebugString(L"---------->ReadThread");
while(TRUE)
{
lbRet = DeviceIoControl(lhDevice,IOCTL_SHOWKEYFILTER,NULL,0,readBuffer,
sizeof(readBuffer),&ReturnLen,NULL);
if (lbRet == FALSE)
{
ldebug.Format(_T("DeviceIoControl error :0x%x."),GetLastError());
OutputDebugString(ldebug);
break;
}
ldebug.Format(_T("----------- DeviceIoControl returnlen : %d"),ReturnLen);
OutputDebugString(ldebug);
if (ReturnLen == 0)
{
continue;
}
PostMessage(lHwnd,WM_INSERT_ITEM_MESSAGE,(WPARAM)readBuffer,(LPARAM)&ReturnLen);
ldebug.Format(_T("----------- DeviceIoControl insert list end "));
OutputDebugString(ldebug);
}
} while (FALSE);
OutputDebugString(L"<----------ReadThread");
_endthreadex( 0 );
return 0;
}
消息处理,界面显示:
BOOL CShowInputKeyDlg::PreTranslateMessage(MSG* pMsg)
{
// TODO: Add your specialized code here and/or call the base class
USHORT Scancode;
USHORT Flag;
CString ldebug;
if (pMsg->message == WM_INSERT_ITEM_MESSAGE)
{
OutputDebugString(L"WM_INSERT_ITEM_MESSAGE");
USHORT * readBuffer = (USHORT *)pMsg->wParam;
PDWORD PReturnLen = (PDWORD)pMsg->lParam;
CString lstrAction = NULL;
for (DWORD index = 0;index < *PReturnLen/sizeof(USHORT);index += 2)
{
Scancode = readBuffer[index];
Flag = readBuffer[index+1];
lstrAction.Format(_T("%d"),mList.GetItemCount()+1);
mList.InsertItem(mList.GetItemCount(),lstrAction);
lstrAction.Format(_T("0x%x"),Scancode);
mList.SetItemText(mList.GetItemCount()-1,1,lstrAction);
UINT VkKey = MapVirtualKey(Scancode,MAPVK_VSC_TO_VK);
if (VkKey != 0)
{
lstrAction.Format(_T("0x%x"),VkKey);
mList.SetItemText(mList.GetItemCount()-1,2,lstrAction);
}
lstrAction.Format(_T("%ws"),Flag? L"Up" : L"Down");
mList.SetItemText(mList.GetItemCount()-1,3,lstrAction);
//确保List Control最后一行可见
mList.EnsureVisible(mList.GetItemCount()-1,FALSE);
}
return TRUE;//直接返回true
}else
{
return CDialogEx::PreTranslateMessage(pMsg);
}
}
完整代码请访问: 猛戳这里
学驱动不久,有不妥之处还望大家指正。