/** @file
  HDD password driver which is used to support HDD security feature.

  Copyright (c) 2019, Intel Corporation. All rights reserved.<BR>
  Copyright (c) Microsoft Corporation.<BR>

  SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "HddPasswordDxe.h"
#include <Library/VariablePolicyHelperLib.h>

EFI_GUID    mHddPasswordVendorGuid          = HDD_PASSWORD_CONFIG_GUID;
CHAR16      mHddPasswordVendorStorageName[] = L"HDD_PASSWORD_CONFIG";
LIST_ENTRY  mHddPasswordConfigFormList;
UINT32      mNumberOfHddDevices = 0;

EFI_GUID                       mHddPasswordDeviceInfoGuid      = HDD_PASSWORD_DEVICE_INFO_GUID;
BOOLEAN                        mHddPasswordEndOfDxe            = FALSE;
HDD_PASSWORD_REQUEST_VARIABLE  *mHddPasswordRequestVariable    = NULL;
UINTN                          mHddPasswordRequestVariableSize = 0;

HII_VENDOR_DEVICE_PATH  mHddPasswordHiiVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    HDD_PASSWORD_CONFIG_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

/**
  Check if the password is full zero.

  @param[in]   Password       Points to the data buffer

  @retval      TRUE           This password string is full zero.
  @retval      FALSE          This password string is not full zero.

**/
BOOLEAN
PasswordIsFullZero (
  IN CHAR8  *Password
  )
{
  UINTN  Index;

  for (Index = 0; Index < HDD_PASSWORD_MAX_LENGTH; Index++) {
    if (Password[Index] != 0) {
      return FALSE;
    }
  }

  return TRUE;
}

/**
  Save device info.

  @param[in]       ConfigFormEntry       Points to HDD_PASSWORD_CONFIG_FORM_ENTRY buffer
  @param[in,out]   TempDevInfo           Points to HDD_PASSWORD_DEVICE_INFO buffer

**/
VOID
SaveDeviceInfo (
  IN     HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry,
  IN OUT HDD_PASSWORD_DEVICE_INFO        *TempDevInfo
  )
{
  TempDevInfo->Device.Bus                = (UINT8)ConfigFormEntry->Bus;
  TempDevInfo->Device.Device             = (UINT8)ConfigFormEntry->Device;
  TempDevInfo->Device.Function           = (UINT8)ConfigFormEntry->Function;
  TempDevInfo->Device.Port               = ConfigFormEntry->Port;
  TempDevInfo->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
  CopyMem (TempDevInfo->Password, ConfigFormEntry->Password, HDD_PASSWORD_MAX_LENGTH);
  TempDevInfo->DevicePathLength = (UINT32)GetDevicePathSize (ConfigFormEntry->DevicePath);
  CopyMem (TempDevInfo->DevicePath, ConfigFormEntry->DevicePath, TempDevInfo->DevicePathLength);
}

/**
  Build HDD password device info and save them to LockBox.

 **/
VOID
BuildHddPasswordDeviceInfo (
  VOID
  )
{
  EFI_STATUS                      Status;
  LIST_ENTRY                      *Entry;
  HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry;
  HDD_PASSWORD_DEVICE_INFO        *DevInfo;
  HDD_PASSWORD_DEVICE_INFO        *TempDevInfo;
  UINTN                           DevInfoLength;
  UINT8                           DummyData;
  BOOLEAN                         S3InitDevicesExist;
  UINTN                           S3InitDevicesLength;
  EFI_DEVICE_PATH_PROTOCOL        *S3InitDevices;
  EFI_DEVICE_PATH_PROTOCOL        *S3InitDevicesBak;

  //
  // Build HDD password device info and save them to LockBox.
  //
  DevInfoLength = 0;
  BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
    ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);

    //
    // 1. Handle device which already set password.
    // 2. When request to send freeze command, driver also needs to handle device
    //    which support security feature.
    //
    if ((!PasswordIsFullZero (ConfigFormEntry->Password)) ||
        ((ConfigFormEntry->IfrData.SecurityStatus.Supported != 0) &&
         (ConfigFormEntry->IfrData.SecurityStatus.Enabled == 0)))
    {
      DevInfoLength += sizeof (HDD_PASSWORD_DEVICE_INFO) +
                       GetDevicePathSize (ConfigFormEntry->DevicePath);
    }
  }

  if (DevInfoLength == 0) {
    return;
  }

  S3InitDevicesLength = sizeof (DummyData);
  Status              = RestoreLockBox (
                          &gS3StorageDeviceInitListGuid,
                          &DummyData,
                          &S3InitDevicesLength
                          );
  ASSERT ((Status == EFI_NOT_FOUND) || (Status == EFI_BUFFER_TOO_SMALL));
  if (Status == EFI_NOT_FOUND) {
    S3InitDevices      = NULL;
    S3InitDevicesExist = FALSE;
  } else if (Status == EFI_BUFFER_TOO_SMALL) {
    S3InitDevices = AllocatePool (S3InitDevicesLength);
    ASSERT (S3InitDevices != NULL);

    Status = RestoreLockBox (
               &gS3StorageDeviceInitListGuid,
               S3InitDevices,
               &S3InitDevicesLength
               );
    ASSERT_EFI_ERROR (Status);
    S3InitDevicesExist = TRUE;
  } else {
    return;
  }

  DevInfo = AllocateZeroPool (DevInfoLength);
  ASSERT (DevInfo != NULL);

  TempDevInfo = DevInfo;
  BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
    ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);

    if ((!PasswordIsFullZero (ConfigFormEntry->Password)) ||
        ((ConfigFormEntry->IfrData.SecurityStatus.Supported != 0) &&
         (ConfigFormEntry->IfrData.SecurityStatus.Enabled == 0)))
    {
      SaveDeviceInfo (ConfigFormEntry, TempDevInfo);

      S3InitDevicesBak = S3InitDevices;
      S3InitDevices    = AppendDevicePathInstance (
                           S3InitDevicesBak,
                           ConfigFormEntry->DevicePath
                           );
      if (S3InitDevicesBak != NULL) {
        FreePool (S3InitDevicesBak);
      }

      ASSERT (S3InitDevices != NULL);

      TempDevInfo = (HDD_PASSWORD_DEVICE_INFO *)((UINTN)TempDevInfo +
                                                 sizeof (HDD_PASSWORD_DEVICE_INFO) +
                                                 TempDevInfo->DevicePathLength);
    }
  }

  Status = SaveLockBox (
             &mHddPasswordDeviceInfoGuid,
             DevInfo,
             DevInfoLength
             );
  ASSERT_EFI_ERROR (Status);

  Status = SetLockBoxAttributes (
             &mHddPasswordDeviceInfoGuid,
             LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
             );
  ASSERT_EFI_ERROR (Status);

  S3InitDevicesLength = GetDevicePathSize (S3InitDevices);
  if (S3InitDevicesExist) {
    Status = UpdateLockBox (
               &gS3StorageDeviceInitListGuid,
               0,
               S3InitDevices,
               S3InitDevicesLength
               );
    ASSERT_EFI_ERROR (Status);
  } else {
    Status = SaveLockBox (
               &gS3StorageDeviceInitListGuid,
               S3InitDevices,
               S3InitDevicesLength
               );
    ASSERT_EFI_ERROR (Status);

    Status = SetLockBoxAttributes (
               &gS3StorageDeviceInitListGuid,
               LOCK_BOX_ATTRIBUTE_RESTORE_IN_S3_ONLY
               );
    ASSERT_EFI_ERROR (Status);
  }

  ZeroMem (DevInfo, DevInfoLength);
  FreePool (DevInfo);
  FreePool (S3InitDevices);
}

/**
  Send freeze lock cmd through Ata Pass Thru Protocol.

  @param[in] AtaPassThru         The pointer to the ATA_PASS_THRU protocol.
  @param[in] Port                The port number of the ATA device to send the command.
  @param[in] PortMultiplierPort  The port multiplier port number of the ATA device to send the command.
                                 If there is no port multiplier, then specify 0xFFFF.

  @retval EFI_SUCCESS            Successful to send freeze lock cmd.
  @retval EFI_INVALID_PARAMETER  The parameter passed-in is invalid.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to send freeze lock cmd.
  @retval EFI_DEVICE_ERROR       Can not send freeze lock cmd.

**/
EFI_STATUS
FreezeLockDevice (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru,
  IN UINT16                      Port,
  IN UINT16                      PortMultiplierPort
  )
{
  EFI_STATUS                        Status;
  EFI_ATA_COMMAND_BLOCK             Acb;
  EFI_ATA_STATUS_BLOCK              *Asb;
  EFI_ATA_PASS_THRU_COMMAND_PACKET  Packet;

  if (AtaPassThru == NULL) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
  // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
  // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
  // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
  // may not be aligned when allocated on stack for some compilers. Hence, we
  // use the API AllocateAlignedPages to ensure this structure is properly
  // aligned.
  //
  Asb = AllocateAlignedPages (
          EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)),
          AtaPassThru->Mode->IoAlign
          );
  if (Asb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Prepare for ATA command block.
  //
  ZeroMem (&Acb, sizeof (Acb));
  ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
  Acb.AtaCommand    = ATA_SECURITY_FREEZE_LOCK_CMD;
  Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));

  //
  // Prepare for ATA pass through packet.
  //
  ZeroMem (&Packet, sizeof (Packet));
  Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_ATA_NON_DATA;
  Packet.Length   = EFI_ATA_PASS_THRU_LENGTH_NO_DATA_TRANSFER;
  Packet.Asb      = Asb;
  Packet.Acb      = &Acb;
  Packet.Timeout  = ATA_TIMEOUT;

  Status = AtaPassThru->PassThru (
                          AtaPassThru,
                          Port,
                          PortMultiplierPort,
                          &Packet,
                          NULL
                          );
  if (!EFI_ERROR (Status) &&
      ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
      ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
  {
    Status = EFI_DEVICE_ERROR;
  }

  FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));

  DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
  return Status;
}

