Part.2

二十七.键盘过滤(Part.2)

2010-04-25 13:11:58 阅读6 评论0 字号:

发代码高亮太占字数....


#include <ntifs.h>
#include <ntddkbd.h>
#include "kbdfilter.h"

ULONG KeyCount = 0;
UNICODE_STRING mDeviceName,symbolic;
PDRIVER_OBJECT mDriverObject = NULL;
PDEVICE_OBJECT mDevice = NULL;
PDEVICE_LIST DeviceList = NULL;//过滤设备表
KSPIN_LOCK DLSpinLock;
USHORT KbdMap[100];

void InsertDevice(PDEVICE_LIST *Head,PDEVICE_OBJECT obj)
{
 PDEVICE_LIST tmp;
 KIRQL irql;
 KeAcquireSpinLock(&DLSpinLock,&irql);
 tmp = (PDEVICE_LIST)ExAllocatePoolWithTag(NonPagedPool,sizeof(DEVICE_LIST),MEM_TAG);
 tmp->DeviceObj = obj;
 tmp->Next = *Head;
 *Head = tmp;
 KeReleaseSpinLock(&DLSpinLock,irql);
}

void kfDetach(PDEVICE_OBJECT DeviceObject)
{
 PMDEV_EXT devExt;
 devExt = (PMDEV_EXT)(DeviceObject->DeviceExtension);
 __try
 {
  IoDetachDevice(devExt->TargetDeviceObject);
  IoDeleteDevice(DeviceObject);
  devExt->TargetDeviceObject = NULL;
  devExt->pFilterDeviceObject = NULL;
  KdPrint(("KbdFilter: Device:%X has been delete\n",DeviceObject));
 }
 __except(EXCEPTION_EXECUTE_HANDLER){}
 return;
}

void mUnload(PDRIVER_OBJECT DriverObject)
{
 PDEVICE_OBJECT DeviceObject;
 PDEVICE_LIST tmp;
 LARGE_INTEGER lDelay;
 PRKTHREAD CurrentThread;
 KIRQL irql;

 KdPrint(("KbdFilter: Driver Unloading\n"));
 lDelay.QuadPart = (__int64)-10*1000*200;//200毫秒
 CurrentThread = KeGetCurrentThread();
 //当前线程设置为低实时模式
 KeSetPriorityThread(CurrentThread,LOW_REALTIME_PRIORITY);
 UNREFERENCED_PARAMETER(DriverObject);
 //卸载mDevice
 IoDeleteSymbolicLink(&symbolic);
 IoDeleteDevice(mDevice);
 //卸载过滤设备
 KeAcquireSpinLock(&DLSpinLock,&irql);
 while(DeviceList)
 {
  tmp = DeviceList->Next;
  kfDetach(DeviceList->DeviceObj);
  ExFreePool(DeviceList);//释放
  DeviceList = tmp;
 }
 ASSERT(DriverObject->DeviceObject == NULL);
 KeReleaseSpinLock(&DLSpinLock,irql);

 while(KeyCount)
 {
  KeDelayExecutionThread(KernelMode, FALSE, &lDelay);
 }

 KdPrint(("KbdFilter: Unload Successful\n"));
 return;
}

