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

📄 ea.c

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

            EaSetHeader = (PEA_SET_HEADER) EaSetRange.Data;

            //
            //  Find the start and length of the Eas.
            //

            FirstPackedEa = (PPACKED_EA) EaSetHeader->PackedEas;

            PackedEasLength = GetcbList( EaSetHeader ) - 4;
        }

        //
        //  Protect our access to the user buffer since IO dosn't do this
        //  for us in this path unless we had specified that our driver
        //  requires buffering for these large requests.  We don't, so ...
        //

        try {

            //
            //  Let's clear the output buffer.
            //

            RtlZeroMemory( Buffer, UserBufferLength );

            //
            //  We now satisfy the user's request depending on whether he
            //  specified an Ea name list, an Ea index or restarting the
            //  search.
            //

            //
            //  The user has supplied a list of Ea names.
            //

            if (UserEaList != NULL) {

                Irp->IoStatus = FatQueryEaUserEaList( IrpContext,
                                                      Ccb,
                                                      FirstPackedEa,
                                                      PackedEasLength,
                                                      Buffer,
                                                      UserBufferLength,
                                                      UserEaList,
                                                      UserEaListLength,
                                                      ReturnSingleEntry );

            //
            //  The user supplied an index into the Ea list.
            //

            } else if (IndexSpecified) {

                Irp->IoStatus = FatQueryEaIndexSpecified( IrpContext,
                                                          Ccb,
                                                          FirstPackedEa,
                                                          PackedEasLength,
                                                          Buffer,
                                                          UserBufferLength,
                                                          UserEaIndex,
                                                          ReturnSingleEntry );

            //
            //  Else perform a simple scan, taking into account the restart
            //  flag and the position of the next Ea stored in the Ccb.
            //

            } else {

                Irp->IoStatus = FatQueryEaSimpleScan( IrpContext,
                                                      Ccb,
                                                      FirstPackedEa,
                                                      PackedEasLength,
                                                      Buffer,
                                                      UserBufferLength,
                                                      ReturnSingleEntry,
                                                      RestartScan
                                                      ? 0
                                                      : Ccb->OffsetOfNextEaToReturn );
            }

        }  except (!FsRtlIsNtstatusExpected(GetExceptionCode()) ?
                   EXCEPTION_EXECUTE_HANDLER : EXCEPTION_CONTINUE_SEARCH) {

               //
               //  We must have had a problem filling in the user's buffer, so fail.
               //

               Irp->IoStatus.Status = GetExceptionCode();
               Irp->IoStatus.Information = 0;
        }

        Status = Irp->IoStatus.Status;

    try_exit: NOTHING;
    } finally {

        DebugUnwind( FatCommonQueryEa );

        //
        //  Release the Fcb for the file object, and the Ea Fcb if
        //  successfully locked.
        //

        FatReleaseFcb( IrpContext, Fcb );

        if (LockedEaFcb) {

            FatReleaseFcb( IrpContext, Vcb->EaFcb );
        }

        //
        //  Unpin the dirents for the Fcb, EaFcb and EaSetFcb if necessary.
        //

        FatUnpinBcb( IrpContext, Bcb );
        FatUnpinBcb( IrpContext, EaBcb );

        FatUnpinEaRange( IrpContext, &EaSetRange );

        if (!AbnormalTermination()) {

            FatCompleteRequest( IrpContext, Irp, Status );
        }

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

    return Status;
#endif
}


NTSTATUS
FatCommonSetEa (
    IN PIRP_CONTEXT IrpContext,
    IN PIRP Irp
    )

/*++

Routine Description:

    This routine implements the common Set Ea File Api called by the
    the Fsd and Fsp threads

Arguments:

    Irp - Supplies the Irp to process

Return Value:

    NTSTATUS - The appropriate status for the Irp

--*/

