阅读:1992回复:15
救救我文件被塞住了
我用FileMon 来实现监控,在读的处理中我做了如下的处理:
if( (strstr(fullPathName,"test.tmp")) ) { if( (Irp->Flags&IRP_NOCACHE) || (Irp->Flags&IRP_PAGING_IO) || (Irp->Flags&IRP_SYNCHRONOUS_PAGING_IO) ) { Alert(); g_HookDevice = HookDevice; g_FileObject = currentIrpStack->FileObject; ; KeInitializeEvent(&g_Event, NotificationEvent, FALSE); KeWaitForSingleObject(&g_Event, Executive, KernelMode, FALSE, NULL); //等待操作完成 } } 在另外一个线程中 Irp = IoBuildSynchronousFsdRequest( IRP_MJ_WRITE, //写操作 g_HookDevice, Buffer, Length, ByteOffset, &Event, IoStatus ); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; Irp->Flags |= IrpFlags; //获得下一级驱动的指针给IrpSp IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->FileObject = g_FileObject; //刚在读处理中的文件 //执行 Status = IoCallDriver(g_HookDevice, Irp); //向该文件写些东西 KeSetEvent(&g_Event, LOW_REALTIME_PRIORITY, FALSE); //让刚被阻塞的读继续 我发现在调用IoCallDriver 不返回 大家帮我看看问题出在哪啦 我的目的是读文件时先让该文件写些东西,再去读,现在发现被阻塞住了 |
|
沙发#
发布于:2007-07-12 13:33
hehe ,我昨天发的贴子,也是这个问题,在read中发自己的read irp 时lock了
|
|
板凳#
发布于:2007-07-12 14:42
你是想实现啥样的功能?
|
|
地板#
发布于:2007-07-12 15:16
最好用异步
|
|
地下室#
发布于:2007-07-12 23:47
In paging READ path, the PagingIOResource is acquired, then you are trying to issue a WRITE which needs to acquire this PagingIOResource again. That's a deadlock. Generally you cannot do that.
BTW, It's dangerous to use global variable to pass data between threads without any synchronization. |
|
5楼#
发布于:2007-07-13 10:20
michaelgz 你好!
如果在irp->flags 我加上irpnocache 的标记可以? 还有就是我用异步的方式可以吗? global variable 我现在只是做下测试 我是实现的是在读之前我要写些东西到该文件,有啥好办法能实现呢?就是绕过我们的驱动 谢谢! |
|
6楼#
发布于:2007-07-13 22:31
如果在irp->flags 我加上irpnocache 的标记可以? No 我用异步的方式可以吗? You can pend your WRITE IRP in another thread, but you cannot wait on it in paging path. FSD synchronization is really tricky. General suggestion is that don't synchronize between different IO paths, especially for non-cached IOs, in a FSFD. 在读之前我要写些东西到该文件 Don't know why you need to do it. No comments. |
|
7楼#
发布于:2007-07-16 10:54
我的需求是这样的:
其实这是个临时的文件,该临时文件做为缓冲,真正的文件的内容是在网络上的服务器上 在读之前要判断缓冲文件的内容是不是更新,没有更新的话就去网络上把文件内容读回来写到该临时文件里,再让文件去读操作 这就是在读的时候要等待的原因 难道就没有办法能绕过文件系统的监控去写了吗?我尝试在挂接我们的分区时候把原来的分区对象记住,再向原来的对象发写命令好象也不行 |
|
8楼#
发布于:2007-07-16 13:41
实现功能: 在sfcreate中发送自己的irp(read)并得到数据
1. 在sfcreate中的得到全路径后调用(发送自建的irp) 运行调试的过程: 1. irp经过sfread、sfreadcomplete、SfIssueReadWriteIrpSynchronously、irpCompletion 2. 在sfread、sfreadcomplete、SfIssueReadWriteIrpSynchronously、irpCompletion中都能看到Buffer的长度,但是Buffer为空 3. 程序运行的过程,先后顺序 sfread->sfreadcomplete->SfIssueReadWriteIrpSynchronously>irpCompletion 4. Buffer为空,为什么??问题所在 5. ntfs下可以调试,fat下黑屏,我正在调试。。。 static NTSTATUS irpCompletion( PDEVICE_OBJECT DeviceObject, PIRP Irp, PVOID Context ) { UNREFERENCED_PARAMETER( DeviceObject ); UNREFERENCED_PARAMETER( Context ); KeSetEvent(Irp->UserEvent, 0, FALSE); // Signal event *Irp->UserIosb = Irp->IoStatus; // Copy status information to // the user KdPrint(("sfilter!irpCompletion[%s]\n", Irp->UserBuffer)); if (Irp->MdlAddress) { MmUnmapLockedPages( MmGetSystemAddressForMdl(Irp->MdlAddress), Irp->MdlAddress); MmUnlockPages(Irp->MdlAddress); IoFreeMdl(Irp->MdlAddress); } IoFreeIrp(Irp); // Free IRP return STATUS_MORE_PROCESSING_REQUIRED; // Tell the I/O manager to stop } 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; UNREFERENCED_PARAMETER( IrpFlags ); ASSERT((MajorFunction == IRP_MJ_READ) || (MajorFunction == IRP_MJ_WRITE)); KeInitializeEvent(&Event, NotificationEvent, FALSE); Irp = IoBuildAsynchronousFsdRequest( MajorFunction, DeviceObject, Buffer, Length, ByteOffset, //&Event, IoStatus ); if (!Irp) return STATUS_INSUFFICIENT_RESOURCES; Irp->Flags = IRP_NOCACHE ;//IRP_READ_OPERATION | IRP_PAGING_IO | IRP_SYNCHRONOUS_PAGING_IO;//IRP_PAGING_IO+IRP_NOCACHE+IRP_SYNCHRONOUS_PAGING_IO(0x43); Irp->RequestorMode = KernelMode; Irp->UserEvent = &Event; IrpSp = IoGetNextIrpStackLocation(Irp); IrpSp->FileObject = FileObject; IrpSp->DeviceObject = DeviceObject; KdPrint(("sfilter!SfIssueReadWriteIrpSynchronously: Length = [%d]\n", IrpSp->Parameters.Read.Length)); KdPrint(("sfilter!SfIssueReadWriteIrpSynchronously: ByteOffset = [%d]\n", IrpSp->Parameters.Read.ByteOffset)); IoSetCompletionRoutine(Irp, &irpCompletion, 0, TRUE, TRUE, TRUE); Status = IoCallDriver(DeviceObject, Irp); //Irp = NULL; if (STATUS_PENDING == Status) { KeWaitForSingleObject(&Event, Executive, KernelMode, FALSE, NULL); } KdPrint(("sfilter!SfIssueReadWriteIrpSynchronously[%s]\n",Buffer)); KdPrint(("sfilter!SfIssueReadWriteIrpSynchronously[%ws]\n",Buffer)); return IoStatus->Status; } NTSTATUS SfEncryptDecryptFileByFileObject( IN PDEVICE_OBJECT DeviceObject, IN PFILE_OBJECT FileObject ) { IO_STATUS_BLOCK IoStatus = {0}; NTSTATUS Status; PVOID Buffer = NULL; LARGE_INTEGER ByteOffset; ULONG Length = MARKLEN; LARGE_INTEGER OrigByteOffset; ByteOffset = FileObject->CurrentByteOffset; while(TRUE) { IoStatus.Status = STATUS_SUCCESS; IoStatus.Information = 0; Buffer = ExAllocatePool( NonPagedPool, Length ); if(Buffer == NULL) break; RtlZeroMemory(Buffer, MARKLEN ); RtlFillMemory(Buffer, MARKLEN-1, 'H'); *((PCHAR)(Buffer) + MARKLEN-1) = 0; OrigByteOffset = FileObject->CurrentByteOffset; Status = SfIssueReadWriteIrpSynchronously( DeviceObject, FileObject, IRP_MJ_READ, &IoStatus, Buffer, Length, &ByteOffset, 0 ); // Restore the original byte offset FileObject->CurrentByteOffset = OrigByteOffset; if (!NT_SUCCESS(Status)) { if (STATUS_END_OF_FILE == Status) { Status = STATUS_SUCCESS; KdPrint(("sfilter!SpyCreate: SfEncryptDecryptFileByFileObject: Status == STATUS_END_OF_FILE\n")); } break; } if (0 == IoStatus.Information) { KdPrint(("sfilter!SpyCreate: SfEncryptDecryptFileByFileObject: IoStatus.Information == 0 and %d\n", strlen(Buffer))); break; } break; } KdPrint(("sfilter!SfEncryptDecryptFileByFileObject: buffer: [%d][%s]\n", strlen(Buffer), Buffer)); if (Buffer != NULL) { ExFreePool( Buffer ); } return Status; } |
|
9楼#
发布于:2007-07-16 17:14
我的需求是这样的:
上层程序读本地的一个临时文件,这个临时文件做为远程文件的缓冲, 在读之前判断下文件的内容是不是更新过, 如果要更新的话就首先从远程读回来, 再写到该临时文件里 现在的问题是读被阻塞了,而写又会触发读,这样就被锁住了 有没有好办法写的时候不触发读操作呢? 或者能不能有办法绕过监控去写呢? |
|
10楼#
发布于:2007-07-16 22:14
Why not using reparse points?
|
|
11楼#
发布于:2007-07-17 18:19
reparse points?what??
|
|
12楼#
发布于:2007-07-17 18:29
引用第11楼wengzuhong于2007-07-17 18:19发表的 : 就是把文件路径改了,返回 reparse 状态,让上层去读新的 |
|
|
13楼#
发布于:2007-07-17 18:39
thx
|
|
14楼#
发布于:2007-07-18 16:43
不能用冲定向的
大家有好办法的话有报酬的 |
|
15楼#
发布于:2007-08-19 20:02
自己顶起!
哪位帅哥或者靓女能解决此问题呀? 报酬再商谈! 我的联系方式:work_beijin@hotmail.com |
|