/**
  Get attached harddisk identify data through Ata Pass Thru Protocol.

  @param[in] AtaPassThru         The pointer to the ATA_PASS_THRU protocol.
  @param[in] Port                The port number of the ATA device to send the command.
  @param[in] PortMultiplierPort  The port multiplier port number of the ATA device to send the command.
                                 If there is no port multiplier, then specify 0xFFFF.
  @param[in] IdentifyData        The buffer to store identify data.

  @retval EFI_SUCCESS            Successful to get identify data.
  @retval EFI_INVALID_PARAMETER  The parameter passed-in is invalid.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to get identify data.
  @retval EFI_DEVICE_ERROR       Can not get identify data.

**/
EFI_STATUS
GetHddDeviceIdentifyData (
  IN  EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru,
  IN  UINT16                      Port,
  IN  UINT16                      PortMultiplierPort,
  IN  ATA_IDENTIFY_DATA           *IdentifyData
  )
{
  EFI_STATUS                        Status;
  EFI_ATA_COMMAND_BLOCK             Acb;
  EFI_ATA_STATUS_BLOCK              *Asb;
  EFI_ATA_PASS_THRU_COMMAND_PACKET  Packet;

  if ((AtaPassThru == NULL) || (IdentifyData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
  // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
  // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
  // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
  // may not be aligned when allocated on stack for some compilers. Hence, we
  // use the API AllocateAlignedPages to ensure this structure is properly
  // aligned.
  //
  Asb = AllocateAlignedPages (
          EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)),
          AtaPassThru->Mode->IoAlign
          );
  if (Asb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Prepare for ATA command block.
  //
  ZeroMem (&Acb, sizeof (Acb));
  ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
  Acb.AtaCommand    = ATA_CMD_IDENTIFY_DRIVE;
  Acb.AtaDeviceHead = (UINT8)(BIT7 | BIT6 | BIT5 | (PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4)));

  //
  // Prepare for ATA pass through packet.
  //
  ZeroMem (&Packet, sizeof (Packet));
  Packet.Protocol         = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_IN;
  Packet.Length           = EFI_ATA_PASS_THRU_LENGTH_BYTES | EFI_ATA_PASS_THRU_LENGTH_SECTOR_COUNT;
  Packet.Asb              = Asb;
  Packet.Acb              = &Acb;
  Packet.InDataBuffer     = IdentifyData;
  Packet.InTransferLength = sizeof (ATA_IDENTIFY_DATA);
  Packet.Timeout          = ATA_TIMEOUT;

  Status = AtaPassThru->PassThru (
                          AtaPassThru,
                          Port,
                          PortMultiplierPort,
                          &Packet,
                          NULL
                          );

  FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));

  return Status;
}

/**
  Parse security status according to identify data.

  @param[in] IdentifyData        The buffer to store identify data.
  @param[in, out] IfrData        IFR data to hold security status.

**/
VOID
GetHddPasswordSecurityStatus (
  IN     ATA_IDENTIFY_DATA    *IdentifyData,
  IN OUT HDD_PASSWORD_CONFIG  *IfrData
  )
{
  IfrData->SecurityStatus.Supported            = (IdentifyData->command_set_supported_82 & BIT1) ? 1 : 0;
  IfrData->SecurityStatus.Enabled              = (IdentifyData->security_status & BIT1) ? 1 : 0;
  IfrData->SecurityStatus.Locked               = (IdentifyData->security_status & BIT2) ? 1 : 0;
  IfrData->SecurityStatus.Frozen               = (IdentifyData->security_status & BIT3) ? 1 : 0;
  IfrData->SecurityStatus.UserPasswordStatus   = IfrData->SecurityStatus.Enabled;
  IfrData->SecurityStatus.MasterPasswordStatus = IfrData->SecurityStatus.Supported;

  DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Supported            = %x\n", IfrData->SecurityStatus.Supported));
  DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Enabled              = %x\n", IfrData->SecurityStatus.Enabled));
  DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Locked               = %x\n", IfrData->SecurityStatus.Locked));
  DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.Frozen               = %x\n", IfrData->SecurityStatus.Frozen));
  DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.UserPasswordStatus   = %x\n", IfrData->SecurityStatus.UserPasswordStatus));
  DEBUG ((DEBUG_INFO, "IfrData->SecurityStatus.MasterPasswordStatus = %x\n", IfrData->SecurityStatus.MasterPasswordStatus));
}

/**
  Notification function of EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  This is a notification function registered on EFI_END_OF_DXE_EVENT_GROUP_GUID event group.

  @param  Event        Event whose notification function is being invoked.
  @param  Context      Pointer to the notification function's context.

**/
VOID
EFIAPI
HddPasswordEndOfDxeEventNotify (
  EFI_EVENT  Event,
  VOID       *Context
  )
{
  LIST_ENTRY                      *Entry;
  HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry;
  EFI_STATUS                      Status;
  ATA_IDENTIFY_DATA               IdentifyData;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  mHddPasswordEndOfDxe = TRUE;

  if (mHddPasswordRequestVariable != NULL) {
    //
    // Free the HDD password request variable buffer here
    // as the HDD password requests should have been processed.
    //
    FreePool (mHddPasswordRequestVariable);
    mHddPasswordRequestVariable     = NULL;
    mHddPasswordRequestVariableSize = 0;
  }

  //
  // If no any device, return directly.
  //
  if (IsListEmpty (&mHddPasswordConfigFormList)) {
    gBS->CloseEvent (Event);
    return;
  }

  BuildHddPasswordDeviceInfo ();

  //
  // Zero passsword and freeze lock device.
  //
  BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
    ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);

    ZeroMem (ConfigFormEntry->Password, HDD_PASSWORD_MAX_LENGTH);

    //
    // Check whether need send freeze lock command.
    // Below device will be froze:
    // 1. Device not enable password.
    // 2. Device enable password and unlocked.
    //
    if ((ConfigFormEntry->IfrData.SecurityStatus.Supported != 0) &&
        (ConfigFormEntry->IfrData.SecurityStatus.Locked == 0) &&
        (ConfigFormEntry->IfrData.SecurityStatus.Frozen == 0))
    {
      Status = FreezeLockDevice (ConfigFormEntry->AtaPassThru, ConfigFormEntry->Port, ConfigFormEntry->PortMultiplierPort);
      DEBUG ((DEBUG_INFO, "FreezeLockDevice return %r!\n", Status));
      Status = GetHddDeviceIdentifyData (
                 ConfigFormEntry->AtaPassThru,
                 ConfigFormEntry->Port,
                 ConfigFormEntry->PortMultiplierPort,
                 &IdentifyData
                 );
      GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);
    }
  }

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));

  gBS->CloseEvent (Event);
}

/**
  Generate Salt value.

  @param[in, out]   SaltValue           Points to the salt buffer, 32 bytes

**/
VOID
GenSalt (
  IN OUT UINT8  *SaltValue
  )
{
  RandomSeed (NULL, 0);
  RandomBytes (SaltValue, PASSWORD_SALT_SIZE);
}

/**
  Hash the data to get credential.

  @param[in]   Buffer         Points to the data buffer
  @param[in]   BufferSize     Buffer size
  @param[in]   SaltValue      Points to the salt buffer, 32 bytes
  @param[out]  Credential     Points to the hashed result

  @retval      TRUE           Hash the data successfully.
  @retval      FALSE          Failed to hash the data.

**/
BOOLEAN
GenerateCredential (
  IN      UINT8  *Buffer,
  IN      UINTN  BufferSize,
  IN      UINT8  *SaltValue,
  OUT  UINT8     *Credential
  )
{
  BOOLEAN  Status;
  UINTN    HashSize;
  VOID     *Hash;
  VOID     *HashData;

  Hash     = NULL;
  HashData = NULL;
  Status   = FALSE;

  HashSize = Sha256GetContextSize ();
  Hash     = AllocateZeroPool (HashSize);
  ASSERT (Hash != NULL);
  if (Hash == NULL) {
    goto Done;
  }

  Status = Sha256Init (Hash);
  if (!Status) {
    goto Done;
  }

  HashData = AllocateZeroPool (PASSWORD_SALT_SIZE + BufferSize);
  ASSERT (HashData != NULL);
  if (HashData == NULL) {
    goto Done;
  }

  CopyMem (HashData, SaltValue, PASSWORD_SALT_SIZE);
  CopyMem ((UINT8 *)HashData + PASSWORD_SALT_SIZE, Buffer, BufferSize);

  Status = Sha256Update (Hash, HashData, PASSWORD_SALT_SIZE + BufferSize);
  if (!Status) {
    goto Done;
  }

  Status = Sha256Final (Hash, Credential);

Done:
  if (Hash != NULL) {
    FreePool (Hash);
  }

  if (HashData != NULL) {
    ZeroMem (HashData, PASSWORD_SALT_SIZE + BufferSize);
    FreePool (HashData);
  }

  return Status;
}

