]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg/FvSimpleFileSystem: Add a new module to provide access to executable...
authorBrendan Jackman <brendan.jackman@arm.com>
Tue, 23 Dec 2014 03:18:04 +0000 (03:18 +0000)
committererictian <erictian@Edk2>
Tue, 23 Dec 2014 03:18:04 +0000 (03:18 +0000)
This module implements Simple FileSystem protocol over Firmware Volume (FV).
EFI Modules included into a FV can be listed and launched from the EFI Shell or any other EFI applications.

Contributed-under: TianoCore Contribution Agreement 1.0

Signed-off-by: Brendan Jackman <brendan.jackman@arm.com>
Signed-off-by: Feng Tian <feng.tian@intel.com>
Reviewed-by: Olivier Martin <olivier.martin@arm.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@16547 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/MdeModulePkg.dsc
MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c [new file with mode: 0644]
MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c [new file with mode: 0644]
MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni [new file with mode: 0644]
MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf [new file with mode: 0644]
MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c [new file with mode: 0644]
MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni [new file with mode: 0644]
MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h [new file with mode: 0644]

index 0b47698afa2f0f3f205e5d0b1ad601228eb5a088..702ffc2ef2c70f9a31613bdbd6dd29c24121d704 100644 (file)
     <LibraryClasses>\r
       NULL|MdeModulePkg/Library/PeiCrc32GuidedSectionExtractLib/PeiCrc32GuidedSectionExtractLib.inf\r
   }\r
