/** @file
File explorer related functions.

Copyright (c) 2004 - 2017, 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;
UINT16              mQuestionIdUpdate;
CHAR16  mNewFileName[MAX_FILE_NAME_LEN];
CHAR16  mNewFolderName[MAX_FOLDER_NAME_LEN];
UINTN  mNewFileQuestionId    = NEW_FILE_QUESTION_ID_BASE;
UINTN  mNewFolderQuestionId  = NEW_FOLDER_QUESTION_ID_BASE;

/**
  Create a new file or folder in current directory.

  @param FileName              Point to the fileNmae or folder.
  @param CreateFile            CreateFile== TRUE  means create a new file.
                               CreateFile== FALSE means create a new Folder.

**/
EFI_STATUS
LibCreateNewFile (
  IN CHAR16     *FileName,
  IN BOOLEAN    CreateFile
  );

/**
  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;
  CHAR16        *NewFileName;
  CHAR16        *NewFolderName;

  NeedExit = TRUE;
  NewFileName   = NULL;
  NewFolderName = NULL;

  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;
  }

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }

    if (QuestionId == KEY_VALUE_CREATE_FILE_AND_EXIT) {
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
      if (!IsZeroBuffer (mNewFileName, sizeof (mNewFileName))) {
        Status = LibCreateNewFile (mNewFileName,TRUE);
        ZeroMem (mNewFileName,sizeof (mNewFileName));
      }
    }

    if (QuestionId == KEY_VALUE_NO_CREATE_FILE_AND_EXIT) {
      ZeroMem (mNewFileName,sizeof (mNewFileName));
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    }

    if (QuestionId == KEY_VALUE_CREATE_FOLDER_AND_EXIT) {
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
      if (!IsZeroBuffer (mNewFolderName, sizeof (mNewFolderName))) {
        Status = LibCreateNewFile (mNewFolderName, FALSE);
        ZeroMem (mNewFolderName,sizeof (mNewFolderName));
      }
    }

    if (QuestionId == KEY_VALUE_NO_CREATE_FOLDER_AND_EXIT) {
      ZeroMem (mNewFolderName,sizeof (mNewFolderName));
      *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;
    }

    if (QuestionId == NEW_FILE_NAME_ID) {
      NewFileName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL);
      if (NewFileName != NULL) {
        StrCpyS (mNewFileName, MAX_FILE_NAME_LEN, NewFileName);
        FreePool (NewFileName);
        NewFileName = NULL;
      } else {
        return EFI_INVALID_PARAMETER;
      }
    }

    if (QuestionId == NEW_FOLDER_NAME_ID) {
      NewFolderName = HiiGetString (gFileExplorerPrivate.FeHiiHandle, Value->string, NULL);
      if (NewFolderName != NULL) {
        StrCpyS (mNewFolderName, MAX_FOLDER_NAME_LEN, NewFolderName);
        FreePool (NewFolderName);
        NewFolderName = NULL;
      } else {
        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) {
      LibGetDevicePath(QuestionId);
      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) {
    if (FileContext->DevicePath != NULL) {
      FreePool (FileContext->DevicePath);
    }
  } else {
    if (FileContext->FileHandle != NULL) {
      FileContext->FileHandle->Close (FileContext->FileHandle);
    }
  }

  if (FileContext->FileName != NULL) {
    FreePool (FileContext->FileName);
  }

  FreePool (FileContext);

  if (MenuEntry->DisplayString != NULL) {
    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);
  ASSERT(TmpStr != NULL);
  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);
  
  //
  // Check overflow
  //
  if (((MAX_UINTN - Size1) < Size2) || ((MAX_UINTN - Size1 - Size2) < sizeof(CHAR16))) {
    return NULL;
  }
  
  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 - (UINTN) Str) / sizeof (CHAR16), 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 - (UINTN) Str) / sizeof (CHAR16), 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;
  EFI_HANDLE                   *SimpleFsHandle;
  UINT16                       *VolumeLabel;
  UINTN                        Index;
  EFI_STATUS                   Status;
  MENU_ENTRY                   *MenuEntry;
  FILE_CONTEXT                 *FileContext;
  UINTN                        OptionNumber;
  EFI_FILE_SYSTEM_VOLUME_LABEL *Info;

  NoSimpleFsHandles = 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
                                             );

      if (Info != NULL)
        FreePool (Info);

      OptionNumber++;
      InsertTailList (&gFileExplorerPrivate.FsOptionMenu->Head, &MenuEntry->Link);
    }
  }

  if (NoSimpleFsHandles != 0) {
    FreePool (SimpleFsHandle);
  }

  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;
    goto Done;
  }
        
  //
  // 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);
      if (TempPath == NULL) {
        LastHandle->Close (LastHandle);
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }
      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;
}

/**
  Create a new file or folder in current directory.

  @param FileName              Point to the fileNmae or folder name.
  @param CreateFile            CreateFile== TRUE  means create a new file.
                               CreateFile== FALSE means create a new Folder.

**/
EFI_STATUS
LibCreateNewFile (
  IN CHAR16     *FileName,
  IN BOOLEAN    CreateFile
  )
{
  EFI_FILE_HANDLE      FileHandle;
  EFI_FILE_HANDLE      NewHandle;
  EFI_HANDLE           DeviceHandle;
  EFI_STATUS           Status;
  CHAR16               *ParentName;
  CHAR16               *FullFileName;

  NewHandle = NULL;
  FullFileName = NULL;

  LibGetFileHandleFromDevicePath(gFileExplorerPrivate.RetDevicePath, &FileHandle, &ParentName, &DeviceHandle);
  FullFileName = LibAppendFileName (ParentName, FileName);
  if (FullFileName == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }
  if (CreateFile) {
    Status = FileHandle->Open(
                          FileHandle,
                          &NewHandle,
                          FullFileName,
                          EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,
                          0
                          );
    if (EFI_ERROR (Status)) {
      FileHandle->Close (FileHandle);
      return Status;
    }
  } else {
    Status = FileHandle->Open(
                          FileHandle,
                          &NewHandle,
                          FullFileName,
                          EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE| EFI_FILE_MODE_CREATE,
                          EFI_FILE_DIRECTORY
                          );
    if (EFI_ERROR (Status)) {
      FileHandle->Close (FileHandle);
      return Status;
    }
  }

  FileHandle->Close (FileHandle);

  //
  // Return the DevicePath of the new created file or folder.
  //
  gFileExplorerPrivate.RetDevicePath = FileDevicePath (DeviceHandle, FullFileName);

  return EFI_SUCCESS;

}

