/** @file
  This driver uses the EFI_FIRMWARE_VOLUME2_PROTOCOL to expose files in firmware
  volumes via the the EFI_SIMPLE_FILESYSTEM_PROTOCOL and EFI_FILE_PROTOCOL.

  It will expose a single directory, containing one file for each file in the firmware
  volume. If a file has a UI section, its contents will be used as a filename.
  Otherwise, a string representation of the GUID will be used.
  Files of an executable type (That is PEIM, DRIVER, COMBINED_PEIM_DRIVER and APPLICATION)
  will have ".efi" added to their filename.

  Its primary intended use is to be able to start EFI applications embedded in FVs
  from the UEFI shell. It is entirely read-only.

Copyright (c) 2014, ARM Limited. All rights reserved.
Copyright (c) 2014, 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 "FvSimpleFileSystemInternal.h"

EFI_UNICODE_COLLATION_PROTOCOL          *mUnicodeCollation = NULL;

//
// A Guid string is 32 hex characters with 4 hyphens and a NULL-terminated char: 37 characters total
//
#define GUID_STRING_SIZE                (37 * sizeof (CHAR16))

#define FVFS_VOLUME_LABEL_PREFIX        L"Firmware Volume: "
#define FVFS_VOLUME_LABEL_SIZE          (sizeof (FVFS_VOLUME_LABEL_PREFIX) + GUID_STRING_SIZE - sizeof (CHAR16))
#define FVFS_FALLBACK_VOLUME_LABEL      L"Firmware Volume"

//
// Template for EFI_SIMPLE_FILE_SYSTEM_PROTOCOL data structure.
//
EFI_SIMPLE_FILE_SYSTEM_PROTOCOL mSimpleFsTemplate = {
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL_REVISION,
  FvSimpleFileSystemOpenVolume
};

//
// Template for EFI_DRIVER_BINDING_PROTOCOL data structure.
//
EFI_DRIVER_BINDING_PROTOCOL mDriverBinding = {
  FvSimpleFileSystemDriverSupported,
  FvSimpleFileSystemDriverStart,
  FvSimpleFileSystemDriverStop,
  0,
  NULL,
  NULL
};

/**
  Open the root directory on a volume.

  @param  This     A pointer to the volume to open the root directory.
  @param  RootFile A pointer to the location to return the opened file handle for the
                   root directory.

  @retval EFI_SUCCESS          The device was opened.
  @retval EFI_UNSUPPORTED      This volume does not support the requested file system type.
  @retval EFI_NO_MEDIA         The device has no medium.
  @retval EFI_DEVICE_ERROR     The device reported an error.
  @retval EFI_VOLUME_CORRUPTED The file system structures are corrupted.
  @retval EFI_ACCESS_DENIED    The service denied access to the file.
  @retval EFI_OUT_OF_RESOURCES The volume was not opened due to lack of resources.
  @retval EFI_MEDIA_CHANGED    The device has a different medium in it or the medium is no
                               longer supported. Any existing file handles for this volume are
                               no longer valid. To access the files on the new medium, the
                               volume must be reopened with OpenVolume().

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemOpenVolume (
  IN     EFI_SIMPLE_FILE_SYSTEM_PROTOCOL *This,
     OUT EFI_FILE_PROTOCOL               **RootFile
  )
{
  EFI_STATUS                      Status;
  FV_FILESYSTEM_FILE              *Root;
  CHAR16                          *UiSection;
  EFI_GUID                        NameGuid;
  EFI_FV_FILE_ATTRIBUTES          Attributes;
  UINT32                          Authentication;
  UINTN                           Key;
  EFI_FV_FILETYPE                 FileType;
  UINTN                           Size;
  FV_FILESYSTEM_INSTANCE          *Instance;
  FV_FILESYSTEM_FILE_INFO         *FvFileInfo;
  EFI_FIRMWARE_VOLUME2_PROTOCOL   *FvProtocol;
  CHAR16                          *Name;
  UINTN                           NameLen;
  UINTN                           NumChars;
  UINTN                           DestMax;

  Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (This);
  Status = EFI_SUCCESS;

  if (Instance->Root == NULL) {
    //
    // Allocate file structure for root file
    //
    Root = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE));
    if (Root == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Instance->Root  = Root;
    Root->Instance  = Instance;
    Root->Signature = FVFS_FILE_SIGNATURE;
    CopyMem (&Root->FileProtocol, &mFileSystemTemplate, sizeof (mFileSystemTemplate));
    Root->FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO));
    if (Root->FvFileInfo == NULL) {
        return EFI_OUT_OF_RESOURCES;
    }
    Root->FvFileInfo->FileInfo.Size      = sizeof (EFI_FILE_INFO);
    Root->FvFileInfo->FileInfo.Attribute = EFI_FILE_DIRECTORY | EFI_FILE_READ_ONLY;

    //
    // Populate the instance's list of files. We consider anything a file that
    // has a UI_SECTION, which we consider to be its filename.
    //
    FvProtocol = Instance->FvProtocol;
    //
    // Allocate Key
    //
    Key = 0;

    do {
      FileType = EFI_FV_FILETYPE_ALL;

      Status = FvProtocol->GetNextFile (
                             FvProtocol,
                             &Key,
                             &FileType,
                             &NameGuid,
                             &Attributes,
                             &Size
                             );
      if (EFI_ERROR (Status)) {
        ASSERT (Status == EFI_NOT_FOUND);
        break;
      }

      //
      // Get a file's name: If it has a UI section, use that, otherwise use
      // its NameGuid.
      //
      UiSection = NULL;
      Status = FvProtocol->ReadSection (
                             FvProtocol,
                             &NameGuid,
                             EFI_SECTION_USER_INTERFACE,
                             0,
                             (VOID **)&UiSection,
                             &Size,
                             &Authentication
                             );
      if (!EFI_ERROR (Status)) {
        Name = UiSection;
      } else {
        Name = AllocateZeroPool (GUID_STRING_SIZE);
        if (Name == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }
        NumChars = UnicodeSPrint (Name, GUID_STRING_SIZE, L"%g", &NameGuid);
        ASSERT ((NumChars + 1) * sizeof (CHAR16) == GUID_STRING_SIZE);
      }

      //
      // Found a file.
      // Allocate a file structure and populate it.
      //
      NameLen = StrSize (Name);
      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
        NameLen += StrSize (L".efi") - sizeof (CHAR16);
      }

      FvFileInfo = AllocateZeroPool (sizeof (FV_FILESYSTEM_FILE_INFO) + NameLen - sizeof (CHAR16));
      if (FvFileInfo == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      FvFileInfo->Signature = FVFS_FILE_INFO_SIGNATURE;
      InitializeListHead (&FvFileInfo->Link);
      CopyMem (&FvFileInfo->NameGuid, &NameGuid, sizeof (EFI_GUID));
      FvFileInfo->Type = FileType;

      //
      // Add ".efi" to filenames of drivers and applications.
      //
      DestMax = NameLen / sizeof (CHAR16);
      Status  = StrnCpyS (&FvFileInfo->FileInfo.FileName[0], DestMax, Name, StrLen (Name));
      ASSERT_EFI_ERROR (Status);

      if (FV_FILETYPE_IS_EXECUTABLE (FileType)) {
        Status  = StrnCatS (&FvFileInfo->FileInfo.FileName[0], DestMax, L".efi", StrLen (L".efi"));
        ASSERT_EFI_ERROR (Status);
      }

      FvFileInfo->FileInfo.Size     = sizeof (EFI_FILE_INFO) + NameLen - sizeof (CHAR16);
      Status = FvFsGetFileSize (FvProtocol, FvFileInfo);
      ASSERT_EFI_ERROR (Status);
      FvFileInfo->FileInfo.PhysicalSize = FvFileInfo->FileInfo.FileSize;
      FvFileInfo->FileInfo.Attribute    = EFI_FILE_READ_ONLY;

      InsertHeadList (&Instance->FileInfoHead, &FvFileInfo->Link);

      FreePool (Name);

    } while (TRUE);

    if (Status == EFI_NOT_FOUND) {
      Status = EFI_SUCCESS;
    }
  }

  Instance->Root->DirReadNext = FVFS_GET_FIRST_FILE_INFO (Instance);
  *RootFile = &Instance->Root->FileProtocol;
  return Status;
}

/**
  Worker function to initialize Unicode Collation support.

  It tries to locate Unicode Collation (2) protocol and matches it with current
  platform language code.

  @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.
  @param  ProtocolGuid         The pointer to Unicode Collation (2) protocol GUID.
  @param  VariableName         The name of the RFC 4646 or ISO 639-2 language variable.
  @param  DefaultLanguage      The default language in case the RFC 4646 or ISO 639-2 language is absent.

  @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.
  @retval Others               The Unicode Collation (2) protocol has not been located.

**/
EFI_STATUS
InitializeUnicodeCollationSupportWorker (
  IN       EFI_HANDLE             AgentHandle,
  IN       EFI_GUID               *ProtocolGuid,
  IN CONST CHAR16                 *VariableName,
  IN CONST CHAR8                  *DefaultLanguage
  )
{
  EFI_STATUS                      ReturnStatus;
  EFI_STATUS                      Status;
  UINTN                           NumHandles;
  UINTN                           Index;
  EFI_HANDLE                      *Handles;
  EFI_UNICODE_COLLATION_PROTOCOL  *Uci;
  BOOLEAN                         Iso639Language;
  CHAR8                           *Language;
  CHAR8                           *BestLanguage;

  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  ProtocolGuid,
                  NULL,
                  &NumHandles,
                  &Handles
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Iso639Language = (BOOLEAN) (ProtocolGuid == &gEfiUnicodeCollationProtocolGuid);
  GetEfiGlobalVariable2 (VariableName, (VOID**) &Language, NULL);

  ReturnStatus = EFI_UNSUPPORTED;
  for (Index = 0; Index < NumHandles; Index++) {
    //
    // Open Unicode Collation Protocol
    //
    Status = gBS->OpenProtocol (
                    Handles[Index],
                    ProtocolGuid,
                    (VOID **) &Uci,
                    AgentHandle,
                    NULL,
                    EFI_OPEN_PROTOCOL_GET_PROTOCOL
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    //
    // Find the best matching matching language from the supported languages
    // of Unicode Collation (2) protocol.
    //
    BestLanguage = GetBestLanguage (
                     Uci->SupportedLanguages,
                     Iso639Language,
                     (Language == NULL) ? "" : Language,
                     DefaultLanguage,
                     NULL
                     );
    if (BestLanguage != NULL) {
      FreePool (BestLanguage);
      mUnicodeCollation = Uci;
      ReturnStatus = EFI_SUCCESS;
      break;
    }
  }

  if (Language != NULL) {
    FreePool (Language);
  }

  FreePool (Handles);

  return ReturnStatus;
}

/**
  Initialize Unicode Collation support.

  It tries to locate Unicode Collation 2 protocol and matches it with current
  platform language code. If for any reason the first attempt fails, it then tries to
  use Unicode Collation Protocol.

  @param  AgentHandle          The handle used to open Unicode Collation (2) protocol.

  @retval EFI_SUCCESS          The Unicode Collation (2) protocol has been successfully located.
  @retval Others               The Unicode Collation (2) protocol has not been located.

**/
EFI_STATUS
InitializeUnicodeCollationSupport (
  IN EFI_HANDLE    AgentHandle
  )
{

  EFI_STATUS       Status;

  Status = EFI_UNSUPPORTED;

  //
  // First try to use RFC 4646 Unicode Collation 2 Protocol.
  //
  Status = InitializeUnicodeCollationSupportWorker (
             AgentHandle,
             &gEfiUnicodeCollation2ProtocolGuid,
             L"PlatformLang",
             (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLang)
             );
  //
  // If the attempt to use Unicode Collation 2 Protocol fails, then we fall back
  // on the ISO 639-2 Unicode Collation Protocol.
  //
  if (EFI_ERROR (Status)) {
    Status = InitializeUnicodeCollationSupportWorker (
               AgentHandle,
               &gEfiUnicodeCollationProtocolGuid,
               L"Lang",
               (CONST CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultLang)
               );
  }

  return Status;
}

/**
  Test to see if this driver supports ControllerHandle.

  @param  DriverBinding       Protocol instance pointer.
  @param  ControllerHandle    Handle of device to test
  @param  RemainingDevicePath Optional parameter use to pick a specific child
                              device to start.

  @retval EFI_SUCCESS         This driver supports this device
  @retval EFI_ALREADY_STARTED This driver is already running on this device
  @retval other               This driver does not support this device

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemDriverSupported (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  return gBS->OpenProtocol (
                ControllerHandle,
                &gEfiFirmwareVolume2ProtocolGuid,
                NULL,
                gImageHandle,
                ControllerHandle,
                EFI_OPEN_PROTOCOL_TEST_PROTOCOL
                );
}

/**
  Start this driver on ControllerHandle by opening a FV protocol and
  installing a SimpleFileSystem protocol on ControllerHandle.

  @param  DriverBinding        Protocol instance pointer.
  @param  ControllerHandle     Handle of device to bind driver to
  @param  RemainingDevicePath  Optional parameter use to pick a specific child
                               device to start.

  @retval EFI_SUCCESS          This driver is added to ControllerHandle
  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle
  @retval other                This driver does not support this device

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemDriverStart (
  IN  EFI_DRIVER_BINDING_PROTOCOL  *DriverBinding,
  IN  EFI_HANDLE                   ControllerHandle,
  IN  EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
  )
{
  EFI_STATUS                       Status;
  EFI_FIRMWARE_VOLUME2_PROTOCOL    *FvProtocol;
  FV_FILESYSTEM_INSTANCE           *Instance;
  EFI_DEVICE_PATH_PROTOCOL         *FvDevicePath;
  EFI_GUID                         *FvGuid;
  UINTN                            NumChars;

  Status = InitializeUnicodeCollationSupport (DriverBinding->DriverBindingHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Open FV protocol
  //
  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiFirmwareVolume2ProtocolGuid,
                  (VOID **) &FvProtocol,
                  gImageHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_BY_DRIVER
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Create an instance
  //
  Instance = AllocateZeroPool (sizeof (FV_FILESYSTEM_INSTANCE));
  if (Instance == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Instance->Root = NULL;
  Instance->FvProtocol = FvProtocol;
  Instance->Signature = FVFS_INSTANCE_SIGNATURE;
  InitializeListHead (&Instance->FileInfoHead);
  InitializeListHead (&Instance->FileHead);
  CopyMem (&Instance->SimpleFs, &mSimpleFsTemplate, sizeof (mSimpleFsTemplate));

  Status = gBS->InstallProtocolInterface(
                  &ControllerHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  EFI_NATIVE_INTERFACE,
                  &Instance->SimpleFs
                  );

  //
  // Decide on a filesystem volume label, which will include the FV's guid.
  // Get the device path to find the FV's GUID
  //
  Instance->VolumeLabel = NULL;
  Status =  gBS->OpenProtocol (
                   ControllerHandle,
                   &gEfiDevicePathProtocolGuid,
                   (VOID **) &FvDevicePath,
                   gImageHandle,
                   ControllerHandle,
                   EFI_OPEN_PROTOCOL_BY_DRIVER
                   );
  if (!EFI_ERROR (Status)) {
    //
    // Iterate over device path until we find a firmware volume node
    //
    while (!IsDevicePathEndType (FvDevicePath)) {
      if (DevicePathType (FvDevicePath) == MEDIA_DEVICE_PATH &&
          DevicePathSubType (FvDevicePath) == MEDIA_PIWG_FW_VOL_DP) {
        //
        // Allocate the volume label
        //
        Instance->VolumeLabel = AllocateZeroPool (FVFS_VOLUME_LABEL_SIZE);
        //
        // Check the allocation was successful
        //
        if (Instance->VolumeLabel != NULL) {
          //
          // Extract the FV's guid
          //
          FvGuid = &((MEDIA_FW_VOL_DEVICE_PATH *) FvDevicePath)->FvName;
          //
          // Build the volume label string
          //
          NumChars = UnicodeSPrint (
                       Instance->VolumeLabel,
                       FVFS_VOLUME_LABEL_SIZE,
                       FVFS_VOLUME_LABEL_PREFIX L"%g",
                       FvGuid
                       );
          ASSERT ((NumChars + 1) * sizeof (CHAR16) == FVFS_VOLUME_LABEL_SIZE);
        }
        break;
      }
      FvDevicePath = NextDevicePathNode (FvDevicePath);
    }
  }
  //
  // If we didn't decide on a volume label, set a fallback one
  //
  if (Instance->VolumeLabel == NULL) {
    Instance->VolumeLabel = AllocateCopyPool (
                              sizeof (FVFS_FALLBACK_VOLUME_LABEL),
                              FVFS_FALLBACK_VOLUME_LABEL
                              );
  }

  return Status;
}

/**
  Stop this driver on ControllerHandle by removing SimpleFileSystem protocol and closing
  the FV protocol on ControllerHandle.

  @param  DriverBinding     Protocol instance pointer.
  @param  ControllerHandle  Handle of device to stop driver on
  @param  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of
                            children is zero stop the entire bus driver.
  @param  ChildHandleBuffer List of Child Handles to Stop.

  @retval EFI_SUCCESS       This driver is removed ControllerHandle
  @retval other             This driver was not removed from this device

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemDriverStop (
  IN  EFI_DRIVER_BINDING_PROTOCOL       *DriverBinding,
  IN  EFI_HANDLE                        ControllerHandle,
  IN  UINTN                             NumberOfChildren,
  IN  EFI_HANDLE                        *ChildHandleBuffer OPTIONAL
  )
{
  EFI_STATUS                       Status;
  FV_FILESYSTEM_INSTANCE           *Instance;
  FV_FILESYSTEM_FILE_INFO          *FvFileInfo;
  LIST_ENTRY                       *Entry;
  LIST_ENTRY                       *DelEntry;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *SimpleFile;

  Status = gBS->OpenProtocol (
                  ControllerHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  (VOID **) &SimpleFile,
                  DriverBinding->DriverBindingHandle,
                  ControllerHandle,
                  EFI_OPEN_PROTOCOL_GET_PROTOCOL
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Instance = FVFS_INSTANCE_FROM_SIMPLE_FS_THIS (SimpleFile);

  if (IsListEmpty (&Instance->FileHead) == FALSE) {
    //
    // Not all opened files are closed
    //
    return EFI_DEVICE_ERROR;
  }

  //
  // Close and uninstall protocols.
  //
  Status = gBS->CloseProtocol (
                   ControllerHandle,
                   &gEfiFirmwareVolume2ProtocolGuid,
                   gImageHandle,
                   ControllerHandle
                   );
  ASSERT_EFI_ERROR (Status);

  Status = gBS->UninstallProtocolInterface (
                  ControllerHandle,
                  &gEfiSimpleFileSystemProtocolGuid,
                  &Instance->SimpleFs
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Free file structures
  //
  if (!IsListEmpty (&Instance->FileInfoHead)) {
    //
    // Free the Subtask list.
    //
    for(Entry = Instance->FileInfoHead.ForwardLink;
        Entry != (&Instance->FileInfoHead);
       ) {
      DelEntry   = Entry;
      Entry      = Entry->ForwardLink;
      FvFileInfo = FVFS_FILE_INFO_FROM_LINK (DelEntry);

      RemoveEntryList (DelEntry);
      FreePool (FvFileInfo);
    }
  }

  if (Instance->Root != NULL) {
    //
    // Root->Name is statically allocated, no need to free.
    //
    if (Instance->Root->FvFileInfo != NULL) {
      FreePool (Instance->Root->FvFileInfo);
    }
    FreePool (Instance->Root);
  }

  //
  // Free Instance
  //
  if (Instance->VolumeLabel != NULL) {
    FreePool (Instance->VolumeLabel);
  }
  FreePool (Instance);

  return EFI_SUCCESS;
}

/**
  The user Entry Point for module FvSimpleFileSystem. The user code starts with this function.

  @param[in] ImageHandle    The firmware allocated handle for the EFI image.
  @param[in] SystemTable    A pointer to the EFI System Table.

  @retval EFI_SUCCESS       The entry point is executed successfully.
  @retval other             Some error occurs when executing this entry point.

**/
EFI_STATUS
EFIAPI
FvSimpleFileSystemEntryPoint (
  IN EFI_HANDLE               ImageHandle,
  IN EFI_SYSTEM_TABLE         *SystemTable
  )
{
  EFI_STATUS Status;

  //
  // Install driver model protocol(s).
  //
  Status = EfiLibInstallDriverBindingComponentName2 (
             ImageHandle,
             SystemTable,
             &mDriverBinding,
             ImageHandle,
             &gFvSimpleFileSystemComponentName,
             &gFvSimpleFileSystemComponentName2
             );
  ASSERT_EFI_ERROR (Status);

  return Status;
}
