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

📄 easup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
                                   &Buffer[Length] :
                                   (PUCHAR) FullEa + FullEa->NextEntryOffset)) {

            OEM_STRING EaName;
            ULONG EaOffset;

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

            //
            //  Make sure the ea name is valid
            //

            if (!FatIsEaNameValid( IrpContext, EaName )) {

                DebugTrace(0, Dbg,
                           "FatCreateEa:  Invalid Ea Name -> %Z\n",
                           EaName);

                IrpContext->OriginatingIrp->IoStatus.Information = (PUCHAR)FullEa - Buffer;
                IrpContext->OriginatingIrp->IoStatus.Status = STATUS_INVALID_EA_NAME;
                FatRaiseStatus( IrpContext, STATUS_INVALID_EA_NAME );
            }

            //
            //  Check that no invalid ea flags are set.
            //

            //
            //  TEMPCODE  We are returning STATUS_INVALID_EA_NAME
            //  until a more appropriate error code exists.
            //

            if (FullEa->Flags != 0
                && FullEa->Flags != FILE_NEED_EA) {

                IrpContext->OriginatingIrp->IoStatus.Information = (PUCHAR)FullEa - Buffer;
                IrpContext->OriginatingIrp->IoStatus.Status = STATUS_INVALID_EA_NAME;
                FatRaiseStatus( IrpContext, STATUS_INVALID_EA_NAME );
            }

            //
            //  If this is a duplicate name then delete the current ea
            //  value.
            //

            if (FatLocateEaByName( IrpContext,
                                   (PPACKED_EA) EaSetHeader->PackedEas,
                                   PackedEasLength,
                                   &EaName,
                                   &EaOffset )) {

                DebugTrace(0, Dbg, "FatCreateEa:  Duplicate name found\n", 0);

                FatDeletePackedEa( IrpContext,
                                   EaSetHeader,
                                   &PackedEasLength,
                                   EaOffset );
            }

            //
            //  We ignore this value if the eavalue length is zero.
            //

            if (FullEa->EaValueLength == 0) {

                DebugTrace(0, Dbg,
                           "FatCreateEa:  Empty ea\n",
                           0);

                continue;
            }

            FatAppendPackedEa( IrpContext,
                               &EaSetHeader,
                               &PackedEasLength,
                               &AllocationLength,
                               FullEa,
                               BytesPerCluster );
        }

        //
        //  If the resulting length isn't zero, then allocate a FAT cluster
        //  to store the data.
        //

        if (PackedEasLength != 0) {

            PEA_SET_HEADER NewEaSetHeader;

            //
            //  If the packed eas length (plus 4 bytes) is greater
            //  than the maximum allowed ea size, we return an error.
            //

            if (PackedEasLength + 4 > MAXIMUM_EA_SIZE) {

                DebugTrace( 0, Dbg, "Ea length is greater than maximum\n", 0 );

                FatRaiseStatus( IrpContext, STATUS_EA_TOO_LARGE );
            }

            //
            //  Get the Ea file.
            //

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

            LockedEaFcb = TRUE;

            FatAddEaSet( IrpContext,
                         Vcb,
                         PackedEasLength + SIZE_OF_EA_SET_HEADER,
                         EaBcb,
                         EaDirent,
                         EaHandle,
                         &EaSetRange );

            NewEaSetHeader = (PEA_SET_HEADER) EaSetRange.Data;

            //
            //  Store the length of the new Ea's into the NewEaSetHeader.
            //  This is the PackedEasLength + 4.
            //

            PackedEasLength += 4;

            CopyU4char( EaSetHeader->cbList, &PackedEasLength );

            //
            //  Copy all but the first four bytes of EaSetHeader into
            //  the new ea.  The signature and index fields have
            //  already been filled in.
            //

            RtlCopyMemory( &NewEaSetHeader->NeedEaCount,
                           &EaSetHeader->NeedEaCount,
                           PackedEasLength + SIZE_OF_EA_SET_HEADER - 8 );

            FatMarkEaRangeDirty( IrpContext, Vcb->VirtualEaFile, &EaSetRange );
            FatUnpinEaRange( IrpContext, &EaSetRange );

            CcFlushCache( Vcb->VirtualEaFile->SectionObjectPointer, NULL, 0, NULL );

        //
        //  There was no data added to the Ea file.  Return a handle
        //  of 0.
        //

        } else {

            *EaHandle = 0;
        }

    } finally {

        DebugUnwind( FatCreateEa );

        //
        //  Deallocate the EaSetHeader if present.
        //

        if (EaSetHeader) {

            ExFreePool( EaSetHeader );
        }

        //
        //  Release the EaFcb if held.
        //

        if (LockedEaFcb) {

            FatReleaseFcb( IrpContext, Vcb->EaFcb );
        }

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

        FatUnpinBcb( IrpContext, EaBcb );
        FatUnpinEaRange( IrpContext, &EaSetRange );

        DebugTrace(-1, Dbg, "FatCreateEa -> Exit\n", 0);
    }

    return;
}

VOID
FatDeleteEa (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN USHORT EaHandle,
    IN POEM_STRING FileName
    )

/*++

Routine Description:

    This routine is called to remove an entire ea set.  Most of the work
    is done in the call to 'FatDeleteEaSet'.  This routine opens the
    Ea file and then calls the support routine.

    NOTE: This routine may block, it should not be called unless the
    thread is waitable.

Arguments:

    Vcb - Vcb for the volume

    EaHandle - The handle for the Ea's to remove.  This handle will be
               verified during this operation.

    FileName - The name of the file whose Ea's are being removed.  This
               name is compared against the Ea owner's name in the Ea set.

Return Value:

    None.

--*/