NTSTATUS kfAttachDevice(IN PDRIVER_OBJECT DriverObject,
      IN PUNICODE_STRING RegistryPath)
{
 NTSTATUS status = STATUS_SUCCESS;
 UNICODE_STRING DrvName;
 PMDEV_EXT devExt;

 PDEVICE_OBJECT pFilterDeviceObject = NULL;
 PDEVICE_OBJECT pTargetDeviceObject = NULL;
 PDEVICE_OBJECT pLowerDeviceObject = NULL;

 PDRIVER_OBJECT KbdDriverObject = NULL;

 KdPrint(("KbdFilter: Attaching Keyboard Device\n"));
 RtlInitUnicodeString(&DrvName,KBD_DRIVER_NAME);
 status = ObReferenceObjectByName ( &DrvName,
          OBJ_CASE_INSENSITIVE,
          NULL,
          0,
          *IoDriverObjectType,
          KernelMode,
          NULL,
          (PVOID *)&KbdDriverObject);
 if(!NT_SUCCESS(status))
 {
  KdPrint(("KbdFilter: [ObReferenceObjectByName]Failed\n"));
  return status;
 }
 
 ObDereferenceObject(KbdDriverObject);
 pTargetDeviceObject = KbdDriverObject->DeviceObject;
 while(pTargetDeviceObject) //遍历设备链
 {
  status = IoCreateDevice(DriverObject,
        sizeof(MDEV_EXT),
        NULL,
        pTargetDeviceObject->DeviceType,
        pTargetDeviceObject->Characteristics,
        FALSE,
        &pFilterDeviceObject);
  if(!NT_SUCCESS(status))
  {
   KdPrint(("KbdFilter: Cannot create filter device!\n"));
   return status;
  }
  pLowerDeviceObject = IoAttachDeviceToDeviceStack(pFilterDeviceObject,pTargetDeviceObject);
  if(!pLowerDeviceObject)
  {
   KdPrint(("KbdFilter: Attach device failed!\n"));
   IoDeleteDevice(pFilterDeviceObject);
   return STATUS_SUCCESS;
  }
  devExt = (PMDEV_EXT)(pFilterDeviceObject->DeviceExtension);
  //修改设备属性
  pFilterDeviceObject->StackSize=pLowerDeviceObject->StackSize+1;
  pFilterDeviceObject->Flags |= pLowerDeviceObject->Flags & (DO_BUFFERED_IO | DO_DIRECT_IO | DO_POWER_PAGABLE);
  //完成设备扩展
  memset(devExt,0,sizeof(MDEV_EXT));
  devExt->NodeSize = sizeof(MDEV_EXT);
  devExt->LowerDeviceObject = pLowerDeviceObject;
  devExt->pFilterDeviceObject = pFilterDeviceObject;
  devExt->TargetDeviceObject = pTargetDeviceObject;
  KeInitializeSpinLock(&(devExt->IoRequestsSpinLock));
  KeInitializeEvent(&(devExt->IoInProgressEvent), NotificationEvent, FALSE);
  //将新建的过滤设备插入链表
  InsertDevice(&DeviceList,pFilterDeviceObject);

  pTargetDeviceObject = pTargetDeviceObject->NextDevice;
 }
 return status;
}

void InitKbdMap()
{
 USHORT i;
 for(i=0;i<100;i++) KbdMap[i]=i;
}

NTSTATUS kfDispatchGeneral(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
 PDEVICE_LIST tmp = DeviceList;
 KIRQL irql;
 PIO_STACK_LOCATION isl;
 PKBD_MAP_CONFIG buf;
 ULONG buflen;
 KeAcquireSpinLock(&DLSpinLock,&irql);
 KeReleaseSpinLock(&DLSpinLock,irql);
 while(tmp)
 {
  if(tmp->DeviceObj == DeviceObject)
  {
   KdPrint(("KbdFilter: OtherDispatch\n"));
   IoSkipCurrentIrpStackLocation(Irp);
   return IoCallDriver(((PMDEV_EXT)(DeviceObject->DeviceExtension))->LowerDeviceObject,Irp);
  }
  tmp = tmp->Next;
 }
 isl = IoGetCurrentIrpStackLocation(Irp);
 if (DeviceObject == mDevice)
 {
  switch(isl->MajorFunction)
  {
  case IRP_MJ_CREATE:
  case IRP_MJ_CLOSE:
   Irp->IoStatus.Information=0;
   Irp->IoStatus.Status = STATUS_SUCCESS;
   break;
  case IRP_MJ_DEVICE_CONTROL:
   Irp->IoStatus.Information=0;
   if(isl->Parameters.DeviceIoControl.IoControlCode == MAP_CONFIG_CODE)
   {
    buflen = isl->Parameters.DeviceIoControl.InputBufferLength;
    buf = (PKBD_MAP_CONFIG)Irp->AssociatedIrp.SystemBuffer;
    if ((buf != NULL)&&(buflen>=sizeof(KBD_MAP_CONFIG)))
    {
     KdPrint(("KbdFilter: SetMapConfig %X --> %X",buf->source,buf->target));
     if((buf->source<100)&&(buf->source>=0)) KbdMap[buf->source]=buf->target;
     Irp->IoStatus.Status = STATUS_SUCCESS;
    }
   }
   else
   {
    Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
   }
   break;
  default:
   Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
   Irp->IoStatus.Information = 0;
  }
  IoCompleteRequest(Irp,IO_NO_INCREMENT);
  return Irp->IoStatus.Status;
 }
 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
 Irp->IoStatus.Information = 0;
 IoCompleteRequest(Irp,IO_NO_INCREMENT);
 return STATUS_INVALID_DEVICE_REQUEST;
}

