/** @file
  The implementation supports Capusle on Disk.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "CapsuleOnDisk.h"

/**
  Return if this capsule is a capsule name capsule, based upon CapsuleHeader.

  @param[in] CapsuleHeader A pointer to EFI_CAPSULE_HEADER

  @retval TRUE  It is a capsule name capsule.
  @retval FALSE It is not a capsule name capsule.
**/
BOOLEAN
IsCapsuleNameCapsule (
  IN EFI_CAPSULE_HEADER  *CapsuleHeader
  );

/**
  Check the integrity of the capsule name capsule.
  If the capsule is vaild, return the physical address of each capsule name string.

  This routine assumes the capsule has been validated by IsValidCapsuleHeader(), so
  capsule memory overflow is not going to happen in this routine.

  @param[in]  CapsuleHeader   Pointer to the capsule header of a capsule name capsule.
  @param[out] CapsuleNameNum  Number of capsule name.

  @retval NULL                Capsule name capsule is not valid.
  @retval CapsuleNameBuf      Array of capsule name physical address.

**/
EFI_PHYSICAL_ADDRESS *
ValidateCapsuleNameCapsuleIntegrity (
  IN  EFI_CAPSULE_HEADER  *CapsuleHeader,
  OUT UINTN               *CapsuleNameNum
  )
{
  UINT8                 *CapsuleNamePtr;
  UINT8                 *CapsuleNameBufStart;
  UINT8                 *CapsuleNameBufEnd;
  UINTN                 Index;
  UINTN                 StringSize;
  EFI_PHYSICAL_ADDRESS  *CapsuleNameBuf;

  if (!IsCapsuleNameCapsule (CapsuleHeader)) {
    return NULL;
  }

  //
  // Total string size must be even.
  //
  if (((CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize) & BIT0) != 0) {
    return NULL;
  }

  *CapsuleNameNum     = 0;
  Index               = 0;
  CapsuleNameBufStart = (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize;

  //
  // If strings are not aligned on a 16-bit boundary, reallocate memory for it.
  //
  if (((UINTN)CapsuleNameBufStart & BIT0) != 0) {
    CapsuleNameBufStart = AllocateCopyPool (CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize, CapsuleNameBufStart);
    if (CapsuleNameBufStart == NULL) {
      return NULL;
    }
  }

  CapsuleNameBufEnd = CapsuleNameBufStart + CapsuleHeader->CapsuleImageSize - CapsuleHeader->HeaderSize;

  CapsuleNamePtr = CapsuleNameBufStart;
  while (CapsuleNamePtr < CapsuleNameBufEnd) {
    StringSize      = StrnSizeS ((CHAR16 *)CapsuleNamePtr, (CapsuleNameBufEnd - CapsuleNamePtr)/sizeof (CHAR16));
    CapsuleNamePtr += StringSize;
    (*CapsuleNameNum)++;
  }

  //
  // Integrity check.
  //
  if (CapsuleNamePtr != CapsuleNameBufEnd) {
    if (CapsuleNameBufStart != (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize) {
      FreePool (CapsuleNameBufStart);
    }

    return NULL;
  }

  CapsuleNameBuf = AllocatePool (*CapsuleNameNum * sizeof (EFI_PHYSICAL_ADDRESS));
  if (CapsuleNameBuf == NULL) {
    if (CapsuleNameBufStart != (UINT8 *)CapsuleHeader + CapsuleHeader->HeaderSize) {
      FreePool (CapsuleNameBufStart);
    }

    return NULL;
  }

  CapsuleNamePtr = CapsuleNameBufStart;
  while (CapsuleNamePtr < CapsuleNameBufEnd) {
    StringSize            = StrnSizeS ((CHAR16 *)CapsuleNamePtr, (CapsuleNameBufEnd - CapsuleNamePtr)/sizeof (CHAR16));
    CapsuleNameBuf[Index] = (EFI_PHYSICAL_ADDRESS)(UINTN)CapsuleNamePtr;
    CapsuleNamePtr       += StringSize;
    Index++;
  }

  return CapsuleNameBuf;
}

/**
  This routine is called to upper case given unicode string.

  @param[in]   Str              String to upper case

  @retval upper cased string after process

**/
static
CHAR16 *
UpperCaseString (
  IN CHAR16  *Str
  )
{
  CHAR16  *Cptr;

  for (Cptr = Str; *Cptr != L'\0'; Cptr++) {
    if ((L'a' <= *Cptr) && (*Cptr <= L'z')) {
      *Cptr = *Cptr - L'a' + L'A';
    }
  }

  return Str;
}

/**
  This routine is used to return substring before period '.' or '\0'
  Caller should respsonsible of substr space allocation & free

  @param[in]   Str              String to check
  @param[out]  SubStr           First part of string before period or '\0'
  @param[out]  SubStrLen        Length of first part of string

**/
static
VOID
GetSubStringBeforePeriod (
  IN  CHAR16  *Str,
  OUT CHAR16  *SubStr,
  OUT UINTN   *SubStrLen
  )
{
  UINTN  Index;

  for (Index = 0; Str[Index] != L'.' && Str[Index] != L'\0'; Index++) {
    SubStr[Index] = Str[Index];
  }

  SubStr[Index] = L'\0';
  *SubStrLen    = Index;
}

/**
  This routine pad the string in tail with input character.

  @param[in]   StrBuf            Str buffer to be padded, should be enough room for
  @param[in]   PadLen            Expected padding length
  @param[in]   Character         Character used to pad

**/
static
VOID
PadStrInTail (
  IN CHAR16  *StrBuf,
  IN UINTN   PadLen,
  IN CHAR16  Character
  )
{
  UINTN  Index;

  for (Index = 0; StrBuf[Index] != L'\0'; Index++) {
  }

  while (PadLen != 0) {
    StrBuf[Index] = Character;
    Index++;
    PadLen--;
  }

  StrBuf[Index] = L'\0';
}

/**
  This routine find the offset of the last period '.' of string. If No period exists
  function FileNameExtension is set to L'\0'

  @param[in]  FileName           File name to split between last period
  @param[out] FileNameFirst      First FileName before last period
  @param[out] FileNameExtension  FileName after last period

**/
static
VOID
SplitFileNameExtension (
  IN CHAR16   *FileName,
  OUT CHAR16  *FileNameFirst,
  OUT CHAR16  *FileNameExtension
  )
{
  UINTN  Index;
  UINTN  StringLen;

  StringLen = StrnLenS (FileName, MAX_FILE_NAME_SIZE);
  for (Index = StringLen; Index > 0 && FileName[Index] != L'.'; Index--) {
  }

  //
  // No period exists. No FileName Extension
  //
  if ((Index == 0) && (FileName[Index] != L'.')) {
    FileNameExtension[0] = L'\0';
    Index                = StringLen;
  } else {
    StrCpyS (FileNameExtension, MAX_FILE_NAME_SIZE, &FileName[Index+1]);
  }

  //
  // Copy First file name
  //
  StrnCpyS (FileNameFirst, MAX_FILE_NAME_SIZE, FileName, Index);
  FileNameFirst[Index] = L'\0';
}

/**
  This routine is called to get all boot options in the order determnined by:
    1. "OptionBuf"
    2. "BootOrder"

  @param[out] OptionBuf           BootList buffer to all boot options returned
  @param[out] OptionCount         BootList count of all boot options returned

  @retval EFI_SUCCESS             There is no error when processing capsule

**/
EFI_STATUS
GetBootOptionInOrder (
  OUT EFI_BOOT_MANAGER_LOAD_OPTION  **OptionBuf,
  OUT UINTN                         *OptionCount
  )
{
  EFI_STATUS                    Status;
  UINTN                         DataSize;
  UINT16                        BootNext;
  CHAR16                        BootOptionName[20];
  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOrderOptionBuf;
  UINTN                         BootOrderCount;
  EFI_BOOT_MANAGER_LOAD_OPTION  BootNextOptionEntry;
  UINTN                         BootNextCount;
  EFI_BOOT_MANAGER_LOAD_OPTION  *TempBuf;

  BootOrderOptionBuf = NULL;
  TempBuf            = NULL;
  BootNextCount      = 0;
  BootOrderCount     = 0;
  *OptionBuf         = NULL;
  *OptionCount       = 0;

  //
  // First Get BootOption from "BootNext"
  //
  DataSize = sizeof (BootNext);
  Status   = gRT->GetVariable (
                    EFI_BOOT_NEXT_VARIABLE_NAME,
                    &gEfiGlobalVariableGuid,
                    NULL,
                    &DataSize,
                    (VOID *)&BootNext
                    );
  //
  // BootNext variable is a single UINT16
  //
  if (!EFI_ERROR (Status) && (DataSize == sizeof (UINT16))) {
    //
    // Add the boot next boot option
    //
    UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", BootNext);
    ZeroMem (&BootNextOptionEntry, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
    Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootNextOptionEntry);

    if (!EFI_ERROR (Status)) {
      BootNextCount = 1;
    }
  }

  //
  // Second get BootOption from "BootOrder"
  //
  BootOrderOptionBuf = EfiBootManagerGetLoadOptions (&BootOrderCount, LoadOptionTypeBoot);
  if ((BootNextCount == 0) && (BootOrderCount == 0)) {
    return EFI_NOT_FOUND;
  }

  //
  // At least one BootOption is found
  //
  TempBuf = AllocatePool (sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * (BootNextCount + BootOrderCount));
  if (TempBuf != NULL) {
    if (BootNextCount == 1) {
      CopyMem (TempBuf, &BootNextOptionEntry, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
    }

    if (BootOrderCount > 0) {
      CopyMem (TempBuf + BootNextCount, BootOrderOptionBuf, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION) * BootOrderCount);
    }

    *OptionBuf   = TempBuf;
    *OptionCount = BootNextCount + BootOrderCount;
    Status       = EFI_SUCCESS;
  } else {
    Status = EFI_OUT_OF_RESOURCES;
  }

  FreePool (BootOrderOptionBuf);

  return Status;
}

/**
  This routine is called to get boot option by OptionNumber.

  @param[in] Number               The OptionNumber of boot option
  @param[out] OptionBuf           BootList buffer to all boot options returned

  @retval EFI_SUCCESS             There is no error when getting boot option

**/
EFI_STATUS
GetBootOptionByNumber (
  IN  UINT16                        Number,
  OUT EFI_BOOT_MANAGER_LOAD_OPTION  **OptionBuf
  )
{
  EFI_STATUS                    Status;
  CHAR16                        BootOptionName[20];
  EFI_BOOT_MANAGER_LOAD_OPTION  BootOption;

  UnicodeSPrint (BootOptionName, sizeof (BootOptionName), L"Boot%04x", Number);
  ZeroMem (&BootOption, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
  Status = EfiBootManagerVariableToLoadOption (BootOptionName, &BootOption);

  if (!EFI_ERROR (Status)) {
    *OptionBuf = AllocatePool (sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
    if (*OptionBuf != NULL) {
      CopyMem (*OptionBuf, &BootOption, sizeof (EFI_BOOT_MANAGER_LOAD_OPTION));
      Status = EFI_SUCCESS;
    } else {
      Status = EFI_OUT_OF_RESOURCES;
    }
  }

  return Status;
}

/**
  Get Active EFI System Partition within GPT based on device path.

  @param[in] DevicePath    Device path to find a active EFI System Partition
  @param[out] FsHandle     BootList points to all boot options returned

  @retval EFI_SUCCESS      Active EFI System Partition is succesfully found
  @retval EFI_NOT_FOUND    No Active EFI System Partition is found

**/
EFI_STATUS
GetEfiSysPartitionFromDevPath (
  IN EFI_DEVICE_PATH_PROTOCOL  *DevicePath,
  OUT EFI_HANDLE               *FsHandle
  )
{
  EFI_STATUS                       Status;
  EFI_DEVICE_PATH_PROTOCOL         *TempDevicePath;
  HARDDRIVE_DEVICE_PATH            *Hd;
  EFI_HANDLE                       Handle;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;

  //
  // Check if the device path contains GPT node
  //
  TempDevicePath = DevicePath;
  while (!IsDevicePathEnd (TempDevicePath)) {
    if ((DevicePathType (TempDevicePath) == MEDIA_DEVICE_PATH) &&
        (DevicePathSubType (TempDevicePath) == MEDIA_HARDDRIVE_DP))
    {
      Hd = (HARDDRIVE_DEVICE_PATH *)TempDevicePath;
      if (Hd->MBRType == MBR_TYPE_EFI_PARTITION_TABLE_HEADER) {
        break;
      }
    }

    TempDevicePath = NextDevicePathNode (TempDevicePath);
  }

  if (!IsDevicePathEnd (TempDevicePath)) {
    //
    // Search for EFI system partition protocol on full device path in Boot Option
    //
    Status = gBS->LocateDevicePath (&gEfiPartTypeSystemPartGuid, &DevicePath, &Handle);

    //
    // Search for simple file system on this handler
    //
    if (!EFI_ERROR (Status)) {
      Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
      if (!EFI_ERROR (Status)) {
        *FsHandle = Handle;
        return EFI_SUCCESS;
      }
    }
  }

  return EFI_NOT_FOUND;
}

/**
  This routine is called to get Simple File System protocol on the first EFI system partition found in
  active boot option. The boot option list is detemined in order by
    1. "BootNext"
    2. "BootOrder"

  @param[in]       MaxRetry           Max Connection Retry. Stall 100ms between each connection try to ensure
                                      device like USB can get enumerated.
  @param[in, out]  LoadOptionNumber   On input, specify the boot option to get EFI system partition.
                                      On output, return the OptionNumber of the boot option where EFI
                                      system partition is got from.
  @param[out]      FsFsHandle         Simple File System Protocol found on first active EFI system partition

  @retval EFI_SUCCESS     Simple File System protocol found for EFI system partition
  @retval EFI_NOT_FOUND   No Simple File System protocol found for EFI system partition

**/
EFI_STATUS
GetEfiSysPartitionFromActiveBootOption (
  IN UINTN        MaxRetry,
  IN OUT UINT16   **LoadOptionNumber,
  OUT EFI_HANDLE  *FsHandle
  )
{
  EFI_STATUS                    Status;
  EFI_BOOT_MANAGER_LOAD_OPTION  *BootOptionBuf;
  UINTN                         BootOptionNum;
  UINTN                         Index;
  EFI_DEVICE_PATH_PROTOCOL      *DevicePath;
  EFI_DEVICE_PATH_PROTOCOL      *CurFullPath;
  EFI_DEVICE_PATH_PROTOCOL      *PreFullPath;

  *FsHandle   = NULL;
  CurFullPath = NULL;

  if (*LoadOptionNumber != NULL) {
    BootOptionNum = 1;
    Status        = GetBootOptionByNumber (**LoadOptionNumber, &BootOptionBuf);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "GetBootOptionByIndex Failed %x! No BootOption available for connection\n", Status));
      return Status;
    }
  } else {
    Status = GetBootOptionInOrder (&BootOptionBuf, &BootOptionNum);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "GetBootOptionInOrder Failed %x! No BootOption available for connection\n", Status));
      return Status;
    }
  }

  //
  // Search BootOptionList to check if it is an active boot option with EFI system partition
  //  1. Connect device path
  //  2. expend short/plug in devicepath
  //  3. LoadImage
  //
  for (Index = 0; Index < BootOptionNum; Index++) {
    //
    // Get the boot option from the link list
    //
    DevicePath = BootOptionBuf[Index].FilePath;

    //
    // Skip inactive or legacy boot options
    //
    if (((BootOptionBuf[Index].Attributes & LOAD_OPTION_ACTIVE) == 0) ||
        (DevicePathType (DevicePath) == BBS_DEVICE_PATH))
    {
      continue;
    }

    DEBUG_CODE_BEGIN ();
    CHAR16  *DevicePathStr;

    DevicePathStr = ConvertDevicePathToText (DevicePath, TRUE, TRUE);
    if (DevicePathStr != NULL) {
      DEBUG ((DEBUG_INFO, "Try BootOption %s\n", DevicePathStr));
      FreePool (DevicePathStr);
    } else {
      DEBUG ((DEBUG_INFO, "DevicePathToStr failed\n"));
    }

    DEBUG_CODE_END ();

    CurFullPath = NULL;
    //
    // Try every full device Path generated from bootoption
    //
    do {
      PreFullPath = CurFullPath;
      CurFullPath = EfiBootManagerGetNextLoadOptionDevicePath (DevicePath, CurFullPath);

      if (PreFullPath != NULL) {
        FreePool (PreFullPath);
      }

      if (CurFullPath == NULL) {
        //
        // No Active EFI system partition is found in BootOption device path
        //
        Status = EFI_NOT_FOUND;
        break;
      }

      DEBUG_CODE_BEGIN ();
      CHAR16  *DevicePathStr1;

      DevicePathStr1 = ConvertDevicePathToText (CurFullPath, TRUE, TRUE);
      if (DevicePathStr1 != NULL) {
        DEBUG ((DEBUG_INFO, "Full device path %s\n", DevicePathStr1));
        FreePool (DevicePathStr1);
      }

      DEBUG_CODE_END ();

      //
      // Make sure the boot option device path connected.
      // Only handle first device in boot option. Other optional device paths are described as OSV specific
      // FullDevice could contain extra directory & file info. So don't check connection status here.
      //
      EfiBootManagerConnectDevicePath (CurFullPath, NULL);
      Status = GetEfiSysPartitionFromDevPath (CurFullPath, FsHandle);

      //
      // Some relocation device like USB need more time to get enumerated
      //
      while (EFI_ERROR (Status) && MaxRetry > 0) {
        EfiBootManagerConnectDevicePath (CurFullPath, NULL);

        //
        // Search for EFI system partition protocol on full device path in Boot Option
        //
        Status = GetEfiSysPartitionFromDevPath (CurFullPath, FsHandle);
        if (!EFI_ERROR (Status)) {
          break;
        }

        DEBUG ((DEBUG_ERROR, "GetEfiSysPartitionFromDevPath Loop %x\n", Status));
        //
        // Stall 100ms if connection failed to ensure USB stack is ready
        //
        gBS->Stall (100000);
        MaxRetry--;
      }
    } while (EFI_ERROR (Status));

    //
    // Find a qualified Simple File System
    //
    if (!EFI_ERROR (Status)) {
      break;
    }
  }

  //
  // Return the OptionNumber of the boot option where EFI system partition is got from
  //
  if (*LoadOptionNumber == NULL) {
    *LoadOptionNumber = AllocateCopyPool (sizeof (UINT16), (UINT16 *)&BootOptionBuf[Index].OptionNumber);
    if (*LoadOptionNumber == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
    }
  }

  //
  // No qualified EFI system partition found
  //
  if (*FsHandle == NULL) {
    Status = EFI_NOT_FOUND;
  }

  DEBUG_CODE_BEGIN ();
  CHAR16  *DevicePathStr2;

  if (*FsHandle != NULL) {
    DevicePathStr2 = ConvertDevicePathToText (CurFullPath, TRUE, TRUE);
    if (DevicePathStr2 != NULL) {
      DEBUG ((DEBUG_INFO, "Found Active EFI System Partion on %s\n", DevicePathStr2));
      FreePool (DevicePathStr2);
    }
  } else {
    DEBUG ((DEBUG_INFO, "Failed to found Active EFI System Partion\n"));
  }

  DEBUG_CODE_END ();

  if (CurFullPath != NULL) {
    FreePool (CurFullPath);
  }

  //
  // Free BootOption Buffer
  //
  for (Index = 0; Index < BootOptionNum; Index++) {
    if (BootOptionBuf[Index].Description != NULL) {
      FreePool (BootOptionBuf[Index].Description);
    }

    if (BootOptionBuf[Index].FilePath != NULL) {
      FreePool (BootOptionBuf[Index].FilePath);
    }

    if (BootOptionBuf[Index].OptionalData != NULL) {
      FreePool (BootOptionBuf[Index].OptionalData);
    }
  }

  FreePool (BootOptionBuf);

  return Status;
}

