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

📄 easup.c

📁 winddk src目录下的文件系统驱动源码压缩!
💻 C
📖 第 1 页 / 共 5 页
字号:
        //  If the file object is now there we only need to get the
        //  dirent for the Ea file.
        //

        if (Vcb->VirtualEaFile != NULL) {

            FatVerifyFcb( IrpContext, Vcb->EaFcb );

            FatGetDirentFromFcbOrDcb( IrpContext,
                                      Vcb->EaFcb,
                                      FALSE,
                                      EaDirent,
                                      EaBcb );

            try_return( NOTHING );

        } else {

            VBO ByteOffset;

            //
            //  Always mark the ea fcb as good.
            //

            Vcb->EaFcb->FcbCondition = FcbGood;

            //
            //  We try to lookup the dirent for the Ea Fcb.
            //

            EaFileName.Buffer = "EA DATA. SF";
            EaFileName.Length = 11;
            EaFileName.MaximumLength = 12;

            //
            //  Now pick up the root directory to be synchronized with
            //  deletion/creation of entries.  If we may create the file,
            //  get it exclusive right now.
            //
            //  Again, note how we are relying on bottom-up lockorder. We
            //  already got the EaFcb.
            //

            if (CreateFile) {
                ExAcquireResourceExclusiveLite( Vcb->RootDcb->Header.Resource, TRUE );
            } else {
                ExAcquireResourceSharedLite( Vcb->RootDcb->Header.Resource, TRUE );
            }
            UnwindLockedRootDcb = TRUE;

            FatLocateSimpleOemDirent( IrpContext,
                                      Vcb->EaFcb->ParentDcb,
                                      &EaFileName,
                                      EaDirent,
                                      EaBcb,
                                      &ByteOffset );

            //
            //  If the file exists, we need to create the virtual file
            //  object for it.
            //

            if (*EaDirent != NULL) {

                //
                //  Since we may be modifying the dirent, pin the data now.
                //

                FatPinMappedData( IrpContext,
                                  Vcb->EaFcb->ParentDcb,
                                  ByteOffset,
                                  sizeof(DIRENT),
                                  EaBcb );

                //
                //  Update the Fcb with information on the file size
                //  and disk location.  Also increment the open/unclean
                //  counts in the EaFcb and the open count in the
                //  Vcb.
                //

                Vcb->EaFcb->FirstClusterOfFile = (*EaDirent)->FirstClusterOfFile;
                Vcb->EaFcb->DirentOffsetWithinDirectory = ByteOffset;

                //
                //  Find the allocation size.  The purpose here is
                //  really to completely fill in the Mcb for the
                //  file.
                //

                Vcb->EaFcb->Header.AllocationSize.QuadPart = FCB_LOOKUP_ALLOCATIONSIZE_HINT;

                FatLookupFileAllocationSize( IrpContext, Vcb->EaFcb );

                //
                //  Start by computing the section size for the cache
                //  manager.
                //

                SectionSize.QuadPart = (*EaDirent)->FileSize;
                Vcb->EaFcb->Header.AllocationSize = SectionSize;
                Vcb->EaFcb->Header.FileSize = SectionSize;

                //
                //  Create and initialize the file object for the
                //  Ea virtual file.
                //

                EaStreamFile = FatOpenEaFile( IrpContext, Vcb->EaFcb );

                Vcb->VirtualEaFile = EaStreamFile;

            //
            //  Else there was no dirent.  If we were instructed to
            //  create the file object, we will try to create the dirent,
            //  allocate disk space, initialize the Ea file header and
            //  return this information to the user.
            //

            } else if (CreateFile) {

                ULONG BytesPerCluster;
                ULONG OffsetTableSize;
                ULONG AllocationSize;
                PEA_FILE_HEADER FileHeader;
                USHORT AllocatedClusters;
                PUSHORT CurrentIndex;
                ULONG Index;
                NTSTATUS Status;

                DebugTrace(0, Dbg, "FatGetEaFile:  Creating local IrpContext\n", 0);

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

                AllocationSize = (((ULONG) sizeof( EA_FILE_HEADER ) << 1) + BytesPerCluster - 1)
                                 & ~(BytesPerCluster - 1);

                AllocatedClusters = (USHORT) (AllocationSize
                                    >> Vcb->AllocationSupport.LogOfBytesPerCluster);

                OffsetTableSize = AllocationSize - sizeof( EA_FILE_HEADER );

                //
                //  Allocate disk space, the space allocated is 1024 bytes
                //  rounded up to the nearest cluster size.
                //

                FatAllocateDiskSpace( IrpContext,
                                      Vcb,
                                      0,
                                      &AllocationSize,
                                      FALSE,
                                      &Vcb->EaFcb->Mcb );

                UnwindAllocatedDiskSpace = TRUE;

                //
                //  Allocate and initialize a dirent in the root directory
                //  to describe this new file.
                //

                Vcb->EaFcb->DirentOffsetWithinDirectory =
                    FatCreateNewDirent( IrpContext,
                                        Vcb->EaFcb->ParentDcb,
                                        1 );

                FatPrepareWriteDirectoryFile( IrpContext,
                                              Vcb->EaFcb->ParentDcb,
                                              Vcb->EaFcb->DirentOffsetWithinDirectory,
                                              sizeof(DIRENT),
                                              EaBcb,
                                              EaDirent,
                                              FALSE,
                                              TRUE,
                                              &Status );

                ASSERT( NT_SUCCESS( Status ));

                UnwindEaDirentCreated = TRUE;

                FatConstructDirent( IrpContext,
                                    *EaDirent,
                                    &EaFileName,
                                    FALSE,
                                    FALSE,
                                    NULL,
                                    FAT_DIRENT_ATTR_READ_ONLY
                                    | FAT_DIRENT_ATTR_HIDDEN
                                    | FAT_DIRENT_ATTR_SYSTEM
                                    | FAT_DIRENT_ATTR_ARCHIVE,
                                    TRUE,
                                    NULL );

                (*EaDirent)->FileSize = AllocationSize;

                //
                //  Initialize the Fcb for this file and initialize the
                //  cache map as well.
                //

                //
                //  Start by computing the section size for the cache
                //  manager.
                //

                SectionSize.QuadPart = (*EaDirent)->FileSize;
                Vcb->EaFcb->Header.AllocationSize = SectionSize;
                Vcb->EaFcb->Header.FileSize = SectionSize;
                UnwindUpdatedSizes = TRUE;

                //
                //  Create and initialize the file object for the
                //  Ea virtual file.
                //

                EaStreamFile = FatOpenEaFile( IrpContext, Vcb->EaFcb );

                //
                //  Update the Fcb with information on the file size
                //  and disk location.  Also increment the open/unclean
                //  counts in the EaFcb and the open count in the
                //  Vcb.
                //

                {
                    LBO FirstLboOfFile;

                    FatLookupMcbEntry( Vcb, &Vcb->EaFcb->Mcb,
                                       0,
                                       &FirstLboOfFile,
                                       NULL,
                                       NULL );

                    //
                    //  The discerning reader will note that this doesn't take
                    //  FAT32 into account, which is of course intentional.
                    //
                    
                    (*EaDirent)->FirstClusterOfFile =
                        (USHORT) FatGetIndexFromLbo( Vcb, FirstLboOfFile );
                }

                Vcb->EaFcb->FirstClusterOfFile = (*EaDirent)->FirstClusterOfFile;

                //
                //  Initialize the Ea file header and mark the Bcb as dirty.
                //

                FatPinEaRange( IrpContext,
                               EaStreamFile,
                               Vcb->EaFcb,
                               &EaFileRange,
                               0,
                               AllocationSize,
                               STATUS_DATA_ERROR );

                FileHeader = (PEA_FILE_HEADER) EaFileRange.Data;

                RtlZeroMemory( FileHeader, AllocationSize );
                FileHeader->Signature = EA_FILE_SIGNATURE;

                for (Index = MAX_EA_BASE_INDEX, CurrentIndex = FileHeader->EaBaseTable;
                     Index;
                     Index--, CurrentIndex++) {

                    *CurrentIndex = AllocatedClusters;
                }

                //
                //  Initialize the offset table with the offset set to
                //  after the just allocated clusters.
                //

                for (Index = OffsetTableSize >> 1,
                        CurrentIndex = (PUSHORT) ((PUCHAR) FileHeader + sizeof( EA_FILE_HEADER ));
                     Index;
                     Index--, CurrentIndex++) {

                    *CurrentIndex = UNUSED_EA_HANDLE;
                }

                //
                //  Unpin the file header and offset table.
                //

                FatMarkEaRangeDirty( IrpContext, EaStreamFile, &EaFileRange );
                FatUnpinEaRange( IrpContext, &EaFileRange );

                CcFlushCache( EaStreamFile->SectionObjectPointer, NULL, 0, NULL );

                //
                //  Return the Ea file object to the user.
                //

                Vcb->VirtualEaFile = EaStreamFile;
            }
        }
    try_exit:  NOTHING;
    } finally {

        DebugUnwind( FatGetEaFile );

        //
        //  If this is abnormal termination and disk space has been
        //  allocated.  We deallocate it now.
        //

        if (AbnormalTermination()) {

            //
            //  Deallocate the Ea file
            //

            if (UnwindAllocatedDiskSpace) {

                FatDeallocateDiskSpace( IrpContext,
                                        Vcb,
                                        &Vcb->EaFcb->Mcb );
            }

            //
            //  Delete the dirent for the Ea file, if created.
            //

            if (UnwindEaDirentCreated) {

                if (UnwindUpdatedSizes) {

                    Vcb->EaFcb->Header.AllocationSize.QuadPart = 0;
                    Vcb->EaFcb->Header.FileSize.QuadPart = 0;
                }

                FatUnpinBcb( IrpContext, *EaBcb );
                FatDeleteDirent( IrpContext, Vcb->EaFcb, NULL, TRUE );
            }

            //
            //  Release the EA Fcb if held
            //

            if (UnwindLockedEaFcb) {

                FatReleaseFcb( IrpContext, Vcb->EaFcb );
            }
            
            //
            //  Dereference the Ea stream file if created.
            //

            if (EaStreamFile != NULL) {

                ObDereferenceObject( EaStreamFile );
            }
        }

        //
        //  Always release the root Dcb (our caller releases the EA Fcb if we
        //  do not raise).
        //
        
        if (UnwindLockedRootDcb) {

            FatReleaseFcb( IrpContext, Vcb->RootDcb );
        }

        //
        //  If the Ea file header is locked down.  We unpin it now.
        //

        FatUnpinEaRange( IrpContext, &EaFileRange );

        DebugTrace(-1, Dbg, "FatGetEaFile:  Exit\n", 0);
    }

    return;
}


