reddargon
驱动小牛
驱动小牛
  • 注册日期2005-08-05
  • 最后登录2008-07-15
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望101点
  • 贡献值0点
  • 好评度100点
  • 原创分0分
  • 专家分0分
阅读:2647回复:12

怎样确定读写文件的长度?

楼主#
更多 发布于:2007-02-27 08:52
  在文件系统过滤驱动中,如何确定读写文件的长度?
在sfilter中添加SfRead和SfWrite例程,
打印PIO_STACK_LOCATION IrpSp;
Length = IrpSp->Parameters.Write.Length;信息时,发现却是4096。
不知道IrpSp中哪个参数可以表示文件的读写长度?

最新喜欢:

linshierlinshi...
reddargon
驱动小牛
驱动小牛
  • 注册日期2005-08-05
  • 最后登录2008-07-15
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望101点
  • 贡献值0点
  • 好评度100点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2007-03-02 17:36
有人说可以利用FCB(文件控制块)进行实现,但不清楚是怎么做的.
有知道的可以给指点一下吗?
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
板凳#
发布于:2007-03-02 18:01
Irp->IoStatus.Information ??

Irp->FileObject->CurrentByteOffset ??
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
地板#
发布于:2007-03-04 04:07
A filter just needs to pay attention to the ByteOffset field in the
stack location (pIrpSp->Parameters.Read.ByteOffset or
pIrpSp->Parameters.Write.ByteOffset), EXCEPT when HighPart is -1 and
LowPart is one of the two constants FILE_WRITE_TO_END_OF_FILE or
FILE_USE_FILE_POINTER_POSITION.

In the case of FILE_WRITE_TO_END_OF_FILE, then you need to interpret the
write as happening at the current EOF (whatever this means in the
context of your filter).

In the case of FILE_USE_FILE_POINTER_POSITION, you pull the intended
offset from the file object.

So a filter should never have to handle FILE_USE_FILE_POINTER_POSITION?
I thought this MIGHT be the case because FastFat does not check for this
flag. However, the flag is listed right next to
FILE_WRITE_TO_END_OF_FILE in ntifs.h, which FastFat DOES check for. I
decided to play it safe and handle both.

- Nicholas Ryan

That flag is never seen in the driver stack. You pass that into
NtRead/WriteFile (with HighPart == -1 as well) when you want IO to use
the file object cbo as the IO offset. It is equivalent to passing in a
NULL ByteOffset pointer to those APIs.

NT4 FASTFAT uses FILE_WRITE_TO_END_OF_FILE but does not use
FILE_USE_FILE_POINTER_POSITION.
Is there a change that these will appear if IRP_NOCACHE bit is set?

Nicholas Ryan wrote:
Yes, FILE_WRITE_TO_END_OF_FILE is compatible with IRP_NOCACHE (but not
IRP_PAGING_IO).

- Nicholas Ryan
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
地下室#
发布于:2007-03-04 04:12
EXCEPT when HighPart is -1 and
LowPart is one of the two constants FILE_WRITE_TO_END_OF_FILE or
FILE_USE_FILE_POINTER_POSITION.
关键是这句话,如果HighPart为-1时候,LowPart 为FILE_WRITE_TO_END_OF_FILE或者FILE_USE_FILE_POINTER_POSITION时候,表示为实际的长度
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
5楼#
发布于:2007-03-04 04:40
We are writing a filter driver and are having problems ( like many before by
the looks of it ;) )
We are trying to read from file in a completion routine when we receive
IRP_MJ_CREATE requests,
so that we can identify files we need to decrypt. (we have a header on our
files)
In the completion routine for the create we queue a work item to try and do
the read from and return STATUS_MORE_PROCESSING_REQUIRED.
In the worker function we use IoBuildSynchronousFsdRequest to create an IRP
for the read and send it on.

This all works fine in almost every circumstance... except when filtering
LanmanRedirector.
Sometimes the read fails with STATUS_ACCESS_DENIED  (0xC0000022).

Help... does anyone have any ideas? Possibly something to do with security?

We have tried SeCreateClientSecurity & SeImpersonateClient to no avail.

We have pasted the offending chunk of code below.

Thanks for any assitance..

Rob Linegar & Duncan Hume
Software Engineers
Data Encryption Systems Limited

// Running in the context of a worker thread - using ExInitializeWorkItem &
ExQueueWorkItem
void FSFil_FileCreateWorker( PFILE_CREATE_CONTEXT pContext )
{
    PDEVICE_OBJECT        pTargetDeviceObject;
    char                *pBuffer;
    IO_STATUS_BLOCK        IoStatusBlock;
       LARGE_INTEGER        ByteOffset;
    LARGE_INTEGER        OrigByteOffset;
    PFILE_OBJECT            pFileObject;

    pFileObject = IoGetCurrentIrpStackLocation( pContext->pOriginalIrp
)->FileObject;

    // Get the Previous filtered device object
    pTargetDeviceObject =
((PFSFIL_DEVICEEXTENSION)pContext->pDeviceObject->DeviceExtension)->pPrevDev
iceObject;

    // No point in continuing if there is no FileObject
    if (pFileObject)
    {
        // Allocate memory for our Buffer
        pBuffer = ExAllocatePool( NonPagedPool, 10 );
        if (pBuffer)
        {
            ByteOffset.QuadPart = 0;
            // Store the original byte offset
            OrigByteOffset = pFileObject->CurrentByteOffset;

            FO_ReadFile( pContext->pOriginalIrp,
pTargetDeviceObject, pFileObject, &ByteOffset, 5, pBuffer, &IoStatusBlock );

            // Restore the original byte offset
            pFileObject->CurrentByteOffset = OrigByteOffset;

            if (NT_SUCCESS(IoStatusBlock.Status))
            {
            }
            else
            {
             ///FAILS
            }

            // Free our read buffer
            ExFreePool( pBuffer );
        }
    }

    // Complete the Create Request
    IoCompleteRequest( pContext->pOriginalIrp, IO_NO_INCREMENT );

    // Free the create context data
    ExFreePool( pContext );
}