{
    PIO_STACK_LOCATION IrpSp;

    NTSTATUS Status;

    USHORT ExtendedAttributes;

    PUCHAR Buffer;
    ULONG UserBufferLength;

    PVCB Vcb;
    PCCB Ccb;

    PFCB Fcb;
    PDIRENT Dirent;
    PBCB Bcb = NULL;

    PDIRENT EaDirent = NULL;
    PBCB EaBcb = NULL;

    PEA_SET_HEADER EaSetHeader = NULL;

    PEA_SET_HEADER PrevEaSetHeader;
    PEA_SET_HEADER NewEaSetHeader;
    EA_RANGE EaSetRange;

    BOOLEAN AcquiredVcb = FALSE;
    BOOLEAN AcquiredFcb = FALSE;
    BOOLEAN AcquiredParentDcb = FALSE;
    BOOLEAN AcquiredRootDcb = FALSE;
    BOOLEAN AcquiredEaFcb = FALSE;

    FatCompleteRequest( IrpContext, Irp, STATUS_INVALID_DEVICE_REQUEST);
    return STATUS_INVALID_DEVICE_REQUEST;
    
#if 0
 
    //
    //  The following booleans are used in the unwind process.
    //

    //
    //  Get the current Irp stack location
    //

    IrpSp = IoGetCurrentIrpStackLocation( Irp );

    DebugTrace(+1, Dbg, "FatCommonSetEa...\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.SetEa.Length );

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

    //
    //  Check that the file object is associated with either a user file
    //  or directory open.
    //

    {
        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,
                       "FatCommonSetEa -> %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,
                   "FatCommonSetEa -> %08lx\n",
                   STATUS_EAS_NOT_SUPPORTED);
        return STATUS_EAS_NOT_SUPPORTED;
    }

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

    UserBufferLength  = IrpSp->Parameters.SetEa.Length;

    //
    //  Since we ask for no outside help (direct or buffered IO), it
    //  is our responsibility to insulate ourselves from the
    //  deviousness of the user above.  Now, buffer and validate the
    //  contents.
    //

    Buffer = FatBufferUserBuffer( IrpContext, Irp, UserBufferLength );

    //
    //  Check the validity of the buffer with the new eas.  We really
    //  need to do this always since we don't know, if it was already
    //  buffered, that we buffered and checked it or some overlying
    //  filter buffered without checking.
    //

    Status = IoCheckEaBufferValidity( (PFILE_FULL_EA_INFORMATION) Buffer,
                                      UserBufferLength,
                                      (PULONG)&Irp->IoStatus.Information );

    if (!NT_SUCCESS( Status )) {

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

    //
    //  Acquire exclusive access to the Fcb.  If this is a write-through operation
    //  we will need to pick up the other possible streams that can be modified in
    //  this operation so that the locking order is preserved - the root directory
    //  (dirent addition if EA database doesn't already exist) and the parent
    //  directory (addition of the EA handle to the object's dirent).
    //
    //  We are primarily synchronizing with directory enumeration here.
    //
    //  If we cannot wait need to send things off to the fsp.
    //

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

        DebugTrace(0, Dbg, "FatCommonSetEa:  Set Ea must be waitable\n", 0);

        Status = FatFsdPostRequest( IrpContext, Irp );

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

        return Status;
    }

    //
    //  Set this handle as having modified the file
    //

    IrpSp->FileObject->Flags |= FO_FILE_MODIFIED;

    RtlZeroMemory( &EaSetRange, sizeof( EA_RANGE ));

    try {

        ULONG PackedEasLength;
        BOOLEAN PreviousEas;
        ULONG AllocationLength;
        ULONG BytesPerCluster;
        USHORT EaHandle;

        PFILE_FULL_EA_INFORMATION FullEa;

        //
        //  Now go pick up everything
        //
        
        FatAcquireSharedVcb( IrpContext, Fcb->Vcb );
        AcquiredVcb = TRUE;
        FatAcquireExclusiveFcb( IrpContext, Fcb );
        AcquiredFcb = TRUE;

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

            if (Fcb->ParentDcb) {

                FatAcquireExclusiveFcb( IrpContext, Fcb->ParentDcb );
                AcquiredParentDcb = TRUE;
            }

            FatAcquireExclusiveFcb( IrpContext, Fcb->Vcb->RootDcb );
            AcquiredRootDcb = TRUE;
        }

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

        DebugTrace(0, Dbg, "FatCommonSetEa:  Dirent Address -> %08lx\n",
                   Dirent );
        DebugTrace(0, Dbg, "FatCommonSetEa:  Dirent Bcb -> %08lx\n",
                   Bcb);

        //
        //  If the handle value is 0, then the file has no Eas.  In that
        //  case we allocate memory to hold the Eas to be added.  If there
        //  are existing Eas for the file, then we must read from the
        //  file and copy the Eas.
        //

        ExtendedAttributes = Dirent->ExtendedAttributes;

        FatUnpinBcb( IrpContext, Bcb );

        if (ExtendedAttributes == 0) {

            PreviousEas = FALSE;

            DebugTrace(0, Dbg,
                      "FatCommonSetEa:  File has no current Eas\n", 0 );

        } else {

            PreviousEas = TRUE;

            DebugTrace(0, Dbg, "FatCommonSetEa:  File has previous Eas\n", 0 );

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

            AcquiredEaFcb = TRUE;

            //
            //  If we didn't get the file then there is an error on
            //  the disk.
            //

            if (Vcb->VirtualEaFile == NULL) {

                Status = STATUS_NO_EAS_ON_FILE;
                try_return( Status );
            }
        }

        DebugTrace(0, Dbg, "FatCommonSetEa:  EaBcb -> %08lx\n", EaBcb);

        DebugTrace(0, Dbg, "FatCommonSetEa:  EaDirent -> %08lx\n", EaDirent);

        //
        //  If the file has existing ea's, we need to read them to
        //  determine the size of the buffer allocation.
        //

        if (PreviousEas) {

            //
            //  We need to try to get the Ea set for the desired file.
            //

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

            PrevEaSetHeader = (PEA_SET_HEADER) EaSetRange.Data;

            //
            //  We now must allocate pool memory for our copy of the
            //  EaSetHeader and then copy the Ea data into it.  At that
            //  time we can unpin the EaSet.
            //

            PackedEasLength = GetcbList( PrevEaSetHeader ) - 4;

        //
        //  Else we will create a dummy EaSetHeader.
        //

        } else {

            PackedEasLength = 0;
        }

        BytesPerCluster = 1 << Vcb->AllocationSupport.LogOfBytesPerCluster;

        AllocationLength = (PackedEasLength
                            + SIZE_OF_EA_SET_HEADER
                            + BytesPerCluster - 1)
                           & ~(BytesPerCluster - 1);

        EaSetHeader = FsRtlAllocatePoolWithTag( PagedPool,
                                                AllocationLength,
                                                TAG_EA_SET_HEADER );

        //
        //  Copy the existing Eas over to pool memory.
        //

        if (PreviousEas) {

            RtlCopyMemory( EaSetHeader, PrevEaSetHeader, AllocationLength );

            FatUnpinEaRange( IrpContext, &EaSetRange );

        } else {

            RtlZeroMemory( EaSetHeader, AllocationLength );

            RtlCopyMemory( EaSetHeader->OwnerFileName,
                           Fcb->ShortName.Name.Oem.Buffer,
                           Fcb->ShortName.Name.Oem.Length );
        }


        AllocationLength -= SIZE_OF_EA_SET_HEADER;

        DebugTrace(0, Dbg, "FatCommonSetEa:  Initial Ea set -> %08lx\n",
                   EaSetHeader);

        //
        //  At this point we have either read in the current eas for the file
        //  or we have initialized a new empty buffer for the eas.  Now for
        //  each full ea in the input user buffer we do the specified operation
        //  on the ea
        //

        for (FullEa = (PFILE_FULL_EA_INFORMATION) Buffer;
             FullEa < (PFILE_FULL_EA_INFORMATION) &Buffer[UserBufferLength];
             FullEa = (PFILE_FULL_EA_INFORMATION) (FullEa->NextEntryOffset == 0 ?
                                  &Buffer[UserBufferLength] :
                                  (PUCHAR) FullEa + FullEa->NextEntryOffset)) {

            OEM_STRING EaName;
            ULONG Offset;

            EaName.MaximumLength = EaName.Length = FullEa->EaNameLength;
            EaName.Buffer = &FullEa->EaName[0];

⌨️ 快捷键说明

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