我将<windows驱动开发>里12章第3节的挂载设备的实例代码, 挂载到了键盘的驱动上。
先声明本人绝对不是准备做盗号木马用的,就是想把新掌握的知识玩个新鲜的熟悉下,毕竟键盘想按就按下,比写个vc程序来测试这个挂载驱动的KdPrint()的信息来的方便,如果想盗号我想直接读键盘缓冲区应该更适用吧。
然后我发现个问题,就是当我按键速度快点,或者是按了10次左右的单一键后,键盘就没有相应了。后来我用IRPtrace获取irp信息,发现最后一个irp是close-kbdclass.
下面是相关的代码,和截获得信息
=============================IRPtrace===================================================
Close
 IRP 82B76E48
 
Previous    Next 
 
 IRP
 82B76E48h
 
Major function
 IRP_MJ_CLOSE
 
Minor function
 00h
 
Target Device
 KeyboardClass0 (Kbdclass) 
 
State
 Completed
 
Status
 STATUS_SUCCESS
 
 Sent
 2010-12-29 21:22:50:390
 
by
 HelloDDKB.sys!+4360h (F78E0360) 
 
process
 System(4h) 
 
thread
 28h
 
at IRQL
 PASSIVE_LEVEL
 
 Completed
 2010-12-29 21:22:50:390
 
by
 KBDCLASS.SYS!+118Ch (F77E518C) 
 
process
 System(4h) 
 
thread
 28h
 
at IRQL
 PASSIVE_LEVEL
 
========================================================================================================
==========================DriverEntry函数的部分代码=====================================================
RtlInitUnicodeString( &DeviceName, L"\\Device\\KeyboardClass0" );/*MyDDKDeviceA*/ PDEVICE_OBJECT DeviceObject = NULL;
PFILE_OBJECT FileObject = NULL;
//寻找DriverA创建的设备对象
ntStatus = IoGetDeviceObjectPointer(&DeviceName,FILE_ALL_ACCESS,&FileObject,&DeviceObject); if (!NT_SUCCESS(ntStatus))
{
KdPrint(("DriverB:IoGetDeviceObjectPointer() 0x%x\n", ntStatus ));
return ntStatus;
} //创建自己的驱动设备对象
ntStatus = CreateDevice(pDriverObject); if ( !NT_SUCCESS( ntStatus ) )
{
ObDereferenceObject( FileObject );
DbgPrint( "IoCreateDevice() 0x%x!\n", ntStatus );
return ntStatus;
} PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION) pDriverObject->DeviceObject->DeviceExtension; PDEVICE_OBJECT FilterDeviceObject = pdx->pDevice; //将自己的设备对象挂载在DriverA的设备对象上
PDEVICE_OBJECT TargetDevice = IoAttachDeviceToDeviceStack( FilterDeviceObject,DeviceObject );
//将底层设备对象记录下来
pdx->TargetDevice = TargetDevice; if ( !TargetDevice )
{
ObDereferenceObject( FileObject );
IoDeleteDevice( FilterDeviceObject );
DbgPrint( "IoAttachDeviceToDeviceStack() 0x%x!\n", ntStatus );
return STATUS_INSUFFICIENT_RESOURCES;
}
FilterDeviceObject->DeviceType = TargetDevice->DeviceType;
FilterDeviceObject->Characteristics = TargetDevice->Characteristics;
//  FilterDeviceObject->Flags &= ~DO_DEVICE_INITIALIZING;
//  FilterDeviceObject->Flags |= ( TargetDevice->Flags & ( DO_DIRECT_IO |
//   DO_BUFFERED_IO ) );
FilterDeviceObject->Flags=TargetDevice->Flags;
ObDereferenceObject( FileObject );
=======================================================================================================
===========================IRP_MJ_READ派遣函数的代码===================================================
NTSTATUS HelloDDKRead(IN PDEVICE_OBJECT pDevObj,
 IN PIRP pIrp) 
{
KdPrint(("DriverB:Enter B HelloDDKRead\n"));
NTSTATUS ntStatus = STATUS_SUCCESS;
//将自己完成IRP,改成由底层驱动负责 PDEVICE_EXTENSION pdx = (PDEVICE_EXTENSION)pDevObj->DeviceExtension; //将当前IRP堆栈拷贝底层堆栈
IoCopyCurrentIrpStackLocationToNext(pIrp); //设置完成例程
IoSetCompletionRoutine(pIrp,MyIoCompletion,NULL,TRUE,TRUE,TRUE); //调用底层驱动
    ntStatus = IoCallDriver(pdx->TargetDevice, pIrp); //当IoCallDriver后,并且完成例程返回的是STATUS_SUCCESS
//IRP就不在属于派遣函数了,就不能对IRP进行操作了
if (ntStatus == STATUS_PENDING)
{
KdPrint(("STATUS_PENDING\n"));
}
ntStatus = STATUS_PENDING;  KdPrint(("DriverB:Leave B HelloDDKRead\n")); return ntStatus;
}
========================================================================================================
==================完成函数的代码========================================================================
#pragma PAGEDCODE
NTSTATUS
  MyIoCompletion(IN PDEVICE_OBJECT  DeviceObject,
    IN PIRP  Irp,
    IN PVOID  Context)
{
//进入此函数标志底层驱动设备将IRP完成
KdPrint(("Enter MyIoCompletion\n"));
KdPrint(("==IoStatus=%x====\n",Irp->IoStatus.Status));
if(NT_SUCCESS(Irp->IoStatus.Status))
{
PUCHAR c;
c=(PUCHAR)Irp->AssociatedIrp.SystemBuffer;
KdPrint(("%x %x %x %x-%x %x %x %x\n%x %x %x %x\n",c[0],c[1],c[2],c[3],c[4],c[5],
c[6],c[7],c[8],c[9],c[10],c[11]));
}
    if (Irp->PendingReturned) 
{
//传播pending位
        IoMarkIrpPending( Irp );
    } return STATUS_SUCCESS;//Irp->IoStatus.Status;
//return STATUS_SUCCESS;//同STATUS_CONTINUE_COMPLETION
}
========================================================================================================
各位高手帮看下吧,我新手,怕自己说不清楚,就直接将代码都复制过了来。但愿这些代码看起来不是那么的让人烦