diff options
Diffstat (limited to 'MdeModulePkg/Universal/FvSimpleFileSystemDxe')
7 files changed, 2615 insertions, 2615 deletions
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c index 663022d28b..0993734ed7 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c @@ -1,181 +1,181 @@ -/** @file
- UEFI Component Name(2) protocol implementation for FvSimpleFileSystem driver.
-
-Copyright (c) 2014, ARM Limited. All rights reserved.
-Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>
-
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "FvSimpleFileSystemInternal.h"
-
-//
-// EFI Component Name Protocol
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gFvSimpleFileSystemComponentName = {
- FvSimpleFileSystemComponentNameGetDriverName,
- FvSimpleFileSystemComponentNameGetControllerName,
- "eng"
-};
-
-//
-// EFI Component Name 2 Protocol
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gFvSimpleFileSystemComponentName2 = {
- (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)FvSimpleFileSystemComponentNameGetDriverName,
- (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)FvSimpleFileSystemComponentNameGetControllerName,
- "en"
-};
-
-//
-// Driver name table for FvSimpleFileSystem module.
-// It is shared by the implementation of ComponentName & ComponentName2 Protocol.
-//
-GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mFvSimpleFileSystemDriverNameTable[] = {
- {
- "eng;en",
- (CHAR16 *)L"Fv Simple File System Driver"
- },
- {
- NULL,
- NULL
- }
-};
-
-/**
- Retrieves a Unicode string that is the user readable name of the driver.
-
- This function retrieves the user readable name of a driver in the form of a
- Unicode string. If the driver specified by This has a user readable name in
- the language specified by Language, then a pointer to the driver name is
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
- by This does not support the language specified by Language,
- then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified
- in RFC 4646 or ISO 639-2 language code format.
-
- @param DriverName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- driver specified by This in the language
- specified by Language.
-
- @retval EFI_SUCCESS The Unicode string for the Driver specified by
- This and the language specified by Language was
- returned in DriverName.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER DriverName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemComponentNameGetDriverName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN CHAR8 *Language,
- OUT CHAR16 **DriverName
- )
-{
- return LookupUnicodeString2 (
- Language,
- This->SupportedLanguages,
- mFvSimpleFileSystemDriverNameTable,
- DriverName,
- (BOOLEAN)(This == &gFvSimpleFileSystemComponentName)
- );
-}
-
-/**
- Retrieves a Unicode string that is the user readable name of the controller
- that is being managed by a driver.
-
- This function retrieves the user readable name of the controller specified by
- ControllerHandle and ChildHandle in the form of a Unicode string. If the
- driver specified by This has a user readable name in the language specified by
- Language, then a pointer to the controller name is returned in ControllerName,
- and EFI_SUCCESS is returned. If the driver specified by This is not currently
- managing the controller specified by ControllerHandle and ChildHandle,
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not
- support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param ControllerHandle[in] The handle of a controller that the driver
- specified by This is managing. This handle
- specifies the controller whose name is to be
- returned.
-
- @param ChildHandle[in] The handle of the child controller to retrieve
- the name of. This is an optional parameter that
- may be NULL. It will be NULL for device
- drivers. It will also be NULL for a bus drivers
- that wish to retrieve the name of the bus
- controller. It will not be NULL for a bus
- driver that wishes to retrieve the name of a
- child controller.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified in
- RFC 4646 or ISO 639-2 language code format.
-
- @param ControllerName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- controller specified by ControllerHandle and
- ChildHandle in the language specified by
- Language from the point of view of the driver
- specified by This.
-
- @retval EFI_SUCCESS The Unicode string for the user readable name in
- the language specified by Language for the
- driver specified by This was returned in
- DriverName.
-
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
-
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
- EFI_HANDLE.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This is not currently
- managing the controller specified by
- ControllerHandle and ChildHandle.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemComponentNameGetControllerName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE ChildHandle OPTIONAL,
- IN CHAR8 *Language,
- OUT CHAR16 **ControllerName
- )
-{
- return EFI_UNSUPPORTED;
-}
+/** @file + UEFI Component Name(2) protocol implementation for FvSimpleFileSystem driver. + +Copyright (c) 2014, ARM Limited. All rights reserved. +Copyright (c) 2014, Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "FvSimpleFileSystemInternal.h" + +// +// EFI Component Name Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gFvSimpleFileSystemComponentName = { + FvSimpleFileSystemComponentNameGetDriverName, + FvSimpleFileSystemComponentNameGetControllerName, + "eng" +}; + +// +// EFI Component Name 2 Protocol +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gFvSimpleFileSystemComponentName2 = { + (EFI_COMPONENT_NAME2_GET_DRIVER_NAME)FvSimpleFileSystemComponentNameGetDriverName, + (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME)FvSimpleFileSystemComponentNameGetControllerName, + "en" +}; + +// +// Driver name table for FvSimpleFileSystem module. +// It is shared by the implementation of ComponentName & ComponentName2 Protocol. +// +GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mFvSimpleFileSystemDriverNameTable[] = { + { + "eng;en", + (CHAR16 *)L"Fv Simple File System Driver" + }, + { + NULL, + NULL + } +}; + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ) +{ + return LookupUnicodeString2 ( + Language, + This->SupportedLanguages, + mFvSimpleFileSystemDriverNameTable, + DriverName, + (BOOLEAN)(This == &gFvSimpleFileSystemComponentName) + ); +} + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ) +{ + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c index 0252db19ad..623cd59d35 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c @@ -1,1041 +1,1041 @@ -/** @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 - 2018, Intel Corporation. All rights reserved.<BR>
-
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#include "FvSimpleFileSystemInternal.h"
-
-//
-// Template for EFI_FILE_SYSTEM_INFO data structure.
-//
-EFI_FILE_SYSTEM_INFO mFsInfoTemplate = {
- 0, // Populate at runtime
- TRUE, // Read-only
- 0, // Don't know volume size
- 0, // No free space
- 0, // Don't know block size
- L"" // Populate at runtime
-};
-
-//
-// Template for EFI_FILE_PROTOCOL data structure.
-//
-EFI_FILE_PROTOCOL mFileSystemTemplate = {
- EFI_FILE_PROTOCOL_REVISION,
- FvSimpleFileSystemOpen,
- FvSimpleFileSystemClose,
- FvSimpleFileSystemDelete,
- FvSimpleFileSystemRead,
- FvSimpleFileSystemWrite,
- FvSimpleFileSystemGetPosition,
- FvSimpleFileSystemSetPosition,
- FvSimpleFileSystemGetInfo,
- FvSimpleFileSystemSetInfo,
- FvSimpleFileSystemFlush
-};
-
-/**
- Find and call ReadSection on the first section found of an executable type.
-
- @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
- @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
- representing a file's info.
- @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of
- the memory represented by *Buffer.
- @param Buffer Pointer to a pointer to a data buffer to contain file content.
-
- @retval EFI_SUCCESS The call completed successfully.
- @retval EFI_WARN_BUFFER_TOO_SMALL The buffer is too small to contain the requested output.
- @retval EFI_ACCESS_DENIED The firmware volume is configured to disallow reads.
- @retval EFI_NOT_FOUND The requested file was not found in the firmware volume.
- @retval EFI_DEVICE_ERROR A hardware error occurred when attempting toaccess the firmware volume.
-
-**/
-EFI_STATUS
-FvFsFindExecutableSection (
- IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
- IN FV_FILESYSTEM_FILE_INFO *FvFileInfo,
- IN OUT UINTN *BufferSize,
- IN OUT VOID **Buffer
- )
-{
- EFI_SECTION_TYPE SectionType;
- UINT32 AuthenticationStatus;
- EFI_STATUS Status;
-
- for (SectionType = EFI_SECTION_PE32; SectionType <= EFI_SECTION_TE; SectionType++) {
- Status = FvProtocol->ReadSection (
- FvProtocol,
- &FvFileInfo->NameGuid,
- SectionType,
- 0,
- Buffer,
- BufferSize,
- &AuthenticationStatus
- );
- if (Status != EFI_NOT_FOUND) {
- return Status;
- }
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Get the size of the buffer that will be returned by FvFsReadFile.
-
- @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
- @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
- representing a file's info.
-
- @retval EFI_SUCCESS The file size was gotten correctly.
- @retval Others The file size wasn't gotten correctly.
-
-**/
-EFI_STATUS
-FvFsGetFileSize (
- IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
- IN OUT FV_FILESYSTEM_FILE_INFO *FvFileInfo
- )
-{
- UINT32 AuthenticationStatus;
- EFI_FV_FILETYPE FoundType;
- EFI_FV_FILE_ATTRIBUTES Attributes;
- EFI_STATUS Status;
- UINT8 IgnoredByte;
- VOID *IgnoredPtr;
-
- //
- // To get the size of a section, we pass 0 for BufferSize. But we can't pass
- // NULL for Buffer, as that will cause a return of INVALID_PARAMETER, and we
- // can't pass NULL for *Buffer, as that will cause the callee to allocate
- // a buffer of the sections size.
- //
- IgnoredPtr = &IgnoredByte;
- FvFileInfo->FileInfo.FileSize = 0;
-
- if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {
- //
- // Get the size of the first executable section out of the file.
- //
- Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, (UINTN *)&FvFileInfo->FileInfo.FileSize, &IgnoredPtr);
- if (Status == EFI_WARN_BUFFER_TOO_SMALL) {
- return EFI_SUCCESS;
- }
- } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {
- //
- // Try to get the size of a raw section out of the file
- //
- Status = FvProtocol->ReadSection (
- FvProtocol,
- &FvFileInfo->NameGuid,
- EFI_SECTION_RAW,
- 0,
- &IgnoredPtr,
- (UINTN *)&FvFileInfo->FileInfo.FileSize,
- &AuthenticationStatus
- );
- if (Status == EFI_WARN_BUFFER_TOO_SMALL) {
- return EFI_SUCCESS;
- }
-
- if (EFI_ERROR (Status)) {
- //
- // Didn't find a raw section, just return the whole file's size.
- //
- return FvProtocol->ReadFile (
- FvProtocol,
- &FvFileInfo->NameGuid,
- NULL,
- (UINTN *)&FvFileInfo->FileInfo.FileSize,
- &FoundType,
- &Attributes,
- &AuthenticationStatus
- );
- }
- } else {
- //
- // Get the size of the entire file
- //
- return FvProtocol->ReadFile (
- FvProtocol,
- &FvFileInfo->NameGuid,
- NULL,
- (UINTN *)&FvFileInfo->FileInfo.FileSize,
- &FoundType,
- &Attributes,
- &AuthenticationStatus
- );
- }
-
- return Status;
-}
-
-/**
- Helper function to read a file.
-
- The data returned depends on the type of the underlying FV file:
- - For executable types, the first section found that contains executable code is returned.
- - For files of type FREEFORM, the driver attempts to return the first section of type RAW.
- If none is found, the entire contents of the FV file are returned.
- - On all other files the entire contents of the FV file is returned, as by
- EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadFile.
-
- @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
- @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
- representing a file's info.
- @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of
- the memory represented by *Buffer.
- @param Buffer Pointer to a pointer to a data buffer to contain file content.
-
- @retval EFI_SUCCESS The call completed successfully.
- @retval EFI_WARN_BUFFER_TOO_SMALL The buffer is too small to contain the requested output.
- @retval EFI_ACCESS_DENIED The firmware volume is configured to disallow reads.
- @retval EFI_NOT_FOUND The requested file was not found in the firmware volume.
- @retval EFI_DEVICE_ERROR A hardware error occurred when attempting toaccess the firmware volume.
-
-**/
-EFI_STATUS
-FvFsReadFile (
- IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
- IN FV_FILESYSTEM_FILE_INFO *FvFileInfo,
- IN OUT UINTN *BufferSize,
- IN OUT VOID **Buffer
- )
-{
- UINT32 AuthenticationStatus;
- EFI_FV_FILETYPE FoundType;
- EFI_FV_FILE_ATTRIBUTES Attributes;
- EFI_STATUS Status;
-
- if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {
- //
- // Read the first executable section out of the file.
- //
- Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, BufferSize, Buffer);
- } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {
- //
- // Try to read a raw section out of the file
- //
- Status = FvProtocol->ReadSection (
- FvProtocol,
- &FvFileInfo->NameGuid,
- EFI_SECTION_RAW,
- 0,
- Buffer,
- BufferSize,
- &AuthenticationStatus
- );
- if (EFI_ERROR (Status)) {
- //
- // Didn't find a raw section, just return the whole file.
- //
- Status = FvProtocol->ReadFile (
- FvProtocol,
- &FvFileInfo->NameGuid,
- Buffer,
- BufferSize,
- &FoundType,
- &Attributes,
- &AuthenticationStatus
- );
- }
- } else {
- //
- // Read the entire file
- //
- Status = FvProtocol->ReadFile (
- FvProtocol,
- &FvFileInfo->NameGuid,
- Buffer,
- BufferSize,
- &FoundType,
- &Attributes,
- &AuthenticationStatus
- );
- }
-
- return Status;
-}
-
-/**
- Helper function for populating an EFI_FILE_INFO for a file.
-
- Note the CreateTime, LastAccessTime and ModificationTime fields in EFI_FILE_INFO
- are full zero as FV2 protocol has no corresponding info to fill.
-
- @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
- representing a file's info.
- @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of
- the memory represented by FileInfo.
- @param FileInfo A pointer to EFI_FILE_INFO to contain the returned file info.
-
- @retval EFI_SUCCESS The call completed successfully.
- @retval EFI_BUFFER_TOO_SMALL The buffer is too small to contain the requested output.
-
-**/
-EFI_STATUS
-FvFsGetFileInfo (
- IN FV_FILESYSTEM_FILE_INFO *FvFileInfo,
- IN OUT UINTN *BufferSize,
- OUT EFI_FILE_INFO *FileInfo
- )
-{
- UINTN InfoSize;
-
- InfoSize = (UINTN)FvFileInfo->FileInfo.Size;
- if (*BufferSize < InfoSize) {
- *BufferSize = InfoSize;
- return EFI_BUFFER_TOO_SMALL;
- }
-
- //
- // Initialize FileInfo
- //
- CopyMem (FileInfo, &FvFileInfo->FileInfo, InfoSize);
-
- *BufferSize = InfoSize;
- return EFI_SUCCESS;
-}
-
-/**
- Removes the last directory or file entry in a path by changing the last
- L'\' to a CHAR_NULL.
-
- @param Path The pointer to the path to modify.
-
- @retval FALSE Nothing was found to remove.
- @retval TRUE A directory or file was removed.
-
-**/
-BOOLEAN
-EFIAPI
-RemoveLastItemFromPath (
- IN OUT CHAR16 *Path
- )
-{
- CHAR16 *Walker;
- CHAR16 *LastSlash;
-
- //
- // get directory name from path... ('chop' off extra)
- //
- for ( Walker = Path, LastSlash = NULL
- ; Walker != NULL && *Walker != CHAR_NULL
- ; Walker++
- )
- {
- if ((*Walker == L'\\') && (*(Walker + 1) != CHAR_NULL)) {
- LastSlash = Walker + 1;
- }
- }
-
- if (LastSlash != NULL) {
- *LastSlash = CHAR_NULL;
- return (TRUE);
- }
-
- return (FALSE);
-}
-
-/**
- Function to clean up paths.
-
- - Single periods in the path are removed.
- - Double periods in the path are removed along with a single parent directory.
- - Forward slashes L'/' are converted to backward slashes L'\'.
-
- This will be done inline and the existing buffer may be larger than required
- upon completion.
-
- @param Path The pointer to the string containing the path.
-
- @retval NULL An error occurred.
- @return Path in all other instances.
-
-**/
-CHAR16 *
-EFIAPI
-TrimFilePathToAbsolutePath (
- IN CHAR16 *Path
- )
-{
- CHAR16 *TempString;
- UINTN TempSize;
-
- if (Path == NULL) {
- return NULL;
- }
-
- //
- // Fix up the '/' vs '\'
- //
- for (TempString = Path; (TempString != NULL) && (*TempString != CHAR_NULL); TempString++) {
- if (*TempString == L'/') {
- *TempString = L'\\';
- }
- }
-
- //
- // Fix up the ..
- //
- while ((TempString = StrStr (Path, L"\\..\\")) != NULL) {
- *TempString = CHAR_NULL;
- TempString += 4;
- RemoveLastItemFromPath (Path);
- TempSize = StrSize (TempString);
- CopyMem (Path + StrLen (Path), TempString, TempSize);
- }
-
- if (((TempString = StrStr (Path, L"\\..")) != NULL) && (*(TempString + 3) == CHAR_NULL)) {
- *TempString = CHAR_NULL;
- RemoveLastItemFromPath (Path);
- }
-
- //
- // Fix up the .
- //
- while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {
- *TempString = CHAR_NULL;
- TempString += 2;
- TempSize = StrSize (TempString);
- CopyMem (Path + StrLen (Path), TempString, TempSize);
- }
-
- if (((TempString = StrStr (Path, L"\\.")) != NULL) && (*(TempString + 2) == CHAR_NULL)) {
- *(TempString + 1) = CHAR_NULL;
- }
-
- while ((TempString = StrStr (Path, L"\\\\")) != NULL) {
- *TempString = CHAR_NULL;
- TempString += 1;
- TempSize = StrSize (TempString);
- CopyMem (Path + StrLen (Path), TempString, TempSize);
- }
-
- if (((TempString = StrStr (Path, L"\\\\")) != NULL) && (*(TempString + 1) == CHAR_NULL)) {
- *(TempString) = CHAR_NULL;
- }
-
- return Path;
-}
-
-/**
- Opens a new file relative to the source file's location.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to the source location. This would typically be an open
- handle to a directory.
- @param NewHandle A pointer to the location to return the opened handle for the new
- file.
- @param FileName The Null-terminated string of the name of the file to be opened.
- The file name may contain the following path modifiers: "\", ".",
- and "..".
- @param OpenMode The mode to open the file. The only valid combinations that the
- file may be opened with are: Read, Read/Write, or Create/Read/Write.
- @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
- attribute bits for the newly created file.
-
- @retval EFI_SUCCESS The file was opened.
- @retval EFI_NOT_FOUND The specified file could not be found on the device.
- @retval EFI_NO_MEDIA The device has no medium.
- @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no
- longer supported.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
- @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write
- when the media is write-protected.
- @retval EFI_ACCESS_DENIED The service denied access to the file.
- @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
- @retval EFI_VOLUME_FULL The volume is full.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemOpen (
- IN EFI_FILE_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **NewHandle,
- IN CHAR16 *FileName,
- IN UINT64 OpenMode,
- IN UINT64 Attributes
- )
-{
- FV_FILESYSTEM_INSTANCE *Instance;
- FV_FILESYSTEM_FILE *File;
- FV_FILESYSTEM_FILE *NewFile;
- FV_FILESYSTEM_FILE_INFO *FvFileInfo;
- LIST_ENTRY *FvFileInfoLink;
- EFI_STATUS Status;
- UINTN FileNameLength;
- UINTN NewFileNameLength;
- CHAR16 *FileNameWithExtension;
-
- //
- // Check for a valid mode
- //
- switch (OpenMode) {
- case EFI_FILE_MODE_READ:
- break;
-
- default:
- return EFI_WRITE_PROTECTED;
- }
-
- File = FVFS_FILE_FROM_FILE_THIS (This);
- Instance = File->Instance;
-
- FileName = TrimFilePathToAbsolutePath (FileName);
- if (FileName == NULL) {
- return EFI_INVALID_PARAMETER;
- }
-
- if (FileName[0] == L'\\') {
- FileName++;
- }
-
- //
- // Check for opening root
- //
- if ((StrCmp (FileName, L".") == 0) || (StrCmp (FileName, L"") == 0)) {
- NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
- if (NewFile == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- NewFile->Signature = FVFS_FILE_SIGNATURE;
- NewFile->Instance = Instance;
- NewFile->FvFileInfo = File->FvFileInfo;
- CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
- InitializeListHead (&NewFile->Link);
- InsertHeadList (&Instance->FileHead, &NewFile->Link);
-
- NewFile->DirReadNext = NULL;
- if (!IsListEmpty (&Instance->FileInfoHead)) {
- NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
- }
-
- *NewHandle = &NewFile->FileProtocol;
- return EFI_SUCCESS;
- }
-
- //
- // Do a linear search for a file in the FV with a matching filename
- //
- Status = EFI_NOT_FOUND;
- FvFileInfo = NULL;
- for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
- !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
- FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink))
- {
- FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
- if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) {
- Status = EFI_SUCCESS;
- break;
- }
- }
-
- // If the file has not been found check if the filename exists with an extension
- // in case there was no extension present.
- // FvFileSystem adds a 'virtual' extension '.EFI' to EFI applications and drivers
- // present in the Firmware Volume
- if (Status == EFI_NOT_FOUND) {
- FileNameLength = StrLen (FileName);
-
- // Does the filename already contain the '.EFI' extension?
- if (mUnicodeCollation->StriColl (mUnicodeCollation, FileName + FileNameLength - 4, L".efi") != 0) {
- // No, there was no extension. So add one and search again for the file
- // NewFileNameLength = FileNameLength + 1 + 4 = (Number of non-null character) + (file extension) + (a null character)
- NewFileNameLength = FileNameLength + 1 + 4;
- FileNameWithExtension = AllocatePool (NewFileNameLength * 2);
- StrCpyS (FileNameWithExtension, NewFileNameLength, FileName);
- StrCatS (FileNameWithExtension, NewFileNameLength, L".EFI");
-
- for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);
- !IsNull (&Instance->FileInfoHead, FvFileInfoLink);
- FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink))
- {
- FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
- if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileNameWithExtension) == 0) {
- Status = EFI_SUCCESS;
- break;
- }
- }
- }
- }
-
- if (!EFI_ERROR (Status)) {
- NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
- if (NewFile == NULL) {
- return EFI_OUT_OF_RESOURCES;
- }
-
- NewFile->Signature = FVFS_FILE_SIGNATURE;
- NewFile->Instance = Instance;
- NewFile->FvFileInfo = FvFileInfo;
- CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
- InitializeListHead (&NewFile->Link);
- InsertHeadList (&Instance->FileHead, &NewFile->Link);
-
- *NewHandle = &NewFile->FileProtocol;
- return EFI_SUCCESS;
- }
-
- return EFI_NOT_FOUND;
-}
-
-/**
- Closes a specified file handle.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to close.
-
- @retval EFI_SUCCESS The file was closed.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemClose (
- IN EFI_FILE_PROTOCOL *This
- )
-{
- FV_FILESYSTEM_INSTANCE *Instance;
- FV_FILESYSTEM_FILE *File;
-
- File = FVFS_FILE_FROM_FILE_THIS (This);
- Instance = File->Instance;
-
- if (File != Instance->Root) {
- RemoveEntryList (&File->Link);
- FreePool (File);
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Reads data from a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to read data from.
- @param BufferSize On input, the size of the Buffer. On output, the amount of data
- returned in Buffer. In both cases, the size is measured in bytes.
- @param Buffer The buffer into which the data is read.
-
- @retval EFI_SUCCESS Data was read.
- @retval EFI_NO_MEDIA The device has no medium.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file.
- @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file.
- @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
- @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
- entry. BufferSize has been updated with the size
- needed to complete the request.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemRead (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
-{
- FV_FILESYSTEM_INSTANCE *Instance;
- FV_FILESYSTEM_FILE *File;
- EFI_STATUS Status;
- LIST_ENTRY *FvFileInfoLink;
- VOID *FileBuffer;
- UINTN FileSize;
-
- File = FVFS_FILE_FROM_FILE_THIS (This);
- Instance = File->Instance;
-
- if (File->FvFileInfo == Instance->Root->FvFileInfo) {
- if (File->DirReadNext) {
- //
- // Directory read: populate Buffer with an EFI_FILE_INFO
- //
- Status = FvFsGetFileInfo (File->DirReadNext, BufferSize, Buffer);
- if (!EFI_ERROR (Status)) {
- //
- // Successfully read a directory entry, now update the pointer to the
- // next file, which will be read on the next call to this function
- //
- FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, &File->DirReadNext->Link);
- if (IsNull (&Instance->FileInfoHead, FvFileInfoLink)) {
- //
- // No more files left
- //
- File->DirReadNext = NULL;
- } else {
- File->DirReadNext = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);
- }
- }
-
- return Status;
- } else {
- //
- // Directory read. All entries have been read, so return a zero-size
- // buffer.
- //
- *BufferSize = 0;
- return EFI_SUCCESS;
- }
- } else {
- FileSize = (UINTN)File->FvFileInfo->FileInfo.FileSize;
-
- FileBuffer = AllocateZeroPool (FileSize);
- if (FileBuffer == NULL) {
- return EFI_DEVICE_ERROR;
- }
-
- Status = FvFsReadFile (File->Instance->FvProtocol, File->FvFileInfo, &FileSize, &FileBuffer);
- if (EFI_ERROR (Status)) {
- FreePool (FileBuffer);
- return EFI_DEVICE_ERROR;
- }
-
- if (*BufferSize + File->Position > FileSize) {
- *BufferSize = (UINTN)(FileSize - File->Position);
- }
-
- CopyMem (Buffer, (UINT8 *)FileBuffer + File->Position, *BufferSize);
- File->Position += *BufferSize;
-
- FreePool (FileBuffer);
-
- return EFI_SUCCESS;
- }
-}
-
-/**
- Writes data to a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to write data to.
- @param BufferSize On input, the size of the Buffer. On output, the amount of data
- actually written. In both cases, the size is measured in bytes.
- @param Buffer The buffer of data to write.
-
- @retval EFI_SUCCESS Data was written.
- @retval EFI_UNSUPPORTED Writes to open directory files are not supported.
- @retval EFI_NO_MEDIA The device has no medium.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
- @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
- @retval EFI_WRITE_PROTECTED The file or medium is write-protected.
- @retval EFI_ACCESS_DENIED The file was opened read only.
- @retval EFI_VOLUME_FULL The volume is full.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemWrite (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- IN VOID *Buffer
- )
-{
- FV_FILESYSTEM_INSTANCE *Instance;
- FV_FILESYSTEM_FILE *File;
-
- File = FVFS_FILE_FROM_FILE_THIS (This);
- Instance = File->Instance;
-
- if (File->FvFileInfo == Instance->Root->FvFileInfo) {
- return EFI_UNSUPPORTED;
- } else {
- return EFI_WRITE_PROTECTED;
- }
-}
-
-/**
- Returns a file's current position.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to get the current position on.
- @param Position The address to return the file's current position value.
-
- @retval EFI_SUCCESS The position was returned.
- @retval EFI_UNSUPPORTED The request is not valid on open directories.
- @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemGetPosition (
- IN EFI_FILE_PROTOCOL *This,
- OUT UINT64 *Position
- )
-{
- FV_FILESYSTEM_INSTANCE *Instance;
- FV_FILESYSTEM_FILE *File;
-
- File = FVFS_FILE_FROM_FILE_THIS (This);
- Instance = File->Instance;
-
- if (File->FvFileInfo == Instance->Root->FvFileInfo) {
- return EFI_UNSUPPORTED;
- } else {
- *Position = File->Position;
- return EFI_SUCCESS;
- }
-}
-
-/**
- Sets a file's current position.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
- file handle to set the requested position on.
- @param Position The byte position from the start of the file to set.
-
- @retval EFI_SUCCESS The position was set.
- @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
- directories.
- @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemSetPosition (
- IN EFI_FILE_PROTOCOL *This,
- IN UINT64 Position
- )
-{
- FV_FILESYSTEM_INSTANCE *Instance;
- FV_FILESYSTEM_FILE *File;
-
- File = FVFS_FILE_FROM_FILE_THIS (This);
- Instance = File->Instance;
-
- if (File->FvFileInfo == Instance->Root->FvFileInfo) {
- if (Position != 0) {
- return EFI_UNSUPPORTED;
- }
-
- //
- // Reset directory position to first entry
- //
- if (File->DirReadNext) {
- File->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
- }
- } else if (Position == 0xFFFFFFFFFFFFFFFFull) {
- File->Position = File->FvFileInfo->FileInfo.FileSize;
- } else {
- File->Position = Position;
- }
-
- return EFI_SUCCESS;
-}
-
-/**
- Flushes all modified data associated with a file to a device.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to flush.
-
- @retval EFI_SUCCESS The data was flushed.
- @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_WRITE_PROTECTED The file or medium is write-protected.
- @retval EFI_ACCESS_DENIED The file was opened read-only.
- @retval EFI_VOLUME_FULL The volume is full.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemFlush (
- IN EFI_FILE_PROTOCOL *This
- )
-{
- return EFI_WRITE_PROTECTED;
-}
-
-/**
- Close and delete the file handle.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
- handle to the file to delete.
-
- @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed.
- @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemDelete (
- IN EFI_FILE_PROTOCOL *This
- )
-{
- EFI_STATUS Status;
-
- Status = FvSimpleFileSystemClose (This);
- ASSERT_EFI_ERROR (Status);
-
- return EFI_WARN_DELETE_FAILURE;
-}
-
-/**
- Returns information about a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle the requested information is for.
- @param InformationType The type identifier for the information being requested.
- @param BufferSize On input, the size of Buffer. On output, the amount of data
- returned in Buffer. In both cases, the size is measured in bytes.
- @param Buffer A pointer to the data buffer to return. The buffer's type is
- indicated by InformationType.
-
- @retval EFI_SUCCESS The information was returned.
- @retval EFI_UNSUPPORTED The InformationType is not known.
- @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_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
- BufferSize has been updated with the size needed to complete
- the request.
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemGetInfo (
- IN EFI_FILE_PROTOCOL *This,
- IN EFI_GUID *InformationType,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- )
-{
- FV_FILESYSTEM_FILE *File;
- EFI_FILE_SYSTEM_INFO *FsInfoOut;
- EFI_FILE_SYSTEM_VOLUME_LABEL *FsVolumeLabel;
- FV_FILESYSTEM_INSTANCE *Instance;
- UINTN Size;
- EFI_STATUS Status;
-
- File = FVFS_FILE_FROM_FILE_THIS (This);
-
- if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {
- //
- // Return filesystem info
- //
- Instance = File->Instance;
-
- Size = sizeof (EFI_FILE_SYSTEM_INFO) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);
-
- if (*BufferSize < Size) {
- *BufferSize = Size;
- return EFI_BUFFER_TOO_SMALL;
- }
-
- //
- // Cast output buffer for convenience
- //
- FsInfoOut = (EFI_FILE_SYSTEM_INFO *)Buffer;
-
- CopyMem (FsInfoOut, &mFsInfoTemplate, sizeof (EFI_FILE_SYSTEM_INFO));
- Status = StrnCpyS (
- FsInfoOut->VolumeLabel,
- (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16),
- Instance->VolumeLabel,
- StrLen (Instance->VolumeLabel)
- );
- ASSERT_EFI_ERROR (Status);
- FsInfoOut->Size = Size;
- return Status;
- } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {
- //
- // Return file info
- //
- return FvFsGetFileInfo (File->FvFileInfo, BufferSize, (EFI_FILE_INFO *)Buffer);
- } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {
- //
- // Return Volume Label
- //
- Instance = File->Instance;
- Size = sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);
- if (*BufferSize < Size) {
- *BufferSize = Size;
- return EFI_BUFFER_TOO_SMALL;
- }
-
- FsVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer;
- Status = StrnCpyS (
- FsVolumeLabel->VolumeLabel,
- (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel)) / sizeof (CHAR16),
- Instance->VolumeLabel,
- StrLen (Instance->VolumeLabel)
- );
- ASSERT_EFI_ERROR (Status);
- return Status;
- } else {
- return EFI_UNSUPPORTED;
- }
-}
-
-/**
- Sets information about a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle the information is for.
- @param InformationType The type identifier for the information being set.
- @param BufferSize The size, in bytes, of Buffer.
- @param Buffer A pointer to the data buffer to write. The buffer's type is
- indicated by InformationType.
-
- @retval EFI_SUCCESS The information was set.
- @retval EFI_UNSUPPORTED The InformationType is not known.
- @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_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media is
- read-only.
- @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID
- and the media is read only.
- @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID
- and the media is read-only.
- @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a
- file that is already present.
- @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY
- Attribute.
- @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory.
- @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened
- read-only and an attempt is being made to modify a field
- other than Attribute.
- @retval EFI_VOLUME_FULL The volume is full.
- @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated
- by InformationType.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemSetInfo (
- IN EFI_FILE_PROTOCOL *This,
- IN EFI_GUID *InformationType,
- IN UINTN BufferSize,
- IN VOID *Buffer
- )
-{
- if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) ||
- CompareGuid (InformationType, &gEfiFileInfoGuid) ||
- CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid))
- {
- return EFI_WRITE_PROTECTED;
- }
-
- return EFI_UNSUPPORTED;
-}
+/** @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 - 2018, Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#include "FvSimpleFileSystemInternal.h" + +// +// Template for EFI_FILE_SYSTEM_INFO data structure. +// +EFI_FILE_SYSTEM_INFO mFsInfoTemplate = { + 0, // Populate at runtime + TRUE, // Read-only + 0, // Don't know volume size + 0, // No free space + 0, // Don't know block size + L"" // Populate at runtime +}; + +// +// Template for EFI_FILE_PROTOCOL data structure. +// +EFI_FILE_PROTOCOL mFileSystemTemplate = { + EFI_FILE_PROTOCOL_REVISION, + FvSimpleFileSystemOpen, + FvSimpleFileSystemClose, + FvSimpleFileSystemDelete, + FvSimpleFileSystemRead, + FvSimpleFileSystemWrite, + FvSimpleFileSystemGetPosition, + FvSimpleFileSystemSetPosition, + FvSimpleFileSystemGetInfo, + FvSimpleFileSystemSetInfo, + FvSimpleFileSystemFlush +}; + +/** + Find and call ReadSection on the first section found of an executable type. + + @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct + representing a file's info. + @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of + the memory represented by *Buffer. + @param Buffer Pointer to a pointer to a data buffer to contain file content. + + @retval EFI_SUCCESS The call completed successfully. + @retval EFI_WARN_BUFFER_TOO_SMALL The buffer is too small to contain the requested output. + @retval EFI_ACCESS_DENIED The firmware volume is configured to disallow reads. + @retval EFI_NOT_FOUND The requested file was not found in the firmware volume. + @retval EFI_DEVICE_ERROR A hardware error occurred when attempting toaccess the firmware volume. + +**/ +EFI_STATUS +FvFsFindExecutableSection ( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol, + IN FV_FILESYSTEM_FILE_INFO *FvFileInfo, + IN OUT UINTN *BufferSize, + IN OUT VOID **Buffer + ) +{ + EFI_SECTION_TYPE SectionType; + UINT32 AuthenticationStatus; + EFI_STATUS Status; + + for (SectionType = EFI_SECTION_PE32; SectionType <= EFI_SECTION_TE; SectionType++) { + Status = FvProtocol->ReadSection ( + FvProtocol, + &FvFileInfo->NameGuid, + SectionType, + 0, + Buffer, + BufferSize, + &AuthenticationStatus + ); + if (Status != EFI_NOT_FOUND) { + return Status; + } + } + + return EFI_NOT_FOUND; +} + +/** + Get the size of the buffer that will be returned by FvFsReadFile. + + @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct + representing a file's info. + + @retval EFI_SUCCESS The file size was gotten correctly. + @retval Others The file size wasn't gotten correctly. + +**/ +EFI_STATUS +FvFsGetFileSize ( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol, + IN OUT FV_FILESYSTEM_FILE_INFO *FvFileInfo + ) +{ + UINT32 AuthenticationStatus; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES Attributes; + EFI_STATUS Status; + UINT8 IgnoredByte; + VOID *IgnoredPtr; + + // + // To get the size of a section, we pass 0 for BufferSize. But we can't pass + // NULL for Buffer, as that will cause a return of INVALID_PARAMETER, and we + // can't pass NULL for *Buffer, as that will cause the callee to allocate + // a buffer of the sections size. + // + IgnoredPtr = &IgnoredByte; + FvFileInfo->FileInfo.FileSize = 0; + + if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) { + // + // Get the size of the first executable section out of the file. + // + Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, (UINTN *)&FvFileInfo->FileInfo.FileSize, &IgnoredPtr); + if (Status == EFI_WARN_BUFFER_TOO_SMALL) { + return EFI_SUCCESS; + } + } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) { + // + // Try to get the size of a raw section out of the file + // + Status = FvProtocol->ReadSection ( + FvProtocol, + &FvFileInfo->NameGuid, + EFI_SECTION_RAW, + 0, + &IgnoredPtr, + (UINTN *)&FvFileInfo->FileInfo.FileSize, + &AuthenticationStatus + ); + if (Status == EFI_WARN_BUFFER_TOO_SMALL) { + return EFI_SUCCESS; + } + + if (EFI_ERROR (Status)) { + // + // Didn't find a raw section, just return the whole file's size. + // + return FvProtocol->ReadFile ( + FvProtocol, + &FvFileInfo->NameGuid, + NULL, + (UINTN *)&FvFileInfo->FileInfo.FileSize, + &FoundType, + &Attributes, + &AuthenticationStatus + ); + } + } else { + // + // Get the size of the entire file + // + return FvProtocol->ReadFile ( + FvProtocol, + &FvFileInfo->NameGuid, + NULL, + (UINTN *)&FvFileInfo->FileInfo.FileSize, + &FoundType, + &Attributes, + &AuthenticationStatus + ); + } + + return Status; +} + +/** + Helper function to read a file. + + The data returned depends on the type of the underlying FV file: + - For executable types, the first section found that contains executable code is returned. + - For files of type FREEFORM, the driver attempts to return the first section of type RAW. + If none is found, the entire contents of the FV file are returned. + - On all other files the entire contents of the FV file is returned, as by + EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadFile. + + @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct + representing a file's info. + @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of + the memory represented by *Buffer. + @param Buffer Pointer to a pointer to a data buffer to contain file content. + + @retval EFI_SUCCESS The call completed successfully. + @retval EFI_WARN_BUFFER_TOO_SMALL The buffer is too small to contain the requested output. + @retval EFI_ACCESS_DENIED The firmware volume is configured to disallow reads. + @retval EFI_NOT_FOUND The requested file was not found in the firmware volume. + @retval EFI_DEVICE_ERROR A hardware error occurred when attempting toaccess the firmware volume. + +**/ +EFI_STATUS +FvFsReadFile ( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol, + IN FV_FILESYSTEM_FILE_INFO *FvFileInfo, + IN OUT UINTN *BufferSize, + IN OUT VOID **Buffer + ) +{ + UINT32 AuthenticationStatus; + EFI_FV_FILETYPE FoundType; + EFI_FV_FILE_ATTRIBUTES Attributes; + EFI_STATUS Status; + + if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) { + // + // Read the first executable section out of the file. + // + Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, BufferSize, Buffer); + } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) { + // + // Try to read a raw section out of the file + // + Status = FvProtocol->ReadSection ( + FvProtocol, + &FvFileInfo->NameGuid, + EFI_SECTION_RAW, + 0, + Buffer, + BufferSize, + &AuthenticationStatus + ); + if (EFI_ERROR (Status)) { + // + // Didn't find a raw section, just return the whole file. + // + Status = FvProtocol->ReadFile ( + FvProtocol, + &FvFileInfo->NameGuid, + Buffer, + BufferSize, + &FoundType, + &Attributes, + &AuthenticationStatus + ); + } + } else { + // + // Read the entire file + // + Status = FvProtocol->ReadFile ( + FvProtocol, + &FvFileInfo->NameGuid, + Buffer, + BufferSize, + &FoundType, + &Attributes, + &AuthenticationStatus + ); + } + + return Status; +} + +/** + Helper function for populating an EFI_FILE_INFO for a file. + + Note the CreateTime, LastAccessTime and ModificationTime fields in EFI_FILE_INFO + are full zero as FV2 protocol has no corresponding info to fill. + + @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct + representing a file's info. + @param BufferSize Pointer to a caller-allocated UINTN. It indicates the size of + the memory represented by FileInfo. + @param FileInfo A pointer to EFI_FILE_INFO to contain the returned file info. + + @retval EFI_SUCCESS The call completed successfully. + @retval EFI_BUFFER_TOO_SMALL The buffer is too small to contain the requested output. + +**/ +EFI_STATUS +FvFsGetFileInfo ( + IN FV_FILESYSTEM_FILE_INFO *FvFileInfo, + IN OUT UINTN *BufferSize, + OUT EFI_FILE_INFO *FileInfo + ) +{ + UINTN InfoSize; + + InfoSize = (UINTN)FvFileInfo->FileInfo.Size; + if (*BufferSize < InfoSize) { + *BufferSize = InfoSize; + return EFI_BUFFER_TOO_SMALL; + } + + // + // Initialize FileInfo + // + CopyMem (FileInfo, &FvFileInfo->FileInfo, InfoSize); + + *BufferSize = InfoSize; + return EFI_SUCCESS; +} + +/** + Removes the last directory or file entry in a path by changing the last + L'\' to a CHAR_NULL. + + @param Path The pointer to the path to modify. + + @retval FALSE Nothing was found to remove. + @retval TRUE A directory or file was removed. + +**/ +BOOLEAN +EFIAPI +RemoveLastItemFromPath ( + IN OUT CHAR16 *Path + ) +{ + CHAR16 *Walker; + CHAR16 *LastSlash; + + // + // get directory name from path... ('chop' off extra) + // + for ( Walker = Path, LastSlash = NULL + ; Walker != NULL && *Walker != CHAR_NULL + ; Walker++ + ) + { + if ((*Walker == L'\\') && (*(Walker + 1) != CHAR_NULL)) { + LastSlash = Walker + 1; + } + } + + if (LastSlash != NULL) { + *LastSlash = CHAR_NULL; + return (TRUE); + } + + return (FALSE); +} + +/** + Function to clean up paths. + + - Single periods in the path are removed. + - Double periods in the path are removed along with a single parent directory. + - Forward slashes L'/' are converted to backward slashes L'\'. + + This will be done inline and the existing buffer may be larger than required + upon completion. + + @param Path The pointer to the string containing the path. + + @retval NULL An error occurred. + @return Path in all other instances. + +**/ +CHAR16 * +EFIAPI +TrimFilePathToAbsolutePath ( + IN CHAR16 *Path + ) +{ + CHAR16 *TempString; + UINTN TempSize; + + if (Path == NULL) { + return NULL; + } + + // + // Fix up the '/' vs '\' + // + for (TempString = Path; (TempString != NULL) && (*TempString != CHAR_NULL); TempString++) { + if (*TempString == L'/') { + *TempString = L'\\'; + } + } + + // + // Fix up the .. + // + while ((TempString = StrStr (Path, L"\\..\\")) != NULL) { + *TempString = CHAR_NULL; + TempString += 4; + RemoveLastItemFromPath (Path); + TempSize = StrSize (TempString); + CopyMem (Path + StrLen (Path), TempString, TempSize); + } + + if (((TempString = StrStr (Path, L"\\..")) != NULL) && (*(TempString + 3) == CHAR_NULL)) { + *TempString = CHAR_NULL; + RemoveLastItemFromPath (Path); + } + + // + // Fix up the . + // + while ((TempString = StrStr (Path, L"\\.\\")) != NULL) { + *TempString = CHAR_NULL; + TempString += 2; + TempSize = StrSize (TempString); + CopyMem (Path + StrLen (Path), TempString, TempSize); + } + + if (((TempString = StrStr (Path, L"\\.")) != NULL) && (*(TempString + 2) == CHAR_NULL)) { + *(TempString + 1) = CHAR_NULL; + } + + while ((TempString = StrStr (Path, L"\\\\")) != NULL) { + *TempString = CHAR_NULL; + TempString += 1; + TempSize = StrSize (TempString); + CopyMem (Path + StrLen (Path), TempString, TempSize); + } + + if (((TempString = StrStr (Path, L"\\\\")) != NULL) && (*(TempString + 1) == CHAR_NULL)) { + *(TempString) = CHAR_NULL; + } + + return Path; +} + +/** + Opens a new file relative to the source file's location. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to the source location. This would typically be an open + handle to a directory. + @param NewHandle A pointer to the location to return the opened handle for the new + file. + @param FileName The Null-terminated string of the name of the file to be opened. + The file name may contain the following path modifiers: "\", ".", + and "..". + @param OpenMode The mode to open the file. The only valid combinations that the + file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the + attribute bits for the newly created file. + + @retval EFI_SUCCESS The file was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ) +{ + FV_FILESYSTEM_INSTANCE *Instance; + FV_FILESYSTEM_FILE *File; + FV_FILESYSTEM_FILE *NewFile; + FV_FILESYSTEM_FILE_INFO *FvFileInfo; + LIST_ENTRY *FvFileInfoLink; + EFI_STATUS Status; + UINTN FileNameLength; + UINTN NewFileNameLength; + CHAR16 *FileNameWithExtension; + + // + // Check for a valid mode + // + switch (OpenMode) { + case EFI_FILE_MODE_READ: + break; + + default: + return EFI_WRITE_PROTECTED; + } + + File = FVFS_FILE_FROM_FILE_THIS (This); + Instance = File->Instance; + + FileName = TrimFilePathToAbsolutePath (FileName); + if (FileName == NULL) { + return EFI_INVALID_PARAMETER; + } + + if (FileName[0] == L'\\') { + FileName++; + } + + // + // Check for opening root + // + if ((StrCmp (FileName, L".") == 0) || (StrCmp (FileName, L"") == 0)) { + NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE)); + if (NewFile == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewFile->Signature = FVFS_FILE_SIGNATURE; + NewFile->Instance = Instance; + NewFile->FvFileInfo = File->FvFileInfo; + CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate)); + InitializeListHead (&NewFile->Link); + InsertHeadList (&Instance->FileHead, &NewFile->Link); + + NewFile->DirReadNext = NULL; + if (!IsListEmpty (&Instance->FileInfoHead)) { + NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance); + } + + *NewHandle = &NewFile->FileProtocol; + return EFI_SUCCESS; + } + + // + // Do a linear search for a file in the FV with a matching filename + // + Status = EFI_NOT_FOUND; + FvFileInfo = NULL; + for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead); + !IsNull (&Instance->FileInfoHead, FvFileInfoLink); + FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) + { + FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink); + if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) { + Status = EFI_SUCCESS; + break; + } + } + + // If the file has not been found check if the filename exists with an extension + // in case there was no extension present. + // FvFileSystem adds a 'virtual' extension '.EFI' to EFI applications and drivers + // present in the Firmware Volume + if (Status == EFI_NOT_FOUND) { + FileNameLength = StrLen (FileName); + + // Does the filename already contain the '.EFI' extension? + if (mUnicodeCollation->StriColl (mUnicodeCollation, FileName + FileNameLength - 4, L".efi") != 0) { + // No, there was no extension. So add one and search again for the file + // NewFileNameLength = FileNameLength + 1 + 4 = (Number of non-null character) + (file extension) + (a null character) + NewFileNameLength = FileNameLength + 1 + 4; + FileNameWithExtension = AllocatePool (NewFileNameLength * 2); + StrCpyS (FileNameWithExtension, NewFileNameLength, FileName); + StrCatS (FileNameWithExtension, NewFileNameLength, L".EFI"); + + for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead); + !IsNull (&Instance->FileInfoHead, FvFileInfoLink); + FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) + { + FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink); + if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileNameWithExtension) == 0) { + Status = EFI_SUCCESS; + break; + } + } + } + } + + if (!EFI_ERROR (Status)) { + NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE)); + if (NewFile == NULL) { + return EFI_OUT_OF_RESOURCES; + } + + NewFile->Signature = FVFS_FILE_SIGNATURE; + NewFile->Instance = Instance; + NewFile->FvFileInfo = FvFileInfo; + CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate)); + InitializeListHead (&NewFile->Link); + InsertHeadList (&Instance->FileHead, &NewFile->Link); + + *NewHandle = &NewFile->FileProtocol; + return EFI_SUCCESS; + } + + return EFI_NOT_FOUND; +} + +/** + Closes a specified file handle. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to close. + + @retval EFI_SUCCESS The file was closed. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemClose ( + IN EFI_FILE_PROTOCOL *This + ) +{ + FV_FILESYSTEM_INSTANCE *Instance; + FV_FILESYSTEM_FILE *File; + + File = FVFS_FILE_FROM_FILE_THIS (This); + Instance = File->Instance; + + if (File != Instance->Root) { + RemoveEntryList (&File->Link); + FreePool (File); + } + + return EFI_SUCCESS; +} + +/** + Reads data from a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to read data from. + @param BufferSize On input, the size of the Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param Buffer The buffer into which the data is read. + + @retval EFI_SUCCESS Data was read. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. + @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory + entry. BufferSize has been updated with the size + needed to complete the request. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + FV_FILESYSTEM_INSTANCE *Instance; + FV_FILESYSTEM_FILE *File; + EFI_STATUS Status; + LIST_ENTRY *FvFileInfoLink; + VOID *FileBuffer; + UINTN FileSize; + + File = FVFS_FILE_FROM_FILE_THIS (This); + Instance = File->Instance; + + if (File->FvFileInfo == Instance->Root->FvFileInfo) { + if (File->DirReadNext) { + // + // Directory read: populate Buffer with an EFI_FILE_INFO + // + Status = FvFsGetFileInfo (File->DirReadNext, BufferSize, Buffer); + if (!EFI_ERROR (Status)) { + // + // Successfully read a directory entry, now update the pointer to the + // next file, which will be read on the next call to this function + // + FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, &File->DirReadNext->Link); + if (IsNull (&Instance->FileInfoHead, FvFileInfoLink)) { + // + // No more files left + // + File->DirReadNext = NULL; + } else { + File->DirReadNext = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink); + } + } + + return Status; + } else { + // + // Directory read. All entries have been read, so return a zero-size + // buffer. + // + *BufferSize = 0; + return EFI_SUCCESS; + } + } else { + FileSize = (UINTN)File->FvFileInfo->FileInfo.FileSize; + + FileBuffer = AllocateZeroPool (FileSize); + if (FileBuffer == NULL) { + return EFI_DEVICE_ERROR; + } + + Status = FvFsReadFile (File->Instance->FvProtocol, File->FvFileInfo, &FileSize, &FileBuffer); + if (EFI_ERROR (Status)) { + FreePool (FileBuffer); + return EFI_DEVICE_ERROR; + } + + if (*BufferSize + File->Position > FileSize) { + *BufferSize = (UINTN)(FileSize - File->Position); + } + + CopyMem (Buffer, (UINT8 *)FileBuffer + File->Position, *BufferSize); + File->Position += *BufferSize; + + FreePool (FileBuffer); + + return EFI_SUCCESS; + } +} + +/** + Writes data to a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to write data to. + @param BufferSize On input, the size of the Buffer. On output, the amount of data + actually written. In both cases, the size is measured in bytes. + @param Buffer The buffer of data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to open directory files are not supported. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ) +{ + FV_FILESYSTEM_INSTANCE *Instance; + FV_FILESYSTEM_FILE *File; + + File = FVFS_FILE_FROM_FILE_THIS (This); + Instance = File->Instance; + + if (File->FvFileInfo == Instance->Root->FvFileInfo) { + return EFI_UNSUPPORTED; + } else { + return EFI_WRITE_PROTECTED; + } +} + +/** + Returns a file's current position. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to get the current position on. + @param Position The address to return the file's current position value. + + @retval EFI_SUCCESS The position was returned. + @retval EFI_UNSUPPORTED The request is not valid on open directories. + @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ) +{ + FV_FILESYSTEM_INSTANCE *Instance; + FV_FILESYSTEM_FILE *File; + + File = FVFS_FILE_FROM_FILE_THIS (This); + Instance = File->Instance; + + if (File->FvFileInfo == Instance->Root->FvFileInfo) { + return EFI_UNSUPPORTED; + } else { + *Position = File->Position; + return EFI_SUCCESS; + } +} + +/** + Sets a file's current position. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the + file handle to set the requested position on. + @param Position The byte position from the start of the file to set. + + @retval EFI_SUCCESS The position was set. + @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open + directories. + @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ) +{ + FV_FILESYSTEM_INSTANCE *Instance; + FV_FILESYSTEM_FILE *File; + + File = FVFS_FILE_FROM_FILE_THIS (This); + Instance = File->Instance; + + if (File->FvFileInfo == Instance->Root->FvFileInfo) { + if (Position != 0) { + return EFI_UNSUPPORTED; + } + + // + // Reset directory position to first entry + // + if (File->DirReadNext) { + File->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance); + } + } else if (Position == 0xFFFFFFFFFFFFFFFFull) { + File->Position = File->FvFileInfo->FileInfo.FileSize; + } else { + File->Position = Position; + } + + return EFI_SUCCESS; +} + +/** + Flushes all modified data associated with a file to a device. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to flush. + + @retval EFI_SUCCESS The data was flushed. + @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_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read-only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemFlush ( + IN EFI_FILE_PROTOCOL *This + ) +{ + return EFI_WRITE_PROTECTED; +} + +/** + Close and delete the file handle. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the + handle to the file to delete. + + @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed. + @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemDelete ( + IN EFI_FILE_PROTOCOL *This + ) +{ + EFI_STATUS Status; + + Status = FvSimpleFileSystemClose (This); + ASSERT_EFI_ERROR (Status); + + return EFI_WARN_DELETE_FAILURE; +} + +/** + Returns information about a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the requested information is for. + @param InformationType The type identifier for the information being requested. + @param BufferSize On input, the size of Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param Buffer A pointer to the data buffer to return. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was returned. + @retval EFI_UNSUPPORTED The InformationType is not known. + @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_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. + BufferSize has been updated with the size needed to complete + the request. +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ) +{ + FV_FILESYSTEM_FILE *File; + EFI_FILE_SYSTEM_INFO *FsInfoOut; + EFI_FILE_SYSTEM_VOLUME_LABEL *FsVolumeLabel; + FV_FILESYSTEM_INSTANCE *Instance; + UINTN Size; + EFI_STATUS Status; + + File = FVFS_FILE_FROM_FILE_THIS (This); + + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) { + // + // Return filesystem info + // + Instance = File->Instance; + + Size = sizeof (EFI_FILE_SYSTEM_INFO) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16); + + if (*BufferSize < Size) { + *BufferSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + // + // Cast output buffer for convenience + // + FsInfoOut = (EFI_FILE_SYSTEM_INFO *)Buffer; + + CopyMem (FsInfoOut, &mFsInfoTemplate, sizeof (EFI_FILE_SYSTEM_INFO)); + Status = StrnCpyS ( + FsInfoOut->VolumeLabel, + (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16), + Instance->VolumeLabel, + StrLen (Instance->VolumeLabel) + ); + ASSERT_EFI_ERROR (Status); + FsInfoOut->Size = Size; + return Status; + } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) { + // + // Return file info + // + return FvFsGetFileInfo (File->FvFileInfo, BufferSize, (EFI_FILE_INFO *)Buffer); + } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) { + // + // Return Volume Label + // + Instance = File->Instance; + Size = sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16); + if (*BufferSize < Size) { + *BufferSize = Size; + return EFI_BUFFER_TOO_SMALL; + } + + FsVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL *)Buffer; + Status = StrnCpyS ( + FsVolumeLabel->VolumeLabel, + (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel)) / sizeof (CHAR16), + Instance->VolumeLabel, + StrLen (Instance->VolumeLabel) + ); + ASSERT_EFI_ERROR (Status); + return Status; + } else { + return EFI_UNSUPPORTED; + } +} + +/** + Sets information about a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the information is for. + @param InformationType The type identifier for the information being set. + @param BufferSize The size, in bytes, of Buffer. + @param Buffer A pointer to the data buffer to write. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + @retval EFI_UNSUPPORTED The InformationType is not known. + @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_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media is + read-only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID + and the media is read only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID + and the media is read-only. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a + file that is already present. + @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY + Attribute. + @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory. + @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened + read-only and an attempt is being made to modify a field + other than Attribute. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated + by InformationType. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ) +{ + if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) || + CompareGuid (InformationType, &gEfiFileInfoGuid) || + CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) + { + return EFI_WRITE_PROTECTED; + } + + return EFI_UNSUPPORTED; +} diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni index ed148b8b11..fa1a87910e 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni @@ -1,16 +1,16 @@ -// /** @file
-// Module that lays Simple File System protocol on every FirmwareVolume2 protocol.
-//
-// This module produces Simple File System protocol to provide the accesses to the files in FVs.
-//
-// Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-
-#string STR_MODULE_ABSTRACT #language en-US "Lays Simple File System protocol on every FirmwareVolume2 protocol"
-
-#string STR_MODULE_DESCRIPTION #language en-US "This module produces Simple File System protocol to provide the accesses to the files in FVs."
-
+// /** @file +// Module that lays Simple File System protocol on every FirmwareVolume2 protocol. +// +// This module produces Simple File System protocol to provide the accesses to the files in FVs. +// +// Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + + +#string STR_MODULE_ABSTRACT #language en-US "Lays Simple File System protocol on every FirmwareVolume2 protocol" + +#string STR_MODULE_DESCRIPTION #language en-US "This module produces Simple File System protocol to provide the accesses to the files in FVs." + diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf index 03797847d9..604b2448fe 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf @@ -1,68 +1,68 @@ -## @file
-# Support for Simple File System over Firmware Volume.
-#
-# 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 Ltd. All rights reserved.<BR>
-# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
-#
-# SPDX-License-Identifier: BSD-2-Clause-Patent
-#
-##
-
-[Defines]
- INF_VERSION = 0x00010005
- BASE_NAME = FvSimpleFileSystem
- MODULE_UNI_FILE = FvSimpleFileSystem.uni
- FILE_GUID = 907125c0-a5f1-11e3-a3fe-a3198b49350c
- MODULE_TYPE = UEFI_DRIVER
- VERSION_STRING = 1.0
- ENTRY_POINT = FvSimpleFileSystemEntryPoint
-
-[Sources]
-
- ComponentName.c
- FvSimpleFileSystem.c
- FvSimpleFileSystemEntryPoint.c
- FvSimpleFileSystemInternal.h
-
-[Packages]
- MdePkg/MdePkg.dec
- MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
- BaseLib
- DevicePathLib
- MemoryAllocationLib
- PrintLib
- UefiDriverEntryPoint
- UefiLib
-
-[Pcd]
- gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang ## SOMETIMES_CONSUMES
- gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang ## SOMETIMES_CONSUMES
-
-[Guids]
- gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED
- gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED
- gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## UNDEFINED
-
-[Protocols]
- gEfiDevicePathProtocolGuid ## TO_START
- gEfiFirmwareVolume2ProtocolGuid ## TO_START
- gEfiUnicodeCollationProtocolGuid ## TO_START
- gEfiUnicodeCollation2ProtocolGuid ## TO_START
- gEfiSimpleFileSystemProtocolGuid ## BY_START
-
-[UserExtensions.TianoCore."ExtraFiles"]
- FvSimpleFileSystemExtra.uni
+## @file +# Support for Simple File System over Firmware Volume. +# +# 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 Ltd. All rights reserved.<BR> +# Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR> +# +# SPDX-License-Identifier: BSD-2-Clause-Patent +# +## + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = FvSimpleFileSystem + MODULE_UNI_FILE = FvSimpleFileSystem.uni + FILE_GUID = 907125c0-a5f1-11e3-a3fe-a3198b49350c + MODULE_TYPE = UEFI_DRIVER + VERSION_STRING = 1.0 + ENTRY_POINT = FvSimpleFileSystemEntryPoint + +[Sources] + + ComponentName.c + FvSimpleFileSystem.c + FvSimpleFileSystemEntryPoint.c + FvSimpleFileSystemInternal.h + +[Packages] + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec + +[LibraryClasses] + BaseLib + DevicePathLib + MemoryAllocationLib + PrintLib + UefiDriverEntryPoint + UefiLib + +[Pcd] + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang ## SOMETIMES_CONSUMES + gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang ## SOMETIMES_CONSUMES + +[Guids] + gEfiFileInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED + gEfiFileSystemInfoGuid ## SOMETIMES_CONSUMES ## UNDEFINED + gEfiFileSystemVolumeLabelInfoIdGuid ## SOMETIMES_CONSUMES ## UNDEFINED + +[Protocols] + gEfiDevicePathProtocolGuid ## TO_START + gEfiFirmwareVolume2ProtocolGuid ## TO_START + gEfiUnicodeCollationProtocolGuid ## TO_START + gEfiUnicodeCollation2ProtocolGuid ## TO_START + gEfiSimpleFileSystemProtocolGuid ## BY_START + +[UserExtensions.TianoCore."ExtraFiles"] + FvSimpleFileSystemExtra.uni diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c index 3f96407dc7..7479cc25ab 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c @@ -1,680 +1,680 @@ -/** @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>
-
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#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 = NULL;
- if (!IsListEmpty (&Instance->FileInfoHead)) {
- 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;
-}
+/** @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> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#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 = NULL; + if (!IsListEmpty (&Instance->FileInfoHead)) { + 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; +} diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni index 48d2b64b4d..d60b3cff06 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni @@ -1,14 +1,14 @@ -// /** @file
-// FvSimpleFileSystem Driver's Localized Strings and Content
-//
-// Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
-//
-// SPDX-License-Identifier: BSD-2-Clause-Patent
-//
-// **/
-
-#string STR_PROPERTIES_MODULE_NAME
-#language en-US
-"FvSimpleFileSystem UEFI Driver"
-
-
+// /** @file +// FvSimpleFileSystem Driver's Localized Strings and Content +// +// Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR> +// +// SPDX-License-Identifier: BSD-2-Clause-Patent +// +// **/ + +#string STR_PROPERTIES_MODULE_NAME +#language en-US +"FvSimpleFileSystem UEFI Driver" + + diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h index fea03b2ce8..837e052d82 100644 --- a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h +++ b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h @@ -1,615 +1,615 @@ -/** @file
- The internal header file of FvSimpleFileSystem driver.
-
-Copyright (c) 2014, ARM Limited. All rights reserved.
-Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR>
-
-SPDX-License-Identifier: BSD-2-Clause-Patent
-
-**/
-
-#ifndef __FVFS_INTERNAL_H__
-#define __FVFS_INTERNAL_H__
-
-#include <Uefi.h>
-#include <PiDxe.h>
-
-#include <Library/BaseLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/DebugLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/PrintLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/UefiLib.h>
-
-#include <Protocol/DriverBinding.h>
-#include <Protocol/FirmwareVolume2.h>
-#include <Protocol/SimpleFileSystem.h>
-#include <Protocol/UnicodeCollation.h>
-
-#include <Guid/FileSystemInfo.h>
-#include <Guid/FileInfo.h>
-#include <Guid/FileSystemVolumeLabelInfo.h>
-
-typedef struct _FV_FILESYSTEM_FILE FV_FILESYSTEM_FILE;
-typedef struct _FV_FILESYSTEM_FILE_INFO FV_FILESYSTEM_FILE_INFO;
-typedef struct _FV_FILESYSTEM_INSTANCE FV_FILESYSTEM_INSTANCE;
-
-//
-// Struct representing an instance of the "filesystem". There will be one of
-// these structs per FV.
-//
-struct _FV_FILESYSTEM_INSTANCE {
- UINT32 Signature;
- LIST_ENTRY FileInfoHead;
- LIST_ENTRY FileHead;
- EFI_DRIVER_BINDING_PROTOCOL *DriverBinding;
- EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol;
- EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs;
- FV_FILESYSTEM_FILE *Root;
- CHAR16 *VolumeLabel;
-};
-
-//
-// Struct representing a opening file. Each opening operation on file will
-// create such an instance except for the "root directory", which will only
-// be created once for each FV.
-//
-struct _FV_FILESYSTEM_FILE {
- UINT32 Signature;
- LIST_ENTRY Link;
- FV_FILESYSTEM_FILE_INFO *DirReadNext;
- FV_FILESYSTEM_INSTANCE *Instance;
- EFI_FILE_PROTOCOL FileProtocol;
- FV_FILESYSTEM_FILE_INFO *FvFileInfo;
- UINT64 Position;
-};
-
-//
-// Struct representing the info of a file.
-//
-struct _FV_FILESYSTEM_FILE_INFO {
- UINT32 Signature;
- LIST_ENTRY Link;
- EFI_GUID NameGuid;
- EFI_FV_FILETYPE Type;
- EFI_FILE_INFO FileInfo;
-};
-
-#define FVFS_FILE_SIGNATURE SIGNATURE_32 ('f', 'v', 'f', 'i')
-#define FVFS_FILE_INFO_SIGNATURE SIGNATURE_32 ('f', 'v', 'i', 'n')
-#define FVFS_INSTANCE_SIGNATURE SIGNATURE_32 ('f', 'v', 'f', 's')
-
-#define FVFS_INSTANCE_FROM_SIMPLE_FS_THIS(This) CR ( \
- This, \
- FV_FILESYSTEM_INSTANCE, \
- SimpleFs, \
- FVFS_INSTANCE_SIGNATURE \
- )
-
-#define FVFS_FILE_FROM_FILE_THIS(This) CR ( \
- This, \
- FV_FILESYSTEM_FILE, \
- FileProtocol, \
- FVFS_FILE_SIGNATURE \
- )
-
-#define FVFS_FILE_INFO_FROM_LINK(This) CR ( \
- This, \
- FV_FILESYSTEM_FILE_INFO, \
- Link, \
- FVFS_FILE_INFO_SIGNATURE \
- )
-
-#define FVFS_FILE_FROM_LINK(FileLink) CR (FileLink, FV_FILESYSTEM_FILE, Link, FVFS_FILE_SIGNATURE)
-
-#define FVFS_GET_FIRST_FILE(Instance) FVFS_FILE_FROM_LINK (GetFirstNode (&Instance->FileHead))
-
-#define FVFS_GET_FIRST_FILE_INFO(Instance) FVFS_FILE_INFO_FROM_LINK (GetFirstNode (&Instance->FileInfoHead))
-
-#define FV_FILETYPE_IS_EXECUTABLE(Type) ((Type) == EFI_FV_FILETYPE_PEIM ||\
- (Type) == EFI_FV_FILETYPE_DRIVER || \
- (Type) == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER || \
- (Type) == EFI_FV_FILETYPE_APPLICATION)
-
-/**
- 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
- );
-
-/**
- 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
- );
-
-/**
- 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
- );
-
-/**
- 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
- );
-
-/**
- Opens a new file relative to the source file's location.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to the source location. This would typically be an open
- handle to a directory.
- @param NewHandle A pointer to the location to return the opened handle for the new
- file.
- @param FileName The Null-terminated string of the name of the file to be opened.
- The file name may contain the following path modifiers: "\", ".",
- and "..".
- @param OpenMode The mode to open the file. The only valid combinations that the
- file may be opened with are: Read, Read/Write, or Create/Read/Write.
- @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the
- attribute bits for the newly created file.
-
- @retval EFI_SUCCESS The file was opened.
- @retval EFI_NOT_FOUND The specified file could not be found on the device.
- @retval EFI_NO_MEDIA The device has no medium.
- @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no
- longer supported.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
- @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write
- when the media is write-protected.
- @retval EFI_ACCESS_DENIED The service denied access to the file.
- @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.
- @retval EFI_VOLUME_FULL The volume is full.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemOpen (
- IN EFI_FILE_PROTOCOL *This,
- OUT EFI_FILE_PROTOCOL **NewHandle,
- IN CHAR16 *FileName,
- IN UINT64 OpenMode,
- IN UINT64 Attributes
- );
-
-/**
- Closes a specified file handle.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to close.
-
- @retval EFI_SUCCESS The file was closed.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemClose (
- IN EFI_FILE_PROTOCOL *This
- );
-
-/**
- Reads data from a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to read data from.
- @param BufferSize On input, the size of the Buffer. On output, the amount of data
- returned in Buffer. In both cases, the size is measured in bytes.
- @param Buffer The buffer into which the data is read.
-
- @retval EFI_SUCCESS Data was read.
- @retval EFI_NO_MEDIA The device has no medium.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file.
- @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file.
- @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
- @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory
- entry. BufferSize has been updated with the size
- needed to complete the request.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemRead (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- );
-
-/**
- Writes data to a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to write data to.
- @param BufferSize On input, the size of the Buffer. On output, the amount of data
- actually written. In both cases, the size is measured in bytes.
- @param Buffer The buffer of data to write.
-
- @retval EFI_SUCCESS Data was written.
- @retval EFI_UNSUPPORTED Writes to open directory files are not supported.
- @retval EFI_NO_MEDIA The device has no medium.
- @retval EFI_DEVICE_ERROR The device reported an error.
- @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file.
- @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
- @retval EFI_WRITE_PROTECTED The file or medium is write-protected.
- @retval EFI_ACCESS_DENIED The file was opened read only.
- @retval EFI_VOLUME_FULL The volume is full.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemWrite (
- IN EFI_FILE_PROTOCOL *This,
- IN OUT UINTN *BufferSize,
- IN VOID *Buffer
- );
-
-/**
- Returns a file's current position.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to get the current position on.
- @param Position The address to return the file's current position value.
-
- @retval EFI_SUCCESS The position was returned.
- @retval EFI_UNSUPPORTED The request is not valid on open directories.
- @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemGetPosition (
- IN EFI_FILE_PROTOCOL *This,
- OUT UINT64 *Position
- );
-
-/**
- Sets a file's current position.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
- file handle to set the requested position on.
- @param Position The byte position from the start of the file to set.
-
- @retval EFI_SUCCESS The position was set.
- @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open
- directories.
- @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemSetPosition (
- IN EFI_FILE_PROTOCOL *This,
- IN UINT64 Position
- );
-
-/**
- Flushes all modified data associated with a file to a device.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle to flush.
-
- @retval EFI_SUCCESS The data was flushed.
- @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_WRITE_PROTECTED The file or medium is write-protected.
- @retval EFI_ACCESS_DENIED The file was opened read-only.
- @retval EFI_VOLUME_FULL The volume is full.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemFlush (
- IN EFI_FILE_PROTOCOL *This
- );
-
-/**
- Close and delete the file handle.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the
- handle to the file to delete.
-
- @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed.
- @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemDelete (
- IN EFI_FILE_PROTOCOL *This
- );
-
-/**
- Returns information about a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle the requested information is for.
- @param InformationType The type identifier for the information being requested.
- @param BufferSize On input, the size of Buffer. On output, the amount of data
- returned in Buffer. In both cases, the size is measured in bytes.
- @param Buffer A pointer to the data buffer to return. The buffer's type is
- indicated by InformationType.
-
- @retval EFI_SUCCESS The information was returned.
- @retval EFI_UNSUPPORTED The InformationType is not known.
- @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_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.
- BufferSize has been updated with the size needed to complete
- the request.
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemGetInfo (
- IN EFI_FILE_PROTOCOL *This,
- IN EFI_GUID *InformationType,
- IN OUT UINTN *BufferSize,
- OUT VOID *Buffer
- );
-
-/**
- Sets information about a file.
-
- @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file
- handle the information is for.
- @param InformationType The type identifier for the information being set.
- @param BufferSize The size, in bytes, of Buffer.
- @param Buffer A pointer to the data buffer to write. The buffer's type is
- indicated by InformationType.
-
- @retval EFI_SUCCESS The information was set.
- @retval EFI_UNSUPPORTED The InformationType is not known.
- @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_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media is
- read-only.
- @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID
- and the media is read only.
- @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID
- and the media is read-only.
- @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a
- file that is already present.
- @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY
- Attribute.
- @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory.
- @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened
- read-only and an attempt is being made to modify a field
- other than Attribute.
- @retval EFI_VOLUME_FULL The volume is full.
- @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated
- by InformationType.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemSetInfo (
- IN EFI_FILE_PROTOCOL *This,
- IN EFI_GUID *InformationType,
- IN UINTN BufferSize,
- IN VOID *Buffer
- );
-
-/**
- Get the size of the buffer that will be returned by FvFsReadFile.
-
- @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.
- @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct
- representing a file's info.
-
- @retval EFI_SUCCESS The file size was gotten correctly.
- @retval Others The file size wasn't gotten correctly.
-
-**/
-EFI_STATUS
-FvFsGetFileSize (
- IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol,
- IN OUT FV_FILESYSTEM_FILE_INFO *FvFileInfo
- );
-
-/**
- Retrieves a Unicode string that is the user readable name of the driver.
-
- This function retrieves the user readable name of a driver in the form of a
- Unicode string. If the driver specified by This has a user readable name in
- the language specified by Language, then a pointer to the driver name is
- returned in DriverName, and EFI_SUCCESS is returned. If the driver specified
- by This does not support the language specified by Language,
- then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified
- in RFC 4646 or ISO 639-2 language code format.
-
- @param DriverName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- driver specified by This in the language
- specified by Language.
-
- @retval EFI_SUCCESS The Unicode string for the Driver specified by
- This and the language specified by Language was
- returned in DriverName.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER DriverName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemComponentNameGetDriverName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN CHAR8 *Language,
- OUT CHAR16 **DriverName
- );
-
-/**
- Retrieves a Unicode string that is the user readable name of the controller
- that is being managed by a driver.
-
- This function retrieves the user readable name of the controller specified by
- ControllerHandle and ChildHandle in the form of a Unicode string. If the
- driver specified by This has a user readable name in the language specified by
- Language, then a pointer to the controller name is returned in ControllerName,
- and EFI_SUCCESS is returned. If the driver specified by This is not currently
- managing the controller specified by ControllerHandle and ChildHandle,
- then EFI_UNSUPPORTED is returned. If the driver specified by This does not
- support the language specified by Language, then EFI_UNSUPPORTED is returned.
-
- @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or
- EFI_COMPONENT_NAME_PROTOCOL instance.
-
- @param ControllerHandle[in] The handle of a controller that the driver
- specified by This is managing. This handle
- specifies the controller whose name is to be
- returned.
-
- @param ChildHandle[in] The handle of the child controller to retrieve
- the name of. This is an optional parameter that
- may be NULL. It will be NULL for device
- drivers. It will also be NULL for a bus drivers
- that wish to retrieve the name of the bus
- controller. It will not be NULL for a bus
- driver that wishes to retrieve the name of a
- child controller.
-
- @param Language[in] A pointer to a Null-terminated ASCII string
- array indicating the language. This is the
- language of the driver name that the caller is
- requesting, and it must match one of the
- languages specified in SupportedLanguages. The
- number of languages supported by a driver is up
- to the driver writer. Language is specified in
- RFC 4646 or ISO 639-2 language code format.
-
- @param ControllerName[out] A pointer to the Unicode string to return.
- This Unicode string is the name of the
- controller specified by ControllerHandle and
- ChildHandle in the language specified by
- Language from the point of view of the driver
- specified by This.
-
- @retval EFI_SUCCESS The Unicode string for the user readable name in
- the language specified by Language for the
- driver specified by This was returned in
- DriverName.
-
- @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.
-
- @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid
- EFI_HANDLE.
-
- @retval EFI_INVALID_PARAMETER Language is NULL.
-
- @retval EFI_INVALID_PARAMETER ControllerName is NULL.
-
- @retval EFI_UNSUPPORTED The driver specified by This is not currently
- managing the controller specified by
- ControllerHandle and ChildHandle.
-
- @retval EFI_UNSUPPORTED The driver specified by This does not support
- the language specified by Language.
-
-**/
-EFI_STATUS
-EFIAPI
-FvSimpleFileSystemComponentNameGetControllerName (
- IN EFI_COMPONENT_NAME_PROTOCOL *This,
- IN EFI_HANDLE ControllerHandle,
- IN EFI_HANDLE ChildHandle OPTIONAL,
- IN CHAR8 *Language,
- OUT CHAR16 **ControllerName
- );
-
-extern EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation;
-extern EFI_FILE_PROTOCOL mFileSystemTemplate;
-extern EFI_COMPONENT_NAME_PROTOCOL gFvSimpleFileSystemComponentName;
-extern EFI_COMPONENT_NAME2_PROTOCOL gFvSimpleFileSystemComponentName2;
-
-#endif
+/** @file + The internal header file of FvSimpleFileSystem driver. + +Copyright (c) 2014, ARM Limited. All rights reserved. +Copyright (c) 2014 - 2018, Intel Corporation. All rights reserved.<BR> + +SPDX-License-Identifier: BSD-2-Clause-Patent + +**/ + +#ifndef __FVFS_INTERNAL_H__ +#define __FVFS_INTERNAL_H__ + +#include <Uefi.h> +#include <PiDxe.h> + +#include <Library/BaseLib.h> +#include <Library/BaseMemoryLib.h> +#include <Library/DebugLib.h> +#include <Library/DevicePathLib.h> +#include <Library/MemoryAllocationLib.h> +#include <Library/PrintLib.h> +#include <Library/UefiBootServicesTableLib.h> +#include <Library/UefiLib.h> + +#include <Protocol/DriverBinding.h> +#include <Protocol/FirmwareVolume2.h> +#include <Protocol/SimpleFileSystem.h> +#include <Protocol/UnicodeCollation.h> + +#include <Guid/FileSystemInfo.h> +#include <Guid/FileInfo.h> +#include <Guid/FileSystemVolumeLabelInfo.h> + +typedef struct _FV_FILESYSTEM_FILE FV_FILESYSTEM_FILE; +typedef struct _FV_FILESYSTEM_FILE_INFO FV_FILESYSTEM_FILE_INFO; +typedef struct _FV_FILESYSTEM_INSTANCE FV_FILESYSTEM_INSTANCE; + +// +// Struct representing an instance of the "filesystem". There will be one of +// these structs per FV. +// +struct _FV_FILESYSTEM_INSTANCE { + UINT32 Signature; + LIST_ENTRY FileInfoHead; + LIST_ENTRY FileHead; + EFI_DRIVER_BINDING_PROTOCOL *DriverBinding; + EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol; + EFI_SIMPLE_FILE_SYSTEM_PROTOCOL SimpleFs; + FV_FILESYSTEM_FILE *Root; + CHAR16 *VolumeLabel; +}; + +// +// Struct representing a opening file. Each opening operation on file will +// create such an instance except for the "root directory", which will only +// be created once for each FV. +// +struct _FV_FILESYSTEM_FILE { + UINT32 Signature; + LIST_ENTRY Link; + FV_FILESYSTEM_FILE_INFO *DirReadNext; + FV_FILESYSTEM_INSTANCE *Instance; + EFI_FILE_PROTOCOL FileProtocol; + FV_FILESYSTEM_FILE_INFO *FvFileInfo; + UINT64 Position; +}; + +// +// Struct representing the info of a file. +// +struct _FV_FILESYSTEM_FILE_INFO { + UINT32 Signature; + LIST_ENTRY Link; + EFI_GUID NameGuid; + EFI_FV_FILETYPE Type; + EFI_FILE_INFO FileInfo; +}; + +#define FVFS_FILE_SIGNATURE SIGNATURE_32 ('f', 'v', 'f', 'i') +#define FVFS_FILE_INFO_SIGNATURE SIGNATURE_32 ('f', 'v', 'i', 'n') +#define FVFS_INSTANCE_SIGNATURE SIGNATURE_32 ('f', 'v', 'f', 's') + +#define FVFS_INSTANCE_FROM_SIMPLE_FS_THIS(This) CR ( \ + This, \ + FV_FILESYSTEM_INSTANCE, \ + SimpleFs, \ + FVFS_INSTANCE_SIGNATURE \ + ) + +#define FVFS_FILE_FROM_FILE_THIS(This) CR ( \ + This, \ + FV_FILESYSTEM_FILE, \ + FileProtocol, \ + FVFS_FILE_SIGNATURE \ + ) + +#define FVFS_FILE_INFO_FROM_LINK(This) CR ( \ + This, \ + FV_FILESYSTEM_FILE_INFO, \ + Link, \ + FVFS_FILE_INFO_SIGNATURE \ + ) + +#define FVFS_FILE_FROM_LINK(FileLink) CR (FileLink, FV_FILESYSTEM_FILE, Link, FVFS_FILE_SIGNATURE) + +#define FVFS_GET_FIRST_FILE(Instance) FVFS_FILE_FROM_LINK (GetFirstNode (&Instance->FileHead)) + +#define FVFS_GET_FIRST_FILE_INFO(Instance) FVFS_FILE_INFO_FROM_LINK (GetFirstNode (&Instance->FileInfoHead)) + +#define FV_FILETYPE_IS_EXECUTABLE(Type) ((Type) == EFI_FV_FILETYPE_PEIM ||\ + (Type) == EFI_FV_FILETYPE_DRIVER || \ + (Type) == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER || \ + (Type) == EFI_FV_FILETYPE_APPLICATION) + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + 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 + ); + +/** + Opens a new file relative to the source file's location. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to the source location. This would typically be an open + handle to a directory. + @param NewHandle A pointer to the location to return the opened handle for the new + file. + @param FileName The Null-terminated string of the name of the file to be opened. + The file name may contain the following path modifiers: "\", ".", + and "..". + @param OpenMode The mode to open the file. The only valid combinations that the + file may be opened with are: Read, Read/Write, or Create/Read/Write. + @param Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the + attribute bits for the newly created file. + + @retval EFI_SUCCESS The file was opened. + @retval EFI_NOT_FOUND The specified file could not be found on the device. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_MEDIA_CHANGED The device has a different medium in it or the medium is no + longer supported. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED An attempt was made to create a file, or open a file for write + when the media is write-protected. + @retval EFI_ACCESS_DENIED The service denied access to the file. + @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemOpen ( + IN EFI_FILE_PROTOCOL *This, + OUT EFI_FILE_PROTOCOL **NewHandle, + IN CHAR16 *FileName, + IN UINT64 OpenMode, + IN UINT64 Attributes + ); + +/** + Closes a specified file handle. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to close. + + @retval EFI_SUCCESS The file was closed. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemClose ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Reads data from a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to read data from. + @param BufferSize On input, the size of the Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param Buffer The buffer into which the data is read. + + @retval EFI_SUCCESS Data was read. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to read from a deleted file. + @retval EFI_DEVICE_ERROR On entry, the current file position is beyond the end of the file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory + entry. BufferSize has been updated with the size + needed to complete the request. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemRead ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Writes data to a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to write data to. + @param BufferSize On input, the size of the Buffer. On output, the amount of data + actually written. In both cases, the size is measured in bytes. + @param Buffer The buffer of data to write. + + @retval EFI_SUCCESS Data was written. + @retval EFI_UNSUPPORTED Writes to open directory files are not supported. + @retval EFI_NO_MEDIA The device has no medium. + @retval EFI_DEVICE_ERROR The device reported an error. + @retval EFI_DEVICE_ERROR An attempt was made to write to a deleted file. + @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted. + @retval EFI_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemWrite ( + IN EFI_FILE_PROTOCOL *This, + IN OUT UINTN *BufferSize, + IN VOID *Buffer + ); + +/** + Returns a file's current position. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to get the current position on. + @param Position The address to return the file's current position value. + + @retval EFI_SUCCESS The position was returned. + @retval EFI_UNSUPPORTED The request is not valid on open directories. + @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemGetPosition ( + IN EFI_FILE_PROTOCOL *This, + OUT UINT64 *Position + ); + +/** + Sets a file's current position. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the + file handle to set the requested position on. + @param Position The byte position from the start of the file to set. + + @retval EFI_SUCCESS The position was set. + @retval EFI_UNSUPPORTED The seek request for nonzero is not valid on open + directories. + @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemSetPosition ( + IN EFI_FILE_PROTOCOL *This, + IN UINT64 Position + ); + +/** + Flushes all modified data associated with a file to a device. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle to flush. + + @retval EFI_SUCCESS The data was flushed. + @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_WRITE_PROTECTED The file or medium is write-protected. + @retval EFI_ACCESS_DENIED The file was opened read-only. + @retval EFI_VOLUME_FULL The volume is full. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemFlush ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Close and delete the file handle. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the + handle to the file to delete. + + @retval EFI_SUCCESS The file was closed and deleted, and the handle was closed. + @retval EFI_WARN_DELETE_FAILURE The handle was closed, but the file was not deleted. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemDelete ( + IN EFI_FILE_PROTOCOL *This + ); + +/** + Returns information about a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the requested information is for. + @param InformationType The type identifier for the information being requested. + @param BufferSize On input, the size of Buffer. On output, the amount of data + returned in Buffer. In both cases, the size is measured in bytes. + @param Buffer A pointer to the data buffer to return. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was returned. + @retval EFI_UNSUPPORTED The InformationType is not known. + @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_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry. + BufferSize has been updated with the size needed to complete + the request. +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemGetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN OUT UINTN *BufferSize, + OUT VOID *Buffer + ); + +/** + Sets information about a file. + + @param This A pointer to the EFI_FILE_PROTOCOL instance that is the file + handle the information is for. + @param InformationType The type identifier for the information being set. + @param BufferSize The size, in bytes, of Buffer. + @param Buffer A pointer to the data buffer to write. The buffer's type is + indicated by InformationType. + + @retval EFI_SUCCESS The information was set. + @retval EFI_UNSUPPORTED The InformationType is not known. + @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_WRITE_PROTECTED InformationType is EFI_FILE_INFO_ID and the media is + read-only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID + and the media is read only. + @retval EFI_WRITE_PROTECTED InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID + and the media is read-only. + @retval EFI_ACCESS_DENIED An attempt is made to change the name of a file to a + file that is already present. + @retval EFI_ACCESS_DENIED An attempt is being made to change the EFI_FILE_DIRECTORY + Attribute. + @retval EFI_ACCESS_DENIED An attempt is being made to change the size of a directory. + @retval EFI_ACCESS_DENIED InformationType is EFI_FILE_INFO_ID and the file was opened + read-only and an attempt is being made to modify a field + other than Attribute. + @retval EFI_VOLUME_FULL The volume is full. + @retval EFI_BAD_BUFFER_SIZE BufferSize is smaller than the size of the type indicated + by InformationType. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemSetInfo ( + IN EFI_FILE_PROTOCOL *This, + IN EFI_GUID *InformationType, + IN UINTN BufferSize, + IN VOID *Buffer + ); + +/** + Get the size of the buffer that will be returned by FvFsReadFile. + + @param FvProtocol A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance. + @param FvFileInfo A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct + representing a file's info. + + @retval EFI_SUCCESS The file size was gotten correctly. + @retval Others The file size wasn't gotten correctly. + +**/ +EFI_STATUS +FvFsGetFileSize ( + IN EFI_FIRMWARE_VOLUME2_PROTOCOL *FvProtocol, + IN OUT FV_FILESYSTEM_FILE_INFO *FvFileInfo + ); + +/** + Retrieves a Unicode string that is the user readable name of the driver. + + This function retrieves the user readable name of a driver in the form of a + Unicode string. If the driver specified by This has a user readable name in + the language specified by Language, then a pointer to the driver name is + returned in DriverName, and EFI_SUCCESS is returned. If the driver specified + by This does not support the language specified by Language, + then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified + in RFC 4646 or ISO 639-2 language code format. + + @param DriverName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + driver specified by This in the language + specified by Language. + + @retval EFI_SUCCESS The Unicode string for the Driver specified by + This and the language specified by Language was + returned in DriverName. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER DriverName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemComponentNameGetDriverName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN CHAR8 *Language, + OUT CHAR16 **DriverName + ); + +/** + Retrieves a Unicode string that is the user readable name of the controller + that is being managed by a driver. + + This function retrieves the user readable name of the controller specified by + ControllerHandle and ChildHandle in the form of a Unicode string. If the + driver specified by This has a user readable name in the language specified by + Language, then a pointer to the controller name is returned in ControllerName, + and EFI_SUCCESS is returned. If the driver specified by This is not currently + managing the controller specified by ControllerHandle and ChildHandle, + then EFI_UNSUPPORTED is returned. If the driver specified by This does not + support the language specified by Language, then EFI_UNSUPPORTED is returned. + + @param This[in] A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or + EFI_COMPONENT_NAME_PROTOCOL instance. + + @param ControllerHandle[in] The handle of a controller that the driver + specified by This is managing. This handle + specifies the controller whose name is to be + returned. + + @param ChildHandle[in] The handle of the child controller to retrieve + the name of. This is an optional parameter that + may be NULL. It will be NULL for device + drivers. It will also be NULL for a bus drivers + that wish to retrieve the name of the bus + controller. It will not be NULL for a bus + driver that wishes to retrieve the name of a + child controller. + + @param Language[in] A pointer to a Null-terminated ASCII string + array indicating the language. This is the + language of the driver name that the caller is + requesting, and it must match one of the + languages specified in SupportedLanguages. The + number of languages supported by a driver is up + to the driver writer. Language is specified in + RFC 4646 or ISO 639-2 language code format. + + @param ControllerName[out] A pointer to the Unicode string to return. + This Unicode string is the name of the + controller specified by ControllerHandle and + ChildHandle in the language specified by + Language from the point of view of the driver + specified by This. + + @retval EFI_SUCCESS The Unicode string for the user readable name in + the language specified by Language for the + driver specified by This was returned in + DriverName. + + @retval EFI_INVALID_PARAMETER ControllerHandle is NULL. + + @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid + EFI_HANDLE. + + @retval EFI_INVALID_PARAMETER Language is NULL. + + @retval EFI_INVALID_PARAMETER ControllerName is NULL. + + @retval EFI_UNSUPPORTED The driver specified by This is not currently + managing the controller specified by + ControllerHandle and ChildHandle. + + @retval EFI_UNSUPPORTED The driver specified by This does not support + the language specified by Language. + +**/ +EFI_STATUS +EFIAPI +FvSimpleFileSystemComponentNameGetControllerName ( + IN EFI_COMPONENT_NAME_PROTOCOL *This, + IN EFI_HANDLE ControllerHandle, + IN EFI_HANDLE ChildHandle OPTIONAL, + IN CHAR8 *Language, + OUT CHAR16 **ControllerName + ); + +extern EFI_UNICODE_COLLATION_PROTOCOL *mUnicodeCollation; +extern EFI_FILE_PROTOCOL mFileSystemTemplate; +extern EFI_COMPONENT_NAME_PROTOCOL gFvSimpleFileSystemComponentName; +extern EFI_COMPONENT_NAME2_PROTOCOL gFvSimpleFileSystemComponentName2; + +#endif |
