⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 read.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 4 页
字号:
                }

                //
                //  If the call didn't succeed, raise the error status
                //

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

                    ASSERT( KeGetCurrentThread() != Vcb->VerifyThread || Status != STATUS_VERIFY_REQUIRED );
                    FatNormalizeAndRaiseStatus( IrpContext, Status );

                } else {

                    //
                    //  Else set the Irp information field to reflect the
                    //  entire desired read.
                    //

                    ASSERT( Irp->IoStatus.Information == BytesToRead );

                    Irp->IoStatus.Information = RequestedByteCount;
                }

                //
                // The transfer is complete.
                //

                try_return( Status );

            }   // if No Intermediate Buffering


            //
            // HANDLE CACHED CASE
            //

            else {

                //
                // We delay setting up the file cache until now, in case the
                // caller never does any I/O to the file, and thus
                // FileObject->PrivateCacheMap == NULL.
                //

                if (FileObject->PrivateCacheMap == NULL) {

                    DebugTrace(0, Dbg, "Initialize cache mapping.\n", 0);

                    //
                    //  Get the file allocation size, and if it is less than
                    //  the file size, raise file corrupt error.
                    //

                    if (FcbOrDcb->Header.AllocationSize.QuadPart == FCB_LOOKUP_ALLOCATIONSIZE_HINT) {

                        FatLookupFileAllocationSize( IrpContext, FcbOrDcb );
                    }

                    if ( FileSize > FcbOrDcb->Header.AllocationSize.LowPart ) {

                        FatPopUpFileCorrupt( IrpContext, FcbOrDcb );

                        FatRaiseStatus( IrpContext, STATUS_FILE_CORRUPT_ERROR );
                    }

                    //
                    //  Now initialize the cache map.
                    //

                    CcInitializeCacheMap( FileObject,
                                          (PCC_FILE_SIZES)&FcbOrDcb->Header.AllocationSize,
                                          FALSE,
                                          &FatData.CacheManagerCallbacks,
                                          FcbOrDcb );

                    CcSetReadAheadGranularity( FileObject, READ_AHEAD_GRANULARITY );
                }


                //
                // DO A NORMAL CACHED READ, if the MDL bit is not set,
                //

                DebugTrace(0, Dbg, "Cached read.\n", 0);

                if (!FlagOn(IrpContext->MinorFunction, IRP_MN_MDL)) {

                    //
                    //  Get hold of the user's buffer.
                    //

                    SystemBuffer = FatMapUserBuffer( IrpContext, Irp );

                    //
                    // Now try to do the copy.
                    //

                    if (!CcCopyRead( FileObject,
                                     &StartingByte,
                                     ByteCount,
                                     Wait,
                                     SystemBuffer,
                                     &Irp->IoStatus )) {

                        DebugTrace( 0, Dbg, "Cached Read could not wait\n", 0 );

                        try_return( PostIrp = TRUE );
                    }

                    Status = Irp->IoStatus.Status;

                    ASSERT( NT_SUCCESS( Status ));

                    try_return( Status );
                }


                //
                //  HANDLE A MDL READ
                //

                else {

                    DebugTrace(0, Dbg, "MDL read.\n", 0);

                    ASSERT( Wait );

                    CcMdlRead( FileObject,
                               &StartingByte,
                               ByteCount,
                               &Irp->MdlAddress,
                               &Irp->IoStatus );

                    Status = Irp->IoStatus.Status;

                    ASSERT( NT_SUCCESS( Status ));

                    try_return( Status );
                }
            }
        }

        //
        //  These two cases correspond to a system read directory file and
        //  ea file.
        //

        if (( TypeOfOpen == DirectoryFile ) || ( TypeOfOpen == EaFile)) {

            ULONG SectorSize;

            DebugTrace(0, Dbg, "Read Directory or Ea file.\n", 0);

            //
            //  For the noncached case, assert that everything is sector
            //  alligned.
            //

            SectorSize = (ULONG)Vcb->Bpb.BytesPerSector;

            //
            //  We make several assumptions about these two types of files.
            //  Make sure all of them are true.
            //

            ASSERT( NonCachedIo && PagingIo );
            ASSERT( ((StartingVbo | ByteCount) & (SectorSize - 1)) == 0 );

            //
            //  These calls must allways be within the allocation size
            //

            if (StartingVbo >= FcbOrDcb->Header.AllocationSize.LowPart) {

                DebugTrace( 0, Dbg, "PagingIo dirent started beyond EOF.\n", 0 );

                Irp->IoStatus.Information = 0;

                try_return( Status = STATUS_SUCCESS );
            }

            if ( StartingVbo + ByteCount > FcbOrDcb->Header.AllocationSize.LowPart ) {

                DebugTrace( 0, Dbg, "PagingIo dirent extending beyond EOF.\n", 0 );
                ByteCount = FcbOrDcb->Header.AllocationSize.LowPart - StartingVbo;
            }

            //
            //  Perform the actual IO
            //

            if (FatNonCachedIo( IrpContext,
                                Irp,
                                FcbOrDcb,
                                StartingVbo,
                                ByteCount,
                                ByteCount ) == STATUS_PENDING) {

                IrpContext->FatIoContext = NULL;

                Irp = NULL;

                try_return( Status = STATUS_PENDING );
            }

            //
            //  If the call didn't succeed, raise the error status
            //

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

                ASSERT( KeGetCurrentThread() != Vcb->VerifyThread || Status != STATUS_VERIFY_REQUIRED );
                FatNormalizeAndRaiseStatus( IrpContext, Status );

            } else {

                ASSERT( Irp->IoStatus.Information == ByteCount );
            }

            try_return( Status );
        }

        //
        // This is the case of a user who openned a directory. No reading is
        // allowed.
        //

        if ( TypeOfOpen == UserDirectoryOpen ) {

            DebugTrace( 0, Dbg, "CommonRead -> STATUS_INVALID_PARAMETER\n", 0);

            try_return( Status = STATUS_INVALID_PARAMETER );
        }

        //
        //  If we get this far, something really serious is wrong.
        //

        DebugDump("Illegal TypeOfOpen\n", 0, FcbOrDcb );

        FatBugCheck( TypeOfOpen, (ULONG_PTR) FcbOrDcb, 0 );

    try_exit: NOTHING;

        //
        //  If the request was not posted and there's an Irp, deal with it.
        //

        if ( Irp ) {

            if ( !PostIrp ) {

                ULONG ActualBytesRead;

                DebugTrace( 0, Dbg, "Completing request with status = %08lx\n",
                            Status);

                DebugTrace( 0, Dbg, "                   Information = %08lx\n",
                            Irp->IoStatus.Information);

                //
                //  Record the total number of bytes actually read
                //

                ActualBytesRead = (ULONG)Irp->IoStatus.Information;

                //
                //  If the file was opened for Synchronous IO, update the current
                //  file position.
                //

                if (SynchronousIo && !PagingIo) {

                    FileObject->CurrentByteOffset.LowPart =
                                                    StartingVbo + ActualBytesRead;
                }

                //
                //  If this was not PagingIo, mark that the last access
                //  time on the dirent needs to be updated on close.
                //

                if (NT_SUCCESS(Status) && !PagingIo) {

                    SetFlag( FileObject->Flags, FO_FILE_FAST_IO_READ );
                }

            } else {

                DebugTrace( 0, Dbg, "Passing request to Fsp\n", 0 );

                if (!OplockPostIrp) {

                    Status = FatFsdPostRequest( IrpContext, Irp );
                }
            }
        }

    } finally {

        DebugUnwind( FatCommonRead );

        //
        // If the FcbOrDcb has been acquired, release it.
        //

        if (FcbOrDcbAcquired && Irp) {

            if ( PagingIo ) {

                ExReleaseResourceLite( FcbOrDcb->Header.PagingIoResource );

            } else {

                FatReleaseFcb( NULL, FcbOrDcb );
            }
        }

        //
        //  Complete the request if we didn't post it and no exception
        //
        //  Note that FatCompleteRequest does the right thing if either
        //  IrpContext or Irp are NULL
        //

        if (!PostIrp) {
             
            //
            //  If we had a stack io context, we have to make sure the contents
            //  are cleaned up before we leave.
            //
            //  At present with zero mdls, this will only really happen on exceptional
            //  termination where we failed to dispatch the IO. Cleanup of zero mdls
            //  normally occurs during completion, but when we bail we must make sure
            //  the cleanup occurs here or the fatiocontext will go out of scope.
            //
            //  If the operation was posted, cleanup occured there.
            //

            if (FlagOn(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT)) {

                if (IrpContext->FatIoContext->ZeroMdl) {
                    IoFreeMdl( IrpContext->FatIoContext->ZeroMdl );
                }

                ClearFlag(IrpContext->Flags, IRP_CONTEXT_STACK_IO_CONTEXT);
                IrpContext->FatIoContext = NULL;
            }

            if (!AbnormalTermination()) {

                FatCompleteRequest( IrpContext, Irp, Status );
            }
        }

        DebugTrace(-1, Dbg, "CommonRead -> %08lx\n", Status );
    }

    return Status;
}

//
//  Local support routine
//

VOID
FatOverflowPagingFileRead (
    IN PVOID Context,
    IN PKEVENT Event
    )

/*++

Routine Description:

    The routine simply call FatPagingFileIo.  It is invoked in cases when
    there was not enough stack space to perform the pagefault in the
    original thread.  It is also responsible for freeing the packet pool.

Arguments:

    Irp - Supplies the Irp being processed

    Fcb - Supplies the paging file Fcb, since we have it handy.

Return Value:

    VOID

--*/

{
    PPAGING_FILE_OVERFLOW_PACKET Packet = Context;

    FatPagingFileIo( Packet->Irp, Packet->Fcb );

    //
    //  Set the stack overflow item's event to tell the original
    //  thread that we're done.
    //

    KeSetEvent( Event, 0, FALSE );

    return;
}



⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -