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

📄 fileinfo.c

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

            switch (FileInformationClass) {

            case FileAllInformation:

                //
                //  For the all information class we'll typecast a local
                //  pointer to the output buffer and then call the
                //  individual routines to fill in the buffer.
                //

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

                FatQueryBasicInfo( IrpContext, Fcb, FileObject, &AllInfo->BasicInformation, &Length );
                FatQueryStandardInfo( IrpContext, Fcb, &AllInfo->StandardInformation, &Length );
                FatQueryInternalInfo( IrpContext, Fcb, &AllInfo->InternalInformation, &Length );
                FatQueryEaInfo( IrpContext, Fcb, &AllInfo->EaInformation, &Length );
                FatQueryPositionInfo( IrpContext, FileObject, &AllInfo->PositionInformation, &Length );
                FatQueryNameInfo( IrpContext, Fcb, Ccb, &AllInfo->NameInformation, &Length );

                break;

            case FileBasicInformation:

                FatQueryBasicInfo( IrpContext, Fcb, FileObject, Buffer, &Length );
                break;

            case FileStandardInformation:

                FatQueryStandardInfo( IrpContext, Fcb, Buffer, &Length );
                break;

            case FileInternalInformation:

                FatQueryInternalInfo( IrpContext, Fcb, Buffer, &Length );
                break;

            case FileEaInformation:

                FatQueryEaInfo( IrpContext, Fcb, Buffer, &Length );
                break;

            case FilePositionInformation:

                FatQueryPositionInfo( IrpContext, FileObject, Buffer, &Length );
                break;

            case FileNameInformation:

                FatQueryNameInfo( IrpContext, Fcb, Ccb, Buffer, &Length );
                break;

            case FileAlternateNameInformation:

                FatQueryShortNameInfo( IrpContext, Fcb, Buffer, &Length );
                break;

            case FileNetworkOpenInformation:

                FatQueryNetworkInfo( IrpContext, Fcb, FileObject, Buffer, &Length );
                break;

            default:

                Status = STATUS_INVALID_PARAMETER;
                break;
            }

            break;

        default:

            KdPrintEx((DPFLTR_FASTFAT_ID,
                       DPFLTR_INFO_LEVEL,
                       "FATQueryFile, Illegal TypeOfOpen = %08lx\n",
                       TypeOfOpen));

            Status = STATUS_INVALID_PARAMETER;
            break;
        }

        //
        //  If we overflowed the buffer, set the length to 0 and change the
        //  status to STATUS_BUFFER_OVERFLOW.
        //

        if ( Length < 0 ) {

            Status = STATUS_BUFFER_OVERFLOW;

            Length = 0;
        }

        //
        //  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;

    try_exit: NOTHING;
    } finally {

        DebugUnwind( FatCommonQueryInformation );

        if (FcbAcquired) { FatReleaseFcb( IrpContext, Fcb ); }
        if (VcbAcquired) { FatReleaseVcb( IrpContext, Vcb ); }

        if (!AbnormalTermination()) {

            FatCompleteRequest( IrpContext, Irp, Status );
        }

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

    return Status;
}


