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

📄 fileinfo.c

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

Copyright (c) 1989  Microsoft Corporation

Module Name:

    FileInfo.c

Abstract:

    This module implements the File Information routines for Udfs called by
    the Fsd/Fsp dispatch drivers.

Author:

    Dan Lovinger    [DanLo]     16-Jan-1997

Revision History:

--*/

#include "UdfProcs.h"

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

#define BugCheckFileId                   (UDFS_BUG_CHECK_FILEINFO)

//
//  The local debug trace level
//

#define Dbg                              (UDFS_DEBUG_LEVEL_FILEINFO)

//
//  Local macros
//

INLINE
ULONG
UdfGetExtraFileAttributes (
    IN PCCB Ccb
    )

/*++

Routine Description:

    Safely figure out extra name-based file attributes given a context block.

Arguments:

    Ccb - a context block to examine.

Return Value:

    ULONG - file attributes for a file based on how it was opened (seperate from
        those based on the object that was opened).

--*/

{
    return ( Ccb->Lcb != NULL? Ccb->Lcb->FileAttributes : 0 );
}

//
//  Local support routines
//

VOID
UdfQueryBasicInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PCCB Ccb,
    IN OUT PFILE_BASIC_INFORMATION Buffer,
    IN OUT PULONG Length
    );

VOID
UdfQueryStandardInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN OUT PFILE_STANDARD_INFORMATION Buffer,
    IN OUT PULONG Length
    );

VOID
UdfQueryInternalInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN OUT PFILE_INTERNAL_INFORMATION Buffer,
    IN OUT PULONG Length
    );

VOID
UdfQueryEaInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN OUT PFILE_EA_INFORMATION Buffer,
    IN OUT PULONG Length
    );

VOID
UdfQueryPositionInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFILE_OBJECT FileObject,
    IN OUT PFILE_POSITION_INFORMATION Buffer,
    IN OUT PULONG Length
    );

NTSTATUS
UdfQueryNameInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFILE_OBJECT FileObject,
    IN OUT PFILE_NAME_INFORMATION Buffer,
    IN OUT PULONG Length
    );

NTSTATUS
UdfQueryAlternateNameInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PCCB Ccb,
    IN OUT PFILE_NAME_INFORMATION Buffer,
    IN OUT PULONG Length
    );

VOID
UdfQueryNetworkInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PCCB Ccb,
    IN OUT PFILE_NETWORK_OPEN_INFORMATION Buffer,
    IN OUT PULONG Length
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, UdfCommonQueryInfo)
#pragma alloc_text(PAGE, UdfCommonSetInfo)
#pragma alloc_text(PAGE, UdfFastQueryBasicInfo)
#pragma alloc_text(PAGE, UdfFastQueryStdInfo)
#pragma alloc_text(PAGE, UdfFastQueryNetworkInfo)
#pragma alloc_text(PAGE, UdfQueryAlternateNameInfo)
#pragma alloc_text(PAGE, UdfQueryBasicInfo)
#pragma alloc_text(PAGE, UdfQueryEaInfo)
#pragma alloc_text(PAGE, UdfQueryInternalInfo)
#pragma alloc_text(PAGE, UdfQueryNameInfo)
#pragma alloc_text(PAGE, UdfQueryNetworkInfo)
#pragma alloc_text(PAGE, UdfQueryPositionInfo)
#pragma alloc_text(PAGE, UdfQueryStandardInfo)
#endif


NTSTATUS
UdfCommonQueryInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for query file information called by both the
    fsd and fsp threads.

Arguments:

    Irp - Supplies the Irp to process.

Return Value:

    NTSTATUS - The return status for this operation.

