wwwxdmfive
驱动牛犊
驱动牛犊
  • 注册日期2002-07-19
  • 最后登录2005-07-25
  • 粉丝0
  • 关注0
  • 积分0分
  • 威望0点
  • 贡献值0点
  • 好评度0点
  • 原创分0分
  • 专家分0分
阅读:1782回复:1

困扰已久的问题,请教

楼主#
更多 发布于:2004-07-13 10:36
  我正做一个网络硬盘的类似产品。客户端在文件系统驱动这一层实现。也就是将IRP_MJ_CREATE,IRP_MJ_READ,IRP_MJ_WRITE,IRP_MJ_CLOSE等对文件和目录的操作通过网络发送给服务器程序,服务器程序在操作服务器本地的文件和目录,并将结果和数据返回给客户端。
  现在有一个问题是,在EXPLORE中从本地硬盘向网络硬盘拷贝文件时,进度对话框开始进展很快(而实际上写入并没有完成那么多),很快进度条指示拷贝将完成,这时进度条停滞不前,直到文件拷贝完成。一句话,EXPLORE的拷贝文件的进度对话框不能正常指示文件写入的进度。
  现在整个系统已经差不多了,能读能写,能建立文件目录等,功能基本和本地硬盘差不多了。只是拷贝文件到网络硬盘时进度对话框不正常。
  http://ud.35.com可以下载一个试用。
  IRP_MJ_WRITE的实现机制时这样的:

DWrite (IN PND_IRP_CONTEXT IrpContext)
{
    NTSTATUS            Status;
    PND_FCB             Fcb;
    PDEVICE_OBJECT      DeviceObject;
    PFILE_OBJECT        FileObject;
    PND_VCB             Vcb;


    __try
    {
        if (FlagOn(IrpContext->MinorFunction, IRP_MN_COMPLETE))
        {
            Status =  NDWriteComplete(IrpContext);
        }
        else
        {
            DeviceObject = IrpContext->DeviceObject;

            if (DeviceObject == NDGlobal->DeviceObject)
            {
                Status = NDCompleteIrpContext(IrpContext, STATUS_INVALID_DEVICE_REQUEST);
                __leave;
            }

            Vcb = (PND_VCB) DeviceObject->DeviceExtension;

            FileObject = IrpContext->FileObject;

            Fcb = (PND_FCB) FileObject->FsContext;

            if (Fcb->NodeType == NDFCB
                && !FlagOn(Fcb->FileAttr,FF_DIRECTORY) )
            {
                Status = NDWriteFile(IrpContext);
            }
            else
            {
                Status = NDCompleteIrpContext(IrpContext, STATUS_INVALID_PARAMETER);
            }
        }
    }

    __finally
    {

    }

    return Status;
}

