/** @file
  Sample platform variable cleanup library implementation.

Copyright (c) 2015 - 2017, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "PlatVarCleanup.h"

VAR_ERROR_FLAG            mLastVarErrorFlag = VAR_ERROR_FLAG_NO_ERROR;
EDKII_VAR_CHECK_PROTOCOL  *mVarCheck        = NULL;

///
/// The flag to indicate whether the platform has left the DXE phase of execution.
///
BOOLEAN  mEndOfDxe = FALSE;

EFI_EVENT  mPlatVarCleanupLibEndOfDxeEvent = NULL;

LIST_ENTRY  mUserVariableList        = INITIALIZE_LIST_HEAD_VARIABLE (mUserVariableList);
UINT16      mUserVariableCount       = 0;
UINT16      mMarkedUserVariableCount = 0;

EFI_GUID  mVariableCleanupHiiGuid = VARIABLE_CLEANUP_HII_GUID;
CHAR16    mVarStoreName[]         = L"VariableCleanup";

HII_VENDOR_DEVICE_PATH  mVarCleanupHiiVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    VARIABLE_CLEANUP_HII_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(sizeof (EFI_DEVICE_PATH_PROTOCOL)),
      (UINT8)((sizeof (EFI_DEVICE_PATH_PROTOCOL)) >> 8)
    }
  }
};

/**
  Internal get variable error flag.

  @return   Variable error flag.

**/
VAR_ERROR_FLAG
InternalGetVarErrorFlag (
  VOID
  )
{
  EFI_STATUS      Status;
  UINTN           Size;
  VAR_ERROR_FLAG  ErrorFlag;

  Size   = sizeof (ErrorFlag);
  Status = gRT->GetVariable (
                  VAR_ERROR_FLAG_NAME,
                  &gEdkiiVarErrorFlagGuid,
                  NULL,
                  &Size,
                  &ErrorFlag
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "%s - not found\n", VAR_ERROR_FLAG_NAME));
    return VAR_ERROR_FLAG_NO_ERROR;
  }

  return ErrorFlag;
}

/**
  Is user variable?

  @param[in] Name   Pointer to variable name.
  @param[in] Guid   Pointer to vendor guid.

  @retval TRUE      User variable.
  @retval FALSE     System variable.

**/
BOOLEAN
IsUserVariable (
  IN CHAR16    *Name,
  IN EFI_GUID  *Guid
  )
{
  EFI_STATUS                   Status;
  VAR_CHECK_VARIABLE_PROPERTY  Property;

  if (mVarCheck == NULL) {
    gBS->LocateProtocol (
           &gEdkiiVarCheckProtocolGuid,
           NULL,
           (VOID **)&mVarCheck
           );
  }

  ASSERT (mVarCheck != NULL);

  ZeroMem (&Property, sizeof (Property));
  Status = mVarCheck->VariablePropertyGet (
                        Name,
                        Guid,
                        &Property
                        );
  if (EFI_ERROR (Status)) {
    //
    // No property, it is user variable.
    //
    DEBUG ((DEBUG_INFO, "PlatformVarCleanup - User variable: %g:%s\n", Guid, Name));
    return TRUE;
  }

  //  DEBUG ((DEBUG_INFO, "PlatformVarCleanup - Variable Property: %g:%s\n", Guid, Name));
  //  DEBUG ((DEBUG_INFO, "  Revision  - 0x%04x\n", Property.Revision));
  //  DEBUG ((DEBUG_INFO, "  Property  - 0x%04x\n", Property.Property));
  //  DEBUG ((DEBUG_INFO, "  Attribute - 0x%08x\n", Property.Attributes));
  //  DEBUG ((DEBUG_INFO, "  MinSize   - 0x%x\n", Property.MinSize));
  //  DEBUG ((DEBUG_INFO, "  MaxSize   - 0x%x\n", Property.MaxSize));

  return FALSE;
}

/**
  Find user variable node by variable GUID.

  @param[in] Guid   Pointer to vendor guid.

  @return Pointer to user variable node.

**/
USER_VARIABLE_NODE *
FindUserVariableNodeByGuid (
  IN EFI_GUID  *Guid
  )
{
  USER_VARIABLE_NODE  *UserVariableNode;
  LIST_ENTRY          *Link;

  for (Link = mUserVariableList.ForwardLink
       ; Link != &mUserVariableList
       ; Link = Link->ForwardLink)
  {
    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);

    if (CompareGuid (Guid, &UserVariableNode->Guid)) {
      //
      // Found it.
      //
      return UserVariableNode;
    }
  }

  //
  // Create new one if not found.
  //
  UserVariableNode = AllocateZeroPool (sizeof (*UserVariableNode));
  ASSERT (UserVariableNode != NULL);
  UserVariableNode->Signature = USER_VARIABLE_NODE_SIGNATURE;
  CopyGuid (&UserVariableNode->Guid, Guid);
  //
  // (36 chars of "########-####-####-####-############" + 1 space + 1 terminator) * sizeof (CHAR16).
  //
  UserVariableNode->PromptString = AllocatePool ((36 + 2) * sizeof (CHAR16));
  ASSERT (UserVariableNode->PromptString != NULL);
  UnicodeSPrint (UserVariableNode->PromptString, (36 + 2) * sizeof (CHAR16), L" %g", &UserVariableNode->Guid);
  InitializeListHead (&UserVariableNode->NameLink);
  InsertTailList (&mUserVariableList, &UserVariableNode->Link);
  return UserVariableNode;
}