NTSTATUS
FatCommonSetInformation (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

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

Arguments:

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    NTSTATUS Status;

    PIO_STACK_LOCATION IrpSp;

    PFILE_OBJECT FileObject;
    FILE_INFORMATION_CLASS FileInformationClass;

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

    BOOLEAN VcbAcquired = FALSE;
    BOOLEAN FcbAcquired = FALSE;

    //
    //  Get the current stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "FatCommonSetInformation...\n", 0);
    DebugTrace( 0, Dbg, "Irp                    = %08lx\n", Irp);
    DebugTrace( 0, Dbg, "->Length               = %08lx\n", IrpSp->Parameters.SetFile.Length);
    DebugTrace( 0, Dbg, "->FileInformationClass = %08lx\n", IrpSp->Parameters.SetFile.FileInformationClass);
    DebugTrace( 0, Dbg, "->FileObject           = %08lx\n", IrpSp->Parameters.SetFile.FileObject);
    DebugTrace( 0, Dbg, "->ReplaceIfExists      = %08lx\n", IrpSp->Parameters.SetFile.ReplaceIfExists);
    DebugTrace( 0, Dbg, "->Buffer               = %08lx\n", Irp->AssociatedIrp.SystemBuffer);

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

    FileInformationClass = IrpSp->Parameters.SetFile.FileInformationClass;
    FileObject = IrpSp->FileObject;

    //
    //  Decode the file object
    //

    TypeOfOpen = FatDecodeFileObject( FileObject, &Vcb, &Fcb, &Ccb );

    try {

        //
        //  Case on the type of open we're dealing with
        //

        switch (TypeOfOpen) {

        case UserVolumeOpen:

            //
            //  We cannot query the user volume open.
            //

            try_return( Status = STATUS_INVALID_PARAMETER );
            break;

        case UserFileOpen:

            if (!FlagOn( Fcb->FcbState, FCB_STATE_PAGING_FILE ) &&
                ((FileInformationClass == FileEndOfFileInformation) ||
                 (FileInformationClass == FileAllocationInformation))) {

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

                Status = FsRtlCheckOplock( &Fcb->Specific.Fcb.Oplock,
                                           Irp,
                                           IrpContext,
                                           NULL,
                                           NULL );

                if (Status != STATUS_SUCCESS) {

                    try_return( Status );
                }

                //
                //  Set the flag indicating if Fast I/O is possible
                //

                Fcb->Header.IsFastIoPossible = FatIsFastIoPossible( Fcb );
            }
            break;

        case UserDirectoryOpen:

            break;

        default:

            try_return( Status = STATUS_INVALID_PARAMETER );
        }

        //
        //  We can only do a set on a nonroot dcb, so we do the test
        //  and then fall through to the user file open code.
        //

        if (NodeType(Fcb) == FAT_NTC_ROOT_DCB) {

            if (FileInformationClass == FileDispositionInformation) {

                try_return( Status = STATUS_CANNOT_DELETE );
            }

            try_return( Status = STATUS_INVALID_PARAMETER );
        }

        //
        //  In the following two cases, we cannot have creates occuring
        //  while we are here, so acquire the volume exclusive.
        //

        if ((FileInformationClass == FileDispositionInformation) ||
            (FileInformationClass == FileRenameInformation)) {

            if (!FatAcquireExclusiveVcb( IrpContext, Vcb )) {

                DebugTrace(0, Dbg, "Cannot acquire Vcb\n", 0);

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

                try_return( Status );
            }

            VcbAcquired = TRUE;

            //
            //  Make sure we haven't been called recursively by a filter inside an existing
            //  create request.
            //

            if (FlagOn( Vcb->VcbState, VCB_STATE_FLAG_CREATE_IN_PROGRESS)) {

                FatBugCheck( 0, 0, 0);
            }
        }

        //
        //  We need to look here to check whether the oplock state
        //  will allow us to continue.  We may have to loop to prevent
        //  an oplock being granted between the time we check the oplock
        //  and obtain the Fcb.
        //

        //
        //  Acquire exclusive access to the Fcb,  We use exclusive
        //  because it is probable that one of the subroutines
        //  that we call will need to monkey with file allocation,
        //  create/delete extra fcbs.  So we're willing to pay the
        //  cost of exclusive Fcb access.
        //
        //  Note that we do not acquire the resource for paging file
        //  operations in order to avoid deadlock with Mm.
        //

        if (!FlagOn( Fcb->FcbState, FCB_STATE_PAGING_FILE )) {

            if (!FatAcquireExclusiveFcb( IrpContext, Fcb )) {

                DebugTrace(0, Dbg, "Cannot acquire Fcb\n", 0);

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

                try_return( Status );
            }

            FcbAcquired = TRUE;
        }

        Status = STATUS_SUCCESS;

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

        FatVerifyFcb( IrpContext, Fcb );

        //
        //  Based on the information class we'll do different
        //  actions.  Each of the procedures that we're calling will either
        //  complete the request of send the request off to the fsp
        //  to do the work.
        //

        switch (FileInformationClass) {

        case FileBasicInformation:

            Status = FatSetBasicInfo( IrpContext, Irp, Fcb, Ccb );
            break;

        case FileDispositionInformation:

            //
            //  If this is on deferred flush media, we have to be able to wait.
            //

            if ( FlagOn(Vcb->VcbState, VCB_STATE_FLAG_DEFERRED_FLUSH) &&
                 !FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT) ) {

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

            } else {

                Status = FatSetDispositionInfo( IrpContext, Irp, FileObject, Fcb );
            }

            break;

        case FileRenameInformation:

            //
            //  We proceed with this operation only if we can wait
            //

            if (!FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT)) {

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

            } else {

                Status = FatSetRenameInfo( IrpContext, Irp, Vcb, Fcb, Ccb );

                //
                //  If STATUS_PENDING is returned it means the oplock
                //  package has the Irp.  Don't complete the request here.
                //

                if (Status == STATUS_PENDING) {
                    Irp = NULL;
                    IrpContext = NULL;
                }
            }

            break;

        case FilePositionInformation:

            Status = FatSetPositionInfo( IrpContext, Irp, FileObject );
            break;

        case FileLinkInformation:

            Status = STATUS_INVALID_DEVICE_REQUEST;
            break;

        case FileAllocationInformation:

            Status = FatSetAllocationInfo( IrpContext, Irp, Fcb, FileObject );
            break;

        case FileEndOfFileInformation:

            Status = FatSetEndOfFileInfo( IrpContext, Irp, FileObject, Vcb, Fcb );
            break;

        default:

            Status = STATUS_INVALID_PARAMETER;
            break;
        }

        if ( IrpContext != NULL ) {

            FatUnpinRepinnedBcbs( IrpContext );
        }

    try_exit: NOTHING;
    } finally {

        DebugUnwind( FatCommonSetInformation );

        if (FcbAcquired) { FatReleaseFcb( IrpContext, Fcb ); }
        if (VcbAcquired) { FatReleaseVcb( IrpContext, Vcb ); }

        if (!AbnormalTermination()) {

            FatCompleteRequest( IrpContext, Irp, Status );
        }

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

    return Status;
}


//
//  Internal Support Routine
//

VOID
FatQueryBasicInfo (
    IN PIRP_CONTEXT IrpContext,
    IN PFCB Fcb,
    IN PFILE_OBJECT FileObject,
    IN OUT PFILE_BASIC_INFORMATION Buffer,
    IN OUT PLONG Length
    )

/*++
 Description:

    This routine performs the query basic information function for fat.

Arguments:

    Fcb - Supplies the Fcb being queried, it has been verified

    FileObject - Supplies the flag bit that indicates the file was modified.

    Buffer - Supplies a pointer to the buffer where the information is to
        be returned

    Length - Supplies the length of the buffer in bytes, and receives the
        remaining bytes free in the buffer upon return.

Return Value:

    None

--*/

{
    DebugTrace(+1, Dbg, "FatQueryBasicInfo...\n", 0);

    //
    //  Zero out the output buffer, and set it to indicate that
    //  the query is a normal file.  Later we might overwrite the
    //  attribute.
    //

    RtlZeroMemory( Buffer, sizeof(FILE_BASIC_INFORMATION) );

    //

⌨️ 快捷键说明

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