]> git.proxmox.com Git - mirror_edk2.git/commitdiff
MdeModulePkg FileExplorerLib: Change file format which has mixed file format.
authorEric Dong <eric.dong@intel.com>
Wed, 16 Dec 2015 03:21:44 +0000 (03:21 +0000)
committerydong10 <ydong10@Edk2>
Wed, 16 Dec 2015 03:21:44 +0000 (03:21 +0000)
Contributed-under: TianoCore Contribution Agreement 1.0
Signed-off-by: Eric Dong <eric.dong@intel.com>
Reviewed-by: Liming Gao <liming.gao@intel.com>
git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@19297 6f19259b-4bc3-4df7-8a09-765794883524

MdeModulePkg/Library/FileExplorerLib/FileExplorer.c
MdeModulePkg/Library/FileExplorerLib/FileExplorer.h
MdeModulePkg/Library/FileExplorerLib/FileExplorerLib.inf
MdeModulePkg/Library/FileExplorerLib/FileExplorerVfr.vfr
MdeModulePkg/Library/FileExplorerLib/FormGuid.h

index 65e4785921e91a7a3bf54b230e151de2fe6a7a13..c64a94bebe5972b2b3e25ecc9cd477b2809bd520 100644 (file)
-/** @file
-File explorer related functions.
-
-Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are licensed and made available under
-the terms and conditions of the BSD License that accompanies this distribution.
-The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php.
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-
-#include "FileExplorer.h"
-
-EFI_GUID FileExplorerGuid       = EFI_FILE_EXPLORE_FORMSET_GUID;
-
-///
-/// File system selection menu
-///
-MENU_OPTION      mFsOptionMenu = {
-  MENU_OPTION_SIGNATURE,
-  {NULL},
-  0,
-  FALSE
-};
-
-FILE_EXPLORER_CALLBACK_DATA  gFileExplorerPrivate = {
-  FILE_EXPLORER_CALLBACK_DATA_SIGNATURE,
-  NULL,
-  NULL,
-  {
-    LibExtractConfig,
-    LibRouteConfig,
-    LibCallback
-  },
-  NULL,
-  &mFsOptionMenu,
-  0
-};
-
-HII_VENDOR_DEVICE_PATH  *gHiiVendorDevicePath;
-
-HII_VENDOR_DEVICE_PATH  FeHiiVendorDevicePath = {
-  {
-    {
-      HARDWARE_DEVICE_PATH,
-      HW_VENDOR_DP,
-      {
-        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
-        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
-      }
-    },
-    //
-    // Will be replace with gEfiCallerIdGuid in code.
-    //
-    { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }
-  },
-  {
-    END_DEVICE_PATH_TYPE,
-    END_ENTIRE_DEVICE_PATH_SUBTYPE,
-    { 
-      (UINT8) (END_DEVICE_PATH_LENGTH),
-      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
-    }
-  }
-};
-
-VOID                *mLibStartOpCodeHandle = NULL;
-VOID                *mLibEndOpCodeHandle = NULL;
-EFI_IFR_GUID_LABEL  *mLibStartLabel = NULL;
-EFI_IFR_GUID_LABEL  *mLibEndLabel = NULL;
-
-/**
-  This function allows a caller to extract the current configuration for one
-  or more named elements from the target driver.
-
-
-  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
-  @param Request         A null-terminated Unicode string in <ConfigRequest> format.
-  @param Progress        On return, points to a character in the Request string.
-                         Points to the string's null terminator if request was successful.
-                         Points to the most recent '&' before the first failing name/value
-                         pair (or the beginning of the string if the failure is in the
-                         first name/value pair) if the request was not successful.
-  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which
-                         has all values filled in for the names in the Request string.
-                         String to be allocated by the called function.
-
-  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.
-  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibExtractConfig (
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
-  IN  CONST EFI_STRING                       Request,
-  OUT EFI_STRING                             *Progress,
-  OUT EFI_STRING                             *Results
-  )
-{
-  if (Progress == NULL || Results == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  *Progress = Request;
-  return EFI_NOT_FOUND;
-}
-
-/**
-  This function processes the results of changes in configuration.
-
-
-  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
-  @param Configuration   A null-terminated Unicode string in <ConfigResp> format.
-  @param Progress        A pointer to a string filled in with the offset of the most
-                         recent '&' before the first failing name/value pair (or the
-                         beginning of the string if the failure is in the first
-                         name/value pair) or the terminating NULL if all was successful.
-
-  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.
-  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibRouteConfig (
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
-  IN  CONST EFI_STRING                       Configuration,
-  OUT EFI_STRING                             *Progress
-  )
-{
-  if (Configuration == NULL || Progress == NULL) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  *Progress = Configuration;
-  return EFI_NOT_FOUND;
-}
-
-/**
-  This function processes the results of changes in configuration.
-  When user select a interactive opcode, this callback will be triggered.
-  Based on the Question(QuestionId) that triggers the callback, the corresponding
-  actions is performed. It handles:
-
-  1) Process the axtra action or exit file explorer when user select one file .
-  2) update of file content if a dir is selected.
-
-  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
-  @param Action          Specifies the type of action taken by the browser.
-  @param QuestionId      A unique value which is sent to the original exporting driver
-                         so that it can identify the type of data to expect.
-  @param Type            The type of value for the question.
-  @param Value           A pointer to the data being sent to the original exporting driver.
-  @param ActionRequest   On return, points to the action requested by the callback function.
-
-  @retval  EFI_SUCCESS           The callback successfully handled the action.
-  @retval  other error           Error occur when parse one directory.
-**/
-EFI_STATUS
-EFIAPI
-LibCallback (
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
-  IN  EFI_BROWSER_ACTION                     Action,
-  IN  EFI_QUESTION_ID                        QuestionId,
-  IN  UINT8                                  Type,
-  IN  EFI_IFR_TYPE_VALUE                     *Value,
-  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
-  )
-{
-  EFI_STATUS    Status;
-  BOOLEAN       NeedExit;
-
-  NeedExit = TRUE;
-  
-  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
-    //
-    // Do nothing for other UEFI Action. Only do call back when data is changed.
-    //
-    return EFI_UNSUPPORTED;
-  }
-
-  *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
-
-  if (Action == EFI_BROWSER_ACTION_CHANGED) {
-    if ((Value == NULL) || (ActionRequest == NULL)) {
-      return EFI_INVALID_PARAMETER;
-    }
-    
-    if (QuestionId >= FILE_OPTION_OFFSET) {
-      LibGetDevicePath(QuestionId);
-
-      //
-      // Process the extra action.
-      //
-      if (gFileExplorerPrivate.ChooseHandler != NULL) {
-        NeedExit = gFileExplorerPrivate.ChooseHandler (gFileExplorerPrivate.RetDevicePath);
-      }
-
-      if (NeedExit) {
-        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
-      }
-    }
-  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
-    if (Value == NULL) {
-      return EFI_INVALID_PARAMETER;
-    }
-    
-    if (QuestionId >= FILE_OPTION_OFFSET) {
-      Status = LibUpdateFileExplorer (QuestionId);
-      if (EFI_ERROR (Status)) {
-        return Status;
-      }
-    }
-  }
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Create a menu entry by given menu type.
-
-  @retval NULL           If failed to create the menu.
-  @return the new menu entry.
-
-**/
-MENU_ENTRY *
-LibCreateMenuEntry (
-  VOID
-  )
-{
-  MENU_ENTRY *MenuEntry;
-
-  //
-  // Create new menu entry
-  //
-  MenuEntry = AllocateZeroPool (sizeof (MENU_ENTRY));
-  if (MenuEntry == NULL) {
-    return NULL;
-  }
-
-  MenuEntry->VariableContext = AllocateZeroPool (sizeof (FILE_CONTEXT));
-  if (MenuEntry->VariableContext == NULL) {
-    FreePool (MenuEntry);
-    return NULL;
-  }
-
-  MenuEntry->Signature        = MENU_ENTRY_SIGNATURE;
-  return MenuEntry;
-}
-
-
-/**
-  Get the Menu Entry from the list in Menu Entry List.
-
-  If MenuNumber is great or equal to the number of Menu
-  Entry in the list, then ASSERT.
-
-  @param MenuOption      The Menu Entry List to read the menu entry.
-  @param MenuNumber      The index of Menu Entry.
-
-  @return The Menu Entry.
-
-**/
-MENU_ENTRY *
-LibGetMenuEntry (
-  MENU_OPTION         *MenuOption,
-  UINTN               MenuNumber
-  )
-{
-  MENU_ENTRY      *NewMenuEntry;
-  UINTN           Index;
-  LIST_ENTRY      *List;
-
-  ASSERT (MenuNumber < MenuOption->MenuNumber);
-
-  List = MenuOption->Head.ForwardLink;
-  for (Index = 0; Index < MenuNumber; Index++) {
-    List = List->ForwardLink;
-  }
-
-  NewMenuEntry = CR (List, MENU_ENTRY, Link, MENU_ENTRY_SIGNATURE);
-
-  return NewMenuEntry;
-}
-
-/**
-  Free up all resource allocated for a BM_MENU_ENTRY.
-
-  @param MenuEntry   A pointer to BM_MENU_ENTRY.
-
-**/
-VOID
-LibDestroyMenuEntry (
-  MENU_ENTRY         *MenuEntry
-  )
-{
-  FILE_CONTEXT           *FileContext;
-
-  FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext;
-
-  if (!FileContext->IsRoot) {
-    FreePool (FileContext->DevicePath);
-  } else {
-    if (FileContext->FileHandle != NULL) {
-      FileContext->FileHandle->Close (FileContext->FileHandle);
-    }
-  }
-
-  if (FileContext->FileName != NULL) {
-    FreePool (FileContext->FileName);
-  }
-
-  FreePool (FileContext);
-
-  FreePool (MenuEntry->DisplayString);
-  if (MenuEntry->HelpString != NULL) {
-    FreePool (MenuEntry->HelpString);
-  }
-
-  FreePool (MenuEntry);
-}
-
-
-/**
-  Free resources allocated in Allocate Rountine.
-
-  @param FreeMenu        Menu to be freed
-**/
-VOID
-LibFreeMenu (
-  MENU_OPTION        *FreeMenu
-  )
-{
-  MENU_ENTRY *MenuEntry;
-  while (!IsListEmpty (&FreeMenu->Head)) {
-    MenuEntry = CR (
-                  FreeMenu->Head.ForwardLink,
-                  MENU_ENTRY,
-                  Link,
-                  MENU_ENTRY_SIGNATURE
-                  );
-    RemoveEntryList (&MenuEntry->Link);
-    LibDestroyMenuEntry (MenuEntry);
-  }
-  FreeMenu->MenuNumber = 0;
-}
-
-/**
-
-  Function opens and returns a file handle to the root directory of a volume.
-
-  @param DeviceHandle    A handle for a device
-
-  @return A valid file handle or NULL is returned
-
-**/
-EFI_FILE_HANDLE
-LibOpenRoot (
-  IN EFI_HANDLE                   DeviceHandle
-  )
-{
-  EFI_STATUS                      Status;
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;
-  EFI_FILE_HANDLE                 File;
-
-  File = NULL;
-
-  //
-  // File the file system interface to the device
-  //
-  Status = gBS->HandleProtocol (
-                  DeviceHandle,
-                  &gEfiSimpleFileSystemProtocolGuid,
-                  (VOID *) &Volume
-                  );
-
-  //
-  // Open the root directory of the volume
-  //
-  if (!EFI_ERROR (Status)) {
-    Status = Volume->OpenVolume (
-                      Volume,
-                      &File
-                      );
-  }
-  //
-  // Done
-  //
-  return EFI_ERROR (Status) ? NULL : File;
-}
-
-/**
-  This function converts an input device structure to a Unicode string.
-
-  @param DevPath                  A pointer to the device path structure.
-
-  @return A new allocated Unicode string that represents the device path.
-
-**/
-CHAR16 *
-LibDevicePathToStr (
-  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath
-  )
-{
-  EFI_STATUS                       Status;
-  CHAR16                           *ToText;
-  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
-
-  if (DevPath == NULL) {
-    return NULL;
-  }
-
-  Status = gBS->LocateProtocol (
-                  &gEfiDevicePathToTextProtocolGuid,
-                  NULL,
-                  (VOID **) &DevPathToText
-                  );
-  ASSERT_EFI_ERROR (Status);
-  ToText = DevPathToText->ConvertDevicePathToText (
-                            DevPath,
-                            FALSE,
-                            TRUE
-                            );
-  ASSERT (ToText != NULL);
-
-  return ToText;
-}
-
-/**
-  Duplicate a string.
-
-  @param Src             The source.
-
-  @return A new string which is duplicated copy of the source.
-  @retval NULL If there is not enough memory.
-
-**/
-CHAR16 *
-LibStrDuplicate (
-  IN CHAR16   *Src
-  )
-{
-  CHAR16  *Dest;
-  UINTN   Size;
-
-  Size  = StrSize (Src);
-  Dest  = AllocateZeroPool (Size);
-  ASSERT (Dest != NULL);
-  if (Dest != NULL) {
-    CopyMem (Dest, Src, Size);
-  }
-
-  return Dest;
-}
-
-/**
-
-  Function gets the file information from an open file descriptor, and stores it
-  in a buffer allocated from pool.
-
-  @param FHand           File Handle.
-  @param InfoType        Info type need to get.
-
-  @retval                A pointer to a buffer with file information or NULL is returned
-
-**/
-VOID *
-LibFileInfo (
-  IN EFI_FILE_HANDLE      FHand,
-  IN EFI_GUID             *InfoType
-  )
-{
-  EFI_STATUS    Status;
-  EFI_FILE_INFO *Buffer;
-  UINTN         BufferSize;
-
-  Buffer      = NULL;
-  BufferSize  = 0;
-  
-  Status = FHand->GetInfo (
-                    FHand,
-                    InfoType,
-                    &BufferSize,
-                    Buffer
-                    );
-  if (Status == EFI_BUFFER_TOO_SMALL) {
-    Buffer = AllocatePool (BufferSize);
-    ASSERT (Buffer != NULL);
-  }
-
-  Status = FHand->GetInfo (
-                    FHand,
-                    InfoType,
-                    &BufferSize,
-                    Buffer
-                    );
-
-  return Buffer;
-}
-
-/**
-
-  Get file type base on the file name.
-  Just cut the file name, from the ".". eg ".efi"
-
-  @param FileName  File need to be checked.
-
-  @retval the file type string.
-
-**/
-CHAR16*
-LibGetTypeFromName (
-  IN CHAR16   *FileName
-  )
-{
-  UINTN    Index;
-
-  Index = StrLen (FileName) - 1;
-  while ((FileName[Index] != L'.') && (Index != 0)) {
-    Index--;
-  }
-
-  return Index == 0 ? NULL : &FileName[Index];
-}
-
-/**
-  Converts the unicode character of the string from uppercase to lowercase.
-  This is a internal function.
-
-  @param ConfigString  String to be converted
-
-**/
-VOID
-LibToLowerString (
-  IN CHAR16  *String
-  )
-{
-  CHAR16      *TmpStr;
-
-  for (TmpStr = String; *TmpStr != L'\0'; TmpStr++) {
-    if (*TmpStr >= L'A' && *TmpStr <= L'Z') {
-      *TmpStr = (CHAR16) (*TmpStr - L'A' + L'a');
-    }
-  }
-}
-
-/**
-
-  Check whether current FileName point to a valid
-  Efi Image File.
-
-  @param FileName  File need to be checked.
-
-  @retval TRUE  Is Efi Image
-  @retval FALSE Not a valid Efi Image
-
-**/
-BOOLEAN
-LibIsSupportedFileType (
-  IN UINT16  *FileName
-  )
-{
-  CHAR16     *InputFileType;
-  CHAR16     *TmpStr;
-  BOOLEAN    IsSupported;
-
-  if (gFileExplorerPrivate.FileType == NULL) {
-    return TRUE;
-  }
-
-  InputFileType = LibGetTypeFromName (FileName);
-  //
-  // If the file not has *.* style, always return TRUE.
-  //
-  if (InputFileType == NULL) {
-    return TRUE;
-  }
-
-  TmpStr = AllocateCopyPool (StrSize (InputFileType), InputFileType);
-  LibToLowerString(TmpStr);
-
-  IsSupported = (StrStr (gFileExplorerPrivate.FileType, TmpStr) == NULL ? FALSE : TRUE);
-
-  FreePool (TmpStr);
-  return IsSupported;
-}
-
-/**
-
-  Append file name to existing file name.
-
-  @param Str1  The existing file name
-  @param Str2  The file name to be appended
-
-  @return Allocate a new string to hold the appended result.
-          Caller is responsible to free the returned string.
-
-**/
-CHAR16 *
-LibAppendFileName (
-  IN  CHAR16  *Str1,
-  IN  CHAR16  *Str2
-  )
-{
-  UINTN   Size1;
-  UINTN   Size2;
-  UINTN   MaxLen;
-  CHAR16  *Str;
-  CHAR16  *TmpStr;
-  CHAR16  *Ptr;
-  CHAR16  *LastSlash;
-
-  Size1 = StrSize (Str1);
-  Size2 = StrSize (Str2);
-  MaxLen = (Size1 + Size2 + sizeof (CHAR16))/ sizeof (CHAR16);
-  Str   = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));
-  ASSERT (Str != NULL);
-
-  TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); 
-  ASSERT (TmpStr != NULL);
-
-  StrCpyS (Str, MaxLen, Str1);
-  if (!((*Str == '\\') && (*(Str + 1) == 0))) {
-    StrCatS (Str, MaxLen, L"\\");
-  }
-
-  StrCatS (Str, MaxLen, Str2);
-
-  Ptr       = Str;
-  LastSlash = Str;
-  while (*Ptr != 0) {
-    if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) == L'\\') {
-      //
-      // Convert "\Name\..\" to "\"
-      // DO NOT convert the .. if it is at the end of the string. This will
-      // break the .. behavior in changing directories.
-      //
-
-      //
-      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings 
-      // that overlap.
-      //
-      StrCpyS (TmpStr, MaxLen, Ptr + 3);
-      StrCpyS (LastSlash, MaxLen - (UINTN) (LastSlash - Str), TmpStr);
-      Ptr = LastSlash;
-    } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {
-      //
-      // Convert a "\.\" to a "\"
-      //
-
-      //
-      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings 
-      // that overlap.
-      //
-      StrCpyS (TmpStr, MaxLen, Ptr + 2);
-      StrCpyS (Ptr, MaxLen - (UINTN) (Ptr - Str), TmpStr);
-      Ptr = LastSlash;
-    } else if (*Ptr == '\\') {
-      LastSlash = Ptr;
-    }
-
-    Ptr++;
-  }
-
-  FreePool (TmpStr);
-  
-  return Str;
-}
-
-/**
-  This function build the FsOptionMenu list which records all
-  available file system in the system. They includes all instances
-  of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM.
-
-
-  @retval  EFI_SUCCESS             Success find the file system
-  @retval  EFI_OUT_OF_RESOURCES    Can not create menu entry
-
-**/
-EFI_STATUS
-LibFindFileSystem (
-  VOID
-  )
-{
-  UINTN                        NoSimpleFsHandles;
-  UINTN                        NoLoadFileHandles;
-  EFI_HANDLE                   *SimpleFsHandle;
-  EFI_HANDLE                   *LoadFileHandle;
-  UINT16                       *VolumeLabel;
-  UINTN                        Index;
-  EFI_STATUS                   Status;
-  MENU_ENTRY                   *MenuEntry;
-  FILE_CONTEXT                 *FileContext;
-  UINTN                        OptionNumber;
-  EFI_FILE_SYSTEM_VOLUME_LABEL *Info;
-
-  NoSimpleFsHandles = 0;
-  NoLoadFileHandles = 0;
-  OptionNumber      = 0;
-
-  //
-  // Locate Handles that support Simple File System protocol
-  //
-  Status = gBS->LocateHandleBuffer (
-                  ByProtocol,
-                  &gEfiSimpleFileSystemProtocolGuid,
-                  NULL,
-                  &NoSimpleFsHandles,
-                  &SimpleFsHandle
-                  );
-  if (!EFI_ERROR (Status)) {
-    //
-    // Find all the instances of the File System prototocol
-    //
-    for (Index = 0; Index < NoSimpleFsHandles; Index++) {
-      //
-      // Allocate pool for this load option
-      //
-      MenuEntry = LibCreateMenuEntry ();
-      if (NULL == MenuEntry) {
-        FreePool (SimpleFsHandle);
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext;
-      FileContext->DeviceHandle = SimpleFsHandle[Index];
-      FileContext->FileHandle = LibOpenRoot (FileContext->DeviceHandle);
-      if (FileContext->FileHandle == NULL) {
-        LibDestroyMenuEntry (MenuEntry);
-        continue;
-      }
-
-      MenuEntry->HelpString = LibDevicePathToStr (DevicePathFromHandle (FileContext->DeviceHandle));
-      FileContext->FileName = LibStrDuplicate (L"\\");
-      FileContext->DevicePath = FileDevicePath (FileContext->DeviceHandle, FileContext->FileName);
-      FileContext->IsDir = TRUE;
-      FileContext->IsRoot = TRUE;
-
-      //
-      // Get current file system's Volume Label
-      //
-      Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *) LibFileInfo (FileContext->FileHandle, &gEfiFileSystemVolumeLabelInfoIdGuid);
-      if (Info == NULL) {
-        VolumeLabel = L"NO FILE SYSTEM INFO";
-      } else {
-        if (Info->VolumeLabel == NULL) {
-          VolumeLabel = L"NULL VOLUME LABEL";
-        } else {
-          VolumeLabel = Info->VolumeLabel;
-          if (*VolumeLabel == 0x0000) {
-            VolumeLabel = L"NO VOLUME LABEL";
-          }
-        }
-      }
-      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);
-      ASSERT (MenuEntry->DisplayString != NULL);
-      UnicodeSPrint (
-        MenuEntry->DisplayString,
-        MAX_CHAR,
-        L"%s, [%s]",
-        VolumeLabel,
-        MenuEntry->HelpString
-        );
-         MenuEntry->DisplayStringToken = HiiSetString (
-                                             gFileExplorerPrivate.FeHiiHandle,
-                                             0,
-                                             MenuEntry->DisplayString,
-                                             NULL
-                                             );
-      FreePool (Info);
-
-      OptionNumber++;
-      InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link);
-    }
-  }
-
-  if (NoSimpleFsHandles != 0) {
-    FreePool (SimpleFsHandle);
-  }
-
-  //
-  // Searching for handles that support Load File protocol
-  //
-  Status = gBS->LocateHandleBuffer (
-                  ByProtocol,
-                  &gEfiLoadFileProtocolGuid,
-                  NULL,
-                  &NoLoadFileHandles,
-                  &LoadFileHandle
-                  );
-
-  if (!EFI_ERROR (Status)) {
-    for (Index = 0; Index < NoLoadFileHandles; Index++) {
-      MenuEntry = LibCreateMenuEntry ();
-      if (NULL == MenuEntry) {
-        FreePool (LoadFileHandle);
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext;
-      FileContext->DeviceHandle = LoadFileHandle[Index];
-      FileContext->IsRoot = TRUE;
-
-      FileContext->DevicePath = DevicePathFromHandle (FileContext->DeviceHandle);
-      FileContext->FileName = LibDevicePathToStr (FileContext->DevicePath);
-
-      MenuEntry->HelpString = LibDevicePathToStr (FileContext->DevicePath);
-      MenuEntry->DisplayString = AllocateZeroPool (MAX_CHAR);
-      ASSERT (MenuEntry->DisplayString != NULL);
-      UnicodeSPrint (
-        MenuEntry->DisplayString,
-        MAX_CHAR,
-        L"Load File [%s]",
-        MenuEntry->HelpString
-        );
-      MenuEntry->DisplayStringToken = HiiSetString (
-                                           gFileExplorerPrivate.FeHiiHandle,
-                                           0,
-                                           MenuEntry->DisplayString,
-                                           NULL
-                                           );
-
-      OptionNumber++;
-      InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link);
-    }
-  }
-
-  if (NoLoadFileHandles != 0) {
-    FreePool (LoadFileHandle);
-  }
-
-  gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber;
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Find the file handle from the input menu info.
-  
-  @param  MenuEntry        Input Menu info.
-  @param  RetFileHandle    Return the file handle for the input device path.
-  
-  @retval EFI_SUCESS       Find the file handle success.
-  @retval Other            Find the file handle failure.
-**/
-EFI_STATUS
-LibGetFileHandleFromMenu (
-  IN  MENU_ENTRY                *MenuEntry,  
-  OUT EFI_FILE_HANDLE           *RetFileHandle
-  )
-{
-  EFI_FILE_HANDLE Dir;
-  EFI_FILE_HANDLE NewDir;
-  FILE_CONTEXT    *FileContext;
-  EFI_STATUS      Status;
-
-  FileContext   = (FILE_CONTEXT *) MenuEntry->VariableContext;
-  Dir           = FileContext->FileHandle;
-
-  //
-  // Open current directory to get files from it
-  //
-  Status = Dir->Open (
-                  Dir,
-                  &NewDir,
-                  FileContext->FileName,
-                  EFI_FILE_READ_ONLY,
-                  0
-                  );
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  if (!FileContext->IsRoot) {
-    Dir->Close (Dir);
-  }
-
-  *RetFileHandle = NewDir;
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Find the file handle from the input device path info.
-  
-  @param  RootDirectory    Device path info.
-  @param  RetFileHandle    Return the file handle for the input device path.
-  @param  ParentFileName   Parent file name.
-  @param  DeviceHandle     Driver handle for this partition.
-  
-  @retval EFI_SUCESS       Find the file handle success.
-  @retval Other            Find the file handle failure.
-**/
-EFI_STATUS
-LibGetFileHandleFromDevicePath (
-  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,  
-  OUT EFI_FILE_HANDLE           *RetFileHandle,
-  OUT UINT16                    **ParentFileName,
-  OUT EFI_HANDLE                *DeviceHandle
-  )
-{
-  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;
-  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePathNode;
-  EFI_STATUS                        Status;
-  EFI_HANDLE                        Handle;
-  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;
-  EFI_FILE_HANDLE                   FileHandle;
-  EFI_FILE_HANDLE                   LastHandle;
-  CHAR16                            *TempPath;
-
-  *ParentFileName = NULL;
-
-  //
-  // Attempt to access the file via a file system interface
-  //
-  DevicePathNode = RootDirectory;
-  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-  
-  Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-  
-  //
-  // Open the Volume to get the File System handle
-  //
-  Status = Volume->OpenVolume (Volume, &FileHandle);
-  if (EFI_ERROR (Status)) {
-    return Status;
-  }
-
-  *DeviceHandle = Handle;
-
-  if (IsDevicePathEnd(DevicePathNode)) {
-    *ParentFileName = AllocateCopyPool (StrSize (L"\\"), L"\\");
-    *RetFileHandle = FileHandle;
-    return EFI_SUCCESS;
-  }
-  
-  //
-  // Duplicate the device path to avoid the access to unaligned device path node.
-  // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH
-  // nodes, It assures the fields in device path nodes are 2 byte aligned.
-  //
-  TempDevicePathNode = DuplicateDevicePath (DevicePathNode);
-  if (TempDevicePathNode == NULL) {
-
-    //
-    // Setting Status to an EFI_ERROR value will cause the rest of
-    // the file system support below to be skipped.
-    //
-    Status = EFI_OUT_OF_RESOURCES;
-  }
-        
-  //
-  // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the
-  // directory information and filename can be seperate. The goal is to inch
-  // our way down each device path node and close the previous node
-  //
-  DevicePathNode = TempDevicePathNode;
-  while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {
-    if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||
-        DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {
-      Status = EFI_UNSUPPORTED;
-      goto Done;
-    }
-
-    LastHandle = FileHandle;
-    FileHandle = NULL;
-
-    Status = LastHandle->Open (
-                          LastHandle,
-                          &FileHandle,
-                          ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,
-                          EFI_FILE_MODE_READ,
-                          0
-                          );
-    if (*ParentFileName == NULL) {
-      *ParentFileName = AllocateCopyPool (StrSize (((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName), ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);
-    } else {
-      TempPath = LibAppendFileName (*ParentFileName, ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);
-      FreePool (*ParentFileName);
-      *ParentFileName = TempPath;
-    }
-
-    //
-    // Close the previous node
-    //
-    LastHandle->Close (LastHandle);
-
-    DevicePathNode = NextDevicePathNode (DevicePathNode);
-  }
-
-  if (EFI_ERROR (Status)) {
-    goto Done;
-  }
-
-  *RetFileHandle = FileHandle;
-
-  Status = EFI_SUCCESS;
-
-Done:
-  if (TempDevicePathNode != NULL) {
-    FreePool (TempDevicePathNode);
-  }
-
-  if ((FileHandle != NULL) && (EFI_ERROR (Status))) {
-    FileHandle->Close (FileHandle);
-  }
-
-  return Status;
-}
-
-/**
-  Find files under current directory.
-  
-  All files and sub-directories in current directory
-  will be stored in DirectoryMenu for future use.
-
-  @param FileHandle    Parent file handle. 
-  @param FileName      Parent file name.
-  @param DeviceHandle  Driver handle for this partition.
-
-  @retval EFI_SUCCESS         Get files from current dir successfully.
-  @return Other value if can't get files from current dir.
-
-**/
-EFI_STATUS
-LibFindFiles (
-  IN EFI_FILE_HANDLE           FileHandle,
-  IN UINT16                    *FileName,
-  IN EFI_HANDLE                DeviceHandle
-  )
-{
-  EFI_FILE_INFO   *DirInfo;
-  UINTN           BufferSize;
-  UINTN           DirBufferSize;
-  MENU_ENTRY      *NewMenuEntry;
-  FILE_CONTEXT    *NewFileContext;
-  UINTN           Pass;
-  EFI_STATUS      Status;
-  UINTN           OptionNumber;
-
-  OptionNumber = 0;
-
-  DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;
-  DirInfo       = AllocateZeroPool (DirBufferSize);
-  if (DirInfo == NULL) {
-    return EFI_OUT_OF_RESOURCES;
-  }
-
-  //
-  // Get all files in current directory
-  // Pass 1 to get Directories
-  // Pass 2 to get files that are EFI images
-  //
-  for (Pass = 1; Pass <= 2; Pass++) {
-    FileHandle->SetPosition (FileHandle, 0);
-    for (;;) {
-      BufferSize  = DirBufferSize;
-      Status      = FileHandle->Read (FileHandle, &BufferSize, DirInfo);
-      if (EFI_ERROR (Status) || BufferSize == 0) {
-        break;
-      }
-
-      if (((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0 && Pass == 2) ||
-          ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0 && Pass == 1)
-          ) {
-        //
-        // Pass 1 is for Directories
-        // Pass 2 is for file names
-        //
-        continue;
-      }
-
-      if (!((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0 || LibIsSupportedFileType (DirInfo->FileName))) {
-        //
-        // Slip file unless it is a directory entry or a .EFI file
-        //
-        continue;
-      }
-
-      NewMenuEntry = LibCreateMenuEntry ();
-      if (NULL == NewMenuEntry) {
-        return EFI_OUT_OF_RESOURCES;
-      }
-
-      NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;
-      NewFileContext->DeviceHandle = DeviceHandle;
-      NewFileContext->FileName = LibAppendFileName (FileName, DirInfo->FileName);
-      NewFileContext->FileHandle = FileHandle;
-      NewFileContext->DevicePath = FileDevicePath (NewFileContext->DeviceHandle, NewFileContext->FileName);
-      NewMenuEntry->HelpString = NULL;
-      NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);
-
-      if (NewFileContext->IsDir) {
-        BufferSize = StrLen (DirInfo->FileName) * 2 + 6;
-        NewMenuEntry->DisplayString = AllocateZeroPool (BufferSize);
-        UnicodeSPrint (
-          NewMenuEntry->DisplayString,
-          BufferSize,
-          L"<%s>",
-          DirInfo->FileName
-          );
-      } else {
-        NewMenuEntry->DisplayString = LibStrDuplicate (DirInfo->FileName);
-      }
-      
-      NewMenuEntry->DisplayStringToken = HiiSetString (
-                                           gFileExplorerPrivate.FeHiiHandle,
-                                           0,
-                                           NewMenuEntry->DisplayString,
-                                           NULL
-                                           );
-
-      NewFileContext->IsRoot            = FALSE;
-
-      OptionNumber++;
-      InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &NewMenuEntry->Link);
-    }
-  }
-
-  gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber;
-
-  FreePool (DirInfo);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Refresh the global UpdateData structure.
-
-**/
-VOID
-LibRefreshUpdateData (
-  VOID
-  )
-{
-  //
-  // Free current updated date
-  //
-  if (mLibStartOpCodeHandle != NULL) {
-    HiiFreeOpCodeHandle (mLibStartOpCodeHandle);
-  }
-  if (mLibEndOpCodeHandle != NULL) {
-    HiiFreeOpCodeHandle (mLibEndOpCodeHandle);
-  }
-
-  //
-  // Create new OpCode Handle
-  //
-  mLibStartOpCodeHandle = HiiAllocateOpCodeHandle ();
-  mLibEndOpCodeHandle = HiiAllocateOpCodeHandle ();
-
-  //
-  // Create Hii Extend Label OpCode as the start opcode
-  //
-  mLibStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
-                                         mLibStartOpCodeHandle,
-                                         &gEfiIfrTianoGuid,
-                                         NULL,
-                                         sizeof (EFI_IFR_GUID_LABEL)
-                                         );
-  mLibStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
-
-  mLibStartLabel->Number = FORM_FILE_EXPLORER_ID;
-
-  //
-  // Create Hii Extend Label OpCode as the start opcode
-  //
-  mLibEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
-                                         mLibEndOpCodeHandle,
-                                         &gEfiIfrTianoGuid,
-                                         NULL,
-                                         sizeof (EFI_IFR_GUID_LABEL)
-                                         );
-  mLibEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
-
-  mLibEndLabel->Number = LABEL_END;
-}
-
-/**
-
-  Update the File Explore page.
-
-**/
-VOID
-LibUpdateFileExplorePage (
-  VOID
-  )
-{
-  UINTN           Index;
-  MENU_ENTRY      *NewMenuEntry;
-  FILE_CONTEXT    *NewFileContext;
-  MENU_OPTION     *MenuOption;
-
-  NewMenuEntry    = NULL;
-  NewFileContext  = NULL;
-
-  LibRefreshUpdateData ();
-  MenuOption = gFileExplorerPrivate.FsOptionMenu;
-
-  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
-    NewMenuEntry    = LibGetMenuEntry (MenuOption, Index);
-    NewFileContext  = (FILE_CONTEXT *) NewMenuEntry->VariableContext;
-
-    if (!NewFileContext->IsDir) {
-      //
-      // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
-      //
-      HiiCreateActionOpCode (
-        mLibStartOpCodeHandle,
-        (UINT16) (FILE_OPTION_OFFSET + Index),
-        NewMenuEntry->DisplayStringToken,
-        STRING_TOKEN (STR_NULL_STRING),
-        EFI_IFR_FLAG_CALLBACK,
-        0
-        );
-    } else {
-      //
-      // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.
-      //
-      HiiCreateGotoOpCode (
-        mLibStartOpCodeHandle,
-        FORM_FILE_EXPLORER_ID,
-        NewMenuEntry->DisplayStringToken,
-        STRING_TOKEN (STR_NULL_STRING),
-        EFI_IFR_FLAG_CALLBACK,
-        (UINT16) (FILE_OPTION_OFFSET + Index)
-        );
-    }
-  }
-
-  HiiUpdateForm (
-    gFileExplorerPrivate.FeHiiHandle,
-    &FileExplorerGuid,
-    FORM_FILE_EXPLORER_ID,
-    mLibStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID
-    mLibEndOpCodeHandle    // LABEL_END
-    );
-}
-
-/**
-  Update the file explower page with the refershed file system.
-
-  @param KeyValue        Key value to identify the type of data to expect.
-
-  @retval  EFI_SUCCESS   Update the file explorer form success.
-  @retval  other errors  Error occur when parse one directory.
-
-**/
-EFI_STATUS
-LibUpdateFileExplorer (
-  IN UINT16                       KeyValue
-  )
-{
-  UINT16          FileOptionMask;
-  MENU_ENTRY      *NewMenuEntry;
-  FILE_CONTEXT    *NewFileContext;
-  EFI_STATUS      Status;
-  EFI_FILE_HANDLE FileHandle;
-
-  Status = EFI_SUCCESS;
-  FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);
-  NewMenuEntry   = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);
-  NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;
-
-  if (NewFileContext->IsDir) {
-    RemoveEntryList (&NewMenuEntry->Link);
-    LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);
-    LibGetFileHandleFromMenu (NewMenuEntry, &FileHandle);
-    Status = LibFindFiles (FileHandle, NewFileContext->FileName, NewFileContext->DeviceHandle);
-    if (!EFI_ERROR (Status)) {
-      LibUpdateFileExplorePage ();
-    } else {
-      LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);
-    }
-    LibDestroyMenuEntry (NewMenuEntry);
-  }
-
-  return Status;
-}
-
-/**
-  Get the device path info saved in the menu structure.
-
-  @param KeyValue        Key value to identify the type of data to expect.
-
-**/
-VOID
-LibGetDevicePath (
-  IN UINT16                       KeyValue
-  )
-{
-  UINT16          FileOptionMask;
-  MENU_ENTRY      *NewMenuEntry;
-  FILE_CONTEXT    *NewFileContext;
-
-  FileOptionMask    = (UINT16) (FILE_OPTION_MASK & KeyValue);
-
-  NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);
-
-  NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;
-
-  if (gFileExplorerPrivate.RetDevicePath != NULL) {
-    FreePool (gFileExplorerPrivate.RetDevicePath);
-  }
-  gFileExplorerPrivate.RetDevicePath = DuplicateDevicePath (NewFileContext->DevicePath);
-}
-
-/**
-  Choose a file in the specified directory. 
-
-  If user input NULL for the RootDirectory, will choose file in the system.
-
-  If user input *File != NULL, function will return the allocate device path
-  info for the choosed file, caller has to free the memory after use it.
-
-  @param  RootDirectory    Pointer to the root directory.
-  @param  FileType         The file type need to choose.
-  @param  ChooseHandler    Function pointer to the extra task need to do
-                           after choose one file.
-  @param  File             Return the device path for the last time chosed file.
-
-  @retval EFI_SUCESS             Choose file success.
-  @retval EFI_INVALID_PARAMETER  Both ChooseHandler and return device path are NULL
-                                 One of them must not NULL.
-  @retval Other errors           Choose file failed.
-**/
-EFI_STATUS
-EFIAPI
-ChooseFile (
-  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,
-  IN  CHAR16                    *FileType,  OPTIONAL
-  IN  CHOOSE_HANDLER            ChooseHandler,  OPTIONAL
-  OUT EFI_DEVICE_PATH_PROTOCOL  **File  OPTIONAL
-  )
-{
-  EFI_FILE_HANDLE                   FileHandle;
-  EFI_STATUS                        Status;
-  UINT16                            *FileName;
-  EFI_HANDLE                        DeviceHandle;
-
-  if ((ChooseHandler == NULL) && (File == NULL)) {
-    return EFI_INVALID_PARAMETER;
-  }
-
-  FileName = NULL;
-
-  gFileExplorerPrivate.RetDevicePath = NULL;
-  gFileExplorerPrivate.ChooseHandler = ChooseHandler;
-  if (FileType != NULL) {
-    gFileExplorerPrivate.FileType = AllocateCopyPool (StrSize (FileType), FileType);
-    LibToLowerString(gFileExplorerPrivate.FileType);
-  } else {
-    gFileExplorerPrivate.FileType = NULL;
-  }
-
-  if (RootDirectory == NULL) {
-    Status = LibFindFileSystem();
-  } else {
-    Status = LibGetFileHandleFromDevicePath(RootDirectory, &FileHandle, &FileName, &DeviceHandle);
-    if (EFI_ERROR (Status)) {
-      goto Done;
-    }
-
-    Status = LibFindFiles (FileHandle, FileName, DeviceHandle);
-  }
-  if (EFI_ERROR (Status)) {
-    goto Done;
-  }
-
-  LibUpdateFileExplorePage();
-
-  gFileExplorerPrivate.FormBrowser2->SendForm (
-                         gFileExplorerPrivate.FormBrowser2,
-                         &gFileExplorerPrivate.FeHiiHandle,
-                         1,
-                         &FileExplorerGuid,
-                         0,
-                         NULL,
-                         NULL
-                         );
-
-Done:
-  if ((Status == EFI_SUCCESS) && (File != NULL)) {
-    *File  = gFileExplorerPrivate.RetDevicePath;
-  } else if (gFileExplorerPrivate.RetDevicePath != NULL) {
-    FreePool (gFileExplorerPrivate.RetDevicePath);
-  }
-
-  if (gFileExplorerPrivate.FileType != NULL) {
-    FreePool (gFileExplorerPrivate.FileType);
-  }
-
-  LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);
-
-  if (FileName != NULL) {
-    FreePool (FileName);
-  }
-
-  return Status;
-}
-
-/**
-
-  Install Boot Manager Menu driver.
-
-  @param ImageHandle     The image handle.
-  @param SystemTable     The system table.
-
-  @retval  EFI_SUCEESS  Install File explorer library success.
-
-**/
-EFI_STATUS
-EFIAPI
-FileExplorerLibConstructor (
-  IN EFI_HANDLE                            ImageHandle,
-  IN EFI_SYSTEM_TABLE                      *SystemTable
-  )
-{
-  EFI_STATUS                     Status;
-
-  gHiiVendorDevicePath = (HII_VENDOR_DEVICE_PATH*) DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*)&FeHiiVendorDevicePath);
-  ASSERT (gHiiVendorDevicePath != NULL);
-  CopyGuid (&gHiiVendorDevicePath->VendorDevicePath.Guid, &gEfiCallerIdGuid);
-
-  //
-  // Install Device Path Protocol and Config Access protocol to driver handle
-  //
-  Status = gBS->InstallMultipleProtocolInterfaces (
-                  &gFileExplorerPrivate.FeDriverHandle,
-                  &gEfiDevicePathProtocolGuid,
-                  gHiiVendorDevicePath,
-                  &gEfiHiiConfigAccessProtocolGuid,
-                  &gFileExplorerPrivate.FeConfigAccess,
-                  NULL
-                  );
-  ASSERT_EFI_ERROR (Status);
-
-  //
-  // Post our File Explorer VFR binary to the HII database.
-  //
-  gFileExplorerPrivate.FeHiiHandle = HiiAddPackages (
-                                   &FileExplorerGuid,
-                                   gFileExplorerPrivate.FeDriverHandle,
-                                   FileExplorerVfrBin,
-                                   FileExplorerLibStrings,
-                                   NULL
-                                   );
-  ASSERT (gFileExplorerPrivate.FeHiiHandle != NULL);
-
-  //
-  // Locate Formbrowser2 protocol
-  //
-  Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFileExplorerPrivate.FormBrowser2);
-  ASSERT_EFI_ERROR (Status);
-    
-  InitializeListHead (&gFileExplorerPrivate.FsOptionMenu->Head);
-
-  return EFI_SUCCESS;
-}
-
-/**
-  Unloads the application and its installed protocol.
-
-  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.
-  @param[in]  SystemTable       The system table.
-
-  @retval EFI_SUCCESS           The image has been unloaded.
-**/
-EFI_STATUS
-EFIAPI
-FileExplorerLibDestructor (
-  IN EFI_HANDLE                            ImageHandle,
-  IN EFI_SYSTEM_TABLE                      *SystemTable
-  )
-{
-  EFI_STATUS    Status;
-
-  ASSERT (gHiiVendorDevicePath != NULL);
-
-  Status = gBS->UninstallMultipleProtocolInterfaces (
-                  gFileExplorerPrivate.FeDriverHandle,
-                  &gEfiDevicePathProtocolGuid,
-                  gHiiVendorDevicePath,
-                  &gEfiHiiConfigAccessProtocolGuid,
-                  &gFileExplorerPrivate.FeConfigAccess,
-                  NULL
-                  );
-  ASSERT_EFI_ERROR (Status);
-  
-  HiiRemovePackages (gFileExplorerPrivate.FeHiiHandle);
-
-  FreePool (gHiiVendorDevicePath);
-
-  return EFI_SUCCESS;
-}
-
+/** @file\r
+File explorer related functions.\r
+\r
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+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
+\r
+#include "FileExplorer.h"\r
+\r
+EFI_GUID FileExplorerGuid       = EFI_FILE_EXPLORE_FORMSET_GUID;\r
+\r
+///\r
+/// File system selection menu\r
+///\r
+MENU_OPTION      mFsOptionMenu = {\r
+  MENU_OPTION_SIGNATURE,\r
+  {NULL},\r
+  0,\r
+  FALSE\r
+};\r
+\r
+FILE_EXPLORER_CALLBACK_DATA  gFileExplorerPrivate = {\r
+  FILE_EXPLORER_CALLBACK_DATA_SIGNATURE,\r
+  NULL,\r
+  NULL,\r
+  {\r
+    LibExtractConfig,\r
+    LibRouteConfig,\r
+    LibCallback\r
+  },\r
+  NULL,\r
+  &mFsOptionMenu,\r
+  0\r
+};\r
+\r
+HII_VENDOR_DEVICE_PATH  *gHiiVendorDevicePath;\r
+\r
+HII_VENDOR_DEVICE_PATH  FeHiiVendorDevicePath = {\r
+  {\r
+    {\r
+      HARDWARE_DEVICE_PATH,\r
+      HW_VENDOR_DP,\r
+      {\r
+        (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
+        (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
+      }\r
+    },\r
+    //\r
+    // Will be replace with gEfiCallerIdGuid in code.\r
+    //\r
+    { 0x0, 0x0, 0x0, { 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 } }\r
+  },\r
+  {\r
+    END_DEVICE_PATH_TYPE,\r
+    END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
+    { \r
+      (UINT8) (END_DEVICE_PATH_LENGTH),\r
+      (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
+    }\r
+  }\r
+};\r
+\r
+VOID                *mLibStartOpCodeHandle = NULL;\r
+VOID                *mLibEndOpCodeHandle = NULL;\r
+EFI_IFR_GUID_LABEL  *mLibStartLabel = NULL;\r
+EFI_IFR_GUID_LABEL  *mLibEndLabel = NULL;\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Request         A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param Progress        On return, points to a character in the Request string.\r
+                         Points to the string's null terminator if request was successful.\r
+                         Points to the most recent '&' before the first failing name/value\r
+                         pair (or the beginning of the string if the failure is in the\r
+                         first name/value pair) if the request was not successful.\r
+  @param Results         A null-terminated Unicode string in <ConfigAltResp> format which\r
+                         has all values filled in for the names in the Request string.\r
+                         String to be allocated by the called function.\r
+\r
+  @retval  EFI_INVALID_PARAMETER  Request is illegal syntax, or unknown name.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LibExtractConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Request,\r
+  OUT EFI_STRING                             *Progress,\r
+  OUT EFI_STRING                             *Results\r
+  )\r
+{\r
+  if (Progress == NULL || Results == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Progress = Request;\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Configuration   A null-terminated Unicode string in <ConfigResp> format.\r
+  @param Progress        A pointer to a string filled in with the offset of the most\r
+                         recent '&' before the first failing name/value pair (or the\r
+                         beginning of the string if the failure is in the first\r
+                         name/value pair) or the terminating NULL if all was successful.\r
+\r
+  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LibRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  )\r
+{\r
+  if (Configuration == NULL || Progress == NULL) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  *Progress = Configuration;\r
+  return EFI_NOT_FOUND;\r
+}\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+  When user select a interactive opcode, this callback will be triggered.\r
+  Based on the Question(QuestionId) that triggers the callback, the corresponding\r
+  actions is performed. It handles:\r
+\r
+  1) Process the axtra action or exit file explorer when user select one file .\r
+  2) update of file content if a dir is selected.\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Action          Specifies the type of action taken by the browser.\r
+  @param QuestionId      A unique value which is sent to the original exporting driver\r
+                         so that it can identify the type of data to expect.\r
+  @param Type            The type of value for the question.\r
+  @param Value           A pointer to the data being sent to the original exporting driver.\r
+  @param ActionRequest   On return, points to the action requested by the callback function.\r
+\r
+  @retval  EFI_SUCCESS           The callback successfully handled the action.\r
+  @retval  other error           Error occur when parse one directory.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LibCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        QuestionId,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  BOOLEAN       NeedExit;\r
+\r
+  NeedExit = TRUE;\r
+  \r
+  if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
+    //\r
+    // Do nothing for other UEFI Action. Only do call back when data is changed.\r
+    //\r
+    return EFI_UNSUPPORTED;\r
+  }\r
+\r
+  *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;\r
+\r
+  if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
+    if ((Value == NULL) || (ActionRequest == NULL)) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    \r
+    if (QuestionId >= FILE_OPTION_OFFSET) {\r
+      LibGetDevicePath(QuestionId);\r
+\r
+      //\r
+      // Process the extra action.\r
+      //\r
+      if (gFileExplorerPrivate.ChooseHandler != NULL) {\r
+        NeedExit = gFileExplorerPrivate.ChooseHandler (gFileExplorerPrivate.RetDevicePath);\r
+      }\r
+\r
+      if (NeedExit) {\r
+        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
+      }\r
+    }\r
+  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
+    if (Value == NULL) {\r
+      return EFI_INVALID_PARAMETER;\r
+    }\r
+    \r
+    if (QuestionId >= FILE_OPTION_OFFSET) {\r
+      Status = LibUpdateFileExplorer (QuestionId);\r
+      if (EFI_ERROR (Status)) {\r
+        return Status;\r
+      }\r
+    }\r
+  }\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Create a menu entry by given menu type.\r
+\r
+  @retval NULL           If failed to create the menu.\r
+  @return the new menu entry.\r
+\r
+**/\r
+MENU_ENTRY *\r
+LibCreateMenuEntry (\r
+  VOID\r
+  )\r
+{\r
+  MENU_ENTRY *MenuEntry;\r
+\r
+  //\r
+  // Create new menu entry\r
+  //\r
+  MenuEntry = AllocateZeroPool (sizeof (MENU_ENTRY));\r
+  if (MenuEntry == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  MenuEntry->VariableContext = AllocateZeroPool (sizeof (FILE_CONTEXT));\r
+  if (MenuEntry->VariableContext == NULL) {\r
+    FreePool (MenuEntry);\r
+    return NULL;\r
+  }\r
+\r
+  MenuEntry->Signature        = MENU_ENTRY_SIGNATURE;\r
+  return MenuEntry;\r
+}\r
+\r
+\r
+/**\r
+  Get the Menu Entry from the list in Menu Entry List.\r
+\r
+  If MenuNumber is great or equal to the number of Menu\r
+  Entry in the list, then ASSERT.\r
+\r
+  @param MenuOption      The Menu Entry List to read the menu entry.\r
+  @param MenuNumber      The index of Menu Entry.\r
+\r
+  @return The Menu Entry.\r
+\r
+**/\r
+MENU_ENTRY *\r
+LibGetMenuEntry (\r
+  MENU_OPTION         *MenuOption,\r
+  UINTN               MenuNumber\r
+  )\r
+{\r
+  MENU_ENTRY      *NewMenuEntry;\r
+  UINTN           Index;\r
+  LIST_ENTRY      *List;\r
+\r
+  ASSERT (MenuNumber < MenuOption->MenuNumber);\r
+\r
+  List = MenuOption->Head.ForwardLink;\r
+  for (Index = 0; Index < MenuNumber; Index++) {\r
+    List = List->ForwardLink;\r
+  }\r
+\r
+  NewMenuEntry = CR (List, MENU_ENTRY, Link, MENU_ENTRY_SIGNATURE);\r
+\r
+  return NewMenuEntry;\r
+}\r
+\r
+/**\r
+  Free up all resource allocated for a BM_MENU_ENTRY.\r
+\r
+  @param MenuEntry   A pointer to BM_MENU_ENTRY.\r
+\r
+**/\r
+VOID\r
+LibDestroyMenuEntry (\r
+  MENU_ENTRY         *MenuEntry\r
+  )\r
+{\r
+  FILE_CONTEXT           *FileContext;\r
+\r
+  FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext;\r
+\r
+  if (!FileContext->IsRoot) {\r
+    FreePool (FileContext->DevicePath);\r
+  } else {\r
+    if (FileContext->FileHandle != NULL) {\r
+      FileContext->FileHandle->Close (FileContext->FileHandle);\r
+    }\r
+  }\r
+\r
+  if (FileContext->FileName != NULL) {\r
+    FreePool (FileContext->FileName);\r
+  }\r
+\r
+  FreePool (FileContext);\r
+\r
+  FreePool (MenuEntry->DisplayString);\r
+  if (MenuEntry->HelpString != NULL) {\r
+    FreePool (MenuEntry->HelpString);\r
+  }\r
+\r
+  FreePool (MenuEntry);\r
+}\r
+\r
+\r
+/**\r
+  Free resources allocated in Allocate Rountine.\r
+\r
+  @param FreeMenu        Menu to be freed\r
+**/\r
+VOID\r
+LibFreeMenu (\r
+  MENU_OPTION        *FreeMenu\r
+  )\r
+{\r
+  MENU_ENTRY *MenuEntry;\r
+  while (!IsListEmpty (&FreeMenu->Head)) {\r
+    MenuEntry = CR (\r
+                  FreeMenu->Head.ForwardLink,\r
+                  MENU_ENTRY,\r
+                  Link,\r
+                  MENU_ENTRY_SIGNATURE\r
+                  );\r
+    RemoveEntryList (&MenuEntry->Link);\r
+    LibDestroyMenuEntry (MenuEntry);\r
+  }\r
+  FreeMenu->MenuNumber = 0;\r
+}\r
+\r
+/**\r
+\r
+  Function opens and returns a file handle to the root directory of a volume.\r
+\r
+  @param DeviceHandle    A handle for a device\r
+\r
+  @return A valid file handle or NULL is returned\r
+\r
+**/\r
+EFI_FILE_HANDLE\r
+LibOpenRoot (\r
+  IN EFI_HANDLE                   DeviceHandle\r
+  )\r
+{\r
+  EFI_STATUS                      Status;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *Volume;\r
+  EFI_FILE_HANDLE                 File;\r
+\r
+  File = NULL;\r
+\r
+  //\r
+  // File the file system interface to the device\r
+  //\r
+  Status = gBS->HandleProtocol (\r
+                  DeviceHandle,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  (VOID *) &Volume\r
+                  );\r
+\r
+  //\r
+  // Open the root directory of the volume\r
+  //\r
+  if (!EFI_ERROR (Status)) {\r
+    Status = Volume->OpenVolume (\r
+                      Volume,\r
+                      &File\r
+                      );\r
+  }\r
+  //\r
+  // Done\r
+  //\r
+  return EFI_ERROR (Status) ? NULL : File;\r
+}\r
+\r
+/**\r
+  This function converts an input device structure to a Unicode string.\r
+\r
+  @param DevPath                  A pointer to the device path structure.\r
+\r
+  @return A new allocated Unicode string that represents the device path.\r
+\r
+**/\r
+CHAR16 *\r
+LibDevicePathToStr (\r
+  IN EFI_DEVICE_PATH_PROTOCOL     *DevPath\r
+  )\r
+{\r
+  EFI_STATUS                       Status;\r
+  CHAR16                           *ToText;\r
+  EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;\r
+\r
+  if (DevPath == NULL) {\r
+    return NULL;\r
+  }\r
+\r
+  Status = gBS->LocateProtocol (\r
+                  &gEfiDevicePathToTextProtocolGuid,\r
+                  NULL,\r
+                  (VOID **) &DevPathToText\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  ToText = DevPathToText->ConvertDevicePathToText (\r
+                            DevPath,\r
+                            FALSE,\r
+                            TRUE\r
+                            );\r
+  ASSERT (ToText != NULL);\r
+\r
+  return ToText;\r
+}\r
+\r
+/**\r
+  Duplicate a string.\r
+\r
+  @param Src             The source.\r
+\r
+  @return A new string which is duplicated copy of the source.\r
+  @retval NULL If there is not enough memory.\r
+\r
+**/\r
+CHAR16 *\r
+LibStrDuplicate (\r
+  IN CHAR16   *Src\r
+  )\r
+{\r
+  CHAR16  *Dest;\r
+  UINTN   Size;\r
+\r
+  Size  = StrSize (Src);\r
+  Dest  = AllocateZeroPool (Size);\r
+  ASSERT (Dest != NULL);\r
+  if (Dest != NULL) {\r
+    CopyMem (Dest, Src, Size);\r
+  }\r
+\r
+  return Dest;\r
+}\r
+\r
+/**\r
+\r
+  Function gets the file information from an open file descriptor, and stores it\r
+  in a buffer allocated from pool.\r
+\r
+  @param FHand           File Handle.\r
+  @param InfoType        Info type need to get.\r
+\r
+  @retval                A pointer to a buffer with file information or NULL is returned\r
+\r
+**/\r
+VOID *\r
+LibFileInfo (\r
+  IN EFI_FILE_HANDLE      FHand,\r
+  IN EFI_GUID             *InfoType\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+  EFI_FILE_INFO *Buffer;\r
+  UINTN         BufferSize;\r
+\r
+  Buffer      = NULL;\r
+  BufferSize  = 0;\r
+  \r
+  Status = FHand->GetInfo (\r
+                    FHand,\r
+                    InfoType,\r
+                    &BufferSize,\r
+                    Buffer\r
+                    );\r
+  if (Status == EFI_BUFFER_TOO_SMALL) {\r
+    Buffer = AllocatePool (BufferSize);\r
+    ASSERT (Buffer != NULL);\r
+  }\r
+\r
+  Status = FHand->GetInfo (\r
+                    FHand,\r
+                    InfoType,\r
+                    &BufferSize,\r
+                    Buffer\r
+                    );\r
+\r
+  return Buffer;\r
+}\r
+\r
+/**\r
+\r
+  Get file type base on the file name.\r
+  Just cut the file name, from the ".". eg ".efi"\r
+\r
+  @param FileName  File need to be checked.\r
+\r
+  @retval the file type string.\r
+\r
+**/\r
+CHAR16*\r
+LibGetTypeFromName (\r
+  IN CHAR16   *FileName\r
+  )\r
+{\r
+  UINTN    Index;\r
+\r
+  Index = StrLen (FileName) - 1;\r
+  while ((FileName[Index] != L'.') && (Index != 0)) {\r
+    Index--;\r
+  }\r
+\r
+  return Index == 0 ? NULL : &FileName[Index];\r
+}\r
+\r
+/**\r
+  Converts the unicode character of the string from uppercase to lowercase.\r
+  This is a internal function.\r
+\r
+  @param ConfigString  String to be converted\r
+\r
+**/\r
+VOID\r
+LibToLowerString (\r
+  IN CHAR16  *String\r
+  )\r
+{\r
+  CHAR16      *TmpStr;\r
+\r
+  for (TmpStr = String; *TmpStr != L'\0'; TmpStr++) {\r
+    if (*TmpStr >= L'A' && *TmpStr <= L'Z') {\r
+      *TmpStr = (CHAR16) (*TmpStr - L'A' + L'a');\r
+    }\r
+  }\r
+}\r
+\r
+/**\r
+\r
+  Check whether current FileName point to a valid\r
+  Efi Image File.\r
+\r
+  @param FileName  File need to be checked.\r
+\r
+  @retval TRUE  Is Efi Image\r
+  @retval FALSE Not a valid Efi Image\r
+\r
+**/\r
+BOOLEAN\r
+LibIsSupportedFileType (\r
+  IN UINT16  *FileName\r
+  )\r
+{\r
+  CHAR16     *InputFileType;\r
+  CHAR16     *TmpStr;\r
+  BOOLEAN    IsSupported;\r
+\r
+  if (gFileExplorerPrivate.FileType == NULL) {\r
+    return TRUE;\r
+  }\r
+\r
+  InputFileType = LibGetTypeFromName (FileName);\r
+  //\r
+  // If the file not has *.* style, always return TRUE.\r
+  //\r
+  if (InputFileType == NULL) {\r
+    return TRUE;\r
+  }\r
+\r
+  TmpStr = AllocateCopyPool (StrSize (InputFileType), InputFileType);\r
+  LibToLowerString(TmpStr);\r
+\r
+  IsSupported = (StrStr (gFileExplorerPrivate.FileType, TmpStr) == NULL ? FALSE : TRUE);\r
+\r
+  FreePool (TmpStr);\r
+  return IsSupported;\r
+}\r
+\r
+/**\r
+\r
+  Append file name to existing file name.\r
+\r
+  @param Str1  The existing file name\r
+  @param Str2  The file name to be appended\r
+\r
+  @return Allocate a new string to hold the appended result.\r
+          Caller is responsible to free the returned string.\r
+\r
+**/\r
+CHAR16 *\r
+LibAppendFileName (\r
+  IN  CHAR16  *Str1,\r
+  IN  CHAR16  *Str2\r
+  )\r
+{\r
+  UINTN   Size1;\r
+  UINTN   Size2;\r
+  UINTN   MaxLen;\r
+  CHAR16  *Str;\r
+  CHAR16  *TmpStr;\r
+  CHAR16  *Ptr;\r
+  CHAR16  *LastSlash;\r
+\r
+  Size1 = StrSize (Str1);\r
+  Size2 = StrSize (Str2);\r
+  MaxLen = (Size1 + Size2 + sizeof (CHAR16))/ sizeof (CHAR16);\r
+  Str   = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));\r
+  ASSERT (Str != NULL);\r
+\r
+  TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); \r
+  ASSERT (TmpStr != NULL);\r
+\r
+  StrCpyS (Str, MaxLen, Str1);\r
+  if (!((*Str == '\\') && (*(Str + 1) == 0))) {\r
+    StrCatS (Str, MaxLen, L"\\");\r
+  }\r
+\r
+  StrCatS (Str, MaxLen, Str2);\r
+\r
+  Ptr       = Str;\r
+  LastSlash = Str;\r
+  while (*Ptr != 0) {\r
+    if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '.' && *(Ptr + 3) == L'\\') {\r
+      //\r
+      // Convert "\Name\..\" to "\"\r
+      // DO NOT convert the .. if it is at the end of the string. This will\r
+      // break the .. behavior in changing directories.\r
+      //\r
+\r
+      //\r
+      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings \r
+      // that overlap.\r
+      //\r
+      StrCpyS (TmpStr, MaxLen, Ptr + 3);\r
+      StrCpyS (LastSlash, MaxLen - (UINTN) (LastSlash - Str), TmpStr);\r
+      Ptr = LastSlash;\r
+    } else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
+      //\r
+      // Convert a "\.\" to a "\"\r
+      //\r
+\r
+      //\r
+      // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings \r
+      // that overlap.\r
+      //\r
+      StrCpyS (TmpStr, MaxLen, Ptr + 2);\r
+      StrCpyS (Ptr, MaxLen - (UINTN) (Ptr - Str), TmpStr);\r
+      Ptr = LastSlash;\r
+    } else if (*Ptr == '\\') {\r
+      LastSlash = Ptr;\r
+    }\r
+\r
+    Ptr++;\r
+  }\r
+\r
+  FreePool (TmpStr);\r
+  \r
+  return Str;\r
+}\r
+\r
+/**\r
+  This function build the FsOptionMenu list which records all\r
+  available file system in the system. They includes all instances\r
+  of EFI_SIMPLE_FILE_SYSTEM_PROTOCOL, all instances of EFI_LOAD_FILE_SYSTEM.\r
+\r
+\r
+  @retval  EFI_SUCCESS             Success find the file system\r
+  @retval  EFI_OUT_OF_RESOURCES    Can not create menu entry\r
+\r
+**/\r
+EFI_STATUS\r
+LibFindFileSystem (\r
+  VOID\r
+  )\r
+{\r
+  UINTN                        NoSimpleFsHandles;\r
+  UINTN                        NoLoadFileHandles;\r
+  EFI_HANDLE                   *SimpleFsHandle;\r
+  EFI_HANDLE                   *LoadFileHandle;\r
+  UINT16                       *VolumeLabel;\r
+  UINTN                        Index;\r
+  EFI_STATUS                   Status;\r
+  MENU_ENTRY                   *MenuEntry;\r
+  FILE_CONTEXT                 *FileContext;\r
+  UINTN                        OptionNumber;\r
+  EFI_FILE_SYSTEM_VOLUME_LABEL *Info;\r
+\r
+  NoSimpleFsHandles = 0;\r
+  NoLoadFileHandles = 0;\r
+  OptionNumber      = 0;\r
+\r
+  //\r
+  // Locate Handles that support Simple File System protocol\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiSimpleFileSystemProtocolGuid,\r
+                  NULL,\r
+                  &NoSimpleFsHandles,\r
+                  &SimpleFsHandle\r
+                  );\r
+  if (!EFI_ERROR (Status)) {\r
+    //\r
+    // Find all the instances of the File System prototocol\r
+    //\r
+    for (Index = 0; Index < NoSimpleFsHandles; Index++) {\r
+      //\r
+      // Allocate pool for this load option\r
+      //\r
+      MenuEntry = LibCreateMenuEntry ();\r
+      if (NULL == MenuEntry) {\r
+        FreePool (SimpleFsHandle);\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext;\r
+      FileContext->DeviceHandle = SimpleFsHandle[Index];\r
+      FileContext->FileHandle = LibOpenRoot (FileContext->DeviceHandle);\r
+      if (FileContext->FileHandle == NULL) {\r
+        LibDestroyMenuEntry (MenuEntry);\r
+        continue;\r
+      }\r
+\r
+      MenuEntry->HelpString = LibDevicePathToStr (DevicePathFromHandle (FileContext->DeviceHandle));\r
+      FileContext->FileName = LibStrDuplicate (L"\\");\r
+      FileContext->DevicePath = FileDevicePath (FileContext->DeviceHandle, FileContext->FileName);\r
+      FileContext->IsDir = TRUE;\r
+      FileContext->IsRoot = TRUE;\r
+\r
+      //\r
+      // Get current file system's Volume Label\r
+      //\r
+      Info = (EFI_FILE_SYSTEM_VOLUME_LABEL *) LibFileInfo (FileContext->FileHandle, &gEfiFileSystemVolumeLabelInfoIdGuid);\r
+      if (Info == NULL) {\r
+        VolumeLabel = L"NO FILE SYSTEM INFO";\r
+      } else {\r
+        if (Info->VolumeLabel == NULL) {\r
+          VolumeLabel = L"NULL VOLUME LABEL";\r
+        } else {\r
+          VolumeLabel = Info->VolumeLabel;\r
+          if (*VolumeLabel == 0x0000) {\r
+            VolumeLabel = L"NO VOLUME LABEL";\r
+          }\r
+        }\r
+      }\r
+      MenuEntry->DisplayString  = AllocateZeroPool (MAX_CHAR);\r
+      ASSERT (MenuEntry->DisplayString != NULL);\r
+      UnicodeSPrint (\r
+        MenuEntry->DisplayString,\r
+        MAX_CHAR,\r
+        L"%s, [%s]",\r
+        VolumeLabel,\r
+        MenuEntry->HelpString\r
+        );\r
+         MenuEntry->DisplayStringToken = HiiSetString (\r
+                                             gFileExplorerPrivate.FeHiiHandle,\r
+                                             0,\r
+                                             MenuEntry->DisplayString,\r
+                                             NULL\r
+                                             );\r
+      FreePool (Info);\r
+\r
+      OptionNumber++;\r
+      InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link);\r
+    }\r
+  }\r
+\r
+  if (NoSimpleFsHandles != 0) {\r
+    FreePool (SimpleFsHandle);\r
+  }\r
+\r
+  //\r
+  // Searching for handles that support Load File protocol\r
+  //\r
+  Status = gBS->LocateHandleBuffer (\r
+                  ByProtocol,\r
+                  &gEfiLoadFileProtocolGuid,\r
+                  NULL,\r
+                  &NoLoadFileHandles,\r
+                  &LoadFileHandle\r
+                  );\r
+\r
+  if (!EFI_ERROR (Status)) {\r
+    for (Index = 0; Index < NoLoadFileHandles; Index++) {\r
+      MenuEntry = LibCreateMenuEntry ();\r
+      if (NULL == MenuEntry) {\r
+        FreePool (LoadFileHandle);\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      FileContext = (FILE_CONTEXT *) MenuEntry->VariableContext;\r
+      FileContext->DeviceHandle = LoadFileHandle[Index];\r
+      FileContext->IsRoot = TRUE;\r
+\r
+      FileContext->DevicePath = DevicePathFromHandle (FileContext->DeviceHandle);\r
+      FileContext->FileName = LibDevicePathToStr (FileContext->DevicePath);\r
+\r
+      MenuEntry->HelpString = LibDevicePathToStr (FileContext->DevicePath);\r
+      MenuEntry->DisplayString = AllocateZeroPool (MAX_CHAR);\r
+      ASSERT (MenuEntry->DisplayString != NULL);\r
+      UnicodeSPrint (\r
+        MenuEntry->DisplayString,\r
+        MAX_CHAR,\r
+        L"Load File [%s]",\r
+        MenuEntry->HelpString\r
+        );\r
+      MenuEntry->DisplayStringToken = HiiSetString (\r
+                                           gFileExplorerPrivate.FeHiiHandle,\r
+                                           0,\r
+                                           MenuEntry->DisplayString,\r
+                                           NULL\r
+                                           );\r
+\r
+      OptionNumber++;\r
+      InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link);\r
+    }\r
+  }\r
+\r
+  if (NoLoadFileHandles != 0) {\r
+    FreePool (LoadFileHandle);\r
+  }\r
+\r
+  gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Find the file handle from the input menu info.\r
+  \r
+  @param  MenuEntry        Input Menu info.\r
+  @param  RetFileHandle    Return the file handle for the input device path.\r
+  \r
+  @retval EFI_SUCESS       Find the file handle success.\r
+  @retval Other            Find the file handle failure.\r
+**/\r
+EFI_STATUS\r
+LibGetFileHandleFromMenu (\r
+  IN  MENU_ENTRY                *MenuEntry,  \r
+  OUT EFI_FILE_HANDLE           *RetFileHandle\r
+  )\r
+{\r
+  EFI_FILE_HANDLE Dir;\r
+  EFI_FILE_HANDLE NewDir;\r
+  FILE_CONTEXT    *FileContext;\r
+  EFI_STATUS      Status;\r
+\r
+  FileContext   = (FILE_CONTEXT *) MenuEntry->VariableContext;\r
+  Dir           = FileContext->FileHandle;\r
+\r
+  //\r
+  // Open current directory to get files from it\r
+  //\r
+  Status = Dir->Open (\r
+                  Dir,\r
+                  &NewDir,\r
+                  FileContext->FileName,\r
+                  EFI_FILE_READ_ONLY,\r
+                  0\r
+                  );\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  if (!FileContext->IsRoot) {\r
+    Dir->Close (Dir);\r
+  }\r
+\r
+  *RetFileHandle = NewDir;\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Find the file handle from the input device path info.\r
+  \r
+  @param  RootDirectory    Device path info.\r
+  @param  RetFileHandle    Return the file handle for the input device path.\r
+  @param  ParentFileName   Parent file name.\r
+  @param  DeviceHandle     Driver handle for this partition.\r
+  \r
+  @retval EFI_SUCESS       Find the file handle success.\r
+  @retval Other            Find the file handle failure.\r
+**/\r
+EFI_STATUS\r
+LibGetFileHandleFromDevicePath (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,  \r
+  OUT EFI_FILE_HANDLE           *RetFileHandle,\r
+  OUT UINT16                    **ParentFileName,\r
+  OUT EFI_HANDLE                *DeviceHandle\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePathNode;\r
+  EFI_DEVICE_PATH_PROTOCOL          *TempDevicePathNode;\r
+  EFI_STATUS                        Status;\r
+  EFI_HANDLE                        Handle;\r
+  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL   *Volume;\r
+  EFI_FILE_HANDLE                   FileHandle;\r
+  EFI_FILE_HANDLE                   LastHandle;\r
+  CHAR16                            *TempPath;\r
+\r
+  *ParentFileName = NULL;\r
+\r
+  //\r
+  // Attempt to access the file via a file system interface\r
+  //\r
+  DevicePathNode = RootDirectory;\r
+  Status = gBS->LocateDevicePath (&gEfiSimpleFileSystemProtocolGuid, &DevicePathNode, &Handle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID**)&Volume);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+  \r
+  //\r
+  // Open the Volume to get the File System handle\r
+  //\r
+  Status = Volume->OpenVolume (Volume, &FileHandle);\r
+  if (EFI_ERROR (Status)) {\r
+    return Status;\r
+  }\r
+\r
+  *DeviceHandle = Handle;\r
+\r
+  if (IsDevicePathEnd(DevicePathNode)) {\r
+    *ParentFileName = AllocateCopyPool (StrSize (L"\\"), L"\\");\r
+    *RetFileHandle = FileHandle;\r
+    return EFI_SUCCESS;\r
+  }\r
+  \r
+  //\r
+  // Duplicate the device path to avoid the access to unaligned device path node.\r
+  // Because the device path consists of one or more FILE PATH MEDIA DEVICE PATH\r
+  // nodes, It assures the fields in device path nodes are 2 byte aligned.\r
+  //\r
+  TempDevicePathNode = DuplicateDevicePath (DevicePathNode);\r
+  if (TempDevicePathNode == NULL) {\r
+\r
+    //\r
+    // Setting Status to an EFI_ERROR value will cause the rest of\r
+    // the file system support below to be skipped.\r
+    //\r
+    Status = EFI_OUT_OF_RESOURCES;\r
+  }\r
+        \r
+  //\r
+  // Parse each MEDIA_FILEPATH_DP node. There may be more than one, since the\r
+  // directory information and filename can be seperate. The goal is to inch\r
+  // our way down each device path node and close the previous node\r
+  //\r
+  DevicePathNode = TempDevicePathNode;\r
+  while (!EFI_ERROR (Status) && !IsDevicePathEnd (DevicePathNode)) {\r
+    if (DevicePathType (DevicePathNode) != MEDIA_DEVICE_PATH ||\r
+        DevicePathSubType (DevicePathNode) != MEDIA_FILEPATH_DP) {\r
+      Status = EFI_UNSUPPORTED;\r
+      goto Done;\r
+    }\r
+\r
+    LastHandle = FileHandle;\r
+    FileHandle = NULL;\r
+\r
+    Status = LastHandle->Open (\r
+                          LastHandle,\r
+                          &FileHandle,\r
+                          ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName,\r
+                          EFI_FILE_MODE_READ,\r
+                          0\r
+                          );\r
+    if (*ParentFileName == NULL) {\r
+      *ParentFileName = AllocateCopyPool (StrSize (((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName), ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);\r
+    } else {\r
+      TempPath = LibAppendFileName (*ParentFileName, ((FILEPATH_DEVICE_PATH *) DevicePathNode)->PathName);\r
+      FreePool (*ParentFileName);\r
+      *ParentFileName = TempPath;\r
+    }\r
+\r
+    //\r
+    // Close the previous node\r
+    //\r
+    LastHandle->Close (LastHandle);\r
+\r
+    DevicePathNode = NextDevicePathNode (DevicePathNode);\r
+  }\r
+\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  *RetFileHandle = FileHandle;\r
+\r
+  Status = EFI_SUCCESS;\r
+\r
+Done:\r
+  if (TempDevicePathNode != NULL) {\r
+    FreePool (TempDevicePathNode);\r
+  }\r
+\r
+  if ((FileHandle != NULL) && (EFI_ERROR (Status))) {\r
+    FileHandle->Close (FileHandle);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Find files under current directory.\r
+  \r
+  All files and sub-directories in current directory\r
+  will be stored in DirectoryMenu for future use.\r
+\r
+  @param FileHandle    Parent file handle. \r
+  @param FileName      Parent file name.\r
+  @param DeviceHandle  Driver handle for this partition.\r
+\r
+  @retval EFI_SUCCESS         Get files from current dir successfully.\r
+  @return Other value if can't get files from current dir.\r
+\r
+**/\r
+EFI_STATUS\r
+LibFindFiles (\r
+  IN EFI_FILE_HANDLE           FileHandle,\r
+  IN UINT16                    *FileName,\r
+  IN EFI_HANDLE                DeviceHandle\r
+  )\r
+{\r
+  EFI_FILE_INFO   *DirInfo;\r
+  UINTN           BufferSize;\r
+  UINTN           DirBufferSize;\r
+  MENU_ENTRY      *NewMenuEntry;\r
+  FILE_CONTEXT    *NewFileContext;\r
+  UINTN           Pass;\r
+  EFI_STATUS      Status;\r
+  UINTN           OptionNumber;\r
+\r
+  OptionNumber = 0;\r
+\r
+  DirBufferSize = sizeof (EFI_FILE_INFO) + 1024;\r
+  DirInfo       = AllocateZeroPool (DirBufferSize);\r
+  if (DirInfo == NULL) {\r
+    return EFI_OUT_OF_RESOURCES;\r
+  }\r
+\r
+  //\r
+  // Get all files in current directory\r
+  // Pass 1 to get Directories\r
+  // Pass 2 to get files that are EFI images\r
+  //\r
+  for (Pass = 1; Pass <= 2; Pass++) {\r
+    FileHandle->SetPosition (FileHandle, 0);\r
+    for (;;) {\r
+      BufferSize  = DirBufferSize;\r
+      Status      = FileHandle->Read (FileHandle, &BufferSize, DirInfo);\r
+      if (EFI_ERROR (Status) || BufferSize == 0) {\r
+        break;\r
+      }\r
+\r
+      if (((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0 && Pass == 2) ||\r
+          ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == 0 && Pass == 1)\r
+          ) {\r
+        //\r
+        // Pass 1 is for Directories\r
+        // Pass 2 is for file names\r
+        //\r
+        continue;\r
+      }\r
+\r
+      if (!((DirInfo->Attribute & EFI_FILE_DIRECTORY) != 0 || LibIsSupportedFileType (DirInfo->FileName))) {\r
+        //\r
+        // Slip file unless it is a directory entry or a .EFI file\r
+        //\r
+        continue;\r
+      }\r
+\r
+      NewMenuEntry = LibCreateMenuEntry ();\r
+      if (NULL == NewMenuEntry) {\r
+        return EFI_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
+      NewFileContext->DeviceHandle = DeviceHandle;\r
+      NewFileContext->FileName = LibAppendFileName (FileName, DirInfo->FileName);\r
+      NewFileContext->FileHandle = FileHandle;\r
+      NewFileContext->DevicePath = FileDevicePath (NewFileContext->DeviceHandle, NewFileContext->FileName);\r
+      NewMenuEntry->HelpString = NULL;\r
+      NewFileContext->IsDir = (BOOLEAN) ((DirInfo->Attribute & EFI_FILE_DIRECTORY) == EFI_FILE_DIRECTORY);\r
+\r
+      if (NewFileContext->IsDir) {\r
+        BufferSize = StrLen (DirInfo->FileName) * 2 + 6;\r
+        NewMenuEntry->DisplayString = AllocateZeroPool (BufferSize);\r
+        UnicodeSPrint (\r
+          NewMenuEntry->DisplayString,\r
+          BufferSize,\r
+          L"<%s>",\r
+          DirInfo->FileName\r
+          );\r
+      } else {\r
+        NewMenuEntry->DisplayString = LibStrDuplicate (DirInfo->FileName);\r
+      }\r
+      \r
+      NewMenuEntry->DisplayStringToken = HiiSetString (\r
+                                           gFileExplorerPrivate.FeHiiHandle,\r
+                                           0,\r
+                                           NewMenuEntry->DisplayString,\r
+                                           NULL\r
+                                           );\r
+\r
+      NewFileContext->IsRoot            = FALSE;\r
+\r
+      OptionNumber++;\r
+      InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &NewMenuEntry->Link);\r
+    }\r
+  }\r
+\r
+  gFileExplorerPrivate.FsOptionMenu->MenuNumber = OptionNumber;\r
+\r
+  FreePool (DirInfo);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Refresh the global UpdateData structure.\r
+\r
+**/\r
+VOID\r
+LibRefreshUpdateData (\r
+  VOID\r
+  )\r
+{\r
+  //\r
+  // Free current updated date\r
+  //\r
+  if (mLibStartOpCodeHandle != NULL) {\r
+    HiiFreeOpCodeHandle (mLibStartOpCodeHandle);\r
+  }\r
+  if (mLibEndOpCodeHandle != NULL) {\r
+    HiiFreeOpCodeHandle (mLibEndOpCodeHandle);\r
+  }\r
+\r
+  //\r
+  // Create new OpCode Handle\r
+  //\r
+  mLibStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+  mLibEndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the start opcode\r
+  //\r
+  mLibStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                         mLibStartOpCodeHandle,\r
+                                         &gEfiIfrTianoGuid,\r
+                                         NULL,\r
+                                         sizeof (EFI_IFR_GUID_LABEL)\r
+                                         );\r
+  mLibStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+\r
+  mLibStartLabel->Number = FORM_FILE_EXPLORER_ID;\r
+\r
+  //\r
+  // Create Hii Extend Label OpCode as the start opcode\r
+  //\r
+  mLibEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (\r
+                                         mLibEndOpCodeHandle,\r
+                                         &gEfiIfrTianoGuid,\r
+                                         NULL,\r
+                                         sizeof (EFI_IFR_GUID_LABEL)\r
+                                         );\r
+  mLibEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
+\r
+  mLibEndLabel->Number = LABEL_END;\r
+}\r
+\r
+/**\r
+\r
+  Update the File Explore page.\r
+\r
+**/\r
+VOID\r
+LibUpdateFileExplorePage (\r
+  VOID\r
+  )\r
+{\r
+  UINTN           Index;\r
+  MENU_ENTRY      *NewMenuEntry;\r
+  FILE_CONTEXT    *NewFileContext;\r
+  MENU_OPTION     *MenuOption;\r
+\r
+  NewMenuEntry    = NULL;\r
+  NewFileContext  = NULL;\r
+\r
+  LibRefreshUpdateData ();\r
+  MenuOption = gFileExplorerPrivate.FsOptionMenu;\r
+\r
+  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
+    NewMenuEntry    = LibGetMenuEntry (MenuOption, Index);\r
+    NewFileContext  = (FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+    if (!NewFileContext->IsDir) {\r
+      //\r
+      // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.\r
+      //\r
+      HiiCreateActionOpCode (\r
+        mLibStartOpCodeHandle,\r
+        (UINT16) (FILE_OPTION_OFFSET + Index),\r
+        NewMenuEntry->DisplayStringToken,\r
+        STRING_TOKEN (STR_NULL_STRING),\r
+        EFI_IFR_FLAG_CALLBACK,\r
+        0\r
+        );\r
+    } else {\r
+      //\r
+      // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.\r
+      //\r
+      HiiCreateGotoOpCode (\r
+        mLibStartOpCodeHandle,\r
+        FORM_FILE_EXPLORER_ID,\r
+        NewMenuEntry->DisplayStringToken,\r
+        STRING_TOKEN (STR_NULL_STRING),\r
+        EFI_IFR_FLAG_CALLBACK,\r
+        (UINT16) (FILE_OPTION_OFFSET + Index)\r
+        );\r
+    }\r
+  }\r
+\r
+  HiiUpdateForm (\r
+    gFileExplorerPrivate.FeHiiHandle,\r
+    &FileExplorerGuid,\r
+    FORM_FILE_EXPLORER_ID,\r
+    mLibStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID\r
+    mLibEndOpCodeHandle    // LABEL_END\r
+    );\r
+}\r
+\r
+/**\r
+  Update the file explower page with the refershed file system.\r
+\r
+  @param KeyValue        Key value to identify the type of data to expect.\r
+\r
+  @retval  EFI_SUCCESS   Update the file explorer form success.\r
+  @retval  other errors  Error occur when parse one directory.\r
+\r
+**/\r
+EFI_STATUS\r
+LibUpdateFileExplorer (\r
+  IN UINT16                       KeyValue\r
+  )\r
+{\r
+  UINT16          FileOptionMask;\r
+  MENU_ENTRY      *NewMenuEntry;\r
+  FILE_CONTEXT    *NewFileContext;\r
+  EFI_STATUS      Status;\r
+  EFI_FILE_HANDLE FileHandle;\r
+\r
+  Status = EFI_SUCCESS;\r
+  FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);\r
+  NewMenuEntry   = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);\r
+  NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+  if (NewFileContext->IsDir) {\r
+    RemoveEntryList (&NewMenuEntry->Link);\r
+    LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);\r
+    LibGetFileHandleFromMenu (NewMenuEntry, &FileHandle);\r
+    Status = LibFindFiles (FileHandle, NewFileContext->FileName, NewFileContext->DeviceHandle);\r
+    if (!EFI_ERROR (Status)) {\r
+      LibUpdateFileExplorePage ();\r
+    } else {\r
+      LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);\r
+    }\r
+    LibDestroyMenuEntry (NewMenuEntry);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+  Get the device path info saved in the menu structure.\r
+\r
+  @param KeyValue        Key value to identify the type of data to expect.\r
+\r
+**/\r
+VOID\r
+LibGetDevicePath (\r
+  IN UINT16                       KeyValue\r
+  )\r
+{\r
+  UINT16          FileOptionMask;\r
+  MENU_ENTRY      *NewMenuEntry;\r
+  FILE_CONTEXT    *NewFileContext;\r
+\r
+  FileOptionMask    = (UINT16) (FILE_OPTION_MASK & KeyValue);\r
+\r
+  NewMenuEntry = LibGetMenuEntry (gFileExplorerPrivate.FsOptionMenu, FileOptionMask);\r
+\r
+  NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+  if (gFileExplorerPrivate.RetDevicePath != NULL) {\r
+    FreePool (gFileExplorerPrivate.RetDevicePath);\r
+  }\r
+  gFileExplorerPrivate.RetDevicePath = DuplicateDevicePath (NewFileContext->DevicePath);\r
+}\r
+\r
+/**\r
+  Choose a file in the specified directory. \r
+\r
+  If user input NULL for the RootDirectory, will choose file in the system.\r
+\r
+  If user input *File != NULL, function will return the allocate device path\r
+  info for the choosed file, caller has to free the memory after use it.\r
+\r
+  @param  RootDirectory    Pointer to the root directory.\r
+  @param  FileType         The file type need to choose.\r
+  @param  ChooseHandler    Function pointer to the extra task need to do\r
+                           after choose one file.\r
+  @param  File             Return the device path for the last time chosed file.\r
+\r
+  @retval EFI_SUCESS             Choose file success.\r
+  @retval EFI_INVALID_PARAMETER  Both ChooseHandler and return device path are NULL\r
+                                 One of them must not NULL.\r
+  @retval Other errors           Choose file failed.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+ChooseFile (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *RootDirectory,\r
+  IN  CHAR16                    *FileType,  OPTIONAL\r
+  IN  CHOOSE_HANDLER            ChooseHandler,  OPTIONAL\r
+  OUT EFI_DEVICE_PATH_PROTOCOL  **File  OPTIONAL\r
+  )\r
+{\r
+  EFI_FILE_HANDLE                   FileHandle;\r
+  EFI_STATUS                        Status;\r
+  UINT16                            *FileName;\r
+  EFI_HANDLE                        DeviceHandle;\r
+\r
+  if ((ChooseHandler == NULL) && (File == NULL)) {\r
+    return EFI_INVALID_PARAMETER;\r
+  }\r
+\r
+  FileName = NULL;\r
+\r
+  gFileExplorerPrivate.RetDevicePath = NULL;\r
+  gFileExplorerPrivate.ChooseHandler = ChooseHandler;\r
+  if (FileType != NULL) {\r
+    gFileExplorerPrivate.FileType = AllocateCopyPool (StrSize (FileType), FileType);\r
+    LibToLowerString(gFileExplorerPrivate.FileType);\r
+  } else {\r
+    gFileExplorerPrivate.FileType = NULL;\r
+  }\r
+\r
+  if (RootDirectory == NULL) {\r
+    Status = LibFindFileSystem();\r
+  } else {\r
+    Status = LibGetFileHandleFromDevicePath(RootDirectory, &FileHandle, &FileName, &DeviceHandle);\r
+    if (EFI_ERROR (Status)) {\r
+      goto Done;\r
+    }\r
+\r
+    Status = LibFindFiles (FileHandle, FileName, DeviceHandle);\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
+    goto Done;\r
+  }\r
+\r
+  LibUpdateFileExplorePage();\r
+\r
+  gFileExplorerPrivate.FormBrowser2->SendForm (\r
+                         gFileExplorerPrivate.FormBrowser2,\r
+                         &gFileExplorerPrivate.FeHiiHandle,\r
+                         1,\r
+                         &FileExplorerGuid,\r
+                         0,\r
+                         NULL,\r
+                         NULL\r
+                         );\r
+\r
+Done:\r
+  if ((Status == EFI_SUCCESS) && (File != NULL)) {\r
+    *File  = gFileExplorerPrivate.RetDevicePath;\r
+  } else if (gFileExplorerPrivate.RetDevicePath != NULL) {\r
+    FreePool (gFileExplorerPrivate.RetDevicePath);\r
+  }\r
+\r
+  if (gFileExplorerPrivate.FileType != NULL) {\r
+    FreePool (gFileExplorerPrivate.FileType);\r
+  }\r
+\r
+  LibFreeMenu (gFileExplorerPrivate.FsOptionMenu);\r
+\r
+  if (FileName != NULL) {\r
+    FreePool (FileName);\r
+  }\r
+\r
+  return Status;\r
+}\r
+\r
+/**\r
+\r
+  Install Boot Manager Menu driver.\r
+\r
+  @param ImageHandle     The image handle.\r
+  @param SystemTable     The system table.\r
+\r
+  @retval  EFI_SUCEESS  Install File explorer library success.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileExplorerLibConstructor (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS                     Status;\r
+\r
+  gHiiVendorDevicePath = (HII_VENDOR_DEVICE_PATH*) DuplicateDevicePath ((EFI_DEVICE_PATH_PROTOCOL*)&FeHiiVendorDevicePath);\r
+  ASSERT (gHiiVendorDevicePath != NULL);\r
+  CopyGuid (&gHiiVendorDevicePath->VendorDevicePath.Guid, &gEfiCallerIdGuid);\r
+\r
+  //\r
+  // Install Device Path Protocol and Config Access protocol to driver handle\r
+  //\r
+  Status = gBS->InstallMultipleProtocolInterfaces (\r
+                  &gFileExplorerPrivate.FeDriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  gHiiVendorDevicePath,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  &gFileExplorerPrivate.FeConfigAccess,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+\r
+  //\r
+  // Post our File Explorer VFR binary to the HII database.\r
+  //\r
+  gFileExplorerPrivate.FeHiiHandle = HiiAddPackages (\r
+                                   &FileExplorerGuid,\r
+                                   gFileExplorerPrivate.FeDriverHandle,\r
+                                   FileExplorerVfrBin,\r
+                                   FileExplorerLibStrings,\r
+                                   NULL\r
+                                   );\r
+  ASSERT (gFileExplorerPrivate.FeHiiHandle != NULL);\r
+\r
+  //\r
+  // Locate Formbrowser2 protocol\r
+  //\r
+  Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFileExplorerPrivate.FormBrowser2);\r
+  ASSERT_EFI_ERROR (Status);\r
+    \r
+  InitializeListHead (&gFileExplorerPrivate.FsOptionMenu->Head);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
+/**\r
+  Unloads the application and its installed protocol.\r
+\r
+  @param[in]  ImageHandle       Handle that identifies the image to be unloaded.\r
+  @param[in]  SystemTable       The system table.\r
+\r
+  @retval EFI_SUCCESS           The image has been unloaded.\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+FileExplorerLibDestructor (\r
+  IN EFI_HANDLE                            ImageHandle,\r
+  IN EFI_SYSTEM_TABLE                      *SystemTable\r
+  )\r
+{\r
+  EFI_STATUS    Status;\r
+\r
+  ASSERT (gHiiVendorDevicePath != NULL);\r
+\r
+  Status = gBS->UninstallMultipleProtocolInterfaces (\r
+                  gFileExplorerPrivate.FeDriverHandle,\r
+                  &gEfiDevicePathProtocolGuid,\r
+                  gHiiVendorDevicePath,\r
+                  &gEfiHiiConfigAccessProtocolGuid,\r
+                  &gFileExplorerPrivate.FeConfigAccess,\r
+                  NULL\r
+                  );\r
+  ASSERT_EFI_ERROR (Status);\r
+  \r
+  HiiRemovePackages (gFileExplorerPrivate.FeHiiHandle);\r
+\r
+  FreePool (gHiiVendorDevicePath);\r
+\r
+  return EFI_SUCCESS;\r
+}\r
+\r
index 4c27ea1d9dda16cb8929aa3f49f6e0fefc2e068c..fab20523adaa005b5989e563ec2c735f8ef04ef0 100644 (file)
-/** @file
-   File explorer lib.
-
-Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials                          
-are licensed and made available under the terms and conditions of the BSD License         
-which accompanies this distribution.  The full text of the license may be found at        
-http://opensource.org/licenses/bsd-license.php                                            
-                                                                                          
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             
-**/
-
-#ifndef _FILE_EXPLORER_H_
-#define _FILE_EXPLORER_H_
-
-#include <PiDxe.h>
-#include <Guid/FileSystemVolumeLabelInfo.h>
-#include <Guid/FileInfo.h>
-#include <Guid/MdeModuleHii.h>
-
-#include <Protocol/HiiConfigAccess.h>
-#include <Protocol/DevicePath.h>
-#include <Protocol/SimpleFileSystem.h>
-#include <Protocol/DevicePathToText.h>
-#include <Protocol/LoadFile.h>
-#include <Protocol/FormBrowser2.h>
-
-#include <Library/DebugLib.h>
-#include <Library/BaseMemoryLib.h>
-#include <Library/UefiBootServicesTableLib.h>
-#include <Library/MemoryAllocationLib.h>
-#include <Library/BaseLib.h>
-#include <Library/UefiLib.h>
-#include <Library/DevicePathLib.h>
-#include <Library/FileExplorerLib.h>
-#include <Library/HiiLib.h>
-#include <Library/PrintLib.h>
-
-#include "FormGuid.h"
-
-#define FILE_EXPLORER_CALLBACK_DATA_SIGNATURE     SIGNATURE_32 ('f', 'e', 'c', 'k')
-
-
-#pragma pack(1)
-
-///
-/// HII specific Vendor Device Path definition.
-///
-typedef struct {
-  VENDOR_DEVICE_PATH             VendorDevicePath;
-  EFI_DEVICE_PATH_PROTOCOL       End;
-} HII_VENDOR_DEVICE_PATH;
-
-typedef struct {
-  EFI_HANDLE                        DeviceHandle;
-  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;
-  EFI_FILE_HANDLE                   FileHandle;
-  UINT16                            *FileName;
-
-  BOOLEAN                           IsRoot;
-  BOOLEAN                           IsDir;
-} FILE_CONTEXT;
-
-typedef struct {
-  UINTN           Signature;
-  LIST_ENTRY      Link;
-  UINT16          *DisplayString;
-  UINT16          *HelpString;
-  EFI_STRING_ID   DisplayStringToken;
-  EFI_STRING_ID   HelpStringToken;
-  VOID            *VariableContext;
-} MENU_ENTRY;
-
-typedef struct {
-  UINTN           Signature;
-  LIST_ENTRY      Head;
-  UINTN           MenuNumber;
-  BOOLEAN         Used;
-} MENU_OPTION;
-
-typedef struct {
-  //
-  // Shared callback data.
-  //
-  UINTN                          Signature;
-
-  //
-  // File explorer formset callback data.
-  //
-  EFI_HII_HANDLE                 FeHiiHandle;
-  EFI_HANDLE                     FeDriverHandle;
-  EFI_HII_CONFIG_ACCESS_PROTOCOL FeConfigAccess;
-  EFI_FORM_BROWSER2_PROTOCOL     *FormBrowser2;
-  MENU_OPTION                    *FsOptionMenu;
-  CHAR16                         *FileType;
-  CHOOSE_HANDLER                 ChooseHandler;
-  EFI_DEVICE_PATH_PROTOCOL       *RetDevicePath;
-
-} FILE_EXPLORER_CALLBACK_DATA;
-
-#define FILE_EXPLORER_PRIVATE_FROM_THIS(a)  CR (a, FILE_EXPLORER_CALLBACK_DATA, FeConfigAccess, FILE_EXPLORER_CALLBACK_DATA_SIGNATURE)
-
-#pragma pack()
-
-extern UINT8    FileExplorerVfrBin[];
-
-#define MENU_OPTION_SIGNATURE      SIGNATURE_32 ('m', 'e', 'n', 'u')
-#define MENU_ENTRY_SIGNATURE       SIGNATURE_32 ('e', 'n', 't', 'r')
-
-///
-/// Define the maximum characters that will be accepted.
-///
-#define MAX_CHAR                480
-#define FILE_OPTION_OFFSET      0x8000
-#define FILE_OPTION_MASK        0x7FFF
-
-
-/**
-  This function processes the results of changes in configuration.
-  When user select a interactive opcode, this callback will be triggered.
-  Based on the Question(QuestionId) that triggers the callback, the corresponding
-  actions is performed. It handles:
-
-  1) the addition of boot option.
-  2) the addition of driver option.
-  3) exit from file browser
-  4) update of file content if a dir is selected.
-  5) boot the file if a file is selected in "boot from file"
-
-
-  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
-  @param Action          Specifies the type of action taken by the browser.
-  @param QuestionId      A unique value which is sent to the original exporting driver
-                         so that it can identify the type of data to expect.
-  @param Type            The type of value for the question.
-  @param Value           A pointer to the data being sent to the original exporting driver.
-  @param ActionRequest   On return, points to the action requested by the callback function.
-
-  @retval  EFI_SUCCESS           The callback successfully handled the action.
-  @retval  EFI_OUT_OF_RESOURCES  Not enough storage is available to hold the variable and its data.
-  @retval  EFI_DEVICE_ERROR      The variable could not be saved.
-  @retval  EFI_UNSUPPORTED       The specified Action is not supported by the callback.
-
-**/
-EFI_STATUS
-EFIAPI
-LibCallback (
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
-  IN  EFI_BROWSER_ACTION                     Action,
-  IN  EFI_QUESTION_ID                        QuestionId,
-  IN  UINT8                                  Type,
-  IN  EFI_IFR_TYPE_VALUE                     *Value,
-  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest
-  );
-
-
-/**
-  This function allows a caller to extract the current configuration for one
-  or more named elements from the target driver.
-
-
-  @param This            - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
-  @param Request         - A null-terminated Unicode string in <ConfigRequest> format.
-  @param Progress        - On return, points to a character in the Request string.
-                         Points to the string's null terminator if request was successful.
-                         Points to the most recent '&' before the first failing name/value
-                         pair (or the beginning of the string if the failure is in the
-                         first name/value pair) if the request was not successful.
-  @param Results         - A null-terminated Unicode string in <ConfigAltResp> format which
-                         has all values filled in for the names in the Request string.
-                         String to be allocated by the called function.
-
-  @retval  EFI_SUCCESS            The Results is filled with the requested values.
-  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.
-  @retval  EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.
-  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibExtractConfig (
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
-  IN  CONST EFI_STRING                       Request,
-  OUT EFI_STRING                             *Progress,
-  OUT EFI_STRING                             *Results
-  );
-
-/**
-  This function processes the results of changes in configuration.
-
-
-  @param This            - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
-  @param Configuration   - A null-terminated Unicode string in <ConfigResp> format.
-  @param Progress        - A pointer to a string filled in with the offset of the most
-                         recent '&' before the first failing name/value pair (or the
-                         beginning of the string if the failure is in the first
-                         name/value pair) or the terminating NULL if all was successful.
-
-  @retval  EFI_SUCCESS            The Results is processed successfully.
-  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.
-  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.
-
-**/
-EFI_STATUS
-EFIAPI
-LibRouteConfig (
-  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,
-  IN  CONST EFI_STRING                       Configuration,
-  OUT EFI_STRING                             *Progress
-  );
-
-/**
-  Update the file explower page with the refershed file system.
-
-  @param KeyValue        Key value to identify the type of data to expect.
-
-  @retval  EFI_SUCCESS   Update the file explorer form success.
-  @retval  other errors  Error occur when parse one directory.
-
-**/
-EFI_STATUS
-LibUpdateFileExplorer (
-  IN UINT16                       KeyValue
-  );
-  
-  
-/**
-  Get the device path info saved in the menu structure.
-
-  @param KeyValue        Key value to identify the type of data to expect.
-
-**/
-VOID
-LibGetDevicePath (
-  IN UINT16                       KeyValue
-  );
-
-#endif 
+/** @file\r
+   File explorer lib.\r
+\r
+Copyright (c) 2015, Intel Corporation. All rights reserved.<BR>\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
+#ifndef _FILE_EXPLORER_H_\r
+#define _FILE_EXPLORER_H_\r
+\r
+#include <PiDxe.h>\r
+#include <Guid/FileSystemVolumeLabelInfo.h>\r
+#include <Guid/FileInfo.h>\r
+#include <Guid/MdeModuleHii.h>\r
+\r
+#include <Protocol/HiiConfigAccess.h>\r
+#include <Protocol/DevicePath.h>\r
+#include <Protocol/SimpleFileSystem.h>\r
+#include <Protocol/DevicePathToText.h>\r
+#include <Protocol/LoadFile.h>\r
+#include <Protocol/FormBrowser2.h>\r
+\r
+#include <Library/DebugLib.h>\r
+#include <Library/BaseMemoryLib.h>\r
+#include <Library/UefiBootServicesTableLib.h>\r
+#include <Library/MemoryAllocationLib.h>\r
+#include <Library/BaseLib.h>\r
+#include <Library/UefiLib.h>\r
+#include <Library/DevicePathLib.h>\r
+#include <Library/FileExplorerLib.h>\r
+#include <Library/HiiLib.h>\r
+#include <Library/PrintLib.h>\r
+\r
+#include "FormGuid.h"\r
+\r
+#define FILE_EXPLORER_CALLBACK_DATA_SIGNATURE     SIGNATURE_32 ('f', 'e', 'c', 'k')\r
+\r
+\r
+#pragma pack(1)\r
+\r
+///\r
+/// HII specific Vendor Device Path definition.\r
+///\r
+typedef struct {\r
+  VENDOR_DEVICE_PATH             VendorDevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL       End;\r
+} HII_VENDOR_DEVICE_PATH;\r
+\r
+typedef struct {\r
+  EFI_HANDLE                        DeviceHandle;\r
+  EFI_DEVICE_PATH_PROTOCOL          *DevicePath;\r
+  EFI_FILE_HANDLE                   FileHandle;\r
+  UINT16                            *FileName;\r
+\r
+  BOOLEAN                           IsRoot;\r
+  BOOLEAN                           IsDir;\r
+} FILE_CONTEXT;\r
+\r
+typedef struct {\r
+  UINTN           Signature;\r
+  LIST_ENTRY      Link;\r
+  UINT16          *DisplayString;\r
+  UINT16          *HelpString;\r
+  EFI_STRING_ID   DisplayStringToken;\r
+  EFI_STRING_ID   HelpStringToken;\r
+  VOID            *VariableContext;\r
+} MENU_ENTRY;\r
+\r
+typedef struct {\r
+  UINTN           Signature;\r
+  LIST_ENTRY      Head;\r
+  UINTN           MenuNumber;\r
+  BOOLEAN         Used;\r
+} MENU_OPTION;\r
+\r
+typedef struct {\r
+  //\r
+  // Shared callback data.\r
+  //\r
+  UINTN                          Signature;\r
+\r
+  //\r
+  // File explorer formset callback data.\r
+  //\r
+  EFI_HII_HANDLE                 FeHiiHandle;\r
+  EFI_HANDLE                     FeDriverHandle;\r
+  EFI_HII_CONFIG_ACCESS_PROTOCOL FeConfigAccess;\r
+  EFI_FORM_BROWSER2_PROTOCOL     *FormBrowser2;\r
+  MENU_OPTION                    *FsOptionMenu;\r
+  CHAR16                         *FileType;\r
+  CHOOSE_HANDLER                 ChooseHandler;\r
+  EFI_DEVICE_PATH_PROTOCOL       *RetDevicePath;\r
+\r
+} FILE_EXPLORER_CALLBACK_DATA;\r
+\r
+#define FILE_EXPLORER_PRIVATE_FROM_THIS(a)  CR (a, FILE_EXPLORER_CALLBACK_DATA, FeConfigAccess, FILE_EXPLORER_CALLBACK_DATA_SIGNATURE)\r
+\r
+#pragma pack()\r
+\r
+extern UINT8    FileExplorerVfrBin[];\r
+\r
+#define MENU_OPTION_SIGNATURE      SIGNATURE_32 ('m', 'e', 'n', 'u')\r
+#define MENU_ENTRY_SIGNATURE       SIGNATURE_32 ('e', 'n', 't', 'r')\r
+\r
+///\r
+/// Define the maximum characters that will be accepted.\r
+///\r
+#define MAX_CHAR                480\r
+#define FILE_OPTION_OFFSET      0x8000\r
+#define FILE_OPTION_MASK        0x7FFF\r
+\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+  When user select a interactive opcode, this callback will be triggered.\r
+  Based on the Question(QuestionId) that triggers the callback, the corresponding\r
+  actions is performed. It handles:\r
+\r
+  1) the addition of boot option.\r
+  2) the addition of driver option.\r
+  3) exit from file browser\r
+  4) update of file content if a dir is selected.\r
+  5) boot the file if a file is selected in "boot from file"\r
+\r
+\r
+  @param This            Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Action          Specifies the type of action taken by the browser.\r
+  @param QuestionId      A unique value which is sent to the original exporting driver\r
+                         so that it can identify the type of data to expect.\r
+  @param Type            The type of value for the question.\r
+  @param Value           A pointer to the data being sent to the original exporting driver.\r
+  @param ActionRequest   On return, points to the action requested by the callback function.\r
+\r
+  @retval  EFI_SUCCESS           The callback successfully handled the action.\r
+  @retval  EFI_OUT_OF_RESOURCES  Not enough storage is available to hold the variable and its data.\r
+  @retval  EFI_DEVICE_ERROR      The variable could not be saved.\r
+  @retval  EFI_UNSUPPORTED       The specified Action is not supported by the callback.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LibCallback (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  EFI_BROWSER_ACTION                     Action,\r
+  IN  EFI_QUESTION_ID                        QuestionId,\r
+  IN  UINT8                                  Type,\r
+  IN  EFI_IFR_TYPE_VALUE                     *Value,\r
+  OUT EFI_BROWSER_ACTION_REQUEST             *ActionRequest\r
+  );\r
+\r
+\r
+/**\r
+  This function allows a caller to extract the current configuration for one\r
+  or more named elements from the target driver.\r
+\r
+\r
+  @param This            - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Request         - A null-terminated Unicode string in <ConfigRequest> format.\r
+  @param Progress        - On return, points to a character in the Request string.\r
+                         Points to the string's null terminator if request was successful.\r
+                         Points to the most recent '&' before the first failing name/value\r
+                         pair (or the beginning of the string if the failure is in the\r
+                         first name/value pair) if the request was not successful.\r
+  @param Results         - A null-terminated Unicode string in <ConfigAltResp> format which\r
+                         has all values filled in for the names in the Request string.\r
+                         String to be allocated by the called function.\r
+\r
+  @retval  EFI_SUCCESS            The Results is filled with the requested values.\r
+  @retval  EFI_OUT_OF_RESOURCES   Not enough memory to store the results.\r
+  @retval  EFI_INVALID_PARAMETER  Request is NULL, illegal syntax, or unknown name.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LibExtractConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Request,\r
+  OUT EFI_STRING                             *Progress,\r
+  OUT EFI_STRING                             *Results\r
+  );\r
+\r
+/**\r
+  This function processes the results of changes in configuration.\r
+\r
+\r
+  @param This            - Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
+  @param Configuration   - A null-terminated Unicode string in <ConfigResp> format.\r
+  @param Progress        - A pointer to a string filled in with the offset of the most\r
+                         recent '&' before the first failing name/value pair (or the\r
+                         beginning of the string if the failure is in the first\r
+                         name/value pair) or the terminating NULL if all was successful.\r
+\r
+  @retval  EFI_SUCCESS            The Results is processed successfully.\r
+  @retval  EFI_INVALID_PARAMETER  Configuration is NULL.\r
+  @retval  EFI_NOT_FOUND          Routing data doesn't match any storage in this driver.\r
+\r
+**/\r
+EFI_STATUS\r
+EFIAPI\r
+LibRouteConfig (\r
+  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL   *This,\r
+  IN  CONST EFI_STRING                       Configuration,\r
+  OUT EFI_STRING                             *Progress\r
+  );\r
+\r
+/**\r
+  Update the file explower page with the refershed file system.\r
+\r
+  @param KeyValue        Key value to identify the type of data to expect.\r
+\r
+  @retval  EFI_SUCCESS   Update the file explorer form success.\r
+  @retval  other errors  Error occur when parse one directory.\r
+\r
+**/\r
+EFI_STATUS\r
+LibUpdateFileExplorer (\r
+  IN UINT16                       KeyValue\r
+  );\r
+  \r
+  \r
+/**\r
+  Get the device path info saved in the menu structure.\r
+\r
+  @param KeyValue        Key value to identify the type of data to expect.\r
+\r
+**/\r
+VOID\r
+LibGetDevicePath (\r
+  IN UINT16                       KeyValue\r
+  );\r
+\r
+#endif \r
index b587bf59245ec78eb06d54ef7fe85aa83931ba89..89c75f9416c508ffbb406896b6ebff2f3d4e8bfe 100644 (file)
@@ -1,59 +1,59 @@
-## @file
-#  library defines a set of interfaces for how to do file explorer.
-#  
-#  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>
-#  This program and the accompanying materials are licensed and made available under
-#  the terms and conditions of the BSD License that accompanies this distribution.
-#  The full text of the license may be found at
-#  http://opensource.org/licenses/bsd-license.php.
-#  
-#  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-#  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-#  
-##
-[Defines]
-  INF_VERSION                    = 0x00010005
-  BASE_NAME                      = FileExplorerLib
-  FILE_GUID                      = 4FC9C630-0F90-4053-8F13-264CBD22FC58
-  MODULE_TYPE                    = DXE_DRIVER
-  VERSION_STRING                 = 1.0
-  LIBRARY_CLASS                  = FileExplorerLib|DXE_DRIVER UEFI_APPLICATION
-  CONSTRUCTOR                    = FileExplorerLibConstructor
-  DESTRUCTOR                     = FileExplorerLibDestructor
-
-#
-# The following information is for reference only and not required by the build tools.
-#
-#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC
-#
-
-[Sources]
-  FileExplorer.h
-  FileExplorerVfr.vfr
-  FileExplorerString.uni
-  FileExplorer.c
-  FormGuid.h
-
-[Packages]
-  MdePkg/MdePkg.dec
-  MdeModulePkg/MdeModulePkg.dec
-
-[LibraryClasses]
-  DevicePathLib
-  BaseLib
-  MemoryAllocationLib
-  UefiBootServicesTableLib
-  BaseMemoryLib
-  DebugLib
-  HiiLib
-
-[Guids]
-  gEfiFileSystemVolumeLabelInfoIdGuid           ## CONSUMES ## GUID (Indicate the information type is volume)
-  gEfiIfrTianoGuid                              ## CONSUMES ## GUID (Extended IFR Guid Opcode)
-[Protocols]
-  gEfiSimpleFileSystemProtocolGuid              ## CONSUMES
-  gEfiLoadFileProtocolGuid                      ## CONSUMES
-  gEfiHiiConfigAccessProtocolGuid               ## CONSUMES
-  gEfiFormBrowser2ProtocolGuid                  ## CONSUMES
+## @file\r
+#  library defines a set of interfaces for how to do file explorer.\r
+#  \r
+#  Copyright (c) 2011 - 2015, Intel Corporation. All rights reserved.<BR>\r
+#  This program and the accompanying materials are licensed and made available under\r
+#  the terms and conditions of the BSD License that accompanies this distribution.\r
+#  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
+[Defines]\r
+  INF_VERSION                    = 0x00010005\r
+  BASE_NAME                      = FileExplorerLib\r
+  FILE_GUID                      = 4FC9C630-0F90-4053-8F13-264CBD22FC58\r
+  MODULE_TYPE                    = DXE_DRIVER\r
+  VERSION_STRING                 = 1.0\r
+  LIBRARY_CLASS                  = FileExplorerLib|DXE_DRIVER UEFI_APPLICATION\r
+  CONSTRUCTOR                    = FileExplorerLibConstructor\r
+  DESTRUCTOR                     = FileExplorerLibDestructor\r
+\r
+#\r
+# The following information is for reference only and not required by the build tools.\r
+#\r
+#  VALID_ARCHITECTURES           = IA32 X64 IPF EBC\r
+#\r
+\r
+[Sources]\r
+  FileExplorer.h\r
+  FileExplorerVfr.vfr\r
+  FileExplorerString.uni\r
+  FileExplorer.c\r
+  FormGuid.h\r
+\r
+[Packages]\r
+  MdePkg/MdePkg.dec\r
+  MdeModulePkg/MdeModulePkg.dec\r
+\r
+[LibraryClasses]\r
+  DevicePathLib\r
+  BaseLib\r
+  MemoryAllocationLib\r
+  UefiBootServicesTableLib\r
+  BaseMemoryLib\r
+  DebugLib\r
+  HiiLib\r
+\r
+[Guids]\r
+  gEfiFileSystemVolumeLabelInfoIdGuid           ## CONSUMES ## GUID (Indicate the information type is volume)\r
+  gEfiIfrTianoGuid                              ## CONSUMES ## GUID (Extended IFR Guid Opcode)\r
\r
+[Protocols]\r
+  gEfiSimpleFileSystemProtocolGuid              ## CONSUMES\r
+  gEfiLoadFileProtocolGuid                      ## CONSUMES\r
+  gEfiHiiConfigAccessProtocolGuid               ## CONSUMES\r
+  gEfiFormBrowser2ProtocolGuid                  ## CONSUMES\r
   gEfiDevicePathToTextProtocolGuid              ## CONSUMES
\ No newline at end of file
index 89dd81ad0820f3e73561f5341a2c253a36f35e34..ef7c99c24fe4642e2522dad5f21dde72305bcabe 100644 (file)
@@ -1,31 +1,31 @@
-///** @file
-//
-//    File Explorer Formset
-//
-//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
-//  This program and the accompanying materials
-//  are licensed and made available under the terms and conditions of the BSD License
-//  which accompanies this distribution.  The full text of the license may be found at
-//  http://opensource.org/licenses/bsd-license.php
-//
-//  THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-//  WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-//
-//**/
-
-#include "FormGuid.h"
-
-formset
-  guid = EFI_FILE_EXPLORE_FORMSET_GUID,
-  title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE),
-  help = STRING_TOKEN(STR_NULL_STRING),
-  classguid = EFI_FILE_EXPLORE_FORMSET_GUID,
-
-  form formid = FORM_FILE_EXPLORER_ID,
-       title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE);
-
-       label FORM_FILE_EXPLORER_ID;
-       label LABEL_END;
-  endform;
-
+///** @file\r
+//\r
+//    File Explorer Formset\r
+//\r
+//  Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\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 "FormGuid.h"\r
+\r
+formset\r
+  guid = EFI_FILE_EXPLORE_FORMSET_GUID,\r
+  title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE),\r
+  help = STRING_TOKEN(STR_NULL_STRING),\r
+  classguid = EFI_FILE_EXPLORE_FORMSET_GUID,\r
+\r
+  form formid = FORM_FILE_EXPLORER_ID,\r
+       title = STRING_TOKEN(STR_FILE_EXPLORER_TITLE);\r
+\r
+       label FORM_FILE_EXPLORER_ID;\r
+       label LABEL_END;\r
+  endform;\r
+\r
 endformset;