/**
  Save HDD password variable that will be used to validate HDD password
  when the device is at frozen state.

  @param[in] ConfigFormEntry        The HDD Password configuration form entry.
  @param[in] Password               The hdd password of attached ATA device.

**/
VOID
SaveHddPasswordVariable (
  IN HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry,
  IN CHAR8                           *Password
  )
{
  EFI_STATUS             Status;
  HDD_PASSWORD_VARIABLE  *TempVariable;
  UINTN                  TempVariableSize;
  HDD_PASSWORD_VARIABLE  *NextNode;
  HDD_PASSWORD_VARIABLE  *Variable;
  UINTN                  VariableSize;
  HDD_PASSWORD_VARIABLE  *NewVariable;
  UINTN                  NewVariableSize;
  BOOLEAN                Delete;
  BOOLEAN                HashOk;
  UINT8                  HashData[SHA256_DIGEST_SIZE];
  UINT8                  SaltData[PASSWORD_SALT_SIZE];

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  Delete = FALSE;
  if (!PasswordIsFullZero (Password)) {
    //
    // It is Set/Update HDD Password.
    //
    ZeroMem (HashData, sizeof (HashData));
    ZeroMem (SaltData, sizeof (SaltData));
    GenSalt (SaltData);
    HashOk = GenerateCredential ((UINT8 *)Password, HDD_PASSWORD_MAX_LENGTH, SaltData, HashData);
    if (!HashOk) {
      DEBUG ((DEBUG_INFO, "GenerateCredential failed\n"));
      return;
    }
  } else {
    //
    // It is Disable HDD Password.
    // Go to delete the variable node for the HDD password device.
    //
    Delete = TRUE;
  }

  Variable        = NULL;
  VariableSize    = 0;
  NewVariable     = NULL;
  NewVariableSize = 0;

  Status = GetVariable2 (
             HDD_PASSWORD_VARIABLE_NAME,
             &mHddPasswordVendorGuid,
             (VOID **)&Variable,
             &VariableSize
             );
  if (Delete) {
    if (!EFI_ERROR (Status) && (Variable != NULL)) {
      TempVariable     = Variable;
      TempVariableSize = VariableSize;
      while (TempVariableSize >= sizeof (HDD_PASSWORD_VARIABLE)) {
        if ((TempVariable->Device.Bus                == ConfigFormEntry->Bus) &&
            (TempVariable->Device.Device             == ConfigFormEntry->Device) &&
            (TempVariable->Device.Function           == ConfigFormEntry->Function) &&
            (TempVariable->Device.Port               == ConfigFormEntry->Port) &&
            (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
        {
          //
          // Found the node for the HDD password device.
          // Delete the node.
          //
          NextNode = TempVariable + 1;
          CopyMem (TempVariable, NextNode, (UINTN)Variable + VariableSize - (UINTN)NextNode);
          NewVariable     = Variable;
          NewVariableSize = VariableSize - sizeof (HDD_PASSWORD_VARIABLE);
          break;
        }

        TempVariableSize -= sizeof (HDD_PASSWORD_VARIABLE);
        TempVariable     += 1;
      }

      if (NewVariable == NULL) {
        DEBUG ((DEBUG_INFO, "The variable node for the HDD password device is not found\n"));
      }
    } else {
      DEBUG ((DEBUG_INFO, "HddPassword variable get failed (%r)\n", Status));
    }
  } else {
    if (!EFI_ERROR (Status) && (Variable != NULL)) {
      TempVariable     = Variable;
      TempVariableSize = VariableSize;
      while (TempVariableSize >= sizeof (HDD_PASSWORD_VARIABLE)) {
        if ((TempVariable->Device.Bus                == ConfigFormEntry->Bus) &&
            (TempVariable->Device.Device             == ConfigFormEntry->Device) &&
            (TempVariable->Device.Function           == ConfigFormEntry->Function) &&
            (TempVariable->Device.Port               == ConfigFormEntry->Port) &&
            (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
        {
          //
          // Found the node for the HDD password device.
          // Update the node.
          //
          CopyMem (TempVariable->PasswordHash, HashData, sizeof (HashData));
          CopyMem (TempVariable->PasswordSalt, SaltData, sizeof (SaltData));
          NewVariable     = Variable;
          NewVariableSize = VariableSize;
          break;
        }

        TempVariableSize -= sizeof (HDD_PASSWORD_VARIABLE);
        TempVariable     += 1;
      }

      if (NewVariable == NULL) {
        //
        // The node for the HDD password device is not found.
        // Create node for the HDD password device.
        //
        NewVariableSize = VariableSize + sizeof (HDD_PASSWORD_VARIABLE);
        NewVariable     = AllocateZeroPool (NewVariableSize);
        ASSERT (NewVariable != NULL);
        CopyMem (NewVariable, Variable, VariableSize);
        TempVariable                            = (HDD_PASSWORD_VARIABLE *)((UINTN)NewVariable + VariableSize);
        TempVariable->Device.Bus                = (UINT8)ConfigFormEntry->Bus;
        TempVariable->Device.Device             = (UINT8)ConfigFormEntry->Device;
        TempVariable->Device.Function           = (UINT8)ConfigFormEntry->Function;
        TempVariable->Device.Port               = ConfigFormEntry->Port;
        TempVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
        CopyMem (TempVariable->PasswordHash, HashData, sizeof (HashData));
        CopyMem (TempVariable->PasswordSalt, SaltData, sizeof (SaltData));
      }
    } else {
      NewVariableSize = sizeof (HDD_PASSWORD_VARIABLE);
      NewVariable     = AllocateZeroPool (NewVariableSize);
      ASSERT (NewVariable != NULL);
      NewVariable->Device.Bus                = (UINT8)ConfigFormEntry->Bus;
      NewVariable->Device.Device             = (UINT8)ConfigFormEntry->Device;
      NewVariable->Device.Function           = (UINT8)ConfigFormEntry->Function;
      NewVariable->Device.Port               = ConfigFormEntry->Port;
      NewVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
      CopyMem (NewVariable->PasswordHash, HashData, sizeof (HashData));
      CopyMem (NewVariable->PasswordSalt, SaltData, sizeof (SaltData));
    }
  }

  if (NewVariable != NULL) {
    Status = gRT->SetVariable (
                    HDD_PASSWORD_VARIABLE_NAME,
                    &mHddPasswordVendorGuid,
                    EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                    NewVariableSize,
                    NewVariable
                    );
    if (EFI_ERROR (Status)) {
      DEBUG ((DEBUG_INFO, "HddPassword variable set failed (%r)\n", Status));
    }
  }

  if (NewVariable != Variable) {
    FreePool (NewVariable);
  }

  if (Variable != NULL) {
    FreePool (Variable);
  }

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
}

/**
  Get saved HDD password variable that will be used to validate HDD password
  when the device is at frozen state.

  @param[in]  ConfigFormEntry       The HDD Password configuration form entry.
  @param[out] HddPasswordVariable   The variable node for the HDD password device.

  @retval TRUE      The variable node for the HDD password device is found and returned.
  @retval FALSE     The variable node for the HDD password device is not found.

**/
BOOLEAN
GetSavedHddPasswordVariable (
  IN  HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry,
  OUT HDD_PASSWORD_VARIABLE           *HddPasswordVariable
  )
{
  EFI_STATUS             Status;
  HDD_PASSWORD_VARIABLE  *TempVariable;
  HDD_PASSWORD_VARIABLE  *Variable;
  UINTN                  VariableSize;
  BOOLEAN                Found;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  Variable     = NULL;
  VariableSize = 0;

  Status = GetVariable2 (
             HDD_PASSWORD_VARIABLE_NAME,
             &mHddPasswordVendorGuid,
             (VOID **)&Variable,
             &VariableSize
             );
  if (EFI_ERROR (Status) || (Variable == NULL)) {
    DEBUG ((DEBUG_INFO, "HddPassword variable get failed (%r)\n", Status));
    return FALSE;
  }

  Found        = FALSE;
  TempVariable = Variable;
  while (VariableSize >= sizeof (HDD_PASSWORD_VARIABLE)) {
    if ((TempVariable->Device.Bus                == ConfigFormEntry->Bus) &&
        (TempVariable->Device.Device             == ConfigFormEntry->Device) &&
        (TempVariable->Device.Function           == ConfigFormEntry->Function) &&
        (TempVariable->Device.Port               == ConfigFormEntry->Port) &&
        (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
    {
      //
      // Found the node for the HDD password device.
      // Get the node.
      //
      CopyMem (HddPasswordVariable, TempVariable, sizeof (HDD_PASSWORD_VARIABLE));
      Found = TRUE;
      break;
    }

    VariableSize -= sizeof (HDD_PASSWORD_VARIABLE);
    TempVariable += 1;
  }

  FreePool (Variable);

  if (!Found) {
    DEBUG ((DEBUG_INFO, "The variable node for the HDD password device is not found\n"));
  }

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));

  return Found;
}

/**
  Use saved HDD password variable to validate HDD password
  when the device is at frozen state.

  @param[in] ConfigFormEntry    The HDD Password configuration form entry.
  @param[in] Password           The hdd password of attached ATA device.

  @retval EFI_SUCCESS           Pass to validate the HDD password.
  @retval EFI_NOT_FOUND         The variable node for the HDD password device is not found.
  @retval EFI_DEVICE_ERROR      Failed to generate credential for the HDD password.
  @retval EFI_INVALID_PARAMETER Failed to validate the HDD password.

**/
EFI_STATUS
ValidateHddPassword (
  IN HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry,
  IN CHAR8                           *Password
  )
{
  EFI_STATUS             Status;
  HDD_PASSWORD_VARIABLE  HddPasswordVariable;
  BOOLEAN                HashOk;
  UINT8                  HashData[SHA256_DIGEST_SIZE];

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  if (!GetSavedHddPasswordVariable (ConfigFormEntry, &HddPasswordVariable)) {
    DEBUG ((DEBUG_INFO, "GetSavedHddPasswordVariable failed\n"));
    return EFI_NOT_FOUND;
  }

  ZeroMem (HashData, sizeof (HashData));
  HashOk = GenerateCredential ((UINT8 *)Password, HDD_PASSWORD_MAX_LENGTH, HddPasswordVariable.PasswordSalt, HashData);
  if (!HashOk) {
    DEBUG ((DEBUG_INFO, "GenerateCredential failed\n"));
    return EFI_DEVICE_ERROR;
  }

  if (CompareMem (HddPasswordVariable.PasswordHash, HashData, sizeof (HashData)) != 0) {
    Status = EFI_INVALID_PARAMETER;
  } else {
    Status = EFI_SUCCESS;
  }

  DEBUG ((DEBUG_INFO, "%a() - exit (%r)\n", __func__, Status));
  return Status;
}

/**
  Send unlock hdd password cmd through Ata Pass Thru Protocol.

  @param[in] AtaPassThru         The pointer to the ATA_PASS_THRU protocol.
  @param[in] Port                The port number of the ATA device to send the command.
  @param[in] PortMultiplierPort  The port multiplier port number of the ATA device to send the command.
                                 If there is no port multiplier, then specify 0xFFFF.
  @param[in] Identifier          The identifier to set user or master password.
  @param[in] Password            The hdd password of attached ATA device.

  @retval EFI_SUCCESS            Successful to send unlock hdd password cmd.
  @retval EFI_INVALID_PARAMETER  The parameter passed-in is invalid.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to send unlock hdd password cmd.
  @retval EFI_DEVICE_ERROR       Can not send unlock hdd password cmd.

**/
EFI_STATUS
UnlockHddPassword (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru,
  IN UINT16                      Port,
  IN UINT16                      PortMultiplierPort,
  IN CHAR8                       Identifier,
  IN CHAR8                       *Password
  )
{
  EFI_STATUS                        Status;
  EFI_ATA_COMMAND_BLOCK             Acb;
  EFI_ATA_STATUS_BLOCK              *Asb;
  EFI_ATA_PASS_THRU_COMMAND_PACKET  Packet;
  UINT8                             Buffer[HDD_PAYLOAD];

  if ((AtaPassThru == NULL) || (Password == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
  // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
  // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
  // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
  // may not be aligned when allocated on stack for some compilers. Hence, we
  // use the API AllocateAlignedPages to ensure this structure is properly
  // aligned.
  //
  Asb = AllocateAlignedPages (
          EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)),
          AtaPassThru->Mode->IoAlign
          );
  if (Asb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Prepare for ATA command block.
  //
  ZeroMem (&Acb, sizeof (Acb));
  ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
  Acb.AtaCommand    = ATA_SECURITY_UNLOCK_CMD;
  Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));

  //
  // Prepare for ATA pass through packet.
  //
  ZeroMem (&Packet, sizeof (Packet));
  Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT;
  Packet.Length   = EFI_ATA_PASS_THRU_LENGTH_BYTES;
  Packet.Asb      = Asb;
  Packet.Acb      = &Acb;

  ((CHAR16 *)Buffer)[0] = Identifier & BIT0;
  CopyMem (&((CHAR16 *)Buffer)[1], Password, HDD_PASSWORD_MAX_LENGTH);

  Packet.OutDataBuffer     = Buffer;
  Packet.OutTransferLength = sizeof (Buffer);
  Packet.Timeout           = ATA_TIMEOUT;

  Status = AtaPassThru->PassThru (
                          AtaPassThru,
                          Port,
                          PortMultiplierPort,
                          &Packet,
                          NULL
                          );
  if (!EFI_ERROR (Status) &&
      ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
      ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
  {
    Status = EFI_DEVICE_ERROR;
  }

  FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));

  ZeroMem (Buffer, sizeof (Buffer));

  DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
  return Status;
}

/**
  Send disable hdd password cmd through Ata Pass Thru Protocol.

  @param[in] AtaPassThru         The pointer to the ATA_PASS_THRU protocol.
  @param[in] Port                The port number of the ATA device to send the command.
  @param[in] PortMultiplierPort  The port multiplier port number of the ATA device to send the command.
                                 If there is no port multiplier, then specify 0xFFFF.
  @param[in] Identifier          The identifier to set user or master password.
  @param[in] Password            The hdd password of attached ATA device.

  @retval EFI_SUCCESS            Successful to disable hdd password cmd.
  @retval EFI_INVALID_PARAMETER  The parameter passed-in is invalid.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to disable hdd password cmd.
  @retval EFI_DEVICE_ERROR       Can not disable hdd password cmd.

**/
EFI_STATUS
DisableHddPassword (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru,
  IN UINT16                      Port,
  IN UINT16                      PortMultiplierPort,
  IN CHAR8                       Identifier,
  IN CHAR8                       *Password
  )
{
  EFI_STATUS                        Status;
  EFI_ATA_COMMAND_BLOCK             Acb;
  EFI_ATA_STATUS_BLOCK              *Asb;
  EFI_ATA_PASS_THRU_COMMAND_PACKET  Packet;
  UINT8                             Buffer[HDD_PAYLOAD];

  if ((AtaPassThru == NULL) || (Password == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
  // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
  // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
  // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
  // may not be aligned when allocated on stack for some compilers. Hence, we
  // use the API AllocateAlignedPages to ensure this structure is properly
  // aligned.
  //
  Asb = AllocateAlignedPages (
          EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)),
          AtaPassThru->Mode->IoAlign
          );
  if (Asb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Prepare for ATA command block.
  //
  ZeroMem (&Acb, sizeof (Acb));
  ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
  Acb.AtaCommand    = ATA_SECURITY_DIS_PASSWORD_CMD;
  Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));

  //
  // Prepare for ATA pass through packet.
  //
  ZeroMem (&Packet, sizeof (Packet));
  Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT;
  Packet.Length   = EFI_ATA_PASS_THRU_LENGTH_BYTES;
  Packet.Asb      = Asb;
  Packet.Acb      = &Acb;

  ((CHAR16 *)Buffer)[0] = Identifier & BIT0;
  CopyMem (&((CHAR16 *)Buffer)[1], Password, HDD_PASSWORD_MAX_LENGTH);

  Packet.OutDataBuffer     = Buffer;
  Packet.OutTransferLength = sizeof (Buffer);
  Packet.Timeout           = ATA_TIMEOUT;

  Status = AtaPassThru->PassThru (
                          AtaPassThru,
                          Port,
                          PortMultiplierPort,
                          &Packet,
                          NULL
                          );
  if (!EFI_ERROR (Status) &&
      ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
      ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
  {
    Status = EFI_DEVICE_ERROR;
  }

  FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));

  ZeroMem (Buffer, sizeof (Buffer));

  DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
  return Status;
}