//#pragma code_seg("PAGE")
NTSTATUS
NDWriteFile(IN PND_IRP_CONTEXT IrpContext)
{
    NTSTATUS            Status = STATUS_UNSUCCESSFUL;

    PND_VCB             Vcb;
    PND_FCB             Fcb;
    PND_CCB             Ccb;
    PFILE_OBJECT        FileObject;
    PFILE_OBJECT        CacheObject;

    PDEVICE_OBJECT      DeviceObject;

    PIRP                Irp;
    PIO_STACK_LOCATION  IoStackLocation;

    ULONG               Length;
    ULONG               ReturnedLength;
    LARGE_INTEGER       ByteOffset;
    PWRITE_CONTEXT      WriteContext = NULL;

    BOOLEAN             PagingIo;
    BOOLEAN             Nocache;
    BOOLEAN             SynchronousIo;
    BOOLEAN             MainResourceAcquired = FALSE;
    BOOLEAN             PagingIoResourceAcquired = FALSE;

    BOOLEAN             bNeedExtending = FALSE;
    BOOLEAN             bAppendFile = FALSE;

    PUCHAR              Buffer;

    __try
    {

        DeviceObject = IrpContext->DeviceObject;

        Vcb = (PND_VCB) DeviceObject->DeviceExtension;

        FileObject = IrpContext->FileObject;

        Fcb = (PND_FCB) FileObject->FsContext;

        Ccb = (PND_CCB) FileObject->FsContext2;

        Irp = IrpContext->Irp;

        IoStackLocation = IoGetCurrentIrpStackLocation(Irp);

        Length = IoStackLocation->Parameters.Write.Length;
        ByteOffset = IoStackLocation->Parameters.Write.ByteOffset;

        PagingIo = (Irp->Flags & IRP_PAGING_IO ? TRUE : FALSE);
        Nocache = (Irp->Flags & IRP_NOCACHE ? TRUE : FALSE);
        SynchronousIo = (FileObject->Flags & FO_SYNCHRONOUS_IO ? TRUE : FALSE);

        KdPrint(("NDWriteFile: Len=%xh Off=%I64x Paging=%xh Nocache=%xh\n", Length, ByteOffset.QuadPart, PagingIo, Nocache));

        if (Length == 0)
        {
            Irp->IoStatus.Information = 0;
            Status = STATUS_SUCCESS;
            __leave;
        }

        //非缓冲读写,offset 和 Length 都必需是扇区大小的整数倍
        if (Nocache &&
           (ByteOffset.LowPart & (512 - 1) ||
            Length & (512 - 1)))
        {
            Status = STATUS_INVALID_PARAMETER;
            __leave;
        }

        //如果是延迟操作,将请求POST
        if (FlagOn(IrpContext->MinorFunction, IRP_MN_DPC))
        {
            ClearFlag(IrpContext->MinorFunction, IRP_MN_DPC);
            Status = STATUS_PENDING;
            __leave;
        }

        //如果是在文件末尾追加,偏移置为文件的当前大小。
        if (IsEndOfFile(ByteOffset))
        {
            bAppendFile = TRUE;
            ByteOffset.QuadPart = Fcb->CommonFCBHeader.FileSize.QuadPart;
        }

//
// FLUSH缓冲区。对于非缓冲写(非页),为了一直性,必需FLUSH缓冲区
//
if (Nocache && !PagingIo && (Fcb->SectionObject.DataSectionObject != NULL))
{
            ExAcquireResourceExclusive(&Fcb->MainResource, IsFlagOn(IrpContext->Flag, ICF_WAIT));
            MainResourceAcquired = TRUE;

            ExAcquireSharedStarveExclusive( &Fcb->PagingIoResource, TRUE);
            ExReleaseResource(&Fcb->PagingIoResource);

CcFlushCache( &(Fcb->SectionObject),
                          &ByteOffset,
                          Length,
                          &(Irp->IoStatus));
            ClearFlag(Fcb->Flag, FF_FILE_MODIFIED);

if (!NT_SUCCESS(Irp->IoStatus.Status))
{
                Status = Irp->IoStatus.Status;
__leave;
}

            ExAcquireSharedStarveExclusive( &Fcb->PagingIoResource, TRUE);
            ExReleaseResource(&Fcb->PagingIoResource);

CcPurgeCacheSection( &(Fcb->SectionObject),
                                 (PLARGE_INTEGER)&(ByteOffset),
Length,
                                 FALSE );

            ExReleaseResource(&Fcb->MainResource);
            MainResourceAcquired = FALSE;
}

        //IF 不是页操作 THEN
        //加Fcb的MainResouce排他锁
        //ELSE
        //加Fcb的MainResouce共享锁
        //ENDIF
        if (!PagingIo)
        {
            if (!ExAcquireResourceSharedLite(
                &Fcb->MainResource,
                IrpContext->IsSynchronous ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            MainResourceAcquired = TRUE;
        }
        else
        {
            if (!ExAcquireResourceSharedLite(
                &Fcb->PagingIoResource,
                IrpContext->IsSynchronous ))
            {
                Status = STATUS_PENDING;
                __leave;
            }

            PagingIoResourceAcquired = TRUE;
        }

        //检查是否于加在文件上的字节锁冲突(对非也文件)
        if (!PagingIo)
        {
            if (!FsRtlCheckLockForWriteAccess(
                &Fcb->FileLockAnchor,
                Irp         ))
            {
                Status = STATUS_FILE_LOCK_CONFLICT;
                __leave;
            }
        }

        //非缓冲写不能超出文件的现有分配空间。如果需要对offset和length进行调整。
        if (Nocache)
        {
            if (ByteOffset.QuadPart + Length > Fcb->CommonFCBHeader.AllocationSize.QuadPart)
            {
                if (ByteOffset.QuadPart >= Fcb->CommonFCBHeader.AllocationSize.QuadPart)
                {
                    Status = STATUS_SUCCESS;
                    Irp->IoStatus.Information = 0;
                    __leave;
                }
                else
                {
                    if (Length > (ULONG)(Fcb->CommonFCBHeader.AllocationSize.QuadPart - ByteOffset.QuadPart))
                        Length = (ULONG)(Fcb->CommonFCBHeader.AllocationSize.QuadPart - ByteOffset.QuadPart);
                }
            }
        }

        //如果是缓冲写,且缓冲区未初使化,初使化缓冲区.
        if (!Nocache)
        {
            if (FileObject->PrivateCacheMap == NULL)
            {
                CcInitializeCacheMap(
                    FileObject,
                    (PCC_FILE_SIZES)(&Fcb->CommonFCBHeader.AllocationSize),
                    FALSE,
                    &NDGlobal->CacheManagerCallbacks,
                    Fcb );

                //CcSetReadAheadGranularity( FileObject, READ_AHEAD_GRANULARITY);
                //CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->CommonFCBHeader.AllocationSize)));
            }

            CacheObject = FileObject;
       }
       //
       //  扩展文件
       //
       if (!Nocache)
       {
            if (bAppendFile || ((ULONG)(ByteOffset.QuadPart + Length) >
                (ULONG)(Fcb->CommonFCBHeader.FileSize.QuadPart)))
            {

                LARGE_INTEGER   ExtendSize;
                LARGE_INTEGER   FileSize;

                bNeedExtending = TRUE;
                FileSize = Fcb->CommonFCBHeader.FileSize;
                ExtendSize.QuadPart = (LONGLONG)(ByteOffset.QuadPart + Length);

                if (ExtendSize.QuadPart > Fcb->CommonFCBHeader.AllocationSize.QuadPart)
                {
                    if (!NDExpandFileAllocation(IrpContext, Vcb, Fcb, &ExtendSize))
                    {
                        Status = STATUS_INSUFFICIENT_RESOURCES;
                        __leave;
                    }
                }

                {
                    Fcb->CommonFCBHeader.FileSize.QuadPart = ExtendSize.QuadPart;
                }

                //对缓冲区进行调整。以下的方法可能并不合适
                if (FileObject->PrivateCacheMap)
                {
                    //通知CMM,文件大小已经改变
                    CcSetFileSizes(FileObject, (PCC_FILE_SIZES)(&(Fcb->CommonFCBHeader.AllocationSize)));

                    //将文件空隙清除为0
                    if (ByteOffset.QuadPart > FileSize.QuadPart)
                    {
                        NDZeroHoles(
                            IrpContext,
                            Vcb,
                            FileObject,
                            FileSize.QuadPart,
                            ByteOffset.QuadPart - FileSize.QuadPart);
                    }

                    //将文件空隙清除为0
                    if (Fcb->CommonFCBHeader.AllocationSize.QuadPart > ExtendSize.QuadPart)
                    {
                        NDZeroHoles(
                            IrpContext,
                            Vcb,
                            FileObject,
                            ExtendSize.QuadPart,
                            Fcb->CommonFCBHeader.AllocationSize.QuadPart - ExtendSize.QuadPart);
                    }
                }

            }
        }

        //真正的文件写

        //缓冲写
        if (!Nocache)
        {
            //MDL缓冲写
            if (FlagOn(IrpContext->MinorFunction, IRP_MN_MDL))
            {
                CcPrepareMdlWrite(
                    CacheObject,
                    (&ByteOffset),
                    Length,
                    &Irp->MdlAddress,
                    &Irp->IoStatus );

                Status = Irp->IoStatus.Status;
            }
            //非MDL缓冲文件写
            else
            {
                Buffer = GetUserBuffer(Irp);

                if (Buffer == NULL)
                {
                    Status = STATUS_INVALID_USER_BUFFER;
                    __leave;
                }

                if (!CcCopyWrite(
                    CacheObject,
                    (PLARGE_INTEGER)&ByteOffset,
                    Length,
                    IrpContext->IsSynchronous,
                    Buffer  ))
                {
                    Status = STATUS_PENDING;
                    __leave;
                }

                Status = Irp->IoStatus.Status;
            }

            if (NT_SUCCESS(Status))
                Irp->IoStatus.Information = Length;

        }
        //直接写
        else
        {

            Status = LockUserBuffer(
                IrpContext->Irp,
                Length,
                IoReadAccess );
            if (!NT_SUCCESS(Status))
            {
                __leave;
            }

            Buffer = GetUserBuffer(Irp);
            if (Buffer == NULL)
            {
                Status = STATUS_INVALID_USER_BUFFER;
                __leave;
            }

            WriteContext = ExAllocatePool(PagedPool,sizeof(WRITE_CONTEXT));
            if (WriteContext ==  NULL)
            {
                Status = STATUS_INSUFFICIENT_RESOURCES;
                __leave;
            }

            if ( ByteOffset.QuadPart + Length > Fcb->CommonFCBHeader.FileSize.QuadPart )
            {
                if (ByteOffset.QuadPart > Fcb->CommonFCBHeader.FileSize.QuadPart)
                {
                    Length = 0;
                    ByteOffset.QuadPart = Fcb->CommonFCBHeader.FileSize.QuadPart;
                }
                else
                {
                    Length = (ULONG)Fcb->CommonFCBHeader.FileSize.QuadPart - (ULONG)ByteOffset.QuadPart;
                }
            }
            
            ReturnedLength = Length;
            
            RtlZeroMemory(WriteContext,sizeof(WRITE_CONTEXT));
            WriteContext->Offset = (ULONG)ByteOffset.QuadPart;
            WriteContext->Buffer = Buffer;
            WriteContext->Length = Length;
            WriteContext->Vcb = Vcb;
            WriteContext->Fcb = Fcb;

            Status = NDNetWrite(
                IrpContext,
                WriteContext);
            if (NT_SUCCESS(Status))
            {
                Irp->IoStatus.Status = STATUS_SUCCESS;
                Irp->IoStatus.Information = ReturnedLength;
            }
            else
            {
                Irp->IoStatus.Status = STATUS_SUCCESS;
                Irp->IoStatus.Information = 0;
            }
            Irp = IrpContext->Irp;

        }
    }

    __finally
    {
        if (PagingIoResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->PagingIoResource,
                ExGetCurrentResourceThread());
        }

        if (MainResourceAcquired)
        {
            ExReleaseResourceForThreadLite(
                &Fcb->MainResource,
                ExGetCurrentResourceThread());
        }
        
        if (WriteContext)
            ExFreePool(WriteContext);

        if (!IrpContext->ExceptionInProgress)
        {
            if (Irp)
            {
                if (Status == STATUS_PENDING)
                {
                    Status = LockUserBuffer(
                        IrpContext->Irp,
                        Length,
                        IoReadAccess );

                    if (NT_SUCCESS(Status))
                    {
                        Status = NDQueueRequest(IrpContext);
                    }
                    else
                    {
                        IrpContext->Irp->IoStatus.Status = Status;
                        NDCompleteRequest(IrpContext->Irp, IO_NO_INCREMENT);
                        NDFreeIrpContext(IrpContext);
                    }
                }
                else
                {
                    IrpContext->Irp->IoStatus.Status = Status;

                    //对同步写,需管理文件对象的FileObject->CurrentByteOffset
                    if (SynchronousIo && !PagingIo && NT_SUCCESS(Status))
                    {
                        FileObject->CurrentByteOffset.QuadPart =
                            ByteOffset.QuadPart + Irp->IoStatus.Information;
                    }

                    if (!PagingIo && NT_SUCCESS(Status))
                    {
                        SetFlag(FileObject->Flags, FO_FILE_MODIFIED);
                        SetFlag(Fcb->Flag, FF_FILE_MODIFIED);
                    }

                    NDCompleteRequest(
                            IrpContext->Irp,
                            (CCHAR)
                            (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT));

                    NDFreeIrpContext(IrpContext);
                }
            }
            else
            {
                NDFreeIrpContext(IrpContext);
            }
        }
    }

    return Status;

}

//#pragma code_seg("PAGE")
NTSTATUS
NDWriteComplete (IN PND_IRP_CONTEXT IrpContext)
{
    NTSTATUS        Status = STATUS_UNSUCCESSFUL;
    PFILE_OBJECT    FileObject;
    PIRP            Irp;
    PIO_STACK_LOCATION IrpSp;

    __try
    {
        FileObject = IrpContext->FileObject;

        Irp = IrpContext->Irp;
        IrpSp = IoGetCurrentIrpStackLocation(Irp);

        CcMdlWriteComplete(FileObject, &(IrpSp->Parameters.Write.ByteOffset), Irp->MdlAddress);

        Irp->MdlAddress = NULL;

        Status = STATUS_SUCCESS;
    }
    __finally
    {
        if (!IrpContext->ExceptionInProgress)
        {
            if (IrpContext->Irp)
            {
                IrpContext->Irp->IoStatus.Status = Status;

                NDCompleteRequest(
                    IrpContext->Irp,
                    (CCHAR)
                    (NT_SUCCESS(Status) ? IO_DISK_INCREMENT : IO_NO_INCREMENT)
                    );

                NDFreeIrpContext(IrpContext);
            }
        }
    }

    return Status;
}

static VOID WriteAckCallBack(
    PND_ACK_WAIT_CONTEXT    AckWaitContext,
    PND_VCB                 Vcb)
{
    ULONG               GetByteLen;
    ND_FRAME_WRITE_ACK  FrameWriteAck;
    PWRITE_CONTEXT      WriteContext;
    
    ASSERT(AckWaitContext->AckContext);
    WriteContext = AckWaitContext->AckContext;
    
    if (AckWaitContext->FrameLen <
        FIELD_OFFSET(ND_FRAME_HEAD,Data) + sizeof(ND_FRAME_WRITE_ACK))
        return;

    //读响应帧
    GetByteLen = sizeof(ND_FRAME_WRITE_ACK);
    GetBytes(
        &FrameWriteAck,
        Vcb,
        AckWaitContext->FrameOffset + FIELD_OFFSET(ND_FRAME_HEAD,Data),
        &GetByteLen);
    ASSERT( GetByteLen == sizeof(ND_FRAME_WRITE_ACK));
  
    WriteContext->Status = TransCreateErroToState(
                      FrameWriteAck.Errno);

}


#define WRITE_BYTES_ONCE    1024
NTSTATUS
NDNetWrite(
            IN PND_IRP_CONTEXT    IrpContext,
            PWRITE_CONTEXT        WriteContext)
{
    NTSTATUS                Status;
    
    PVOID                   PackBuffer = NULL;
    PVOID                   Buffer;
    ULONG                   PackSize;

    ULONG                   AnsiFileNameMaximumLength;

    __try
    {
        ASSERT(WriteContext);

        if (WriteContext->Length == 0)
        {
            Status = STATUS_SUCCESS;
            __leave;
        }

        AnsiFileNameMaximumLength =
            (USHORT)RtlUnicodeStringToAnsiSize(&WriteContext->Fcb->FileName);

        //
        //  计算报文缓冲区应该多大。由于报文多次重复使用,取其所需空间最大值
        //
        ASSERT( (WriteContext->Offset & (ENCRYPT_PACK_SIZE - 1)) == 0);                
        if ( WriteContext->Length > WRITE_BYTES_ONCE )
        {
            PackSize =
                FIELD_OFFSET(ND_PACK_HEAD,Data) +
                FIELD_OFFSET(ND_FRAME_HEAD,Data) +
                FIELD_OFFSET(ND_FRAME_WRITE,PathName) +
                AnsiFileNameMaximumLength +
                WRITE_BYTES_ONCE;
        }
        else
            PackSize =
                FIELD_OFFSET(ND_PACK_HEAD,Data) +
                FIELD_OFFSET(ND_FRAME_HEAD,Data) +
                FIELD_OFFSET(ND_FRAME_WRITE,PathName) +
                AnsiFileNameMaximumLength +
                WriteContext->Length;
        //ASSERT ( PackSize <= MAX_PACK_SIZE);

        //
        // 分配报文
        //
        PackBuffer  = ExAllocatePool(
            PagedPool,
            PackSize
            );
        if (PackBuffer == NULL)
        {
            Status = STATUS_INSUFFICIENT_RESOURCES;
            __leave;
        }
        WriteContext->PackBuffer = PackBuffer;

        //发送各报文。可能分多次        
        
        if (!IrpContext->IsSynchronous)
        {
            if (IrpContext->Irp)
                IoMarkIrpPending(IrpContext->Irp);
            WriteContext->Irp = IrpContext->Irp;
            IrpContext->Irp = NULL;
            Status = STATUS_PENDING;
            NDQueueSendWritePackets(WriteContext,IrpContext);
        }
        
        
        if (IrpContext->IsSynchronous)
        {
           NDSendWritePackets(WriteContext);
           Status = WriteContext->Status;
        }
    }
    __finally
    {
    }

    return Status;
}

VOID
NDQueueSendWritePackets (IN PWRITE_CONTEXT WriteContext,
        PND_IRP_CONTEXT IrpContext)
{
    // POST了以后,在工作者线程环境下可以同步执行

    ExInitializeWorkItem(
        &WriteContext->WorkQueueItem,
        NDSendWritePackets,
        WriteContext);
    
    ExQueueWorkItem(&WriteContext->WorkQueueItem, CriticalWorkQueue);
}

VOID
NDSendWritePackets (IN PVOID Context)
{
    PWRITE_CONTEXT  WriteContext = Context;
    KEVENT          AckEvent;
    ULONG           WriteLength;
    PVOID           Buffer;
    ANSI_STRING     AnsiFileName;
    ULONG           PackSize;
    USHORT          FrameId;
    BOOLEAN         MultiFrameWrite = FALSE;
    PND_ACK_WAIT_CONTEXT    AckWaitContxt;

    RtlZeroMemory(&AnsiFileName,sizeof(AnsiFileName));
    AnsiFileName.MaximumLength =
        (USHORT)RtlUnicodeStringToAnsiSize(&WriteContext->Fcb->FileName);

    WriteContext->Status = STATUS_SUCCESS;
    //
    // 获得帧id
    //
    ExAcquireResourceExclusiveLite(
        &WriteContext->Vcb->SendResource,
        TRUE
        );
    FrameId = WriteContext->Vcb->SendFrameId++;
    ExReleaseResourceForThreadLite(
        &WriteContext->Vcb->SendResource,
        ExGetCurrentResourceThread()
        );

    if (WriteContext->Length > WRITE_BYTES_ONCE)
        MultiFrameWrite = TRUE;

    KeInitializeEvent(
            &AckEvent,
            SynchronizationEvent,
            FALSE
            );
    WriteContext->Status = NDAddAckWaitQueue(
            WriteContext->Vcb,
            FT_WRITE | FT_ACK,
            FrameId,
            NULL,
            NULL,
            &AckEvent,
            FALSE,
            &AckWaitContxt);
    if (!NT_SUCCESS(WriteContext->Status))
        goto Out;
    
    while(WriteContext->Length > 0)
    {
        WriteLength = WriteContext->Length;
        if (WriteLength > WRITE_BYTES_ONCE)
            WriteLength = WRITE_BYTES_ONCE;
        PackSize =
            FIELD_OFFSET(ND_PACK_HEAD,Data) +
            FIELD_OFFSET(ND_FRAME_HEAD,Data) +
            FIELD_OFFSET(ND_FRAME_WRITE,PathName) +
            AnsiFileName.MaximumLength +
            WriteLength;

        //  填充头
        //
        Buffer = FillPackHead(
            WriteContext->PackBuffer,
            PackSize - FIELD_OFFSET(ND_PACK_HEAD,Data)
            );
        Buffer = FillFrameHead(
            Buffer,
            FrameId,
            FT_WRITE,
            PackSize - FIELD_OFFSET(ND_PACK_HEAD,Data)
                - FIELD_OFFSET(ND_FRAME_HEAD,Data)
            );
        
        // 填充写帧
        //
        if (MultiFrameWrite)
        {
            if (WriteContext->Length > WRITE_BYTES_ONCE)
                ((PND_FRAME_WRITE)Buffer)->Flag = WF_MULTIWRITE_MORE;
            else
                ((PND_FRAME_WRITE)Buffer)->Flag = WF_MULTIWRITE_LAST;
        }
        else
        {
            ((PND_FRAME_WRITE)Buffer)->Flag = WF_ONECEWRITE;
        }
        
        ((PND_FRAME_WRITE)Buffer)->PathNameLen = AnsiFileName.MaximumLength;
        ((PND_FRAME_WRITE)Buffer)->Offset = WriteContext->Offset;
        ((PND_FRAME_WRITE)Buffer)->Length = WriteLength;
        ((PND_FRAME_WRITE)Buffer)->LogicDataLen = WriteLength;
        AnsiFileName.Buffer = ((PND_FRAME_WRITE)Buffer)->PathName;
        WriteContext->Status = RtlUnicodeStringToAnsiString(
            &AnsiFileName,
            &WriteContext->Fcb->FileName,
            FALSE
           );
        ASSERT( NT_SUCCESS(WriteContext->Status));

        Buffer = (PCHAR)AnsiFileName.Buffer + AnsiFileName.MaximumLength;
        RtlCopyMemory(
            Buffer,
            WriteContext->Buffer,
            WriteLength);

        // 发送报文
        WriteContext->Status = NDSendPacket(
            WriteContext->Vcb,
            WriteContext->PackBuffer
            );
        if (!NT_SUCCESS(WriteContext->Status))
            break;

        // 准备下一次循环
        //
        WriteContext->Buffer = (PCHAR)WriteContext->Buffer + WriteLength;
        WriteContext->Offset += WriteLength;
        WriteContext->Length -= WriteLength;
    }

    if (!NDWaitForAck(&AckEvent))
        WriteContext->Status = STATUS_UNSUCCESSFUL;
Out:
    ExFreePool(WriteContext->PackBuffer);

    if (WriteContext->Irp)
    {
        WriteContext->Irp->IoStatus.Status = WriteContext->Status;
        IoCompleteRequest(WriteContext->Irp,IO_DISK_INCREMENT);
    }
    
   // NDWaitForAck(&AckEvent);

}
    
 
deltali
驱动小牛
驱动小牛
  • 注册日期2002-10-25
  • 最后登录2010-07-06
  • 粉丝0
  • 关注0
  • 积分2分
  • 威望23点
  • 贡献值0点
  • 好评度11点
  • 原创分0分
  • 专家分0分
沙发#
发布于:2004-07-13 11:24
太长了,没怎么看。

你每次写的时候,改成同步的看看,每次写完才发包回来表示写完。看行不行
我又来了,生命不息,驱动不止。
游客

返回顶部