/** @file
File explorer related functions.

Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials are licensed and made available under
the terms and conditions of the BSD License 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;
  }

  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
                  );
  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;
}

