/** @file
  Implementation of the HII for the Opal UEFI Driver.

Copyright (c) 2016 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "OpalHii.h"
//
// Character definitions
//
#define UPPER_LOWER_CASE_OFFSET  0x20

//
// This is the generated IFR binary Data for each formset defined in VFR.
// This Data array is ready to be used as input of HiiAddPackages() to
// create a packagelist (which contains Form packages, String packages, etc).
//
extern UINT8  OpalPasswordFormBin[];

//
// This is the generated String package Data for all .UNI files.
// This Data array is ready to be used as input of HiiAddPackages() to
// create a packagelist (which contains Form packages, String packages, etc).
//
extern UINT8  OpalPasswordDxeStrings[];

CHAR16  OpalPasswordStorageName[] = L"OpalHiiConfig";

EFI_HII_CONFIG_ACCESS_PROTOCOL  gHiiConfigAccessProtocol;

//
// Handle to the list of HII packages (forms and strings) for this driver
//
EFI_HII_HANDLE  gHiiPackageListHandle = NULL;

//
// Package List GUID containing all form and string packages
//
const EFI_GUID  gHiiPackageListGuid   = PACKAGE_LIST_GUID;
const EFI_GUID  gHiiSetupVariableGuid = SETUP_VARIABLE_GUID;

//
// Structure that contains state of the HII
// This structure is updated by Hii.cpp and its contents
// is rendered in the HII.
//
OPAL_HII_CONFIGURATION  gHiiConfiguration;

//
// The device path containing the VENDOR_DEVICE_PATH and EFI_DEVICE_PATH_PROTOCOL
//
HII_VENDOR_DEVICE_PATH  gHiiVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    OPAL_PASSWORD_CONFIG_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

/**
  Get saved OPAL request.

  @param[in]  OpalDisk      The disk needs to get the saved OPAL request.
  @param[out] OpalRequest   OPAL request got.

**/
VOID
GetSavedOpalRequest (
  IN OPAL_DISK      *OpalDisk,
  OUT OPAL_REQUEST  *OpalRequest
  )
{
  EFI_STATUS                Status;
  OPAL_REQUEST_VARIABLE     *TempVariable;
  OPAL_REQUEST_VARIABLE     *Variable;
  UINTN                     VariableSize;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInVariable;
  UINTN                     DevicePathSizeInVariable;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     DevicePathSize;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  Variable     = NULL;
  VariableSize = 0;

  Status = GetVariable2 (
             OPAL_REQUEST_VARIABLE_NAME,
             &gHiiSetupVariableGuid,
             (VOID **)&Variable,
             &VariableSize
             );
  if (EFI_ERROR (Status) || (Variable == NULL)) {
    return;
  }

  TempVariable = Variable;
  while ((VariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
         (VariableSize >= TempVariable->Length) &&
         (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE)))
  {
    DevicePathInVariable     = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
    DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
    DevicePath               = OpalDisk->OpalDevicePath;
    DevicePathSize           = GetDevicePathSize (DevicePath);
    if ((DevicePathSize == DevicePathSizeInVariable) &&
        (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0))
    {
      //
      // Found the node for the OPAL device.
      // Get the OPAL request.
      //
      CopyMem (OpalRequest, &TempVariable->OpalRequest, sizeof (OPAL_REQUEST));
      DEBUG ((
        DEBUG_INFO,
        "OpalRequest got: 0x%x\n",
        *OpalRequest
        ));
      break;
    }

    VariableSize -= TempVariable->Length;
    TempVariable  = (OPAL_REQUEST_VARIABLE *)((UINTN)TempVariable + TempVariable->Length);
  }

  FreePool (Variable);

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
}