/**
  Send set hdd password cmd through Ata Pass Thru Protocol.

  @param[in] AtaPassThru                The pointer to the ATA_PASS_THRU protocol.
  @param[in] Port                       The port number of the ATA device to send the command.
  @param[in] PortMultiplierPort         The port multiplier port number of the ATA device to send the command.
                                        If there is no port multiplier, then specify 0xFFFF.
  @param[in] Identifier                 The identifier to set user or master password.
  @param[in] SecurityLevel              The security level to be set to device.
  @param[in] MasterPasswordIdentifier   The master password identifier to be set to device.
  @param[in] Password                   The hdd password of attached ATA device.

  @retval EFI_SUCCESS            Successful to set hdd password cmd.
  @retval EFI_INVALID_PARAMETER  The parameter passed-in is invalid.
  @retval EFI_OUT_OF_RESOURCES   Not enough memory to set hdd password cmd.
  @retval EFI_DEVICE_ERROR       Can not set hdd password cmd.

**/
EFI_STATUS
SetHddPassword (
  IN EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru,
  IN UINT16                      Port,
  IN UINT16                      PortMultiplierPort,
  IN CHAR8                       Identifier,
  IN CHAR8                       SecurityLevel,
  IN CHAR16                      MasterPasswordIdentifier,
  IN CHAR8                       *Password
  )
{
  EFI_STATUS                        Status;
  EFI_ATA_COMMAND_BLOCK             Acb;
  EFI_ATA_STATUS_BLOCK              *Asb;
  EFI_ATA_PASS_THRU_COMMAND_PACKET  Packet;
  UINT8                             Buffer[HDD_PAYLOAD];

  if ((AtaPassThru == NULL) || (Password == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // The 'Asb' field (a pointer to the EFI_ATA_STATUS_BLOCK structure) in
  // EFI_ATA_PASS_THRU_COMMAND_PACKET is required to be aligned specified by
  // the 'IoAlign' field in the EFI_ATA_PASS_THRU_MODE structure. Meanwhile,
  // the structure EFI_ATA_STATUS_BLOCK is composed of only UINT8 fields, so it
  // may not be aligned when allocated on stack for some compilers. Hence, we
  // use the API AllocateAlignedPages to ensure this structure is properly
  // aligned.
  //
  Asb = AllocateAlignedPages (
          EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)),
          AtaPassThru->Mode->IoAlign
          );
  if (Asb == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Prepare for ATA command block.
  //
  ZeroMem (&Acb, sizeof (Acb));
  ZeroMem (Asb, sizeof (EFI_ATA_STATUS_BLOCK));
  Acb.AtaCommand    = ATA_SECURITY_SET_PASSWORD_CMD;
  Acb.AtaDeviceHead = (UINT8)(PortMultiplierPort == 0xFFFF ? 0 : (PortMultiplierPort << 4));

  //
  // Prepare for ATA pass through packet.
  //
  ZeroMem (&Packet, sizeof (Packet));
  Packet.Protocol = EFI_ATA_PASS_THRU_PROTOCOL_PIO_DATA_OUT;
  Packet.Length   = EFI_ATA_PASS_THRU_LENGTH_BYTES;
  Packet.Asb      = Asb;
  Packet.Acb      = &Acb;

  ((CHAR16 *)Buffer)[0] = (Identifier | (UINT16)(SecurityLevel << 8)) & (BIT0 | BIT8);
  CopyMem (&((CHAR16 *)Buffer)[1], Password, HDD_PASSWORD_MAX_LENGTH);
  if ((Identifier & BIT0) != 0) {
    ((CHAR16 *)Buffer)[17] = MasterPasswordIdentifier;
  }

  Packet.OutDataBuffer     = Buffer;
  Packet.OutTransferLength = sizeof (Buffer);
  Packet.Timeout           = ATA_TIMEOUT;

  Status = AtaPassThru->PassThru (
                          AtaPassThru,
                          Port,
                          PortMultiplierPort,
                          &Packet,
                          NULL
                          );
  if (!EFI_ERROR (Status) &&
      ((Asb->AtaStatus & ATA_STSREG_ERR) != 0) &&
      ((Asb->AtaError & ATA_ERRREG_ABRT) != 0))
  {
    Status = EFI_DEVICE_ERROR;
  }

  FreeAlignedPages (Asb, EFI_SIZE_TO_PAGES (sizeof (EFI_ATA_STATUS_BLOCK)));

  ZeroMem (Buffer, sizeof (Buffer));

  DEBUG ((DEBUG_INFO, "%a() - %r\n", __func__, Status));
  return Status;
}

/**
  Get attached harddisk model number from identify data buffer.

  @param[in] IdentifyData    Pointer to identify data buffer.
  @param[in, out] String     The buffer to store harddisk model number.

**/
VOID
GetHddDeviceModelNumber (
  IN ATA_IDENTIFY_DATA  *IdentifyData,
  IN OUT CHAR16         *String
  )
{
  UINTN  Index;

  //
  // Swap the byte order in the original module name.
  // From Ata spec, the maximum length is 40 bytes.
  //
  for (Index = 0; Index < 40; Index += 2) {
    String[Index]     = IdentifyData->ModelName[Index + 1];
    String[Index + 1] = IdentifyData->ModelName[Index];
  }

  //
  // Chap it off after 20 characters
  //
  String[20] = L'\0';

  return;
}

/**
  Get password input from the popup windows.

  @param[in]      PopUpString1  Pop up string 1.
  @param[in]      PopUpString2  Pop up string 2.
  @param[in, out] Password      The buffer to hold the input password.

  @retval EFI_ABORTED           It is given up by pressing 'ESC' key.
  @retval EFI_SUCCESS           Get password input successfully.

**/
EFI_STATUS
PopupHddPasswordInputWindows (
  IN CHAR16     *PopUpString1,
  IN CHAR16     *PopUpString2,
  IN OUT CHAR8  *Password
  )
{
  EFI_INPUT_KEY  Key;
  UINTN          Length;
  CHAR16         Mask[HDD_PASSWORD_MAX_LENGTH + 1];
  CHAR16         Unicode[HDD_PASSWORD_MAX_LENGTH + 1];
  CHAR8          Ascii[HDD_PASSWORD_MAX_LENGTH + 1];

  ZeroMem (Unicode, sizeof (Unicode));
  ZeroMem (Ascii, sizeof (Ascii));
  ZeroMem (Mask, sizeof (Mask));

  gST->ConOut->ClearScreen (gST->ConOut);

  Length = 0;
  while (TRUE) {
    Mask[Length] = L'_';
    if (PopUpString2 == NULL) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        PopUpString1,
        L"---------------------",
        Mask,
        NULL
        );
    } else {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        PopUpString1,
        PopUpString2,
        L"---------------------",
        Mask,
        NULL
        );
    }

    //
    // Check key.
    //
    if (Key.ScanCode == SCAN_NULL) {
      if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
        //
        // Add the null terminator.
        //
        Unicode[Length] = 0;
        break;
      } else if ((Key.UnicodeChar == CHAR_NULL) ||
                 (Key.UnicodeChar == CHAR_TAB) ||
                 (Key.UnicodeChar == CHAR_LINEFEED)
                 )
      {
        continue;
      } else {
        if (Key.UnicodeChar == CHAR_BACKSPACE) {
          if (Length > 0) {
            Unicode[Length] = 0;
            Mask[Length]    = 0;
            Length--;
          }
        } else {
          Unicode[Length] = Key.UnicodeChar;
          Mask[Length]    = L'*';
          Length++;
          if (Length == HDD_PASSWORD_MAX_LENGTH) {
            //
            // Add the null terminator.
            //
            Unicode[Length] = 0;
            Mask[Length]    = 0;
            break;
          }
        }
      }
    }

    if (Key.ScanCode == SCAN_ESC) {
      ZeroMem (Unicode, sizeof (Unicode));
      ZeroMem (Ascii, sizeof (Ascii));
      gST->ConOut->ClearScreen (gST->ConOut);
      return EFI_ABORTED;
    }
  }

  UnicodeStrToAsciiStrS (Unicode, Ascii, sizeof (Ascii));
  CopyMem (Password, Ascii, HDD_PASSWORD_MAX_LENGTH);
  ZeroMem (Unicode, sizeof (Unicode));
  ZeroMem (Ascii, sizeof (Ascii));

  gST->ConOut->ClearScreen (gST->ConOut);
  return EFI_SUCCESS;
}