/**
  This routine is called to get all file infos with in a given dir & with given file attribute, the file info is listed in
  alphabetical order described in UEFI spec.

  @param[in]  Dir                 Directory file handler
  @param[in]  FileAttr            Attribute of file to be red from directory
  @param[out] FileInfoList        File images info list red from directory
  @param[out] FileNum             File images number red from directory

  @retval EFI_SUCCESS             File FileInfo list in the given

**/
EFI_STATUS
GetFileInfoListInAlphabetFromDir (
  IN EFI_FILE_HANDLE  Dir,
  IN UINT64           FileAttr,
  OUT LIST_ENTRY      *FileInfoList,
  OUT UINTN           *FileNum
  )
{
  EFI_STATUS       Status;
  FILE_INFO_ENTRY  *NewFileInfoEntry;
  FILE_INFO_ENTRY  *TempFileInfoEntry;
  EFI_FILE_INFO    *FileInfo;
  CHAR16           *NewFileName;
  CHAR16           *ListedFileName;
  CHAR16           *NewFileNameExtension;
  CHAR16           *ListedFileNameExtension;
  CHAR16           *TempNewSubStr;
  CHAR16           *TempListedSubStr;
  LIST_ENTRY       *Link;
  BOOLEAN          NoFile;
  UINTN            FileCount;
  UINTN            IndexNew;
  UINTN            IndexListed;
  UINTN            NewSubStrLen;
  UINTN            ListedSubStrLen;
  INTN             SubStrCmpResult;

  Status                  = EFI_SUCCESS;
  NewFileName             = NULL;
  ListedFileName          = NULL;
  NewFileNameExtension    = NULL;
  ListedFileNameExtension = NULL;
  TempNewSubStr           = NULL;
  TempListedSubStr        = NULL;
  FileInfo                = NULL;
  NoFile                  = FALSE;
  FileCount               = 0;

  InitializeListHead (FileInfoList);

  TempNewSubStr    = (CHAR16 *)AllocateZeroPool (MAX_FILE_NAME_SIZE);
  TempListedSubStr = (CHAR16 *)AllocateZeroPool (MAX_FILE_NAME_SIZE);

  if ((TempNewSubStr == NULL) || (TempListedSubStr == NULL)) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  for ( Status = FileHandleFindFirstFile (Dir, &FileInfo)
        ; !EFI_ERROR (Status) && !NoFile
        ; Status = FileHandleFindNextFile (Dir, FileInfo, &NoFile)
        )
  {
    if (FileInfo == NULL) {
      goto EXIT;
    }

    //
    // Skip file with mismatching File attribute
    //
    if ((FileInfo->Attribute & (FileAttr)) == 0) {
      continue;
    }

    NewFileInfoEntry = NULL;
    NewFileInfoEntry = (FILE_INFO_ENTRY *)AllocateZeroPool (sizeof (FILE_INFO_ENTRY));
    if (NewFileInfoEntry == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    NewFileInfoEntry->Signature = FILE_INFO_SIGNATURE;
    NewFileInfoEntry->FileInfo  = AllocateCopyPool ((UINTN)FileInfo->Size, FileInfo);
    if (NewFileInfoEntry->FileInfo == NULL) {
      FreePool (NewFileInfoEntry);
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    NewFileInfoEntry->FileNameFirstPart = (CHAR16 *)AllocateZeroPool (MAX_FILE_NAME_SIZE);
    if (NewFileInfoEntry->FileNameFirstPart == NULL) {
      FreePool (NewFileInfoEntry->FileInfo);
      FreePool (NewFileInfoEntry);
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    NewFileInfoEntry->FileNameSecondPart = (CHAR16 *)AllocateZeroPool (MAX_FILE_NAME_SIZE);
    if (NewFileInfoEntry->FileNameSecondPart == NULL) {
      FreePool (NewFileInfoEntry->FileInfo);
      FreePool (NewFileInfoEntry->FileNameFirstPart);
      FreePool (NewFileInfoEntry);
      Status = EFI_OUT_OF_RESOURCES;
      goto EXIT;
    }

    //
    // Splitter the whole New file name into 2 parts between the last period L'.' into NewFileName NewFileExtension
    // If no period in the whole file name. NewFileExtension is set to L'\0'
    //
    NewFileName          = NewFileInfoEntry->FileNameFirstPart;
    NewFileNameExtension = NewFileInfoEntry->FileNameSecondPart;
    SplitFileNameExtension (FileInfo->FileName, NewFileName, NewFileNameExtension);
    UpperCaseString (NewFileName);
    UpperCaseString (NewFileNameExtension);

    //
    // Insert capsule file in alphabetical ordered list
    //
    for (Link = FileInfoList->ForwardLink; Link != FileInfoList; Link = Link->ForwardLink) {
      //
      // Get the FileInfo from the link list
      //
      TempFileInfoEntry       = CR (Link, FILE_INFO_ENTRY, Link, FILE_INFO_SIGNATURE);
      ListedFileName          = TempFileInfoEntry->FileNameFirstPart;
      ListedFileNameExtension = TempFileInfoEntry->FileNameSecondPart;

      //
      // Follow rule in UEFI spec 8.5.5 to compare file name
      //
      IndexListed = 0;
      IndexNew    = 0;
      while (TRUE) {
        //
        // First compare each substrings in NewFileName & ListedFileName between periods
        //
        GetSubStringBeforePeriod (&NewFileName[IndexNew], TempNewSubStr, &NewSubStrLen);
        GetSubStringBeforePeriod (&ListedFileName[IndexListed], TempListedSubStr, &ListedSubStrLen);
        if (NewSubStrLen > ListedSubStrLen) {
          //
          // Substr in NewFileName is longer. Pad tail with SPACE
          //
          PadStrInTail (TempListedSubStr, NewSubStrLen - ListedSubStrLen, L' ');
        } else if (NewSubStrLen < ListedSubStrLen) {
          //
          // Substr in ListedFileName is longer. Pad tail with SPACE
          //
          PadStrInTail (TempNewSubStr, ListedSubStrLen - NewSubStrLen, L' ');
        }

        SubStrCmpResult = StrnCmp (TempNewSubStr, TempListedSubStr, MAX_FILE_NAME_LEN);
        if (SubStrCmpResult != 0) {
          break;
        }

        //
        // Move to skip this substring
        //
        IndexNew    += NewSubStrLen;
        IndexListed += ListedSubStrLen;
        //
        // Reach File First Name end
        //
        if ((NewFileName[IndexNew] == L'\0') || (ListedFileName[IndexListed] == L'\0')) {
          break;
        }

        //
        // Skip the period L'.'
        //
        IndexNew++;
        IndexListed++;
      }

      if (SubStrCmpResult < 0) {
        //
        // NewFileName is smaller. Find the right place to insert New file
        //
        break;
      } else if (SubStrCmpResult == 0) {
        //
        // 2 cases whole NewFileName is smaller than ListedFileName
        //   1. if NewFileName == ListedFileName. Continue to compare FileNameExtension
        //   2. if NewFileName is shorter than ListedFileName
        //
        if (NewFileName[IndexNew] == L'\0') {
          if ((ListedFileName[IndexListed] != L'\0') || (StrnCmp (NewFileNameExtension, ListedFileNameExtension, MAX_FILE_NAME_LEN) < 0)) {
            break;
          }
        }
      }

      //
      // Other case, ListedFileName is smaller. Continue to compare the next file in the list
      //
    }

    //
    // If Find an entry in the list whose name is bigger than new FileInfo in alphabet order
    //    Insert it before this entry
    // else
    //    Insert at the tail of this list (Link = FileInfoList)
    //
    InsertTailList (Link, &NewFileInfoEntry->Link);

    FileCount++;
  }

  *FileNum = FileCount;

EXIT:

  if (TempNewSubStr != NULL) {
    FreePool (TempNewSubStr);
  }

  if (TempListedSubStr != NULL) {
    FreePool (TempListedSubStr);
  }

  if (EFI_ERROR (Status)) {
    while (!IsListEmpty (FileInfoList)) {
      Link = FileInfoList->ForwardLink;
      RemoveEntryList (Link);

      TempFileInfoEntry = CR (Link, FILE_INFO_ENTRY, Link, FILE_INFO_SIGNATURE);

      FreePool (TempFileInfoEntry->FileInfo);
      FreePool (TempFileInfoEntry->FileNameFirstPart);
      FreePool (TempFileInfoEntry->FileNameSecondPart);
      FreePool (TempFileInfoEntry);
    }

    *FileNum = 0;
  }

  return Status;
}

/**
  This routine is called to get all qualified image from file from an given directory
  in alphabetic order. All the file image is copied to allocated boottime memory.
  Caller should free these memory

  @param[in]  Dir            Directory file handler
  @param[in]  FileAttr       Attribute of file to be red from directory
  @param[out] FilePtr        File images Info buffer red from directory
  @param[out] FileNum        File images number red from directory

  @retval EFI_SUCCESS  Succeed to get all capsules in alphabetic order.

**/
EFI_STATUS
GetFileImageInAlphabetFromDir (
  IN EFI_FILE_HANDLE  Dir,
  IN UINT64           FileAttr,
  OUT IMAGE_INFO      **FilePtr,
  OUT UINTN           *FileNum
  )
{
  EFI_STATUS       Status;
  LIST_ENTRY       *Link;
  EFI_FILE_HANDLE  FileHandle;
  FILE_INFO_ENTRY  *FileInfoEntry;
  EFI_FILE_INFO    *FileInfo;
  UINTN            FileCount;
  IMAGE_INFO       *TempFilePtrBuf;
  UINTN            Size;
  LIST_ENTRY       FileInfoList;

  FileHandle     = NULL;
  FileCount      = 0;
  TempFilePtrBuf = NULL;
  *FilePtr       = NULL;

  //
  // Get file list in Dir in alphabetical order
  //
  Status = GetFileInfoListInAlphabetFromDir (
             Dir,
             FileAttr,
             &FileInfoList,
             &FileCount
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "GetFileInfoListInAlphabetFromDir Failed!\n"));
    goto EXIT;
  }

  if (FileCount == 0) {
    DEBUG ((DEBUG_ERROR, "No file found in Dir!\n"));
    Status = EFI_NOT_FOUND;
    goto EXIT;
  }

  TempFilePtrBuf = (IMAGE_INFO *)AllocateZeroPool (sizeof (IMAGE_INFO) * FileCount);
  if (TempFilePtrBuf == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  //
  // Read all files from FileInfoList to BS memory
  //
  FileCount = 0;
  for (Link = FileInfoList.ForwardLink; Link != &FileInfoList; Link = Link->ForwardLink) {
    //
    // Get FileInfo from the link list
    //
    FileInfoEntry = CR (Link, FILE_INFO_ENTRY, Link, FILE_INFO_SIGNATURE);
    FileInfo      = FileInfoEntry->FileInfo;

    Status = Dir->Open (
                    Dir,
                    &FileHandle,
                    FileInfo->FileName,
                    EFI_FILE_MODE_READ,
                    0
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    Size                                   = (UINTN)FileInfo->FileSize;
    TempFilePtrBuf[FileCount].ImageAddress = AllocateZeroPool (Size);
    if (TempFilePtrBuf[FileCount].ImageAddress == NULL) {
      DEBUG ((DEBUG_ERROR, "Fail to allocate memory for capsule. Stop processing the rest.\n"));
      break;
    }

    Status = FileHandle->Read (
                           FileHandle,
                           &Size,
                           TempFilePtrBuf[FileCount].ImageAddress
                           );

    FileHandle->Close (FileHandle);

    //
    // Skip read error file
    //
    if (EFI_ERROR (Status) || (Size != (UINTN)FileInfo->FileSize)) {
      //
      // Remove this error file info accordingly
      // & move Link to BackLink
      //
      Link = RemoveEntryList (Link);
      Link = Link->BackLink;

      FreePool (FileInfoEntry->FileInfo);
      FreePool (FileInfoEntry->FileNameFirstPart);
      FreePool (FileInfoEntry->FileNameSecondPart);
      FreePool (FileInfoEntry);

      FreePool (TempFilePtrBuf[FileCount].ImageAddress);
      TempFilePtrBuf[FileCount].ImageAddress = NULL;
      TempFilePtrBuf[FileCount].FileInfo     = NULL;

      continue;
    }

    TempFilePtrBuf[FileCount].FileInfo = FileInfo;
    FileCount++;
  }

  DEBUG_CODE_BEGIN ();
  for (Link = FileInfoList.ForwardLink; Link != &FileInfoList; Link = Link->ForwardLink) {
    FileInfoEntry = CR (Link, FILE_INFO_ENTRY, Link, FILE_INFO_SIGNATURE);
    FileInfo      = FileInfoEntry->FileInfo;
    DEBUG ((DEBUG_INFO, "Successfully read capsule file %s from disk.\n", FileInfo->FileName));
  }

  DEBUG_CODE_END ();

EXIT:

  *FilePtr = TempFilePtrBuf;
  *FileNum = FileCount;

  //
  // FileInfo will be freed by Calller
  //
  while (!IsListEmpty (&FileInfoList)) {
    Link = FileInfoList.ForwardLink;
    RemoveEntryList (Link);

    FileInfoEntry = CR (Link, FILE_INFO_ENTRY, Link, FILE_INFO_SIGNATURE);

    FreePool (FileInfoEntry->FileNameFirstPart);
    FreePool (FileInfoEntry->FileNameSecondPart);
    FreePool (FileInfoEntry);
  }

  return Status;
}

/**
  This routine is called to remove all qualified image from file from an given directory.

  @param[in] Dir                  Directory file handler
  @param[in] FileAttr             Attribute of files to be deleted

  @retval EFI_SUCCESS  Succeed to remove all files from an given directory.

**/
EFI_STATUS
RemoveFileFromDir (
  IN EFI_FILE_HANDLE  Dir,
  IN UINT64           FileAttr
  )
{
  EFI_STATUS       Status;
  LIST_ENTRY       *Link;
  LIST_ENTRY       FileInfoList;
  EFI_FILE_HANDLE  FileHandle;
  FILE_INFO_ENTRY  *FileInfoEntry;
  EFI_FILE_INFO    *FileInfo;
  UINTN            FileCount;

  FileHandle = NULL;

  //
  // Get file list in Dir in alphabetical order
  //
  Status = GetFileInfoListInAlphabetFromDir (
             Dir,
             FileAttr,
             &FileInfoList,
             &FileCount
             );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "GetFileInfoListInAlphabetFromDir Failed!\n"));
    goto EXIT;
  }

  if (FileCount == 0) {
    DEBUG ((DEBUG_ERROR, "No file found in Dir!\n"));
    Status = EFI_NOT_FOUND;
    goto EXIT;
  }

  //
  // Delete all files with given attribute in Dir
  //
  for (Link = FileInfoList.ForwardLink; Link != &(FileInfoList); Link = Link->ForwardLink) {
    //
    // Get FileInfo from the link list
    //
    FileInfoEntry = CR (Link, FILE_INFO_ENTRY, Link, FILE_INFO_SIGNATURE);
    FileInfo      = FileInfoEntry->FileInfo;

    Status = Dir->Open (
                    Dir,
                    &FileHandle,
                    FileInfo->FileName,
                    EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
                    0
                    );
    if (EFI_ERROR (Status)) {
      continue;
    }

    Status = FileHandle->Delete (FileHandle);
  }

EXIT:

  while (!IsListEmpty (&FileInfoList)) {
    Link = FileInfoList.ForwardLink;
    RemoveEntryList (Link);

    FileInfoEntry = CR (Link, FILE_INFO_ENTRY, Link, FILE_INFO_SIGNATURE);

    FreePool (FileInfoEntry->FileInfo);
    FreePool (FileInfoEntry);
  }

  return Status;
}