/**
  Create user variable node.

**/
VOID
CreateUserVariableNode (
  VOID
  )
{
  EFI_STATUS               Status;
  EFI_STATUS               GetVariableStatus;
  CHAR16                   *VarName;
  UINTN                    MaxVarNameSize;
  UINTN                    VarNameSize;
  UINTN                    MaxDataSize;
  UINTN                    DataSize;
  VOID                     *Data;
  UINT32                   Attributes;
  EFI_GUID                 Guid;
  USER_VARIABLE_NODE       *UserVariableNode;
  USER_VARIABLE_NAME_NODE  *UserVariableNameNode;
  UINT16                   Index;
  UINTN                    StringSize;

  //
  // Initialize 128 * sizeof (CHAR16) variable name size.
  //
  MaxVarNameSize = 128 * sizeof (CHAR16);
  VarName        = AllocateZeroPool (MaxVarNameSize);
  ASSERT (VarName != NULL);

  //
  // Initialize 0x1000 variable data size.
  //
  MaxDataSize = 0x1000;
  Data        = AllocateZeroPool (MaxDataSize);
  ASSERT (Data != NULL);

  Index = 0;
  do {
    VarNameSize = MaxVarNameSize;
    Status      = gRT->GetNextVariableName (&VarNameSize, VarName, &Guid);
    if (Status == EFI_BUFFER_TOO_SMALL) {
      VarName = ReallocatePool (MaxVarNameSize, VarNameSize, VarName);
      ASSERT (VarName != NULL);
      MaxVarNameSize = VarNameSize;
      Status         = gRT->GetNextVariableName (&VarNameSize, VarName, &Guid);
    }

    if (!EFI_ERROR (Status)) {
      if (IsUserVariable (VarName, &Guid)) {
        DataSize          = MaxDataSize;
        GetVariableStatus = gRT->GetVariable (VarName, &Guid, &Attributes, &DataSize, Data);
        if (GetVariableStatus == EFI_BUFFER_TOO_SMALL) {
          Data = ReallocatePool (MaxDataSize, DataSize, Data);
          ASSERT (Data != NULL);
          MaxDataSize       = DataSize;
          GetVariableStatus = gRT->GetVariable (VarName, &Guid, &Attributes, &DataSize, Data);
        }

        ASSERT_EFI_ERROR (GetVariableStatus);

        if ((Attributes & EFI_VARIABLE_NON_VOLATILE) != 0) {
          UserVariableNode = FindUserVariableNodeByGuid (&Guid);
          ASSERT (UserVariableNode != NULL);

          //
          // Different variables that have same variable GUID share same user variable node.
          //
          UserVariableNameNode = AllocateZeroPool (sizeof (*UserVariableNameNode));
          ASSERT (UserVariableNameNode != NULL);
          UserVariableNameNode->Signature  = USER_VARIABLE_NAME_NODE_SIGNATURE;
          UserVariableNameNode->Name       = AllocateCopyPool (VarNameSize, VarName);
          UserVariableNameNode->Attributes = Attributes;
          UserVariableNameNode->DataSize   = DataSize;
          UserVariableNameNode->Index      = Index;
          UserVariableNameNode->QuestionId = (EFI_QUESTION_ID)(USER_VARIABLE_QUESTION_ID + Index);
          //
          // 2 space * sizeof (CHAR16) + StrSize.
          //
          StringSize                         = 2 * sizeof (CHAR16) + StrSize (UserVariableNameNode->Name);
          UserVariableNameNode->PromptString = AllocatePool (StringSize);
          ASSERT (UserVariableNameNode->PromptString != NULL);
          UnicodeSPrint (UserVariableNameNode->PromptString, StringSize, L"  %s", UserVariableNameNode->Name);
          //
          // (33 chars of "Attribtues = 0x and DataSize = 0x" + 1 terminator + (sizeof (UINT32) + sizeof (UINTN)) * 2) * sizeof (CHAR16).
          //
          StringSize                       = (33 + 1 + (sizeof (UINT32) + sizeof (UINTN)) * 2) * sizeof (CHAR16);
          UserVariableNameNode->HelpString = AllocatePool (StringSize);
          ASSERT (UserVariableNameNode->HelpString != NULL);
          UnicodeSPrint (UserVariableNameNode->HelpString, StringSize, L"Attribtues = 0x%08x and DataSize = 0x%x", UserVariableNameNode->Attributes, UserVariableNameNode->DataSize);
          UserVariableNameNode->Deleted = FALSE;
          InsertTailList (&UserVariableNode->NameLink, &UserVariableNameNode->Link);
          Index++;
        }
      }
    }
  } while (Status != EFI_NOT_FOUND);

  mUserVariableCount = Index;
  ASSERT (mUserVariableCount <= MAX_USER_VARIABLE_COUNT);
  DEBUG ((DEBUG_INFO, "PlatformVarCleanup - User variable count: 0x%04x\n", mUserVariableCount));

  FreePool (VarName);
  FreePool (Data);
}

