+++ /dev/null
-/** @file\r
-*\r
-* Copyright (c) 2012-2014, ARM Limited. All rights reserved.\r
-*\r
-* This program and the accompanying materials\r
-* are licensed and made available under the terms and conditions of the BSD License\r
-* which accompanies this distribution. The full text of the license may be found at\r
-* http://opensource.org/licenses/bsd-license.php\r
-*\r
-* THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
-* WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
-*\r
-**/\r
-\r
-#include "BootMonFsInternal.h"\r
-\r
-EFIAPI\r
-EFI_STATUS\r
-OpenBootMonFsOpenVolume (\r
- IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
- OUT EFI_FILE_PROTOCOL **Root\r
- )\r
-{\r
- BOOTMON_FS_INSTANCE *Instance;\r
-\r
- Instance = BOOTMON_FS_FROM_FS_THIS (This);\r
- if (Instance == NULL) {\r
- return EFI_DEVICE_ERROR;\r
- }\r
-\r
- Instance->RootFile->Info->Attribute = EFI_FILE_READ_ONLY | EFI_FILE_DIRECTORY;\r
-\r
- *Root = &Instance->RootFile->File;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-UINT32\r
-BootMonFsGetImageLength (\r
- IN BOOTMON_FS_FILE *File\r
- )\r
-{\r
- UINT32 Index;\r
- UINT32 FileSize;\r
- LIST_ENTRY *RegionToFlushLink;\r
- BOOTMON_FS_FILE_REGION *Region;\r
-\r
- FileSize = 0;\r
-\r
- // Look at all Flash areas to determine file size\r
- for (Index = 0; Index < HW_IMAGE_DESCRIPTION_REGION_MAX; Index++) {\r
- FileSize += File->HwDescription.Region[Index].Size;\r
- }\r
-\r
- // Add the regions that have not been flushed yet\r
- for (RegionToFlushLink = GetFirstNode (&File->RegionToFlushLink);\r
- !IsNull (&File->RegionToFlushLink, RegionToFlushLink);\r
- RegionToFlushLink = GetNextNode (&File->RegionToFlushLink, RegionToFlushLink)\r
- )\r
- {\r
- Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;\r
- if (Region->Offset + Region->Size > FileSize) {\r
- FileSize += Region->Offset + Region->Size;\r
- }\r
- }\r
-\r
- return FileSize;\r
-}\r
-\r
-UINTN\r
-BootMonFsGetPhysicalSize (\r
- IN BOOTMON_FS_FILE* File\r
- )\r
-{\r
- // Return 0 for files that haven't yet been flushed to media\r
- if (File->HwDescription.RegionCount == 0) {\r
- return 0;\r
- }\r
-\r
- return ((File->HwDescription.BlockEnd - File->HwDescription.BlockStart) + 1 )\r
- * File->Instance->Media->BlockSize;\r
-}\r
-\r
-EFIAPI\r
-EFI_STATUS\r
-BootMonFsSetDirPosition (\r
- IN EFI_FILE_PROTOCOL *This,\r
- IN UINT64 Position\r
- )\r
-{\r
- BOOTMON_FS_FILE *File;\r
-\r
- File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
- if (File == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- // UEFI Spec section 12.5:\r
- // "The seek request for nonzero is not valid on open directories."\r
- if (Position != 0) {\r
- return EFI_UNSUPPORTED;\r
- }\r
- File->Position = Position;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFI_STATUS\r
-BootMonFsOpenDirectory (\r
- OUT EFI_FILE_PROTOCOL **NewHandle,\r
- IN CHAR16 *FileName,\r
- IN BOOTMON_FS_INSTANCE *Volume\r
- )\r
-{\r
- ASSERT(0);\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetFileSystemVolumeLabelInfo (\r
- IN BOOTMON_FS_INSTANCE *Instance,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- UINTN Size;\r
- EFI_FILE_SYSTEM_VOLUME_LABEL *Label;\r
- EFI_STATUS Status;\r
-\r
- Label = Buffer;\r
-\r
- // Value returned by StrSize includes null terminator.\r
- Size = SIZE_OF_EFI_FILE_SYSTEM_VOLUME_LABEL\r
- + StrSize (Instance->FsInfo.VolumeLabel);\r
-\r
- if (*BufferSize >= Size) {\r
- CopyMem (&Label->VolumeLabel, &Instance->FsInfo.VolumeLabel, Size);\r
- Status = EFI_SUCCESS;\r
- } else {\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- }\r
- *BufferSize = Size;\r
- return Status;\r
-}\r
-\r
-// Helper function that calculates a rough "free space" by:\r
-// - Taking the media size\r
-// - Subtracting the sum of all file sizes\r
-// - Subtracting the block size times the number of files\r
-// (To account for the blocks containing the HW_IMAGE_INFO\r
-STATIC\r
-UINT64\r
-ComputeFreeSpace (\r
- IN BOOTMON_FS_INSTANCE *Instance\r
- )\r
-{\r
- LIST_ENTRY *FileLink;\r
- UINT64 FileSizeSum;\r
- UINT64 MediaSize;\r
- UINTN NumFiles;\r
- EFI_BLOCK_IO_MEDIA *Media;\r
- BOOTMON_FS_FILE *File;\r
-\r
- Media = Instance->BlockIo->Media;\r
- MediaSize = Media->BlockSize * (Media->LastBlock + 1);\r
-\r
- NumFiles = 0;\r
- FileSizeSum = 0;\r
- for (FileLink = GetFirstNode (&Instance->RootFile->Link);\r
- !IsNull (&Instance->RootFile->Link, FileLink);\r
- FileLink = GetNextNode (&Instance->RootFile->Link, FileLink)\r
- )\r
- {\r
- File = BOOTMON_FS_FILE_FROM_LINK_THIS (FileLink);\r
- FileSizeSum += BootMonFsGetImageLength (File);\r
-\r
- NumFiles++;\r
- }\r
-\r
- return MediaSize - (FileSizeSum + (Media->BlockSize + NumFiles));\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetFilesystemInfo (\r
- IN BOOTMON_FS_INSTANCE *Instance,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
-\r
- if (*BufferSize >= Instance->FsInfo.Size) {\r
- Instance->FsInfo.FreeSpace = ComputeFreeSpace (Instance);\r
- CopyMem (Buffer, &Instance->FsInfo, Instance->FsInfo.Size);\r
- Status = EFI_SUCCESS;\r
- } else {\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- *BufferSize = Instance->FsInfo.Size;\r
- return Status;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetFileInfo (\r
- IN BOOTMON_FS_INSTANCE *Instance,\r
- IN BOOTMON_FS_FILE *File,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_FILE_INFO *Info;\r
- UINTN ResultSize;\r
-\r
- ResultSize = SIZE_OF_EFI_FILE_INFO + StrSize (File->Info->FileName);\r
-\r
- if (*BufferSize < ResultSize) {\r
- *BufferSize = ResultSize;\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- Info = Buffer;\r
-\r
- CopyMem (Info, File->Info, ResultSize);\r
- // Size of the information\r
- Info->Size = ResultSize;\r
-\r
- *BufferSize = ResultSize;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-STATIC\r
-EFI_STATUS\r
-GetBootMonFsFileInfo (\r
- IN BOOTMON_FS_INSTANCE *Instance,\r
- IN BOOTMON_FS_FILE *File,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOTMON_FS_FILE_INFO *Info;\r
- UINTN ResultSize;\r
- UINTN Index;\r
-\r
- if (File == Instance->RootFile) {\r
- Status = EFI_UNSUPPORTED;\r
- } else {\r
- ResultSize = SIZE_OF_BOOTMON_FS_FILE_INFO;\r
-\r
- if (*BufferSize < ResultSize) {\r
- *BufferSize = ResultSize;\r
- Status = EFI_BUFFER_TOO_SMALL;\r
- } else {\r
- Info = Buffer;\r
-\r
- // Zero out the structure\r
- ZeroMem (Info, ResultSize);\r
-\r
- // Fill in the structure\r
- Info->Size = ResultSize;\r
-\r
- Info->EntryPoint = File->HwDescription.EntryPoint;\r
- Info->RegionCount = File->HwDescription.RegionCount;\r
- for (Index = 0; Index < File->HwDescription.RegionCount; Index++) {\r
- Info->Region[Index].LoadAddress = File->HwDescription.Region[Index].LoadAddress;\r
- Info->Region[Index].Size = File->HwDescription.Region[Index].Size;\r
- Info->Region[Index].Offset = File->HwDescription.Region[Index].Offset;\r
- Info->Region[Index].Checksum = File->HwDescription.Region[Index].Checksum;\r
- }\r
- *BufferSize = ResultSize;\r
- Status = EFI_SUCCESS;\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Set the name of a file.\r
-\r
- This is a helper function for SetFileInfo().\r
-\r
- @param[in] Instance A pointer to the description of the volume\r
- the file belongs to.\r
- @param[in] File A pointer to the description of the file.\r
- @param[in] FileName A pointer to the new name of the file.\r
-\r
- @retval EFI_SUCCESS The name was set.\r
- @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file\r
- to a file that is already present.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-SetFileName (\r
- IN BOOTMON_FS_INSTANCE *Instance,\r
- IN BOOTMON_FS_FILE *File,\r
- IN CONST CHAR16 *FileName\r
- )\r
-{\r
- CHAR8 AsciiFileName[MAX_NAME_LENGTH];\r
- BOOTMON_FS_FILE *SameFile;\r
-\r
- // If the file path start with a \ strip it. The EFI Shell may\r
- // insert a \ in front of the file name.\r
- if (FileName[0] == L'\\') {\r
- FileName++;\r
- }\r
-\r
- UnicodeStrToAsciiStrS (FileName, AsciiFileName, MAX_NAME_LENGTH);\r
-\r
- if (BootMonGetFileFromAsciiFileName (\r
- File->Instance,\r
- AsciiFileName,\r
- &SameFile\r
- ) != EFI_NOT_FOUND) {\r
- // A file with that name already exists.\r
- return EFI_ACCESS_DENIED;\r
- } else {\r
- // OK, change the filename.\r
- AsciiStrToUnicodeStrS (AsciiFileName, File->Info->FileName,\r
- (File->Info->Size - SIZE_OF_EFI_FILE_INFO) / sizeof (CHAR16));\r
- return EFI_SUCCESS;\r
- }\r
-}\r
-\r
-/**\r
- Set the size of a file.\r
-\r
- This is a helper function for SetFileInfo().\r
-\r
- @param[in] Instance A pointer to the description of the volume\r
- the file belongs to.\r
- @param[in] File A pointer to the description of the file.\r
- @param[in] NewSize The requested new size for the file.\r
-\r
- @retval EFI_SUCCESS The size was set.\r
- @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request failed.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-SetFileSize (\r
- IN BOOTMON_FS_INSTANCE *Instance,\r
- IN BOOTMON_FS_FILE *BootMonFsFile,\r
- IN UINTN NewSize\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINT32 OldSize;\r
- LIST_ENTRY *RegionToFlushLink;\r
- LIST_ENTRY *NextRegionToFlushLink;\r
- BOOTMON_FS_FILE_REGION *Region;\r
- EFI_FILE_PROTOCOL *File;\r
- CHAR8 *Buffer;\r
- UINTN BufferSize;\r
- UINT64 StoredPosition;\r
-\r
- OldSize = BootMonFsFile->Info->FileSize;\r
-\r
- //\r
- // In case of file truncation, force the regions waiting for writing to\r
- // not overflow the new size of the file.\r
- //\r
- if (NewSize < OldSize) {\r
- for (RegionToFlushLink = GetFirstNode (&BootMonFsFile->RegionToFlushLink);\r
- !IsNull (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);\r
- )\r
- {\r
- NextRegionToFlushLink = GetNextNode (&BootMonFsFile->RegionToFlushLink, RegionToFlushLink);\r
- Region = (BOOTMON_FS_FILE_REGION*)RegionToFlushLink;\r
- if (Region->Offset > NewSize) {\r
- RemoveEntryList (RegionToFlushLink);\r
- FreePool (Region->Buffer);\r
- FreePool (Region);\r
- } else {\r
- Region->Size = MIN (Region->Size, NewSize - Region->Offset);\r
- }\r
- RegionToFlushLink = NextRegionToFlushLink;\r
- }\r
-\r
- } else if (NewSize > OldSize) {\r
- // Increasing a file's size is potentially complicated as it may require\r
- // moving the image description on media. The simplest way to do it is to\r
- // seek past the end of the file (which is valid in UEFI) and perform a\r
- // Write.\r
- File = &BootMonFsFile->File;\r
-\r
- // Save position\r
- Status = File->GetPosition (File, &StoredPosition);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- // Set position at the end of the file\r
- Status = File->SetPosition (File, OldSize);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- BufferSize = NewSize - OldSize;\r
- Buffer = AllocateZeroPool (BufferSize);\r
- if (Buffer == NULL) {\r
- return EFI_OUT_OF_RESOURCES;\r
- }\r
-\r
- Status = File->Write (File, &BufferSize, Buffer);\r
- FreePool (Buffer);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- // Restore saved position\r
- Status = File->SetPosition (File, StoredPosition);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- BootMonFsFile->Info->FileSize = NewSize;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- Set information about a file.\r
-\r
- @param[in] Instance A pointer to the description of the volume\r
- the file belongs to.\r
- @param[in] File A pointer to the description of the file.\r
- @param[in] Info A pointer to the file information to write.\r
-\r
- @retval EFI_SUCCESS The information was set.\r
- @retval EFI_ACCESS_DENIED An attempt is being made to change the\r
- EFI_FILE_DIRECTORY Attribute.\r
- @retval EFI_ACCESS_DENIED The file was opened in read-only mode and an\r
- attempt is being made to modify a field other\r
- than Attribute.\r
- @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file\r
- to a file that is already present.\r
- @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only\r
- attribute.\r
- @retval EFI_OUT_OF_RESOURCES An allocation needed to process the request\r
- failed.\r
-\r
-**/\r
-STATIC\r
-EFI_STATUS\r
-SetFileInfo (\r
- IN BOOTMON_FS_INSTANCE *Instance,\r
- IN BOOTMON_FS_FILE *File,\r
- IN EFI_FILE_INFO *Info\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOLEAN FileSizeIsDifferent;\r
- BOOLEAN FileNameIsDifferent;\r
- BOOLEAN TimeIsDifferent;\r
-\r
- //\r
- // A directory can not be changed to a file and a file can\r
- // not be changed to a directory.\r
- //\r
- if ((Info->Attribute & EFI_FILE_DIRECTORY) !=\r
- (File->Info->Attribute & EFI_FILE_DIRECTORY) ) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
-\r
- FileSizeIsDifferent = (Info->FileSize != File->Info->FileSize);\r
- FileNameIsDifferent = (StrnCmp (\r
- Info->FileName,\r
- File->Info->FileName,\r
- MAX_NAME_LENGTH - 1\r
- ) != 0);\r
- //\r
- // Check if the CreateTime, LastAccess or ModificationTime\r
- // have been changed. The file system does not support file\r
- // timestamps thus the three times in "File->Info" are\r
- // always equal to zero. The following comparison actually\r
- // checks if all three times are still equal to 0 or not.\r
- //\r
- TimeIsDifferent = CompareMem (\r
- &Info->CreateTime,\r
- &File->Info->CreateTime,\r
- 3 * sizeof (EFI_TIME)\r
- ) != 0;\r
-\r
- //\r
- // For a file opened in read-only mode, only the Attribute field can be\r
- // modified. The root directory open mode is forced to read-only at opening\r
- // thus the following test protects the root directory to be somehow modified.\r
- //\r
- if (File->OpenMode == EFI_FILE_MODE_READ) {\r
- if (FileSizeIsDifferent || FileNameIsDifferent || TimeIsDifferent) {\r
- return EFI_ACCESS_DENIED;\r
- }\r
- }\r
-\r
- if (TimeIsDifferent) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
-\r
- if (FileSizeIsDifferent) {\r
- Status = SetFileSize (Instance, File, Info->FileSize);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- //\r
- // Note down in RAM the Attribute field but we can not\r
- // ask to store it in flash for the time being.\r
- //\r
- File->Info->Attribute = Info->Attribute;\r
-\r
- if (FileNameIsDifferent) {\r
- Status = SetFileName (Instance, File, Info->FileName);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFIAPI\r
-EFI_STATUS\r
-BootMonFsGetInfo (\r
- IN EFI_FILE_PROTOCOL *This,\r
- IN EFI_GUID *InformationType,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- EFI_STATUS Status;\r
- BOOTMON_FS_FILE *File;\r
- BOOTMON_FS_INSTANCE *Instance;\r
-\r
- if ((This == NULL) ||\r
- (InformationType == NULL) ||\r
- (BufferSize == NULL) ||\r
- ((Buffer == NULL) && (*BufferSize > 0)) ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
- if (File->Info == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- Instance = File->Instance;\r
-\r
- // If the instance has not been initialized yet then do it ...\r
- if (!Instance->Initialized) {\r
- Status = BootMonFsInitialize (Instance);\r
- } else {\r
- Status = EFI_SUCCESS;\r
- }\r
-\r
- if (!EFI_ERROR (Status)) {\r
- if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)\r
- != 0) {\r
- Status = GetFileSystemVolumeLabelInfo (Instance, BufferSize, Buffer);\r
- } else if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) != 0) {\r
- Status = GetFilesystemInfo (Instance, BufferSize, Buffer);\r
- } else if (CompareGuid (InformationType, &gEfiFileInfoGuid) != 0) {\r
- Status = GetFileInfo (Instance, File, BufferSize, Buffer);\r
- } else if (CompareGuid (InformationType, &gArmBootMonFsFileInfoGuid) != 0) {\r
- Status = GetBootMonFsFileInfo (Instance, File, BufferSize, Buffer);\r
- } else {\r
- Status = EFI_UNSUPPORTED;\r
- }\r
- }\r
-\r
- return Status;\r
-}\r
-\r
-/**\r
- Set information about a file or a volume.\r
-\r
- @param[in] This A pointer to the EFI_FILE_PROTOCOL instance that\r
- is the file handle the information is for.\r
- @param[in] InformationType The type identifier for the information being set :\r
- EFI_FILE_INFO_ID or EFI_FILE_SYSTEM_INFO_ID or\r
- EFI_FILE_SYSTEM_VOLUME_LABEL_ID\r
- @param[in] BufferSize The size, in bytes, of Buffer.\r
- @param[in] Buffer A pointer to the data buffer to write. The type of the\r
- data inside the buffer is indicated by InformationType.\r
-\r
- @retval EFI_SUCCESS The information was set.\r
- @retval EFI_UNSUPPORTED The InformationType is not known.\r
- @retval EFI_DEVICE_ERROR The last issued semi-hosting operation failed.\r
- @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file\r
- to a file that is already present.\r
- @retval EFI_ACCESS_DENIED An attempt is being made to change the\r
- EFI_FILE_DIRECTORY Attribute.\r
- @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and\r
- the file was opened in read-only mode and an\r
- attempt is being made to modify a field other\r
- than Attribute.\r
- @retval EFI_WRITE_PROTECTED An attempt is being made to modify a read-only\r
- attribute.\r
- @retval EFI_BAD_BUFFER_SIZE The size of the buffer is lower than that indicated by\r
- the data inside the buffer.\r
- @retval EFI_OUT_OF_RESOURCES A allocation needed to process the request failed.\r
- @retval EFI_INVALID_PARAMETER At least one of the parameters is invalid.\r
-\r
-**/\r
-EFIAPI\r
-EFI_STATUS\r
-BootMonFsSetInfo (\r
- IN EFI_FILE_PROTOCOL *This,\r
- IN EFI_GUID *InformationType,\r
- IN UINTN BufferSize,\r
- IN VOID *Buffer\r
- )\r
-{\r
- BOOTMON_FS_FILE *File;\r
- EFI_FILE_INFO *Info;\r
- EFI_FILE_SYSTEM_INFO *SystemInfo;\r
-\r
- if ((This == NULL) ||\r
- (InformationType == NULL) ||\r
- (Buffer == NULL) ) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- File = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
- if (File->Info == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
- Info = Buffer;\r
- if (Info->Size < (SIZE_OF_EFI_FILE_INFO + StrSize (Info->FileName))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (BufferSize < Info->Size) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
- return (SetFileInfo (File->Instance, File, Info));\r
- }\r
-\r
- //\r
- // The only writable field in the other two information types\r
- // (i.e. EFI_FILE_SYSTEM_INFO and EFI_FILE_SYSTEM_VOLUME_LABEL) is the\r
- // filesystem volume label. This can be retrieved with GetInfo, but it is\r
- // hard-coded into this driver, not stored on media.\r
- //\r
-\r
- if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
- SystemInfo = Buffer;\r
- if (SystemInfo->Size <\r
- (SIZE_OF_EFI_FILE_SYSTEM_INFO + StrSize (SystemInfo->VolumeLabel))) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- if (BufferSize < SystemInfo->Size) {\r
- return EFI_BAD_BUFFER_SIZE;\r
- }\r
- return EFI_WRITE_PROTECTED;\r
- }\r
-\r
- if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
- return EFI_WRITE_PROTECTED;\r
- }\r
-\r
- return EFI_UNSUPPORTED;\r
-}\r
-\r
-EFIAPI\r
-EFI_STATUS\r
-BootMonFsReadDirectory (\r
- IN EFI_FILE_PROTOCOL *This,\r
- IN OUT UINTN *BufferSize,\r
- OUT VOID *Buffer\r
- )\r
-{\r
- BOOTMON_FS_INSTANCE *Instance;\r
- BOOTMON_FS_FILE *RootFile;\r
- BOOTMON_FS_FILE *File;\r
- EFI_FILE_INFO *Info;\r
- UINTN NameSize;\r
- UINTN ResultSize;\r
- EFI_STATUS Status;\r
- UINTN Index;\r
-\r
- RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
- if (RootFile == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- Instance = RootFile->Instance;\r
- Status = BootMonGetFileFromPosition (Instance, RootFile->Position, &File);\r
- if (EFI_ERROR (Status)) {\r
- // No more file\r
- *BufferSize = 0;\r
- return EFI_SUCCESS;\r
- }\r
-\r
- NameSize = AsciiStrLen (File->HwDescription.Footer.Filename) + 1;\r
- ResultSize = SIZE_OF_EFI_FILE_INFO + (NameSize * sizeof (CHAR16));\r
- if (*BufferSize < ResultSize) {\r
- *BufferSize = ResultSize;\r
- return EFI_BUFFER_TOO_SMALL;\r
- }\r
-\r
- // Zero out the structure\r
- Info = Buffer;\r
- ZeroMem (Info, ResultSize);\r
-\r
- // Fill in the structure\r
- Info->Size = ResultSize;\r
- Info->FileSize = BootMonFsGetImageLength (File);\r
- Info->PhysicalSize = BootMonFsGetPhysicalSize (File);\r
- for (Index = 0; Index < NameSize; Index++) {\r
- Info->FileName[Index] = File->HwDescription.Footer.Filename[Index];\r
- }\r
-\r
- *BufferSize = ResultSize;\r
- RootFile->Position++;\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-EFIAPI\r
-EFI_STATUS\r
-BootMonFsFlushDirectory (\r
- IN EFI_FILE_PROTOCOL *This\r
- )\r
-{\r
- BOOTMON_FS_FILE *RootFile;\r
- LIST_ENTRY *ListFiles;\r
- LIST_ENTRY *Link;\r
- BOOTMON_FS_FILE *File;\r
-\r
- RootFile = BOOTMON_FS_FILE_FROM_FILE_THIS (This);\r
- if (RootFile == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- ListFiles = &RootFile->Link;\r
-\r
- if (IsListEmpty (ListFiles)) {\r
- return EFI_SUCCESS;\r
- }\r
-\r
- //\r
- // Flush all the files that need to be flushed\r
- //\r
-\r
- // Go through all the list of files to flush them\r
- for (Link = GetFirstNode (ListFiles);\r
- !IsNull (ListFiles, Link);\r
- Link = GetNextNode (ListFiles, Link)\r
- )\r
- {\r
- File = BOOTMON_FS_FILE_FROM_LINK_THIS (Link);\r
- File->File.Flush (&File->File);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r