/**
  Save OPAL request.

  @param[in] OpalDisk       The disk has OPAL request to save.
  @param[in] OpalRequest    OPAL request to save.

**/
VOID
SaveOpalRequest (
  IN OPAL_DISK     *OpalDisk,
  IN OPAL_REQUEST  OpalRequest
  )
{
  EFI_STATUS                Status;
  OPAL_REQUEST_VARIABLE     *TempVariable;
  UINTN                     TempVariableSize;
  OPAL_REQUEST_VARIABLE     *Variable;
  UINTN                     VariableSize;
  OPAL_REQUEST_VARIABLE     *NewVariable;
  UINTN                     NewVariableSize;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInVariable;
  UINTN                     DevicePathSizeInVariable;
  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;
  UINTN                     DevicePathSize;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  DEBUG ((
    DEBUG_INFO,
    "OpalRequest to save: 0x%x\n",
    OpalRequest
    ));

  Variable        = NULL;
  VariableSize    = 0;
  NewVariable     = NULL;
  NewVariableSize = 0;

  Status = GetVariable2 (
             OPAL_REQUEST_VARIABLE_NAME,
             &gHiiSetupVariableGuid,
             (VOID **)&Variable,
             &VariableSize
             );
  if (!EFI_ERROR (Status) && (Variable != NULL)) {
    TempVariable     = Variable;
    TempVariableSize = VariableSize;
    while ((TempVariableSize > sizeof (OPAL_REQUEST_VARIABLE)) &&
           (TempVariableSize >= TempVariable->Length) &&
           (TempVariable->Length > sizeof (OPAL_REQUEST_VARIABLE)))
    {
      DevicePathInVariable     = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
      DevicePathSizeInVariable = GetDevicePathSize (DevicePathInVariable);
      DevicePath               = OpalDisk->OpalDevicePath;
      DevicePathSize           = GetDevicePathSize (DevicePath);
      if ((DevicePathSize == DevicePathSizeInVariable) &&
          (CompareMem (DevicePath, DevicePathInVariable, DevicePathSize) == 0))
      {
        //
        // Found the node for the OPAL device.
        // Update the OPAL request.
        //
        CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
        NewVariable     = Variable;
        NewVariableSize = VariableSize;
        break;
      }

      TempVariableSize -= TempVariable->Length;
      TempVariable      = (OPAL_REQUEST_VARIABLE *)((UINTN)TempVariable + TempVariable->Length);
    }

    if (NewVariable == NULL) {
      //
      // The node for the OPAL device is not found.
      // Create node for the OPAL device.
      //
      DevicePath      = OpalDisk->OpalDevicePath;
      DevicePathSize  = GetDevicePathSize (DevicePath);
      NewVariableSize = VariableSize + sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize;
      NewVariable     = AllocatePool (NewVariableSize);
      ASSERT (NewVariable != NULL);
      CopyMem (NewVariable, Variable, VariableSize);
      TempVariable         = (OPAL_REQUEST_VARIABLE *)((UINTN)NewVariable + VariableSize);
      TempVariable->Length = (UINT32)(sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize);
      CopyMem (&TempVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
      DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)TempVariable + sizeof (OPAL_REQUEST_VARIABLE));
      CopyMem (DevicePathInVariable, DevicePath, DevicePathSize);
    }
  } else {
    DevicePath      = OpalDisk->OpalDevicePath;
    DevicePathSize  = GetDevicePathSize (DevicePath);
    NewVariableSize = sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize;
    NewVariable     = AllocatePool (NewVariableSize);
    ASSERT (NewVariable != NULL);
    NewVariable->Length = (UINT32)(sizeof (OPAL_REQUEST_VARIABLE) + DevicePathSize);
    CopyMem (&NewVariable->OpalRequest, &OpalRequest, sizeof (OPAL_REQUEST));
    DevicePathInVariable = (EFI_DEVICE_PATH_PROTOCOL *)((UINTN)NewVariable + sizeof (OPAL_REQUEST_VARIABLE));
    CopyMem (DevicePathInVariable, DevicePath, DevicePathSize);
  }

  Status = gRT->SetVariable (
                  OPAL_REQUEST_VARIABLE_NAME,
                  (EFI_GUID *)&gHiiSetupVariableGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                  NewVariableSize,
                  NewVariable
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "OpalRequest variable set failed (%r)\n", Status));
  }

  if (NewVariable != Variable) {
    FreePool (NewVariable);
  }

  if (Variable != NULL) {
    FreePool (Variable);
  }

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
}

/**
  Sets the current system state of global config variables.

**/
VOID
HiiSetCurrentConfiguration (
  VOID
  )
{
  UINT32      PpStorageFlag;
  EFI_STRING  NewString;

  gHiiConfiguration.NumDisks = GetDeviceCount ();

  //
  // Update the BlockSID status string.
  //
  PpStorageFlag = Tcg2PhysicalPresenceLibGetManagementFlags ();

  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_ENABLE_BLOCK_SID) != 0) {
    NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN (STR_ENABLED), NULL);
    if (NewString == NULL) {
      DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
      return;
    }
  } else {
    NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN (STR_DISABLED), NULL);
    if (NewString == NULL) {
      DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
      return;
    }
  }

  HiiSetString (gHiiPackageListHandle, STRING_TOKEN (STR_BLOCKSID_STATUS1), NewString, NULL);
  FreePool (NewString);

  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_ENABLE_BLOCK_SID) != 0) {
    NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN (STR_DISK_INFO_ENABLE_BLOCKSID_TRUE), NULL);
    if (NewString == NULL) {
      DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
      return;
    }
  } else {
    NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN (STR_DISK_INFO_ENABLE_BLOCKSID_FALSE), NULL);
    if (NewString == NULL) {
      DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
      return;
    }
  }

  HiiSetString (gHiiPackageListHandle, STRING_TOKEN (STR_BLOCKSID_STATUS2), NewString, NULL);
  FreePool (NewString);

  if ((PpStorageFlag & TCG2_BIOS_STORAGE_MANAGEMENT_FLAG_PP_REQUIRED_FOR_DISABLE_BLOCK_SID) != 0) {
    NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN (STR_DISK_INFO_DISABLE_BLOCKSID_TRUE), NULL);
    if (NewString == NULL) {
      DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
      return;
    }
  } else {
    NewString = HiiGetString (gHiiPackageListHandle, STRING_TOKEN (STR_DISK_INFO_DISABLE_BLOCKSID_FALSE), NULL);
    if (NewString == NULL) {
      DEBUG ((DEBUG_INFO, "HiiSetCurrentConfiguration: HiiGetString( ) failed\n"));
      return;
    }
  }

  HiiSetString (gHiiPackageListHandle, STRING_TOKEN (STR_BLOCKSID_STATUS3), NewString, NULL);
  FreePool (NewString);
}