/**
  Check if disk is locked, show popup window and ask for password if it is.

  @param[in] AtaPassThru            Pointer to ATA_PASSTHRU instance.
  @param[in] Port                   The port number of attached ATA device.
  @param[in] PortMultiplierPort     The port number of port multiplier of attached ATA device.
  @param[in] ConfigFormEntry        The HDD Password configuration form entry.

**/
VOID
HddPasswordRequestPassword (
  IN EFI_ATA_PASS_THRU_PROTOCOL      *AtaPassThru,
  IN UINT16                          Port,
  IN UINT16                          PortMultiplierPort,
  IN HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry
  )
{
  EFI_STATUS         Status;
  CHAR16             PopUpString[100];
  ATA_IDENTIFY_DATA  IdentifyData;
  EFI_INPUT_KEY      Key;
  UINT16             RetryCount;
  CHAR8              Password[HDD_PASSWORD_MAX_LENGTH];

  RetryCount = 0;

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Unlock: %s", ConfigFormEntry->HddString);

  //
  // Check the device security status.
  //
  if ((ConfigFormEntry->IfrData.SecurityStatus.Supported) &&
      (ConfigFormEntry->IfrData.SecurityStatus.Enabled))
  {
    //
    // Add PcdSkipHddPasswordPrompt to determin whether to skip password prompt.
    // Due to board design, device may not power off during system warm boot, which result in
    // security status remain unlocked status, hence we add device security status check here.
    //
    // If device is in the locked status, device keeps locked and system continues booting.
    // If device is in the unlocked status, system is forced shutdown for security concern.
    //
    if (PcdGetBool (PcdSkipHddPasswordPrompt)) {
      if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
        return;
      } else {
        gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
      }
    }

    //
    // As soon as the HDD password is in enabled state, we pop up a window to unlock hdd
    // no matter it's really in locked or unlocked state.
    // This way forces user to enter password every time to provide best safety.
    //
    while (TRUE) {
      Status = PopupHddPasswordInputWindows (PopUpString, NULL, Password);
      if (!EFI_ERROR (Status)) {
        //
        // The HDD is in locked state, unlock it by user input.
        //
        if (!PasswordIsFullZero (Password)) {
          if (!ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
            Status = UnlockHddPassword (AtaPassThru, Port, PortMultiplierPort, 0, Password);
          } else {
            //
            // Use saved HDD password variable to validate HDD password
            // when the device is at frozen state.
            //
            Status = ValidateHddPassword (ConfigFormEntry, Password);
          }
        } else {
          Status = EFI_INVALID_PARAMETER;
        }

        if (!EFI_ERROR (Status)) {
          CopyMem (ConfigFormEntry->Password, Password, HDD_PASSWORD_MAX_LENGTH);
          if (!ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
            SaveHddPasswordVariable (ConfigFormEntry, Password);
          }

          ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
          Status = GetHddDeviceIdentifyData (AtaPassThru, Port, PortMultiplierPort, &IdentifyData);
          ASSERT_EFI_ERROR (Status);

          //
          // Check the device security status again.
          //
          GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);
          return;
        }

        ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);

        if (EFI_ERROR (Status)) {
          RetryCount++;
          if (RetryCount < MAX_HDD_PASSWORD_RETRY_COUNT) {
            do {
              CreatePopUp (
                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                &Key,
                L"Invalid password.",
                L"Press ENTER to retry",
                NULL
                );
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            continue;
          } else {
            do {
              CreatePopUp (
                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                &Key,
                L"Hdd password retry count is expired. Please shutdown the machine.",
                L"Press ENTER to shutdown",
                NULL
                );
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
            break;
          }
        }
      } else if (Status == EFI_ABORTED) {
        if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
          //
          // Current device in the lock status and
          // User not input password and press ESC,
          // keep device in lock status and continue boot.
          //
          do {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"Press ENTER to skip the request and continue boot,",
              L"Press ESC to input password again",
              NULL
              );
          } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

          if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
            gST->ConOut->ClearScreen (gST->ConOut);
            //
            // Keep lock and continue boot.
            //
            return;
          } else {
            //
            // Let user input password again.
            //
            continue;
          }
        } else {
          //
          // Current device in the unlock status and
          // User not input password and press ESC,
          // Shutdown the device.
          //
          do {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"Press ENTER to shutdown, Press ESC to input password again",
              NULL
              );
          } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

          if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
            gRT->ResetSystem (EfiResetShutdown, EFI_SUCCESS, 0, NULL);
          } else {
            //
            // Let user input password again.
            //
            continue;
          }
        }
      }
    }
  }
}

/**
  Process Set User Pwd HDD password request.

  @param[in] AtaPassThru            Pointer to ATA_PASSTHRU instance.
  @param[in] Port                   The port number of attached ATA device.
  @param[in] PortMultiplierPort     The port number of port multiplier of attached ATA device.
  @param[in] ConfigFormEntry        The HDD Password configuration form entry.

**/
VOID
ProcessHddPasswordRequestSetUserPwd (
  IN EFI_ATA_PASS_THRU_PROTOCOL      *AtaPassThru,
  IN UINT16                          Port,
  IN UINT16                          PortMultiplierPort,
  IN HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry
  )
{
  EFI_STATUS         Status;
  CHAR16             PopUpString[100];
  ATA_IDENTIFY_DATA  IdentifyData;
  EFI_INPUT_KEY      Key;
  UINT16             RetryCount;
  CHAR8              Password[HDD_PASSWORD_MAX_LENGTH];
  CHAR8              PasswordConfirm[HDD_PASSWORD_MAX_LENGTH];

  RetryCount = 0;

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  if (ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
    DEBUG ((DEBUG_INFO, "%s is frozen, do nothing\n", ConfigFormEntry->HddString));
    return;
  }

  if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
    DEBUG ((DEBUG_INFO, "%s is locked, do nothing\n", ConfigFormEntry->HddString));
    return;
  }

  UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Set User Pwd: %s", ConfigFormEntry->HddString);

  //
  // Check the device security status.
  //
  if (ConfigFormEntry->IfrData.SecurityStatus.Supported) {
    while (TRUE) {
      Status = PopupHddPasswordInputWindows (PopUpString, L"Please type in your new password", Password);
      if (!EFI_ERROR (Status)) {
        Status = PopupHddPasswordInputWindows (PopUpString, L"Please confirm your new password", PasswordConfirm);
        if (!EFI_ERROR (Status)) {
          if (CompareMem (Password, PasswordConfirm, HDD_PASSWORD_MAX_LENGTH) == 0) {
            if (!PasswordIsFullZero (Password)) {
              Status = SetHddPassword (AtaPassThru, Port, PortMultiplierPort, 0, 1, 0, Password);
            } else {
              if (ConfigFormEntry->IfrData.SecurityStatus.Enabled) {
                Status = DisableHddPassword (AtaPassThru, Port, PortMultiplierPort, 0, ConfigFormEntry->Password);
              } else {
                Status = EFI_INVALID_PARAMETER;
              }
            }

            if (!EFI_ERROR (Status)) {
              CopyMem (ConfigFormEntry->Password, Password, HDD_PASSWORD_MAX_LENGTH);
              SaveHddPasswordVariable (ConfigFormEntry, Password);
              ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
              ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);
              Status = GetHddDeviceIdentifyData (AtaPassThru, Port, PortMultiplierPort, &IdentifyData);
              ASSERT_EFI_ERROR (Status);

              //
              // Check the device security status again.
              //
              GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);
              return;
            } else {
              do {
                CreatePopUp (
                  EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                  &Key,
                  L"Set/Disable User Pwd failed or invalid password.",
                  L"Press ENTER to retry",
                  NULL
                  );
              } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
            }
          } else {
            do {
              CreatePopUp (
                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                &Key,
                L"Passwords are not the same.",
                L"Press ENTER to retry",
                NULL
                );
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            Status = EFI_INVALID_PARAMETER;
          }
        }

        ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
        ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);

        if (EFI_ERROR (Status)) {
          RetryCount++;
          if (RetryCount >= MAX_HDD_PASSWORD_RETRY_COUNT) {
            do {
              CreatePopUp (
                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                &Key,
                L"Hdd password retry count is expired.",
                L"Press ENTER to skip the request and continue boot",
                NULL
                );
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            gST->ConOut->ClearScreen (gST->ConOut);
            return;
          }
        }
      } else if (Status == EFI_ABORTED) {
        do {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Press ENTER to skip the request and continue boot,",
            L"Press ESC to input password again",
            NULL
            );
        } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

        if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
          gST->ConOut->ClearScreen (gST->ConOut);
          return;
        } else {
          //
          // Let user input password again.
          //
          continue;
        }
      }
    }
  }
}

/**
  Process Set Master Pwd HDD password request.

  @param[in] AtaPassThru            Pointer to ATA_PASSTHRU instance.
  @param[in] Port                   The port number of attached ATA device.
  @param[in] PortMultiplierPort     The port number of port multiplier of attached ATA device.
  @param[in] ConfigFormEntry        The HDD Password configuration form entry.

**/
VOID
ProcessHddPasswordRequestSetMasterPwd (
  IN EFI_ATA_PASS_THRU_PROTOCOL      *AtaPassThru,
  IN UINT16                          Port,
  IN UINT16                          PortMultiplierPort,
  IN HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry
  )
{
  EFI_STATUS     Status;
  CHAR16         PopUpString[100];
  EFI_INPUT_KEY  Key;
  UINT16         RetryCount;
  CHAR8          Password[HDD_PASSWORD_MAX_LENGTH];
  CHAR8          PasswordConfirm[HDD_PASSWORD_MAX_LENGTH];

  RetryCount = 0;

  DEBUG ((DEBUG_INFO, "%a()\n", __func__));

  if (ConfigFormEntry->IfrData.SecurityStatus.Frozen) {
    DEBUG ((DEBUG_INFO, "%s is frozen, do nothing\n", ConfigFormEntry->HddString));
    return;
  }

  if (ConfigFormEntry->IfrData.SecurityStatus.Locked) {
    DEBUG ((DEBUG_INFO, "%s is locked, do nothing\n", ConfigFormEntry->HddString));
    return;
  }

  UnicodeSPrint (PopUpString, sizeof (PopUpString), L"Set Master Pwd: %s", ConfigFormEntry->HddString);

  //
  // Check the device security status.
  //
  if (ConfigFormEntry->IfrData.SecurityStatus.Supported) {
    while (TRUE) {
      Status = PopupHddPasswordInputWindows (PopUpString, L"Please type in your new password", Password);
      if (!EFI_ERROR (Status)) {
        Status = PopupHddPasswordInputWindows (PopUpString, L"Please confirm your new password", PasswordConfirm);
        if (!EFI_ERROR (Status)) {
          if (CompareMem (Password, PasswordConfirm, HDD_PASSWORD_MAX_LENGTH) == 0) {
            if (!PasswordIsFullZero (Password)) {
              Status = SetHddPassword (AtaPassThru, Port, PortMultiplierPort, 1, 1, 1, Password);
            } else {
              Status = EFI_INVALID_PARAMETER;
            }

            if (!EFI_ERROR (Status)) {
              ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
              ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);
              return;
            } else {
              do {
                CreatePopUp (
                  EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                  &Key,
                  L"Set Master Pwd failed or invalid password.",
                  L"Press ENTER to retry",
                  NULL
                  );
              } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
            }
          } else {
            do {
              CreatePopUp (
                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                &Key,
                L"Passwords are not the same.",
                L"Press ENTER to retry",
                NULL
                );
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            Status = EFI_INVALID_PARAMETER;
          }
        }

        ZeroMem (Password, HDD_PASSWORD_MAX_LENGTH);
        ZeroMem (PasswordConfirm, HDD_PASSWORD_MAX_LENGTH);

        if (EFI_ERROR (Status)) {
          RetryCount++;
          if (RetryCount >= MAX_HDD_PASSWORD_RETRY_COUNT) {
            do {
              CreatePopUp (
                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                &Key,
                L"Hdd password retry count is expired.",
                L"Press ENTER to skip the request and continue boot",
                NULL
                );
            } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);

            gST->ConOut->ClearScreen (gST->ConOut);
            return;
          }
        }
      } else if (Status == EFI_ABORTED) {
        do {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Press ENTER to skip the request and continue boot,",
            L"Press ESC to input password again",
            NULL
            );
        } while ((Key.ScanCode != SCAN_ESC) && (Key.UnicodeChar != CHAR_CARRIAGE_RETURN));

        if (Key.UnicodeChar == CHAR_CARRIAGE_RETURN) {
          gST->ConOut->ClearScreen (gST->ConOut);
          return;
        } else {
          //
          // Let user input password again.
          //
          continue;
        }
      }
    }
  }
}