/**
  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
  //
  Status = EFI_SUCCESS;
  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) {
        Status = EFI_SUCCESS;
        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) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      NewFileContext = (FILE_CONTEXT *) NewMenuEntry->VariableContext;
      NewFileContext->DeviceHandle = DeviceHandle;
      NewFileContext->FileName = LibAppendFileName (FileName, DirInfo->FileName);
      if  (NewFileContext->FileName == NULL) {
        LibDestroyMenuEntry (NewMenuEntry);
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }
      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;

Done:

  FreePool (DirInfo);

  return Status;
}

/**
  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;
  BOOLEAN         CreateNewFile;

  NewMenuEntry    = NULL;
  NewFileContext  = NULL;
  CreateNewFile   = FALSE;

  LibRefreshUpdateData ();
  MenuOption = gFileExplorerPrivate.FsOptionMenu;

  mQuestionIdUpdate += QUESTION_ID_UPDATE_STEP;

  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
    NewMenuEntry    = LibGetMenuEntry (MenuOption, Index);
    NewFileContext  = (FILE_CONTEXT *) NewMenuEntry->VariableContext;

    if (!NewFileContext->IsRoot && !CreateNewFile) {
      HiiCreateGotoOpCode (
        mLibStartOpCodeHandle,
        FORM_ADD_NEW_FILE_ID,
        STRING_TOKEN (STR_NEW_FILE),
        STRING_TOKEN (STR_NEW_FILE_HELP),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (mNewFileQuestionId++)
        );
      HiiCreateGotoOpCode (
        mLibStartOpCodeHandle,
        FORM_ADD_NEW_FOLDER_ID,
        STRING_TOKEN (STR_NEW_FOLDER),
        STRING_TOKEN (STR_NEW_FOLDER_HELP),
        EFI_IFR_FLAG_CALLBACK,
        (UINT16) (mNewFolderQuestionId++)
        );
      HiiCreateTextOpCode(
        mLibStartOpCodeHandle,
        STRING_TOKEN (STR_NULL_STRING),
        STRING_TOKEN (STR_NULL_STRING),
        0
        );
      CreateNewFile = TRUE;
    }

    if (!NewFileContext->IsDir) {
      //
      // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
      //
      HiiCreateActionOpCode (
        mLibStartOpCodeHandle,
        (UINT16) (FILE_OPTION_OFFSET + Index + mQuestionIdUpdate),
        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 + mQuestionIdUpdate)
        );
    }
  }

  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) - mQuestionIdUpdate;
  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) - mQuestionIdUpdate;

  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;
  }

  mQuestionIdUpdate = 0;
  FileName = NULL;

  gFileExplorerPrivate.RetDevicePath = NULL;
  gFileExplorerPrivate.ChooseHandler = ChooseHandler;
  if (FileType != NULL) {
    gFileExplorerPrivate.FileType = AllocateCopyPool (StrSize (FileType), FileType);
    ASSERT(gFileExplorerPrivate.FileType != NULL);
    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
                  );
  if (Status == EFI_ALREADY_STARTED) {
    return EFI_SUCCESS;
  }
  if (EFI_ERROR (Status)) {
    return 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);

  if (gFileExplorerPrivate.FeDriverHandle != NULL) {
    Status = gBS->UninstallMultipleProtocolInterfaces (
                    gFileExplorerPrivate.FeDriverHandle,
                    &gEfiDevicePathProtocolGuid,
                    gHiiVendorDevicePath,
                    &gEfiHiiConfigAccessProtocolGuid,
                    &gFileExplorerPrivate.FeConfigAccess,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);
    
    HiiRemovePackages (gFileExplorerPrivate.FeHiiHandle);
  }

  FreePool (gHiiVendorDevicePath);

  return EFI_SUCCESS;
}