VOID
FatReadEaSet (
    IN PIRP_CONTEXT IrpContext,
    IN PVCB Vcb,
    IN USHORT EaHandle,
    IN POEM_STRING FileName,
    IN BOOLEAN ReturnEntireSet,
    OUT PEA_RANGE EaSetRange
    )

/*++

Routine Description:

    This routine pins the Ea set for the given ea handle within the
    Ea stream file.  The EaHandle, after first comparing against valid
    index values, is used to compute the cluster offset for this
    this Ea set.  The Ea set is then verified as belonging to this
    index and lying within the Ea data file.

    The caller of this function will have verified that the Ea file
    exists and that the Vcb field points to an initialized cache file.
    The caller will already have gained exclusive access to the
    EaFcb.

Arguments:

    Vcb - Supplies the Vcb for the volume.

    EaHandle - Supplies the handle for the Ea's to read.

    FileName - Name of the file whose Ea's are being read.

    ReturnEntireSet - Indicates if the caller needs the entire set
        as opposed to just the header.

    EaSetRange - Pointer to the EaRange structure which will describe the Ea
        on return.

Return Value:

    None

--*/

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

    ULONG EaOffsetVbo;
    EA_RANGE EaOffsetRange;
    USHORT EaOffsetCluster;

    EA_RANGE EaHeaderRange;
    PEA_FILE_HEADER EaHeader;

    ULONG EaSetVbo;
    PEA_SET_HEADER EaSet;

    ULONG CbList;

    DebugTrace(+1, Dbg, "FatReadEaSet\n", 0);
    DebugTrace( 0, Dbg, "  Vcb      = %8lx\n", Vcb);

    //
    //  Verify that the Ea index has a legal value.  Raise status
    //  STATUS_NONEXISTENT_EA_ENTRY if illegal.
    //

    if (EaHandle < MIN_EA_HANDLE
        || EaHandle > MAX_EA_HANDLE) {

        DebugTrace(-1, Dbg, "FatReadEaSet: Illegal handle value\n", 0);
        FatRaiseStatus( IrpContext, STATUS_NONEXISTENT_EA_ENTRY );
    }

⌨️ 快捷键说明

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