NTSTATUS kfPnP(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
 NTSTATUS status;
 KIRQL irql;
 PMDEV_EXT devExt;
 PIO_STACK_LOCATION irpStack;
 PDEVICE_LIST tmp,last;

 KeAcquireSpinLock(&DLSpinLock,&irql);
 tmp  = DeviceList;
 last = NULL;
 while(tmp)
 {
  if (tmp->DeviceObj == DeviceObject)
  {
   irpStack = IoGetCurrentIrpStackLocation(Irp);
   devExt = (PMDEV_EXT)tmp->DeviceObj->DeviceExtension;
   if (irpStack->MinorFunction == IRP_MN_REMOVE_DEVICE)
   {  
    KdPrint(("KbdFilter: IRP_MN_REMOVE_DEVICE\n"));
    IoSkipCurrentIrpStackLocation(Irp);
    IoCallDriver(devExt->LowerDeviceObject, Irp);
    status = STATUS_SUCCESS;
    //解除绑定,删除过滤设备
    IoDetachDevice(devExt->TargetDeviceObject);
    IoDeleteDevice(DeviceObject);
    //从列表中移除
    if (tmp == DeviceList) //是否在链表的头部?
    {
     DeviceList = tmp->Next;
     ExFreePool(tmp);
    }
    else
    {
     last->Next = tmp->Next;
     ExFreePool(tmp);
    }
   }
   else
   {
    //对于其他类型的IRP,全部都直接下发
    IoSkipCurrentIrpStackLocation(Irp);
    status = IoCallDriver(devExt->LowerDeviceObject, Irp);
   }
   return status;
  }
  last = tmp;
  tmp = tmp->Next;
 }
 KeReleaseSpinLock(&DLSpinLock,irql);

 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
 Irp->IoStatus.Information = 0;
 IoCompleteRequest(Irp,IO_NO_INCREMENT);
 return STATUS_INVALID_DEVICE_REQUEST;
}

NTSTATUS kfPower(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
 PMDEV_EXT devExt;
 PDEVICE_LIST tmp;
 KIRQL irql;
 KeAcquireSpinLock(&DLSpinLock,&irql);
 KeReleaseSpinLock(&DLSpinLock,irql);
 tmp = DeviceList;
 while(tmp)
 {
  if(tmp->DeviceObj == DeviceObject)
  {
   devExt = (PMDEV_EXT)DeviceObject->DeviceExtension;

   PoStartNextPowerIrp( Irp );
   IoSkipCurrentIrpStackLocation( Irp );
   return PoCallDriver(devExt->LowerDeviceObject, Irp );
  }
  tmp = tmp->Next;
 }
 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
 Irp->IoStatus.Information = 0;
 IoCompleteRequest(Irp,IO_NO_INCREMENT);
 return STATUS_INVALID_DEVICE_REQUEST;
}

