/** @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)) || (BootOrderOptionBuf == NULL)) {
    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;
}
