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

📄 ea.c

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

Copyright (c) 1989-2000 Microsoft Corporation

Module Name:

    Ea.c

Abstract:

    This module implements the EA routines for Fat called by
    the dispatch driver.


--*/

#include "FatProcs.h"

//
//  The local debug trace level
//

#define Dbg                              (DEBUG_TRACE_EA)

//
//  Local procedure prototypes
//

IO_STATUS_BLOCK
FatQueryEaUserEaList (
    IN PIRP_CONTEXT IrpContext,
    OUT PCCB Ccb,
    IN PPACKED_EA FirstPackedEa,
    IN ULONG PackedEasLength,
    OUT PUCHAR UserBuffer,
    IN ULONG  UserBufferLength,
    IN PUCHAR UserEaList,
    IN ULONG  UserEaListLength,
    IN BOOLEAN ReturnSingleEntry
    );

IO_STATUS_BLOCK
FatQueryEaIndexSpecified (
    IN PIRP_CONTEXT IrpContext,
    OUT PCCB Ccb,
    IN PPACKED_EA FirstPackedEa,
    IN ULONG PackedEasLength,
    OUT PUCHAR UserBuffer,
    IN ULONG  UserBufferLength,
    IN ULONG  UserEaIndex,
    IN BOOLEAN ReturnSingleEntry
    );

IO_STATUS_BLOCK
FatQueryEaSimpleScan (
    IN PIRP_CONTEXT IrpContext,
    OUT PCCB Ccb,
    IN PPACKED_EA FirstPackedEa,
    IN ULONG PackedEasLength,
    OUT PUCHAR UserBuffer,
    IN ULONG  UserBufferLength,
    IN BOOLEAN ReturnSingleEntry,
    ULONG StartOffset
    );

BOOLEAN
FatIsDuplicateEaName (
    IN PIRP_CONTEXT IrpContext,
    IN PFILE_GET_EA_INFORMATION GetEa,
    IN PUCHAR UserBuffer
    );

#ifdef ALLOC_PRAGMA
#pragma alloc_text(PAGE, FatCommonQueryEa)
#pragma alloc_text(PAGE, FatCommonSetEa)
#pragma alloc_text(PAGE, FatFsdQueryEa)
#pragma alloc_text(PAGE, FatFsdSetEa)
#if 0
#pragma alloc_text(PAGE, FatIsDuplicateEaName)
#pragma alloc_text(PAGE, FatQueryEaIndexSpecified)
#pragma alloc_text(PAGE, FatQueryEaSimpleScan)
#pragma alloc_text(PAGE, FatQueryEaUserEaList)
#endif
#endif


NTSTATUS
FatFsdQueryEa (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the Fsd part of the NtQueryEa API
    call.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the file
        being queried exists.

    Irp - Supplies the Irp being processed.

Return Value:

    NTSTATUS - The FSD status for the Irp.

--*/

{
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;

    DebugTrace(+1, Dbg, "FatFsdQueryEa\n", 0);

    //
    //  Call the common query routine, with blocking allowed if synchronous
    //

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

    try {

        IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );

        Status = FatCommonQueryEa( IrpContext, Irp );

    } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with
        //  the error status that we get back from the
        //  execption code
        //

        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
    }

    if (TopLevel) { IoSetTopLevelIrp( NULL ); }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

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

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}


