阅读:1747回复:11
如何绕过自己的驱动,把读、写直接传给下一层呢?我看了sfilter的但不成
以下是读或写的代码
NTSTATUS SfIssueReadWriteIrpSynchronously( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject, IN ULONG MajorFunction, IN PIO_STATUS_BLOCK IoStatus, IN PVOID Buffer, IN ULONG Length, IN PLARGE_INTEGER ByteOffset, IN ULONG IrpFlags ) { PIRP Irp = NULL; PIO_STACK_LOCATION IrpSp = NULL; KEVENT Event; NTSTATUS Status; ASSERT((MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE)); KeInitializeEvent(&Event, NotificationEvent, FALSE); //和下一级驱动建立同步的请求(这里是IRP_MJ_READ或IRP_MJ_WRITE) Irp = IoBuildSynchronousFsdRequest( MajorFunction, DeviceObject, Buffer, Length, ByteOffset, &Event, IoStatus ); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; Irp->Flags |= IrpFlags; //获得下一级驱动的指针给IrpSp IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->FileObject = FileObject; //执行 Status = IoCallDriver(DeviceObject, Irp); if (STATUS_PENDING == Status) { //等待完成 KdPrint(("SfIssueReadWriteIrpSynchronously:KeWaitForSingleObject,Event, FALSE")); KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } KdPrint(("SfIssueReadWriteIrpSynchronously:finisth")); return IoStatus->Status; } ==================== 以下是调用的 Status = SfIssueReadWriteIrpSynchronously( DevExt->AttachedToDeviceObject, FileObject, IRP_MJ_READ, &IoStatus, EncryptInfo, sizeof(ENCRYPT_INFO)-1, &ByteOffset, 0 ); ========================== 我用的是DevExt->AttachedToDeviceObject,但是不知为什么还是不能传下去执行,它还会触发我写的IRP_MJ_READ,IRP_MJ_Write, 这是为什么呢呀?有知道的吗,请告诉我一下,谢谢了先。 |
|
最新喜欢:Leopar...
|
沙发#
发布于:2007-02-27 09:42
请大侠不啬赐教呀
|
|
|
板凳#
发布于:2007-02-27 10:31
用shadowdevice 或者直接build irp
如果只考虑应用层,可以把kernelmode的访问pass 掉 |
|
|
地板#
发布于:2007-02-27 10:39
可以借鉴楚狂人的防重入的方法,创建一个自己的工作线程来完成,
然后在IRP派遣例程中排除和该工作线程有关的所有IRP请求。 |
|
|
地下室#
发布于:2007-02-27 10:48
可能是缓冲读写,所以cc mgr会调用你的DispatchRead/Write进行paging io
|
|
5楼#
发布于:2007-02-27 11:51
我自己构建irp往下传也不成,可以读到内容,但还是经过我的irp_mj_read,倒底为什么呀,我要疯了
读的irp代码: BOOLEAN MyReadDispatch(PDEVICE_OBJECT DeviceObject, PFILE_OBJECT FileObject, PUCHAR FileBuffer, ULONG FileBufferSize, PLARGE_INTEGER Offset ) { PIRP irp; KEVENT event; IO_STATUS_BLOCK IoStatusBlock; PIO_STACK_LOCATION irpSp; NTSTATUS Status; // // Set up the event we\'ll use. // KeInitializeEvent(&event, SynchronizationEvent, FALSE); // // Allocate an irp for this request. This could also come from a // private pool, for instance. // irp = IoAllocateIrp(DeviceObject->StackSize, FALSE); if (!irp) { return FALSE; } // // Build the IRP\'s main body // irp->UserEvent = &event; irp->UserIosb = &IoStatusBlock; irp->Tail.Overlay.Thread = PsGetCurrentThread(); irp->Tail.Overlay.OriginalFileObject = FileObject; irp->RequestorMode = KernelMode; irp->Flags = IRP_READ_OPERATION; // // Set up the I/O stack location. // irpSp = IoGetNextIrpStackLocation(irp); irpSp->MajorFunction = IRP_MJ_READ; irpSp->MinorFunction = 0; irpSp->DeviceObject = DeviceObject; irpSp->FileObject = FileObject; irp->MdlAddress = IoAllocateMdl( FileBuffer, FileBufferSize, FALSE, FALSE, (PIRP) NULL ); if (irp->MdlAddress == NULL) { IoFreeIrp( irp ); return FALSE; } try { MmProbeAndLockPages( irp->MdlAddress, KernelMode, (LOCK_OPERATION) (irpSp->MajorFunction == IRP_MJ_READ ? IoWriteAccess : IoReadAccess) ); } except(EXCEPTION_EXECUTE_HANDLER) { if (irp->MdlAddress != NULL) { IoFreeMdl( irp->MdlAddress ); } IoFreeIrp( irp ); return FALSE; } irp->UserBuffer = FileBuffer; irpSp->Parameters.Read.Length = FileBufferSize; irpSp->Parameters.Read.ByteOffset = *Offset; // // Set the completion routine. // IoSetCompletionRoutine(irp, MyReadCompleted, 0, TRUE, TRUE, TRUE); // // Send it to the FSD // Status = IoCallDriver(DeviceObject, irp); // // Wait for the I/O // if(Status == STATUS_PENDING) KeWaitForSingleObject(&event, Executive, KernelMode, TRUE, 0); return( NT_SUCCESS( IoStatusBlock.Status )); } NTSTATUS MyReadCompleted(PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context) { // // Copy the status information back into the \"user\" IOSB. // DeviceObject; Context; *Irp->UserIosb = Irp->IoStatus; if( !NT_SUCCESS(Irp->IoStatus.Status) ) { KdPrint((" ERROR ON IRP: %x\\n", Irp->IoStatus.Status )); } // // Set the user event - wakes up the mainline code doing this. // KeSetEvent(Irp->UserEvent, 0, FALSE); //清除我们创建的内存变量 if (Irp->MdlAddress) { MmUnmapLockedPages(MmGetSystemAddressForMdl(Irp->MdlAddress), Irp->MdlAddress); MmUnlockPages(Irp->MdlAddress); IoFreeMdl(Irp->MdlAddress); Irp->MdlAddress = NULL; } // // Free the IRP now that we are done with it. // IoFreeIrp(Irp); return STATUS_MORE_PROCESSING_REQUIRED; } ======================== 调用代码: PSFILTER_DEVICE_EXTENSION DevExt = (PSFILTER_DEVICE_EXTENSION) DeviceObject->DeviceExtension; UCHAR EncryptInfo[3]; LARGE_INTEGER ByteOffset; ByteOffset.QuadPart = 0; KdPrint(("SfPostCreateWorker star---------------------------")); MyReadDispatch(DevExt->AttachedToDeviceObject, FileObject, EncryptInfo, 2, &ByteOffset ); KdPrint(("SfPostCreateWorker finish---------------------------")); if (!NT_SUCCESS(Status) ) { KdPrint(("SfPostCreateWorker: Read Err")); } else { KdPrint(("SfPostCreateWorker: Read Context=%x",EncryptInfo[0])); KdPrint(("SfPostCreateWorker: Read Context=%x",EncryptInfo[1])); KdPrint(("SfPostCreateWorker: Read Success")); } |
|
|
6楼#
发布于:2007-02-28 09:57
检查你的CALLSTACK,怀疑你下面的某个家伙存在重入,虽然他自己能避免......
|
|
|
7楼#
发布于:2007-02-28 13:27
能告诉我怎么检查CALLSTACK吗?
你说的“重入的那个家伙”是我写的,还是系统自带的? 如果系统自己带的我怎么避过它? |
|
|
8楼#
发布于:2007-02-28 13:35
谢谢了先,着急呀
|
|
|
9楼#
发布于:2007-06-11 11:07
我也见到如此类的问题
我的需求是:在驱动的读调度历程监控到所要的读操作,这时候我在这里用KeWaitForSingleObject无限等待事件到达后在往下层驱动派发,也就是这时候被阻塞了, 这时候我想往这个文件里写点东西,我用ZwCreateFiles是能打开该文件的,但写的时候就被阻塞了,我用sfilter里面的方法也是一样,我没有试直接构建irp的方式 我有疑问就是:为何打开的时候不会被阻塞,而写的时候被阻塞了,他们不都要经过我们的驱动吗? 有大狭能解决此问题吗? |
|
驱动小牛
|
10楼#
发布于:2007-06-11 18:41
还是用IoCreateFileSpecifyDeviceObjectHint 吧,现在已经很少有用98的系统的了.即使是2000的,也可以让他装个SP4.防止重入可以考虑线程列表的做法.Zw***,IoCallDriver都可能引起重入.有时候Io***也会.重入最大的问题就是引起死锁,比蓝屏还讨厌!
|
|
11楼#
发布于:2007-06-13 09:58
用Shadow Device或IoGet...Hint.
|
|