/**
  Install the HII related resources.

  @retval  EFI_SUCCESS        Install all the resources success.
  @retval  other              Error occur when install the resources.
**/
EFI_STATUS
HiiInstall (
  VOID
  )
{
  EFI_STATUS  Status;
  EFI_HANDLE  DriverHandle;

  //
  // Clear the global configuration.
  //
  ZeroMem (&gHiiConfiguration, sizeof (gHiiConfiguration));

  //
  // Obtain the driver handle that the BIOS assigned us
  //
  DriverHandle = HiiGetDriverImageHandleCB ();

  //
  // Populate the config access protocol with the three functions we are publishing
  //
  gHiiConfigAccessProtocol.ExtractConfig = ExtractConfig;
  gHiiConfigAccessProtocol.RouteConfig   = RouteConfig;
  gHiiConfigAccessProtocol.Callback      = DriverCallback;

  //
  // Associate the required protocols with our driver handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &DriverHandle,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &gHiiConfigAccessProtocol,   // HII callback
                  &gEfiDevicePathProtocolGuid,
                  &gHiiVendorDevicePath,     // required for HII callback allow all disks to be shown in same hii
                  NULL
                  );

  if (EFI_ERROR (Status)) {
    return Status;
  }

  return OpalHiiAddPackages ();
}

/**
  Install the HII form and string packages.

  @retval  EFI_SUCCESS           Install all the resources success.
  @retval  EFI_OUT_OF_RESOURCES  Out of resource error.
**/
EFI_STATUS
OpalHiiAddPackages (
  VOID
  )
{
  EFI_HANDLE  DriverHandle;

  DriverHandle = HiiGetDriverImageHandleCB ();

  //
  // Publish the HII form and HII string packages
  //
  gHiiPackageListHandle = HiiAddPackages (
                            &gHiiPackageListGuid,
                            DriverHandle,
                            OpalPasswordDxeStrings,
                            OpalPasswordFormBin,
                            (VOID *)NULL
                            );

  //
  // Make sure the packages installed successfully
  //
  if (gHiiPackageListHandle == NULL) {
    DEBUG ((DEBUG_INFO, "OpalHiiAddPackages failed\n"));
    return EFI_OUT_OF_RESOURCES;
  }

  return EFI_SUCCESS;
}

/**
  Uninstall the HII capability.

  @retval  EFI_SUCCESS           Uninstall all the resources success.
  @retval  others                Other errors occur when unistall the hii resource.
**/
EFI_STATUS
HiiUninstall (
  VOID
  )
{
  EFI_STATUS  Status;

  //
  // Remove the packages we've provided to the BIOS
  //
  HiiRemovePackages (gHiiPackageListHandle);

  //
  // Remove the protocols from our driver handle
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  HiiGetDriverImageHandleCB (),
                  &gEfiHiiConfigAccessProtocolGuid,
                  &gHiiConfigAccessProtocol,                // HII callback
                  &gEfiDevicePathProtocolGuid,
                  &gHiiVendorDevicePath,                    // required for HII callback
                  NULL
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "Cannot uninstall Hii Protocols: %r\n", Status));
  }

  return Status;
}

/**
  Updates the main menu form.

  @retval  EFI_SUCCESS           update the main form success.
**/
EFI_STATUS
HiiPopulateMainMenuForm (
  VOID
  )
{
  UINT8          Index;
  CHAR8          *DiskName;
  EFI_STRING_ID  DiskNameId;
  OPAL_DISK      *OpalDisk;

  HiiSetCurrentConfiguration ();

  gHiiConfiguration.SupportedDisks = 0;

  for (Index = 0; Index < gHiiConfiguration.NumDisks; Index++) {
    OpalDisk = HiiGetOpalDiskCB (Index);
    if ((OpalDisk != NULL) && OpalFeatureSupported (&OpalDisk->SupportedAttributes)) {
      gHiiConfiguration.SupportedDisks |= (1 << Index);
      DiskNameId                        = GetDiskNameStringId (Index);
      DiskName                          = HiiDiskGetNameCB (Index);
      if ((DiskName == NULL) || (DiskNameId == 0)) {
        return EFI_UNSUPPORTED;
      }

      HiiSetFormString (DiskNameId, DiskName);
    }
  }

  OpalHiiSetBrowserData ();
  return EFI_SUCCESS;
}