/**
  This routine is called to get all caspules from file. The capsule file image is
  copied to BS memory. Caller is responsible to free them.

  @param[in]    MaxRetry             Max Connection Retry. Stall 100ms between each connection try to ensure
                                     devices like USB can get enumerated.
  @param[out]   CapsulePtr           Copied Capsule file Image Info buffer
  @param[out]   CapsuleNum           CapsuleNumber
  @param[out]   FsHandle             File system handle
  @param[out]   LoadOptionNumber     OptionNumber of boot option

  @retval EFI_SUCCESS  Succeed to get all capsules.

**/
EFI_STATUS
GetAllCapsuleOnDisk (
  IN  UINTN       MaxRetry,
  OUT IMAGE_INFO  **CapsulePtr,
  OUT UINTN       *CapsuleNum,
  OUT EFI_HANDLE  *FsHandle,
  OUT UINT16      *LoadOptionNumber
  )
{
  EFI_STATUS                       Status;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
  EFI_FILE_HANDLE                  RootDir;
  EFI_FILE_HANDLE                  FileDir;
  UINT16                           *TempOptionNumber;

  TempOptionNumber = NULL;
  *CapsuleNum      = 0;

  Status = GetEfiSysPartitionFromActiveBootOption (MaxRetry, &TempOptionNumber, FsHandle);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = gBS->HandleProtocol (*FsHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = Fs->OpenVolume (Fs, &RootDir);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  Status = RootDir->Open (
                      RootDir,
                      &FileDir,
                      EFI_CAPSULE_FILE_DIRECTORY,
                      EFI_FILE_MODE_READ,
                      0
                      );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "CodLibGetAllCapsuleOnDisk fail to open RootDir!\n"));
    RootDir->Close (RootDir);
    return Status;
  }

  RootDir->Close (RootDir);

  //
  // Only Load files with EFI_FILE_SYSTEM or EFI_FILE_ARCHIVE attribute
  // ignore EFI_FILE_READ_ONLY, EFI_FILE_HIDDEN, EFI_FILE_RESERVED, EFI_FILE_DIRECTORY
  //
  Status = GetFileImageInAlphabetFromDir (
             FileDir,
             EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE,
             CapsulePtr,
             CapsuleNum
             );
  DEBUG ((DEBUG_INFO, "GetFileImageInAlphabetFromDir status %x\n", Status));

  //
  // Always remove file to avoid deadloop in capsule process
  //
  Status = RemoveFileFromDir (FileDir, EFI_FILE_SYSTEM | EFI_FILE_ARCHIVE);
  DEBUG ((DEBUG_INFO, "RemoveFileFromDir status %x\n", Status));

  FileDir->Close (FileDir);

  if (LoadOptionNumber != NULL) {
    *LoadOptionNumber = *TempOptionNumber;
  }

  return Status;
}