/**
  Destroy user variable nodes.

**/
VOID
DestroyUserVariableNode (
  VOID
  )
{
  USER_VARIABLE_NODE       *UserVariableNode;
  LIST_ENTRY               *Link;
  USER_VARIABLE_NAME_NODE  *UserVariableNameNode;
  LIST_ENTRY               *NameLink;

  while (mUserVariableList.ForwardLink != &mUserVariableList) {
    Link             = mUserVariableList.ForwardLink;
    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);

    RemoveEntryList (&UserVariableNode->Link);

    while (UserVariableNode->NameLink.ForwardLink != &UserVariableNode->NameLink) {
      NameLink             = UserVariableNode->NameLink.ForwardLink;
      UserVariableNameNode = USER_VARIABLE_NAME_FROM_LINK (NameLink);

      RemoveEntryList (&UserVariableNameNode->Link);

      FreePool (UserVariableNameNode->Name);
      FreePool (UserVariableNameNode->PromptString);
      FreePool (UserVariableNameNode->HelpString);
      FreePool (UserVariableNameNode);
    }

    FreePool (UserVariableNode->PromptString);
    FreePool (UserVariableNode);
  }
}

/**
  Create a time based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION_2
  descriptor with the input data. NO authentication is required in this function.

  @param[in, out] DataSize          On input, the size of Data buffer in bytes.
                                    On output, the size of data returned in Data
                                    buffer in bytes.
  @param[in, out] Data              On input, Pointer to data buffer to be wrapped or
                                    pointer to NULL to wrap an empty payload.
                                    On output, Pointer to the new payload date buffer allocated from pool,
                                    it's caller's responsibility to free the memory after using it.

  @retval EFI_SUCCESS               Create time based payload successfully.
  @retval EFI_OUT_OF_RESOURCES      There are not enough memory resourses to create time based payload.
  @retval EFI_INVALID_PARAMETER     The parameter is invalid.
  @retval Others                    Unexpected error happens.

**/
EFI_STATUS
CreateTimeBasedPayload (
  IN OUT UINTN  *DataSize,
  IN OUT UINT8  **Data
  )
{
  EFI_STATUS                     Status;
  UINT8                          *NewData;
  UINT8                          *Payload;
  UINTN                          PayloadSize;
  EFI_VARIABLE_AUTHENTICATION_2  *DescriptorData;
  UINTN                          DescriptorSize;
  EFI_TIME                       Time;

  if ((Data == NULL) || (DataSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // At user physical presence, the variable does not need to be signed but the
  // parameters to the SetVariable() call still need to be prepared as authenticated
  // variable. So we create EFI_VARIABLE_AUTHENTICATED_2 descriptor without certificate
  // data in it.
  //
  Payload     = *Data;
  PayloadSize = *DataSize;

  DescriptorSize = OFFSET_OF (EFI_VARIABLE_AUTHENTICATION_2, AuthInfo) + OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
  NewData        = (UINT8 *)AllocateZeroPool (DescriptorSize + PayloadSize);
  if (NewData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if ((Payload != NULL) && (PayloadSize != 0)) {
    CopyMem (NewData + DescriptorSize, Payload, PayloadSize);
  }

  DescriptorData = (EFI_VARIABLE_AUTHENTICATION_2 *)(NewData);

  ZeroMem (&Time, sizeof (EFI_TIME));
  Status = gRT->GetTime (&Time, NULL);
  if (EFI_ERROR (Status)) {
    FreePool (NewData);
    return Status;
  }

  Time.Pad1       = 0;
  Time.Nanosecond = 0;
  Time.TimeZone   = 0;
  Time.Daylight   = 0;
  Time.Pad2       = 0;
  CopyMem (&DescriptorData->TimeStamp, &Time, sizeof (EFI_TIME));

  DescriptorData->AuthInfo.Hdr.dwLength         = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData);
  DescriptorData->AuthInfo.Hdr.wRevision        = 0x0200;
  DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
  CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertPkcs7Guid);

  if (Payload != NULL) {
    FreePool (Payload);
  }

  *DataSize = DescriptorSize + PayloadSize;
  *Data     = NewData;
  return EFI_SUCCESS;
}

/**
  Create a counter based data payload by concatenating the EFI_VARIABLE_AUTHENTICATION
  descriptor with the input data. NO authentication is required in this function.

  @param[in, out] DataSize          On input, the size of Data buffer in bytes.
                                    On output, the size of data returned in Data
                                    buffer in bytes.
  @param[in, out] Data              On input, Pointer to data buffer to be wrapped or
                                    pointer to NULL to wrap an empty payload.
                                    On output, Pointer to the new payload date buffer allocated from pool,
                                    it's caller's responsibility to free the memory after using it.

  @retval EFI_SUCCESS               Create counter based payload successfully.
  @retval EFI_OUT_OF_RESOURCES      There are not enough memory resourses to create time based payload.
  @retval EFI_INVALID_PARAMETER     The parameter is invalid.
  @retval Others                    Unexpected error happens.

**/
EFI_STATUS
CreateCounterBasedPayload (
  IN OUT UINTN  *DataSize,
  IN OUT UINT8  **Data
  )
{
  EFI_STATUS                   Status;
  UINT8                        *NewData;
  UINT8                        *Payload;
  UINTN                        PayloadSize;
  EFI_VARIABLE_AUTHENTICATION  *DescriptorData;
  UINTN                        DescriptorSize;
  UINT64                       MonotonicCount;

  if ((Data == NULL) || (DataSize == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // At user physical presence, the variable does not need to be signed but the
  // parameters to the SetVariable() call still need to be prepared as authenticated
  // variable. So we create EFI_VARIABLE_AUTHENTICATED descriptor without certificate
  // data in it.
  //
  Payload     = *Data;
  PayloadSize = *DataSize;

  DescriptorSize = (OFFSET_OF (EFI_VARIABLE_AUTHENTICATION, AuthInfo)) + \
                   (OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData)) + \
                   sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256);
  NewData = (UINT8 *)AllocateZeroPool (DescriptorSize + PayloadSize);
  if (NewData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if ((Payload != NULL) && (PayloadSize != 0)) {
    CopyMem (NewData + DescriptorSize, Payload, PayloadSize);
  }

  DescriptorData = (EFI_VARIABLE_AUTHENTICATION *)(NewData);

  Status = gBS->GetNextMonotonicCount (&MonotonicCount);
  if (EFI_ERROR (Status)) {
    FreePool (NewData);
    return Status;
  }

  DescriptorData->MonotonicCount = MonotonicCount;

  DescriptorData->AuthInfo.Hdr.dwLength         = OFFSET_OF (WIN_CERTIFICATE_UEFI_GUID, CertData) + sizeof (EFI_CERT_BLOCK_RSA_2048_SHA256);
  DescriptorData->AuthInfo.Hdr.wRevision        = 0x0200;
  DescriptorData->AuthInfo.Hdr.wCertificateType = WIN_CERT_TYPE_EFI_GUID;
  CopyGuid (&DescriptorData->AuthInfo.CertType, &gEfiCertTypeRsa2048Sha256Guid);

  if (Payload != NULL) {
    FreePool (Payload);
  }

  *DataSize = DescriptorSize + PayloadSize;
  *Data     = NewData;
  return EFI_SUCCESS;
}

/**
  Delete user variable.

  @param[in] DeleteAll              Delete all user variables.
  @param[in] VariableCleanupData    Pointer to variable cleanup data.

**/
VOID
DeleteUserVariable (
  IN BOOLEAN                DeleteAll,
  IN VARIABLE_CLEANUP_DATA  *VariableCleanupData OPTIONAL
  )
{
  EFI_STATUS               Status;
  USER_VARIABLE_NODE       *UserVariableNode;
  LIST_ENTRY               *Link;
  USER_VARIABLE_NAME_NODE  *UserVariableNameNode;
  LIST_ENTRY               *NameLink;
  UINTN                    DataSize;
  UINT8                    *Data;

  for (Link = mUserVariableList.ForwardLink
       ; Link != &mUserVariableList
       ; Link = Link->ForwardLink)
  {
    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);

    for (NameLink = UserVariableNode->NameLink.ForwardLink
         ; NameLink != &UserVariableNode->NameLink
         ; NameLink = NameLink->ForwardLink)
    {
      UserVariableNameNode = USER_VARIABLE_NAME_FROM_LINK (NameLink);

      if (!UserVariableNameNode->Deleted && (DeleteAll || ((VariableCleanupData != NULL) && (VariableCleanupData->UserVariable[UserVariableNameNode->Index] == TRUE)))) {
        DEBUG ((DEBUG_INFO, "PlatformVarCleanup - Delete variable: %g:%s\n", &UserVariableNode->Guid, UserVariableNameNode->Name));
        if ((UserVariableNameNode->Attributes & EFI_VARIABLE_TIME_BASED_AUTHENTICATED_WRITE_ACCESS) != 0) {
          DataSize = 0;
          Data     = NULL;
          Status   = CreateTimeBasedPayload (&DataSize, &Data);
          if (!EFI_ERROR (Status)) {
            Status = gRT->SetVariable (UserVariableNameNode->Name, &UserVariableNode->Guid, UserVariableNameNode->Attributes, DataSize, Data);
            FreePool (Data);
          }
        } else if ((UserVariableNameNode->Attributes & EFI_VARIABLE_AUTHENTICATED_WRITE_ACCESS) != 0) {
          DataSize = 0;
          Data     = NULL;
          Status   = CreateCounterBasedPayload (&DataSize, &Data);
          if (!EFI_ERROR (Status)) {
            Status = gRT->SetVariable (UserVariableNameNode->Name, &UserVariableNode->Guid, UserVariableNameNode->Attributes, DataSize, Data);
            FreePool (Data);
          }
        } else {
          Status = gRT->SetVariable (UserVariableNameNode->Name, &UserVariableNode->Guid, 0, 0, NULL);
        }

        if (!EFI_ERROR (Status)) {
          UserVariableNameNode->Deleted = TRUE;
        } else {
          DEBUG ((DEBUG_INFO, "PlatformVarCleanup - Delete variable fail: %g:%s\n", &UserVariableNode->Guid, UserVariableNameNode->Name));
        }
      }
    }
  }
}

/**
  This function allows a caller to extract the current configuration for one
  or more named elements from the target driver.

  @param[in]  This          Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Request       A null-terminated Unicode string in <ConfigRequest> format.
  @param[out] Progress      On return, points to a character in the Request string.
                            Points to the string's null terminator if request was successful.
                            Points to the most recent '&' before the first failing name/value
                            pair (or the beginning of the string if the failure is in the
                            first name/value pair) if the request was not successful.
  @param[out] Results       A null-terminated Unicode string in <ConfigAltResp> format which
                            has all values filled in for the names in the Request string.
                            String to be allocated by the called function.

  @retval EFI_SUCCESS               The Results is filled with the requested values.
  @retval EFI_OUT_OF_RESOURCES      Not enough memory to store the results.
  @retval EFI_INVALID_PARAMETER     Request is illegal syntax, or unknown name.
  @retval EFI_NOT_FOUND             Routing data doesn't match any storage in this driver.

**/
EFI_STATUS
EFIAPI
VariableCleanupHiiExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Request,
  OUT EFI_STRING                            *Progress,
  OUT EFI_STRING                            *Results
  )
{
  EFI_STATUS                         Status;
  VARIABLE_CLEANUP_HII_PRIVATE_DATA  *Private;
  UINTN                              BufferSize;
  EFI_STRING                         ConfigRequestHdr;
  EFI_STRING                         ConfigRequest;
  BOOLEAN                            AllocatedRequest;
  UINTN                              Size;

  if ((Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mVariableCleanupHiiGuid, mVarStoreName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  Private = VARIABLE_CLEANUP_HII_PRIVATE_FROM_THIS (This);
  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig().
  //
  BufferSize    = sizeof (VARIABLE_CLEANUP_DATA);
  ConfigRequest = Request;
  if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
    //
    // Request has no request element, construct full request string.
    // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
    // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
    //
    ConfigRequestHdr = HiiConstructConfigHdr (
                         &mVariableCleanupHiiGuid,
                         mVarStoreName,
                         Private->DriverHandle
                         );
    Size          = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest = AllocateZeroPool (Size);
    ASSERT (ConfigRequest != NULL);
    AllocatedRequest = TRUE;
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
    FreePool (ConfigRequestHdr);
  }

  Status = Private->ConfigRouting->BlockToConfig (
                                     Private->ConfigRouting,
                                     ConfigRequest,
                                     (UINT8 *)&Private->VariableCleanupData,
                                     BufferSize,
                                     Results,
                                     Progress
                                     );
  ASSERT_EFI_ERROR (Status);

  //
  // Free the allocated config request string.
  //
  if (AllocatedRequest) {
    FreePool (ConfigRequest);
    ConfigRequest = NULL;
  }

  //
  // Set Progress string to the original request string or the string's null terminator.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return Status;
}

/**
  Update user variable form.

  @param[in] Private    Points to the VARIABLE_CLEANUP_HII_PRIVATE_DATA.

**/
VOID
UpdateUserVariableForm (
  IN VARIABLE_CLEANUP_HII_PRIVATE_DATA  *Private
  )
{
  EFI_STRING_ID            PromptStringToken;
  EFI_STRING_ID            HelpStringToken;
  VOID                     *StartOpCodeHandle;
  VOID                     *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL       *StartLabel;
  EFI_IFR_GUID_LABEL       *EndLabel;
  USER_VARIABLE_NODE       *UserVariableNode;
  LIST_ENTRY               *Link;
  USER_VARIABLE_NAME_NODE  *UserVariableNameNode;
  LIST_ENTRY               *NameLink;
  BOOLEAN                  Created;

  //
  // Init OpCode Handle.
  //
  StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (StartOpCodeHandle != NULL);

  EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  ASSERT (EndOpCodeHandle != NULL);

  //
  // Create Hii Extend Label OpCode as the start opcode.
  //
  StartLabel               = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  StartLabel->Number       = LABEL_START;

  //
  // Create Hii Extend Label OpCode as the end opcode.
  //
  EndLabel               = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
  EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  EndLabel->Number       = LABEL_END;

  HiiUpdateForm (
    Private->HiiHandle,
    &mVariableCleanupHiiGuid,
    FORM_ID_VARIABLE_CLEANUP,
    StartOpCodeHandle, // LABEL_START
    EndOpCodeHandle    // LABEL_END
    );

  for (Link = mUserVariableList.ForwardLink
       ; Link != &mUserVariableList
       ; Link = Link->ForwardLink)
  {
    UserVariableNode = USER_VARIABLE_FROM_LINK (Link);

    //
    // Create checkbox opcode for variables in the same variable GUID space.
    //
    Created = FALSE;
    for (NameLink = UserVariableNode->NameLink.ForwardLink
         ; NameLink != &UserVariableNode->NameLink
         ; NameLink = NameLink->ForwardLink)
    {
      UserVariableNameNode = USER_VARIABLE_NAME_FROM_LINK (NameLink);

      if (!UserVariableNameNode->Deleted) {
        if (!Created) {
          //
          // Create subtitle opcode for variable GUID.
          //
          PromptStringToken = HiiSetString (Private->HiiHandle, 0, UserVariableNode->PromptString, NULL);
          HiiCreateSubTitleOpCode (StartOpCodeHandle, PromptStringToken, 0, 0, 0);
          Created = TRUE;
        }

        //
        // Only create opcode for the non-deleted variables.
        //
        PromptStringToken = HiiSetString (Private->HiiHandle, 0, UserVariableNameNode->PromptString, NULL);
        HelpStringToken   = HiiSetString (Private->HiiHandle, 0, UserVariableNameNode->HelpString, NULL);
        HiiCreateCheckBoxOpCode (
          StartOpCodeHandle,
          UserVariableNameNode->QuestionId,
          VARIABLE_CLEANUP_VARSTORE_ID,
          (UINT16)(USER_VARIABLE_VAR_OFFSET + UserVariableNameNode->Index),
          PromptStringToken,
          HelpStringToken,
          EFI_IFR_FLAG_CALLBACK,
          Private->VariableCleanupData.UserVariable[UserVariableNameNode->Index],
          NULL
          );
      }
    }
  }

  HiiCreateSubTitleOpCode (
    StartOpCodeHandle,
    STRING_TOKEN (STR_NULL_STRING),
    0,
    0,
    0
    );

  //
  // Create the "Apply changes" and "Discard changes" tags.
  //
  HiiCreateActionOpCode (
    StartOpCodeHandle,
    SAVE_AND_EXIT_QUESTION_ID,
    STRING_TOKEN (STR_SAVE_AND_EXIT),
    STRING_TOKEN (STR_NULL_STRING),
    EFI_IFR_FLAG_CALLBACK,
    0
    );
  HiiCreateActionOpCode (
    StartOpCodeHandle,
    NO_SAVE_AND_EXIT_QUESTION_ID,
    STRING_TOKEN (STR_NO_SAVE_AND_EXIT),
    STRING_TOKEN (STR_NULL_STRING),
    EFI_IFR_FLAG_CALLBACK,
    0
    );

  HiiUpdateForm (
    Private->HiiHandle,
    &mVariableCleanupHiiGuid,
    FORM_ID_VARIABLE_CLEANUP,
    StartOpCodeHandle, // LABEL_START
    EndOpCodeHandle    // LABEL_END
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}

/**
  This function applies changes in a driver's configuration.
  Input is a Configuration, which has the routing data for this
  driver followed by name / value configuration pairs. The driver
  must apply those pairs to its configurable storage. If the
  driver's configuration is stored in a linear block of data
  and the driver's name / value pairs are in <BlockConfig>
  format, it may use the ConfigToBlock helper function (above) to
  simplify the job. Currently not implemented.

  @param[in]  This                  Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Configuration         A null-terminated Unicode string in
                                    <ConfigString> format.
  @param[out] Progress              A pointer to a string filled in with the
                                    offset of the most recent '&' before the
                                    first failing name / value pair (or the
                                    beginn ing of the string if the failure
                                    is in the first name / value pair) or
                                    the terminating NULL if all was
                                    successful.

  @retval EFI_SUCCESS               The results have been distributed or are
                                    awaiting distribution.
  @retval EFI_OUT_OF_RESOURCES      Not enough memory to store the
                                    parts of the results that must be
                                    stored awaiting possible future
                                    protocols.
  @retval EFI_INVALID_PARAMETERS    Passing in a NULL for the
                                    Results parameter would result
                                    in this type of error.
  @retval EFI_NOT_FOUND             Target for the specified routing data
                                    was not found.

**/
EFI_STATUS
EFIAPI
VariableCleanupHiiRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                            *Progress
  )
{
  EFI_STATUS                         Status;
  VARIABLE_CLEANUP_HII_PRIVATE_DATA  *Private;
  UINTN                              BufferSize;

  if (Progress == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Configuration;

  if (Configuration == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check routing data in <ConfigHdr>.
  // Note: there is no name for Name/Value storage, only GUID will be checked.
  //
  if (!HiiIsConfigHdrMatch (Configuration, &mVariableCleanupHiiGuid, mVarStoreName)) {
    return EFI_NOT_FOUND;
  }

  Private = VARIABLE_CLEANUP_HII_PRIVATE_FROM_THIS (This);
  //
  // Get Buffer Storage data.
  //
  BufferSize = sizeof (VARIABLE_CLEANUP_DATA);
  //
  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock().
  //
  Status = Private->ConfigRouting->ConfigToBlock (
                                     Private->ConfigRouting,
                                     Configuration,
                                     (UINT8 *)&Private->VariableCleanupData,
                                     &BufferSize,
                                     Progress
                                     );
  ASSERT_EFI_ERROR (Status);

  DeleteUserVariable (FALSE, &Private->VariableCleanupData);
  //
  // For "F10" hotkey to refresh the form.
  //
  //  UpdateUserVariableForm (Private);

  return EFI_SUCCESS;
}

/**
  This function is called to provide results data to the driver.
  This data consists of a unique key that is used to identify
  which data is either being passed back or being asked for.

  @param[in]  This                  Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Action                Specifies the type of action taken by the browser.
  @param[in]  QuestionId            A unique value which is sent to the original
                                    exporting driver so that it can identify the type
                                    of data to expect. The format of the data tends to
                                    vary based on the opcode that generated the callback.
  @param[in]  Type                  The type of value for the question.
  @param[in]  Value                 A pointer to the data being sent to the original
                                    exporting driver.
  @param[out] ActionRequest         On return, points to the action requested by the
                                    callback function.

  @retval EFI_SUCCESS               The callback successfully handled the action.
  @retval EFI_OUT_OF_RESOURCES      Not enough storage is available to hold the
                                    variable and its data.
  @retval EFI_DEVICE_ERROR          The variable could not be saved.
  @retval EFI_UNSUPPORTED           The specified Action is not supported by the
                                    callback.
**/
EFI_STATUS
EFIAPI
VariableCleanupHiiCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  EFI_BROWSER_ACTION                    Action,
  IN  EFI_QUESTION_ID                       QuestionId,
  IN  UINT8                                 Type,
  IN  EFI_IFR_TYPE_VALUE                    *Value,
  OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  VARIABLE_CLEANUP_HII_PRIVATE_DATA  *Private;
  VARIABLE_CLEANUP_DATA              *VariableCleanupData;

  Private = VARIABLE_CLEANUP_HII_PRIVATE_FROM_THIS (This);

  if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
    //
    // All other action return unsupported.
    //
    return EFI_UNSUPPORTED;
  }

  //
  // Retrieve uncommitted data from Form Browser.
  //
  VariableCleanupData = &Private->VariableCleanupData;
  HiiGetBrowserData (&mVariableCleanupHiiGuid, mVarStoreName, sizeof (VARIABLE_CLEANUP_DATA), (UINT8 *)VariableCleanupData);
  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    if (Value == NULL) {
      return EFI_INVALID_PARAMETER;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    if ((Value == NULL) || (ActionRequest == NULL)) {
      return EFI_INVALID_PARAMETER;
    }

    if ((QuestionId >= USER_VARIABLE_QUESTION_ID) && (QuestionId < USER_VARIABLE_QUESTION_ID + MAX_USER_VARIABLE_COUNT)) {
      if (Value->b) {
        //
        // Means one user variable checkbox is marked to delete but not press F10 or "Commit Changes and Exit" menu.
        //
        mMarkedUserVariableCount++;
        ASSERT (mMarkedUserVariableCount <= mUserVariableCount);
        if (mMarkedUserVariableCount == mUserVariableCount) {
          //
          // All user variables have been marked, then also mark the SelectAll checkbox.
          //
          VariableCleanupData->SelectAll = TRUE;
        }
      } else {
        //
        // Means one user variable checkbox is unmarked.
        //
        mMarkedUserVariableCount--;
        //
        // Also unmark the SelectAll checkbox.
        //
        VariableCleanupData->SelectAll = FALSE;
      }
    } else {
      switch (QuestionId) {
        case SELECT_ALL_QUESTION_ID:
          if (Value->b) {
            //
            // Means the SelectAll checkbox is marked to delete all user variables but not press F10 or "Commit Changes and Exit" menu.
            //
            SetMem (VariableCleanupData->UserVariable, sizeof (VariableCleanupData->UserVariable), TRUE);
            mMarkedUserVariableCount = mUserVariableCount;
          } else {
            //
            // Means the SelectAll checkbox is unmarked.
            //
            SetMem (VariableCleanupData->UserVariable, sizeof (VariableCleanupData->UserVariable), FALSE);
            mMarkedUserVariableCount = 0;
          }

          break;
        case SAVE_AND_EXIT_QUESTION_ID:
          DeleteUserVariable (FALSE, VariableCleanupData);
          *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
          break;

        case NO_SAVE_AND_EXIT_QUESTION_ID:
          //
          // Restore local maintain data.
          //
          *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
          break;

        default:
          break;
      }
    }
  }

  //
  // Pass changed uncommitted data back to Form Browser.
  //
  HiiSetBrowserData (&mVariableCleanupHiiGuid, mVarStoreName, sizeof (VARIABLE_CLEANUP_DATA), (UINT8 *)VariableCleanupData, NULL);
  return EFI_SUCCESS;
}

/**
  Platform variable cleanup.

  @param[in] Flag                   Variable error flag.
  @param[in] Type                   Variable cleanup type.
                                    If it is VarCleanupManually, the interface must be called after console connected.

  @retval EFI_SUCCESS               No error or error processed.
  @retval EFI_UNSUPPORTED           The specified Flag or Type is not supported.
                                    For example, system error may be not supported to process and Platform should have mechanism to reset system to manufacture mode.
                                    Another, if system and user variables are wanted to be distinguished to process, the interface must be called after EndOfDxe.
  @retval EFI_OUT_OF_RESOURCES      Not enough resource to process the error.
  @retval EFI_INVALID_PARAMETER     The specified Flag or Type is an invalid value.
  @retval Others                    Other failure occurs.

**/
EFI_STATUS
EFIAPI
PlatformVarCleanup (
  IN VAR_ERROR_FLAG    Flag,
  IN VAR_CLEANUP_TYPE  Type
  )
{
  EFI_STATUS                         Status;
  EFI_FORM_BROWSER2_PROTOCOL         *FormBrowser2;
  VARIABLE_CLEANUP_HII_PRIVATE_DATA  *Private;

  if (!mEndOfDxe) {
    //
    // This implementation must be called after EndOfDxe.
    //
    return EFI_UNSUPPORTED;
  }

  if ((Type >= VarCleanupMax) || ((Flag & ((VAR_ERROR_FLAG)(VAR_ERROR_FLAG_SYSTEM_ERROR & VAR_ERROR_FLAG_USER_ERROR))) == 0)) {
    return EFI_INVALID_PARAMETER;
  }

  if (Flag == VAR_ERROR_FLAG_NO_ERROR) {
    //
    // Just return success if no error.
    //
    return EFI_SUCCESS;
  }

  if ((Flag & (~((VAR_ERROR_FLAG)VAR_ERROR_FLAG_SYSTEM_ERROR))) == 0) {
    //
    // This sample does not support system variables cleanup.
    //
    DEBUG ((DEBUG_ERROR, "NOTICE - VAR_ERROR_FLAG_SYSTEM_ERROR\n"));
    DEBUG ((DEBUG_ERROR, "Platform should have mechanism to reset system to manufacture mode\n"));
    return EFI_UNSUPPORTED;
  }

  //
  // Continue to process VAR_ERROR_FLAG_USER_ERROR.
  //

  //
  // Create user variable nodes for the following processing.
  //
  CreateUserVariableNode ();

  switch (Type) {
    case VarCleanupAll:
      DeleteUserVariable (TRUE, NULL);
      //
      // Destroyed the created user variable nodes
      //
      DestroyUserVariableNode ();
      return EFI_SUCCESS;
      break;

    case VarCleanupManually:
      //
      // Locate FormBrowser2 protocol.
      //
      Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **)&FormBrowser2);
      if (EFI_ERROR (Status)) {
        return Status;
      }

      Private = AllocateZeroPool (sizeof (VARIABLE_CLEANUP_HII_PRIVATE_DATA));
      if (Private == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      Private->Signature                  = VARIABLE_CLEANUP_HII_PRIVATE_SIGNATURE;
      Private->ConfigAccess.ExtractConfig = VariableCleanupHiiExtractConfig;
      Private->ConfigAccess.RouteConfig   = VariableCleanupHiiRouteConfig;
      Private->ConfigAccess.Callback      = VariableCleanupHiiCallback;

      Status = gBS->LocateProtocol (
                      &gEfiHiiConfigRoutingProtocolGuid,
                      NULL,
                      (VOID **)&Private->ConfigRouting
                      );
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      //
      // Install Device Path Protocol and Config Access protocol to driver handle.
      //
      Status = gBS->InstallMultipleProtocolInterfaces (
                      &Private->DriverHandle,
                      &gEfiDevicePathProtocolGuid,
                      &mVarCleanupHiiVendorDevicePath,
                      &gEfiHiiConfigAccessProtocolGuid,
                      &Private->ConfigAccess,
                      NULL
                      );
      if (EFI_ERROR (Status)) {
        goto Done;
      }

      //
      // Publish our HII data.
      //
      Private->HiiHandle = HiiAddPackages (
                             &mVariableCleanupHiiGuid,
                             Private->DriverHandle,
                             PlatformVarCleanupLibStrings,
                             PlatVarCleanupBin,
                             NULL
                             );
      if (Private->HiiHandle == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Done;
      }

      UpdateUserVariableForm (Private);

      Status = FormBrowser2->SendForm (
                               FormBrowser2,
                               &Private->HiiHandle,
                               1,
                               NULL,
                               0,
                               NULL,
                               NULL
                               );
      break;

    default:
      return EFI_UNSUPPORTED;
      break;
  }

Done:
  if (Private->DriverHandle != NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           Private->DriverHandle,
           &gEfiDevicePathProtocolGuid,
           &mVarCleanupHiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &Private->ConfigAccess,
           NULL
           );
  }

  if (Private->HiiHandle != NULL) {
    HiiRemovePackages (Private->HiiHandle);
  }

  FreePool (Private);

  //
  // Destroyed the created user variable nodes
  //
  DestroyUserVariableNode ();
  return Status;
}