/**
  Process HDD password request.

  @param[in] AtaPassThru            Pointer to ATA_PASSTHRU instance.
  @param[in] Port                   The port number of attached ATA device.
  @param[in] PortMultiplierPort     The port number of port multiplier of attached ATA device.
  @param[in] ConfigFormEntry        The HDD Password configuration form entry.

**/
VOID
ProcessHddPasswordRequest (
  IN EFI_ATA_PASS_THRU_PROTOCOL      *AtaPassThru,
  IN UINT16                          Port,
  IN UINT16                          PortMultiplierPort,
  IN HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry
  )
{
  EFI_STATUS                     Status;
  HDD_PASSWORD_REQUEST_VARIABLE  *TempVariable;
  HDD_PASSWORD_REQUEST_VARIABLE  *Variable;
  UINTN                          VariableSize;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  if (mHddPasswordRequestVariable == NULL) {
    Status = GetVariable2 (
               HDD_PASSWORD_REQUEST_VARIABLE_NAME,
               &mHddPasswordVendorGuid,
               (VOID **)&Variable,
               &VariableSize
               );
    if (EFI_ERROR (Status) || (Variable == NULL)) {
      return;
    }

    mHddPasswordRequestVariable     = Variable;
    mHddPasswordRequestVariableSize = VariableSize;

    //
    // Delete the HDD password request variable.
    //
    Status = gRT->SetVariable (
                    HDD_PASSWORD_REQUEST_VARIABLE_NAME,
                    &mHddPasswordVendorGuid,
                    0,
                    0,
                    NULL
                    );
    ASSERT_EFI_ERROR (Status);
  } else {
    Variable     = mHddPasswordRequestVariable;
    VariableSize = mHddPasswordRequestVariableSize;
  }

  //
  // Process the HDD password requests.
  //
  TempVariable = Variable;
  while (VariableSize >= sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) {
    if ((TempVariable->Device.Bus                == ConfigFormEntry->Bus) &&
        (TempVariable->Device.Device             == ConfigFormEntry->Device) &&
        (TempVariable->Device.Function           == ConfigFormEntry->Function) &&
        (TempVariable->Device.Port               == ConfigFormEntry->Port) &&
        (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
    {
      //
      // Found the node for the HDD password device.
      //
      if (TempVariable->Request.UserPassword != 0) {
        ProcessHddPasswordRequestSetUserPwd (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);
      }

      if (TempVariable->Request.MasterPassword != 0) {
        ProcessHddPasswordRequestSetMasterPwd (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);
      }

      break;
    }

    VariableSize -= sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
    TempVariable += 1;
  }

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
}

/**
  Get saved HDD password request.

  @param[in, out] ConfigFormEntry       The HDD Password configuration form entry.

**/
VOID
GetSavedHddPasswordRequest (
  IN OUT HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry
  )
{
  EFI_STATUS                     Status;
  HDD_PASSWORD_REQUEST_VARIABLE  *TempVariable;
  HDD_PASSWORD_REQUEST_VARIABLE  *Variable;
  UINTN                          VariableSize;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  Variable     = NULL;
  VariableSize = 0;

  Status = GetVariable2 (
             HDD_PASSWORD_REQUEST_VARIABLE_NAME,
             &mHddPasswordVendorGuid,
             (VOID **)&Variable,
             &VariableSize
             );
  if (EFI_ERROR (Status) || (Variable == NULL)) {
    return;
  }

  TempVariable = Variable;
  while (VariableSize >= sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) {
    if ((TempVariable->Device.Bus                == ConfigFormEntry->Bus) &&
        (TempVariable->Device.Device             == ConfigFormEntry->Device) &&
        (TempVariable->Device.Function           == ConfigFormEntry->Function) &&
        (TempVariable->Device.Port               == ConfigFormEntry->Port) &&
        (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
    {
      //
      // Found the node for the HDD password device.
      // Get the HDD password request.
      //
      CopyMem (&ConfigFormEntry->IfrData.Request, &TempVariable->Request, sizeof (HDD_PASSWORD_REQUEST));
      DEBUG ((
        DEBUG_INFO,
        "HddPasswordRequest got: 0x%x\n",
        ConfigFormEntry->IfrData.Request
        ));
      break;
    }

    VariableSize -= sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
    TempVariable += 1;
  }

  FreePool (Variable);

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
}

/**
  Save HDD password request.

  @param[in] ConfigFormEntry        The HDD Password configuration form entry.

**/
VOID
SaveHddPasswordRequest (
  IN HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry
  )
{
  EFI_STATUS                     Status;
  HDD_PASSWORD_REQUEST_VARIABLE  *TempVariable;
  UINTN                          TempVariableSize;
  HDD_PASSWORD_REQUEST_VARIABLE  *Variable;
  UINTN                          VariableSize;
  HDD_PASSWORD_REQUEST_VARIABLE  *NewVariable;
  UINTN                          NewVariableSize;

  DEBUG ((DEBUG_INFO, "%a() - enter\n", __func__));

  DEBUG ((
    DEBUG_INFO,
    "HddPasswordRequest to save: 0x%x\n",
    ConfigFormEntry->IfrData.Request
    ));

  Variable        = NULL;
  VariableSize    = 0;
  NewVariable     = NULL;
  NewVariableSize = 0;

  Status = GetVariable2 (
             HDD_PASSWORD_REQUEST_VARIABLE_NAME,
             &mHddPasswordVendorGuid,
             (VOID **)&Variable,
             &VariableSize
             );
  if (!EFI_ERROR (Status) && (Variable != NULL)) {
    TempVariable     = Variable;
    TempVariableSize = VariableSize;
    while (TempVariableSize >= sizeof (HDD_PASSWORD_REQUEST_VARIABLE)) {
      if ((TempVariable->Device.Bus                == ConfigFormEntry->Bus) &&
          (TempVariable->Device.Device             == ConfigFormEntry->Device) &&
          (TempVariable->Device.Function           == ConfigFormEntry->Function) &&
          (TempVariable->Device.Port               == ConfigFormEntry->Port) &&
          (TempVariable->Device.PortMultiplierPort == ConfigFormEntry->PortMultiplierPort))
      {
        //
        // Found the node for the HDD password device.
        // Update the HDD password request.
        //
        CopyMem (&TempVariable->Request, &ConfigFormEntry->IfrData.Request, sizeof (HDD_PASSWORD_REQUEST));
        NewVariable     = Variable;
        NewVariableSize = VariableSize;
        break;
      }

      TempVariableSize -= sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
      TempVariable     += 1;
    }

    if (NewVariable == NULL) {
      //
      // The node for the HDD password device is not found.
      // Create node for the HDD password device.
      //
      NewVariableSize = VariableSize + sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
      NewVariable     = AllocateZeroPool (NewVariableSize);
      ASSERT (NewVariable != NULL);
      CopyMem (NewVariable, Variable, VariableSize);
      TempVariable                            = (HDD_PASSWORD_REQUEST_VARIABLE *)((UINTN)NewVariable + VariableSize);
      TempVariable->Device.Bus                = (UINT8)ConfigFormEntry->Bus;
      TempVariable->Device.Device             = (UINT8)ConfigFormEntry->Device;
      TempVariable->Device.Function           = (UINT8)ConfigFormEntry->Function;
      TempVariable->Device.Port               = ConfigFormEntry->Port;
      TempVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
      CopyMem (&TempVariable->Request, &ConfigFormEntry->IfrData.Request, sizeof (HDD_PASSWORD_REQUEST));
    }
  } else {
    NewVariableSize = sizeof (HDD_PASSWORD_REQUEST_VARIABLE);
    NewVariable     = AllocateZeroPool (NewVariableSize);
    ASSERT (NewVariable != NULL);
    NewVariable->Device.Bus                = (UINT8)ConfigFormEntry->Bus;
    NewVariable->Device.Device             = (UINT8)ConfigFormEntry->Device;
    NewVariable->Device.Function           = (UINT8)ConfigFormEntry->Function;
    NewVariable->Device.Port               = ConfigFormEntry->Port;
    NewVariable->Device.PortMultiplierPort = ConfigFormEntry->PortMultiplierPort;
    CopyMem (&NewVariable->Request, &ConfigFormEntry->IfrData.Request, sizeof (HDD_PASSWORD_REQUEST));
  }

  Status = gRT->SetVariable (
                  HDD_PASSWORD_REQUEST_VARIABLE_NAME,
                  &mHddPasswordVendorGuid,
                  EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS,
                  NewVariableSize,
                  NewVariable
                  );
  if (EFI_ERROR (Status)) {
    DEBUG ((DEBUG_INFO, "HddPasswordRequest variable set failed (%r)\n", Status));
  }

  if (NewVariable != Variable) {
    FreePool (NewVariable);
  }

  if (Variable != NULL) {
    FreePool (Variable);
  }

  DEBUG ((DEBUG_INFO, "%a() - exit\n", __func__));
}

/**
  Get the HDD Password configuration form entry by the index of the goto opcode activated.

  @param[in]  Index The 0-based index of the goto opcode activated.

  @return The HDD Password configuration form entry found.
**/
HDD_PASSWORD_CONFIG_FORM_ENTRY *
HddPasswordGetConfigFormEntryByIndex (
  IN UINT32  Index
  )
{
  LIST_ENTRY                      *Entry;
  UINT32                          CurrentIndex;
  HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry;

  CurrentIndex    = 0;
  ConfigFormEntry = NULL;

  BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
    if (CurrentIndex == Index) {
      ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);
      break;
    }

    CurrentIndex++;
  }

  return ConfigFormEntry;
}

/**
  This function allows the caller to request the current
  configuration for one or more named elements. The resulting
  string is in <ConfigAltResp> format. Any and all alternative
  configuration strings shall also be appended to the end of the
  current configuration string. If they are, they must appear
  after the current configuration. They must contain the same
  routing (GUID, NAME, PATH) as the current configuration string.
  They must have an additional description indicating the type of
  alternative configuration the string represents,
  "ALTCFG=<StringToken>". That <StringToken> (when
  converted from Hex UNICODE to binary) is a reference to a
  string in the associated string pack.

  @param[in] This       Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in] Request    A null-terminated Unicode string in
                        <ConfigRequest> format. Note that this
                        includes the routing information as well as
                        the configurable name / value pairs. It is
                        invalid for this string to be in
                        <MultiConfigRequest> 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 string is filled with the
                                  values corresponding to all requested
                                  names.
  @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_PARAMETER   For example, passing in a NULL
                                  for the Request parameter
                                  would result in this type of
                                  error. In this case, the
                                  Progress parameter would be
                                  set to NULL.
  @retval EFI_NOT_FOUND           Routing data doesn't match any
                                  known driver. Progress set to the
                                  first character in the routing header.
                                  Note: There is no requirement that the
                                  driver validate the routing data. It
                                  must skip the <ConfigHdr> in order to
                                  process the names.
  @retval EFI_INVALID_PARAMETER   Illegal syntax. Progress set
                                  to most recent & before the
                                  error or the beginning of the
                                  string.
  @retval EFI_INVALID_PARAMETER   Unknown name. Progress points
                                  to the & before the name in
                                  question.Currently not implemented.
**/
EFI_STATUS
EFIAPI
HddPasswordFormExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Request,
  OUT EFI_STRING                            *Progress,
  OUT EFI_STRING                            *Results
  )
{
  EFI_STATUS                     Status;
  UINTN                          BufferSize;
  HDD_PASSWORD_CONFIG            *IfrData;
  HDD_PASSWORD_DXE_PRIVATE_DATA  *Private;
  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, &mHddPasswordVendorGuid, mHddPasswordVendorStorageName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  Private = HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This);
  IfrData = AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG));
  ASSERT (IfrData != NULL);
  if (Private->Current != NULL) {
    CopyMem (IfrData, &Private->Current->IfrData, sizeof (HDD_PASSWORD_CONFIG));
  }

  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
  //
  BufferSize    = sizeof (HDD_PASSWORD_CONFIG);
  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 (&mHddPasswordVendorGuid, mHddPasswordVendorStorageName, 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 = gHiiConfigRouting->BlockToConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *)IfrData,
                                BufferSize,
                                Results,
                                Progress
                                );
  FreePool (IfrData);
  //
  // 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;
}

