文件重定向

来源:互联网 发布:淘宝宝贝分类怎么编辑 编辑:程序博客网 时间:2024/04/30 22:03

文件重定向(采用文件过滤驱动实现)

Windows的I/O管理器提供了一个方便的方法来重定向一个文件对象。通常使用文件过滤驱动(在文件打开和文件创建的操作中)实现该方法。操作方法如下:

1、在IRP_MJ_CREATE的分发函数中,获得FILE_OBJET的FileName属性。

2、用目标文件的完整路径替换原有的文件名字。

这个全名,包括卷设备对象的名字(例如,Device\HardDiskVolume0\Directory\MyFile.txt)。可以释放掉原有的FileName.Buffer,同时用自己定义的缓冲区(buffer,以NonPagedPool方式申请)替换它。

3、设置IoStatus的status字段为STATUS_REPARSE,然后设置Information字段为IO_REPARSE.

4、完成该IRP请求。

5、返回STATUS_REPARSE

I/O管理器接收到该返回后,便会触发另一个文件打开操作,并发送一个IRP_MJ_CREATE的请求。

 

‍ 而目标文件可以是本地或远程计算机。而若要重定向远程文件打开操作,文件名要遵循以下语法:

"\??\UNC\HostName\Share\File"

"\Device\Mup\HostName\Share\File"

"\Device\LanmanagerRedirector\HostName\Share\File"(在你的目标文件是CIFS/SMB/LanManager的情况下)

在你的首次打开/创建文件操作是相对于另一个文件对象的时候,没有必有修改FILE_OBJECT的RelatedFileObject域。在重定向时,I/O管理器只考虑FileName域,而不考虑RelatedFileObject域(在I/O管理器收到STATUS_REPARSE后,它便会释放该域)。

I/O管理器为了避免重定向的无限循环,在嵌套循环中加了一些限制:重定向操作的最大嵌套次数是32.

 

代码

IRP_MJ_CREATE例程里添加如下代码:

irpSp = IoGetCurrentIrpStackLocation(Irp);

   RtlInitUnicodeString(&cmpFileName, L"\\hello.txt");

   KdPrint((">>> Create/Open FileName:%ws\n", irpSp->FileObject->FileName.Buffer));

   if (RtlCompareUnicodeString(&cmpFileName, &irpSp->FileObject->FileName, FALSE) == 0)

   {

    pusFileName = &(irpSp->FileObject->FileName);

    // 方法很简单

    // 就是把FileObject->FileName.Buffer释放掉

    // 然后自己ExAllocatePool...分配一个缓冲区用于保存重定向的文件名 这里需要是全文件名

    // FileObject->FileName指向新分配的缓冲区

    // 把新文件名拷贝到FileObject->FileName里

    // 设置Irp->IoStatus的值如下

    // Irp->IoStatus.Status = STATUS_REPARSE;

    // Irp->IoStatus.Information = IO_REPARSE;

    // 返回STATUS_REPARSE

    // 经测试跨卷访问也可以

    RtlInitUnicodeString(&usNewFileName, L"\\??\\E:\\123\\hello.txt");

    pwNewNameBuffer = ExAllocatePool(PagedPool, usNewFileName.MaximumLength);

    if (pwNewNameBuffer == NULL)

    {

     Irp->IoStatus.Status = STATUS_INSUFFICIENT_RESOURCES;

     Irp->IoStatus.Information = 0;

 

     IoCompleteRequest( Irp, IO_NO_INCREMENT );

     return STATUS_INSUFFICIENT_RESOURCES;

    }

 

    ExFreePool( pusFileName->Buffer );

    pusFileName->Buffer = pwNewNameBuffer;

    pusFileName->MaximumLength = usNewFileName.MaximumLength;

    RtlCopyUnicodeString(pusFileName, &usNewFileName);

 

    Irp->IoStatus.Status = STATUS_REPARSE;

    Irp->IoStatus.Information = IO_REPARSE;

    IoCompleteRequest( Irp, IO_NO_INCREMENT );

    return STATUS_REPARSE;

}

原创粉丝点击