/**
  Get last boot variable error flag.

  @return   Last boot variable error flag.

**/
VAR_ERROR_FLAG
EFIAPI
GetLastBootVarErrorFlag (
  VOID
  )
{
  return mLastVarErrorFlag;
}

/**
  Notification function of END_OF_DXE.

  This is a notification function registered on END_OF_DXE event.

  @param[in] Event      Event whose notification function is being invoked.
  @param[in] Context    Pointer to the notification function's context.

**/
VOID
EFIAPI
PlatformVarCleanupEndOfDxeEvent (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  mEndOfDxe = TRUE;
}

/**
  The constructor function caches the pointer to VarCheck protocol and last boot variable error flag.

  The constructor function locates VarCheck protocol from protocol database.
  It will ASSERT() if that operation fails and it will always return EFI_SUCCESS.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The constructor always returns EFI_SUCCESS.

**/
EFI_STATUS
EFIAPI
PlatformVarCleanupLibConstructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  mLastVarErrorFlag = InternalGetVarErrorFlag ();
  DEBUG ((DEBUG_INFO, "mLastVarErrorFlag - 0x%02x\n", mLastVarErrorFlag));

  //
  // Register EFI_END_OF_DXE_EVENT_GROUP_GUID event.
  //
  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  PlatformVarCleanupEndOfDxeEvent,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &mPlatVarCleanupLibEndOfDxeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}

/**
  The destructor function closes the End of DXE event.

  @param  ImageHandle   The firmware allocated handle for the EFI image.
  @param  SystemTable   A pointer to the EFI System Table.

  @retval EFI_SUCCESS   The destructor completed successfully.

**/
EFI_STATUS
EFIAPI
PlatformVarCleanupLibDestructor (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS  Status;

  //
  // Close the End of DXE event.
  //
  Status = gBS->CloseEvent (mPlatVarCleanupLibEndOfDxeEvent);
  ASSERT_EFI_ERROR (Status);

  return EFI_SUCCESS;
}