{
    PBCB EaBcb;
    BOOLEAN LockedEaFcb;

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

    //
    //  Initialize local values.
    //

    EaBcb = NULL;
    LockedEaFcb = FALSE;

    //
    //  Use a try statement to facilitate cleanup.
    //

    try {

        PDIRENT EaDirent;

        //
        //  Get the Ea stream file.  If the file doesn't exist on the disk
        //  then the disk has been corrupted.
        //

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

        LockedEaFcb = TRUE;

        //
        //  If we didn't get the Ea file, then the disk is corrupt.
        //

        if ( EaBcb == NULL ) {


            DebugTrace(0, Dbg,
                       "FatDeleteEa:  No Ea file exists\n",
                       0);

            FatRaiseStatus( IrpContext, STATUS_NO_EAS_ON_FILE );
        }

        //
        //  We now have everything we need to delete the ea set.  Call the
        //  support routine to do this.
        //

        FatDeleteEaSet( IrpContext,
                        Vcb,
                        EaBcb,
                        EaDirent,
                        EaHandle,
                        FileName );

        CcFlushCache( Vcb->VirtualEaFile->SectionObjectPointer, NULL, 0, NULL );

    } finally {

        DebugUnwind( FatDeleteEa );

        //
        //  Release the EaFcb if held.
        //

        if (LockedEaFcb) {

            FatReleaseFcb( IrpContext, Vcb->EaFcb );
        }

        //
        //  Unpin the dirent for the Ea file if pinned.
        //

        FatUnpinBcb( IrpContext, EaBcb );

        DebugTrace(-1, Dbg, "FatDeleteEa -> Exit\n", 0);
    }

    return;
}


VOID
FatGetEaFile (
    IN PIRP_CONTEXT IrpContext,
    IN OUT PVCB Vcb,
    OUT PDIRENT *EaDirent,
    OUT PBCB *EaBcb,
    IN BOOLEAN CreateFile,
    IN BOOLEAN ExclusiveFcb
    )

/*++

Routine Description:

    This routine is used to completely initialize the Vcb and
    the Ea file for the Vcb.

    If the Vcb doesn't have the Ea file object, then we first try to
    lookup the Ea data file in the root directory and if that fails
    we try to create the file.  The 'CreateFile' flag is used to check
    whether it is necessary to create the Ea file.

    This routine will lock down the Fcb for exclusive or shared access before
    performing any operations.  If the operation does not complete due
    to blocking, exclusive or shared access will be given up before returning.

    If we are creating the Ea file and marking sections of it dirty,
    we can't use the repin feature through the cache map.  In that case
    we use a local IrpContext and then unpin all of the Bcb's before
    continuing.

    Note: If this routine will be creating the Ea file, we are guaranteed
    to be waitable.

Arguments:

    Vcb - Vcb for the volume

    EaDirent - Location to store the address of the pinned dirent for the
               Ea file.

    EaBcb - Location to store the address of the Bcb for the pinned dirent.

    CreateFile - Boolean indicating whether we should create the Ea file
                 on the disk.

    ExclusiveFcb - Indicates whether shared or exclusive access is desired
                   for the EaFcb.

Return Value:

    None.

--*/

{
    PFILE_OBJECT EaStreamFile = NULL;
    EA_RANGE EaFileRange;

    BOOLEAN UnwindLockedEaFcb = FALSE;
    BOOLEAN UnwindLockedRootDcb = FALSE;
    BOOLEAN UnwindAllocatedDiskSpace = FALSE;
    BOOLEAN UnwindEaDirentCreated = FALSE;
    BOOLEAN UnwindUpdatedSizes = FALSE;

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

    RtlZeroMemory( &EaFileRange, sizeof( EA_RANGE ));

    //
    //  Use a try to facilitate cleanup
    //

    try {

        OEM_STRING EaFileName;
        LARGE_INTEGER SectionSize;

        //
        //  Check if the Vcb already has the file object.  If it doesn't, then
        //  we need to search the root directory for the Ea data file.
        //

        if (Vcb->VirtualEaFile == NULL) {

            //
            //  Always lock the Ea file exclusively if we have to create the file.
            //

            if ( !FatAcquireExclusiveFcb( IrpContext, Vcb->EaFcb )) {

                DebugTrace(0, Dbg, "FatGetEaFile:  Can't grab exclusive\n", 0);
                FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
            }

            UnwindLockedEaFcb = TRUE;

        //
        //  Otherwise we acquire the Fcb as the caller requested.
        //

        } else {

            if ((ExclusiveFcb && !FatAcquireExclusiveFcb( IrpContext, Vcb->EaFcb ))
                || (!ExclusiveFcb && !FatAcquireSharedFcb( IrpContext, Vcb->EaFcb))) {

                DebugTrace(0, Dbg, "FatGetEaFile:  Can't grab EaFcb\n", 0);

                FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
            }

            UnwindLockedEaFcb = TRUE;

            //
            //  If the file now does not exist we need to release the Fcb and
            //  reacquire exclusive if we acquired shared.
            //

            if ((Vcb->VirtualEaFile == NULL) && !ExclusiveFcb) {

                FatReleaseFcb( IrpContext, Vcb->EaFcb );
                UnwindLockedEaFcb = FALSE;

                if (!FatAcquireExclusiveFcb( IrpContext, Vcb->EaFcb )) {

                    DebugTrace(0, Dbg, "FatGetEaFile:  Can't grab EaFcb\n", 0);

                    FatRaiseStatus( IrpContext, STATUS_CANT_WAIT );
                }

                UnwindLockedEaFcb = TRUE;
            }
        }

        //

⌨️ 快捷键说明

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