/**
  Build Gather list for a list of capsule images.

  @param[in]  CapsuleBuffer    An array of pointer to capsule images
  @param[in]  CapsuleSize      An array of UINTN to capsule images size
  @param[in]  CapsuleNum       The count of capsule images
  @param[out] BlockDescriptors The block descriptors for the capsule images

  @retval EFI_SUCCESS The block descriptors for the capsule images are constructed.

**/
EFI_STATUS
BuildGatherList (
  IN VOID                           **CapsuleBuffer,
  IN UINTN                          *CapsuleSize,
  IN UINTN                          CapsuleNum,
  OUT EFI_CAPSULE_BLOCK_DESCRIPTOR  **BlockDescriptors
  )
{
  EFI_STATUS                    Status;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockDescriptors1;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockDescriptorPre;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockDescriptorsHeader;
  UINTN                         Index;

  BlockDescriptors1      = NULL;
  BlockDescriptorPre     = NULL;
  BlockDescriptorsHeader = NULL;

  for (Index = 0; Index < CapsuleNum; Index++) {
    //
    // Allocate memory for the descriptors.
    //
    BlockDescriptors1 = AllocateZeroPool (2 * sizeof (EFI_CAPSULE_BLOCK_DESCRIPTOR));
    if (BlockDescriptors1 == NULL) {
      DEBUG ((DEBUG_ERROR, "BuildGatherList: failed to allocate memory for descriptors\n"));
      Status = EFI_OUT_OF_RESOURCES;
      goto ERREXIT;
    } else {
      DEBUG ((DEBUG_INFO, "BuildGatherList: creating capsule descriptors at 0x%X\n", (UINTN)BlockDescriptors1));
    }

    //
    // Record descirptor header
    //
    if (Index == 0) {
      BlockDescriptorsHeader = BlockDescriptors1;
    }

    if (BlockDescriptorPre != NULL) {
      BlockDescriptorPre->Union.ContinuationPointer = (UINTN)BlockDescriptors1;
      BlockDescriptorPre->Length                    = 0;
    }

    BlockDescriptors1->Union.DataBlock = (UINTN)CapsuleBuffer[Index];
    BlockDescriptors1->Length          = CapsuleSize[Index];

    BlockDescriptorPre = BlockDescriptors1 + 1;
    BlockDescriptors1  = NULL;
  }

  //
  // Null-terminate.
  //
  if (BlockDescriptorPre != NULL) {
    BlockDescriptorPre->Union.ContinuationPointer = (UINTN)NULL;
    BlockDescriptorPre->Length                    = 0;
    *BlockDescriptors                             = BlockDescriptorsHeader;
  }

  return EFI_SUCCESS;

ERREXIT:
  if (BlockDescriptors1 != NULL) {
    FreePool (BlockDescriptors1);
  }

  return Status;
}