--*/

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

    ULONG Length;
    FILE_INFORMATION_CLASS FileInformationClass;
    PFILE_ALL_INFORMATION Buffer;

    TYPE_OF_OPEN TypeOfOpen;
    PFCB Fcb;
    PCCB Ccb;

    BOOLEAN ReleaseFcb = FALSE;

    PAGED_CODE();

    //
    //  Reference our input parameters to make things easier
    //

    Length = IrpSp->Parameters.QueryFile.Length;
    FileInformationClass = IrpSp->Parameters.QueryFile.FileInformationClass;
    Buffer = Irp->AssociatedIrp.SystemBuffer;

    //
    //  Decode the file object
    //

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

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

    try {

        //
        //  We only support query on file and directory handles.
        //

        switch (TypeOfOpen) {

        case UserDirectoryOpen :
        case UserFileOpen :

            //
            //  Acquire shared access to this file.
            //

            UdfAcquireFileShared( IrpContext, Fcb );
            ReleaseFcb = TRUE;

            ASSERT( FlagOn( Fcb->FcbState, FCB_STATE_INITIALIZED ));
            
            //
            //  Make sure the Fcb is in a usable condition.  This will raise
            //  an error condition if the volume is unusable
            //

            UdfVerifyFcbOperation( IrpContext, Fcb );

            //
            //  Based on the information class we'll do different
            //  actions.  Each of hte procedures that we're calling fills
            //  up the output buffer, if possible.  They will raise the
            //  status STATUS_BUFFER_OVERFLOW for an insufficient buffer.
            //  This is considered a somewhat unusual case and is handled
            //  more cleanly with the exception mechanism rather than
            //  testing a return status value for each call.
            //

            switch (FileInformationClass) {

            case FileAllInformation:

                //
                //  We don't allow this operation on a file opened by file Id.
                //

                if (FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {

                    Status = STATUS_INVALID_PARAMETER;
                    break;
                }

                //
                //  In this case go ahead and call the individual routines to
                //  fill in the buffer.  Only the name routine will
                //  pointer to the output buffer and then call the
                //  individual routines to fill in the buffer.
                //

                Length -= (sizeof( FILE_ACCESS_INFORMATION ) +
                           sizeof( FILE_MODE_INFORMATION ) +
                           sizeof( FILE_ALIGNMENT_INFORMATION ));

                UdfQueryBasicInfo( IrpContext, Fcb, Ccb, &Buffer->BasicInformation, &Length );
                UdfQueryStandardInfo( IrpContext, Fcb, &Buffer->StandardInformation, &Length );
                UdfQueryInternalInfo( IrpContext, Fcb, &Buffer->InternalInformation, &Length );
                UdfQueryEaInfo( IrpContext, Fcb, &Buffer->EaInformation, &Length );
                UdfQueryPositionInfo( IrpContext, IrpSp->FileObject, &Buffer->PositionInformation, &Length );
                Status = UdfQueryNameInfo( IrpContext, IrpSp->FileObject, &Buffer->NameInformation, &Length );

                break;

            case FileBasicInformation:

                UdfQueryBasicInfo( IrpContext, Fcb, Ccb, (PFILE_BASIC_INFORMATION) Buffer, &Length );
                break;

            case FileStandardInformation:

                UdfQueryStandardInfo( IrpContext, Fcb, (PFILE_STANDARD_INFORMATION) Buffer, &Length );
                break;

            case FileInternalInformation:

                UdfQueryInternalInfo( IrpContext, Fcb, (PFILE_INTERNAL_INFORMATION) Buffer, &Length );
                break;

            case FileEaInformation:

                UdfQueryEaInfo( IrpContext, Fcb, (PFILE_EA_INFORMATION) Buffer, &Length );
                break;

            case FilePositionInformation:

                UdfQueryPositionInfo( IrpContext, IrpSp->FileObject, (PFILE_POSITION_INFORMATION) Buffer, &Length );
                break;

            case FileNameInformation:

                //
                //  We don't allow this operation on a file opened by file Id.
                //

                if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {

                    Status = UdfQueryNameInfo( IrpContext, IrpSp->FileObject, (PFILE_NAME_INFORMATION) Buffer, &Length );

                } else {

                    Status = STATUS_INVALID_PARAMETER;
                }

                break;

            case FileAlternateNameInformation:

                if (!FlagOn( Ccb->Flags, CCB_FLAG_OPEN_BY_ID )) {

                    Status = UdfQueryAlternateNameInfo( IrpContext, Fcb, Ccb, (PFILE_NAME_INFORMATION) Buffer, &Length );

                } else {

                    Status = STATUS_INVALID_PARAMETER;
                }

                break;

            case FileNetworkOpenInformation:

                UdfQueryNetworkInfo( IrpContext, Fcb, Ccb, (PFILE_NETWORK_OPEN_INFORMATION) Buffer, &Length );
                break;

            default :

                Status = STATUS_INVALID_PARAMETER;
            }

            break;

        default :

            Status = STATUS_INVALID_PARAMETER;
        }

        //
        //  Set the information field to the number of bytes actually filled in
        //  and then complete the request
        //

        Irp->IoStatus.Information = IrpSp->Parameters.QueryFile.Length - Length;

    } finally {

        //
        //  Release the file.
        //

        if (ReleaseFcb) {

            UdfReleaseFile( IrpContext, Fcb );
        }
    }

    //
    //  Complete the request if we didn't raise.
    //

    UdfCompleteRequest( IrpContext, Irp, Status );

    return Status;
}