\ No newline at end of file
index 6c23c6c5e40635b955200c401c874159aab4c4ad..011ae228c9f3ba94a2e4283f3414f2b7cca3f3fa 100644 (file)
@@ -1,29 +1,29 @@
-/** @file
-Formset guids, form id and VarStore data structure for File explorer library.
-
-Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
-This program and the accompanying materials are licensed and made available under
-the terms and conditions of the BSD License that accompanies this distribution.
-The full text of the license may be found at
-http://opensource.org/licenses/bsd-license.php.
-
-THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
-WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
-
-**/
-
-
-#ifndef _FILE_EXPLORER_FORM_GUID_H_
-#define _FILE_EXPLORER_FORM_GUID_H_
-
-
-#define EFI_FILE_EXPLORE_FORMSET_GUID \
-  { \
-  0x1f2d63e1, 0xfebd, 0x4dc7, {0x9c, 0xc5, 0xba, 0x2b, 0x1c, 0xef, 0x9c, 0x5b} \
-  }
-
-#define FORM_FILE_EXPLORER_ID                0x1000
-#define LABEL_END                            0xffff
-
-#endif
-
+/** @file\r
+Formset guids, form id and VarStore data structure for File explorer library.\r
+\r
+Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
+This program and the accompanying materials are licensed and made available under\r
+the terms and conditions of the BSD License that accompanies this distribution.\r
+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
+\r
+#ifndef _FILE_EXPLORER_FORM_GUID_H_\r
+#define _FILE_EXPLORER_FORM_GUID_H_\r
+\r
+\r
+#define EFI_FILE_EXPLORE_FORMSET_GUID \\r
+  { \\r
+  0x1f2d63e1, 0xfebd, 0x4dc7, {0x9c, 0xc5, 0xba, 0x2b, 0x1c, 0xef, 0x9c, 0x5b} \\r
+  }\r
+\r
+#define FORM_FILE_EXPLORER_ID                0x1000\r
+#define LABEL_END                            0xffff\r
+\r
+#endif\r
+\r