-  \r
-[Components.IA32, Components.X64, Components.IPF]\r
+\r
+  MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf\r
+\r
+[Components.IA32, Components.X64, Components.IPF]  \r
   MdeModulePkg/Universal/Network/UefiPxeBcDxe/UefiPxeBcDxe.inf\r
   MdeModulePkg/Universal/DebugSupportDxe/DebugSupportDxe.inf\r
   MdeModulePkg/Universal/EbcDxe/EbcDxe.inf\r
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/ComponentName.c
new file mode 100644 (file)
index 0000000..5ea0597
--- /dev/null
@@ -0,0 +1,187 @@
+/** @file\r
+  UEFI Component Name(2) protocol implementation for FvSimpleFileSystem driver.\r
+\r
+Copyright (c) 2014, ARM Limited. All rights reserved.\r
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "FvSimpleFileSystemInternal.h"\r
+\r
+//\r
+// EFI Component Name Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL  gFvSimpleFileSystemComponentName = {\r
+  FvSimpleFileSystemComponentNameGetDriverName,\r
+  FvSimpleFileSystemComponentNameGetControllerName,\r
+  "eng"\r
+};\r
+\r
+//\r
+// EFI Component Name 2 Protocol\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gFvSimpleFileSystemComponentName2 = {\r
+  (EFI_COMPONENT_NAME2_GET_DRIVER_NAME) FvSimpleFileSystemComponentNameGetDriverName,\r
+  (EFI_COMPONENT_NAME2_GET_CONTROLLER_NAME) FvSimpleFileSystemComponentNameGetControllerName,\r
+  "en"\r
+};\r
+\r
+//\r
+// Driver name table for FvSimpleFileSystem module.\r
+// It is shared by the implementation of ComponentName & ComponentName2 Protocol.\r
+//\r
+GLOBAL_REMOVE_IF_UNREFERENCED EFI_UNICODE_STRING_TABLE mFvSimpleFileSystemDriverNameTable[] = {\r
+  {\r
+    "eng;en",\r
+    (CHAR16 *)L"Fv Simple File System Driver"\r
+  },\r
+  {\r
+    NULL,\r
+    NULL\r
+  }\r
+};\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  )\r
+{\r
+  return LookupUnicodeString2 (\r
+           Language,\r
+           This->SupportedLanguages,\r
+           mFvSimpleFileSystemDriverNameTable,\r
+           DriverName,\r
+           (BOOLEAN)(This == &gFvSimpleFileSystemComponentName)\r
+           );\r
+}\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  )\r
+{\r
+  return EFI_UNSUPPORTED;\r
+}\r
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.c
new file mode 100644 (file)
index 0000000..9661cfd
--- /dev/null
@@ -0,0 +1,978 @@
+/** @file\r
+  This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware\r
+  volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.\r
+\r
+  It will expose a single directory, containing one file for each file in the firmware\r
+  volume. If a file has a UI section, its contents will be used as a filename.\r
+  Otherwise, a string representation of the GUID will be used.\r
+  Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)\r
+  will have ".efi" added to their filename.\r
+\r
+  Its primary intended use is to be able to start EFI applications embedded in FVs\r
+  from the UEFI shell. It is entirely read-only.\r
+\r
+Copyright (c) 2014, ARM Limited. All rights reserved.\r
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "FvSimpleFileSystemInternal.h"\r
+\r
+//\r
+// Template for EFI_FILE_SYSTEM_INFO data structure.\r
+//\r
+EFI_FILE_SYSTEM_INFO mFsInfoTemplate = {\r
+  0,    // Populate at runtime\r
+  TRUE, // Read-only\r
+  0,    // Don't know volume size\r
+  0,    // No free space\r
+  0,    // Don't know block size\r
+  L""   // Populate at runtime\r
+};\r
+\r
+//\r
+// Template for EFI_FILE_PROTOCOL data structure.\r
+//\r
+EFI_FILE_PROTOCOL mFileSystemTemplate = {\r
+  EFI_FILE_PROTOCOL_REVISION,\r
+  FvSimpleFileSystemOpen,\r
+  FvSimpleFileSystemClose,\r
+  FvSimpleFileSystemDelete,\r
+  FvSimpleFileSystemRead,\r
+  FvSimpleFileSystemWrite,\r
+  FvSimpleFileSystemGetPosition,\r
+  FvSimpleFileSystemSetPosition,\r
+  FvSimpleFileSystemGetInfo,\r
+  FvSimpleFileSystemSetInfo,\r
+  FvSimpleFileSystemFlush\r
+};\r
+\r
+/**\r
+  Find and call ReadSection on the first section found of an executable type.\r
+\r
+  @param  FvProtocol                  A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
+  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct\r
+                                      representing a file's info.\r
+  @param  BufferSize                  Pointer to a caller-allocated UINTN. It indicates the size of\r
+                                      the memory represented by *Buffer.\r
+  @param  Buffer                      Pointer to a pointer to a data buffer to contain file content.\r
+\r
+  @retval EFI_SUCCESS                 The call completed successfully.\r
+  @retval EFI_WARN_BUFFER_TOO_SMALL   The buffer is too small to contain the requested output.\r
+  @retval EFI_ACCESS_DENIED           The firmware volume is configured to disallow reads.\r
+  @retval EFI_NOT_FOUND               The requested file was not found in the firmware volume.\r
+  @retval EFI_DEVICE_ERROR            A hardware error occurred when attempting toaccess the firmware volume.\r
+\r
+**/\r
+EFI_STATUS\r
+FvFsFindExecutableSection (\r
+  IN     EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol,\r
+  IN     FV_FILESYSTEM_FILE_INFO           *FvFileInfo,\r
+  IN OUT UINTN                             *BufferSize,\r
+  IN OUT VOID                              **Buffer\r
+  )\r
+{\r
+  EFI_SECTION_TYPE                    SectionType;\r
+  UINT32                              AuthenticationStatus;\r
+  EFI_STATUS                          Status;\r
+\r
+  for (SectionType = EFI_SECTION_PE32; SectionType <= EFI_SECTION_TE; SectionType++) {\r
+    Status = FvProtocol->ReadSection (\r
+                           FvProtocol,\r
+                           &FvFileInfo->NameGuid,\r
+                           SectionType,\r
+                           0,\r
+                           Buffer,\r
+                           BufferSize,\r
+                           &AuthenticationStatus\r
+                           );\r
+    if (Status != EFI_NOT_FOUND) {\r
+      return Status;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Get the size of the buffer that will be returned by FvFsReadFile.\r
+\r
+  @param  FvProtocol                  A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
+  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct\r
+                                      representing a file's info.\r
+\r
+  @retval EFI_SUCCESS                 The file size was gotten correctly.\r
+  @retval Others                      The file size wasn't gotten correctly.\r
+\r
+**/\r
+EFI_STATUS\r
+FvFsGetFileSize (\r
+  IN     EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol,\r
+  IN OUT FV_FILESYSTEM_FILE_INFO           *FvFileInfo\r
+  )\r
+{\r
+  UINT32                         AuthenticationStatus;\r
+  EFI_FV_FILETYPE                FoundType;\r
+  EFI_FV_FILE_ATTRIBUTES         Attributes;\r
+  EFI_STATUS                     Status;\r
+  UINT8                          IgnoredByte;\r
+  VOID                           *IgnoredPtr;\r
+\r
+  //\r
+  // To get the size of a section, we pass 0 for BufferSize. But we can't pass\r
+  // NULL for Buffer, as that will cause a return of INVALID_PARAMETER, and we\r
+  // can't pass NULL for *Buffer, as that will cause the callee to allocate\r
+  // a buffer of the sections size.\r
+  //\r
+  IgnoredPtr = &IgnoredByte;\r
+  FvFileInfo->FileInfo.FileSize = 0;\r
+\r
+  if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {\r
+    //\r
+    // Get the size of the first executable section out of the file.\r
+    //\r
+    Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, &FvFileInfo->FileInfo.FileSize, &IgnoredPtr);\r
+    if (Status == EFI_WARN_BUFFER_TOO_SMALL) {\r
+      return EFI_SUCCESS;\r
+    }\r
+  } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {\r
+    //\r
+    // Try to get the size of a raw section out of the file\r
+    //\r
+    Status = FvProtocol->ReadSection (\r
+                           FvProtocol,\r
+                           &FvFileInfo->NameGuid,\r
+                           EFI_SECTION_RAW,\r
+                           0,\r
+                           &IgnoredPtr,\r
+                           &FvFileInfo->FileInfo.FileSize,\r
+                           &AuthenticationStatus\r
+                           );\r
+    if (Status == EFI_WARN_BUFFER_TOO_SMALL) {\r
+      return EFI_SUCCESS;\r
+    }\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Didn't find a raw section, just return the whole file's size.\r
+      //\r
+      return FvProtocol->ReadFile (\r
+                           FvProtocol,\r
+                           &FvFileInfo->NameGuid,\r
+                           NULL,\r
+                           &FvFileInfo->FileInfo.FileSize,\r
+                           &FoundType,\r
+                           &Attributes,\r
+                           &AuthenticationStatus\r
+                           );\r
+    }\r
+  } else {\r
+    //\r
+    // Get the size of the entire file\r
+    //\r
+    return FvProtocol->ReadFile (\r
+                         FvProtocol,\r
+                         &FvFileInfo->NameGuid,\r
+                         NULL,\r
+                         &FvFileInfo->FileInfo.FileSize,\r
+                         &FoundType,\r
+                         &Attributes,\r
+                         &AuthenticationStatus\r
+                         );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Helper function to read a file.\r
+\r
+  The data returned depends on the type of the underlying FV file:\r
+  - For executable types, the first section found that contains executable code is returned.\r
+  - For files of type FREEFORM, the driver attempts to return the first section of type RAW.\r
+    If none is found, the entire contents of the FV file are returned.\r
+  - On all other files the entire contents of the FV file is returned, as by\r
+    EFI_FIRMWARE_VOLUME2_PROTOCOL.ReadFile.\r
+\r
+  @param  FvProtocol                  A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
+  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct\r
+                                      representing a file's info.\r
+  @param  BufferSize                  Pointer to a caller-allocated UINTN. It indicates the size of\r
+                                      the memory represented by *Buffer.\r
+  @param  Buffer                      Pointer to a pointer to a data buffer to contain file content.\r
+\r
+  @retval EFI_SUCCESS                 The call completed successfully.\r
+  @retval EFI_WARN_BUFFER_TOO_SMALL   The buffer is too small to contain the requested output.\r
+  @retval EFI_ACCESS_DENIED           The firmware volume is configured to disallow reads.\r
+  @retval EFI_NOT_FOUND               The requested file was not found in the firmware volume.\r
+  @retval EFI_DEVICE_ERROR            A hardware error occurred when attempting toaccess the firmware volume.\r
+\r
+**/\r
+EFI_STATUS\r
+FvFsReadFile (\r
+  IN     EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol,\r
+  IN     FV_FILESYSTEM_FILE_INFO           *FvFileInfo,\r
+  IN OUT UINTN                             *BufferSize,\r
+  IN OUT VOID                              **Buffer\r
+  )\r
+{\r
+  UINT32                         AuthenticationStatus;\r
+  EFI_FV_FILETYPE                FoundType;\r
+  EFI_FV_FILE_ATTRIBUTES         Attributes;\r
+  EFI_STATUS                     Status;\r
+\r
+  if (FV_FILETYPE_IS_EXECUTABLE (FvFileInfo->Type)) {\r
+    //\r
+    // Read the first executable section out of the file.\r
+    //\r
+    Status = FvFsFindExecutableSection (FvProtocol, FvFileInfo, BufferSize, Buffer);\r
+  } else if (FvFileInfo->Type == EFI_FV_FILETYPE_FREEFORM) {\r
+    //\r
+    // Try to read a raw section out of the file\r
+    //\r
+    Status = FvProtocol->ReadSection (\r
+                           FvProtocol,\r
+                           &FvFileInfo->NameGuid,\r
+                           EFI_SECTION_RAW,\r
+                           0,\r
+                           Buffer,\r
+                           BufferSize,\r
+                           &AuthenticationStatus\r
+                           );\r
+    if (EFI_ERROR (Status)) {\r
+      //\r
+      // Didn't find a raw section, just return the whole file.\r
+      //\r
+      Status = FvProtocol->ReadFile (\r
+                             FvProtocol,\r
+                             &FvFileInfo->NameGuid,\r
+                             Buffer,\r
+                             BufferSize,\r
+                             &FoundType,\r
+                             &Attributes,\r
+                             &AuthenticationStatus\r
+                             );\r
+    }\r
+  } else {\r
+    //\r
+    // Read the entire file\r
+    //\r
+    Status = FvProtocol->ReadFile (\r
+                           FvProtocol,\r
+                           &FvFileInfo->NameGuid,\r
+                           Buffer,\r
+                           BufferSize,\r
+                           &FoundType,\r
+                           &Attributes,\r
+                           &AuthenticationStatus\r
+                           );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Helper function for populating an EFI_FILE_INFO for a file.\r
+\r
+  Note the CreateTime, LastAccessTime and ModificationTime fields in EFI_FILE_INFO\r
+  are full zero as FV2 protocol has no corresponding info to fill.\r
+\r
+  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct\r
+                                      representing a file's info.\r
+  @param  BufferSize                  Pointer to a caller-allocated UINTN. It indicates the size of\r
+                                      the memory represented by FileInfo.\r
+  @param  FileInfo                    A pointer to EFI_FILE_INFO to contain the returned file info.\r
+\r
+  @retval EFI_SUCCESS                 The call completed successfully.\r
+  @retval EFI_BUFFER_TOO_SMALL        The buffer is too small to contain the requested output.\r
+\r
+**/\r
+EFI_STATUS\r
+FvFsGetFileInfo (\r
+  IN     FV_FILESYSTEM_FILE_INFO           *FvFileInfo,\r
+  IN OUT UINTN                             *BufferSize,\r
+     OUT EFI_FILE_INFO                     *FileInfo\r
+  )\r
+{\r
+  UINTN                      InfoSize;\r
+\r
+  InfoSize = FvFileInfo->FileInfo.Size;\r
+  if (*BufferSize < InfoSize) {\r
+    *BufferSize = InfoSize;\r
+    return EFI_BUFFER_TOO_SMALL;\r
+  }\r
+\r
+  //\r
+  // Initialize FileInfo\r
+  //\r
+  CopyMem (FileInfo, &FvFileInfo->FileInfo, InfoSize);\r
+\r
+  *BufferSize = InfoSize;\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Removes the last directory or file entry in a path by changing the last\r
+  L'\' to a CHAR_NULL.\r
+\r
+  @param  Path      The pointer to the path to modify.\r
+\r
+  @retval FALSE     Nothing was found to remove.\r
+  @retval TRUE      A directory or file was removed.\r
+\r
+**/\r
+BOOLEAN\r
+EFIAPI\r
+RemoveLastItemFromPath (\r
+  IN OUT CHAR16 *Path\r
+  )\r
+{\r
+  CHAR16        *Walker;\r
+  CHAR16        *LastSlash;\r
+  //\r
+  // get directory name from path... ('chop' off extra)\r
+  //\r
+  for ( Walker = Path, LastSlash = NULL\r
+      ; Walker != NULL && *Walker != CHAR_NULL\r
+      ; Walker++\r
+     ){\r
+    if (*Walker == L'\\' && *(Walker + 1) != CHAR_NULL) {\r
+      LastSlash = Walker + 1;\r
+    }\r
+  }\r
+\r
+  if (LastSlash != NULL) {\r
+    *LastSlash = CHAR_NULL;\r
+    return (TRUE);\r
+  }\r
+\r
+  return (FALSE);\r
+}\r
+\r
+/**\r
+  Function to clean up paths.\r
+\r
+  - Single periods in the path are removed.\r
+  - Double periods in the path are removed along with a single parent directory.\r
+  - Forward slashes L'/' are converted to backward slashes L'\'.\r
+\r
+  This will be done inline and the existing buffer may be larger than required\r
+  upon completion.\r
+\r
+  @param  Path          The pointer to the string containing the path.\r
+\r
+  @retval NULL          An error occured.\r
+  @return Path in all other instances.\r
+\r
+**/\r
+CHAR16*\r
+EFIAPI\r
+TrimFilePathToAbsolutePath (\r
+  IN CHAR16 *Path\r
+  )\r
+{\r
+  CHAR16  *TempString;\r
+  UINTN   TempSize;\r
+\r
+  if (Path == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  //\r
+  // Fix up the '/' vs '\'\r
+  //\r
+  for (TempString = Path ; (TempString != NULL) && (*TempString != CHAR_NULL); TempString++) {\r
+    if (*TempString == L'/') {\r
+      *TempString = L'\\';\r
+    }\r
+  }\r
+\r
+  //\r
+  // Fix up the ..\r
+  //\r
+  while ((TempString = StrStr (Path, L"\\..\\")) != NULL) {\r
+    *TempString  = CHAR_NULL;\r
+    TempString  += 4;\r
+    RemoveLastItemFromPath (Path);\r
+    TempSize     = StrSize (TempString);\r
+    CopyMem (Path + StrLen (Path), TempString, TempSize);\r
+  }\r
+\r
+  if (((TempString = StrStr (Path, L"\\..")) != NULL) && (*(TempString + 3) == CHAR_NULL)) {\r
+    *TempString  = CHAR_NULL;\r
+    RemoveLastItemFromPath (Path);\r
+  }\r
+\r
+  //\r
+  // Fix up the .\r
+  //\r
+  while ((TempString = StrStr (Path, L"\\.\\")) != NULL) {\r
+    *TempString  = CHAR_NULL;\r
+    TempString  += 2;\r
+    TempSize     = StrSize (TempString);\r
+    CopyMem(Path + StrLen (Path), TempString, TempSize);\r
+  }\r
+\r
+  if (((TempString = StrStr (Path, L"\\.")) != NULL) && (*(TempString + 2) == CHAR_NULL)) {\r
+    *(TempString + 1) = CHAR_NULL;\r
+  }\r
+\r
+  while ((TempString = StrStr (Path, L"\\\\")) != NULL) {\r
+    *TempString  = CHAR_NULL;\r
+    TempString  += 1;\r
+    TempSize     = StrSize(TempString);\r
+    CopyMem(Path + StrLen(Path), TempString, TempSize);\r
+  }\r
+\r
+  if (((TempString = StrStr(Path, L"\\\\")) != NULL) && (*(TempString + 1) == CHAR_NULL)) {\r
+    *(TempString) = CHAR_NULL;\r
+  }\r
+\r
+  return Path;\r
+}\r
+\r
+/**\r
+  Opens a new file relative to the source file's location.\r
+\r
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                     handle to the source location. This would typically be an open\r
+                     handle to a directory.\r
+  @param  NewHandle  A pointer to the location to return the opened handle for the new\r
+                     file.\r
+  @param  FileName   The Null-terminated string of the name of the file to be opened.\r
+                     The file name may contain the following path modifiers: "\", ".",\r
+                     and "..".\r
+  @param  OpenMode   The mode to open the file. The only valid combinations that the\r
+                     file may be opened with are: Read, Read/Write, or Create/Read/Write.\r
+  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the\r
+                     attribute bits for the newly created file.\r
+\r
+  @retval EFI_SUCCESS          The file was opened.\r
+  @retval EFI_NOT_FOUND        The specified file could not be found on the device.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no\r
+                               longer supported.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write\r
+                               when the media is write-protected.\r
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.\r
+  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemOpen (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+     OUT EFI_FILE_PROTOCOL    **NewHandle,\r
+  IN     CHAR16               *FileName,\r
+  IN     UINT64               OpenMode,\r
+  IN     UINT64               Attributes\r
+  )\r
+{\r
+  FV_FILESYSTEM_INSTANCE      *Instance;\r
+  FV_FILESYSTEM_FILE          *File;\r
+  FV_FILESYSTEM_FILE          *NewFile;\r
+  FV_FILESYSTEM_FILE_INFO     *FvFileInfo;\r
+  LIST_ENTRY                  *FvFileInfoLink;\r
+\r
+  //\r
+  // Check for a valid mode\r
+  //\r
+  switch (OpenMode) {\r
+  case EFI_FILE_MODE_READ:\r
+    break;\r
+\r
+  default:\r
+    return EFI_WRITE_PROTECTED;\r
+  }\r
+\r
+  File = FVFS_FILE_FROM_FILE_THIS (This);\r
+  Instance = File->Instance;\r
+\r
+  FileName = TrimFilePathToAbsolutePath (FileName);\r
+\r
+  if (FileName[0] == L'\\') {\r
+    FileName++;\r
+  }\r
+\r
+  //\r
+  // Check for opening root\r
+  //\r
+  if (StrCmp (FileName, L".") == 0 || StrCmp (FileName, L"") == 0) {\r
+    NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));\r
+    if (NewFile == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    NewFile->Signature = FVFS_FILE_SIGNATURE;\r
+    NewFile->Instance  = Instance;\r
+    NewFile->FvFileInfo = File->FvFileInfo;\r
+    CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));\r
+    InitializeListHead (&NewFile->Link);\r
+    InsertHeadList (&Instance->FileHead, &NewFile->Link);\r
+\r
+    NewFile->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);\r
+\r
+    *NewHandle = &NewFile->FileProtocol;\r
+    return EFI_SUCCESS;\r
+  }\r
+\r
+  //\r
+  // Do a linear search for a file in the FV with a matching filename\r
+  //\r
+  for (FvFileInfoLink = GetFirstNode (&Instance->FileInfoHead);\r
+      !IsNull (&Instance->FileInfoHead, FvFileInfoLink);\r
+       FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, FvFileInfoLink)) {\r
+    FvFileInfo = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);\r
+    if (mUnicodeCollation->StriColl (mUnicodeCollation, &FvFileInfo->FileInfo.FileName[0], FileName) == 0) {\r
+      NewFile = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));\r
+      if (NewFile == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      NewFile->Signature = FVFS_FILE_SIGNATURE;\r
+      NewFile->Instance  = Instance;\r
+      NewFile->FvFileInfo = FvFileInfo;\r
+      CopyMem (&NewFile->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));\r
+      InitializeListHead (&NewFile->Link);\r
+      InsertHeadList (&Instance->FileHead, &NewFile->Link);\r
+\r
+      *NewHandle = &NewFile->FileProtocol;\r
+      return EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  Closes a specified file handle.\r
+\r
+  @param  This          A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                        handle to close.\r
+\r
+  @retval EFI_SUCCESS   The file was closed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemClose (\r
+  IN EFI_FILE_PROTOCOL  *This\r
+  )\r
+{\r
+  FV_FILESYSTEM_INSTANCE      *Instance;\r
+  FV_FILESYSTEM_FILE          *File;\r
+\r
+  File = FVFS_FILE_FROM_FILE_THIS (This);\r
+  Instance = File->Instance;\r
+\r
+  if (File != Instance->Root) {\r
+    RemoveEntryList (&File->Link);\r
+    FreePool (File);\r
+  }\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Reads data from a file.\r
+\r
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                     handle to read data from.\r
+  @param  BufferSize On input, the size of the Buffer. On output, the amount of data\r
+                     returned in Buffer. In both cases, the size is measured in bytes.\r
+  @param  Buffer     The buffer into which the data is read.\r
+\r
+  @retval EFI_SUCCESS          Data was read.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_DEVICE_ERROR     An attempt was made to read from a deleted file.\r
+  @retval EFI_DEVICE_ERROR     On entry, the current file position is beyond the end of the file.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory\r
+                               entry. BufferSize has been updated with the size\r
+                               needed to complete the request.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemRead (\r
+  IN     EFI_FILE_PROTOCOL      *This,\r
+  IN OUT UINTN                  *BufferSize,\r
+     OUT VOID                   *Buffer\r
+  )\r
+{\r
+  FV_FILESYSTEM_INSTANCE        *Instance;\r
+  FV_FILESYSTEM_FILE            *File;\r
+  EFI_STATUS                    Status;\r
+  LIST_ENTRY                    *FvFileInfoLink;\r
+  VOID                          *FileBuffer;\r
+  UINTN                         FileSize;\r
+\r
+  File = FVFS_FILE_FROM_FILE_THIS (This);\r
+  Instance = File->Instance;\r
+\r
+  if (File->FvFileInfo == Instance->Root->FvFileInfo) {\r
+    if (File->DirReadNext) {\r
+      //\r
+      // Directory read: populate Buffer with an EFI_FILE_INFO\r
+      //\r
+      Status = FvFsGetFileInfo (File->DirReadNext, BufferSize, Buffer);\r
+      if (!EFI_ERROR (Status)) {\r
+        //\r
+        // Successfully read a directory entry, now update the pointer to the\r
+        // next file, which will be read on the next call to this function\r
+        //\r
+        FvFileInfoLink = GetNextNode (&Instance->FileInfoHead, &File->DirReadNext->Link);\r
+        if (IsNull (&Instance->FileInfoHead, FvFileInfoLink)) {\r
+          //\r
+          // No more files left\r
+          //\r
+          File->DirReadNext = NULL;\r
+        } else {\r
+          File->DirReadNext = FVFS_FILE_INFO_FROM_LINK (FvFileInfoLink);\r
+        }\r
+      }\r
+      return Status;\r
+    } else {\r
+      //\r
+      // Directory read. All entries have been read, so return a zero-size\r
+      // buffer.\r
+      //\r
+      *BufferSize = 0;\r
+      return EFI_SUCCESS;\r
+    }\r
+  } else {\r
+    FileSize = File->FvFileInfo->FileInfo.FileSize;\r
+\r
+    FileBuffer = AllocateZeroPool (FileSize);\r
+    if (FileBuffer == NULL) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    Status = FvFsReadFile (File->Instance->FvProtocol, File->FvFileInfo, &FileSize, &FileBuffer);\r
+    if (EFI_ERROR (Status)) {\r
+      return EFI_DEVICE_ERROR;\r
+    }\r
+\r
+    if (*BufferSize + File->Position > FileSize) {\r
+      *BufferSize = FileSize - File->Position;\r
+    }\r
+\r
+    CopyMem (Buffer, (UINT8*)FileBuffer + File->Position, *BufferSize);\r
+    File->Position += *BufferSize;\r
+\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
+/**\r
+  Writes data to a file.\r
+\r
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                     handle to write data to.\r
+  @param  BufferSize On input, the size of the Buffer. On output, the amount of data\r
+                     actually written. In both cases, the size is measured in bytes.\r
+  @param  Buffer     The buffer of data to write.\r
+\r
+  @retval EFI_SUCCESS          Data was written.\r
+  @retval EFI_UNSUPPORTED      Writes to open directory files are not supported.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_DEVICE_ERROR     An attempt was made to write to a deleted file.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.\r
+  @retval EFI_ACCESS_DENIED    The file was opened read only.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemWrite (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+  IN OUT UINTN                *BufferSize,\r
+  IN     VOID                 *Buffer\r
+  )\r
+{\r
+  FV_FILESYSTEM_INSTANCE        *Instance;\r
+  FV_FILESYSTEM_FILE            *File;\r
+\r
+  File = FVFS_FILE_FROM_FILE_THIS (This);\r
+  Instance = File->Instance;\r
+\r
+  if (File->FvFileInfo == Instance->Root->FvFileInfo) {\r
+    return EFI_UNSUPPORTED;\r
+  } else {\r
+    return EFI_WRITE_PROTECTED;\r
+  }\r
+}\r
+\r
+/**\r
+  Returns a file's current position.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                          handle to get the current position on.\r
+  @param  Position        The address to return the file's current position value.\r
+\r
+  @retval EFI_SUCCESS      The position was returned.\r
+  @retval EFI_UNSUPPORTED  The request is not valid on open directories.\r
+  @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemGetPosition (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+     OUT UINT64               *Position\r
+  )\r
+{\r
+  FV_FILESYSTEM_INSTANCE        *Instance;\r
+  FV_FILESYSTEM_FILE            *File;\r
+\r
+  File = FVFS_FILE_FROM_FILE_THIS (This);\r
+  Instance = File->Instance;\r
+\r
+  if (File->FvFileInfo == Instance->Root->FvFileInfo) {\r
+    return EFI_UNSUPPORTED;\r
+  } else {\r
+    *Position = File->Position;\r
+    return EFI_SUCCESS;\r
+  }\r
+}\r
+\r
+/**\r
+  Sets a file's current position.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the\r
+                          file handle to set the requested position on.\r
+  @param  Position        The byte position from the start of the file to set.\r
+\r
+  @retval EFI_SUCCESS      The position was set.\r
+  @retval EFI_UNSUPPORTED  The seek request for nonzero is not valid on open\r
+                           directories.\r
+  @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemSetPosition (\r
+  IN EFI_FILE_PROTOCOL        *This,\r
+  IN UINT64                   Position\r
+  )\r
+{\r
+  FV_FILESYSTEM_INSTANCE      *Instance;\r
+  FV_FILESYSTEM_FILE          *File;\r
+\r
+  File = FVFS_FILE_FROM_FILE_THIS (This);\r
+  Instance = File->Instance;\r
+\r
+  if (File->FvFileInfo == Instance->Root->FvFileInfo) {\r
+    if (Position != 0) {\r
+      return EFI_UNSUPPORTED;\r
+    }\r
+    //\r
+    // Reset directory position to first entry\r
+    //\r
+    File->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);\r
+  } else if (Position == 0xFFFFFFFFFFFFFFFFull) {\r
+    File->Position = File->FvFileInfo->FileInfo.FileSize;\r
+  } else {\r
+    File->Position = Position;\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Flushes all modified data associated with a file to a device.\r
+\r
+  @param  This A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+               handle to flush.\r
+\r
+  @retval EFI_SUCCESS          The data was flushed.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.\r
+  @retval EFI_ACCESS_DENIED    The file was opened read-only.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemFlush (\r
+  IN EFI_FILE_PROTOCOL  *This\r
+  )\r
+{\r
+  return EFI_WRITE_PROTECTED;\r
+}\r
+\r
+/**\r
+  Close and delete the file handle.\r
+\r
+  @param  This                     A pointer to the EFI_FILE_PROTOCOL instance that is the\r
+                                   handle to the file to delete.\r
+\r
+  @retval EFI_SUCCESS              The file was closed and deleted, and the handle was closed.\r
+  @retval EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDelete (\r
+  IN EFI_FILE_PROTOCOL *This\r
+  )\r
+{\r
+  EFI_STATUS       Status;\r
+\r
+  Status = FvSimpleFileSystemClose (This);\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return EFI_WARN_DELETE_FAILURE;\r
+}\r
+\r
+/**\r
+  Returns information about a file.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                          handle the requested information is for.\r
+  @param  InformationType The type identifier for the information being requested.\r
+  @param  BufferSize      On input, the size of Buffer. On output, the amount of data\r
+                          returned in Buffer. In both cases, the size is measured in bytes.\r
+  @param  Buffer          A pointer to the data buffer to return. The buffer's type is\r
+                          indicated by InformationType.\r
+\r
+  @retval EFI_SUCCESS          The information was returned.\r
+  @retval EFI_UNSUPPORTED      The InformationType is not known.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.\r
+                               BufferSize has been updated with the size needed to complete\r
+                               the request.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemGetInfo (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+  IN     EFI_GUID             *InformationType,\r
+  IN OUT UINTN                *BufferSize,\r
+     OUT VOID                 *Buffer\r
+  )\r
+{\r
+  FV_FILESYSTEM_FILE           *File;\r
+  EFI_FILE_SYSTEM_INFO         *FsInfoOut;\r
+  EFI_FILE_SYSTEM_VOLUME_LABEL *FsVolumeLabel;\r
+  FV_FILESYSTEM_INSTANCE       *Instance;\r
+  UINTN                        Size;\r
+  EFI_STATUS                   Status;\r
+\r
+  File = FVFS_FILE_FROM_FILE_THIS (This);\r
+\r
+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid)) {\r
+    //\r
+    // Return filesystem info\r
+    //\r
+    Instance = File->Instance;\r
+\r
+    Size = sizeof (EFI_FILE_SYSTEM_INFO) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);\r
+\r
+    if (*BufferSize < Size) {\r
+      *BufferSize = Size;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+\r
+    //\r
+    // Cast output buffer for convenience\r
+    //\r
+    FsInfoOut = (EFI_FILE_SYSTEM_INFO *) Buffer;\r
+\r
+    CopyMem (FsInfoOut, &mFsInfoTemplate, sizeof (EFI_FILE_SYSTEM_INFO));\r
+    Status = StrnCpyS (FsInfoOut->VolumeLabel, (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_INFO, VolumeLabel)) / sizeof (CHAR16), Instance->VolumeLabel, StrLen (Instance->VolumeLabel));\r
+    ASSERT_EFI_ERROR (Status);\r
+    FsInfoOut->Size = Size;\r
+    return Status;\r
+  } else if (CompareGuid (InformationType, &gEfiFileInfoGuid)) {\r
+    //\r
+    // Return file info\r
+    //\r
+    return FvFsGetFileInfo (File->FvFileInfo, BufferSize, (EFI_FILE_INFO *) Buffer);\r
+  } else if (CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
+    //\r
+    // Return Volume Label\r
+    //\r
+    Instance = File->Instance;\r
+    Size     = sizeof (EFI_FILE_SYSTEM_VOLUME_LABEL) + StrSize (Instance->VolumeLabel) - sizeof (CHAR16);;\r
+    if (*BufferSize < Size) {\r
+      *BufferSize = Size;\r
+      return EFI_BUFFER_TOO_SMALL;\r
+    }\r
+\r
+    FsVolumeLabel = (EFI_FILE_SYSTEM_VOLUME_LABEL*) Buffer;\r
+    Status        = StrnCpyS (FsVolumeLabel->VolumeLabel, (*BufferSize - OFFSET_OF (EFI_FILE_SYSTEM_VOLUME_LABEL, VolumeLabel)) / sizeof (CHAR16), Instance->VolumeLabel, StrLen (Instance->VolumeLabel));\r
+    ASSERT_EFI_ERROR (Status);\r
+    return Status;\r
+  } else {\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+}\r
+\r
+/**\r
+  Sets information about a file.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                          handle the information is for.\r
+  @param  InformationType The type identifier for the information being set.\r
+  @param  BufferSize      The size, in bytes, of Buffer.\r
+  @param  Buffer          A pointer to the data buffer to write. The buffer's type is\r
+                          indicated by InformationType.\r
+\r
+  @retval EFI_SUCCESS          The information was set.\r
+  @retval EFI_UNSUPPORTED      The InformationType is not known.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_INFO_ID and the media is\r
+                               read-only.\r
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID\r
+                               and the media is read only.\r
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID\r
+                               and the media is read-only.\r
+  @retval EFI_ACCESS_DENIED    An attempt is made to change the name of a file to a\r
+                               file that is already present.\r
+  @retval EFI_ACCESS_DENIED    An attempt is being made to change the EFI_FILE_DIRECTORY\r
+                               Attribute.\r
+  @retval EFI_ACCESS_DENIED    An attempt is being made to change the size of a directory.\r
+  @retval EFI_ACCESS_DENIED    InformationType is EFI_FILE_INFO_ID and the file was opened\r
+                               read-only and an attempt is being made to modify a field\r
+                               other than Attribute.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+  @retval EFI_BAD_BUFFER_SIZE  BufferSize is smaller than the size of the type indicated\r
+                               by InformationType.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemSetInfo (\r
+  IN EFI_FILE_PROTOCOL        *This,\r
+  IN EFI_GUID                 *InformationType,\r
+  IN UINTN                    BufferSize,\r
+  IN VOID                     *Buffer\r
+  )\r
+{\r
+  if (CompareGuid (InformationType, &gEfiFileSystemInfoGuid) || \r
+      CompareGuid (InformationType, &gEfiFileInfoGuid) ||\r
+      CompareGuid (InformationType, &gEfiFileSystemVolumeLabelInfoIdGuid)) {\r
+    return EFI_WRITE_PROTECTED;\r
+  }\r
+\r
+  return EFI_UNSUPPORTED;\r
+}\r
+\r
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni
new file mode 100644 (file)
index 0000000..fc8c929
Binary files /dev/null and b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystem.uni differ
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemDxe.inf
new file mode 100644 (file)
index 0000000..a648c2e
--- /dev/null
@@ -0,0 +1,74 @@
+## @file\r
+#  Support for Simple File System over Firmware Volume.\r
+#\r
+#  This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware\r
+#  volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.\r
+#\r
+#  It will expose a single directory, containing one file for each file in the firmware\r
+#  volume. If a file has a UI section, its contents will be used as a filename.\r
+#  Otherwise, a string representation of the GUID will be used.\r
+#  Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)\r
+#  will have ".efi" added to their filename.\r
+#\r
+#  Its primary intended use is to be able to start EFI applications embedded in FVs\r
+#  from the UEFI shell. It is entirely read-only.\r
+#\r
+#  Copyright (c) 2014, ARM Ltd. All rights reserved.<BR>\r
+#  Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+#\r
+#  This program and the accompanying materials\r
+#  are licensed and made available under the terms and conditions of the BSD License\r
+#  which accompanies this distribution.  The full text of the license may be found at\r
+#  http://opensource.org/licenses/bsd-license.php\r
+#\r
+#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+#\r
+##\r
+\r
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = FvSimpleFileSystem\r
+  MODULE_UNI_FILE                = FvSimpleFileSystem.uni\r
+  FILE_GUID                      = 907125c0-a5f1-11e3-a3fe-a3198b49350c\r
+  MODULE_TYPE                    = UEFI_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  ENTRY_POINT                    = FvSimpleFileSystemEntryPoint\r
+\r
+[Sources]\r
+\r
+  ComponentName.c\r
+  FvSimpleFileSystem.c\r
+  FvSimpleFileSystemEntryPoint.c\r
+  FvSimpleFileSystemInternal.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  BaseLib\r
+  DevicePathLib\r
+  MemoryAllocationLib\r
+  PrintLib\r
+  UefiDriverEntryPoint\r
+  UefiLib\r
+\r
+[Pcd]\r
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultPlatformLang              ## SOMETIMES_CONSUMES\r
+  gEfiMdePkgTokenSpaceGuid.PcdUefiVariableDefaultLang                      ## SOMETIMES_CONSUMES\r
+\r
+[Guids]\r
+  gEfiFileInfoGuid                                                         ## SOMETIMES_CONSUMES   ## UNDEFINED\r
+  gEfiFileSystemInfoGuid                                                   ## SOMETIMES_CONSUMES   ## UNDEFINED\r
+  gEfiFileSystemVolumeLabelInfoIdGuid                                      ## SOMETIMES_CONSUMES   ## UNDEFINED\r
+\r
+[Protocols]\r
+  gEfiDevicePathProtocolGuid                                               ## TO_START\r
+  gEfiFirmwareVolume2ProtocolGuid                                          ## TO_START\r
+  gEfiUnicodeCollationProtocolGuid                                         ## TO_START\r
+  gEfiUnicodeCollation2ProtocolGuid                                        ## TO_START\r
+  gEfiSimpleFileSystemProtocolGuid                                         ## BY_START\r
+\r
+[UserExtensions.TianoCore."ExtraFiles"]\r
+  FvSimpleFileSystemExtra.uni
\ No newline at end of file
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemEntryPoint.c
new file mode 100644 (file)
index 0000000..975ab88
--- /dev/null
@@ -0,0 +1,676 @@
+/** @file\r
+  This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware\r
+  volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.\r
+\r
+  It will expose a single directory, containing one file for each file in the firmware\r
+  volume. If a file has a UI section, its contents will be used as a filename.\r
+  Otherwise, a string representation of the GUID will be used.\r
+  Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)\r
+  will have ".efi" added to their filename.\r
+\r
+  Its primary intended use is to be able to start EFI applications embedded in FVs\r
+  from the UEFI shell. It is entirely read-only.\r
+\r
+Copyright (c) 2014, ARM Limited. All rights reserved.\r
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#include "FvSimpleFileSystemInternal.h"\r
+\r
+EFI_UNICODE_COLLATION_PROTOCOL          *mUnicodeCollation = NULL;\r
+\r
+//\r
+// A Guid string is 32 hex characters with 4 hyphens and a NULL-terminated char: 37 characters total\r
+//\r
+#define GUID_STRING_SIZE                (37 * sizeof (CHAR16))\r
+\r
+#define FVFS_VOLUME_LABEL_PREFIX        L"Firmware Volume: "\r
+#define FVFS_VOLUME_LABEL_SIZE          (sizeof (FVFS_VOLUME_LABEL_PREFIX) + GUID_STRING_SIZE - sizeof (CHAR16))\r
+#define FVFS_FALLBACK_VOLUME_LABEL      L"Firmware Volume"\r
+\r
+//\r
+// Template for EFI_SIMPLE_FILE_SYSTEM_PROTOCOL data structure.\r
+//\r
+EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mSimpleFsTemplate = {\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,\r
+  FvSimpleFileSystemOpenVolume\r
+};\r
+\r
+//\r
+// Template for EFI_DRIVER_BINDING_PROTOCOL data structure.\r
+//\r
+EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = {\r
+  FvSimpleFileSystemDriverSupported,\r
+  FvSimpleFileSystemDriverStart,\r
+  FvSimpleFileSystemDriverStop,\r
+  0,\r
+  NULL,\r
+  NULL\r
+};\r
+\r
+/**\r
+  Open the root directory on a volume.\r
+\r
+  @param  This     A pointer to the volume to open the root directory.\r
+  @param  RootFile A pointer to the location to return the opened file handle for the\r
+                   root directory.\r
+\r
+  @retval EFI_SUCCESS          The device was opened.\r
+  @retval EFI_UNSUPPORTED      This volume does not support the requested file system type.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.\r
+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.\r
+  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no\r
+                               longer supported. Any existing file handles for this volume are\r
+                               no longer valid. To access the files on the new medium, the\r
+                               volume must be reopened with OpenVolume().\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemOpenVolume (\r
+  IN     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
+     OUT EFI_FILE_PROTOCOL               **RootFile\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  FV_FILESYSTEM_FILE              *Root;\r
+  CHAR16                          *UiSection;\r
+  EFI_GUID                        NameGuid;\r
+  EFI_FV_FILE_ATTRIBUTES          Attributes;\r
+  UINT32                          Authentication;\r
+  UINTN                           Key;\r
+  EFI_FV_FILETYPE                 FileType;\r
+  UINTN                           Size;\r
+  FV_FILESYSTEM_INSTANCE          *Instance;\r
+  FV_FILESYSTEM_FILE_INFO         *FvFileInfo;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FvProtocol;\r
+  CHAR16                          *Name;\r
+  UINTN                           NameLen;\r
+  UINTN                           NumChars;\r
+  UINTN                           DestMax;\r
+\r
+  Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This);\r
+  Status = EFI_SUCCESS;\r
+\r
+  if (Instance->Root == NULL) {\r
+    //\r
+    // Allocate file structure for root file\r
+    //\r
+    Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));\r
+    if (Root == NULL) {\r
+      return EFI_OUT_OF_RESOURCES;\r
+    }\r
+\r
+    Instance->Root  = Root;\r
+    Root->Instance  = Instance;\r
+    Root->Signature = FVFS_FILE_SIGNATURE;\r
+    CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));\r
+    Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO));\r
+    if (Root->FvFileInfo == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+    }\r
+    Root->FvFileInfo->FileInfo.Size      = sizeof (EFI_FILE_INFO);\r
+    Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY;\r
+\r
+    //\r
+    // Populate the instance's list of files. We consider anything a file that\r
+    // has a UI_SECTION, which we consider to be its filename.\r
+    //\r
+    FvProtocol = Instance->FvProtocol;\r
+    //\r
+    // Allocate Key\r
+    //\r
+    Key = 0;\r
+\r
+    do {\r
+      FileType = EFI_FV_FILETYPE_ALL;\r
+\r
+      Status = FvProtocol->GetNextFile (\r
+                             FvProtocol,\r
+                             &Key,\r
+                             &FileType,\r
+                             &NameGuid,\r
+                             &Attributes,\r
+                             &Size\r
+                             );\r
+      if (EFI_ERROR (Status)) {\r
+        ASSERT (Status == EFI_NOT_FOUND);\r
+        break;\r
+      }\r
+\r
+      //\r
+      // Get a file's name: If it has a UI section, use that, otherwise use\r
+      // its NameGuid.\r
+      //\r
+      UiSection = NULL;\r
+      Status = FvProtocol->ReadSection (\r
+                             FvProtocol,\r
+                             &NameGuid,\r
+                             EFI_SECTION_USER_INTERFACE,\r
+                             0,\r
+                             (VOID **)&UiSection,\r
+                             &Size,\r
+                             &Authentication\r
+                             );\r
+      if (!EFI_ERROR (Status)) {\r
+        Name = UiSection;\r
+      } else {\r
+        Name = AllocateZeroPool (GUID_STRING_SIZE);\r
+        if (Name == NULL) {\r
+          return EFI_OUT_OF_RESOURCES;\r
+        }\r
+        NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid);\r
+        ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE);\r
+      }\r
+\r
+      //\r
+      // Found a file.\r
+      // Allocate a file structure and populate it.\r
+      //\r
+      NameLen = StrSize (Name);\r
+      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {\r
+        NameLen += StrSize (L".efi") - sizeof (CHAR16);\r
+      }\r
+\r
+      FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16));\r
+      if (FvFileInfo == NULL) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE;\r
+      InitializeListHead (&FvFileInfo->Link);\r
+      CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID));\r
+      FvFileInfo->Type = FileType;\r
+\r
+      //\r
+      // Add ".efi" to filenames of drivers and applications.\r
+      //\r
+      DestMax = NameLen / sizeof (CHAR16);\r
+      Status  = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name));\r
+      ASSERT_EFI_ERROR (Status);\r
+\r
+      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {\r
+        Status  = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi"));\r
+        ASSERT_EFI_ERROR (Status);\r
+      }\r
+\r
+      FvFileInfo->FileInfo.Size     = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16);\r
+      Status = FvFsGetFileSize (FvProtocol, FvFileInfo);\r
+      ASSERT_EFI_ERROR (Status);\r
+      FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize;\r
+      FvFileInfo->FileInfo.Attribute    = EFI_FILE_READ_ONLY;\r
+\r
+      InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link);\r
+\r
+      FreePool (Name);\r
+\r
+    } while (TRUE);\r
+\r
+    if (Status == EFI_NOT_FOUND) {\r
+      Status = EFI_SUCCESS;\r
+    }\r
+  }\r
+\r
+  Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);\r
+  *RootFile = &Instance->Root->FileProtocol;\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Worker function to initialize Unicode Collation support.\r
+\r
+  It tries to locate Unicode Collation (2) protocol and matches it with current\r
+  platform language code.\r
+\r
+  @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.\r
+  @param  ProtocolGuid         The pointer to Unicode Collation (2) protocol GUID.\r
+  @param  VariableName         The name of the RFC 4646 or ISO 639-2 language variable.\r
+  @param  DefaultLanguage      The default language in case the RFC 4646 or ISO 639-2 language is absent.\r
+\r
+  @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.\r
+  @retval Others               The Unicode Collation (2) protocol has not been located.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeUnicodeCollationSupportWorker (\r
+  IN       EFI_HANDLE             AgentHandle,\r
+  IN       EFI_GUID               *ProtocolGuid,\r
+  IN CONST CHAR16                 *VariableName,\r
+  IN CONST CHAR8                  *DefaultLanguage\r
+  )\r
+{\r
+  EFI_STATUS                      ReturnStatus;\r
+  EFI_STATUS                      Status;\r
+  UINTN                           NumHandles;\r
+  UINTN                           Index;\r
+  EFI_HANDLE                      *Handles;\r
+  EFI_UNICODE_COLLATION_PROTOCOL  *Uci;\r
+  BOOLEAN                         Iso639Language;\r
+  CHAR8                           *Language;\r
+  CHAR8                           *BestLanguage;\r
+\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  ProtocolGuid,\r
+                  NULL,\r
+                  &NumHandles,\r
+                  &Handles\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Iso639Language = (BOOLEAN) (ProtocolGuid == &gEfiUnicodeCollationProtocolGuid);\r
+  GetEfiGlobalVariable2 (VariableName, (VOID**) &Language, NULL);\r
+\r
+  ReturnStatus = EFI_UNSUPPORTED;\r
+  for (Index = 0; Index < NumHandles; Index++) {\r
+    //\r
+    // Open Unicode Collation Protocol\r
+    //\r
+    Status = gBS->OpenProtocol (\r
+                    Handles[Index],\r
+                    ProtocolGuid,\r
+                    (VOID **) &Uci,\r
+                    AgentHandle,\r
+                    NULL,\r
+                    EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                    );\r
+    if (EFI_ERROR (Status)) {\r
+      continue;\r
+    }\r
+\r
+    //\r
+    // Find the best matching matching language from the supported languages\r
+    // of Unicode Collation (2) protocol.\r
+    //\r
+    BestLanguage = GetBestLanguage (\r
+                     Uci->SupportedLanguages,\r
+                     Iso639Language,\r
+                     (Language == NULL) ? "" : Language,\r
+                     DefaultLanguage,\r
+                     NULL\r
+                     );\r
+    if (BestLanguage != NULL) {\r
+      FreePool (BestLanguage);\r
+      mUnicodeCollation = Uci;\r
+      ReturnStatus = EFI_SUCCESS;\r
+      break;\r
+    }\r
+  }\r
+\r
+  if (Language != NULL) {\r
+    FreePool (Language);\r
+  }\r
+\r
+  FreePool (Handles);\r
+\r
+  return ReturnStatus;\r
+}\r
+\r
+/**\r
+  Initialize Unicode Collation support.\r
+\r
+  It tries to locate Unicode Collation 2 protocol and matches it with current\r
+  platform language code. If for any reason the first attempt fails, it then tries to\r
+  use Unicode Collation Protocol.\r
+\r
+  @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.\r
+\r
+  @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.\r
+  @retval Others               The Unicode Collation (2) protocol has not been located.\r
+\r
+**/\r
+EFI_STATUS\r
+InitializeUnicodeCollationSupport (\r
+  IN EFI_HANDLE    AgentHandle\r
+  )\r
+{\r
+\r
+  EFI_STATUS       Status;\r
+\r
+  Status = EFI_UNSUPPORTED;\r
+\r
+  //\r
+  // First try to use RFC 4646 Unicode Collation 2 Protocol.\r
+  //\r
+  Status = InitializeUnicodeCollationSupportWorker (\r
+             AgentHandle,\r
+             &gEfiUnicodeCollation2ProtocolGuid,\r
+             L"PlatformLang",\r
+             (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang)\r
+             );\r
+  //\r
+  // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back\r
+  // on the ISO 639-2 Unicode Collation Protocol.\r
+  //\r
+  if (EFI_ERROR (Status)) {\r
+    Status = InitializeUnicodeCollationSupportWorker (\r
+               AgentHandle,\r
+               &gEfiUnicodeCollationProtocolGuid,\r
+               L"Lang",\r
+               (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang)\r
+               );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Test to see if this driver supports ControllerHandle.\r
+\r
+  @param  DriverBinding       Protocol instance pointer.\r
+  @param  ControllerHandle    Handle of device to test\r
+  @param  RemainingDevicePath Optional parameter use to pick a specific child\r
+                              device to start.\r
+\r
+  @retval EFI_SUCCESS         This driver supports this device\r
+  @retval EFI_ALREADY_STARTED This driver is already running on this device\r
+  @retval other               This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDriverSupported (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  return gBS->OpenProtocol (\r
+                ControllerHandle,\r
+                &gEfiFirmwareVolume2ProtocolGuid,\r
+                NULL,\r
+                gImageHandle,\r
+                ControllerHandle,\r
+                EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
+                );\r
+}\r
+\r
+/**\r
+  Start this driver on ControllerHandle by opening a FV protocol and\r
+  installing a SimpleFileSystem protocol on ControllerHandle.\r
+\r
+  @param  DriverBinding        Protocol instance pointer.\r
+  @param  ControllerHandle     Handle of device to bind driver to\r
+  @param  RemainingDevicePath  Optional parameter use to pick a specific child\r
+                               device to start.\r
+\r
+  @retval EFI_SUCCESS          This driver is added to ControllerHandle\r
+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle\r
+  @retval other                This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDriverStart (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL    *FvProtocol;\r
+  FV_FILESYSTEM_INSTANCE           *Instance;\r
+  EFI_DEVICE_PATH_PROTOCOL         *FvDevicePath;\r
+  EFI_GUID                         *FvGuid;\r
+  UINTN                            NumChars;\r
+\r
+  Status = InitializeUnicodeCollationSupport (DriverBinding->DriverBindingHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Open FV protocol\r
+  //\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiFirmwareVolume2ProtocolGuid,\r
+                  (VOID **) &FvProtocol,\r
+                  gImageHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  //\r
+  // Create an instance\r
+  //\r
+  Instance = AllocateZeroPool (sizeof (FV_FILESYSTEM_INSTANCE));\r
+  if (Instance == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  Instance->Root = NULL;\r
+  Instance->FvProtocol = FvProtocol;\r
+  Instance->Signature = FVFS_INSTANCE_SIGNATURE;\r
+  InitializeListHead (&Instance->FileInfoHead);\r
+  InitializeListHead (&Instance->FileHead);\r
+  CopyMem (&Instance->SimpleFs, &mSimpleFsTemplate, sizeof (mSimpleFsTemplate));\r
+\r
+  Status = gBS->InstallProtocolInterface(\r
+                  &ControllerHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  EFI_NATIVE_INTERFACE,\r
+                  &Instance->SimpleFs\r
+                  );\r
+\r
+  //\r
+  // Decide on a filesystem volume label, which will include the FV's guid.\r
+  // Get the device path to find the FV's GUID\r
+  //\r
+  Instance->VolumeLabel = NULL;\r
+  Status =  gBS->OpenProtocol (\r
+                   ControllerHandle,\r
+                   &gEfiDevicePathProtocolGuid,\r
+                   (VOID **) &FvDevicePath,\r
+                   gImageHandle,\r
+                   ControllerHandle,\r
+                   EFI_OPEN_PROTOCOL_BY_DRIVER\r
+                   );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Iterate over device path until we find a firmware volume node\r
+    //\r
+    while (!IsDevicePathEndType (FvDevicePath)) {\r
+      if (DevicePathType (FvDevicePath) == MEDIA_DEVICE_PATH &&\r
+          DevicePathSubType (FvDevicePath) == MEDIA_PIWG_FW_VOL_DP) {\r
+        //\r
+        // Allocate the volume label\r
+        //\r
+        Instance->VolumeLabel = AllocateZeroPool (FVFS_VOLUME_LABEL_SIZE);\r
+        //\r
+        // Check the allocation was successful\r
+        //\r
+        if (Instance->VolumeLabel != NULL) {\r
+          //\r
+          // Extract the FV's guid\r
+          //\r
+          FvGuid = &((MEDIA_FW_VOL_DEVICE_PATH *) FvDevicePath)->FvName;\r
+          //\r
+          // Build the volume label string\r
+          //\r
+          NumChars = UnicodeSPrint (\r
+                       Instance->VolumeLabel,\r
+                       FVFS_VOLUME_LABEL_SIZE,\r
+                       FVFS_VOLUME_LABEL_PREFIX L"%g",\r
+                       FvGuid\r
+                       );\r
+          ASSERT ((NumChars + 1) * sizeof (CHAR16) == FVFS_VOLUME_LABEL_SIZE);\r
+        }\r
+        break;\r
+      }\r
+      FvDevicePath = NextDevicePathNode (FvDevicePath);\r
+    }\r
+  }\r
+  //\r
+  // If we didn't decide on a volume label, set a fallback one\r
+  //\r
+  if (Instance->VolumeLabel == NULL) {\r
+    Instance->VolumeLabel = AllocateCopyPool (\r
+                              sizeof (FVFS_FALLBACK_VOLUME_LABEL),\r
+                              FVFS_FALLBACK_VOLUME_LABEL\r
+                              );\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing\r
+  the FV protocol on ControllerHandle.\r
+\r
+  @param  DriverBinding     Protocol instance pointer.\r
+  @param  ControllerHandle  Handle of device to stop driver on\r
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
+                            children is zero stop the entire bus driver.\r
+  @param  ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCESS       This driver is removed ControllerHandle\r
+  @retval other             This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDriverStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding,\r
+  IN  EFI_HANDLE                        ControllerHandle,\r
+  IN  UINTN                             NumberOfChildren,\r
+  IN  EFI_HANDLE                        *ChildHandleBuffer OPTIONAL\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  FV_FILESYSTEM_INSTANCE           *Instance;\r
+  FV_FILESYSTEM_FILE_INFO          *FvFileInfo;\r
+  LIST_ENTRY                       *Entry;\r
+  LIST_ENTRY                       *DelEntry;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *SimpleFile;\r
+\r
+  Status = gBS->OpenProtocol (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  (VOID **) &SimpleFile,\r
+                  DriverBinding->DriverBindingHandle,\r
+                  ControllerHandle,\r
+                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (SimpleFile);\r
+\r
+  if (IsListEmpty (&Instance->FileHead) == FALSE) {\r
+    //\r
+    // Not all opened files are closed\r
+    //\r
+    return EFI_DEVICE_ERROR;\r
+  }\r
+\r
+  //\r
+  // Close and uninstall protocols.\r
+  //\r
+  Status = gBS->CloseProtocol (\r
+                   ControllerHandle,\r
+                   &gEfiFirmwareVolume2ProtocolGuid,\r
+                   gImageHandle,\r
+                   ControllerHandle\r
+                   );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  Status = gBS->UninstallProtocolInterface (\r
+                  ControllerHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  &Instance->SimpleFs\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Free file structures\r
+  //\r
+  if (!IsListEmpty (&Instance->FileInfoHead)) {\r
+    //\r
+    // Free the Subtask list.\r
+    //\r
+    for(Entry = Instance->FileInfoHead.ForwardLink;\r
+        Entry != (&Instance->FileInfoHead);\r
+       ) {\r
+      DelEntry   = Entry;\r
+      Entry      = Entry->ForwardLink;\r
+      FvFileInfo = FVFS_FILE_INFO_FROM_LINK (DelEntry);\r
+\r
+      RemoveEntryList (DelEntry);\r
+      FreePool (FvFileInfo);\r
+    }\r
+  }\r
+\r
+  if (Instance->Root != NULL) {\r
+    //\r
+    // Root->Name is statically allocated, no need to free.\r
+    //\r
+    if (Instance->Root->FvFileInfo != NULL) {\r
+      FreePool (Instance->Root->FvFileInfo);\r
+    }\r
+    FreePool (Instance->Root);\r
+  }\r
+\r
+  //\r
+  // Free Instance\r
+  //\r
+  if (Instance->VolumeLabel != NULL) {\r
+    FreePool (Instance->VolumeLabel);\r
+  }\r
+  FreePool (Instance);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  The user Entry Point for module FvSimpleFileSystem. The user code starts with this function.\r
+\r
+  @param[in] ImageHandle    The firmware allocated handle for the EFI image.\r
+  @param[in] SystemTable    A pointer to the EFI System Table.\r
+\r
+  @retval EFI_SUCCESS       The entry point is executed successfully.\r
+  @retval other             Some error occurs when executing this entry point.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemEntryPoint (\r
+  IN EFI_HANDLE               ImageHandle,\r
+  IN EFI_SYSTEM_TABLE         *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS Status;\r
+\r
+  //\r
+  // Install driver model protocol(s).\r
+  //\r
+  Status = EfiLibInstallDriverBindingComponentName2 (\r
+             ImageHandle,\r
+             SystemTable,\r
+             &mDriverBinding,\r
+             ImageHandle,\r
+             &gFvSimpleFileSystemComponentName,\r
+             &gFvSimpleFileSystemComponentName2\r
+             );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  return Status;\r
+}\r
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni
new file mode 100644 (file)
index 0000000..7988ee5
Binary files /dev/null and b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemExtra.uni differ
diff --git a/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h b/MdeModulePkg/Universal/FvSimpleFileSystemDxe/FvSimpleFileSystemInternal.h
new file mode 100644 (file)
index 0000000..c8da5f6
--- /dev/null
@@ -0,0 +1,622 @@
+/** @file\r
+  The internal header file of FvSimpleFileSystem driver.\r
+\r
+Copyright (c) 2014, ARM Limited. All rights reserved.\r
+Copyright (c) 2014, Intel Corporation. All rights reserved.<BR>\r
+\r
+This program and the accompanying materials\r
+are licensed and made available under the terms and conditions of the BSD License\r
+which accompanies this distribution.  The full text of the license may be found at\r
+http://opensource.org/licenses/bsd-license.php\r
+\r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
+\r
+**/\r
+\r
+#ifndef __FVFS_INTERNAL_H__\r
+#define __FVFS_INTERNAL_H__\r
+\r
+#include <Uefi.h>\r
+#include <PiDxe.h>\r
+\r
+#include <Library/BaseLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/DebugLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/PrintLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/UefiLib.h>\r
+\r
+#include <Protocol/DriverBinding.h>\r
+#include <Protocol/FirmwareVolume2.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Protocol/UnicodeCollation.h>\r
+\r
+#include <Guid/FileSystemInfo.h>\r
+#include <Guid/FileInfo.h>\r
+#include <Guid/FileSystemVolumeLabelInfo.h>\r
+\r
+typedef struct _FV_FILESYSTEM_FILE       FV_FILESYSTEM_FILE;\r
+typedef struct _FV_FILESYSTEM_FILE_INFO  FV_FILESYSTEM_FILE_INFO;\r
+typedef struct _FV_FILESYSTEM_INSTANCE   FV_FILESYSTEM_INSTANCE;\r
+\r
+//\r
+// Struct representing an instance of the "filesystem". There will be one of\r
+// these structs per FV.\r
+//\r
+struct _FV_FILESYSTEM_INSTANCE {\r
+  UINT32                           Signature;\r
+  LIST_ENTRY                       FileInfoHead;\r
+  LIST_ENTRY                       FileHead;\r
+  EFI_DRIVER_BINDING_PROTOCOL      *DriverBinding;\r
+  EFI_FIRMWARE_VOLUME2_PROTOCOL    *FvProtocol;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  SimpleFs;\r
+  FV_FILESYSTEM_FILE               *Root;\r
+  CHAR16                           *VolumeLabel;\r
+};\r
+\r
+//\r
+// Struct representing a opening file. Each opening operation on file will \r
+// create such an instance except for the "root directory", which will only\r
+// be created once for each FV.\r
+//\r
+struct _FV_FILESYSTEM_FILE {\r
+  UINT32                           Signature;\r
+  LIST_ENTRY                       Link;\r
+  FV_FILESYSTEM_FILE_INFO          *DirReadNext;\r
+  FV_FILESYSTEM_INSTANCE           *Instance;\r
+  EFI_FILE_PROTOCOL                FileProtocol;\r
+  FV_FILESYSTEM_FILE_INFO          *FvFileInfo;\r
+  UINT64                           Position;\r
+};\r
+\r
+//\r
+// Struct representing the info of a file.\r
+//\r
+struct _FV_FILESYSTEM_FILE_INFO {\r
+  UINT32                           Signature;\r
+  LIST_ENTRY                       Link;\r
+  EFI_GUID                         NameGuid;\r
+  EFI_FV_FILETYPE                  Type;\r
+  EFI_FILE_INFO                    FileInfo;\r
+};\r
+\r
+#define FVFS_FILE_SIGNATURE        SIGNATURE_32 ('f', 'v', 'f', 'i')\r
+#define FVFS_FILE_INFO_SIGNATURE   SIGNATURE_32 ('f', 'v', 'i', 'n')\r
+#define FVFS_INSTANCE_SIGNATURE    SIGNATURE_32 ('f', 'v', 'f', 's')\r
+\r
+#define FVFS_INSTANCE_FROM_SIMPLE_FS_THIS(This) CR (  \\r
+          This,                                       \\r
+          FV_FILESYSTEM_INSTANCE,                     \\r
+          SimpleFs,                                   \\r
+          FVFS_INSTANCE_SIGNATURE                     \\r
+          )\r
+\r
+#define FVFS_FILE_FROM_FILE_THIS(This) CR (           \\r
+          This,                                       \\r
+          FV_FILESYSTEM_FILE,                         \\r
+          FileProtocol,                               \\r
+          FVFS_FILE_SIGNATURE                         \\r
+          )\r
+\r
+#define FVFS_FILE_INFO_FROM_LINK(This) CR (           \\r
+          This,                                       \\r
+          FV_FILESYSTEM_FILE_INFO,                    \\r
+          Link,                                       \\r
+          FVFS_FILE_INFO_SIGNATURE                    \\r
+          )\r
+\r
+#define FVFS_FILE_FROM_LINK(FileLink) CR (FileLink, FV_FILESYSTEM_FILE, Link, FVFS_FILE_SIGNATURE)\r
+\r
+#define FVFS_GET_FIRST_FILE(Instance) FVFS_FILE_FROM_LINK (GetFirstNode (&Instance->FileHead))\r
+\r
+#define FVFS_GET_FIRST_FILE_INFO(Instance) FVFS_FILE_INFO_FROM_LINK (GetFirstNode (&Instance->FileInfoHead))\r
+\r
+\r
+#define FV_FILETYPE_IS_EXECUTABLE(Type) ((Type) == EFI_FV_FILETYPE_PEIM                  || \\r
+                                         (Type) == EFI_FV_FILETYPE_DRIVER                || \\r
+                                         (Type) == EFI_FV_FILETYPE_COMBINED_PEIM_DRIVER  || \\r
+                                         (Type) == EFI_FV_FILETYPE_APPLICATION)\r
+\r
+/**\r
+  Open the root directory on a volume.\r
+\r
+  @param  This     A pointer to the volume to open the root directory.\r
+  @param  RootFile A pointer to the location to return the opened file handle for the\r
+                   root directory.\r
+\r
+  @retval EFI_SUCCESS          The device was opened.\r
+  @retval EFI_UNSUPPORTED      This volume does not support the requested file system type.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.\r
+  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.\r
+  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no\r
+                               longer supported. Any existing file handles for this volume are\r
+                               no longer valid. To access the files on the new medium, the\r
+                               volume must be reopened with OpenVolume().\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemOpenVolume (\r
+  IN     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,\r
+     OUT EFI_FILE_PROTOCOL               **RootFile\r
+  );\r
+\r
+/**\r
+  Test to see if this driver supports ControllerHandle.\r
+\r
+  @param  DriverBinding       Protocol instance pointer.\r
+  @param  ControllerHandle    Handle of device to test\r
+  @param  RemainingDevicePath Optional parameter use to pick a specific child\r
+                              device to start.\r
+\r
+  @retval EFI_SUCCESS         This driver supports this device\r
+  @retval EFI_ALREADY_STARTED This driver is already running on this device\r
+  @retval other               This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDriverSupported (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  );\r
+\r
+/**\r
+  Start this driver on ControllerHandle by opening a FV protocol and\r
+  installing a SimpleFileSystem protocol on ControllerHandle.\r
+\r
+  @param  DriverBinding        Protocol instance pointer.\r
+  @param  ControllerHandle     Handle of device to bind driver to\r
+  @param  RemainingDevicePath  Optional parameter use to pick a specific child\r
+                               device to start.\r
+\r
+  @retval EFI_SUCCESS          This driver is added to ControllerHandle\r
+  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle\r
+  @retval other                This driver does not support this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDriverStart (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,\r
+  IN  EFI_HANDLE                   ControllerHandle,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
+  );\r
+\r
+/**\r
+  Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing\r
+  the FV protocol on ControllerHandle.\r
+\r
+  @param  DriverBinding     Protocol instance pointer.\r
+  @param  ControllerHandle  Handle of device to stop driver on\r
+  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
+                            children is zero stop the entire bus driver.\r
+  @param  ChildHandleBuffer List of Child Handles to Stop.\r
+\r
+  @retval EFI_SUCCESS       This driver is removed ControllerHandle\r
+  @retval other             This driver was not removed from this device\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDriverStop (\r
+  IN  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding,\r
+  IN  EFI_HANDLE                        ControllerHandle,\r
+  IN  UINTN                             NumberOfChildren,\r
+  IN  EFI_HANDLE                        *ChildHandleBuffer OPTIONAL\r
+  );\r
+\r
+/**\r
+  Opens a new file relative to the source file's location.\r
+\r
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                     handle to the source location. This would typically be an open\r
+                     handle to a directory.\r
+  @param  NewHandle  A pointer to the location to return the opened handle for the new\r
+                     file.\r
+  @param  FileName   The Null-terminated string of the name of the file to be opened.\r
+                     The file name may contain the following path modifiers: "\", ".",\r
+                     and "..".\r
+  @param  OpenMode   The mode to open the file. The only valid combinations that the\r
+                     file may be opened with are: Read, Read/Write, or Create/Read/Write.\r
+  @param  Attributes Only valid for EFI_FILE_MODE_CREATE, in which case these are the\r
+                     attribute bits for the newly created file.\r
+\r
+  @retval EFI_SUCCESS          The file was opened.\r
+  @retval EFI_NOT_FOUND        The specified file could not be found on the device.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no\r
+                               longer supported.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  An attempt was made to create a file, or open a file for write\r
+                               when the media is write-protected.\r
+  @retval EFI_ACCESS_DENIED    The service denied access to the file.\r
+  @retval EFI_OUT_OF_RESOURCES Not enough resources were available to open the file.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemOpen (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+     OUT EFI_FILE_PROTOCOL    **NewHandle,\r
+  IN     CHAR16               *FileName,\r
+  IN     UINT64               OpenMode,\r
+  IN     UINT64               Attributes\r
+  );\r
+\r
+/**\r
+  Closes a specified file handle.\r
+\r
+  @param  This          A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                        handle to close.\r
+\r
+  @retval EFI_SUCCESS   The file was closed.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemClose (\r
+  IN EFI_FILE_PROTOCOL  *This\r
+  );\r
+\r
+/**\r
+  Reads data from a file.\r
+\r
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                     handle to read data from.\r
+  @param  BufferSize On input, the size of the Buffer. On output, the amount of data\r
+                     returned in Buffer. In both cases, the size is measured in bytes.\r
+  @param  Buffer     The buffer into which the data is read.\r
+\r
+  @retval EFI_SUCCESS          Data was read.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_DEVICE_ERROR     An attempt was made to read from a deleted file.\r
+  @retval EFI_DEVICE_ERROR     On entry, the current file position is beyond the end of the file.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory\r
+                               entry. BufferSize has been updated with the size\r
+                               needed to complete the request.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemRead (\r
+  IN     EFI_FILE_PROTOCOL      *This,\r
+  IN OUT UINTN                  *BufferSize,\r
+     OUT VOID                   *Buffer\r
+  );\r
+\r
+/**\r
+  Writes data to a file.\r
+\r
+  @param  This       A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                     handle to write data to.\r
+  @param  BufferSize On input, the size of the Buffer. On output, the amount of data\r
+                     actually written. In both cases, the size is measured in bytes.\r
+  @param  Buffer     The buffer of data to write.\r
+\r
+  @retval EFI_SUCCESS          Data was written.\r
+  @retval EFI_UNSUPPORTED      Writes to open directory files are not supported.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_DEVICE_ERROR     An attempt was made to write to a deleted file.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.\r
+  @retval EFI_ACCESS_DENIED    The file was opened read only.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemWrite (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+  IN OUT UINTN                *BufferSize,\r
+  IN     VOID                 *Buffer\r
+  );\r
+\r
+/**\r
+  Returns a file's current position.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                          handle to get the current position on.\r
+  @param  Position        The address to return the file's current position value.\r
+\r
+  @retval EFI_SUCCESS      The position was returned.\r
+  @retval EFI_UNSUPPORTED  The request is not valid on open directories.\r
+  @retval EFI_DEVICE_ERROR An attempt was made to get the position from a deleted file.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemGetPosition (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+     OUT UINT64               *Position\r
+  );\r
+\r
+/**\r
+  Sets a file's current position.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the\r
+                          file handle to set the requested position on.\r
+  @param  Position        The byte position from the start of the file to set.\r
+\r
+  @retval EFI_SUCCESS      The position was set.\r
+  @retval EFI_UNSUPPORTED  The seek request for nonzero is not valid on open\r
+                           directories.\r
+  @retval EFI_DEVICE_ERROR An attempt was made to set the position of a deleted file.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemSetPosition (\r
+  IN EFI_FILE_PROTOCOL        *This,\r
+  IN UINT64                   Position\r
+  );\r
+\r
+/**\r
+  Flushes all modified data associated with a file to a device.\r
+\r
+  @param  This A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+               handle to flush.\r
+\r
+  @retval EFI_SUCCESS          The data was flushed.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  The file or medium is write-protected.\r
+  @retval EFI_ACCESS_DENIED    The file was opened read-only.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemFlush (\r
+  IN EFI_FILE_PROTOCOL  *This\r
+  );\r
+\r
+/**\r
+  Close and delete the file handle.\r
+\r
+  @param  This                     A pointer to the EFI_FILE_PROTOCOL instance that is the\r
+                                   handle to the file to delete.\r
+\r
+  @retval EFI_SUCCESS              The file was closed and deleted, and the handle was closed.\r
+  @retval EFI_WARN_DELETE_FAILURE  The handle was closed, but the file was not deleted.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemDelete (\r
+  IN EFI_FILE_PROTOCOL *This\r
+  );\r
+\r
+/**\r
+  Returns information about a file.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                          handle the requested information is for.\r
+  @param  InformationType The type identifier for the information being requested.\r
+  @param  BufferSize      On input, the size of Buffer. On output, the amount of data\r
+                          returned in Buffer. In both cases, the size is measured in bytes.\r
+  @param  Buffer          A pointer to the data buffer to return. The buffer's type is\r
+                          indicated by InformationType.\r
+\r
+  @retval EFI_SUCCESS          The information was returned.\r
+  @retval EFI_UNSUPPORTED      The InformationType is not known.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_BUFFER_TOO_SMALL The BufferSize is too small to read the current directory entry.\r
+                               BufferSize has been updated with the size needed to complete\r
+                               the request.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemGetInfo (\r
+  IN     EFI_FILE_PROTOCOL    *This,\r
+  IN     EFI_GUID             *InformationType,\r
+  IN OUT UINTN                *BufferSize,\r
+     OUT VOID                 *Buffer\r
+  );\r
+\r
+/**\r
+  Sets information about a file.\r
+\r
+  @param  This            A pointer to the EFI_FILE_PROTOCOL instance that is the file\r
+                          handle the information is for.\r
+  @param  InformationType The type identifier for the information being set.\r
+  @param  BufferSize      The size, in bytes, of Buffer.\r
+  @param  Buffer          A pointer to the data buffer to write. The buffer's type is\r
+                          indicated by InformationType.\r
+\r
+  @retval EFI_SUCCESS          The information was set.\r
+  @retval EFI_UNSUPPORTED      The InformationType is not known.\r
+  @retval EFI_NO_MEDIA         The device has no medium.\r
+  @retval EFI_DEVICE_ERROR     The device reported an error.\r
+  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.\r
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_INFO_ID and the media is\r
+                               read-only.\r
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_PROTOCOL_SYSTEM_INFO_ID\r
+                               and the media is read only.\r
+  @retval EFI_WRITE_PROTECTED  InformationType is EFI_FILE_SYSTEM_VOLUME_LABEL_ID\r
+                               and the media is read-only.\r
+  @retval EFI_ACCESS_DENIED    An attempt is made to change the name of a file to a\r
+                               file that is already present.\r
+  @retval EFI_ACCESS_DENIED    An attempt is being made to change the EFI_FILE_DIRECTORY\r
+                               Attribute.\r
+  @retval EFI_ACCESS_DENIED    An attempt is being made to change the size of a directory.\r
+  @retval EFI_ACCESS_DENIED    InformationType is EFI_FILE_INFO_ID and the file was opened\r
+                               read-only and an attempt is being made to modify a field\r
+                               other than Attribute.\r
+  @retval EFI_VOLUME_FULL      The volume is full.\r
+  @retval EFI_BAD_BUFFER_SIZE  BufferSize is smaller than the size of the type indicated\r
+                               by InformationType.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemSetInfo (\r
+  IN EFI_FILE_PROTOCOL        *This,\r
+  IN EFI_GUID                 *InformationType,\r
+  IN UINTN                    BufferSize,\r
+  IN VOID                     *Buffer\r
+  );\r
+\r
+/**\r
+  Get the size of the buffer that will be returned by FvFsReadFile.\r
+\r
+  @param  FvProtocol                  A pointer to the EFI_FIRMWARE_VOLUME2_PROTOCOL instance.\r
+  @param  FvFileInfo                  A pointer to the FV_FILESYSTEM_FILE_INFO instance that is a struct\r
+                                      representing a file's info.\r
+\r
+  @retval EFI_SUCCESS                 The file size was gotten correctly.\r
+  @retval Others                      The file size wasn't gotten correctly.\r
+\r
+**/\r
+EFI_STATUS\r
+FvFsGetFileSize (\r
+  IN     EFI_FIRMWARE_VOLUME2_PROTOCOL     *FvProtocol,\r
+  IN OUT FV_FILESYSTEM_FILE_INFO           *FvFileInfo\r
+  );\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the driver.\r
+\r
+  This function retrieves the user readable name of a driver in the form of a\r
+  Unicode string. If the driver specified by This has a user readable name in\r
+  the language specified by Language, then a pointer to the driver name is\r
+  returned in DriverName, and EFI_SUCCESS is returned. If the driver specified\r
+  by This does not support the language specified by Language,\r
+  then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language. This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified\r
+                                in RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  DriverName[out]       A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                driver specified by This in the language\r
+                                specified by Language.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the Driver specified by\r
+                                This and the language specified by Language was\r
+                                returned in DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER DriverName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemComponentNameGetDriverName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL  *This,\r
+  IN  CHAR8                        *Language,\r
+  OUT CHAR16                       **DriverName\r
+  );\r
+\r
+/**\r
+  Retrieves a Unicode string that is the user readable name of the controller\r
+  that is being managed by a driver.\r
+\r
+  This function retrieves the user readable name of the controller specified by\r
+  ControllerHandle and ChildHandle in the form of a Unicode string. If the\r
+  driver specified by This has a user readable name in the language specified by\r
+  Language, then a pointer to the controller name is returned in ControllerName,\r
+  and EFI_SUCCESS is returned.  If the driver specified by This is not currently\r
+  managing the controller specified by ControllerHandle and ChildHandle,\r
+  then EFI_UNSUPPORTED is returned.  If the driver specified by This does not\r
+  support the language specified by Language, then EFI_UNSUPPORTED is returned.\r
+\r
+  @param  This[in]              A pointer to the EFI_COMPONENT_NAME2_PROTOCOL or\r
+                                EFI_COMPONENT_NAME_PROTOCOL instance.\r
+\r
+  @param  ControllerHandle[in]  The handle of a controller that the driver\r
+                                specified by This is managing.  This handle\r
+                                specifies the controller whose name is to be\r
+                                returned.\r
+\r
+  @param  ChildHandle[in]       The handle of the child controller to retrieve\r
+                                the name of.  This is an optional parameter that\r
+                                may be NULL.  It will be NULL for device\r
+                                drivers.  It will also be NULL for a bus drivers\r
+                                that wish to retrieve the name of the bus\r
+                                controller.  It will not be NULL for a bus\r
+                                driver that wishes to retrieve the name of a\r
+                                child controller.\r
+\r
+  @param  Language[in]          A pointer to a Null-terminated ASCII string\r
+                                array indicating the language.  This is the\r
+                                language of the driver name that the caller is\r
+                                requesting, and it must match one of the\r
+                                languages specified in SupportedLanguages. The\r
+                                number of languages supported by a driver is up\r
+                                to the driver writer. Language is specified in\r
+                                RFC 4646 or ISO 639-2 language code format.\r
+\r
+  @param  ControllerName[out]   A pointer to the Unicode string to return.\r
+                                This Unicode string is the name of the\r
+                                controller specified by ControllerHandle and\r
+                                ChildHandle in the language specified by\r
+                                Language from the point of view of the driver\r
+                                specified by This.\r
+\r
+  @retval EFI_SUCCESS           The Unicode string for the user readable name in\r
+                                the language specified by Language for the\r
+                                driver specified by This was returned in\r
+                                DriverName.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerHandle is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ChildHandle is not NULL and it is not a valid\r
+                                EFI_HANDLE.\r
+\r
+  @retval EFI_INVALID_PARAMETER Language is NULL.\r
+\r
+  @retval EFI_INVALID_PARAMETER ControllerName is NULL.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This is not currently\r
+                                managing the controller specified by\r
+                                ControllerHandle and ChildHandle.\r
+\r
+  @retval EFI_UNSUPPORTED       The driver specified by This does not support\r
+                                the language specified by Language.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FvSimpleFileSystemComponentNameGetControllerName (\r
+  IN  EFI_COMPONENT_NAME_PROTOCOL                     *This,\r
+  IN  EFI_HANDLE                                      ControllerHandle,\r
+  IN  EFI_HANDLE                                      ChildHandle        OPTIONAL,\r
+  IN  CHAR8                                           *Language,\r
+  OUT CHAR16                                          **ControllerName\r
+  );\r
+\r
+extern EFI_UNICODE_COLLATION_PROTOCOL  *mUnicodeCollation;\r
+extern EFI_FILE_PROTOCOL               mFileSystemTemplate;\r
+extern EFI_COMPONENT_NAME_PROTOCOL     gFvSimpleFileSystemComponentName;\r
+extern EFI_COMPONENT_NAME2_PROTOCOL    gFvSimpleFileSystemComponentName2;\r
+\r
+#endif
\ No newline at end of file