/**
  This routine is called to check if CapsuleOnDisk flag in OsIndications Variable
  is enabled.

  @retval TRUE     Flag is enabled
  @retval FALSE    Flag is not enabled

**/
BOOLEAN
EFIAPI
CoDCheckCapsuleOnDiskFlag (
  VOID
  )
{
  EFI_STATUS  Status;
  UINT64      OsIndication;
  UINTN       DataSize;

  //
  // Check File Capsule Delivery Supported Flag in OsIndication variable
  //
  OsIndication = 0;
  DataSize     = sizeof (UINT64);
  Status       = gRT->GetVariable (
                        EFI_OS_INDICATIONS_VARIABLE_NAME,
                        &gEfiGlobalVariableGuid,
                        NULL,
                        &DataSize,
                        &OsIndication
                        );
  if (!EFI_ERROR (Status) &&
      ((OsIndication & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) != 0))
  {
    return TRUE;
  }

  return FALSE;
}

/**
  This routine is called to clear CapsuleOnDisk flags including OsIndications and BootNext variable.

  @retval EFI_SUCCESS   All Capsule On Disk flags are cleared

**/
EFI_STATUS
EFIAPI
CoDClearCapsuleOnDiskFlag (
  VOID
  )
{
  EFI_STATUS  Status;
  UINT64      OsIndication;
  UINTN       DataSize;

  //
  // Reset File Capsule Delivery Supported Flag in OsIndication variable
  //
  OsIndication = 0;
  DataSize     = sizeof (UINT64);
  Status       = gRT->GetVariable (
                        EFI_OS_INDICATIONS_VARIABLE_NAME,
                        &gEfiGlobalVariableGuid,
                        NULL,
                        &DataSize,
                        &OsIndication
                        );
  if (EFI_ERROR (Status) ||
      ((OsIndication & EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED) == 0))
  {
    return Status;
  }

  OsIndication &= ~((UINT64)EFI_OS_INDICATIONS_FILE_CAPSULE_DELIVERY_SUPPORTED);
  Status        = gRT->SetVariable (
                         EFI_OS_INDICATIONS_VARIABLE_NAME,
                         &gEfiGlobalVariableGuid,
                         EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                         sizeof (UINT64),
                         &OsIndication
                         );
  ASSERT (!EFI_ERROR (Status));

  //
  // Delete BootNext variable. Capsule Process may reset system, so can't rely on Bds to clear this variable
  //
  Status = gRT->SetVariable (
                  EFI_BOOT_NEXT_VARIABLE_NAME,
                  &gEfiGlobalVariableGuid,
                  0,
                  0,
                  NULL
                  );
  ASSERT (Status == EFI_SUCCESS || Status == EFI_NOT_FOUND);

  return EFI_SUCCESS;
}