/**
  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
HddPasswordFormRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                            *Progress
  )
{
  if ((Configuration == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Check routing data in <ConfigHdr>.
  // Note: if only one Storage is used, then this checking could be skipped.
  //
  if (!HiiIsConfigHdrMatch (Configuration, &mHddPasswordVendorGuid, mHddPasswordVendorStorageName)) {
    *Progress = Configuration;
    return EFI_NOT_FOUND;
  }

  *Progress = Configuration + StrLen (Configuration);
  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 enerated 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.Currently not implemented.
  @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
  @retval Others                 Other errors as indicated.
**/
EFI_STATUS
EFIAPI
HddPasswordFormCallback (
  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
  )
{
  HDD_PASSWORD_DXE_PRIVATE_DATA   *Private;
  EFI_STRING_ID                   DeviceFormTitleToken;
  HDD_PASSWORD_CONFIG             *IfrData;
  HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry;

  if (ActionRequest != NULL) {
    *ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
  } else {
    return EFI_INVALID_PARAMETER;
  }

  if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
    //
    // Do nothing for other UEFI Action. Only do call back when data is changing or changed.
    //
    return EFI_UNSUPPORTED;
  }

  Private = HDD_PASSWORD_DXE_PRIVATE_FROM_THIS (This);

  //
  // Retrive data from Browser
  //
  IfrData = AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG));
  ASSERT (IfrData != NULL);
  if (!HiiGetBrowserData (&mHddPasswordVendorGuid, mHddPasswordVendorStorageName, sizeof (HDD_PASSWORD_CONFIG), (UINT8 *)IfrData)) {
    FreePool (IfrData);
    return EFI_NOT_FOUND;
  }

  switch (QuestionId) {
    case KEY_HDD_USER_PASSWORD:
      if (Action == EFI_BROWSER_ACTION_CHANGED) {
        DEBUG ((DEBUG_INFO, "KEY_HDD_USER_PASSWORD\n"));
        ConfigFormEntry                               = Private->Current;
        ConfigFormEntry->IfrData.Request.UserPassword = Value->b;
        SaveHddPasswordRequest (ConfigFormEntry);
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
      }

      break;
    case KEY_HDD_MASTER_PASSWORD:
      if (Action == EFI_BROWSER_ACTION_CHANGED) {
        DEBUG ((DEBUG_INFO, "KEY_HDD_MASTER_PASSWORD\n"));
        ConfigFormEntry                                 = Private->Current;
        ConfigFormEntry->IfrData.Request.MasterPassword = Value->b;
        SaveHddPasswordRequest (ConfigFormEntry);
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
      }

      break;

    default:
      if ((QuestionId >= KEY_HDD_DEVICE_ENTRY_BASE) && (QuestionId < (mNumberOfHddDevices + KEY_HDD_DEVICE_ENTRY_BASE))) {
        if (Action == EFI_BROWSER_ACTION_CHANGING) {
          //
          // In case goto the device configuration form, update the device form title.
          //
          ConfigFormEntry = HddPasswordGetConfigFormEntryByIndex ((UINT32)(QuestionId - KEY_HDD_DEVICE_ENTRY_BASE));
          ASSERT (ConfigFormEntry != NULL);

          DeviceFormTitleToken = (EFI_STRING_ID)STR_HDD_SECURITY_HD;
          HiiSetString (Private->HiiHandle, DeviceFormTitleToken, ConfigFormEntry->HddString, NULL);

          Private->Current = ConfigFormEntry;
          CopyMem (IfrData, &ConfigFormEntry->IfrData, sizeof (HDD_PASSWORD_CONFIG));
        }
      }

      break;
  }

  //
  // Pass changed uncommitted data back to Form Browser
  //
  HiiSetBrowserData (&mHddPasswordVendorGuid, mHddPasswordVendorStorageName, sizeof (HDD_PASSWORD_CONFIG), (UINT8 *)IfrData, NULL);

  FreePool (IfrData);
  return EFI_SUCCESS;
}

