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

📄 read.c

📁 windows 2000中的UDF文件系统的驱动程序.只有读的功能,不支持未关闭的盘片.只支持UDF2.0以下版本,不支持VAT格式的UDF.
💻 C
📖 第 1 页 / 共 2 页
字号:
/*++

Copyright (c) 1989  Microsoft Corporation

Module Name:

    Read.c

Abstract:

    This module implements the File Read routine for Read called by the
    Fsd/Fsp dispatch drivers.

Author:

    Dan Lovinger    [DanLo]     22-Sep-1996

Revision History:

--*/

#include "UdfProcs.h"

//
//  The Bug check file id for this module
//

#define BugCheckFileId                   (UDFS_BUG_CHECK_READ)

//
//  The local debug trace level
//

#define Dbg                              (UDFS_DEBUG_LEVEL_READ)

//
//  VOID
//  SafeZeroMemory (
//      IN PUCHAR At,
//      IN ULONG ByteCount
//      );
//

//
//  This macro just puts a nice little try-except around RtlZeroMemory
//

#define SafeZeroMemory(IC,AT,BYTE_COUNT) {                  \
    try {                                                   \
        RtlZeroMemory( (AT), (BYTE_COUNT) );                \
    } except( EXCEPTION_EXECUTE_HANDLER ) {                 \
         UdfRaiseStatus( IC, STATUS_INVALID_USER_BUFFER );   \
    }                                                       \
}

//
// Read ahead amount used for normal data files
//

#define READ_AHEAD_GRANULARITY           (0x10000)

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, UdfCommonRead)
#endif


NTSTATUS
UdfCommonRead (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common entry point for NtReadFile calls.  For synchronous requests,
    CommonRead will complete the request in the current thread.  If not
    synchronous the request will be passed to the Fsp if there is a need to
    block.

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - The result of this operation.

--*/

{
    NTSTATUS Status;
    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

    TYPE_OF_OPEN TypeOfOpen;
    PFCB Fcb;
    PCCB Ccb;
    PVCB Vcb;

    BOOLEAN Wait;
    ULONG PagingIo;
    ULONG SynchronousIo;
    ULONG NonCachedIo;

    LONGLONG StartingOffset;
    LONGLONG ByteRange;
    ULONG ByteCount;
    ULONG ReadByteCount;
    ULONG OriginalByteCount;

    PVOID SystemBuffer, UserBuffer;

    BOOLEAN ReleaseFile = TRUE;

    PFILE_OBJECT MappingFileObject;

    UDF_IO_CONTEXT LocalIoContext;

    PAGED_CODE();

    //
    //  If this is a zero length read then return SUCCESS immediately.
    //

    if (IrpSp->Parameters.Read.Length == 0) {

        UdfCompleteRequest( IrpContext, Irp, STATUS_SUCCESS );
        return STATUS_SUCCESS;
    }

    //
    //  Decode the file object and verify we support read on this.  It
    //  must be a user file, stream file or volume file (for a data disk).
    //

    TypeOfOpen = UdfDecodeFileObject( IrpSp->FileObject, &Fcb, &Ccb );

    Vcb = Fcb->Vcb;

    if ((TypeOfOpen == UnopenedFileObject) || (TypeOfOpen == UserDirectoryOpen)) {

        UdfCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST );
        return STATUS_INVALID_DEVICE_REQUEST;
    }

    //
    //  Examine our input parameters to determine if this is noncached and/or
    //  a paging io operation.
    //

    Wait = BooleanFlagOn( IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT );
    PagingIo = FlagOn( Irp->Flags, IRP_PAGING_IO );
    NonCachedIo = FlagOn( Irp->Flags, IRP_NOCACHE );
    SynchronousIo = FlagOn( IrpSp->FileObject->Flags, FO_SYNCHRONOUS_IO );

    //
    //  Extract the range of the Io.
    //

    StartingOffset = IrpSp->Parameters.Read.ByteOffset.QuadPart;
    OriginalByteCount = ByteCount = IrpSp->Parameters.Read.Length;

    ByteRange = StartingOffset + ByteCount;

    //
    //  Make sure that Dasd access is always non-cached.
    //

    if (TypeOfOpen == UserVolumeOpen) {

        NonCachedIo = TRUE;
    }

    //
    //  Acquire the file shared to perform the read.  If we are doing paging IO,
    //  it may be the case that we would have a deadlock imminent because we may
    //  block on shared access, so starve out any exclusive waiters.  This requires
    //  a degree of caution - we believe that any paging IO bursts will recede and
    //  allow the exclusive waiter in.
    //

    if (PagingIo) {

        UdfAcquireFileSharedStarveExclusive( IrpContext, Fcb );
    
    } else {
        
        UdfAcquireFileShared( IrpContext, Fcb );
    }

    //
    //  Use a try-finally to facilitate cleanup.
    //

    try {

        //
        //  Verify the Fcb.
        //

        UdfVerifyFcbOperation( IrpContext, Fcb );

        //
        //  If this is a user request then verify the oplock and filelock state.
        //

        if (TypeOfOpen == UserFileOpen) {

            //
            //  We check whether we can proceed
            //  based on the state of the file oplocks.
            //

            Status = FsRtlCheckOplock( &Fcb->Oplock,
                                       Irp,
                                       IrpContext,
                                       UdfOplockComplete,
                                       UdfPrePostIrp );

            //
            //  If the result is not STATUS_SUCCESS then the Irp was completed
            //  elsewhere.
            //

            if (Status != STATUS_SUCCESS) {

                Irp = NULL;
                IrpContext = NULL;

                try_leave( Status );
            }

            if (!PagingIo &&
                (Fcb->FileLock != NULL) &&
                !FsRtlCheckLockForReadAccess( Fcb->FileLock, Irp )) {

                try_leave( Status = STATUS_FILE_LOCK_CONFLICT );
            }
        }

        //
        //  Complete the request if it begins beyond the end of file.
        //

        if (StartingOffset >= Fcb->FileSize.QuadPart) {

            try_leave( Status = STATUS_END_OF_FILE );
        }

        //
        //  Truncate the read if it extends beyond the end of the file.
        //

        if (ByteRange > Fcb->FileSize.QuadPart) {

            ByteCount = (ULONG) (Fcb->FileSize.QuadPart - StartingOffset);
            ByteRange = Fcb->FileSize.QuadPart;
        }

        //
        //  Now if the data is embedded in the ICB, map through the metadata
        //  stream to retrieve the bytes.
        //
            
        if (FlagOn( Fcb->FcbState, FCB_STATE_EMBEDDED_DATA )) {

            //
            //  The metadata stream better be here by now.
            //

            ASSERT( Vcb->MetadataFcb->FileObject != NULL );

            //
            //  Bias our starting offset by the offset of the ICB in the metadata
            //  stream plus the offset of the data bytes in that ICB.  Obviously,
            //  we aren't doing non-cached IO here.
            //

            StartingOffset += (BytesFromSectors( Vcb, Fcb->EmbeddedVsn ) + Fcb->EmbeddedOffset);
            MappingFileObject = Vcb->MetadataFcb->FileObject;
            NonCachedIo = FALSE;

        //
        //  We are mapping through the caller's fileobject
        //

⌨️ 快捷键说明

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