/**
  This routine is called to clear CapsuleOnDisk Relocation Info variable.
  Total Capsule On Disk length is recorded in this variable

  @retval EFI_SUCCESS   Capsule On Disk flags are cleared

**/
EFI_STATUS
CoDClearCapsuleRelocationInfo (
  VOID
  )
{
  return gRT->SetVariable (
                COD_RELOCATION_INFO_VAR_NAME,
                &gEfiCapsuleVendorGuid,
                0,
                0,
                NULL
                );
}

/**
  Relocate Capsule on Disk from EFI system partition to a platform-specific NV storage device
  with BlockIo protocol. Relocation device path, identified by PcdCodRelocationDevPath, must
  be a full device path.
  Device enumeration like USB costs time, user can input MaxRetry to tell function to retry.
  Function will stall 100ms between each retry.

  Side Effects:
    Content corruption. Block IO write directly touches low level write. Orignal partitions, file systems
    of the relocation device will be corrupted.

  @param[in]    MaxRetry             Max Connection Retry. Stall 100ms between each connection try to ensure
                                     devices like USB can get enumerated.

  @retval EFI_SUCCESS   Capsule on Disk images are sucessfully relocated to the platform-specific device.

**/
EFI_STATUS
RelocateCapsuleToDisk (
  UINTN  MaxRetry
  )
{
  EFI_STATUS                       Status;
  UINTN                            CapsuleOnDiskNum;
  UINTN                            Index;
  UINTN                            DataSize;
  UINT64                           TotalImageSize;
  UINT64                           TotalImageNameSize;
  IMAGE_INFO                       *CapsuleOnDiskBuf;
  EFI_HANDLE                       Handle;
  EFI_HANDLE                       TempHandle;
  EFI_HANDLE                       *HandleBuffer;
  UINTN                            NumberOfHandles;
  EFI_BLOCK_IO_PROTOCOL            *BlockIo;
  UINT8                            *CapsuleDataBuf;
  UINT8                            *CapsulePtr;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
  EFI_FILE_HANDLE                  RootDir;
  EFI_FILE_HANDLE                  TempCodFile;
  UINT64                           TempCodFileSize;
  EFI_DEVICE_PATH                  *TempDevicePath;
  BOOLEAN                          RelocationInfo;
  UINT16                           LoadOptionNumber;
  EFI_CAPSULE_HEADER               FileNameCapsuleHeader;

  RootDir          = NULL;
  TempCodFile      = NULL;
  HandleBuffer     = NULL;
  CapsuleDataBuf   = NULL;
  CapsuleOnDiskBuf = NULL;
  NumberOfHandles  = 0;

  DEBUG ((DEBUG_INFO, "CapsuleOnDisk RelocateCapsule Enter\n"));

  //
  // 1. Load all Capsule On Disks in to memory
  //
  Status = GetAllCapsuleOnDisk (MaxRetry, &CapsuleOnDiskBuf, &CapsuleOnDiskNum, &Handle, &LoadOptionNumber);
  if (EFI_ERROR (Status) || (CapsuleOnDiskNum == 0) || (CapsuleOnDiskBuf == NULL)) {
    DEBUG ((DEBUG_INFO, "RelocateCapsule: GetAllCapsuleOnDisk Status - 0x%x\n", Status));
    return EFI_NOT_FOUND;
  }

  //
  // 2. Connect platform special device path as relocation device.
  // If no platform special device path specified or the device path is invalid, use the EFI system partition where
  // stores the capsules as relocation device.
  //
  if (IsDevicePathValid ((EFI_DEVICE_PATH *)PcdGetPtr (PcdCodRelocationDevPath), PcdGetSize (PcdCodRelocationDevPath))) {
    Status = EfiBootManagerConnectDevicePath ((EFI_DEVICE_PATH *)PcdGetPtr (PcdCodRelocationDevPath), &TempHandle);
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "RelocateCapsule: EfiBootManagerConnectDevicePath Status - 0x%x\n", Status));
      goto EXIT;
    }

    //
    // Connect all the child handle. Partition & FAT drivers are allowed in this case
    //
    gBS->ConnectController (TempHandle, NULL, NULL, TRUE);
    Status = gBS->LocateHandleBuffer (
                    ByProtocol,
                    &gEfiSimpleFileSystemProtocolGuid,
                    NULL,
                    &NumberOfHandles,
                    &HandleBuffer
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_ERROR, "RelocateCapsule: LocateHandleBuffer Status - 0x%x\n", Status));
      goto EXIT;
    }

    //
    // Find first Simple File System Handle which can match PcdCodRelocationDevPath
    //
    for (Index = 0; Index < NumberOfHandles; Index++) {
      Status = gBS->HandleProtocol (HandleBuffer[Index], &gEfiDevicePathProtocolGuid, (VOID **)&TempDevicePath);
      if (EFI_ERROR (Status)) {
        continue;
      }

      DataSize = GetDevicePathSize ((EFI_DEVICE_PATH *)PcdGetPtr (PcdCodRelocationDevPath)) - sizeof (EFI_DEVICE_PATH);
      if (0 == CompareMem ((EFI_DEVICE_PATH *)PcdGetPtr (PcdCodRelocationDevPath), TempDevicePath, DataSize)) {
        Handle = HandleBuffer[Index];
        break;
      }
    }

    FreePool (HandleBuffer);

    if (Index == NumberOfHandles) {
      DEBUG ((DEBUG_ERROR, "RelocateCapsule: No simple file system protocol found.\n"));
      Status = EFI_NOT_FOUND;
    }
  }

  Status = gBS->HandleProtocol (Handle, &gEfiBlockIoProtocolGuid, (VOID **)&BlockIo);
  if (EFI_ERROR (Status) || BlockIo->Media->ReadOnly) {
    DEBUG ((DEBUG_ERROR, "Fail to find Capsule on Disk relocation BlockIo device or device is ReadOnly!\n"));
    goto EXIT;
  }

  Status = gBS->HandleProtocol (Handle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  //
  // Check if device used to relocate Capsule On Disk is big enough
  //
  TotalImageSize     = 0;
  TotalImageNameSize = 0;
  for (Index = 0; Index < CapsuleOnDiskNum; Index++) {
    //
    // Overflow check
    //
    if (MAX_ADDRESS - (UINTN)TotalImageSize <= CapsuleOnDiskBuf[Index].FileInfo->FileSize) {
      Status = EFI_INVALID_PARAMETER;
      goto EXIT;
    }

    if (MAX_ADDRESS - (UINTN)TotalImageNameSize <= StrSize (CapsuleOnDiskBuf[Index].FileInfo->FileName)) {
      Status = EFI_INVALID_PARAMETER;
      goto EXIT;
    }

    TotalImageSize     += CapsuleOnDiskBuf[Index].FileInfo->FileSize;
    TotalImageNameSize += StrSize (CapsuleOnDiskBuf[Index].FileInfo->FileName);
    DEBUG ((DEBUG_INFO, "RelocateCapsule: %x Size %x\n", CapsuleOnDiskBuf[Index].FileInfo->FileName, CapsuleOnDiskBuf[Index].FileInfo->FileSize));
  }

  DEBUG ((DEBUG_INFO, "RelocateCapsule: TotalImageSize %x\n", TotalImageSize));
  DEBUG ((DEBUG_INFO, "RelocateCapsule: TotalImageNameSize %x\n", TotalImageNameSize));

  if ((MAX_ADDRESS - (UINTN)TotalImageNameSize <= sizeof (UINT64) * 2) ||
      (MAX_ADDRESS - (UINTN)TotalImageSize <= (UINTN)TotalImageNameSize + sizeof (UINT64) * 2))
  {
    Status = EFI_INVALID_PARAMETER;
    goto EXIT;
  }

  TempCodFileSize = sizeof (UINT64) + TotalImageSize + sizeof (EFI_CAPSULE_HEADER) + TotalImageNameSize;

  //
  // Check if CapsuleTotalSize. There could be reminder, so use LastBlock number directly
  //
  if (DivU64x32 (TempCodFileSize, BlockIo->Media->BlockSize) > BlockIo->Media->LastBlock) {
    DEBUG ((DEBUG_ERROR, "RelocateCapsule: Relocation device isn't big enough to hold all Capsule on Disk!\n"));
    DEBUG ((DEBUG_ERROR, "TotalImageSize = %x\n", TotalImageSize));
    DEBUG ((DEBUG_ERROR, "TotalImageNameSize = %x\n", TotalImageNameSize));
    DEBUG ((DEBUG_ERROR, "RelocationDev BlockSize = %x LastBlock = %x\n", BlockIo->Media->BlockSize, BlockIo->Media->LastBlock));
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  CapsuleDataBuf = AllocatePool ((UINTN)TempCodFileSize);
  if (CapsuleDataBuf == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto EXIT;
  }

  //
  // First UINT64 reserved for total image size, including capsule name capsule.
  //
  *(UINT64 *)CapsuleDataBuf = TotalImageSize + sizeof (EFI_CAPSULE_HEADER) + TotalImageNameSize;

  //
  // Line up all the Capsule on Disk and write to relocation disk at one time. It could save some time in disk write
  //
  for (Index = 0, CapsulePtr = CapsuleDataBuf + sizeof (UINT64); Index < CapsuleOnDiskNum; Index++) {
    CopyMem (CapsulePtr, CapsuleOnDiskBuf[Index].ImageAddress, (UINTN)CapsuleOnDiskBuf[Index].FileInfo->FileSize);
    CapsulePtr += CapsuleOnDiskBuf[Index].FileInfo->FileSize;
  }

  //
  // Line the capsule header for capsule name capsule.
  //
  CopyGuid (&FileNameCapsuleHeader.CapsuleGuid, &gEdkiiCapsuleOnDiskNameGuid);
  FileNameCapsuleHeader.CapsuleImageSize = (UINT32)TotalImageNameSize + sizeof (EFI_CAPSULE_HEADER);
  FileNameCapsuleHeader.Flags            = CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
  FileNameCapsuleHeader.HeaderSize       = sizeof (EFI_CAPSULE_HEADER);
  CopyMem (CapsulePtr, &FileNameCapsuleHeader, FileNameCapsuleHeader.HeaderSize);
  CapsulePtr += FileNameCapsuleHeader.HeaderSize;

  //
  // Line up all the Capsule file names.
  //
  for (Index = 0; Index < CapsuleOnDiskNum; Index++) {
    CopyMem (CapsulePtr, CapsuleOnDiskBuf[Index].FileInfo->FileName, StrSize (CapsuleOnDiskBuf[Index].FileInfo->FileName));
    CapsulePtr += StrSize (CapsuleOnDiskBuf[Index].FileInfo->FileName);
  }

  //
  // 5. Flash all Capsules on Disk to TempCoD.tmp under RootDir
  //
  Status = Fs->OpenVolume (Fs, &RootDir);
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "RelocateCapsule: OpenVolume error. %x\n", Status));
    goto EXIT;
  }

  Status = RootDir->Open (
                      RootDir,
                      &TempCodFile,
                      (CHAR16 *)PcdGetPtr (PcdCoDRelocationFileName),
                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
                      0
                      );
  if (!EFI_ERROR (Status)) {
    //
    // Error handling code to prevent malicious code to hold this file to block capsule on disk
    //
    TempCodFile->Delete (TempCodFile);
  }

  Status = RootDir->Open (
                      RootDir,
                      &TempCodFile,
                      (CHAR16 *)PcdGetPtr (PcdCoDRelocationFileName),
                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE | EFI_FILE_MODE_CREATE,
                      0
                      );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "RelocateCapsule: Open TemCoD.tmp error. %x\n", Status));
    goto EXIT;
  }

  //
  // Always write at the begining of TempCap file
  //
  DataSize = (UINTN)TempCodFileSize;
  Status   = TempCodFile->Write (
                            TempCodFile,
                            &DataSize,
                            CapsuleDataBuf
                            );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_ERROR, "RelocateCapsule: Write TemCoD.tmp error. %x\n", Status));
    goto EXIT;
  }

  if (DataSize != TempCodFileSize) {
    Status = EFI_DEVICE_ERROR;
    goto EXIT;
  }

  //
  // Save Capsule On Disk relocation info to "CodRelocationInfo" Var
  // It is used in next reboot by TCB
  //
  RelocationInfo = TRUE;
  Status         = gRT->SetVariable (
                          COD_RELOCATION_INFO_VAR_NAME,
                          &gEfiCapsuleVendorGuid,
                          EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                          sizeof (BOOLEAN),
                          &RelocationInfo
                          );
  //
  // Save the LoadOptionNumber of the boot option, where the capsule is relocated,
  // into "CodRelocationLoadOption" var. It is used in next reboot after capsule is
  // updated out of TCB to remove the TempCoDFile.
  //
  Status = gRT->SetVariable (
                  COD_RELOCATION_LOAD_OPTION_VAR_NAME,
                  &gEfiCapsuleVendorGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                  sizeof (UINT16),
                  &LoadOptionNumber
                  );