NTSTATUS
FatFsdSetEa (
    IN PVOLUME_DEVICE_OBJECT VolumeDeviceObject,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the FSD part of the NtSetEa API
    call.

Arguments:

    VolumeDeviceObject - Supplies the volume device object where the file
        being set exists.

    Irp - Supplies the Irp being processed.

Return Value:

    NTSTATUS - The FSD status for the Irp.

--*/

{
    NTSTATUS Status;
    PIRP_CONTEXT IrpContext = NULL;

    BOOLEAN TopLevel;

    DebugTrace(+1, Dbg, "FatFsdSetEa\n", 0);

    //
    //  Call the common set routine, with blocking allowed if synchronous
    //

    FsRtlEnterFileSystem();

    TopLevel = FatIsIrpTopLevel( Irp );

    try {

        IrpContext = FatCreateIrpContext( Irp, CanFsdWait( Irp ) );

        Status = FatCommonSetEa( IrpContext, Irp );

    } except(FatExceptionFilter( IrpContext, GetExceptionInformation() )) {

        //
        //  We had some trouble trying to perform the requested
        //  operation, so we'll abort the I/O request with
        //  the error status that we get back from the
        //  execption code
        //

        Status = FatProcessException( IrpContext, Irp, GetExceptionCode() );
    }

    if (TopLevel) { IoSetTopLevelIrp( NULL ); }

    FsRtlExitFileSystem();

    //
    //  And return to our caller
    //

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

    UNREFERENCED_PARAMETER( VolumeDeviceObject );

    return Status;
}


NTSTATUS
FatCommonQueryEa (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This is the common routine for querying File ea called by both
    the fsd and fsp threads.

Arguments:

    Irp - Supplies the Irp being processed

Return Value:

    NTSTATUS - The return status for the operation

--*/

{
    PIO_STACK_LOCATION IrpSp;

    NTSTATUS Status;

    PUCHAR  Buffer;
    ULONG   UserBufferLength;

    PUCHAR  UserEaList;
    ULONG   UserEaListLength;
    ULONG   UserEaIndex;
    BOOLEAN RestartScan;
    BOOLEAN ReturnSingleEntry;
    BOOLEAN IndexSpecified;

    PVCB Vcb;
    PCCB Ccb;

    PFCB Fcb;
    PDIRENT Dirent;
    PBCB Bcb;

    PDIRENT EaDirent;
    PBCB EaBcb;
    BOOLEAN LockedEaFcb;

    PEA_SET_HEADER EaSetHeader;
    EA_RANGE EaSetRange;

    USHORT ExtendedAttributes;

    FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST);
    return STATUS_INVALID_DEVICE_REQUEST;
#if 0
    //
    //  Get the current Irp stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "FatCommonQueryEa...\n", 0);
    DebugTrace( 0, Dbg, " Wait                = %08lx\n", FlagOn(IrpContext->Flags, IRP_CONTEXT_FLAG_WAIT));
    DebugTrace( 0, Dbg, " Irp                 = %08lx\n", Irp );
    DebugTrace( 0, Dbg, " ->SystemBuffer      = %08lx\n", Irp->AssociatedIrp.SystemBuffer );
    DebugTrace( 0, Dbg, " ->Length            = %08lx\n", IrpSp->Parameters.QueryEa.Length );
    DebugTrace( 0, Dbg, " ->EaList            = %08lx\n", IrpSp->Parameters.QueryEa.EaList );
    DebugTrace( 0, Dbg, " ->EaListLength      = %08lx\n", IrpSp->Parameters.QueryEa.EaListLength );
    DebugTrace( 0, Dbg, " ->EaIndex           = %08lx\n", IrpSp->Parameters.QueryEa.EaIndex );
    DebugTrace( 0, Dbg, " ->RestartScan       = %08lx\n", FlagOn(IrpSp->Flags, SL_RESTART_SCAN));
    DebugTrace( 0, Dbg, " ->ReturnSingleEntry = %08lx\n", FlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY));
    DebugTrace( 0, Dbg, " ->IndexSpecified    = %08lx\n", FlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED));

    Irp->IoStatus.Status = STATUS_SUCCESS;
    Irp->IoStatus.Information = 0;

    //
    //  Check that the file object is associated with either a user file
    //  or directory open.  We don't allow Ea operations on the root
    //  directory.
    //

    {
        TYPE_OF_OPEN OpenType;

        if (((OpenType = FatDecodeFileObject( IrpSp->FileObject,
                                             &Vcb,
                                             &Fcb,
                                             &Ccb )) != UserFileOpen
             && OpenType != UserDirectoryOpen) ||

            (NodeType( Fcb )) == FAT_NTC_ROOT_DCB) {

            FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_PARAMETER );

            DebugTrace(-1, Dbg,
                       "FatCommonQueryEa -> %08lx\n",
                       STATUS_INVALID_PARAMETER);

            return STATUS_INVALID_PARAMETER;
        }
    }

    //
    //  Fat32 does not support ea's.
    //

    if (FatIsFat32(Vcb)) {

        FatCompleteRequest( IrpContext, Irp, STATUS_EAS_NOT_SUPPORTED );
        DebugTrace(-1, Dbg,
                   "FatCommonQueryEa -> %08lx\n",
                   STATUS_EAS_NOT_SUPPORTED);
        return STATUS_EAS_NOT_SUPPORTED;
    }

    //
    //  Acquire shared access to the Fcb and enqueue the Irp if we didn't
    //  get access.
    //

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

        DebugTrace(0, Dbg, "FatCommonQueryEa:  Thread can't wait\n", 0);

        Status = FatFsdPostRequest( IrpContext, Irp );

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

        return Status;
    }

    FatAcquireSharedFcb( IrpContext, Fcb );

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

    UserBufferLength  = IrpSp->Parameters.QueryEa.Length;
    UserEaList        = IrpSp->Parameters.QueryEa.EaList;
    UserEaListLength  = IrpSp->Parameters.QueryEa.EaListLength;
    UserEaIndex       = IrpSp->Parameters.QueryEa.EaIndex;
    RestartScan       = BooleanFlagOn(IrpSp->Flags, SL_RESTART_SCAN);
    ReturnSingleEntry = BooleanFlagOn(IrpSp->Flags, SL_RETURN_SINGLE_ENTRY);
    IndexSpecified    = BooleanFlagOn(IrpSp->Flags, SL_INDEX_SPECIFIED);

    //
    //  Initialize our local values.
    //

    LockedEaFcb = FALSE;
    Bcb = NULL;
    EaBcb = NULL;

    Status = STATUS_SUCCESS;

    RtlZeroMemory( &EaSetRange, sizeof( EA_RANGE ));

    try {

        PPACKED_EA FirstPackedEa;
        ULONG PackedEasLength;

        Buffer = FatMapUserBuffer( IrpContext, Irp );

        //
        //  We verify that the Fcb is still valid.
        //

        FatVerifyFcb( IrpContext, Fcb );

        //
        //  We need to get the dirent for the Fcb to recover the Ea handle.
        //

        FatGetDirentFromFcbOrDcb( IrpContext, Fcb, &Dirent, &Bcb );

        //
        //  Verify that the Ea file is in a consistant state.  If the
        //  Ea modification count in the Fcb doesn't match that in
        //  the CCB, then the Ea file has been changed from under
        //  us.  If we are not starting the search from the beginning
        //  of the Ea set, we return an error.
        //

        if (UserEaList == NULL
            && Ccb->OffsetOfNextEaToReturn != 0
            && !IndexSpecified
            && !RestartScan
            && Fcb->EaModificationCount != Ccb->EaModificationCount) {

            DebugTrace(0, Dbg,
                      "FatCommonQueryEa:  Ea file in unknown state\n", 0);

            Status = STATUS_EA_CORRUPT_ERROR;

            try_return( Status );
        }

        //
        //  Show that the Ea's for this file are consistant for this
        //  file handle.
        //

        Ccb->EaModificationCount = Fcb->EaModificationCount;

        //
        //  If the handle value is 0, then the file has no Eas.  We dummy up
        //  an ea list to use below.
        //

        ExtendedAttributes = Dirent->ExtendedAttributes;

        FatUnpinBcb( IrpContext, Bcb );

        if (ExtendedAttributes == 0) {

            DebugTrace(0, Dbg,
                      "FatCommonQueryEa:  Zero handle, no Ea's for this file\n", 0);

            FirstPackedEa = (PPACKED_EA) NULL;

            PackedEasLength = 0;

        } else {

            //
            //  We need to get the Ea file for this volume.  If the
            //  operation doesn't complete due to blocking, then queue the
            //  Irp to the Fsp.
            //

            FatGetEaFile( IrpContext,
                          Vcb,
                          &EaDirent,
                          &EaBcb,
                          FALSE,
                          FALSE );

            LockedEaFcb = TRUE;

            //
            //  If the above operation completed and the Ea file did not exist,
            //  the disk has been corrupted.  There is an existing Ea handle
            //  without any Ea data.
            //

            if (Vcb->VirtualEaFile == NULL) {

                DebugTrace(0, Dbg,
                          "FatCommonQueryEa:  No Ea file found when expected\n", 0);

                Status = STATUS_NO_EAS_ON_FILE;

                try_return( Status );
            }

            //
            //  We need to try to get the Ea set for the desired file.  If
            //  blocking is necessary then we'll post the request to the Fsp.
            //

            FatReadEaSet( IrpContext,
                          Vcb,
                          ExtendedAttributes,
                          &Fcb->ShortName.Name.Oem,
                          TRUE,

⌨️ 快捷键说明

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