/**
  Get disk name string id.

  @param   DiskIndex             The input disk index info.

  @retval  The disk name string id.

**/
EFI_STRING_ID
GetDiskNameStringId (
  UINT8  DiskIndex
  )
{
  switch (DiskIndex) {
    case 0: return STRING_TOKEN (STR_MAIN_GOTO_DISK_INFO_0);
    case 1: return STRING_TOKEN (STR_MAIN_GOTO_DISK_INFO_1);
    case 2: return STRING_TOKEN (STR_MAIN_GOTO_DISK_INFO_2);
    case 3: return STRING_TOKEN (STR_MAIN_GOTO_DISK_INFO_3);
    case 4: return STRING_TOKEN (STR_MAIN_GOTO_DISK_INFO_4);
    case 5: return STRING_TOKEN (STR_MAIN_GOTO_DISK_INFO_5);
  }

  return 0;
}

/**
  Confirm whether user truly want to do the revert action.

  @param     OpalDisk            The device which need to perform data removal action.
  @param     ActionString        Specifies the action name shown on pop up menu.

  @retval  EFI_SUCCESS           Confirmed user want to do the revert action.
**/
EFI_STATUS
HiiConfirmDataRemovalAction (
  IN OPAL_DISK  *OpalDisk,
  IN CHAR16     *ActionString

  )
{
  CHAR16         Unicode[512];
  EFI_INPUT_KEY  Key;
  CHAR16         ApproveResponse;
  CHAR16         RejectResponse;

  //
  // When the estimate cost time bigger than MAX_ACCEPTABLE_REVERTING_TIME, pop up dialog to let user confirm
  // the revert action.
  //
  if (OpalDisk->EstimateTimeCost < MAX_ACCEPTABLE_REVERTING_TIME) {
    return EFI_SUCCESS;
  }

  ApproveResponse = L'Y';
  RejectResponse  = L'N';

  UnicodeSPrint (Unicode, StrSize (L"WARNING: ############# action needs about ####### seconds"), L"WARNING: %s action needs about %d seconds", ActionString, OpalDisk->EstimateTimeCost);

  do {
    CreatePopUp (
      EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
      &Key,
      Unicode,
      L" System should not be powered off until action completion ",
      L" ",
      L" Press 'Y/y' to continue, press 'N/n' to cancel ",
      NULL
      );
  } while (
           ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (ApproveResponse | UPPER_LOWER_CASE_OFFSET)) &&
           ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) != (RejectResponse | UPPER_LOWER_CASE_OFFSET))
           );

  if ((Key.UnicodeChar | UPPER_LOWER_CASE_OFFSET) == (RejectResponse | UPPER_LOWER_CASE_OFFSET)) {
    return EFI_ABORTED;
  }

  return EFI_SUCCESS;
}

