123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595 |
- /** @file
- Routines dealing with setting/getting file/volume info
- Copyright (c) 2005 - 2015, Intel Corporation. All rights reserved.<BR>
- SPDX-License-Identifier: BSD-2-Clause-Patent
- **/
- #include "Fat.h"
- /**
- Get the volume's info into Buffer.
- @param Volume - FAT file system volume.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing volume info.
- @retval EFI_SUCCESS - Get the volume info successfully.
- @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
- **/
- EFI_STATUS
- FatGetVolumeInfo (
- IN FAT_VOLUME *Volume,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- );
- /**
- Set the volume's info.
- @param Volume - FAT file system volume.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing the new volume info.
- @retval EFI_SUCCESS - Set the volume info successfully.
- @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
- @retval EFI_WRITE_PROTECTED - The volume is read only.
- @return other - An error occurred when operation the disk.
- **/
- EFI_STATUS
- FatSetVolumeInfo (
- IN FAT_VOLUME *Volume,
- IN UINTN BufferSize,
- IN VOID *Buffer
- );
- /**
- Set or Get the some types info of the file into Buffer.
- @param IsSet - TRUE:The access is set, else is get
- @param FHand - The handle of file
- @param Type - The type of the info
- @param BufferSize - Size of Buffer
- @param Buffer - Buffer containing volume info
- @retval EFI_SUCCESS - Get the info successfully
- @retval EFI_DEVICE_ERROR - Can not find the OFile for the file
- **/
- EFI_STATUS
- FatSetOrGetInfo (
- IN BOOLEAN IsSet,
- IN EFI_FILE_PROTOCOL *FHand,
- IN EFI_GUID *Type,
- IN OUT UINTN *BufferSize,
- IN OUT VOID *Buffer
- );
- /**
- Get the open file's info into Buffer.
- @param OFile - The open file.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing file info.
- @retval EFI_SUCCESS - Get the file info successfully.
- @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
- **/
- EFI_STATUS
- FatGetFileInfo (
- IN FAT_OFILE *OFile,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
- {
- return FatGetDirEntInfo (OFile->Volume, OFile->DirEnt, BufferSize, Buffer);
- }
- /**
- Get the volume's info into Buffer.
- @param Volume - FAT file system volume.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing volume info.
- @retval EFI_SUCCESS - Get the volume info successfully.
- @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
- **/
- EFI_STATUS
- FatGetVolumeInfo (
- IN FAT_VOLUME *Volume,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
- {
- UINTN Size;
- UINTN NameSize;
- UINTN ResultSize;
- CHAR16 Name[FAT_NAME_LEN + 1];
- EFI_STATUS Status;
- EFI_FILE_SYSTEM_INFO *Info;
- UINT8 ClusterAlignment;
- Size = SIZE_OF_EFI_FILE_SYSTEM_INFO;
- Status = FatGetVolumeEntry (Volume, Name);
- NameSize = StrSize (Name);
- ResultSize = Size + NameSize;
- ClusterAlignment = Volume->ClusterAlignment;
- //
- // If we don't have valid info, compute it now
- //
- FatComputeFreeInfo (Volume);
- Status = EFI_BUFFER_TOO_SMALL;
- if (*BufferSize >= ResultSize) {
- Status = EFI_SUCCESS;
- Info = Buffer;
- ZeroMem (Info, SIZE_OF_EFI_FILE_SYSTEM_INFO);
- Info->Size = ResultSize;
- Info->ReadOnly = Volume->ReadOnly;
- Info->BlockSize = (UINT32) Volume->ClusterSize;
- Info->VolumeSize = LShiftU64 (Volume->MaxCluster, ClusterAlignment);
- Info->FreeSpace = LShiftU64 (
- Volume->FatInfoSector.FreeInfo.ClusterCount,
- ClusterAlignment
- );
- CopyMem ((CHAR8 *) Buffer + Size, Name, NameSize);
- }
- *BufferSize = ResultSize;
- return Status;
- }
- /**
- Get the volume's label info into Buffer.
- @param Volume - FAT file system volume.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing volume's label info.
- @retval EFI_SUCCESS - Get the volume's label info successfully.
- @retval EFI_BUFFER_TOO_SMALL - The buffer is too small.
- **/
- EFI_STATUS
- FatGetVolumeLabelInfo (
- IN FAT_VOLUME *Volume,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
- {
- UINTN Size;
- UINTN NameSize;
- UINTN ResultSize;
- CHAR16 Name[FAT_NAME_LEN + 1];
- EFI_STATUS Status;
- Size = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL;
- Status = FatGetVolumeEntry (Volume, Name);
- NameSize = StrSize (Name);
- ResultSize = Size + NameSize;
- Status = EFI_BUFFER_TOO_SMALL;
- if (*BufferSize >= ResultSize) {
- Status = EFI_SUCCESS;
- CopyMem ((CHAR8 *) Buffer + Size, Name, NameSize);
- }
- *BufferSize = ResultSize;
- return Status;
- }
- /**
- Set the volume's info.
- @param Volume - FAT file system volume.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing the new volume info.
- @retval EFI_SUCCESS - Set the volume info successfully.
- @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
- @retval EFI_WRITE_PROTECTED - The volume is read only.
- @return other - An error occurred when operation the disk.
- **/
- EFI_STATUS
- FatSetVolumeInfo (
- IN FAT_VOLUME *Volume,
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
- {
- EFI_FILE_SYSTEM_INFO *Info;
- Info = (EFI_FILE_SYSTEM_INFO *) Buffer;
- if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_INFO + 2 || Info->Size > BufferSize) {
- return EFI_BAD_BUFFER_SIZE;
- }
- return FatSetVolumeEntry (Volume, Info->VolumeLabel);
- }
- /**
- Set the volume's label info.
- @param Volume - FAT file system volume.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing the new volume label info.
- @retval EFI_SUCCESS - Set the volume label info successfully.
- @retval EFI_WRITE_PROTECTED - The disk is write protected.
- @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
- @return other - An error occurred when operation the disk.
- **/
- EFI_STATUS
- FatSetVolumeLabelInfo (
- IN FAT_VOLUME *Volume,
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
- {
- EFI_FILE_SYSTEM_VOLUME_LABEL *Info;
- Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *) Buffer;
- if (BufferSize < SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL + 2) {
- return EFI_BAD_BUFFER_SIZE;
- }
- return FatSetVolumeEntry (Volume, Info->VolumeLabel);
- }
- /**
- Set the file info.
- @param Volume - FAT file system volume.
- @param IFile - The instance of the open file.
- @param OFile - The open file.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing the new file info.
- @retval EFI_SUCCESS - Set the file info successfully.
- @retval EFI_ACCESS_DENIED - It is the root directory
- or the directory attribute bit can not change
- or try to change a directory size
- or something else.
- @retval EFI_UNSUPPORTED - The new file size is larger than 4GB.
- @retval EFI_WRITE_PROTECTED - The disk is write protected.
- @retval EFI_BAD_BUFFER_SIZE - The buffer size is error.
- @retval EFI_INVALID_PARAMETER - The time info or attributes info is error.
- @retval EFI_OUT_OF_RESOURCES - Can not allocate new memory.
- @retval EFI_VOLUME_CORRUPTED - The volume is corrupted.
- @return other - An error occurred when operation the disk.
- **/
- EFI_STATUS
- FatSetFileInfo (
- IN FAT_VOLUME *Volume,
- IN FAT_IFILE *IFile,
- IN FAT_OFILE *OFile,
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
- {
- EFI_STATUS Status;
- EFI_FILE_INFO *NewInfo;
- FAT_OFILE *DotOFile;
- FAT_OFILE *Parent;
- CHAR16 NewFileName[EFI_PATH_STRING_LENGTH];
- EFI_TIME ZeroTime;
- FAT_DIRENT *DirEnt;
- FAT_DIRENT *TempDirEnt;
- UINT8 NewAttribute;
- BOOLEAN ReadOnly;
- ZeroMem (&ZeroTime, sizeof (EFI_TIME));
- Parent = OFile->Parent;
- DirEnt = OFile->DirEnt;
- //
- // If this is the root directory, we can't make any updates
- //
- if (Parent == NULL) {
- return EFI_ACCESS_DENIED;
- }
- //
- // Make sure there's a valid input buffer
- //
- NewInfo = Buffer;
- if (BufferSize < SIZE_OF_EFI_FILE_INFO + 2 || NewInfo->Size > BufferSize) {
- return EFI_BAD_BUFFER_SIZE;
- }
- ReadOnly = (BOOLEAN)(IFile->ReadOnly || (DirEnt->Entry.Attributes & EFI_FILE_READ_ONLY));
- //
- // if a zero time is specified, then the original time is preserved
- //
- if (CompareMem (&ZeroTime, &NewInfo->CreateTime, sizeof (EFI_TIME)) != 0) {
- if (!FatIsValidTime (&NewInfo->CreateTime)) {
- return EFI_INVALID_PARAMETER;
- }
- if (!ReadOnly) {
- FatEfiTimeToFatTime (&NewInfo->CreateTime, &DirEnt->Entry.FileCreateTime);
- }
- }
- if (CompareMem (&ZeroTime, &NewInfo->ModificationTime, sizeof (EFI_TIME)) != 0) {
- if (!FatIsValidTime (&NewInfo->ModificationTime)) {
- return EFI_INVALID_PARAMETER;
- }
- if (!ReadOnly) {
- FatEfiTimeToFatTime (&NewInfo->ModificationTime, &DirEnt->Entry.FileModificationTime);
- }
- OFile->PreserveLastModification = TRUE;
- }
- if (NewInfo->Attribute & (~EFI_FILE_VALID_ATTR)) {
- return EFI_INVALID_PARAMETER;
- }
- NewAttribute = (UINT8) NewInfo->Attribute;
- //
- // Can not change the directory attribute bit
- //
- if ((NewAttribute ^ DirEnt->Entry.Attributes) & EFI_FILE_DIRECTORY) {
- return EFI_ACCESS_DENIED;
- }
- //
- // Set the current attributes even if the IFile->ReadOnly is TRUE
- //
- DirEnt->Entry.Attributes = (UINT8) ((DirEnt->Entry.Attributes &~EFI_FILE_VALID_ATTR) | NewAttribute);
- //
- // Open the filename and see if it refers to an existing file
- //
- Status = FatLocateOFile (&Parent, NewInfo->FileName, DirEnt->Entry.Attributes, NewFileName);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- if (*NewFileName != 0) {
- //
- // File was not found. We do not allow rename of the current directory if
- // there are open files below the current directory
- //
- if (!IsListEmpty (&OFile->ChildHead) || Parent == OFile) {
- return EFI_ACCESS_DENIED;
- }
- if (ReadOnly) {
- return EFI_ACCESS_DENIED;
- }
- Status = FatRemoveDirEnt (OFile->Parent, DirEnt);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- //
- // Create new dirent
- //
- Status = FatCreateDirEnt (Parent, NewFileName, DirEnt->Entry.Attributes, &TempDirEnt);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- FatCloneDirEnt (TempDirEnt, DirEnt);
- FatFreeDirEnt (DirEnt);
- DirEnt = TempDirEnt;
- DirEnt->OFile = OFile;
- OFile->DirEnt = DirEnt;
- OFile->Parent = Parent;
- RemoveEntryList (&OFile->ChildLink);
- InsertHeadList (&Parent->ChildHead, &OFile->ChildLink);
- //
- // If this is a directory, synchronize its dot directory entry
- //
- if (OFile->ODir != NULL) {
- //
- // Syncronize its dot entry
- //
- FatResetODirCursor (OFile);
- ASSERT (OFile->Parent != NULL);
- for (DotOFile = OFile; DotOFile != OFile->Parent->Parent; DotOFile = DotOFile->Parent) {
- Status = FatGetNextDirEnt (OFile, &DirEnt);
- if (EFI_ERROR (Status) || DirEnt == NULL || !FatIsDotDirEnt (DirEnt)) {
- return EFI_VOLUME_CORRUPTED;
- }
- FatCloneDirEnt (DirEnt, DotOFile->DirEnt);
- Status = FatStoreDirEnt (OFile, DirEnt);
- if (EFI_ERROR (Status)) {
- return Status;
- }
- }
- }
- //
- // If the file is renamed, we should append the ARCHIVE attribute
- //
- OFile->Archive = TRUE;
- } else if (Parent != OFile) {
- //
- // filename is to a different filename that already exists
- //
- return EFI_ACCESS_DENIED;
- }
- //
- // If the file size has changed, apply it
- //
- if (NewInfo->FileSize != OFile->FileSize) {
- if (OFile->ODir != NULL || ReadOnly) {
- //
- // If this is a directory or the file is read only, we can't change the file size
- //
- return EFI_ACCESS_DENIED;
- }
- if (NewInfo->FileSize > OFile->FileSize) {
- Status = FatExpandOFile (OFile, NewInfo->FileSize);
- } else {
- Status = FatTruncateOFile (OFile, (UINTN) NewInfo->FileSize);
- }
- if (EFI_ERROR (Status)) {
- return Status;
- }
- FatUpdateDirEntClusterSizeInfo (OFile);
- }
- OFile->Dirty = TRUE;
- return FatOFileFlush (OFile);
- }
- /**
- Set or Get the some types info of the file into Buffer.
- @param IsSet - TRUE:The access is set, else is get
- @param FHand - The handle of file
- @param Type - The type of the info
- @param BufferSize - Size of Buffer
- @param Buffer - Buffer containing volume info
- @retval EFI_SUCCESS - Get the info successfully
- @retval EFI_DEVICE_ERROR - Can not find the OFile for the file
- **/
- EFI_STATUS
- FatSetOrGetInfo (
- IN BOOLEAN IsSet,
- IN EFI_FILE_PROTOCOL *FHand,
- IN EFI_GUID *Type,
- IN OUT UINTN *BufferSize,
- IN OUT VOID *Buffer
- )
- {
- FAT_IFILE *IFile;
- FAT_OFILE *OFile;
- FAT_VOLUME *Volume;
- EFI_STATUS Status;
- IFile = IFILE_FROM_FHAND (FHand);
- OFile = IFile->OFile;
- Volume = OFile->Volume;
- Status = OFile->Error;
- if (Status == EFI_NOT_FOUND) {
- return EFI_DEVICE_ERROR;
- }
- FatWaitNonblockingTask (IFile);
- FatAcquireLock ();
- //
- // Verify the file handle isn't in an error state
- //
- if (!EFI_ERROR (Status)) {
- //
- // Get the proper information based on the request
- //
- Status = EFI_UNSUPPORTED;
- if (IsSet) {
- if (CompareGuid (Type, &gEfiFileInfoGuid)) {
- Status = Volume->ReadOnly ? EFI_WRITE_PROTECTED : FatSetFileInfo (Volume, IFile, OFile, *BufferSize, Buffer);
- }
- if (CompareGuid (Type, &gEfiFileSystemInfoGuid)) {
- Status = Volume->ReadOnly ? EFI_WRITE_PROTECTED : FatSetVolumeInfo (Volume, *BufferSize, Buffer);
- }
- if (CompareGuid (Type, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
- Status = Volume->ReadOnly ? EFI_WRITE_PROTECTED : FatSetVolumeLabelInfo (Volume, *BufferSize, Buffer);
- }
- } else {
- if (CompareGuid (Type, &gEfiFileInfoGuid)) {
- Status = FatGetFileInfo (OFile, BufferSize, Buffer);
- }
- if (CompareGuid (Type, &gEfiFileSystemInfoGuid)) {
- Status = FatGetVolumeInfo (Volume, BufferSize, Buffer);
- }
- if (CompareGuid (Type, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
- Status = FatGetVolumeLabelInfo (Volume, BufferSize, Buffer);
- }
- }
- }
- Status = FatCleanupVolume (Volume, NULL, Status, NULL);
- FatReleaseLock ();
- return Status;
- }
- /**
- Get the some types info of the file into Buffer.
- @param FHand - The handle of file.
- @param Type - The type of the info.
- @param BufferSize - Size of Buffer.
- @param Buffer - Buffer containing volume info.
- @retval EFI_SUCCESS - Get the info successfully.
- @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
- **/
- EFI_STATUS
- EFIAPI
- FatGetInfo (
- IN EFI_FILE_PROTOCOL *FHand,
- IN EFI_GUID *Type,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
- {
- return FatSetOrGetInfo (FALSE, FHand, Type, BufferSize, Buffer);
- }
- /**
- Set the some types info of the file into Buffer.
- @param FHand - The handle of file.
- @param Type - The type of the info.
- @param BufferSize - Size of Buffer
- @param Buffer - Buffer containing volume info.
- @retval EFI_SUCCESS - Set the info successfully.
- @retval EFI_DEVICE_ERROR - Can not find the OFile for the file.
- **/
- EFI_STATUS
- EFIAPI
- FatSetInfo (
- IN EFI_FILE_PROTOCOL *FHand,
- IN EFI_GUID *Type,
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
- {
- return FatSetOrGetInfo (TRUE, FHand, Type, &BufferSize, Buffer);
- }
|