/**
  Updates the HDD Password configuration form to add an entry for the attached
  ata harddisk device specified by the Controller.

  @param[in] HiiHandle            The HII Handle associated with the registered package list.
  @param[in] AtaPassThru          Pointer to ATA_PASSTHRU instance.
  @param[in] PciIo                Pointer to PCI_IO instance.
  @param[in] Controller           The controller handle of the attached ata controller.
  @param[in] Bus                  The bus number of ATA controller.
  @param[in] Device               The device number of ATA controller.
  @param[in] Function             The function number of ATA controller.
  @param[in] Port                 The port number of attached ATA device.
  @param[in] PortMultiplierPort   The port number of port multiplier of attached ATA device.

  @retval EFI_SUCCESS             The Hdd Password configuration form is updated.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.
  @retval Others                  Other errors as indicated.

**/
EFI_STATUS
HddPasswordConfigUpdateForm (
  IN EFI_HII_HANDLE              HiiHandle,
  IN EFI_ATA_PASS_THRU_PROTOCOL  *AtaPassThru,
  IN EFI_PCI_IO_PROTOCOL         *PciIo,
  IN EFI_HANDLE                  Controller,
  IN UINTN                       Bus,
  IN UINTN                       Device,
  IN UINTN                       Function,
  IN UINT16                      Port,
  IN UINT16                      PortMultiplierPort
  )
{
  LIST_ENTRY                      *Entry;
  HDD_PASSWORD_CONFIG_FORM_ENTRY  *ConfigFormEntry;
  BOOLEAN                         EntryExisted;
  EFI_STATUS                      Status;
  VOID                            *StartOpCodeHandle;
  VOID                            *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL              *StartLabel;
  EFI_IFR_GUID_LABEL              *EndLabel;
  CHAR16                          HddString[40];
  ATA_IDENTIFY_DATA               IdentifyData;
  EFI_DEVICE_PATH_PROTOCOL        *AtaDeviceNode;

  ConfigFormEntry = NULL;
  EntryExisted    = FALSE;

  BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
    ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);

    if ((ConfigFormEntry->Bus == Bus) &&
        (ConfigFormEntry->Device == Device) &&
        (ConfigFormEntry->Function == Function) &&
        (ConfigFormEntry->Port == Port) &&
        (ConfigFormEntry->PortMultiplierPort == PortMultiplierPort))
    {
      EntryExisted = TRUE;
      break;
    }
  }

  if (!EntryExisted) {
    //
    // Add a new form.
    //
    ConfigFormEntry = AllocateZeroPool (sizeof (HDD_PASSWORD_CONFIG_FORM_ENTRY));
    if (ConfigFormEntry == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    InitializeListHead (&ConfigFormEntry->Link);
    ConfigFormEntry->Controller         = Controller;
    ConfigFormEntry->Bus                = Bus;
    ConfigFormEntry->Device             = Device;
    ConfigFormEntry->Function           = Function;
    ConfigFormEntry->Port               = Port;
    ConfigFormEntry->PortMultiplierPort = PortMultiplierPort;
    ConfigFormEntry->AtaPassThru        = AtaPassThru;

    DEBUG ((DEBUG_INFO, "HddPasswordDxe: Create new form for device[%d][%d] at Bus 0x%x Dev 0x%x Func 0x%x\n", Port, PortMultiplierPort, Bus, Device, Function));

    //
    // Construct the device path for the HDD password device
    //
    Status = AtaPassThru->BuildDevicePath (
                            AtaPassThru,
                            Port,
                            PortMultiplierPort,
                            &AtaDeviceNode
                            );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    ConfigFormEntry->DevicePath = AppendDevicePathNode (DevicePathFromHandle (Controller), AtaDeviceNode);
    FreePool (AtaDeviceNode);
    if (ConfigFormEntry->DevicePath == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Get attached harddisk model number
    //
    Status = GetHddDeviceIdentifyData (AtaPassThru, Port, PortMultiplierPort, &IdentifyData);
    ASSERT_EFI_ERROR (Status);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    GetHddDeviceModelNumber (&IdentifyData, HddString);
    //
    // Compose the HDD title string and help string of this port and create a new EFI_STRING_ID.
    //
    UnicodeSPrint (ConfigFormEntry->HddString, sizeof (ConfigFormEntry->HddString), L"HDD %d:%s", mNumberOfHddDevices, HddString);
    ConfigFormEntry->TitleToken     = HiiSetString (HiiHandle, 0, ConfigFormEntry->HddString, NULL);
    ConfigFormEntry->TitleHelpToken = HiiSetString (HiiHandle, 0, L"Request to set HDD Password", NULL);

    GetHddPasswordSecurityStatus (&IdentifyData, &ConfigFormEntry->IfrData);

    InsertTailList (&mHddPasswordConfigFormList, &ConfigFormEntry->Link);

    //
    // 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       = HDD_DEVICE_ENTRY_LABEL;

    //
    // 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       = HDD_DEVICE_LABEL_END;

    mNumberOfHddDevices = 0;
    BASE_LIST_FOR_EACH (Entry, &mHddPasswordConfigFormList) {
      ConfigFormEntry = BASE_CR (Entry, HDD_PASSWORD_CONFIG_FORM_ENTRY, Link);

      HiiCreateGotoOpCode (
        StartOpCodeHandle,                                        // Container for dynamic created opcodes
        FORMID_HDD_DEVICE_FORM,                                   // Target Form ID
        ConfigFormEntry->TitleToken,                              // Prompt text
        ConfigFormEntry->TitleHelpToken,                          // Help text
        EFI_IFR_FLAG_CALLBACK,                                    // Question flag
        (UINT16)(KEY_HDD_DEVICE_ENTRY_BASE + mNumberOfHddDevices) // Question ID
        );

      mNumberOfHddDevices++;
    }

    HiiUpdateForm (
      HiiHandle,
      &mHddPasswordVendorGuid,
      FORMID_HDD_MAIN_FORM,
      StartOpCodeHandle,
      EndOpCodeHandle
      );

    HiiFreeOpCodeHandle (StartOpCodeHandle);
    HiiFreeOpCodeHandle (EndOpCodeHandle);

    //
    // Check if device is locked and prompt for password.
    //
    HddPasswordRequestPassword (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);

    //
    // Process HDD password request from last boot.
    //
    ProcessHddPasswordRequest (AtaPassThru, Port, PortMultiplierPort, ConfigFormEntry);
  }

  return EFI_SUCCESS;
}

/**
  Ata Pass Thru Protocol notification event handler.

  Check attached harddisk status to see if it's locked. If yes, then pop up a password windows to require user input.
  It also registers a form for user configuration on Hdd password configuration.

  @param[in] Event    Event whose notification function is being invoked.
  @param[in] Context  Pointer to the notification function's context.

**/
VOID
EFIAPI
HddPasswordNotificationEvent (
  IN  EFI_EVENT  Event,
  IN  VOID       *Context
  )
{
  EFI_STATUS                     Status;
  HDD_PASSWORD_DXE_PRIVATE_DATA  *Private;
  EFI_ATA_PASS_THRU_PROTOCOL     *AtaPassThru;
  UINT16                         Port;
  UINT16                         PortMultiplierPort;
  EFI_HANDLE                     Controller;
  EFI_HANDLE                     *HandleBuffer;
  UINTN                          HandleCount;
  UINTN                          Index;
  EFI_PCI_IO_PROTOCOL            *PciIo;
  UINTN                          SegNum;
  UINTN                          BusNum;
  UINTN                          DevNum;
  UINTN                          FuncNum;

  if (mHddPasswordEndOfDxe) {
    gBS->CloseEvent (Event);
    return;
  }

  Private = (HDD_PASSWORD_DXE_PRIVATE_DATA *)Context;

  //
  // Locate all handles of AtaPassThru protocol
  //
  Status = gBS->LocateHandleBuffer (
                  ByProtocol,
                  &gEfiAtaPassThruProtocolGuid,
                  NULL,
                  &HandleCount,
                  &HandleBuffer
                  );
  if (EFI_ERROR (Status)) {
    return;
  }

  //
  // Check attached hard disk status to see if it's locked
  //
  for (Index = 0; Index < HandleCount; Index += 1) {
    Controller = HandleBuffer[Index];
    Status     = gBS->HandleProtocol (
                        Controller,
                        &gEfiAtaPassThruProtocolGuid,
                        (VOID **)&AtaPassThru
                        );
    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // Ignore those logical ATA_PASS_THRU instance.
    //
    if ((AtaPassThru->Mode->Attributes & EFI_ATA_PASS_THRU_ATTRIBUTES_PHYSICAL) == 0) {
      continue;
    }

    Status = gBS->HandleProtocol (
                    Controller,
                    &gEfiPciIoProtocolGuid,
                    (VOID **)&PciIo
                    );
    ASSERT_EFI_ERROR (Status);
    if (EFI_ERROR (Status)) {
      break;
    }

    Status = PciIo->GetLocation (
                      PciIo,
                      &SegNum,
                      &BusNum,
                      &DevNum,
                      &FuncNum
                      );
    ASSERT_EFI_ERROR (Status);
    if (EFI_ERROR (Status)) {
      break;
    }

    //
    // Assume and only support Segment == 0.
    //
    ASSERT (SegNum == 0);

    //
    // traverse all attached harddisk devices to update form and unlock it
    //
    Port = 0xFFFF;

    while (TRUE) {
      Status = AtaPassThru->GetNextPort (AtaPassThru, &Port);
      if (EFI_ERROR (Status)) {
        //
        // We cannot find more legal port then we are done.
        //
        break;
      }

      PortMultiplierPort = 0xFFFF;
      while (TRUE) {
        Status = AtaPassThru->GetNextDevice (AtaPassThru, Port, &PortMultiplierPort);
        if (EFI_ERROR (Status)) {
          //
          // We cannot find more legal port multiplier port number for ATA device
          // on the port, then we are done.
          //
          break;
        }

        //
        // Find out the attached harddisk devices.
        // Try to add a HDD Password configuration page for the attached devices.
        //
        gBS->RestoreTPL (TPL_APPLICATION);
        Status = HddPasswordConfigUpdateForm (Private->HiiHandle, AtaPassThru, PciIo, Controller, BusNum, DevNum, FuncNum, Port, PortMultiplierPort);
        gBS->RaiseTPL (TPL_CALLBACK);
        if (EFI_ERROR (Status)) {
          break;
        }
      }
    }
  }

  FreePool (HandleBuffer);
  return;
}

/**
  Initialize the HDD Password configuration form.

  @param[out] Instance             Pointer to private instance.

  @retval EFI_SUCCESS              The HDD Password configuration form is initialized.
  @retval EFI_OUT_OF_RESOURCES     Failed to allocate memory.
  @retval Others                   Other errors as indicated.
**/
EFI_STATUS
HddPasswordConfigFormInit (
  OUT HDD_PASSWORD_DXE_PRIVATE_DATA  **Instance
  )
{
  EFI_STATUS                     Status;
  HDD_PASSWORD_DXE_PRIVATE_DATA  *Private;

  InitializeListHead (&mHddPasswordConfigFormList);

  Private = AllocateZeroPool (sizeof (HDD_PASSWORD_DXE_PRIVATE_DATA));
  if (Private == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  Private->Signature = HDD_PASSWORD_DXE_PRIVATE_SIGNATURE;

  Private->ConfigAccess.ExtractConfig = HddPasswordFormExtractConfig;
  Private->ConfigAccess.RouteConfig   = HddPasswordFormRouteConfig;
  Private->ConfigAccess.Callback      = HddPasswordFormCallback;

  //
  // Install Device Path Protocol and Config Access protocol to driver handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &Private->DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mHddPasswordHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &Private->ConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);
  if (EFI_ERROR (Status)) {
    FreePool (Private);
    return Status;
  }

  //
  // Publish our HII data
  //
  Private->HiiHandle = HiiAddPackages (
                         &mHddPasswordVendorGuid,
                         Private->DriverHandle,
                         HddPasswordDxeStrings,
                         HddPasswordBin,
                         NULL
                         );
  if (Private->HiiHandle == NULL) {
    FreePool (Private);
    return EFI_OUT_OF_RESOURCES;
  }

  *Instance = Private;
  return Status;
}

/**
  Main entry for this driver.

  @param ImageHandle     Image handle this driver.
  @param SystemTable     Pointer to SystemTable.

  @retval EFI_SUCCESS     This function always complete successfully.

**/
EFI_STATUS
EFIAPI
HddPasswordDxeInit (
  IN EFI_HANDLE        ImageHandle,
  IN EFI_SYSTEM_TABLE  *SystemTable
  )
{
  EFI_STATUS                      Status;
  HDD_PASSWORD_DXE_PRIVATE_DATA   *Private;
  VOID                            *Registration;
  EFI_EVENT                       EndOfDxeEvent;
  EDKII_VARIABLE_POLICY_PROTOCOL  *VariablePolicy;

  Private = NULL;

  //
  // Initialize the configuration form of HDD Password.
  //
  Status = HddPasswordConfigFormInit (&Private);
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Register HddPasswordNotificationEvent() notify function.
  //
  EfiCreateProtocolNotifyEvent (
    &gEfiAtaPassThruProtocolGuid,
    TPL_CALLBACK,
    HddPasswordNotificationEvent,
    (VOID *)Private,
    &Registration
    );

  Status = gBS->CreateEventEx (
                  EVT_NOTIFY_SIGNAL,
                  TPL_CALLBACK,
                  HddPasswordEndOfDxeEventNotify,
                  NULL,
                  &gEfiEndOfDxeEventGroupGuid,
                  &EndOfDxeEvent
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Make HDD_PASSWORD_VARIABLE_NAME variable read-only.
  //
  Status = gBS->LocateProtocol (&gEdkiiVariablePolicyProtocolGuid, NULL, (VOID **)&VariablePolicy);
  if (!EFI_ERROR (Status)) {
    Status = RegisterBasicVariablePolicy (
               VariablePolicy,
               &mHddPasswordVendorGuid,
               HDD_PASSWORD_VARIABLE_NAME,
               VARIABLE_POLICY_NO_MIN_SIZE,
               VARIABLE_POLICY_NO_MAX_SIZE,
               VARIABLE_POLICY_NO_MUST_ATTR,
               VARIABLE_POLICY_NO_CANT_ATTR,
               VARIABLE_POLICY_TYPE_LOCK_NOW
               );
    DEBUG ((DEBUG_INFO, "%a(): Lock %s variable (%r)\n", __func__, HDD_PASSWORD_VARIABLE_NAME, Status));
    ASSERT_EFI_ERROR (Status);
  }

  return Status;
}