/**
  This function processes the results of changes in configuration.

  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param  Action                 Specifies the type of action taken by the browser.
  @param  QuestionId             A unique value which is sent to the original
                                 exporting driver so that it can identify the type
                                 of data to expect.
  @param  Type                   The type of value for the question.
  @param  Value                  A pointer to the data being sent to the original
                                 exporting driver.
  @param  ActionRequest          On return, points to the action requested by the
                                 callback function.

  @retval EFI_SUCCESS            The callback successfully handled the action.
  @retval 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
DriverCallback (
  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  EFI_BROWSER_ACTION                    Action,
  EFI_QUESTION_ID                       QuestionId,
  UINT8                                 Type,
  EFI_IFR_TYPE_VALUE                    *Value,
  EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  HII_KEY    HiiKey;
  UINT8      HiiKeyId;
  UINT32     PpRequest;
  OPAL_DISK  *OpalDisk;

  if (ActionRequest != NULL) {
    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
  } else {
    return EFI_INVALID_PARAMETER;
  }

  //
  // If QuestionId is an auto-generated key (label, empty line, etc.), ignore it.
  //
  if ((QuestionId & HII_KEY_FLAG) == 0) {
    return EFI_SUCCESS;
  }

  HiiKey.Raw = QuestionId;
  HiiKeyId   = (UINT8)HiiKey.KeyBits.Id;

  if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
    switch (HiiKeyId) {
      case HII_KEY_ID_VAR_SUPPORTED_DISKS:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SUPPORTED_DISKS\n"));
        return HiiPopulateMainMenuForm ();

      case HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_VAR_SELECTED_DISK_AVAILABLE_ACTIONS\n"));
        return HiiPopulateDiskInfoForm ();
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGING) {
    switch (HiiKeyId) {
      case HII_KEY_ID_GOTO_DISK_INFO:
        return HiiSelectDisk ((UINT8)HiiKey.KeyBits.Index);

      case HII_KEY_ID_REVERT:
      case HII_KEY_ID_PSID_REVERT:
        OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          return HiiConfirmDataRemovalAction (OpalDisk, L"Revert");
        } else {
          ASSERT (FALSE);
          return EFI_SUCCESS;
        }

      case HII_KEY_ID_SECURE_ERASE:
        OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          return HiiConfirmDataRemovalAction (OpalDisk, L"Secure erase");
        } else {
          ASSERT (FALSE);
          return EFI_SUCCESS;
        }
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    switch (HiiKeyId) {
      case HII_KEY_ID_BLOCKSID:
        switch (Value->u8) {
          case 0:
            PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
            break;

          case 1:
            PpRequest = TCG2_PHYSICAL_PRESENCE_ENABLE_BLOCK_SID;
            break;

          case 2:
            PpRequest = TCG2_PHYSICAL_PRESENCE_DISABLE_BLOCK_SID;
            break;

          case 3:
            PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_TRUE;
            break;

          case 4:
            PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_ENABLE_BLOCK_SID_FUNC_FALSE;
            break;

          case 5:
            PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_TRUE;
            break;

          case 6:
            PpRequest = TCG2_PHYSICAL_PRESENCE_SET_PP_REQUIRED_FOR_DISABLE_BLOCK_SID_FUNC_FALSE;
            break;

          default:
            PpRequest = TCG2_PHYSICAL_PRESENCE_NO_ACTION;
            DEBUG ((DEBUG_ERROR, "Invalid value input!\n"));
            break;
        }

        HiiSetBlockSidAction (PpRequest);

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      case HII_KEY_ID_SET_ADMIN_PWD:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_ADMIN_PWD\n"));
        gHiiConfiguration.OpalRequest.SetAdminPwd = Value->b;
        OpalDisk                                  = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      case HII_KEY_ID_SET_USER_PWD:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_SET_USER_PWD\n"));
        gHiiConfiguration.OpalRequest.SetUserPwd = Value->b;
        OpalDisk                                 = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      case HII_KEY_ID_SECURE_ERASE:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_SECURE_ERASE\n"));
        gHiiConfiguration.OpalRequest.SecureErase = Value->b;
        OpalDisk                                  = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      case HII_KEY_ID_REVERT:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_REVERT\n"));
        gHiiConfiguration.OpalRequest.Revert = Value->b;
        OpalDisk                             = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;
      case HII_KEY_ID_KEEP_USER_DATA:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_KEEP_USER_DATA\n"));
        gHiiConfiguration.OpalRequest.KeepUserData = Value->b;
        OpalDisk                                   = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      case HII_KEY_ID_PSID_REVERT:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_PSID_REVERT\n"));
        gHiiConfiguration.OpalRequest.PsidRevert = Value->b;
        OpalDisk                                 = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      case HII_KEY_ID_DISABLE_USER:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_DISABLE_USER\n"));
        gHiiConfiguration.OpalRequest.DisableUser = Value->b;
        OpalDisk                                  = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      case HII_KEY_ID_ENABLE_FEATURE:
        DEBUG ((DEBUG_INFO, "HII_KEY_ID_ENABLE_FEATURE\n"));
        gHiiConfiguration.OpalRequest.EnableFeature = Value->b;
        OpalDisk                                    = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);
        if (OpalDisk != NULL) {
          SaveOpalRequest (OpalDisk, gHiiConfiguration.OpalRequest);
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        return EFI_SUCCESS;

      default:
        break;
    }
  }

  return EFI_UNSUPPORTED;
}

/**
  Update the global Disk index info.

  @param   Index             The input disk index info.

  @retval  EFI_SUCCESS       Update the disk index info success.

**/
EFI_STATUS
HiiSelectDisk (
  UINT8  Index
  )
{
  OpalHiiGetBrowserData ();
  gHiiConfiguration.SelectedDiskIndex = Index;
  OpalHiiSetBrowserData ();

  return EFI_SUCCESS;
}

