| /** @file | |
| This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware | |
| volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL. | |
| It will expose a single directory, containing one file for each file in the firmware | |
| volume. If a file has a UI section, its contents will be used as a filename. | |
| Otherwise, a string representation of the GUID will be used. | |
| Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION) | |
| will have ".efi" added to their filename. | |
| Its primary intended use is to be able to start EFI applications embedded in FVs | |
| from the UEFI shell. It is entirely read-only. | |
| Copyright (c) 2014, ARM Limited. All rights reserved. | |
| Copyright (c) 2014 - 2016, Intel Corporation. All rights reserved.<BR> | |
| This program and the accompanying materials | |
| are licensed and made available under the terms and conditions of the BSD License | |
| which accompanies this distribution. The full text of the license may be found at | |
| http://opensource.org/licenses/bsd-license.php | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. | |
| **/ | |
| #include "FvSimpleFileSystemInternal.h" | |
| EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation = NULL; | |
| // | |
| // A Guid string is 32 hex characters with 4 hyphens and a NULL-terminated char: 37 characters total | |
| // | |
| #define GUID_STRING_SIZE (37 * sizeof (CHAR16)) | |
| #define FVFS_VOLUME_LABEL_PREFIX L"Firmware Volume: " | |
| #define FVFS_VOLUME_LABEL_SIZE (sizeof (FVFS_VOLUME_LABEL_PREFIX) + GUID_STRING_SIZE - sizeof (CHAR16)) | |
| #define FVFS_FALLBACK_VOLUME_LABEL L"Firmware Volume" | |
| // | |
| // Template for EFI_SIMPLE_FILE_SYSTEM_PROTOCOL data structure. | |
| // | |
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mSimpleFsTemplate = { | |
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION, | |
| FvSimpleFileSystemOpenVolume | |
| }; | |
| // | |
| // Template for EFI_DRIVER_BINDING_PROTOCOL data structure. | |
| // | |
| EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = { | |
| FvSimpleFileSystemDriverSupported, | |
| FvSimpleFileSystemDriverStart, | |
| FvSimpleFileSystemDriverStop, | |
| 0, | |
| NULL, | |
| NULL | |
| }; | |
| /** | |
| Open the root directory on a volume. | |
| @param This A pointer to the volume to open the root directory. | |
| @param RootFile A pointer to the location to return the opened file handle for the | |
| root directory. | |
| @retval EFI_SUCCESS The device was opened. | |
| @retval EFI_UNSUPPORTED This volume does not support the requested file system type. | |
| @retval EFI_NO_MEDIA The device has no medium. | |
| @retval EFI_DEVICE_ERROR The device reported an error. | |
| @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. | |
| @retval EFI_ACCESS_DENIED The service denied access to the file. | |
| @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources. | |
| @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no | |
| longer supported. Any existing file handles for this volume are | |
| no longer valid. To access the files on the new medium, the | |
| volume must be reopened with OpenVolume(). | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| FvSimpleFileSystemOpenVolume ( | |
| IN EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This, | |
| OUT EFI_FILE_PROTOCOL **RootFile | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| FV_FILESYSTEM_FILE *Root; | |
| CHAR16 *UiSection; | |
| EFI_GUID NameGuid; | |
| EFI_FV_FILE_ATTRIBUTES Attributes; | |
| UINT32 Authentication; | |
| UINTN Key; | |
| EFI_FV_FILETYPE FileType; | |
| UINTN Size; | |
| FV_FILESYSTEM_INSTANCE *Instance; | |
| FV_FILESYSTEM_FILE_INFO *FvFileInfo; | |
| EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; | |
| CHAR16 *Name; | |
| UINTN NameLen; | |
| UINTN NumChars; | |
| UINTN DestMax; | |
| Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This); | |
| Status = EFI_SUCCESS; | |
| if (Instance->Root == NULL) { | |
| // | |
| // Allocate file structure for root file | |
| // | |
| Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE)); | |
| if (Root == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| Instance->Root = Root; | |
| Root->Instance = Instance; | |
| Root->Signature = FVFS_FILE_SIGNATURE; | |
| CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate)); | |
| Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO)); | |
| if (Root->FvFileInfo == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| Root->FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO); | |
| Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY; | |
| // | |
| // Populate the instance's list of files. We consider anything a file that | |
| // has a UI_SECTION, which we consider to be its filename. | |
| // | |
| FvProtocol = Instance->FvProtocol; | |
| // | |
| // Allocate Key | |
| // | |
| Key = 0; | |
| do { | |
| FileType = EFI_FV_FILETYPE_ALL; | |
| Status = FvProtocol->GetNextFile ( | |
| FvProtocol, | |
| &Key, | |
| &FileType, | |
| &NameGuid, | |
| &Attributes, | |
| &Size | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| ASSERT (Status == EFI_NOT_FOUND); | |
| break; | |
| } | |
| // | |
| // Get a file's name: If it has a UI section, use that, otherwise use | |
| // its NameGuid. | |
| // | |
| UiSection = NULL; | |
| Status = FvProtocol->ReadSection ( | |
| FvProtocol, | |
| &NameGuid, | |
| EFI_SECTION_USER_INTERFACE, | |
| 0, | |
| (VOID **)&UiSection, | |
| &Size, | |
| &Authentication | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| Name = UiSection; | |
| } else { | |
| Name = AllocateZeroPool (GUID_STRING_SIZE); | |
| if (Name == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid); | |
| ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE); | |
| } | |
| // | |
| // Found a file. | |
| // Allocate a file structure and populate it. | |
| // | |
| NameLen = StrSize (Name); | |
| if (FV_FILETYPE_IS_EXECUTABLE (FileType)) { | |
| NameLen += StrSize (L".efi") - sizeof (CHAR16); | |
| } | |
| FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16)); | |
| if (FvFileInfo == NULL) { | |
| return EFI_OUT_OF_RESOURCES; | |
| } | |
| FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE; | |
| InitializeListHead (&FvFileInfo->Link); | |
| CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID)); | |
| FvFileInfo->Type = FileType; | |
| // | |
| // Add ".efi" to filenames of drivers and applications. | |
| // | |
| DestMax = NameLen / sizeof (CHAR16); | |
| Status = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name)); | |
| ASSERT_EFI_ERROR (Status); | |
| if (FV_FILETYPE_IS_EXECUTABLE (FileType)) { | |
| Status = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi")); | |
| ASSERT_EFI_ERROR (Status); | |
| } | |
| FvFileInfo->FileInfo.Size = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16); | |
| Status = FvFsGetFileSize (FvProtocol, FvFileInfo); | |
| ASSERT_EFI_ERROR (Status); | |
| FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize; | |
| FvFileInfo->FileInfo.Attribute = EFI_FILE_READ_ONLY; | |
| InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link); | |
| FreePool (Name); | |
| } while (TRUE); | |
| if (Status == EFI_NOT_FOUND) { | |
| Status = EFI_SUCCESS; | |
| } | |
| } | |
| Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance); | |
| *RootFile = &Instance->Root->FileProtocol; | |
| return Status; | |
| } | |
| /** | |
| Worker function to initialize Unicode Collation support. | |
| It tries to locate Unicode Collation (2) protocol and matches it with current | |
| platform language code. | |
| @param AgentHandle The handle used to open Unicode Collation (2) protocol. | |
| @param ProtocolGuid The pointer to Unicode Collation (2) protocol GUID. | |
| @param VariableName The name of the RFC 4646 or ISO 639-2 language variable. | |
| @param DefaultLanguage The default language in case the RFC 4646 or ISO 639-2 language is absent. | |
| @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located. | |
| @retval Others The Unicode Collation (2) protocol has not been located. | |
| **/ | |
| EFI_STATUS | |
| InitializeUnicodeCollationSupportWorker ( | |
| IN EFI_HANDLE AgentHandle, | |
| IN EFI_GUID *ProtocolGuid, | |
| IN CONST CHAR16 *VariableName, | |
| IN CONST CHAR8 *DefaultLanguage | |
| ) | |
| { | |
| EFI_STATUS ReturnStatus; | |
| EFI_STATUS Status; | |
| UINTN NumHandles; | |
| UINTN Index; | |
| EFI_HANDLE *Handles; | |
| EFI_UNICODE_COLLATION_PROTOCOL *Uci; | |
| BOOLEAN Iso639Language; | |
| CHAR8 *Language; | |
| CHAR8 *BestLanguage; | |
| Status = gBS->LocateHandleBuffer ( | |
| ByProtocol, | |
| ProtocolGuid, | |
| NULL, | |
| &NumHandles, | |
| &Handles | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Iso639Language = (BOOLEAN) (ProtocolGuid == &gEfiUnicodeCollationProtocolGuid); | |
| GetEfiGlobalVariable2 (VariableName, (VOID**) &Language, NULL); | |
| ReturnStatus = EFI_UNSUPPORTED; | |
| for (Index = 0; Index < NumHandles; Index++) { | |
| // | |
| // Open Unicode Collation Protocol | |
| // | |
| Status = gBS->OpenProtocol ( | |
| Handles[Index], | |
| ProtocolGuid, | |
| (VOID **) &Uci, | |
| AgentHandle, | |
| NULL, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| continue; | |
| } | |
| // | |
| // Find the best matching matching language from the supported languages | |
| // of Unicode Collation (2) protocol. | |
| // | |
| BestLanguage = GetBestLanguage ( | |
| Uci->SupportedLanguages, | |
| Iso639Language, | |
| (Language == NULL) ? "" : Language, | |
| DefaultLanguage, | |
| NULL | |
| ); | |
| if (BestLanguage != NULL) { | |
| FreePool (BestLanguage); | |
| mUnicodeCollation = Uci; | |
| ReturnStatus = EFI_SUCCESS; | |
| break; | |
| } | |
| } | |
| if (Language != NULL) { | |
| FreePool (Language); | |
| } | |
| FreePool (Handles); | |
| return ReturnStatus; | |
| } | |
| /** | |
| Initialize Unicode Collation support. | |
| It tries to locate Unicode Collation 2 protocol and matches it with current | |
| platform language code. If for any reason the first attempt fails, it then tries to | |
| use Unicode Collation Protocol. | |
| @param AgentHandle The handle used to open Unicode Collation (2) protocol. | |
| @retval EFI_SUCCESS The Unicode Collation (2) protocol has been successfully located. | |
| @retval Others The Unicode Collation (2) protocol has not been located. | |
| **/ | |
| EFI_STATUS | |
| InitializeUnicodeCollationSupport ( | |
| IN EFI_HANDLE AgentHandle | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| Status = EFI_UNSUPPORTED; | |
| // | |
| // First try to use RFC 4646 Unicode Collation 2 Protocol. | |
| // | |
| Status = InitializeUnicodeCollationSupportWorker ( | |
| AgentHandle, | |
| &gEfiUnicodeCollation2ProtocolGuid, | |
| L"PlatformLang", | |
| (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang) | |
| ); | |
| // | |
| // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back | |
| // on the ISO 639-2 Unicode Collation Protocol. | |
| // | |
| if (EFI_ERROR (Status)) { | |
| Status = InitializeUnicodeCollationSupportWorker ( | |
| AgentHandle, | |
| &gEfiUnicodeCollationProtocolGuid, | |
| L"Lang", | |
| (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang) | |
| ); | |
| } | |
| return Status; | |
| } | |
| /** | |
| Test to see if this driver supports ControllerHandle. | |
| @param DriverBinding Protocol instance pointer. | |
| @param ControllerHandle Handle of device to test | |
| @param RemainingDevicePath Optional parameter use to pick a specific child | |
| device to start. | |
| @retval EFI_SUCCESS This driver supports this device | |
| @retval EFI_ALREADY_STARTED This driver is already running on this device | |
| @retval other This driver does not support this device | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| FvSimpleFileSystemDriverSupported ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, | |
| IN EFI_HANDLE ControllerHandle, | |
| IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL | |
| ) | |
| { | |
| return gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiFirmwareVolume2ProtocolGuid, | |
| NULL, | |
| gImageHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_TEST_PROTOCOL | |
| ); | |
| } | |
| /** | |
| Start this driver on ControllerHandle by opening a FV protocol and | |
| installing a SimpleFileSystem protocol on ControllerHandle. | |
| @param DriverBinding Protocol instance pointer. | |
| @param ControllerHandle Handle of device to bind driver to | |
| @param RemainingDevicePath Optional parameter use to pick a specific child | |
| device to start. | |
| @retval EFI_SUCCESS This driver is added to ControllerHandle | |
| @retval EFI_ALREADY_STARTED This driver is already running on ControllerHandle | |
| @retval other This driver does not support this device | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| FvSimpleFileSystemDriverStart ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, | |
| IN EFI_HANDLE ControllerHandle, | |
| IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; | |
| FV_FILESYSTEM_INSTANCE *Instance; | |
| EFI_DEVICE_PATH_PROTOCOL *FvDevicePath; | |
| EFI_GUID *FvGuid; | |
| UINTN NumChars; | |
| Status = InitializeUnicodeCollationSupport (DriverBinding->DriverBindingHandle); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| // | |
| // Open FV protocol | |
| // | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiFirmwareVolume2ProtocolGuid, | |
| (VOID **) &FvProtocol, | |
| gImageHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_BY_DRIVER | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| // | |
| // Create an instance | |
| // | |
| Instance = AllocateZeroPool (sizeof (FV_FILESYSTEM_INSTANCE)); | |
| ASSERT (Instance != NULL); | |
| Instance->Root = NULL; | |
| Instance->FvProtocol = FvProtocol; | |
| Instance->Signature = FVFS_INSTANCE_SIGNATURE; | |
| InitializeListHead (&Instance->FileInfoHead); | |
| InitializeListHead (&Instance->FileHead); | |
| CopyMem (&Instance->SimpleFs, &mSimpleFsTemplate, sizeof (mSimpleFsTemplate)); | |
| Status = gBS->InstallProtocolInterface( | |
| &ControllerHandle, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| EFI_NATIVE_INTERFACE, | |
| &Instance->SimpleFs | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Decide on a filesystem volume label, which will include the FV's guid. | |
| // Get the device path to find the FV's GUID | |
| // | |
| Instance->VolumeLabel = NULL; | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiDevicePathProtocolGuid, | |
| (VOID **) &FvDevicePath, | |
| gImageHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if (!EFI_ERROR (Status)) { | |
| // | |
| // Iterate over device path until we find a firmware volume node | |
| // | |
| while (!IsDevicePathEndType (FvDevicePath)) { | |
| if (DevicePathType (FvDevicePath) == MEDIA_DEVICE_PATH && | |
| DevicePathSubType (FvDevicePath) == MEDIA_PIWG_FW_VOL_DP) { | |
| // | |
| // Allocate the volume label | |
| // | |
| Instance->VolumeLabel = AllocateZeroPool (FVFS_VOLUME_LABEL_SIZE); | |
| // | |
| // Check the allocation was successful | |
| // | |
| if (Instance->VolumeLabel != NULL) { | |
| // | |
| // Extract the FV's guid | |
| // | |
| FvGuid = &((MEDIA_FW_VOL_DEVICE_PATH *) FvDevicePath)->FvName; | |
| // | |
| // Build the volume label string | |
| // | |
| NumChars = UnicodeSPrint ( | |
| Instance->VolumeLabel, | |
| FVFS_VOLUME_LABEL_SIZE, | |
| FVFS_VOLUME_LABEL_PREFIX L"%g", | |
| FvGuid | |
| ); | |
| ASSERT ((NumChars + 1) * sizeof (CHAR16) == FVFS_VOLUME_LABEL_SIZE); | |
| } | |
| break; | |
| } | |
| FvDevicePath = NextDevicePathNode (FvDevicePath); | |
| } | |
| } | |
| // | |
| // If we didn't decide on a volume label, set a fallback one | |
| // | |
| if (Instance->VolumeLabel == NULL) { | |
| Instance->VolumeLabel = AllocateCopyPool ( | |
| sizeof (FVFS_FALLBACK_VOLUME_LABEL), | |
| FVFS_FALLBACK_VOLUME_LABEL | |
| ); | |
| } | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing | |
| the FV protocol on ControllerHandle. | |
| @param DriverBinding Protocol instance pointer. | |
| @param ControllerHandle Handle of device to stop driver on | |
| @param NumberOfChildren Number of Handles in ChildHandleBuffer. If number of | |
| children is zero stop the entire bus driver. | |
| @param ChildHandleBuffer List of Child Handles to Stop. | |
| @retval EFI_SUCCESS This driver is removed ControllerHandle | |
| @retval other This driver was not removed from this device | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| FvSimpleFileSystemDriverStop ( | |
| IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, | |
| IN EFI_HANDLE ControllerHandle, | |
| IN UINTN NumberOfChildren, | |
| IN EFI_HANDLE *ChildHandleBuffer OPTIONAL | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| FV_FILESYSTEM_INSTANCE *Instance; | |
| FV_FILESYSTEM_FILE_INFO *FvFileInfo; | |
| LIST_ENTRY *Entry; | |
| LIST_ENTRY *DelEntry; | |
| EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *SimpleFile; | |
| Status = gBS->OpenProtocol ( | |
| ControllerHandle, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| (VOID **) &SimpleFile, | |
| DriverBinding->DriverBindingHandle, | |
| ControllerHandle, | |
| EFI_OPEN_PROTOCOL_GET_PROTOCOL | |
| ); | |
| if (EFI_ERROR (Status)) { | |
| return Status; | |
| } | |
| Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (SimpleFile); | |
| if (IsListEmpty (&Instance->FileHead) == FALSE) { | |
| // | |
| // Not all opened files are closed | |
| // | |
| return EFI_DEVICE_ERROR; | |
| } | |
| // | |
| // Close and uninstall protocols. | |
| // | |
| Status = gBS->CloseProtocol ( | |
| ControllerHandle, | |
| &gEfiFirmwareVolume2ProtocolGuid, | |
| gImageHandle, | |
| ControllerHandle | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| Status = gBS->UninstallProtocolInterface ( | |
| ControllerHandle, | |
| &gEfiSimpleFileSystemProtocolGuid, | |
| &Instance->SimpleFs | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| // | |
| // Free file structures | |
| // | |
| if (!IsListEmpty (&Instance->FileInfoHead)) { | |
| // | |
| // Free the Subtask list. | |
| // | |
| for(Entry = Instance->FileInfoHead.ForwardLink; | |
| Entry != (&Instance->FileInfoHead); | |
| ) { | |
| DelEntry = Entry; | |
| Entry = Entry->ForwardLink; | |
| FvFileInfo = FVFS_FILE_INFO_FROM_LINK (DelEntry); | |
| RemoveEntryList (DelEntry); | |
| FreePool (FvFileInfo); | |
| } | |
| } | |
| if (Instance->Root != NULL) { | |
| // | |
| // Root->Name is statically allocated, no need to free. | |
| // | |
| if (Instance->Root->FvFileInfo != NULL) { | |
| FreePool (Instance->Root->FvFileInfo); | |
| } | |
| FreePool (Instance->Root); | |
| } | |
| // | |
| // Free Instance | |
| // | |
| if (Instance->VolumeLabel != NULL) { | |
| FreePool (Instance->VolumeLabel); | |
| } | |
| FreePool (Instance); | |
| return EFI_SUCCESS; | |
| } | |
| /** | |
| The user Entry Point for module FvSimpleFileSystem. The user code starts with this function. | |
| @param[in] ImageHandle The firmware allocated handle for the EFI image. | |
| @param[in] SystemTable A pointer to the EFI System Table. | |
| @retval EFI_SUCCESS The entry point is executed successfully. | |
| @retval other Some error occurs when executing this entry point. | |
| **/ | |
| EFI_STATUS | |
| EFIAPI | |
| FvSimpleFileSystemEntryPoint ( | |
| IN EFI_HANDLE ImageHandle, | |
| IN EFI_SYSTEM_TABLE *SystemTable | |
| ) | |
| { | |
| EFI_STATUS Status; | |
| // | |
| // Install driver model protocol(s). | |
| // | |
| Status = EfiLibInstallDriverBindingComponentName2 ( | |
| ImageHandle, | |
| SystemTable, | |
| &mDriverBinding, | |
| ImageHandle, | |
| &gFvSimpleFileSystemComponentName, | |
| &gFvSimpleFileSystemComponentName2 | |
| ); | |
| ASSERT_EFI_ERROR (Status); | |
| return Status; | |
| } |