driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
阅读:1992回复:15

救救我文件被塞住了

楼主#
更多 发布于:2007-07-12 13:29
我用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 不返回 大家帮我看看问题出在哪啦    
我的目的是读文件时先让该文件写些东西,再去读,现在发现被阻塞住了
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-07-12 13:33
hehe ,我昨天发的贴子,也是这个问题,在read中发自己的read irp 时lock了
driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
板凳#
发布于:2007-07-12 14:42
你是想实现啥样的功能?
liyunch
驱动小牛
驱动小牛
  • 注册日期2001-06-28
  • 最后登录2014-09-05
  • 粉丝0
  • 关注0
  • 积分13分
  • 威望134点
  • 贡献值0点
  • 好评度94点
  • 原创分0分
  • 专家分0分
地板#
发布于:2007-07-12 15:16
最好用异步
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
地下室#
发布于: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.
driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
5楼#
发布于:2007-07-13 10:20
michaelgz  你好!
如果在irp->flags 我加上irpnocache 的标记可以?
还有就是我用异步的方式可以吗?
global variable  我现在只是做下测试
我是实现的是在读之前我要写些东西到该文件,有啥好办法能实现呢?就是绕过我们的驱动
谢谢!
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
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.
driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-07-16 10:54
我的需求是这样的:
        其实这是个临时的文件,该临时文件做为缓冲,真正的文件的内容是在网络上的服务器上
    在读之前要判断缓冲文件的内容是不是更新,没有更新的话就去网络上把文件内容读回来写到该临时文件里,再让文件去读操作
    这就是在读的时候要等待的原因
    难道就没有办法能绕过文件系统的监控去写了吗?我尝试在挂接我们的分区时候把原来的分区对象记住,再向原来的对象发写命令好象也不行
  
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
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;
}
driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-07-16 17:14
我的需求是这样的:
        上层程序读本地的一个临时文件,这个临时文件做为远程文件的缓冲,
         在读之前判断下文件的内容是不是更新过,
         如果要更新的话就首先从远程读回来,
         再写到该临时文件里
    现在的问题是读被阻塞了,而写又会触发读,这样就被锁住了
    有没有好办法写的时候不触发读操作呢?
         或者能不能有办法绕过监控去写呢?
michaelgz
论坛版主
论坛版主
  • 注册日期2005-01-26
  • 最后登录2012-10-22
  • 粉丝1
  • 关注1
  • 积分150分
  • 威望1524点
  • 贡献值1点
  • 好评度213点
  • 原创分0分
  • 专家分2分
10楼#
发布于:2007-07-16 22:14
Why not using reparse points?
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-07-17 18:19
reparse points?what??
znsoft
管理员
管理员
  • 注册日期2001-03-23
  • 最后登录2023-10-25
  • 粉丝300
  • 关注6
  • 积分910分
  • 威望14796点
  • 贡献值7点
  • 好评度2410点
  • 原创分5分
  • 专家分100分
  • 社区居民
  • 最爱沙发
  • 社区明星
12楼#
发布于:2007-07-17 18:29
引用第11楼wengzuhong于2007-07-17 18:19发表的  :
reparse points?what??



就是把文件路径改了,返回 reparse 状态,让上层去读新的
http://www.zndev.com 免费源码交换网 ----------------------------- 软件创造价值,驱动提供力量! 淡泊以明志,宁静以致远。 ---------------------------------- 勤用搜索,多查资料,先搜再问。
wengzuhong
驱动小牛
驱动小牛
  • 注册日期2004-07-16
  • 最后登录2014-10-22
  • 粉丝3
  • 关注1
  • 积分9分
  • 威望262点
  • 贡献值0点
  • 好评度219点
  • 原创分0分
  • 专家分0分
13楼#
发布于:2007-07-17 18:39
thx
driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
14楼#
发布于:2007-07-18 16:43
不能用冲定向的
大家有好办法的话有报酬的
driver12345
驱动牛犊
驱动牛犊
  • 注册日期2005-11-15
  • 最后登录2007-10-28
  • 粉丝0
  • 关注0
  • 积分814分
  • 威望84点
  • 贡献值0点
  • 好评度82点
  • 原创分0分
  • 专家分0分
15楼#
发布于:2007-08-19 20:02
自己顶起!
哪位帅哥或者靓女能解决此问题呀?
报酬再商谈!
我的联系方式:work_beijin@hotmail.com
游客

返回顶部