/** @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", __FUNCTION__));

  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", __FUNCTION__));
}

/**
  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", __FUNCTION__));

  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", __FUNCTION__));
}

/**
  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);
}