NTSTATUS
UdfCommonSetInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for set file information called by both the
    fsd and fsp threads.  We only support operations which set the file position.

Arguments:

    Irp - Supplies the Irp to process.

Return Value:

    NTSTATUS - The return status for this operation.

--*/

{
    NTSTATUS Status = STATUS_INVALID_PARAMETER;

    TYPE_OF_OPEN TypeOfOpen;
    PFCB Fcb;
    PCCB Ccb;

    PIO_STACK_LOCATION IrpSp = IoGetCurrentIrpStackLocation( Irp );

    PFILE_POSITION_INFORMATION Buffer;

    PAGED_CODE();

    //
    //  Decode the file object
    //

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

    //
    //  We only support a SetPositionInformation on a user file.
    //

    if ((TypeOfOpen != UserFileOpen) ||
        (IrpSp->Parameters.QueryFile.FileInformationClass != FilePositionInformation)) {

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

    //
    //  Acquire shared access to this file.
    //

    UdfAcquireFileShared( IrpContext, Fcb );

    try {

        //
        //  Make sure the Fcb is in a usable condition.  This
        //  will raise an error condition if the fcb is unusable
        //

        UdfVerifyFcbOperation( IrpContext, Fcb );

        Buffer = Irp->AssociatedIrp.SystemBuffer;

        //
        //  Check if the file does not use intermediate buffering.  If it
        //  does not use intermediate buffering then the new position we're
        //  supplied must be aligned properly for the device
        //

        if (FlagOn( IrpSp->FileObject->Flags, FO_NO_INTERMEDIATE_BUFFERING ) &&
            ((Buffer->CurrentByteOffset.LowPart & IrpSp->DeviceObject->AlignmentRequirement) != 0)) {

            try_leave( NOTHING );
        }

        //
        //  The input parameter is fine so set the current byte offset and
        //  complete the request
        //

        //
        //  Lock the Fcb to provide synchronization.
        //

        UdfLockFcb( IrpContext, Fcb );
        IrpSp->FileObject->CurrentByteOffset = Buffer->CurrentByteOffset;
        UdfUnlockFcb( IrpContext, Fcb );

        Status = STATUS_SUCCESS;

    } finally {

        UdfReleaseFile( IrpContext, Fcb );
    }

    //
    //  Complete the request if there was no raise.
    //

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


BOOLEAN
UdfFastQueryBasicInfo (
    IN PFILE_OBJECT FileObject,
    IN BOOLEAN Wait,
    IN OUT PFILE_BASIC_INFORMATION Buffer,

⌨️ 快捷键说明

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