EXIT:

  if (CapsuleDataBuf != NULL) {
    FreePool (CapsuleDataBuf);
  }

  if (CapsuleOnDiskBuf != NULL) {
    //
    // Free resources allocated by CodLibGetAllCapsuleOnDisk
    //
    for (Index = 0; Index < CapsuleOnDiskNum; Index++ ) {
      FreePool (CapsuleOnDiskBuf[Index].ImageAddress);
      FreePool (CapsuleOnDiskBuf[Index].FileInfo);
    }

    FreePool (CapsuleOnDiskBuf);
  }

  if (TempCodFile != NULL) {
    if (EFI_ERROR (Status)) {
      TempCodFile->Delete (TempCodFile);
    } else {
      TempCodFile->Close (TempCodFile);
    }
  }

  if (RootDir != NULL) {
    RootDir->Close (RootDir);
  }

  return Status;
}

/**
  For the platforms that support Capsule In Ram, reuse the Capsule In Ram to deliver capsule.
  Relocate Capsule On Disk to memory and call UpdateCapsule().
  Device enumeration like USB costs time, user can input MaxRetry to tell function to retry.
  Function will stall 100ms between each retry.

  @param[in]    MaxRetry             Max Connection Retry. Stall 100ms between each connection try to ensure
                                     devices like USB can get enumerated.

  @retval EFI_SUCCESS   Deliver capsule through Capsule In Ram successfully.

**/
EFI_STATUS
RelocateCapsuleToRam (
  UINTN  MaxRetry
  )
{
  EFI_STATUS                    Status;
  UINTN                         CapsuleOnDiskNum;
  IMAGE_INFO                    *CapsuleOnDiskBuf;
  EFI_HANDLE                    Handle;
  EFI_CAPSULE_BLOCK_DESCRIPTOR  *BlockDescriptors;
  VOID                          **CapsuleBuffer;
  UINTN                         *CapsuleSize;
  EFI_CAPSULE_HEADER            *FileNameCapsule;
  UINTN                         Index;
  UINT8                         *StringBuf;
  UINTN                         StringSize;
  UINTN                         TotalStringSize;
  UINTN                         CapsulesToProcess;

  CapsuleOnDiskBuf = NULL;
  BlockDescriptors = NULL;
  CapsuleBuffer    = NULL;
  CapsuleSize      = NULL;
  FileNameCapsule  = NULL;
  TotalStringSize  = 0;

  //
  // 1. Load all Capsule On Disks into memory
  //
  Status = GetAllCapsuleOnDisk (MaxRetry, &CapsuleOnDiskBuf, &CapsuleOnDiskNum, &Handle, NULL);
  if (EFI_ERROR (Status) || (CapsuleOnDiskNum == 0) || (CapsuleOnDiskBuf == NULL)) {
    DEBUG ((DEBUG_ERROR, "GetAllCapsuleOnDisk Status - 0x%x\n", Status));
    return EFI_NOT_FOUND;
  }

  //
  // 2. Add a capsule for Capsule file name strings
  //
  CapsuleBuffer = AllocateZeroPool ((CapsuleOnDiskNum + 1) * sizeof (VOID *));
  if (CapsuleBuffer == NULL) {
    DEBUG ((DEBUG_ERROR, "Fail to allocate memory for capsules.\n"));
    return EFI_OUT_OF_RESOURCES;
  }

  CapsuleSize = AllocateZeroPool ((CapsuleOnDiskNum + 1) * sizeof (UINTN));
  if (CapsuleSize == NULL) {
    DEBUG ((DEBUG_ERROR, "Fail to allocate memory for capsules.\n"));
    FreePool (CapsuleBuffer);
    return EFI_OUT_OF_RESOURCES;
  }

  for (Index = 0; Index < CapsuleOnDiskNum; Index++) {
    CapsuleBuffer[Index] = (VOID *)(UINTN)CapsuleOnDiskBuf[Index].ImageAddress;
    CapsuleSize[Index]   = (UINTN)CapsuleOnDiskBuf[Index].FileInfo->FileSize;
    TotalStringSize     += StrSize (CapsuleOnDiskBuf[Index].FileInfo->FileName);
  }

  // If Persist Across Reset isn't supported, skip the file name strings capsule
  if (!FeaturePcdGet (PcdSupportUpdateCapsuleReset)) {
    CapsulesToProcess = CapsuleOnDiskNum;
    goto BuildGather;
  }

  CapsulesToProcess = CapsuleOnDiskNum + 1;

  FileNameCapsule = AllocateZeroPool (sizeof (EFI_CAPSULE_HEADER) + TotalStringSize);
  if (FileNameCapsule == NULL) {
    DEBUG ((DEBUG_ERROR, "Fail to allocate memory for name capsule.\n"));
    FreePool (CapsuleBuffer);
    FreePool (CapsuleSize);
    return EFI_OUT_OF_RESOURCES;
  }

  FileNameCapsule->CapsuleImageSize = (UINT32)(sizeof (EFI_CAPSULE_HEADER) + TotalStringSize);
  FileNameCapsule->Flags            = CAPSULE_FLAGS_PERSIST_ACROSS_RESET;
  FileNameCapsule->HeaderSize       = sizeof (EFI_CAPSULE_HEADER);
  CopyGuid (&(FileNameCapsule->CapsuleGuid), &gEdkiiCapsuleOnDiskNameGuid);

  StringBuf = (UINT8 *)FileNameCapsule + FileNameCapsule->HeaderSize;
  for (Index = 0; Index < CapsuleOnDiskNum; Index++) {
    StringSize = StrSize (CapsuleOnDiskBuf[Index].FileInfo->FileName);
    CopyMem (StringBuf, CapsuleOnDiskBuf[Index].FileInfo->FileName, StringSize);
    StringBuf += StringSize;
  }

  CapsuleBuffer[CapsuleOnDiskNum] = FileNameCapsule;
  CapsuleSize[CapsuleOnDiskNum]   = TotalStringSize + sizeof (EFI_CAPSULE_HEADER);

  //
  // 3. Build Gather list for the capsules
  //
BuildGather:
  Status = BuildGatherList (CapsuleBuffer, CapsuleSize, CapsulesToProcess, &BlockDescriptors);
  if (EFI_ERROR (Status) || (BlockDescriptors == NULL)) {
    FreePool (CapsuleBuffer);
    FreePool (CapsuleSize);
    if (FileNameCapsule != NULL) {
      FreePool (FileNameCapsule);
    }

    return EFI_OUT_OF_RESOURCES;
  }

  //
  // 4. Call UpdateCapsule() service
  //
  Status = gRT->UpdateCapsule (
                  (EFI_CAPSULE_HEADER **)CapsuleBuffer,
                  CapsulesToProcess,
                  (UINTN)BlockDescriptors
                  );

  return Status;
}