NTSTATUS kfCompletionRead(IN PDEVICE_OBJECT DeviceObject,
        IN PIRP Irp,
        IN PVOID Context)
{
 PIO_STACK_LOCATION IrpSp;
 ULONG buf_len;
 PKEYBOARD_INPUT_DATA buf = NULL;
 ULONG i;
 
 IrpSp = IoGetCurrentIrpStackLocation(Irp);

 if(NT_SUCCESS(Irp->IoStatus.Status))
 {
  buf = Irp->AssociatedIrp.SystemBuffer;
  buf_len = (ULONG)Irp->IoStatus.Information;
  for(i=0;i<(buf_len/sizeof(KEYBOARD_INPUT_DATA));i++)
  {
   if(!(buf->Flags&KEY_BREAK))
   {
    KdPrint(("KbdFilter: MakeCode:%d  Flags:%4X\n",buf->MakeCode,buf->Flags));
   }
   buf->MakeCode = KbdMap[buf->MakeCode];
   buf++;
  }
 }
 KeyCount--;

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

NTSTATUS kfRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{
 NTSTATUS status = STATUS_SUCCESS;
 PMDEV_EXT devExt;
 PDEVICE_LIST tmp;
 KIRQL irql;

 if (Irp->CurrentLocation == 1)
 {
  ULONG ReturnedInformation = 0;
  KdPrint(("KbdFilter: Dispatch encountered bogus current location\n"));
  status = STATUS_INVALID_DEVICE_REQUEST;
  Irp->IoStatus.Status = status;
  Irp->IoStatus.Information = ReturnedInformation;
  IoCompleteRequest(Irp, IO_NO_INCREMENT);
  return(status);
 }  

 KeAcquireSpinLock(&DLSpinLock,&irql);
 KeReleaseSpinLock(&DLSpinLock,irql);
 tmp = DeviceList;
 while(tmp)
 {
  if (tmp->DeviceObj == DeviceObject)
  {
   KeyCount++;
   devExt = (PMDEV_EXT)DeviceObject->DeviceExtension;
   IoCopyCurrentIrpStackLocationToNext(Irp);
   IoSetCompletionRoutine(Irp,kfCompletionRead,DeviceObject,TRUE,TRUE,TRUE);
   status = IoCallDriver( devExt->LowerDeviceObject, Irp );
   return status;
  }
  tmp = tmp->Next;
 }

 Irp->IoStatus.Status = STATUS_INVALID_DEVICE_REQUEST;
 Irp->IoStatus.Information = 0;
 IoCompleteRequest(Irp,IO_NO_INCREMENT);
 return STATUS_INVALID_DEVICE_REQUEST;
}

NTSTATUS DriverEntry(PDRIVER_OBJECT DriverObject,PUNICODE_STRING RegPath)
{
 NTSTATUS status = STATUS_SUCCESS;
 ULONG i;
 mDriverObject=DriverObject;
 
 KdPrint(("KbdFilter: Entering DriverEntry\n"));
 //__asm int 3
 KeInitializeSpinLock(&DLSpinLock);
 
 for(i = 0;i<IRP_MJ_MAXIMUM_FUNCTION;i++)
 {
  DriverObject->MajorFunction[i] = kfDispatchGeneral;
 }
 DriverObject->MajorFunction[IRP_MJ_PNP]   = kfPnP;
 DriverObject->MajorFunction[IRP_MJ_POWER] = kfPower;
 DriverObject->MajorFunction[IRP_MJ_READ]  = kfRead;

 DriverObject->DriverUnload = mUnload;

 //建立设备以完成与用户层通讯
 RtlInitUnicodeString(&mDeviceName,MDEVICE_NAME);
 status = IoCreateDevice(DriverObject,
       0,
       &mDeviceName,
       FILE_DEVICE_UNKNOWN,
       0,
       FALSE,
       &mDevice);
 if(!NT_SUCCESS(status))
 {
  KdPrint(("KbdFilter: Cannot create device!"));
  return status;
 }
 RtlInitUnicodeString(&symbolic,MDEVICE_SYMB);
 status = IoCreateSymbolicLink(&symbolic,&mDeviceName);
 if(!NT_SUCCESS(status))
 {
  KdPrint(("KbdFilter: Cannot create device!"));
  IoDeleteDevice(mDevice);
  return status;
 }
 mDevice->Flags &= ~DO_DEVICE_INITIALIZING;
 InitKbdMap();
 //绑定键盘设备
 status = kfAttachDevice(DriverObject,RegPath);
 return status;
}

 

<#--{zx1}日志--> <#--推荐日志--> <#--引用记录--> <#--相关日志--> <#--推荐日志--> <#--推荐阅读--> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构-->
郑重声明:资讯 【Part.2】由 发布,版权归原作者及其所在单位,其原创性以及文中陈述文字和内容未经(企业库qiyeku.com)证实,请读者仅作参考,并请自行核实相关内容。若本文有侵犯到您的版权, 请你提供相关证明及申请并与我们联系(qiyeku # qq.com)或【在线投诉】,我们审核后将会尽快处理。
—— 相关资讯 ——