/**
  Draws the disk info form.

  @retval  EFI_SUCCESS       Draw the disk info success.

**/
EFI_STATUS
HiiPopulateDiskInfoForm (
  VOID
  )
{
  OPAL_DISK          *OpalDisk;
  OPAL_DISK_ACTIONS  AvailActions;
  TCG_RESULT         Ret;
  CHAR8              *DiskName;

  OpalHiiGetBrowserData ();

  DiskName = HiiDiskGetNameCB (gHiiConfiguration.SelectedDiskIndex);
  if (DiskName == NULL) {
    return EFI_UNSUPPORTED;
  }

  HiiSetFormString (STRING_TOKEN (STR_DISK_INFO_SELECTED_DISK_NAME), DiskName);

  gHiiConfiguration.SelectedDiskAvailableActions = HII_ACTION_NONE;
  ZeroMem (&gHiiConfiguration.OpalRequest, sizeof (OPAL_REQUEST));
  gHiiConfiguration.KeepUserDataForced = FALSE;

  OpalDisk = HiiGetOpalDiskCB (gHiiConfiguration.SelectedDiskIndex);

  if (OpalDisk != NULL) {
    OpalDiskUpdateStatus (OpalDisk);
    Ret = OpalSupportGetAvailableActions (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature, OpalDisk->Owner, &AvailActions);
    if (Ret == TcgResultSuccess) {
      //
      // Update actions, always allow PSID Revert
      //
      gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.PsidRevert == 1) ? HII_ACTION_PSID_REVERT : HII_ACTION_NONE;

      //
      // Always allow unlock to handle device migration
      //
      gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Unlock == 1) ? HII_ACTION_UNLOCK : HII_ACTION_NONE;

      if (!OpalFeatureEnabled (&OpalDisk->SupportedAttributes, &OpalDisk->LockingFeature)) {
        if (OpalDisk->Owner == OpalOwnershipNobody) {
          gHiiConfiguration.SelectedDiskAvailableActions |= HII_ACTION_ENABLE_FEATURE;

          //
          // Update strings
          //
          HiiSetFormString (STRING_TOKEN (STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default");
        } else {
          DEBUG ((DEBUG_INFO, "Feature disabled but ownership != nobody\n"));
        }
      } else {
        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.Revert == 1) ? HII_ACTION_REVERT : HII_ACTION_NONE;
        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.AdminPass == 1) ? HII_ACTION_SET_ADMIN_PWD : HII_ACTION_NONE;
        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.UserPass == 1) ? HII_ACTION_SET_USER_PWD : HII_ACTION_NONE;
        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.SecureErase == 1) ? HII_ACTION_SECURE_ERASE : HII_ACTION_NONE;
        gHiiConfiguration.SelectedDiskAvailableActions |= (AvailActions.DisableUser == 1) ? HII_ACTION_DISABLE_USER : HII_ACTION_NONE;

        HiiSetFormString (STRING_TOKEN (STR_DISK_INFO_PSID_REVERT), "PSID Revert to factory default and Disable");

        //
        // Determine revert options for disk
        // Default initialize keep user Data to be true
        //
        gHiiConfiguration.OpalRequest.KeepUserData = 1;
        if (AvailActions.RevertKeepDataForced) {
          gHiiConfiguration.KeepUserDataForced = TRUE;
        }
      }
    }

    GetSavedOpalRequest (OpalDisk, &gHiiConfiguration.OpalRequest);
  }

  //
  // Pass the current configuration to the BIOS
  //
  OpalHiiSetBrowserData ();

  return EFI_SUCCESS;
}

/**
  Send BlockSid request through TPM physical presence module.

  @param   PpRequest         TPM physical presence operation request.

  @retval  EFI_SUCCESS       Do the required action success.
  @retval  Others            Other error occur.

**/
EFI_STATUS
HiiSetBlockSidAction (
  IN UINT32  PpRequest
  )
{
  UINT32      ReturnCode;
  EFI_STATUS  Status;

  ReturnCode = Tcg2PhysicalPresenceLibSubmitRequestToPreOSFunction (PpRequest, 0);
  if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_SUCCESS) {
    Status = EFI_SUCCESS;
  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_GENERAL_FAILURE) {
    Status = EFI_OUT_OF_RESOURCES;
  } else if (ReturnCode == TCG_PP_SUBMIT_REQUEST_TO_PREOS_NOT_IMPLEMENTED) {
    Status = EFI_UNSUPPORTED;
  } else {
    Status = EFI_DEVICE_ERROR;
  }

  return Status;
}