/**
  Relocate Capsule on Disk from EFI system partition.

  Two solution to deliver Capsule On Disk:
  Solution A: If PcdCapsuleInRamSupport is enabled, relocate Capsule On Disk to memory and call UpdateCapsule().
  Solution B: If PcdCapsuleInRamSupport is disabled, relocate Capsule On Disk to a platform-specific NV storage
  device with BlockIo protocol.

  Device enumeration like USB costs time, user can input MaxRetry to tell function to retry.
  Function will stall 100ms between each retry.

  Side Effects:
    Capsule Delivery Supported Flag in OsIndication variable and BootNext variable will be cleared.
    Solution B: Content corruption. Block IO write directly touches low level write. Orignal partitions, file
  systems of the relocation device will be corrupted.

  @param[in]    MaxRetry             Max Connection Retry. Stall 100ms between each connection try to ensure
                                     devices like USB can get enumerated. Input 0 means no retry.

  @retval EFI_SUCCESS   Capsule on Disk images are successfully relocated.

**/
EFI_STATUS
EFIAPI
CoDRelocateCapsule (
  UINTN  MaxRetry
  )
{
  if (!PcdGetBool (PcdCapsuleOnDiskSupport)) {
    return EFI_UNSUPPORTED;
  }

  //
  // Clear CapsuleOnDisk Flag firstly.
  //
  CoDClearCapsuleOnDiskFlag ();

  //
  // If Capsule In Ram is supported, delivery capsules through memory
  //
  if (PcdGetBool (PcdCapsuleInRamSupport)) {
    DEBUG ((DEBUG_INFO, "Capsule In Ram is supported, call gRT->UpdateCapsule().\n"));
    return RelocateCapsuleToRam (MaxRetry);
  } else {
    DEBUG ((DEBUG_INFO, "Reallcoate all Capsule on Disks to %s in RootDir.\n", (CHAR16 *)PcdGetPtr (PcdCoDRelocationFileName)));
    return RelocateCapsuleToDisk (MaxRetry);
  }
}

/**
  Remove the temp file from the root of EFI System Partition.
  Device enumeration like USB costs time, user can input MaxRetry to tell function to retry.
  Function will stall 100ms between each retry.

  @param[in]    MaxRetry             Max Connection Retry. Stall 100ms between each connection try to ensure
                                     devices like USB can get enumerated. Input 0 means no retry.

  @retval EFI_SUCCESS   Remove the temp file successfully.

**/
EFI_STATUS
EFIAPI
CoDRemoveTempFile (
  UINTN  MaxRetry
  )
{
  EFI_STATUS                       Status;
  UINTN                            DataSize;
  UINT16                           *LoadOptionNumber;
  EFI_SIMPLE_FILE_SYSTEM_PROTOCOL  *Fs;
  EFI_HANDLE                       FsHandle;
  EFI_FILE_HANDLE                  RootDir;
  EFI_FILE_HANDLE                  TempCodFile;

  RootDir     = NULL;
  TempCodFile = NULL;
  DataSize    = sizeof (UINT16);

  LoadOptionNumber = AllocatePool (sizeof (UINT16));
  if (LoadOptionNumber == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Check if capsule files are relocated
  //
  Status = gRT->GetVariable (
                  COD_RELOCATION_LOAD_OPTION_VAR_NAME,
                  &gEfiCapsuleVendorGuid,
                  NULL,
                  &DataSize,
                  (VOID *)LoadOptionNumber
                  );
  if (EFI_ERROR (Status) || (DataSize != sizeof (UINT16))) {
    goto EXIT;
  }

  //
  // Get the EFI file system from the boot option where the capsules are relocated
  //
  Status = GetEfiSysPartitionFromActiveBootOption (MaxRetry, &LoadOptionNumber, &FsHandle);
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  Status = gBS->HandleProtocol (FsHandle, &gEfiSimpleFileSystemProtocolGuid, (VOID **)&Fs);
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  Status = Fs->OpenVolume (Fs, &RootDir);
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  //
  // Delete the TempCoDFile
  //
  Status = RootDir->Open (
                      RootDir,
                      &TempCodFile,
                      (CHAR16 *)PcdGetPtr (PcdCoDRelocationFileName),
                      EFI_FILE_MODE_READ | EFI_FILE_MODE_WRITE,
                      0
                      );
  if (EFI_ERROR (Status)) {
    goto EXIT;
  }

  TempCodFile->Delete (TempCodFile);

  //
  // Clear "CoDRelocationLoadOption" variable
  //
  Status = gRT->SetVariable (
                  COD_RELOCATION_LOAD_OPTION_VAR_NAME,
                  &gEfiCapsuleVendorGuid,
                  0,
                  0,
                  NULL
                  );

EXIT:
  if (LoadOptionNumber != NULL) {
    FreePool (LoadOptionNumber);
  }

  if (RootDir != NULL) {
    RootDir->Close (RootDir);
  }

  return Status;
}
