阅读:2147回复:19
KeWaitForSingleObject
NTSTATUS SfReadCompletion(IN PDEVICE_OBJECT DeviceObject,
IN PIRP Irp, IN PVOID Context) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); UNREFERENCED_PARAMETER( Context ); UNREFERENCED_PARAMETER( DeviceObject ); ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); return STATUS_MORE_PROCESSING_REQUIRED; //如果换成 return STATUS_SUCCESS;在输入密码完成后,进如系统时重起 }; NTSTATUS SfRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT file_object = irpsp->FileObject; PSFILTER_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; NTSTATUS Status = STATUS_SUCCESS; ULONG IsFile = 0; KEVENT waitEvent; PAGED_CODE(); // 对控制设备的操作,返回成功? if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS;; } // 对文件系统其他设备的操作,passthru. if (!devExt->StorageStackDeviceObject) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->AttachedToDeviceObject, Irp); } if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->AttachedToDeviceObject, Irp); } KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); IoCopyCurrentIrpStackLocationToNext ( Irp ); IoSetCompletionRoutine( Irp, SfReadCompletion, &waitEvent , TRUE, TRUE, TRUE ); Status = IoCallDriver( devExt->AttachedToDeviceObject, Irp ); if (STATUS_PENDING == Status) { Status = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL ); ASSERT( STATUS_SUCCESS == Status ); } return Status; }; 编译环境:Windows IFS Kit and DDK 3790 Windows 2000 Free Build Environment 运行环境:Win2000 Professional Sp4 症状:在登陆截面的时候,就是出现Win2k的画面时,进度条走到大概3/4的时候就停了,一直不动了 但这个在xp下又没有问题 请问是怎么回事啊? 先谢谢大家啦! |
|
沙发#
发布于:2007-07-04 13:03
SfRead的末尾应该有completerequest
|
|
板凳#
发布于:2007-07-04 13:20
用了IoSetCompletionRoutine这个,还需要设置completerequest么?
|
|
地板#
发布于:2007-07-04 13:26
IoSetCompletionRoutine是为了设置sfreadcomplete的,completerequest是完成此irp,使此irp不再下传
|
|
地下室#
发布于:2007-07-04 13:52
不对吧,加了之后,BugChk
MULTIPLE_IRP_COMPLETE_REQUEST |
|
5楼#
发布于:2007-07-04 14:04
看看xiangxiangren的书。我试过,没问题的,不过当时的学习例程没了
贴出来,我看看妮怎么写的? |
|
6楼#
发布于:2007-07-04 14:06
症状:在登陆截面的时候,就是出现Win2k的画面时,进度条走到大概3/4的时候就停了,一直不动了
但这个在xp下又没有问题 你用的是什么架构?? filespy? sfilter? filemon? |
|
7楼#
发布于:2007-07-04 14:07
NTSTATUS SfRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp)
{ PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT file_object = irpsp->FileObject; PSFILTER_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; NTSTATUS Status = STATUS_SUCCESS; ULONG IsFile = 0; KEVENT waitEvent; PAGED_CODE(); // 对控制设备的操作,返回成功? if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS;; } // 对文件系统其他设备的操作,passthru. if (!devExt->StorageStackDeviceObject) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->AttachedToDeviceObject, Irp); } if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->AttachedToDeviceObject, Irp); } KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); IoCopyCurrentIrpStackLocationToNext ( Irp ); IoSetCompletionRoutine( Irp, SfReadCompletion, &waitEvent , TRUE, TRUE, TRUE ); Status = IoCallDriver( devExt->AttachedToDeviceObject, Irp ); if (STATUS_PENDING == Status) { Status = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL ); ASSERT( STATUS_SUCCESS == Status ); } //加了3句话 Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return Status; }; |
|
8楼#
发布于:2007-07-04 14:09
我用sfilter改的
|
|
9楼#
发布于:2007-07-04 14:16
我现在在家上网,没法看我办公电脑的程序,你在SfReadCompletion中加一个context的非空判断试试。
症状:在登陆截面的时候,就是出现Win2k的画面时,进度条走到大概3/4的时候就停了,一直不动了 但这个在xp下又没有问题,这个我也不明白拉,我不记得我的例程是否在2000上测试过。 |
|
10楼#
发布于:2007-07-04 14:22
是得加IoCompleteRequest来完成IRP
|
|
|
11楼#
发布于:2007-07-04 14:28
没有效果....同样在输入密码完成后,系统重起
NTSTATUS SfReadCompletion(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context) { PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation(Irp); UNREFERENCED_PARAMETER( DeviceObject ); ASSERT(IS_MY_DEVICE_OBJECT( DeviceObject )); if(Context) KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); return STATUS_SUCCESS; }; NTSTATUS SfRead(IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp) { PIO_STACK_LOCATION irpsp = IoGetCurrentIrpStackLocation(Irp); PFILE_OBJECT file_object = irpsp->FileObject; PSFILTER_DEVICE_EXTENSION devExt = DeviceObject->DeviceExtension; NTSTATUS Status = STATUS_SUCCESS; ULONG IsFile = 0; KEVENT waitEvent; PAGED_CODE(); // 对控制设备的操作,返回成功? if (IS_MY_CONTROL_DEVICE_OBJECT(DeviceObject)) { Irp->IoStatus.Status = STATUS_SUCCESS; Irp->IoStatus.Information = 0; IoCompleteRequest( Irp, IO_NO_INCREMENT ); return STATUS_SUCCESS;; } // 对文件系统其他设备的操作,passthru. if (!devExt->StorageStackDeviceObject) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->AttachedToDeviceObject, Irp); } if (!(Irp->Flags & (IRP_NOCACHE | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO))) { IoSkipCurrentIrpStackLocation(Irp); return IoCallDriver(devExt->AttachedToDeviceObject, Irp); } KeInitializeEvent( &waitEvent, NotificationEvent, FALSE ); IoCopyCurrentIrpStackLocationToNext ( Irp ); IoSetCompletionRoutine( Irp, SfReadCompletion, &waitEvent , TRUE, TRUE, TRUE ); Status = IoCallDriver( devExt->AttachedToDeviceObject, Irp ); if (STATUS_PENDING == Status) { Status = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL ); ASSERT( STATUS_SUCCESS == Status ); } return Status; }; |
|
12楼#
发布于:2007-07-04 14:42
安全模式下,又冒似没有问题,驱动正常
|
|
13楼#
发布于:2007-07-05 00:05
我测了一下2000系统下的情况,确实有这个现象,我也不知道什么问题
得问问楚老师拉(xiangxiangren) |
|
14楼#
发布于:2007-07-05 10:55
大哥些,进来看下嘛
|
|
15楼#
发布于:2007-07-05 12:48
你这种情况只加IoCompleteRequest一句就行,干嘛给Irp->IoStatus.Informatio赋值,自讨苦吃呀
|
|
16楼#
发布于:2007-07-09 13:58
正解,谢谢
|
|
17楼#
发布于:2007-07-09 14:02
解密过程: 在sfread中用下面的代码行吗???????
{// while KEVENT waitEvent; KeInitializeEvent( &waitEvent, NotificationEvent, FALSE); IoCopyCurrentIrpStackLocationToNext(Irp); IoSetCompletionRoutine( Irp, SpyReadCompletion, &waitEvent, TRUE, TRUE, TRUE); Status = IoCallDriver(DevExt->NLExtHeader.AttachedToDeviceObject, Irp); if(STATUS_PENDING == Status) { Status = KeWaitForSingleObject( &waitEvent, Executive, KernelMode, FALSE, NULL); ASSERT(STATUS_PENDING == Status); } // 以上是等待读完成函数完成. // 以下是异或加密过程 Length = IrpSp->Parameters.Read.Length; if (Irp->MdlAddress) { OldBuffer = MmGetSystemAddressForMdl(Irp->MdlAddress); } else { OldBuffer = Irp->UserBuffer ; } { // by me NumofBlock = Length / FILE_BUFFER; if((Length % FILE_BUFFER) != 0) NumofBlock++; for(i = 0 ; i < NumofBlock; i++) { if(i == NumofBlock - 1) BlockLength = Length - i*FILE_BUFFER; else BlockLength = FILE_BUFFER; ilen = (i*FILE_BUFFER); for( j = 0; j < BlockLength; j++ ) *(((PCHAR)OldBuffer)+ilen+j) = *(((PCHAR) OldBuffer)+ilen+j) ^ 0XFF;// 异或 } } } while (FALSE); //Irp->IoStatus.Status = Status; IoCompleteRequest(Irp, IO_NO_INCREMENT); |
|
18楼#
发布于:2007-07-09 16:22
在SfRead中调用IoCompleteRequest完成Irp,那么SfReadCompletion中就必须返回STATUS_MORE_PROCESSING_REQUIRED;
|
|
19楼#
发布于:2007-07-09 16:54
呵呵,看看我的complete,忘了贴出来了:
NTSTATUS SpyReadCompletion( IN PDEVICE_OBJECT DeviceObject, IN PIRP Irp, IN PVOID Context ) { PREAD_WRITE_COMPLETION_CONTEXT CompletionCtx = (PREAD_WRITE_COMPLETION_CONTEXT) Context; UNREFERENCED_PARAMETER(DeviceObject); UNREFERENCED_PARAMETER(Irp); if(Context != NULL) { KeSetEvent((PKEVENT)Context, IO_NO_INCREMENT, FALSE); //return STATUS_SUCCESS; KdPrint(("sfilter!SfRead: buffer:[4444444444444444444444]\n")); return STATUS_MORE_PROCESSING_REQUIRED ; //return STATUS_PENDING; } return STATUS_SUCCESS; } 看看行否???? 是不是比原来的简单啊?? |
|