/**
  This function processes the results of changes in configuration.

  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param  Configuration          A null-terminated Unicode string in <ConfigResp>
                                 format.
  @param  Progress               A pointer to a string filled in with the offset of
                                 the most recent '&' before the first failing
                                 name/value pair (or the beginning of the string if
                                 the failure is in the first name/value pair) or
                                 the terminating NULL if all was successful.

  @retval EFI_SUCCESS            The Results is processed successfully.
  @retval EFI_INVALID_PARAMETER  Configuration is NULL.
  @retval EFI_NOT_FOUND          Routing data doesn't match any storage in this
                                 driver.

**/
EFI_STATUS
EFIAPI
RouteConfig (
  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  CONST EFI_STRING                      Configuration,
  EFI_STRING                            *Progress
  )
{
  if ((Configuration == NULL) || (Progress == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  *Progress = Configuration;
  if (!HiiIsConfigHdrMatch (Configuration, &gHiiSetupVariableGuid, OpalPasswordStorageName)) {
    return EFI_NOT_FOUND;
  }

  *Progress = Configuration + StrLen (Configuration);

  return EFI_SUCCESS;
}

/**
  This function allows a caller to extract the current configuration for one
  or more named elements from the target driver.

  @param  This                   Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param  Request                A null-terminated Unicode string in
                                 <ConfigRequest> format.
  @param  Progress               On return, points to a character in the Request
                                 string. Points to the string's null terminator if
                                 request was successful. Points to the most recent
                                 '&' before the first failing name/value pair (or
                                 the beginning of the string if the failure is in
                                 the first name/value pair) if the request was not
                                 successful.
  @param  Results                A null-terminated Unicode string in
                                 <ConfigAltResp> format which has all values filled
                                 in for the names in the Request string. String to
                                 be allocated by the called function.

  @retval EFI_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
ExtractConfig (
  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  CONST EFI_STRING                      Request,
  EFI_STRING                            *Progress,
  EFI_STRING                            *Results
  )
{
  EFI_STATUS  Status;
  EFI_STRING  ConfigRequest;
  EFI_STRING  ConfigRequestHdr;
  UINTN       BufferSize;
  UINTN       Size;
  BOOLEAN     AllocatedRequest;
  EFI_HANDLE  DriverHandle;

  //
  // Check for valid parameters
  //
  if ((Progress == NULL) || (Results == NULL)) {
    return (EFI_INVALID_PARAMETER);
  }

  *Progress = Request;
  if ((Request != NULL) &&
      !HiiIsConfigHdrMatch (Request, &gHiiSetupVariableGuid, OpalPasswordStorageName))
  {
    return EFI_NOT_FOUND;
  }

  AllocatedRequest = FALSE;
  BufferSize       = sizeof (OPAL_HII_CONFIGURATION);
  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
    //
    DriverHandle     = HiiGetDriverImageHandleCB ();
    ConfigRequestHdr = HiiConstructConfigHdr (&gHiiSetupVariableGuid, OpalPasswordStorageName, DriverHandle);
    Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest    = AllocateZeroPool (Size);
    if (ConfigRequest == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    AllocatedRequest = TRUE;
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
    FreePool (ConfigRequestHdr);
  }

  //
  // Convert Buffer Data to <ConfigResp> by helper function BlockToConfig( )
  //
  Status = gHiiConfigRouting->BlockToConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *)&gHiiConfiguration,
                                sizeof (OPAL_HII_CONFIGURATION),
                                Results,
                                Progress
                                );

  //
  // Free the allocated config request string.
  //
  if (AllocatedRequest) {
    FreePool (ConfigRequest);
    ConfigRequest = NULL;
  }

  //
  // Set Progress string to the original request string.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return (Status);
}

/**

  Pass the current system state to the bios via the hii_G_Configuration.

**/
VOID
OpalHiiSetBrowserData (
  VOID
  )
{
  HiiSetBrowserData (
    &gHiiSetupVariableGuid,
    (CHAR16 *)L"OpalHiiConfig",
    sizeof (gHiiConfiguration),
    (UINT8 *)&gHiiConfiguration,
    NULL
    );
}

/**

  Populate the hii_g_Configuration with the browser Data.

**/
VOID
OpalHiiGetBrowserData (
  VOID
  )
{
  HiiGetBrowserData (
    &gHiiSetupVariableGuid,
    (CHAR16 *)L"OpalHiiConfig",
    sizeof (gHiiConfiguration),
    (UINT8 *)&gHiiConfiguration
    );
}

/**
  Set a string Value in a form.

  @param      DestStringId   The stringid which need to update.
  @param      SrcAsciiStr    The string need to update.

  @retval  EFI_SUCCESS       Do the required action success.
  @retval  Others            Other error occur.

**/
EFI_STATUS
HiiSetFormString (
  EFI_STRING_ID  DestStringId,
  CHAR8          *SrcAsciiStr
  )
{
  UINT32  Len;
  UINT32  UniSize;
  CHAR16  *UniStr;

  //
  // Determine the Length of the sting
  //
  Len = (UINT32)AsciiStrLen (SrcAsciiStr);

  //
  // Allocate space for the unicode string, including terminator
  //
  UniSize = (Len + 1) * sizeof (CHAR16);
  UniStr  = (CHAR16 *)AllocateZeroPool (UniSize);

  //
  // Copy into unicode string, then copy into string id
  //
  AsciiStrToUnicodeStrS (SrcAsciiStr, UniStr, Len + 1);

  //
  // Update the string in the form
  //
  if (HiiSetString (gHiiPackageListHandle, DestStringId, UniStr, NULL) == 0) {
    DEBUG ((DEBUG_INFO, "HiiSetFormString( ) failed\n"));
    FreePool (UniStr);
    return (EFI_OUT_OF_RESOURCES);
  }

  //
  // Free the memory
  //
  FreePool (UniStr);

  return (EFI_SUCCESS);
}

/**
  Initialize the Opal disk base on the hardware info get from device.

  @param Dev                  The Opal device.

  @retval EFI_SUCCESS         Initialize the device success.
  @retval EFI_DEVICE_ERROR    Get info from device failed.

**/
EFI_STATUS
OpalDiskInitialize (
  IN OPAL_DRIVER_DEVICE  *Dev
  )
{
  TCG_RESULT    TcgResult;
  OPAL_SESSION  Session;
  UINT8         ActiveDataRemovalMechanism;
  UINT32        RemovalMechanishLists[ResearvedMechanism];

  ZeroMem (&Dev->OpalDisk, sizeof (OPAL_DISK));
  Dev->OpalDisk.Sscp           = Dev->Sscp;
  Dev->OpalDisk.MediaId        = Dev->MediaId;
  Dev->OpalDisk.OpalDevicePath = Dev->OpalDevicePath;

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp    = Dev->Sscp;
  Session.MediaId = Dev->MediaId;

  TcgResult = OpalGetSupportedAttributesInfo (&Session, &Dev->OpalDisk.SupportedAttributes, &Dev->OpalDisk.OpalBaseComId);
  if (TcgResult != TcgResultSuccess) {
    return EFI_DEVICE_ERROR;
  }

  Session.OpalBaseComId = Dev->OpalDisk.OpalBaseComId;

  TcgResult = OpalUtilGetMsid (&Session, Dev->OpalDisk.Msid, OPAL_MSID_LENGTH, &Dev->OpalDisk.MsidLength);
  if (TcgResult != TcgResultSuccess) {
    return EFI_DEVICE_ERROR;
  }

  if (Dev->OpalDisk.SupportedAttributes.DataRemoval) {
    TcgResult = OpalUtilGetDataRemovalMechanismLists (&Session, RemovalMechanishLists);
    if (TcgResult != TcgResultSuccess) {
      return EFI_DEVICE_ERROR;
    }

    TcgResult = OpalUtilGetActiveDataRemovalMechanism (&Session, Dev->OpalDisk.Msid, Dev->OpalDisk.MsidLength, &ActiveDataRemovalMechanism);
    if (TcgResult != TcgResultSuccess) {
      return EFI_DEVICE_ERROR;
    }

    Dev->OpalDisk.EstimateTimeCost = RemovalMechanishLists[ActiveDataRemovalMechanism];
  }

  return OpalDiskUpdateStatus (&Dev->OpalDisk);
}

/**
  Update the device ownship

  @param OpalDisk                The Opal device.

  @retval EFI_SUCCESS            Get ownership success.
  @retval EFI_ACCESS_DENIED      Has send BlockSID command, can't change ownership.
  @retval EFI_INVALID_PARAMETER  Not get Msid info before get ownership info.

**/
EFI_STATUS
OpalDiskUpdateOwnerShip (
  OPAL_DISK  *OpalDisk
  )
{
  OPAL_SESSION  Session;

  if (OpalDisk->MsidLength == 0) {
    return EFI_INVALID_PARAMETER;
  }

  if (OpalDisk->SentBlockSID) {
    return EFI_ACCESS_DENIED;
  }

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp          = OpalDisk->Sscp;
  Session.MediaId       = OpalDisk->MediaId;
  Session.OpalBaseComId = OpalDisk->OpalBaseComId;

  OpalDisk->Owner = OpalUtilDetermineOwnership (&Session, OpalDisk->Msid, OpalDisk->MsidLength);
  return EFI_SUCCESS;
}

/**
  Update the device info.

  @param OpalDisk                The Opal device.

  @retval EFI_SUCCESS            Initialize the device success.
  @retval EFI_DEVICE_ERROR       Get info from device failed.
  @retval EFI_INVALID_PARAMETER  Not get Msid info before get ownership info.
  @retval EFI_ACCESS_DENIED      Has send BlockSID command, can't change ownership.

**/
EFI_STATUS
OpalDiskUpdateStatus (
  OPAL_DISK  *OpalDisk
  )
{
  TCG_RESULT    TcgResult;
  OPAL_SESSION  Session;

  ZeroMem (&Session, sizeof (Session));
  Session.Sscp          = OpalDisk->Sscp;
  Session.MediaId       = OpalDisk->MediaId;
  Session.OpalBaseComId = OpalDisk->OpalBaseComId;

  TcgResult = OpalGetLockingInfo (&Session, &OpalDisk->LockingFeature);
  if (TcgResult != TcgResultSuccess) {
    return EFI_DEVICE_ERROR;
  }

  return OpalDiskUpdateOwnerShip (OpalDisk);
}