VOID FO_ReadFile( PIRP pIrp, PDEVICE_OBJECT pDeviceObject, PFILE_OBJECT
pFileObject, PLARGE_INTEGER Offset, ULONG Length, char * pBuffer,
PIO_STATUS_BLOCK IoStatusBlock )
{
    KEVENT            kEvent;
    PIRP                pReadIrp;
    NTSTATUS            ntStatus;
    
    // Initialise an event to wait for after calling the previous driver
    KeInitializeEvent( &kEvent, NotificationEvent, FALSE );

    // Build an Irp for the read
    pReadIrp = IoBuildSynchronousFsdRequest( IRP_MJ_READ, pDeviceObject,
pBuffer, Length, Offset, &kEvent, IoStatusBlock );
    if (pReadIrp)
    {
        PIO_STACK_LOCATION pReadStack = IoGetNextIrpStackLocation(
pReadIrp );

        // Caching? no thank you maam!
        pReadIrp->Flags = IRP_NOCACHE | IRP_READ_OPERATION;

        pReadIrp->Tail.Overlay.Thread = pIrp->Tail.Overlay.Thread;
        pReadIrp->RequestorMode = KernelMode;

        // We need a FileObject to identify the file we are reading
        pReadStack->FileObject = pFileObject;
        pReadStack->DeviceObject = pDeviceObject;

        // Call on to the previous driver
        ntStatus = IoCallDriver( pDeviceObject, pReadIrp );
        if (ntStatus == STATUS_PENDING)
        {
            // Wait for the Irp to complete if it is pending
            KeWaitForSingleObject( &kEvent, Executive,
KernelMode, FALSE, NULL );
        }
        else
            IoStatusBlock->Status = ntStatus;
    }
    else
    {
                IoStatusBlock->Status =
STATUS_INSUFFICIENT_RESOURCES;
                IoStatusBlock->Information = 0;
    }
}
reddargon
驱动小牛
驱动小牛
  • 注册日期2005-08-05
  • 最后登录2008-07-15
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望101点
  • 贡献值0点
  • 好评度100点
  • 原创分0分
  • 专家分0分
6楼#
发布于:2007-03-05 08:03
多谢lsxredrain,
我先看一下.
reddargon
驱动小牛
驱动小牛
  • 注册日期2005-08-05
  • 最后登录2008-07-15
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望101点
  • 贡献值0点
  • 好评度100点
  • 原创分0分
  • 专家分0分
7楼#
发布于:2007-03-06 12:52
好象还是不行呀,l只是在读写完成例程中可以看到读写后的信息,
但如果在读写例程中改变了文件长度,处理后得到还是原来文件长度的内容;
sxredrain,能否告知这些相关的资料可以在那个网站上找到?
多谢。
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
8楼#
发布于:2007-03-06 13:13
http://www.osronline.com
上面,测试发现
在write中Irp->FileObject->CurrentByteOffset 可以代表真实的文件偏移,但是read中是不对的
reddargon
驱动小牛
驱动小牛
  • 注册日期2005-08-05
  • 最后登录2008-07-15
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望101点
  • 贡献值0点
  • 好评度100点
  • 原创分0分
  • 专家分0分
9楼#
发布于:2007-03-06 13:20
是的,我在调试时也是同样的结果;
只是在进行写操作时可以看到。
如果处理后的长度比原来的大,就需要重新考虑了。
我记得在以前的帖子中,有人给出重新分配一块内存,拷贝原来的Irp进行处理,但不知道最后的结果怎样。
lsxredrain
驱动中牛
驱动中牛
  • 注册日期2006-08-31
  • 最后登录2008-10-18
  • 粉丝1
  • 关注0
  • 积分540分
  • 威望421点
  • 贡献值1点
  • 好评度420点
  • 原创分4分
  • 专家分0分
10楼#
发布于:2007-03-06 13:36
我是用压缩法,不需要改变文件长度,写时把需要解压的长度和位置记下来,读时检查文件头就行了.其实对于磁盘上的文件,只有写时才有文件长度改变的
在osr上面搜索一下相关的资料看看,这几天在准备考博,没有太多时间去钻研这了,有好消息通报通报
dargons
驱动小牛
驱动小牛
  • 注册日期2005-11-18
  • 最后登录2008-07-25
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望273点
  • 贡献值0点
  • 好评度272点
  • 原创分0分
  • 专家分0分
11楼#
发布于:2007-03-08 17:27
我在tooflat所给的代码上进行处理的.
由于使用了分组算法导致文件长度增加,在读时无法正确解密.
比如我要输入40字节的明文,经驱动加密处理后会产生48字节密文,
但在实际写入文件时它只写入了密文的前面40字节.

现在的问题是:如何在实际写入时,写入48字节的密文;
在读时利用48字节的密文将明文还原出来.

关键是怎样写入这48字节的明文.
这其中就牵涉到文件的变长处理问题.
各位大牛们可否给些参考呢?
linuxyf
驱动小牛
驱动小牛
  • 注册日期2007-04-03
  • 最后登录2016-01-09
  • 粉丝0
  • 关注0
  • 积分1000分
  • 威望162点
  • 贡献值0点
  • 好评度161点
  • 原创分1分
  • 专家分0分
12楼#
发布于:2007-05-09 19:43
我也遇到了同样的问题,也没有解决
在孤独和无助中缓慢前行...
游客

返回顶部