/** @file
  Helper functions for configuring or getting the parameters relating to iSCSI.

Copyright (c) 2004 - 2019, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "IScsiImpl.h"

CHAR16                    mVendorStorageName[] = L"ISCSI_CONFIG_IFR_NVDATA";
ISCSI_FORM_CALLBACK_INFO  *mCallbackInfo       = NULL;

HII_VENDOR_DEVICE_PATH  mIScsiHiiVendorDevicePath = {
  {
    {
      HARDWARE_DEVICE_PATH,
      HW_VENDOR_DP,
      {
        (UINT8)(sizeof (VENDOR_DEVICE_PATH)),
        (UINT8)((sizeof (VENDOR_DEVICE_PATH)) >> 8)
      }
    },
    ISCSI_CONFIG_GUID
  },
  {
    END_DEVICE_PATH_TYPE,
    END_ENTIRE_DEVICE_PATH_SUBTYPE,
    {
      (UINT8)(END_DEVICE_PATH_LENGTH),
      (UINT8)((END_DEVICE_PATH_LENGTH) >> 8)
    }
  }
};

/**
  Convert the IP address into a dotted string.

  @param[in]  Ip        The IP address.
  @param[in]  Ipv6Flag  Indicates whether the IP address is version 4 or version 6.
  @param[out] Str       The formatted IP string.

**/
VOID
IScsiIpToStr (
  IN  EFI_IP_ADDRESS  *Ip,
  IN  BOOLEAN         Ipv6Flag,
  OUT CHAR16          *Str
  )
{
  EFI_IPv4_ADDRESS  *Ip4;
  EFI_IPv6_ADDRESS  *Ip6;
  UINTN             Index;
  BOOLEAN           Short;
  UINTN             Number;
  CHAR16            FormatString[8];

  if (!Ipv6Flag) {
    Ip4 = &Ip->v4;

    UnicodeSPrint (
      Str,
      (UINTN)2 * IP4_STR_MAX_SIZE,
      L"%d.%d.%d.%d",
      (UINTN)Ip4->Addr[0],
      (UINTN)Ip4->Addr[1],
      (UINTN)Ip4->Addr[2],
      (UINTN)Ip4->Addr[3]
      );

    return;
  }

  Ip6   = &Ip->v6;
  Short = FALSE;

  for (Index = 0; Index < 15; Index = Index + 2) {
    if (!Short &&
        (Index % 2 == 0) &&
        (Ip6->Addr[Index] == 0) &&
        (Ip6->Addr[Index + 1] == 0)
        )
    {
      //
      // Deal with the case of ::.
      //
      if (Index == 0) {
        *Str       = L':';
        *(Str + 1) = L':';
        Str        = Str + 2;
      } else {
        *Str = L':';
        Str  = Str + 1;
      }

      while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) {
        Index = Index + 2;
      }

      Short = TRUE;

      if (Index == 16) {
        //
        // :: is at the end of the address.
        //
        *Str = L'\0';
        break;
      }
    }

    ASSERT (Index < 15);

    if (Ip6->Addr[Index] == 0) {
      Number = UnicodeSPrint (Str, 2 * IP_STR_MAX_SIZE, L"%x:", (UINTN)Ip6->Addr[Index + 1]);
    } else {
      if (Ip6->Addr[Index + 1] < 0x10) {
        CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:"));
      } else {
        CopyMem (FormatString, L"%x%x:", StrSize (L"%x%x:"));
      }

      Number = UnicodeSPrint (
                 Str,
                 2 * IP_STR_MAX_SIZE,
                 (CONST CHAR16 *)FormatString,
                 (UINTN)Ip6->Addr[Index],
                 (UINTN)Ip6->Addr[Index + 1]
                 );
    }

    Str = Str + Number;

    if (Index + 2 == 16) {
      *Str = L'\0';
      if (*(Str - 1) == L':') {
        *(Str - 1) = L'\0';
      }
    }
  }
}

/**
  Check whether the input IP address is valid.

  @param[in]  Ip        The IP address.
  @param[in]  IpMode    Indicates iSCSI running on IP4 or IP6 stack.

  @retval     TRUE      The input IP address is valid.
  @retval     FALSE     Otherwise

**/
BOOLEAN
IpIsUnicast (
  IN EFI_IP_ADDRESS  *Ip,
  IN  UINT8          IpMode
  )
{
  if (IpMode == IP_MODE_IP4) {
    if (IP4_IS_UNSPECIFIED (NTOHL (Ip->Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip->Addr[0]))) {
      return FALSE;
    }

    return TRUE;
  } else if (IpMode == IP_MODE_IP6) {
    return NetIp6IsValidUnicast (&Ip->v6);
  } else {
    DEBUG ((DEBUG_ERROR, "IpMode %d is invalid when configuring the iSCSI target IP!\n", IpMode));
    return FALSE;
  }
}

/**
  Parse IsId in string format and convert it to binary.

  @param[in]        String  The buffer of the string to be parsed.
  @param[in, out]   IsId    The buffer to store IsId.

  @retval EFI_SUCCESS              The operation finished successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.

**/
EFI_STATUS
IScsiParseIsIdFromString (
  IN CONST CHAR16  *String,
  IN OUT   UINT8   *IsId
  )
{
  UINT8          Index;
  CHAR16         *IsIdStr;
  CHAR16         TempStr[3];
  UINTN          NodeVal;
  CHAR16         PortString[ISCSI_NAME_IFR_MAX_SIZE];
  EFI_INPUT_KEY  Key;

  if ((String == NULL) || (IsId == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  IsIdStr = (CHAR16 *)String;

  if ((StrLen (IsIdStr) != 6) && (StrLen (IsIdStr) != 12)) {
    UnicodeSPrint (
      PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"Error! Only last 3 bytes are configurable, please input 6 hex numbers for last 3 bytes only or 12 hex numbers for full SSID!\n"
      );

    CreatePopUp (
      EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
      &Key,
      PortString,
      NULL
      );

    return EFI_INVALID_PARAMETER;
  }

  if (StrLen (IsIdStr) == 12) {
    IsIdStr += 6;
  }

  for (Index = 3; Index < 6; Index++) {
    CopyMem (TempStr, IsIdStr, sizeof (TempStr));
    TempStr[2] = L'\0';

    //
    // Convert the string to IsId. StrHexToUintn stops at the first character
    // that is not a valid hex character, '\0' here.
    //
    NodeVal = StrHexToUintn (TempStr);

    IsId[Index] = (UINT8)NodeVal;

    IsIdStr = IsIdStr + 2;
  }

  return EFI_SUCCESS;
}

/**
  Convert IsId from binary to string format.

  @param[out]      String  The buffer to store the converted string.
  @param[in]       IsId    The buffer to store IsId.

  @retval EFI_SUCCESS              The string converted successfully.
  @retval EFI_INVALID_PARAMETER    Any input parameter is invalid.

**/
EFI_STATUS
IScsiConvertIsIdToString (
  OUT CHAR16  *String,
  IN  UINT8   *IsId
  )
{
  UINT8  Index;
  UINTN  Number;

  if ((String == NULL) || (IsId == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  for (Index = 0; Index < 6; Index++) {
    if (IsId[Index] <= 0xF) {
      Number = UnicodeSPrint (
                 String,
                 2 * ISID_CONFIGURABLE_STORAGE,
                 L"0%X",
                 (UINTN)IsId[Index]
                 );
    } else {
      Number = UnicodeSPrint (
                 String,
                 2 * ISID_CONFIGURABLE_STORAGE,
                 L"%X",
                 (UINTN)IsId[Index]
                 );
    }

    String = String + Number;
  }

  *String = L'\0';

  return EFI_SUCCESS;
}

/**
  Get the Offset value specified by the input String.

  @param[in]  Configuration      A null-terminated Unicode string in
                                 <ConfigString> format.
  @param[in]  String             The string is "&OFFSET=".
  @param[out] Value              The Offset value.

  @retval EFI_OUT_OF_RESOURCES   Insufficient resources to store necessary
                                 structures.
  @retval EFI_SUCCESS            Value of <Number> is outputted in Number
                                 successfully.

**/
EFI_STATUS
IScsiGetValue (
  IN  CONST EFI_STRING  Configuration,
  IN  CHAR16            *String,
  OUT UINTN             *Value
  )
{
  CHAR16      *StringPtr;
  CHAR16      *TmpPtr;
  CHAR16      *Str;
  CHAR16      TmpStr[2];
  UINTN       Length;
  UINTN       Len;
  UINTN       Index;
  UINT8       *Buf;
  UINT8       DigitUint8;
  EFI_STATUS  Status;

  //
  // Get Value.
  //
  Buf       = NULL;
  StringPtr = StrStr (Configuration, String);
  ASSERT (StringPtr != NULL);
  StringPtr += StrLen (String);
  TmpPtr     = StringPtr;

  while (*StringPtr != L'\0' && *StringPtr != L'&') {
    StringPtr++;
  }

  Length = StringPtr - TmpPtr;
  Len    = Length + 1;

  Str = AllocateZeroPool (Len * sizeof (CHAR16));
  if (Str == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  CopyMem (Str, TmpPtr, Len * sizeof (CHAR16));
  *(Str + Length) = L'\0';

  Len = (Len + 1) / 2;
  Buf = (UINT8 *)AllocateZeroPool (Len);
  if (Buf == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  ZeroMem (TmpStr, sizeof (TmpStr));
  for (Index = 0; Index < Length; Index++) {
    TmpStr[0]  = Str[Length - Index - 1];
    DigitUint8 = (UINT8)StrHexToUint64 (TmpStr);
    if ((Index & 1) == 0) {
      Buf[Index/2] = DigitUint8;
    } else {
      Buf[Index/2] = (UINT8)((DigitUint8 << 4) + Buf[Index/2]);
    }
  }

  *Value = 0;
  CopyMem (
    Value,
    Buf,
    (((Length + 1) / 2) < sizeof (UINTN)) ? ((Length + 1) / 2) : sizeof (UINTN)
    );

  FreePool (Buf);
  Status = EFI_SUCCESS;

Exit:
  if (Str != NULL) {
    FreePool (Str);
  }

  return Status;
}

/**
  Get the attempt config data from global structure by the ConfigIndex.

  @param[in]  AttemptConfigIndex     The unique index indicates the attempt.

  @return       Pointer to the attempt config data.
  @retval NULL  The attempt configuration data cannot be found.

**/
ISCSI_ATTEMPT_CONFIG_NVDATA *
IScsiConfigGetAttemptByConfigIndex (
  IN UINT8  AttemptConfigIndex
  )
{
  LIST_ENTRY                   *Entry;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *Attempt;

  NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
    Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    if (Attempt->AttemptConfigIndex == AttemptConfigIndex) {
      return Attempt;
    }
  }

  return NULL;
}

/**
  Get the existing attempt config data from global structure by the NicIndex.

  @param[in]  NewAttempt         The created new attempt
  @param[in]  IScsiMode          The IScsi Mode of the new attempt, Enabled or
                                 Enabled for MPIO.

  @return                        Pointer to the existing attempt config data which
                                 has the same NICIndex as the new created attempt.
  @retval     NULL               The attempt with NicIndex does not exist.

**/
ISCSI_ATTEMPT_CONFIG_NVDATA *
IScsiConfigGetAttemptByNic (
  IN ISCSI_ATTEMPT_CONFIG_NVDATA  *NewAttempt,
  IN UINT8                        IScsiMode
  )
{
  LIST_ENTRY                   *Entry;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *Attempt;

  NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
    Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    if ((Attempt != NewAttempt) && (Attempt->NicIndex == NewAttempt->NicIndex) &&
        (Attempt->SessionConfigData.Enabled == IScsiMode))
    {
      return Attempt;
    }
  }

  return NULL;
}

/**
  Extract the Index of the attempt list.

  @param[in]   AttemptNameList     The Name list of the Attempts.
  @param[out]  AttemptIndexList    The Index list of the Attempts.
  @param[in]   IsAddAttempts       If TRUE, Indicates add one or more attempts.
                                   If FALSE, Indicates delete attempts or change attempt order.

  @retval EFI_SUCCESS              The Attempt list is valid.
  @retval EFI_INVALID_PARAMETERS   The Attempt List is invalid.

**/
EFI_STATUS
IScsiGetAttemptIndexList (
  IN      CHAR16   *AttemptNameList,
  OUT  UINT8       *AttemptIndexList,
  IN      BOOLEAN  IsAddAttempts
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  CHAR16                       *AttemptStr;
  UINT8                        AttemptIndex;
  UINTN                        Len;
  UINTN                        Index;

  Index = 0;

  if ((AttemptNameList == NULL) || (*AttemptNameList == L'\0')) {
    return EFI_INVALID_PARAMETER;
  }

  AttemptStr = AttemptNameList;
  Len        = StrLen (L"attempt:");

  while (*AttemptStr != L'\0') {
    AttemptStr = StrStr (AttemptStr, L"attempt:");
    if (AttemptStr == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    AttemptStr       += Len;
    AttemptIndex      = (UINT8)(*AttemptStr - L'0');
    AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (IsAddAttempts) {
      if ((AttemptConfigData != NULL) || ((AttemptIndex) > PcdGet8 (PcdMaxIScsiAttemptNumber))) {
        return EFI_INVALID_PARAMETER;
      }
    } else {
      if (AttemptConfigData == NULL) {
        return EFI_INVALID_PARAMETER;
      }
    }

    AttemptIndexList[Index] = AttemptIndex;
    Index++;
    AttemptStr += 2;
  }

  return EFI_SUCCESS;
}

/**
  Convert the iSCSI configuration data into the IFR data.

  @param[in]       Attempt                The iSCSI attempt config data.
  @param[in, out]  IfrNvData              The IFR nv data.

**/
VOID
IScsiConvertAttemptConfigDataToIfrNvData (
  IN ISCSI_ATTEMPT_CONFIG_NVDATA  *Attempt,
  IN OUT ISCSI_CONFIG_IFR_NVDATA  *IfrNvData
  )
{
  ISCSI_SESSION_CONFIG_NVDATA    *SessionConfigData;
  ISCSI_CHAP_AUTH_CONFIG_NVDATA  *AuthConfigData;
  EFI_IP_ADDRESS                 Ip;
  BOOLEAN                        DnsMode;

  //
  // Normal session configuration parameters.
  //
  SessionConfigData  = &Attempt->SessionConfigData;
  IfrNvData->Enabled = SessionConfigData->Enabled;
  IfrNvData->IpMode  = SessionConfigData->IpMode;
  DnsMode            = SessionConfigData->DnsMode;

  IfrNvData->InitiatorInfoFromDhcp = SessionConfigData->InitiatorInfoFromDhcp;
  IfrNvData->TargetInfoFromDhcp    = SessionConfigData->TargetInfoFromDhcp;
  IfrNvData->TargetPort            = SessionConfigData->TargetPort;

  if (IfrNvData->IpMode == IP_MODE_IP4) {
    CopyMem (&Ip.v4, &SessionConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));
    IScsiIpToStr (&Ip, FALSE, IfrNvData->LocalIp);
    CopyMem (&Ip.v4, &SessionConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
    IScsiIpToStr (&Ip, FALSE, IfrNvData->SubnetMask);
    CopyMem (&Ip.v4, &SessionConfigData->Gateway, sizeof (EFI_IPv4_ADDRESS));
    IScsiIpToStr (&Ip, FALSE, IfrNvData->Gateway);
    ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));
    if (SessionConfigData->TargetIp.v4.Addr[0] != '\0') {
      CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));
      IScsiIpToStr (&Ip, FALSE, IfrNvData->TargetIp);
    }
  } else if (IfrNvData->IpMode == IP_MODE_IP6) {
    ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));
    if (SessionConfigData->TargetIp.v6.Addr[0] != '\0') {
      IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);
      IScsiIpToStr (&Ip, TRUE, IfrNvData->TargetIp);
    }
  }

  AsciiStrToUnicodeStrS (
    SessionConfigData->TargetName,
    IfrNvData->TargetName,
    sizeof (IfrNvData->TargetName) / sizeof (IfrNvData->TargetName[0])
    );

  if (DnsMode) {
    AsciiStrToUnicodeStrS (
      SessionConfigData->TargetUrl,
      IfrNvData->TargetIp,
      sizeof (IfrNvData->TargetIp) / sizeof (IfrNvData->TargetIp[0])
      );
  }

  IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->BootLun);
  IScsiConvertIsIdToString (IfrNvData->IsId, SessionConfigData->IsId);

  IfrNvData->ConnectRetryCount = SessionConfigData->ConnectRetryCount;
  IfrNvData->ConnectTimeout    = SessionConfigData->ConnectTimeout;

  //
  // Authentication parameters.
  //
  IfrNvData->AuthenticationType = Attempt->AuthenticationType;

  if (IfrNvData->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
    AuthConfigData      = &Attempt->AuthConfigData.CHAP;
    IfrNvData->CHAPType = AuthConfigData->CHAPType;
    AsciiStrToUnicodeStrS (
      AuthConfigData->CHAPName,
      IfrNvData->CHAPName,
      sizeof (IfrNvData->CHAPName) / sizeof (IfrNvData->CHAPName[0])
      );
    AsciiStrToUnicodeStrS (
      AuthConfigData->CHAPSecret,
      IfrNvData->CHAPSecret,
      sizeof (IfrNvData->CHAPSecret) / sizeof (IfrNvData->CHAPSecret[0])
      );
    AsciiStrToUnicodeStrS (
      AuthConfigData->ReverseCHAPName,
      IfrNvData->ReverseCHAPName,
      sizeof (IfrNvData->ReverseCHAPName) / sizeof (IfrNvData->ReverseCHAPName[0])
      );
    AsciiStrToUnicodeStrS (
      AuthConfigData->ReverseCHAPSecret,
      IfrNvData->ReverseCHAPSecret,
      sizeof (IfrNvData->ReverseCHAPSecret) / sizeof (IfrNvData->ReverseCHAPSecret[0])
      );
  }

  //
  // Other parameters.
  //
  AsciiStrToUnicodeStrS (
    Attempt->AttemptName,
    IfrNvData->AttemptName,
    sizeof (IfrNvData->AttemptName) / sizeof (IfrNvData->AttemptName[0])
    );
}

/**
  Convert the iSCSI configuration data into the IFR data Which will be used
  to extract the iSCSI Keyword configuration in <ConfigAltResp> format.

  @param[in, out]  IfrNvData              The IFR nv data.

**/
VOID
EFIAPI
IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (
  IN OUT ISCSI_CONFIG_IFR_NVDATA  *IfrNvData
  )
{
  LIST_ENTRY                     *Entry;
  ISCSI_ATTEMPT_CONFIG_NVDATA    *Attempt;
  ISCSI_SESSION_CONFIG_NVDATA    *SessionConfigData;
  ISCSI_CHAP_AUTH_CONFIG_NVDATA  *AuthConfigData;
  CHAR16                         AttemptNameList[ATTEMPT_NAME_LIST_SIZE];
  ISCSI_NIC_INFO                 *NicInfo;
  CHAR16                         MacString[ISCSI_MAX_MAC_STRING_LEN];
  EFI_IP_ADDRESS                 Ip;
  UINTN                          Index;
  UINTN                          StringLen;

  NicInfo = NULL;
  ZeroMem (AttemptNameList, sizeof (AttemptNameList));

  if ((mPrivate != NULL) && (mPrivate->AttemptCount != 0)) {
    NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
      Attempt = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
      //
      // Normal session configuration parameters.
      //
      SessionConfigData = &Attempt->SessionConfigData;

      ASSERT ((Attempt->AttemptConfigIndex > 0) && (Attempt->AttemptConfigIndex <= FixedPcdGet8 (PcdMaxIScsiAttemptNumber)));
      Index = Attempt->AttemptConfigIndex - 1;

      //
      // Save the attempt to AttemptNameList as Attempt:1 Attempt:2
      //
      AsciiStrToUnicodeStrS (
        Attempt->AttemptName,
        AttemptNameList + StrLen (AttemptNameList),
        ATTEMPT_NAME_LIST_SIZE - StrLen (AttemptNameList)
        );

      StringLen = StrLen (AttemptNameList);
      ASSERT (StringLen > 2);
      *(AttemptNameList + StringLen - 2) = L':';
      *(AttemptNameList + StringLen)     = L' ';

      AsciiStrToUnicodeStrS (
        Attempt->AttemptName,
        IfrNvData->ISCSIAttemptName  + ATTEMPT_NAME_SIZE * Index,
        ATTEMPT_NAME_LIST_SIZE - ATTEMPT_NAME_SIZE * Index
        );

      IfrNvData->ISCSIBootEnableList[Index]    = SessionConfigData->Enabled;
      IfrNvData->ISCSIIpAddressTypeList[Index] = SessionConfigData->IpMode;

      IfrNvData->ISCSIInitiatorInfoViaDHCP[Index] = SessionConfigData->InitiatorInfoFromDhcp;
      IfrNvData->ISCSITargetInfoViaDHCP[Index]    = SessionConfigData->TargetInfoFromDhcp;
      IfrNvData->ISCSIConnectRetry[Index]         = SessionConfigData->ConnectRetryCount;
      IfrNvData->ISCSIConnectTimeout[Index]       = SessionConfigData->ConnectTimeout;
      IfrNvData->ISCSITargetTcpPort[Index]        = SessionConfigData->TargetPort;

      if (SessionConfigData->IpMode == IP_MODE_IP4) {
        CopyMem (&Ip.v4, &SessionConfigData->LocalIp, sizeof (EFI_IPv4_ADDRESS));
        IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorIpAddress);
        CopyMem (&Ip.v4, &SessionConfigData->SubnetMask, sizeof (EFI_IPv4_ADDRESS));
        IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorNetmask);
        CopyMem (&Ip.v4, &SessionConfigData->Gateway, sizeof (EFI_IPv4_ADDRESS));
        IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSIInitiatorGateway);
        if (SessionConfigData->TargetIp.v4.Addr[0] != '\0') {
          CopyMem (&Ip.v4, &SessionConfigData->TargetIp, sizeof (EFI_IPv4_ADDRESS));
          IScsiIpToStr (&Ip, FALSE, IfrNvData->Keyword[Index].ISCSITargetIpAddress);
        }
      } else if (SessionConfigData->IpMode == IP_MODE_IP6) {
        ZeroMem (IfrNvData->Keyword[Index].ISCSITargetIpAddress, sizeof (IfrNvData->TargetIp));
        if (SessionConfigData->TargetIp.v6.Addr[0] != '\0') {
          IP6_COPY_ADDRESS (&Ip.v6, &SessionConfigData->TargetIp);
          IScsiIpToStr (&Ip, TRUE, IfrNvData->Keyword[Index].ISCSITargetIpAddress);
        }
      }

      AsciiStrToUnicodeStrS (
        SessionConfigData->TargetName,
        IfrNvData->Keyword[Index].ISCSITargetName,
        ISCSI_NAME_MAX_SIZE
        );

      if (SessionConfigData->DnsMode) {
        AsciiStrToUnicodeStrS (
          SessionConfigData->TargetUrl,
          IfrNvData->Keyword[Index].ISCSITargetIpAddress,
          sizeof (IfrNvData->Keyword[Index].ISCSITargetIpAddress) / sizeof (IfrNvData->Keyword[Index].ISCSITargetIpAddress[0])
          );
      }

      IScsiLunToUnicodeStr (SessionConfigData->BootLun, IfrNvData->Keyword[Index].ISCSILun);
      IScsiConvertIsIdToString (IfrNvData->Keyword[Index].ISCSIIsId, SessionConfigData->IsId);

      IfrNvData->ISCSIAuthenticationMethod[Index] = Attempt->AuthenticationType;

      if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
        AuthConfigData                  = &Attempt->AuthConfigData.CHAP;
        IfrNvData->ISCSIChapType[Index] = AuthConfigData->CHAPType;
        AsciiStrToUnicodeStrS (
          AuthConfigData->CHAPName,
          IfrNvData->Keyword[Index].ISCSIChapUsername,
          ISCSI_CHAP_NAME_STORAGE
          );

        AsciiStrToUnicodeStrS (
          AuthConfigData->CHAPSecret,
          IfrNvData->Keyword[Index].ISCSIChapSecret,
          ISCSI_CHAP_SECRET_STORAGE
          );

        AsciiStrToUnicodeStrS (
          AuthConfigData->ReverseCHAPName,
          IfrNvData->Keyword[Index].ISCSIReverseChapUsername,
          ISCSI_CHAP_NAME_STORAGE
          );

        AsciiStrToUnicodeStrS (
          AuthConfigData->ReverseCHAPSecret,
          IfrNvData->Keyword[Index].ISCSIReverseChapSecret,
          ISCSI_CHAP_SECRET_STORAGE
          );
      }
    }
    CopyMem (IfrNvData->ISCSIDisplayAttemptList, AttemptNameList, ATTEMPT_NAME_LIST_SIZE);

    ZeroMem (IfrNvData->ISCSIMacAddr, sizeof (IfrNvData->ISCSIMacAddr));
    NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
      NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
      IScsiMacAddrToStr (
        &NicInfo->PermanentAddress,
        NicInfo->HwAddressSize,
        NicInfo->VlanId,
        MacString
        );
      CopyMem (
        IfrNvData->ISCSIMacAddr + StrLen (IfrNvData->ISCSIMacAddr),
        MacString,
        StrLen (MacString) * sizeof (CHAR16)
        );

      *(IfrNvData->ISCSIMacAddr + StrLen (IfrNvData->ISCSIMacAddr)) = L'/';
    }

    StringLen = StrLen (IfrNvData->ISCSIMacAddr);
    if (StringLen > 0) {
      *(IfrNvData->ISCSIMacAddr + StringLen - 1) = L'\0';
    }
  }
}

/**
  Convert the IFR data to iSCSI configuration data.

  @param[in]       IfrNvData              Point to ISCSI_CONFIG_IFR_NVDATA.
  @param[in, out]  Attempt                The iSCSI attempt config data.

  @retval EFI_INVALID_PARAMETER  Any input or configured parameter is invalid.
  @retval EFI_NOT_FOUND          Cannot find the corresponding variable.
  @retval EFI_OUT_OF_RESOURCES   The operation is failed due to lack of resources.
  @retval EFI_ABORTED            The operation is aborted.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiConvertIfrNvDataToAttemptConfigData (
  IN ISCSI_CONFIG_IFR_NVDATA          *IfrNvData,
  IN OUT ISCSI_ATTEMPT_CONFIG_NVDATA  *Attempt
  )
{
  EFI_IP_ADDRESS               HostIp;
  EFI_IP_ADDRESS               SubnetMask;
  EFI_IP_ADDRESS               Gateway;
  CHAR16                       *MacString;
  CHAR16                       *AttemptName1;
  CHAR16                       *AttemptName2;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *ExistAttempt;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *SameNicAttempt;
  CHAR16                       IScsiMode[64];
  CHAR16                       IpMode[64];
  ISCSI_NIC_INFO               *NicInfo;
  EFI_INPUT_KEY                Key;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINT8                        *AttemptOrderTmp;
  UINTN                        TotalNumber;
  EFI_STATUS                   Status;

  if ((IfrNvData == NULL) || (Attempt == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  //
  // Update those fields which don't have INTERACTIVE attribute.
  //
  Attempt->SessionConfigData.ConnectRetryCount = IfrNvData->ConnectRetryCount;
  Attempt->SessionConfigData.ConnectTimeout    = IfrNvData->ConnectTimeout;
  Attempt->SessionConfigData.IpMode            = IfrNvData->IpMode;

  if (IfrNvData->IpMode < IP_MODE_AUTOCONFIG) {
    Attempt->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->InitiatorInfoFromDhcp;
    Attempt->SessionConfigData.TargetPort            = IfrNvData->TargetPort;

    if (Attempt->SessionConfigData.TargetPort == 0) {
      Attempt->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;
    }

    Attempt->SessionConfigData.TargetInfoFromDhcp = IfrNvData->TargetInfoFromDhcp;
  }

  Attempt->AuthenticationType = IfrNvData->AuthenticationType;

  if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
    Attempt->AuthConfigData.CHAP.CHAPType = IfrNvData->CHAPType;
  }

  //
  // Only do full parameter validation if iSCSI is enabled on this device.
  //
  if (IfrNvData->Enabled != ISCSI_DISABLED) {
    if (Attempt->SessionConfigData.ConnectTimeout < CONNECT_MIN_TIMEOUT) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Connection Establishing Timeout is less than minimum value 100ms.",
        NULL
        );

      return EFI_INVALID_PARAMETER;
    }

    //
    // Validate the address configuration of the Initiator if DHCP isn't
    // deployed.
    //
    if (!Attempt->SessionConfigData.InitiatorInfoFromDhcp) {
      CopyMem (&HostIp.v4, &Attempt->SessionConfigData.LocalIp, sizeof (HostIp.v4));
      CopyMem (&SubnetMask.v4, &Attempt->SessionConfigData.SubnetMask, sizeof (SubnetMask.v4));
      CopyMem (&Gateway.v4, &Attempt->SessionConfigData.Gateway, sizeof (Gateway.v4));

      if ((Gateway.Addr[0] != 0)) {
        if (SubnetMask.Addr[0] == 0) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Gateway address is set but subnet mask is zero.",
            NULL
            );

          return EFI_INVALID_PARAMETER;
        } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Local IP and Gateway are not in the same subnet.",
            NULL
            );

          return EFI_INVALID_PARAMETER;
        }
      }
    }

    //
    // Validate target configuration if DHCP isn't deployed.
    //
    if (!Attempt->SessionConfigData.TargetInfoFromDhcp && (Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG)) {
      if (!Attempt->SessionConfigData.DnsMode) {
        if (!IpIsUnicast (&Attempt->SessionConfigData.TargetIp, IfrNvData->IpMode)) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Target IP is invalid!",
            NULL
            );
          return EFI_INVALID_PARAMETER;
        }
      } else {
        if (Attempt->SessionConfigData.TargetUrl[0] == '\0') {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"iSCSI target Url should not be NULL!",
            NULL
            );
          return EFI_INVALID_PARAMETER;
        }
      }

      //
      // Validate iSCSI target name configuration again:
      // The format of iSCSI target name is already verified in IScsiFormCallback() when
      // user input the name; here we only check the case user does not input the name.
      //
      if (Attempt->SessionConfigData.TargetName[0] == '\0') {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"iSCSI target name is NULL!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    }

    //
    // Validate the authentication info.
    //
    if (IfrNvData->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
      if ((IfrNvData->CHAPName[0] == '\0') || (IfrNvData->CHAPSecret[0] == '\0')) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"CHAP Name or CHAP Secret is invalid!",
          NULL
          );

        return EFI_INVALID_PARAMETER;
      }

      if ((IfrNvData->CHAPType == ISCSI_CHAP_MUTUAL) &&
          ((IfrNvData->ReverseCHAPName[0] == '\0') || (IfrNvData->ReverseCHAPSecret[0] == '\0'))
          )
      {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Reverse CHAP Name or Reverse CHAP Secret is invalid!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    }

    //
    // Check whether this attempt uses NIC which is already used by existing attempt.
    //
    SameNicAttempt = IScsiConfigGetAttemptByNic (Attempt, IfrNvData->Enabled);
    if (SameNicAttempt != NULL) {
      AttemptName1 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));
      if (AttemptName1 == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }

      AttemptName2 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));
      if (AttemptName2 == NULL) {
        FreePool (AttemptName1);
        return EFI_OUT_OF_RESOURCES;
      }

      AsciiStrToUnicodeStrS (Attempt->AttemptName, AttemptName1, ATTEMPT_NAME_SIZE);
      AsciiStrToUnicodeStrS (SameNicAttempt->AttemptName, AttemptName2, ATTEMPT_NAME_SIZE);

      UnicodeSPrint (
        mPrivate->PortString,
        (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
        L"Warning! Attempt \"%s\" uses same NIC as Attempt \"%s\".",
        AttemptName1,
        AttemptName2
        );

      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        mPrivate->PortString,
        NULL
        );

      FreePool (AttemptName1);
      FreePool (AttemptName2);
    }
  }

  //
  // Update the iSCSI Mode data and record it in attempt help info.
  //
  if (IfrNvData->Enabled == ISCSI_DISABLED) {
    UnicodeSPrint (IScsiMode, 64, L"Disabled");
  } else if (IfrNvData->Enabled == ISCSI_ENABLED) {
    UnicodeSPrint (IScsiMode, 64, L"Enabled");
  } else if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {
    UnicodeSPrint (IScsiMode, 64, L"Enabled for MPIO");
  }

  if (IfrNvData->IpMode == IP_MODE_IP4) {
    UnicodeSPrint (IpMode, 64, L"IP4");
  } else if (IfrNvData->IpMode == IP_MODE_IP6) {
    UnicodeSPrint (IpMode, 64, L"IP6");
  } else if (IfrNvData->IpMode == IP_MODE_AUTOCONFIG) {
    UnicodeSPrint (IpMode, 64, L"Autoconfigure");
  }

  NicInfo = IScsiGetNicInfoByIndex (Attempt->NicIndex);
  if (NicInfo == NULL) {
    return EFI_NOT_FOUND;
  }

  MacString = (CHAR16 *)AllocateZeroPool (ISCSI_MAX_MAC_STRING_LEN * sizeof (CHAR16));
  if (MacString == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  AsciiStrToUnicodeStrS (Attempt->MacString, MacString, ISCSI_MAX_MAC_STRING_LEN);

  UnicodeSPrint (
    mPrivate->PortString,
    (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
    L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
    MacString,
    NicInfo->BusNumber,
    NicInfo->DeviceNumber,
    NicInfo->FunctionNumber,
    IScsiMode,
    IpMode
    );

  Attempt->AttemptTitleHelpToken = HiiSetString (
                                     mCallbackInfo->RegisteredHandle,
                                     Attempt->AttemptTitleHelpToken,
                                     mPrivate->PortString,
                                     NULL
                                     );
  if (Attempt->AttemptTitleHelpToken == 0) {
    FreePool (MacString);
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Check whether this attempt is an existing one.
  //
  ExistAttempt = IScsiConfigGetAttemptByConfigIndex (Attempt->AttemptConfigIndex);
  if (ExistAttempt != NULL) {
    ASSERT (ExistAttempt == Attempt);

    if ((IfrNvData->Enabled == ISCSI_DISABLED) &&
        (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED))
    {
      //
      // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".
      //
      if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
        if (mPrivate->MpioCount < 1) {
          return EFI_ABORTED;
        }

        if (--mPrivate->MpioCount == 0) {
          mPrivate->EnableMpio = FALSE;
        }
      } else if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED) {
        if (mPrivate->SinglePathCount < 1) {
          return EFI_ABORTED;
        }

        mPrivate->SinglePathCount--;
      }
    } else if ((IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) &&
               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED))
    {
      //
      // User updates the Attempt from "Enabled" to "Enabled for MPIO".
      //
      if (mPrivate->SinglePathCount < 1) {
        return EFI_ABORTED;
      }

      mPrivate->EnableMpio = TRUE;
      mPrivate->MpioCount++;
      mPrivate->SinglePathCount--;
    } else if ((IfrNvData->Enabled == ISCSI_ENABLED) &&
               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO))
    {
      //
      // User updates the Attempt from "Enabled for MPIO" to "Enabled".
      //
      if (mPrivate->MpioCount < 1) {
        return EFI_ABORTED;
      }

      if (--mPrivate->MpioCount == 0) {
        mPrivate->EnableMpio = FALSE;
      }

      mPrivate->SinglePathCount++;
    } else if ((IfrNvData->Enabled != ISCSI_DISABLED) &&
               (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED))
    {
      //
      // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".
      //
      if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {
        mPrivate->EnableMpio = TRUE;
        mPrivate->MpioCount++;
      } else if (IfrNvData->Enabled == ISCSI_ENABLED) {
        mPrivate->SinglePathCount++;
      }
    }
  } else if (ExistAttempt == NULL) {
    //
    // When a new attempt is created, pointer of the attempt is saved to
    // mCallbackInfo->Current in IScsiConfigProcessDefault. If input Attempt
    // does not match any existing attempt, it should be a new created attempt.
    // Save it to system now.
    //

    //
    // Save current order number for this attempt.
    //
    AttemptConfigOrder = IScsiGetVariableAndSize (
                           L"AttemptOrder",
                           &gIScsiConfigGuid,
                           &AttemptConfigOrderSize
                           );

    TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);
    TotalNumber++;

    //
    // Append the new created attempt order to the end.
    //
    AttemptOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));
    if (AttemptOrderTmp == NULL) {
      if (AttemptConfigOrder != NULL) {
        FreePool (AttemptConfigOrder);
      }

      return EFI_OUT_OF_RESOURCES;
    }

    if (AttemptConfigOrder != NULL) {
      CopyMem (AttemptOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);
      FreePool (AttemptConfigOrder);
    }

    AttemptOrderTmp[TotalNumber - 1] = Attempt->AttemptConfigIndex;
    AttemptConfigOrder               = AttemptOrderTmp;
    AttemptConfigOrderSize           = TotalNumber * sizeof (UINT8);

    Status = gRT->SetVariable (
                    L"AttemptOrder",
                    &gIScsiConfigGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    AttemptConfigOrderSize,
                    AttemptConfigOrder
                    );
    FreePool (AttemptConfigOrder);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Insert new created attempt to array.
    //
    InsertTailList (&mPrivate->AttemptConfigs, &Attempt->Link);
    mPrivate->AttemptCount++;

    if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {
      //
      // This new Attempt is enabled for MPIO; enable the multipath mode.
      //
      mPrivate->EnableMpio = TRUE;
      mPrivate->MpioCount++;
    } else if (IfrNvData->Enabled == ISCSI_ENABLED) {
      mPrivate->SinglePathCount++;
    }

    IScsiConfigUpdateAttempt ();
  }

  Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;

  //
  // Record the user configuration information in NVR.
  //
  UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", Attempt->AttemptConfigIndex);

  FreePool (MacString);

  return gRT->SetVariable (
                mPrivate->PortString,
                &gEfiIScsiInitiatorNameProtocolGuid,
                ISCSI_CONFIG_VAR_ATTR,
                sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
                Attempt
                );
}

/**
  Convert the IFR data configured by keyword to iSCSI configuration data.

  @param[in]  IfrNvData      Point to ISCSI_CONFIG_IFR_NVDATA.
  @param[in]  OffSet         The offset of the variable to the configuration structure.

  @retval EFI_INVALID_PARAMETER  Any input or configured parameter is invalid.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (
  IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData,
  IN UINTN                    OffSet
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA  *Attempt;
  UINT8                        AttemptIndex;
  UINT8                        Index;
  UINT8                        ChapSecretLen;
  UINT8                        ReverseChapSecretLen;
  CHAR16                       *AttemptName1;
  CHAR16                       *AttemptName2;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *SameNicAttempt;
  CHAR8                        LunString[ISCSI_LUN_STR_MAX_LEN];
  CHAR8                        IScsiName[ISCSI_NAME_MAX_SIZE];
  CHAR8                        IpString[IP_STR_MAX_SIZE];
  EFI_IP_ADDRESS               HostIp;
  EFI_IP_ADDRESS               SubnetMask;
  EFI_IP_ADDRESS               Gateway;
  EFI_INPUT_KEY                Key;
  UINT64                       Lun;
  EFI_STATUS                   Status;

  Attempt = NULL;
  ZeroMem (IScsiName, sizeof (IScsiName));

  if (OffSet < ATTEMPT_BOOTENABLE_VAR_OFFSET) {
    return EFI_SUCCESS;
  } else if ((OffSet >= ATTEMPT_BOOTENABLE_VAR_OFFSET) && (OffSet < ATTEMPT_ADDRESS_TYPE_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_BOOTENABLE_VAR_OFFSET) + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    IfrNvData->Enabled = IfrNvData->ISCSIBootEnableList[AttemptIndex - 1];
    //
    // Validate the configuration of attempt.
    //
    if (IfrNvData->Enabled != ISCSI_DISABLED) {
      //
      // Check whether this attempt uses NIC which is already used by existing attempt.
      //
      SameNicAttempt = IScsiConfigGetAttemptByNic (Attempt, IfrNvData->Enabled);
      if (SameNicAttempt != NULL) {
        AttemptName1 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));
        if (AttemptName1 == NULL) {
          return EFI_OUT_OF_RESOURCES;
        }

        AttemptName2 = (CHAR16 *)AllocateZeroPool (ATTEMPT_NAME_SIZE * sizeof (CHAR16));
        if (AttemptName2 == NULL) {
          FreePool (AttemptName1);
          return EFI_OUT_OF_RESOURCES;
        }

        AsciiStrToUnicodeStrS (Attempt->AttemptName, AttemptName1, ATTEMPT_NAME_SIZE);
        AsciiStrToUnicodeStrS (SameNicAttempt->AttemptName, AttemptName2, ATTEMPT_NAME_SIZE);

        UnicodeSPrint (
          mPrivate->PortString,
          (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
          L"Warning! \"%s\" uses same NIC as Attempt \"%s\".",
          AttemptName1,
          AttemptName2
          );

        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          mPrivate->PortString,
          NULL
          );

        FreePool (AttemptName1);
        FreePool (AttemptName2);
      }
    }

    if ((IfrNvData->Enabled == ISCSI_DISABLED) &&
        (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED))
    {
      //
      // User updates the Attempt from "Enabled"/"Enabled for MPIO" to "Disabled".
      //
      if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
        if (mPrivate->MpioCount < 1) {
          return EFI_ABORTED;
        }

        if (--mPrivate->MpioCount == 0) {
          mPrivate->EnableMpio = FALSE;
        }
      } else if (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED) {
        if (mPrivate->SinglePathCount < 1) {
          return EFI_ABORTED;
        }

        mPrivate->SinglePathCount--;
      }
    } else if ((IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) &&
               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED))
    {
      //
      // User updates the Attempt from "Enabled" to "Enabled for MPIO".
      //
      if (mPrivate->SinglePathCount < 1) {
        return EFI_ABORTED;
      }

      mPrivate->EnableMpio = TRUE;
      mPrivate->MpioCount++;
      mPrivate->SinglePathCount--;
    } else if ((IfrNvData->Enabled == ISCSI_ENABLED) &&
               (Attempt->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO))
    {
      //
      // User updates the Attempt from "Enabled for MPIO" to "Enabled".
      //
      if (mPrivate->MpioCount < 1) {
        return EFI_ABORTED;
      }

      if (--mPrivate->MpioCount == 0) {
        mPrivate->EnableMpio = FALSE;
      }

      mPrivate->SinglePathCount++;
    } else if ((IfrNvData->Enabled != ISCSI_DISABLED) &&
               (Attempt->SessionConfigData.Enabled == ISCSI_DISABLED))
    {
      //
      // User updates the Attempt from "Disabled" to "Enabled"/"Enabled for MPIO".
      //
      if (IfrNvData->Enabled == ISCSI_ENABLED_FOR_MPIO) {
        mPrivate->EnableMpio = TRUE;
        mPrivate->MpioCount++;
      } else if (IfrNvData->Enabled == ISCSI_ENABLED) {
        mPrivate->SinglePathCount++;
      }
    }

    Attempt->SessionConfigData.Enabled = IfrNvData->Enabled;
  } else if ((OffSet >= ATTEMPT_ADDRESS_TYPE_VAR_OFFSET) && (OffSet < ATTEMPT_CONNECT_RETRY_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_ADDRESS_TYPE_VAR_OFFSET) + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    Attempt->SessionConfigData.IpMode = IfrNvData->ISCSIIpAddressTypeList[AttemptIndex - 1];
    if (Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) {
      Attempt->AutoConfigureMode = 0;
    }
  } else if ((OffSet >= ATTEMPT_CONNECT_RETRY_VAR_OFFSET) && (OffSet < ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_CONNECT_RETRY_VAR_OFFSET) + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if (IfrNvData->ISCSIConnectRetry[AttemptIndex - 1] > CONNECT_MAX_RETRY) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"The minimum value is 0 and the maximum is 16. 0 means no retry.",
        NULL
        );
      return EFI_INVALID_PARAMETER;
    }

    Attempt->SessionConfigData.ConnectRetryCount = IfrNvData->ISCSIConnectRetry[AttemptIndex - 1];
  } else if ((OffSet >= ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_CONNECT_TIMEOUT_VAR_OFFSET) / 2 + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if ((IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1] < CONNECT_MIN_TIMEOUT) ||
        (IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1] > CONNECT_MAX_TIMEOUT))
    {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"The minimum value is 100 milliseconds and the maximum is 20 seconds.",
        NULL
        );
      return EFI_INVALID_PARAMETER;
    }

    Attempt->SessionConfigData.ConnectTimeout = IfrNvData->ISCSIConnectTimeout[AttemptIndex - 1];
    if (Attempt->SessionConfigData.ConnectTimeout == 0) {
      Attempt->SessionConfigData.ConnectTimeout = CONNECT_DEFAULT_TIMEOUT;
    }
  } else if ((OffSet >= ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_INITIATOR_VIA_DHCP_VAR_OFFSET) + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    Attempt->SessionConfigData.InitiatorInfoFromDhcp = IfrNvData->ISCSIInitiatorInfoViaDHCP[AttemptIndex - 1];
  } else if ((OffSet >= ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_TARGET_VIA_DHCP_VAR_OFFSET) + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {
      Attempt->SessionConfigData.TargetInfoFromDhcp = IfrNvData->ISCSITargetInfoViaDHCP[AttemptIndex - 1];
    } else {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Invalid Configuration, Check value of IpMode or Enable DHCP!",
        NULL
        );
      return EFI_INVALID_PARAMETER;
    }
  } else if ((OffSet >= ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET) && (OffSet < ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_TARGET_TCP_PORT_VAR_OFFSET) / 2 + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {
      Attempt->SessionConfigData.TargetPort = IfrNvData->ISCSITargetTcpPort[AttemptIndex - 1];
      if (Attempt->SessionConfigData.TargetPort == 0) {
        Attempt->SessionConfigData.TargetPort = ISCSI_WELL_KNOWN_PORT;
      }
    } else {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
        NULL
        );
      return EFI_INVALID_PARAMETER;
    }
  } else if ((OffSet >= ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET) && (OffSet < ATTEMPT_CHARTYPE_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_AUTHENTICATION_METHOD_VAR_OFFSET) + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    Attempt->AuthenticationType = IfrNvData->ISCSIAuthenticationMethod[AttemptIndex - 1];
  } else if ((OffSet >= ATTEMPT_CHARTYPE_VAR_OFFSET) && (OffSet < ATTEMPT_ISID_VAR_OFFSET)) {
    AttemptIndex = (UINT8)((OffSet - ATTEMPT_CHARTYPE_VAR_OFFSET) + 1);
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
      Attempt->AuthConfigData.CHAP.CHAPType = IfrNvData->ISCSIChapType[AttemptIndex - 1];
    }
  } else if (OffSet >= ATTEMPT_ISID_VAR_OFFSET) {
    Index        = (UINT8)((OffSet - ATTEMPT_ISID_VAR_OFFSET) / sizeof (KEYWORD_STR));
    AttemptIndex = Index + 1;
    Attempt      = IScsiConfigGetAttemptByConfigIndex (AttemptIndex);
    if (Attempt == NULL) {
      return EFI_INVALID_PARAMETER;
    }

    OffSet = OffSet - Index * sizeof (KEYWORD_STR);

    if ((OffSet >= ATTEMPT_ISID_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET)) {
      IScsiParseIsIdFromString (IfrNvData->Keyword[Index].ISCSIIsId, Attempt->SessionConfigData.IsId);
    } else if ((OffSet >= ATTEMPT_INITIATOR_IP_ADDRESS_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET)) {
      if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {
        //
        // Config Local ip
        //
        Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorIpAddress, &HostIp.v4);
        if (EFI_ERROR (Status) || ((Attempt->SessionConfigData.SubnetMask.Addr[0] != 0) &&
                                   !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), NTOHL (*(UINT32 *)Attempt->SessionConfigData.SubnetMask.Addr))))
        {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid IP address!",
            NULL
            );
          return EFI_INVALID_PARAMETER;
        } else {
          CopyMem (&Attempt->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of IpMode or Enable DHCP!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_INITIATOR_NET_MASK_VAR_OFFSET) && (OffSet < ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET)) {
      if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {
        Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorNetmask, &SubnetMask.v4);
        if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid Subnet Mask!",
            NULL
            );
          return EFI_INVALID_PARAMETER;
        } else {
          CopyMem (&Attempt->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of IpMode or Enable DHCP!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_INITIATOR_GATE_WAY_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_NAME_VAR_OFFSET)) {
      if ((Attempt->SessionConfigData.IpMode == IP_MODE_IP4) && (!Attempt->SessionConfigData.InitiatorInfoFromDhcp)) {
        Status = NetLibStrToIp4 (IfrNvData->Keyword[Index].ISCSIInitiatorGateway, &Gateway.v4);
        if (EFI_ERROR (Status) ||
            ((Gateway.Addr[0] != 0) && (Attempt->SessionConfigData.SubnetMask.Addr[0] != 0) &&
             !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (*(UINT32 *)Attempt->SessionConfigData.SubnetMask.Addr))))
        {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid Gateway!",
            NULL
            );
          return EFI_INVALID_PARAMETER;
        } else {
          CopyMem (&Attempt->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of IpMode or Enable DHCP!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_TARGET_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET)) {
      if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {
        UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetName, IScsiName, ISCSI_NAME_MAX_SIZE);
        Status = IScsiNormalizeName (IScsiName, AsciiStrLen (IScsiName));
        if (EFI_ERROR (Status)) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid iSCSI Name!",
            NULL
            );
        } else {
          AsciiStrCpyS (Attempt->SessionConfigData.TargetName, ISCSI_NAME_MAX_SIZE, IScsiName);
        }

        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {
          if (Attempt->SessionConfigData.TargetName[0] == L'\0') {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"iSCSI target name is NULL!",
              NULL
              );
            return EFI_INVALID_PARAMETER;
          }
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_TARGET_IP_ADDRESS_VAR_OFFSET) && (OffSet < ATTEMPT_LUN_VAR_OFFSET)) {
      if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (!Attempt->SessionConfigData.TargetInfoFromDhcp)) {
        UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetIpAddress, IpString, sizeof (IpString));
        Status = IScsiAsciiStrToIp (IpString, Attempt->SessionConfigData.IpMode, &HostIp);
        if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, Attempt->SessionConfigData.IpMode)) {
          Attempt->SessionConfigData.DnsMode = TRUE;
          ZeroMem (&Attempt->SessionConfigData.TargetIp, sizeof (Attempt->SessionConfigData.TargetIp));
          UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSITargetIpAddress, Attempt->SessionConfigData.TargetUrl, ISCSI_NAME_MAX_SIZE);
        } else {
          Attempt->SessionConfigData.DnsMode = FALSE;
          CopyMem (&Attempt->SessionConfigData.TargetIp, &HostIp, sizeof (HostIp));
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_LUN_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_USER_NAME_VAR_OFFSET)) {
      if ((Attempt->SessionConfigData.IpMode < IP_MODE_AUTOCONFIG) && (Attempt->SessionConfigData.TargetInfoFromDhcp == 0)) {
        //
        // Config LUN.
        //
        UnicodeStrToAsciiStrS (IfrNvData->Keyword[Index].ISCSILun, LunString, ISCSI_LUN_STR_MAX_LEN);
        Status = IScsiAsciiStrToLun (LunString, (UINT8 *)&Lun);
        if (EFI_ERROR (Status)) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid LUN string, Examples are: 4752-3A4F-6b7e-2F99, 6734-9-156f-127, 4186-9!",
            NULL
            );
        } else {
          CopyMem (&Attempt->SessionConfigData.BootLun, &Lun, sizeof (Lun));
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of IpMode or Target Via DHCP!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_CHAR_USER_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_SECRET_VAR_OFFSET)) {
      if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
        UnicodeStrToAsciiStrS (
          IfrNvData->Keyword[Index].ISCSIChapUsername,
          Attempt->AuthConfigData.CHAP.CHAPName,
          ISCSI_CHAP_NAME_STORAGE
          );

        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {
          if (IfrNvData->Keyword[Index].ISCSIChapUsername[0] == L'\0') {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"CHAP Name is invalid!",
              NULL
              );
            return EFI_INVALID_PARAMETER;
          }
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of AuthenticationType!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_CHAR_SECRET_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET)) {
      if (Attempt->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
        ChapSecretLen = (UINT8)StrLen (IfrNvData->Keyword[Index].ISCSIChapSecret);
        UnicodeStrToAsciiStrS (
          IfrNvData->Keyword[Index].ISCSIChapSecret,
          Attempt->AuthConfigData.CHAP.CHAPSecret,
          ISCSI_CHAP_SECRET_STORAGE
          );

        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {
          if ((ChapSecretLen < ISCSI_CHAP_SECRET_MIN_LEN) || (ChapSecretLen > ISCSI_CHAP_SECRET_MAX_LEN)) {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"The Chap Secret minimum length is 12 bytes and the maximum length is 16 bytes.",
              NULL
              );
            return EFI_INVALID_PARAMETER;
          }
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of AuthenticationType!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if ((OffSet >= ATTEMPT_CHAR_REVERSE_USER_NAME_VAR_OFFSET) && (OffSet < ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET)) {
      if (Attempt->AuthConfigData.CHAP.CHAPType == ISCSI_CHAP_MUTUAL) {
        UnicodeStrToAsciiStrS (
          IfrNvData->Keyword[Index].ISCSIReverseChapUsername,
          Attempt->AuthConfigData.CHAP.ReverseCHAPName,
          ISCSI_CHAP_NAME_STORAGE
          );
        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {
          if (IfrNvData->Keyword[Index].ISCSIReverseChapUsername[0] == L'\0') {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"Reverse CHAP Name is invalid!",
              NULL
              );
            return EFI_INVALID_PARAMETER;
          }
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of AuthenticationType or Chap Type!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    } else if (OffSet >= ATTEMPT_CHAR_REVERSE_SECRET_VAR_OFFSET) {
      if (Attempt->AuthConfigData.CHAP.CHAPType == ISCSI_CHAP_MUTUAL) {
        ReverseChapSecretLen = (UINT8)StrLen (IfrNvData->Keyword[Index].ISCSIReverseChapSecret);
        UnicodeStrToAsciiStrS (
          IfrNvData->Keyword[Index].ISCSIReverseChapSecret,
          Attempt->AuthConfigData.CHAP.ReverseCHAPSecret,
          ISCSI_CHAP_SECRET_STORAGE
          );

        if (Attempt->SessionConfigData.Enabled != ISCSI_DISABLED) {
          if ((ReverseChapSecretLen < ISCSI_CHAP_SECRET_MIN_LEN) || (ReverseChapSecretLen > ISCSI_CHAP_SECRET_MAX_LEN)) {
            CreatePopUp (
              EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
              &Key,
              L"The Reverse CHAP Secret minimum length is 12 bytes and the maximum length is 16 bytes.",
              NULL
              );
            return EFI_INVALID_PARAMETER;
          }
        }
      } else {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Invalid Configuration, Check value of AuthenticationType or Chap Type!",
          NULL
          );
        return EFI_INVALID_PARAMETER;
      }
    }
  }

  //
  // Record the user configuration information in NVR.
  //
  ASSERT (Attempt != NULL);
  UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", Attempt->AttemptConfigIndex);
  return gRT->SetVariable (
                mPrivate->PortString,
                &gEfiIScsiInitiatorNameProtocolGuid,
                ISCSI_CONFIG_VAR_ATTR,
                sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
                Attempt
                );
}

/**
  Create Hii Extend Label OpCode as the start opcode and end opcode. It is
  a help function.

  @param[in]  StartLabelNumber   The number of start label.
  @param[out] StartOpCodeHandle  Points to the start opcode handle.
  @param[out] StartLabel         Points to the created start opcode.
  @param[out] EndOpCodeHandle    Points to the end opcode handle.
  @param[out] EndLabel           Points to the created end opcode.

  @retval EFI_OUT_OF_RESOURCES   Do not have sufficient resource to finish this
                                 operation.
  @retval EFI_INVALID_PARAMETER  Any input parameter is invalid.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiCreateOpCode (
  IN  UINT16              StartLabelNumber,
  OUT VOID                **StartOpCodeHandle,
  OUT EFI_IFR_GUID_LABEL  **StartLabel,
  OUT VOID                **EndOpCodeHandle,
  OUT EFI_IFR_GUID_LABEL  **EndLabel
  )
{
  EFI_STATUS          Status;
  EFI_IFR_GUID_LABEL  *InternalStartLabel;
  EFI_IFR_GUID_LABEL  *InternalEndLabel;

  if ((StartOpCodeHandle == NULL) || (StartLabel == NULL) || (EndOpCodeHandle == NULL) || (EndLabel == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *StartOpCodeHandle = NULL;
  *EndOpCodeHandle   = NULL;
  Status             = EFI_OUT_OF_RESOURCES;

  //
  // Initialize the container for dynamic opcodes.
  //
  *StartOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (*StartOpCodeHandle == NULL) {
    return Status;
  }

  *EndOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (*EndOpCodeHandle == NULL) {
    goto Exit;
  }

  //
  // Create Hii Extend Label OpCode as the start opcode.
  //
  InternalStartLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                               *StartOpCodeHandle,
                                               &gEfiIfrTianoGuid,
                                               NULL,
                                               sizeof (EFI_IFR_GUID_LABEL)
                                               );
  if (InternalStartLabel == NULL) {
    goto Exit;
  }

  InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  InternalStartLabel->Number       = StartLabelNumber;

  //
  // Create Hii Extend Label OpCode as the end opcode.
  //
  InternalEndLabel = (EFI_IFR_GUID_LABEL *)HiiCreateGuidOpCode (
                                             *EndOpCodeHandle,
                                             &gEfiIfrTianoGuid,
                                             NULL,
                                             sizeof (EFI_IFR_GUID_LABEL)
                                             );
  if (InternalEndLabel == NULL) {
    goto Exit;
  }

  InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
  InternalEndLabel->Number       = LABEL_END;

  *StartLabel = InternalStartLabel;
  *EndLabel   = InternalEndLabel;

  return EFI_SUCCESS;

Exit:

  if (*StartOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (*StartOpCodeHandle);
  }

  if (*EndOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (*EndOpCodeHandle);
  }

  return Status;
}

/**
  Update the MAIN form to display the configured attempts.

**/
VOID
IScsiConfigUpdateAttempt (
  VOID
  )
{
  LIST_ENTRY                   *Entry;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  VOID                         *StartOpCodeHandle;
  EFI_IFR_GUID_LABEL           *StartLabel;
  VOID                         *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL           *EndLabel;
  EFI_STATUS                   Status;

  Status = IScsiCreateOpCode (
             ATTEMPT_ENTRY_LABEL,
             &StartOpCodeHandle,
             &StartLabel,
             &EndOpCodeHandle,
             &EndLabel
             );
  if (EFI_ERROR (Status)) {
    return;
  }

  NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    if (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED) {
      //
      // Update Attempt Help Info.
      //
      UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", (UINTN)AttemptConfigData->AttemptConfigIndex);
      AttemptConfigData->AttemptTitleToken = HiiSetString (
                                               mCallbackInfo->RegisteredHandle,
                                               0,
                                               mPrivate->PortString,
                                               NULL
                                               );
      if (AttemptConfigData->AttemptTitleToken == 0) {
        return;
      }

      HiiCreateGotoOpCode (
        StartOpCodeHandle,                                                       // Container for dynamic created opcodes
        FORMID_ATTEMPT_FORM,                                                     // Form ID
        AttemptConfigData->AttemptTitleToken,                                    // Prompt text
        AttemptConfigData->AttemptTitleHelpToken,                                // Help text
        EFI_IFR_FLAG_CALLBACK,                                                   // Question flag
        (UINT16)(KEY_ATTEMPT_ENTRY_BASE + AttemptConfigData->AttemptConfigIndex) // Question ID
        );
    }
  }

  HiiUpdateForm (
    mCallbackInfo->RegisteredHandle, // HII handle
    &gIScsiConfigGuid,               // Formset GUID
    FORMID_MAIN_FORM,                // Form ID
    StartOpCodeHandle,               // Label for where to insert opcodes
    EndOpCodeHandle                  // Replace data
    );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
}

/**
  Callback function when user presses "Add an Attempt".

  @retval EFI_OUT_OF_RESOURCES   Does not have sufficient resources to finish this
                                 operation.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiConfigAddAttempt (
  VOID
  )
{
  LIST_ENTRY          *Entry;
  ISCSI_NIC_INFO      *NicInfo;
  EFI_STRING_ID       PortTitleToken;
  EFI_STRING_ID       PortTitleHelpToken;
  CHAR16              MacString[ISCSI_MAX_MAC_STRING_LEN];
  EFI_STATUS          Status;
  VOID                *StartOpCodeHandle;
  EFI_IFR_GUID_LABEL  *StartLabel;
  VOID                *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL  *EndLabel;

  Status = IScsiCreateOpCode (
             MAC_ENTRY_LABEL,
             &StartOpCodeHandle,
             &StartLabel,
             &EndOpCodeHandle,
             &EndLabel
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Ask user to select a MAC for this attempt.
  //
  NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    IScsiMacAddrToStr (
      &NicInfo->PermanentAddress,
      NicInfo->HwAddressSize,
      NicInfo->VlanId,
      MacString
      );

    UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"MAC %s", MacString);
    PortTitleToken = HiiSetString (
                       mCallbackInfo->RegisteredHandle,
                       0,
                       mPrivate->PortString,
                       NULL
                       );
    if (PortTitleToken == 0) {
      Status = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"PFA: Bus %d | Dev %d | Func %d",
      NicInfo->BusNumber,
      NicInfo->DeviceNumber,
      NicInfo->FunctionNumber
      );
    PortTitleHelpToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, mPrivate->PortString, NULL);
    if (PortTitleHelpToken == 0) {
      Status = EFI_INVALID_PARAMETER;
      goto Exit;
    }

    HiiCreateGotoOpCode (
      StartOpCodeHandle,                      // Container for dynamic created opcodes
      FORMID_ATTEMPT_FORM,
      PortTitleToken,
      PortTitleHelpToken,
      EFI_IFR_FLAG_CALLBACK,                  // Question flag
      (UINT16)(KEY_MAC_ENTRY_BASE + NicInfo->NicIndex)
      );
  }

  Status = HiiUpdateForm (
             mCallbackInfo->RegisteredHandle, // HII handle
             &gIScsiConfigGuid,               // Formset GUID
             FORMID_MAC_FORM,                 // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

Exit:
  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  return Status;
}

/**
  Add the attempts by keyword 'iSCSIAddAttempts', you can use this keyword with
  value 'attempt:1 attempt:2' etc to add one or more attempts once. This is different
  with IScsiConfigAddAttempt function which is used to add attempt by UI configuration.

  @param[in]  AttemptList        The new attempt List will be added.

  @retval EFI_SUCCESS            The operation to add attempt list successfully.
  @retval EFI_INVALID_PARAMETER  Any parameter is invalid.
  @retval EFI_NOT_FOUND          Cannot find the corresponding variable.
  @retval EFI_OUT_OF_RESOURCES   Fail to finish the operation due to lack of
                                 resources.

**/
EFI_STATUS
IScsiConfigAddAttemptsByKeywords (
  IN UINT8  *AttemptList
  )
{
  UINT8                        Index;
  UINT8                        Number;
  UINTN                        TotalNumber;
  UINT8                        Nic;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINT8                        *AttemptConfigOrderTmp;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  ISCSI_NIC_INFO               *NicInfo;
  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR16                       IScsiMode[64];
  CHAR16                       IpMode[64];
  EFI_STATUS                   Status;

  Nic     = mPrivate->CurrentNic;
  NicInfo = IScsiGetNicInfoByIndex (Nic);
  if (NicInfo == NULL) {
    return EFI_NOT_FOUND;
  }

  //
  // The MAC info will be recorded in Config Data.
  //
  IScsiMacAddrToStr (
    &NicInfo->PermanentAddress,
    NicInfo->HwAddressSize,
    NicInfo->VlanId,
    MacString
    );

  for (Index = 0; Index < PcdGet8 (PcdMaxIScsiAttemptNumber); Index++) {
    if (AttemptList[Index] == 0) {
      continue;
    }

    //
    // Add the attempt.
    //
    Number = AttemptList[Index];

    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"Attempt %d",
      Number
      );

    GetVariable2 (
      mPrivate->PortString,
      &gEfiIScsiInitiatorNameProtocolGuid,
      (VOID **)&AttemptConfigData,
      NULL
      );
    if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED)) {
      return EFI_INVALID_PARAMETER;
    }

    AttemptConfigData->Actived  = ISCSI_ACTIVE_ENABLED;
    AttemptConfigData->NicIndex = NicInfo->NicIndex;
    UnicodeStrToAsciiStrS (MacString, AttemptConfigData->MacString, ISCSI_MAX_MAC_STRING_LEN);

    //
    // Generate OUI-format ISID based on MAC address.
    //
    CopyMem (AttemptConfigData->SessionConfigData.IsId, &NicInfo->PermanentAddress, 6);
    AttemptConfigData->SessionConfigData.IsId[0] =
      (UINT8)(AttemptConfigData->SessionConfigData.IsId[0] & 0x3F);

    //
    // Configure the iSCSI Mode and IpMode to default.
    // Add Attempt Help Info.
    //
    UnicodeSPrint (IScsiMode, 64, L"Disabled");
    UnicodeSPrint (IpMode, 64, L"IP4");
    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"MAC: %s, PFA: Bus %d | Dev %d | Func %d, iSCSI mode: %s, IP version: %s",
      MacString,
      NicInfo->BusNumber,
      NicInfo->DeviceNumber,
      NicInfo->FunctionNumber,
      IScsiMode,
      IpMode
      );

    AttemptConfigData->AttemptTitleHelpToken = HiiSetString (
                                                 mCallbackInfo->RegisteredHandle,
                                                 0,
                                                 mPrivate->PortString,
                                                 NULL
                                                 );
    if (AttemptConfigData->AttemptTitleHelpToken == 0) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Get current Attempt order and number.
    //
    AttemptConfigOrder = IScsiGetVariableAndSize (
                           L"AttemptOrder",
                           &gIScsiConfigGuid,
                           &AttemptConfigOrderSize
                           );
    TotalNumber = AttemptConfigOrderSize / sizeof (UINT8);
    TotalNumber++;

    //
    // Append the new created attempt order to the end.
    //
    AttemptConfigOrderTmp = AllocateZeroPool (TotalNumber * sizeof (UINT8));
    if (AttemptConfigOrderTmp == NULL) {
      if (AttemptConfigOrder != NULL) {
        FreePool (AttemptConfigOrder);
      }

      return EFI_OUT_OF_RESOURCES;
    }

    if (AttemptConfigOrder != NULL) {
      CopyMem (AttemptConfigOrderTmp, AttemptConfigOrder, AttemptConfigOrderSize);
      FreePool (AttemptConfigOrder);
    }

    AttemptConfigOrderTmp[TotalNumber - 1] = Number;
    AttemptConfigOrder                     = AttemptConfigOrderTmp;
    AttemptConfigOrderSize                 = TotalNumber * sizeof (UINT8);

    Status = gRT->SetVariable (
                    L"AttemptOrder",
                    &gIScsiConfigGuid,
                    EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                    AttemptConfigOrderSize,
                    AttemptConfigOrder
                    );
    FreePool (AttemptConfigOrder);
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Record the attempt in global link list.
    //
    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);
    mPrivate->AttemptCount++;
    UnicodeSPrint (mPrivate->PortString, (UINTN)ISCSI_NAME_IFR_MAX_SIZE, L"Attempt %d", AttemptConfigData->AttemptConfigIndex);
    gRT->SetVariable (
           mPrivate->PortString,
           &gEfiIScsiInitiatorNameProtocolGuid,
           ISCSI_CONFIG_VAR_ATTR,
           sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
           AttemptConfigData
           );
  }

  return EFI_SUCCESS;
}

/**
  Callback function when user presses "Commit Changes and Exit" in Delete Attempts or Delete Attempts by Keyword.

  @param[in]  IfrNvData          The IFR NV data.

  @retval EFI_NOT_FOUND          Cannot find the corresponding variable.
  @retval EFI_SUCCESS            The operation is completed successfully.
  @retval EFI_ABORTED            This operation is aborted cause of error
                                 configuration.
  @retval EFI_OUT_OF_RESOURCES   Fail to finish the operation due to lack of
                                 resources.

**/
EFI_STATUS
IScsiConfigDeleteAttempts (
  IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData
  )
{
  EFI_STATUS                   Status;
  UINTN                        Index;
  UINTN                        NewIndex;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINT8                        *AttemptNewOrder;
  UINT8                        AttemptConfigIndex;
  UINT32                       Attribute;
  UINTN                        Total;
  UINTN                        NewTotal;
  LIST_ENTRY                   *Entry;
  LIST_ENTRY                   *NextEntry;
  ISCSI_SESSION_CONFIG_NVDATA  *ConfigData;

  Index = 0;

  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if ((AttemptConfigOrder == NULL) || (AttemptConfigOrderSize == 0)) {
    return EFI_NOT_FOUND;
  }

  AttemptNewOrder = AllocateZeroPool (AttemptConfigOrderSize);
  if (AttemptNewOrder == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  Total    = AttemptConfigOrderSize / sizeof (UINT8);
  NewTotal = Total;

  NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {
    if (IfrNvData->DeleteAttemptList[Index] == 0) {
      Index++;
      continue;
    }

    //
    // Delete the attempt.
    //

    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);

    //
    // Remove this attempt from UI configured attempt list.
    //
    RemoveEntryList (&AttemptConfigData->Link);
    mPrivate->AttemptCount--;

    if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED_FOR_MPIO) {
      if (mPrivate->MpioCount < 1) {
        Status = EFI_ABORTED;
        goto Error;
      }

      //
      // No more attempt is enabled for MPIO. Transit the iSCSI mode to single path.
      //
      if (--mPrivate->MpioCount == 0) {
        mPrivate->EnableMpio = FALSE;
      }
    } else if (AttemptConfigData->SessionConfigData.Enabled == ISCSI_ENABLED) {
      if (mPrivate->SinglePathCount < 1) {
        Status = EFI_ABORTED;
        goto Error;
      }

      mPrivate->SinglePathCount--;
    }

    AttemptConfigIndex = AttemptConfigData->AttemptConfigIndex;
    FreePool (AttemptConfigData);

    //
    // Create a new Attempt
    //
    AttemptConfigData = AllocateZeroPool (sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA));
    if (AttemptConfigData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    ConfigData                    = &AttemptConfigData->SessionConfigData;
    ConfigData->TargetPort        = ISCSI_WELL_KNOWN_PORT;
    ConfigData->ConnectTimeout    = CONNECT_DEFAULT_TIMEOUT;
    ConfigData->ConnectRetryCount = CONNECT_MIN_RETRY;

    AttemptConfigData->AuthenticationType           = ISCSI_AUTH_TYPE_CHAP;
    AttemptConfigData->AuthConfigData.CHAP.CHAPType = ISCSI_CHAP_UNI;
    //
    // Configure the Attempt index and set variable.
    //
    AttemptConfigData->AttemptConfigIndex = AttemptConfigIndex;

    //
    // Set the attempt name to default.
    //
    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"Attempt %d",
      (UINTN)AttemptConfigData->AttemptConfigIndex
      );
    UnicodeStrToAsciiStrS (mPrivate->PortString, AttemptConfigData->AttemptName, ATTEMPT_NAME_SIZE);
    gRT->SetVariable (
           mPrivate->PortString,
           &gEfiIScsiInitiatorNameProtocolGuid,
           ISCSI_CONFIG_VAR_ATTR,
           sizeof (ISCSI_ATTEMPT_CONFIG_NVDATA),
           AttemptConfigData
           );

    //
    // Mark the attempt order in NVR to be deleted - 0.
    //
    for (NewIndex = 0; NewIndex < Total; NewIndex++) {
      if (AttemptConfigOrder[NewIndex] == AttemptConfigData->AttemptConfigIndex) {
        AttemptConfigOrder[NewIndex] = 0;
        break;
      }
    }

    NewTotal--;
    if (mCallbackInfo->Current == AttemptConfigData) {
      mCallbackInfo->Current = NULL;
    }

    FreePool (AttemptConfigData);

    //
    // Check next Attempt.
    //
    Index++;
  }

  //
  // Construct AttemptNewOrder.
  //
  for (Index = 0, NewIndex = 0; Index < Total; Index++) {
    if (AttemptConfigOrder[Index] != 0) {
      AttemptNewOrder[NewIndex] = AttemptConfigOrder[Index];
      NewIndex++;
    }
  }

  Attribute = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE;

  //
  // Update AttemptOrder in NVR.
  //
  Status = gRT->SetVariable (
                  L"AttemptOrder",
                  &gIScsiConfigGuid,
                  Attribute,
                  NewTotal * sizeof (UINT8),
                  AttemptNewOrder
                  );

Error:
  if (AttemptConfigOrder != NULL) {
    FreePool (AttemptConfigOrder);
  }

  if (AttemptNewOrder != NULL) {
    FreePool (AttemptNewOrder);
  }

  return Status;
}

/**
  Callback function when user presses "Delete Attempts".

  @param[in]  IfrNvData          The IFR nv data.

  @retval EFI_INVALID_PARAMETER  Any parameter is invalid.
  @retval EFI_BUFFER_TOO_SMALL   The buffer in UpdateData is too small.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiConfigDisplayDeleteAttempts (
  IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData
  )
{
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  LIST_ENTRY                   *Entry;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  UINT8                        Index;
  VOID                         *StartOpCodeHandle;
  EFI_IFR_GUID_LABEL           *StartLabel;
  VOID                         *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL           *EndLabel;
  EFI_STATUS                   Status;

  Status = IScsiCreateOpCode (
             DELETE_ENTRY_LABEL,
             &StartOpCodeHandle,
             &StartLabel,
             &EndOpCodeHandle,
             &EndLabel
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if (AttemptConfigOrder != NULL) {
    //
    // Create the check box opcode to be deleted.
    //
    Index = 0;

    NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
      AttemptConfigData                   = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
      IfrNvData->DeleteAttemptList[Index] = 0x00;

      HiiCreateCheckBoxOpCode (
        StartOpCodeHandle,
        (EFI_QUESTION_ID)(ATTEMPT_DEL_QUESTION_ID + Index),
        CONFIGURATION_VARSTORE_ID,
        (UINT16)(ATTEMPT_DEL_VAR_OFFSET + Index),
        AttemptConfigData->AttemptTitleToken,
        AttemptConfigData->AttemptTitleHelpToken,
        0,
        0,
        NULL
        );

      Index++;

      if (Index == ISCSI_MAX_ATTEMPTS_NUM) {
        break;
      }
    }

    FreePool (AttemptConfigOrder);
  }

  Status = HiiUpdateForm (
             mCallbackInfo->RegisteredHandle, // HII handle
             &gIScsiConfigGuid,               // Formset GUID
             FORMID_DELETE_FORM,              // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);

  return Status;
}

/**
  Callback function when user presses "Change Attempt Order".

  @retval EFI_INVALID_PARAMETER  Any parameter is invalid.
  @retval EFI_OUT_OF_RESOURCES   Does not have sufficient resources to finish this
                                 operation.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiConfigDisplayOrderAttempts (
  VOID
  )
{
  EFI_STATUS                   Status;
  UINT8                        Index;
  LIST_ENTRY                   *Entry;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  VOID                         *StartOpCodeHandle;
  EFI_IFR_GUID_LABEL           *StartLabel;
  VOID                         *EndOpCodeHandle;
  EFI_IFR_GUID_LABEL           *EndLabel;
  VOID                         *OptionsOpCodeHandle;

  Status = IScsiCreateOpCode (
             ORDER_ENTRY_LABEL,
             &StartOpCodeHandle,
             &StartLabel,
             &EndOpCodeHandle,
             &EndLabel
             );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  ASSERT (StartOpCodeHandle != NULL);

  OptionsOpCodeHandle = NULL;

  //
  // If no attempt to be ordered, update the original form and exit.
  //
  if (mPrivate->AttemptCount == 0) {
    goto Exit;
  }

  //
  // Create Option OpCode.
  //
  OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
  if (OptionsOpCodeHandle == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  Index = 0;

  NET_LIST_FOR_EACH (Entry, &mPrivate->AttemptConfigs) {
    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    HiiCreateOneOfOptionOpCode (
      OptionsOpCodeHandle,
      AttemptConfigData->AttemptTitleToken,
      0,
      EFI_IFR_NUMERIC_SIZE_1,
      AttemptConfigData->AttemptConfigIndex
      );
    Index++;
  }

  ASSERT (Index == mPrivate->AttemptCount);

  HiiCreateOrderedListOpCode (
    StartOpCodeHandle,                          // Container for dynamic created opcodes
    DYNAMIC_ORDERED_LIST_QUESTION_ID,           // Question ID
    CONFIGURATION_VARSTORE_ID,                  // VarStore ID
    DYNAMIC_ORDERED_LIST_VAR_OFFSET,            // Offset in Buffer Storage
    STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),     // Question prompt text
    STRING_TOKEN (STR_ORDER_ATTEMPT_ENTRY),     // Question help text
    0,                                          // Question flag
    EFI_IFR_UNIQUE_SET,                         // Ordered list flag, e.g. EFI_IFR_UNIQUE_SET
    EFI_IFR_NUMERIC_SIZE_1,                     // Data type of Question value
    ISCSI_MAX_ATTEMPTS_NUM,                     // Maximum container
    OptionsOpCodeHandle,                        // Option Opcode list
    NULL                                        // Default Opcode is NULL
    );

Exit:
  Status = HiiUpdateForm (
             mCallbackInfo->RegisteredHandle, // HII handle
             &gIScsiConfigGuid,               // Formset GUID
             FORMID_ORDER_FORM,               // Form ID
             StartOpCodeHandle,               // Label for where to insert opcodes
             EndOpCodeHandle                  // Replace data
             );

Error:
  HiiFreeOpCodeHandle (StartOpCodeHandle);
  HiiFreeOpCodeHandle (EndOpCodeHandle);
  if (OptionsOpCodeHandle != NULL) {
    HiiFreeOpCodeHandle (OptionsOpCodeHandle);
  }

  return Status;
}

/**
  Callback function when user presses "Commit Changes and Exit" in Change Attempt Order or Change Attempt Order by Keyword.

  @param[in]  IfrNvData          The IFR nv data.

  @retval EFI_OUT_OF_RESOURCES   Does not have sufficient resources to finish this
                                 operation.
  @retval EFI_NOT_FOUND          Cannot find the corresponding variable.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiConfigOrderAttempts (
  IN ISCSI_CONFIG_IFR_NVDATA  *IfrNvData
  )
{
  EFI_STATUS                   Status;
  UINTN                        Index;
  UINTN                        Indexj;
  UINT8                        AttemptConfigIndex;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  UINT8                        *AttemptConfigOrder;
  UINT8                        *AttemptConfigOrderTmp;
  UINTN                        AttemptConfigOrderSize;

  AttemptConfigOrder = IScsiGetVariableAndSize (
                         L"AttemptOrder",
                         &gIScsiConfigGuid,
                         &AttemptConfigOrderSize
                         );
  if (AttemptConfigOrder == NULL) {
    return EFI_NOT_FOUND;
  }

  AttemptConfigOrderTmp = AllocateZeroPool (AttemptConfigOrderSize);
  if (AttemptConfigOrderTmp == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  for (Index = 0; Index < ISCSI_MAX_ATTEMPTS_NUM; Index++) {
    //
    // The real content ends with 0.
    //
    if (IfrNvData->DynamicOrderedList[Index] == 0) {
      break;
    }

    AttemptConfigIndex = IfrNvData->DynamicOrderedList[Index];
    AttemptConfigData  = IScsiConfigGetAttemptByConfigIndex (AttemptConfigIndex);
    if (AttemptConfigData == NULL) {
      Status = EFI_NOT_FOUND;
      goto Exit;
    }

    //
    // Reorder the Attempt List.
    //
    RemoveEntryList (&AttemptConfigData->Link);
    InsertTailList (&mPrivate->AttemptConfigs, &AttemptConfigData->Link);

    AttemptConfigOrderTmp[Index] = AttemptConfigIndex;

    //
    // Mark it to be deleted - 0.
    //
    for (Indexj = 0; Indexj < AttemptConfigOrderSize / sizeof (UINT8); Indexj++) {
      if (AttemptConfigOrder[Indexj] == AttemptConfigIndex) {
        AttemptConfigOrder[Indexj] = 0;
        break;
      }
    }
  }

  //
  // Adjust the attempt order in NVR.
  //
  for ( ; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
    for (Indexj = 0; Indexj < AttemptConfigOrderSize / sizeof (UINT8); Indexj++) {
      if (AttemptConfigOrder[Indexj] != 0) {
        AttemptConfigOrderTmp[Index] = AttemptConfigOrder[Indexj];
        AttemptConfigOrder[Indexj]   = 0;
        continue;
      }
    }
  }

  Status = gRT->SetVariable (
                  L"AttemptOrder",
                  &gIScsiConfigGuid,
                  EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_NON_VOLATILE,
                  AttemptConfigOrderSize,
                  AttemptConfigOrderTmp
                  );

Exit:
  if (AttemptConfigOrderTmp != NULL) {
    FreePool (AttemptConfigOrderTmp);
  }

  FreePool (AttemptConfigOrder);
  return Status;
}

/**
  Callback function when a user presses "Attempt *" or when a user selects a NIC to
  create the new attempt.

  @param[in]  KeyValue           A unique value which is sent to the original
                                 exporting driver so that it can identify the type
                                 of data to expect.
  @param[in]  IfrNvData          The IFR nv data.

  @retval EFI_OUT_OF_RESOURCES   Does not have sufficient resources to finish this
                                 operation.
  @retval EFI_NOT_FOUND          Cannot find the corresponding variable.
  @retval EFI_UNSUPPORTED        Can not create more attempts.
  @retval EFI_SUCCESS            The operation is completed successfully.

**/
EFI_STATUS
IScsiConfigProcessDefault (
  IN  EFI_QUESTION_ID          KeyValue,
  IN  ISCSI_CONFIG_IFR_NVDATA  *IfrNvData
  )
{
  BOOLEAN                      NewAttempt;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  UINT8                        CurrentAttemptConfigIndex;
  ISCSI_NIC_INFO               *NicInfo;
  UINT8                        NicIndex;
  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];
  UINT8                        *AttemptConfigOrder;
  UINTN                        AttemptConfigOrderSize;
  UINTN                        Index;
  EFI_INPUT_KEY                Key;

  AttemptConfigData = NULL;
  //
  // Is User creating a new attempt?
  //
  NewAttempt = FALSE;

  if ((KeyValue >= KEY_MAC_ENTRY_BASE) &&
      (KeyValue <= (UINT16)(mPrivate->MaxNic + KEY_MAC_ENTRY_BASE)))
  {
    //
    // User has pressed "Add an Attempt" and then selects a NIC.
    //
    NewAttempt = TRUE;
  } else if ((KeyValue >= KEY_ATTEMPT_ENTRY_BASE) &&
             (KeyValue < (ISCSI_MAX_ATTEMPTS_NUM + KEY_ATTEMPT_ENTRY_BASE)))
  {
    //
    // User has pressed "Attempt *".
    //
    NewAttempt = FALSE;
  } else {
    //
    // Don't process anything.
    //
    return EFI_SUCCESS;
  }

  if (NewAttempt) {
    //
    // Determine which NIC user has selected for the new created attempt.
    //
    NicIndex = (UINT8)(KeyValue - KEY_MAC_ENTRY_BASE);
    NicInfo  = IScsiGetNicInfoByIndex (NicIndex);
    if (NicInfo == NULL) {
      return EFI_NOT_FOUND;
    }

    //
    // Create an attempt following the initialized attempt order.
    //
    AttemptConfigOrder = IScsiGetVariableAndSize (
                           L"InitialAttemptOrder",
                           &gIScsiConfigGuid,
                           &AttemptConfigOrderSize
                           );

    if (AttemptConfigOrder == NULL) {
      return EFI_NOT_FOUND;
    }

    for (Index = 0; Index < AttemptConfigOrderSize / sizeof (UINT8); Index++) {
      UnicodeSPrint (
        mPrivate->PortString,
        (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
        L"Attempt %d",
        (UINTN)AttemptConfigOrder[Index]
        );
      GetVariable2 (
        mPrivate->PortString,
        &gEfiIScsiInitiatorNameProtocolGuid,
        (VOID **)&AttemptConfigData,
        NULL
        );
      if ((AttemptConfigData == NULL) || (AttemptConfigData->Actived == ISCSI_ACTIVE_ENABLED)) {
        continue;
      }

      break;
    }

    if (Index > PcdGet8 (PcdMaxIScsiAttemptNumber)) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Can not create more attempts, Please configure the PcdMaxIScsiAttemptNumber if needed!",
        NULL
        );
      return EFI_UNSUPPORTED;
    }

    if (AttemptConfigOrder != NULL) {
      FreePool (AttemptConfigOrder);
    }

    //
    // Record the MAC info in Config Data.
    //
    IScsiMacAddrToStr (
      &NicInfo->PermanentAddress,
      NicInfo->HwAddressSize,
      NicInfo->VlanId,
      MacString
      );

    ASSERT (AttemptConfigData != NULL);
    UnicodeStrToAsciiStrS (MacString, AttemptConfigData->MacString, sizeof (AttemptConfigData->MacString));
    AttemptConfigData->NicIndex = NicIndex;
    AttemptConfigData->Actived  = ISCSI_ACTIVE_ENABLED;

    //
    // Generate OUI-format ISID based on MAC address.
    //
    CopyMem (AttemptConfigData->SessionConfigData.IsId, &NicInfo->PermanentAddress, 6);
    AttemptConfigData->SessionConfigData.IsId[0] =
      (UINT8)(AttemptConfigData->SessionConfigData.IsId[0] & 0x3F);

    //
    // Add the help info for the new attempt.
    //
    UnicodeSPrint (
      mPrivate->PortString,
      (UINTN)ISCSI_NAME_IFR_MAX_SIZE,
      L"MAC: %s, PFA: Bus %d | Dev %d | Func %d",
      MacString,
      NicInfo->BusNumber,
      NicInfo->DeviceNumber,
      NicInfo->FunctionNumber
      );

    AttemptConfigData->AttemptTitleHelpToken = HiiSetString (
                                                 mCallbackInfo->RegisteredHandle,
                                                 0,
                                                 mPrivate->PortString,
                                                 NULL
                                                 );
    if (AttemptConfigData->AttemptTitleHelpToken == 0) {
      FreePool (AttemptConfigData);
      return EFI_OUT_OF_RESOURCES;
    }
  } else {
    //
    // Determine which Attempt user has selected to configure.
    // Get the attempt configuration data.
    //
    CurrentAttemptConfigIndex = (UINT8)(KeyValue - KEY_ATTEMPT_ENTRY_BASE);

    AttemptConfigData = IScsiConfigGetAttemptByConfigIndex (CurrentAttemptConfigIndex);
    if (AttemptConfigData == NULL) {
      DEBUG ((DEBUG_ERROR, "Corresponding configuration data can not be retrieved!\n"));
      return EFI_NOT_FOUND;
    }
  }

  //
  // Clear the old IFR data to avoid sharing it with other attempts.
  //
  if (IfrNvData->AuthenticationType == ISCSI_AUTH_TYPE_CHAP) {
    ZeroMem (IfrNvData->CHAPName, sizeof (IfrNvData->CHAPName));
    ZeroMem (IfrNvData->CHAPSecret, sizeof (IfrNvData->CHAPSecret));
    ZeroMem (IfrNvData->ReverseCHAPName, sizeof (IfrNvData->ReverseCHAPName));
    ZeroMem (IfrNvData->ReverseCHAPSecret, sizeof (IfrNvData->ReverseCHAPSecret));
  }

  IScsiConvertAttemptConfigDataToIfrNvData (AttemptConfigData, IfrNvData);

  //
  // Update current attempt to be a new created attempt or an existing attempt.
  //
  mCallbackInfo->Current = AttemptConfigData;

  return EFI_SUCCESS;
}

/**

  This function allows the caller to request the current
  configuration for one or more named elements. The resulting
  string is in <ConfigAltResp> format. Also, any and all alternative
  configuration strings shall 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.

**/
EFI_STATUS
EFIAPI
IScsiFormExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Request,
  OUT EFI_STRING                            *Progress,
  OUT EFI_STRING                            *Results
  )
{
  EFI_STATUS                Status;
  CHAR8                     *InitiatorName;
  UINTN                     BufferSize;
  ISCSI_CONFIG_IFR_NVDATA   *IfrNvData;
  ISCSI_FORM_CALLBACK_INFO  *Private;
  EFI_STRING                ConfigRequestHdr;
  EFI_STRING                ConfigRequest;
  BOOLEAN                   AllocatedRequest;
  UINTN                     Size;

  if ((This == NULL) || (Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Request;
  if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gIScsiConfigGuid, mVendorStorageName)) {
    return EFI_NOT_FOUND;
  }

  ConfigRequestHdr = NULL;
  ConfigRequest    = NULL;
  AllocatedRequest = FALSE;
  Size             = 0;

  Private   = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);
  IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  if (Private->Current != NULL) {
    IScsiConvertAttemptConfigDataToIfrNvData (Private->Current, IfrNvData);
  }

  //
  // Extract all AttemptConfigData to Keyword storage of IfrNvData.
  //
  IScsiConvertAttemptConfigDataToIfrNvDataByKeyword (IfrNvData);

  BufferSize    = ISCSI_NAME_MAX_SIZE;
  InitiatorName = (CHAR8 *)AllocateZeroPool (BufferSize);
  if (InitiatorName == NULL) {
    FreePool (IfrNvData);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);
  if (EFI_ERROR (Status)) {
    IfrNvData->InitiatorName[0] = L'\0';
  } else {
    AsciiStrToUnicodeStrS (
      InitiatorName,
      IfrNvData->InitiatorName,
      sizeof (IfrNvData->InitiatorName) / sizeof (IfrNvData->InitiatorName[0])
      );
  }

  //
  // Convert buffer data to <ConfigResp> by helper function BlockToConfig().
  //
  BufferSize    = sizeof (ISCSI_CONFIG_IFR_NVDATA);
  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 (&gIScsiConfigGuid, mVendorStorageName, Private->DriverHandle);
    Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
    ConfigRequest    = AllocateZeroPool (Size);
    if (ConfigRequest == NULL) {
      FreePool (IfrNvData);
      FreePool (InitiatorName);
      return EFI_OUT_OF_RESOURCES;
    }

    AllocatedRequest = TRUE;
    UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
    FreePool (ConfigRequestHdr);
  }

  Status = gHiiConfigRouting->BlockToConfig (
                                gHiiConfigRouting,
                                ConfigRequest,
                                (UINT8 *)IfrNvData,
                                BufferSize,
                                Results,
                                Progress
                                );
  FreePool (IfrNvData);
  FreePool (InitiatorName);

  //
  // 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.

  @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
                             beginning of the string if the failure
                             is in the first name / value pair) or
                             the terminating NULL if all was
                             successful.

  @retval EFI_SUCCESS             The results 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
IScsiFormRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                            *Progress
  )
{
  EFI_STATUS                   Status;
  ISCSI_CONFIG_IFR_NVDATA      *IfrNvData;
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  LIST_ENTRY                   *Entry;
  LIST_ENTRY                   *NextEntry;
  ISCSI_NIC_INFO               *NicInfo;
  EFI_INPUT_KEY                Key;
  CHAR16                       MacString[ISCSI_MAX_MAC_STRING_LEN];
  CHAR8                        *InitiatorName;
  UINT8                        *AttemptList;
  UINTN                        BufferSize;
  UINTN                        OffSet;
  UINTN                        Index;
  UINTN                        Index2;

  Index       = 0;
  Index2      = 0;
  NicInfo     = NULL;
  AttemptList = NULL;
  Status      = EFI_SUCCESS;

  if ((This == NULL) || (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, &gIScsiConfigGuid, mVendorStorageName)) {
    *Progress = Configuration;
    return EFI_NOT_FOUND;
  }

  IfrNvData = AllocateZeroPool (sizeof (ISCSI_CONFIG_IFR_NVDATA));
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  BufferSize    = ISCSI_NAME_MAX_SIZE;
  InitiatorName = (CHAR8 *)AllocateZeroPool (BufferSize);
  if (InitiatorName == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Exit;
  }

  //
  // Convert <ConfigResp> to buffer data by helper function ConfigToBlock().
  //
  BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);
  Status     = gHiiConfigRouting->ConfigToBlock (
                                    gHiiConfigRouting,
                                    Configuration,
                                    (UINT8 *)IfrNvData,
                                    &BufferSize,
                                    Progress
                                    );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  if (IfrNvData->InitiatorName[0] != L'\0') {
    UnicodeStrToAsciiStrS (IfrNvData->InitiatorName, InitiatorName, ISCSI_NAME_MAX_SIZE);
    BufferSize = AsciiStrSize (InitiatorName);

    Status = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, InitiatorName);
    if (EFI_ERROR (Status)) {
      CreatePopUp (
        EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
        &Key,
        L"Invalid iSCSI Name!",
        NULL
        );
      goto Exit;
    }
  } else {
    Status = IScsiGetValue (Configuration, L"&OFFSET=", &OffSet);
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    if (OffSet >= ATTEMPT_MAC_ADDR_VAR_OFFSET) {
      Status = gIScsiInitiatorName.Get (&gIScsiInitiatorName, &BufferSize, InitiatorName);
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Error: please configure iSCSI initiator name first!",
          NULL
          );
        goto Exit;
      }
    } else {
      goto Exit;
    }

    if (IfrNvData->ISCSIAddAttemptList[0] != L'\0') {
      Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIAddAttemptList, IfrNvData->AddAttemptList, TRUE);
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Error: The add attempt list is invalid",
          NULL
          );
        goto Exit;
      }

      Status = IScsiConfigAddAttemptsByKeywords (IfrNvData->AddAttemptList);
      if (EFI_ERROR (Status)) {
        goto Exit;
      }
    } else if (IfrNvData->ISCSIDeleteAttemptList[0] != L'\0') {
      AttemptList = (UINT8 *)AllocateZeroPool ((ISCSI_MAX_ATTEMPTS_NUM + 1) * sizeof (UINT8));
      if (AttemptList == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Exit;
      }

      Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIDeleteAttemptList, AttemptList, FALSE);
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Error: The delete attempt list is invalid",
          NULL
          );
        goto Exit;
      }

      //
      // Mark the attempt which will be delete in the global list.
      //
      NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, &mPrivate->AttemptConfigs) {
        AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
        while (AttemptList[Index] != 0) {
          if (AttemptConfigData->AttemptConfigIndex == AttemptList[Index]) {
            IfrNvData->DeleteAttemptList[Index2] = 1;
            break;
          }

          Index++;
        }

        Index2++;
        Index = 0;
      }

      Status = IScsiConfigDeleteAttempts (IfrNvData);
      if (EFI_ERROR (Status)) {
        goto Exit;
      }

      FreePool (AttemptList);
    } else if (IfrNvData->ISCSIAttemptOrder[0] != L'\0') {
      Status = IScsiGetAttemptIndexList (IfrNvData->ISCSIAttemptOrder, IfrNvData->DynamicOrderedList, FALSE);
      if (EFI_ERROR (Status)) {
        CreatePopUp (
          EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
          &Key,
          L"Error: The new attempt order list is invalid",
          NULL
          );
        goto Exit;
      }

      Status = IScsiConfigOrderAttempts (IfrNvData);
      if (EFI_ERROR (Status)) {
        goto Exit;
      }
    } else if (IfrNvData->ISCSIMacAddr[0] != L'\0') {
      NET_LIST_FOR_EACH (Entry, &mPrivate->NicInfoList) {
        NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
        IScsiMacAddrToStr (
          &NicInfo->PermanentAddress,
          NicInfo->HwAddressSize,
          NicInfo->VlanId,
          MacString
          );
        if (!StrCmp (MacString, IfrNvData->ISCSIMacAddr)) {
          mPrivate->CurrentNic = NicInfo->NicIndex;
          break;
        }
      }

      if ((NicInfo == NULL) || (NicInfo->NicIndex == 0)) {
        Status = EFI_NOT_FOUND;
        goto Exit;
      }
    } else {
      Status = IScsiConvertlfrNvDataToAttemptConfigDataByKeyword (IfrNvData, OffSet);
      if (EFI_ERROR (Status)) {
        goto Exit;
      }
    }
  }

  IScsiConfigUpdateAttempt ();

Exit:
  if (InitiatorName != NULL) {
    FreePool (InitiatorName);
  }

  if (IfrNvData != NULL) {
    FreePool (IfrNvData);
  }

  return Status;
}

/**

  This function is called to provide results data to the driver.
  This data consists of a unique key that is used to identify
  which data is either being passed back or being asked for.

  @param[in]       This          Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]       Action        Specifies the type of action taken by the browser.
  @param[in]       QuestionId    A unique value which is sent to the original
                                 exporting driver so that it can identify the type
                                 of data to expect. The format of the data tends to
                                 vary based on the opcode that generated the callback.
  @param[in]       Type          The type of value for the question.
  @param[in, out]  Value         A pointer to the data being sent to the original
                                 exporting driver.
  @param[out]      ActionRequest On return, points to the action requested by the
                                 callback function.

  @retval EFI_SUCCESS            The callback successfully handled the action.
  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
                                 variable and its data.
  @retval EFI_DEVICE_ERROR       The variable could not be saved.
  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
                                 callback.
**/
EFI_STATUS
EFIAPI
IScsiFormCallback (
  IN CONST  EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN        EFI_BROWSER_ACTION              Action,
  IN        EFI_QUESTION_ID                 QuestionId,
  IN        UINT8                           Type,
  IN OUT    EFI_IFR_TYPE_VALUE              *Value,
  OUT       EFI_BROWSER_ACTION_REQUEST      *ActionRequest
  )
{
  ISCSI_FORM_CALLBACK_INFO  *Private;
  UINTN                     BufferSize;
  CHAR8                     *IScsiName;
  CHAR8                     IpString[ISCSI_NAME_MAX_SIZE];
  CHAR8                     LunString[ISCSI_LUN_STR_MAX_LEN];
  UINT64                    Lun;
  EFI_IP_ADDRESS            HostIp;
  EFI_IP_ADDRESS            SubnetMask;
  EFI_IP_ADDRESS            Gateway;
  ISCSI_CONFIG_IFR_NVDATA   *IfrNvData;
  ISCSI_CONFIG_IFR_NVDATA   OldIfrNvData;
  EFI_STATUS                Status;
  EFI_INPUT_KEY             Key;
  ISCSI_NIC_INFO            *NicInfo;

  NicInfo = NULL;

  if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)) {
    //
    // Do nothing for UEFI OPEN/CLOSE Action
    //
    return EFI_SUCCESS;
  }

  if ((Action != EFI_BROWSER_ACTION_CHANGING) && (Action != EFI_BROWSER_ACTION_CHANGED)) {
    //
    // All other type return unsupported.
    //
    return EFI_UNSUPPORTED;
  }

  if ((Value == NULL) || (ActionRequest == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Private = ISCSI_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);

  //
  // Retrieve uncommitted data from Browser
  //

  BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);
  IfrNvData  = AllocateZeroPool (BufferSize);
  if (IfrNvData == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  IScsiName = (CHAR8 *)AllocateZeroPool (ISCSI_NAME_MAX_SIZE);
  if (IScsiName == NULL) {
    FreePool (IfrNvData);
    return EFI_OUT_OF_RESOURCES;
  }

  Status = EFI_SUCCESS;

  ZeroMem (&OldIfrNvData, BufferSize);

  HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData);

  CopyMem (&OldIfrNvData, IfrNvData, BufferSize);

  if (Action == EFI_BROWSER_ACTION_CHANGING) {
    switch (QuestionId) {
      case KEY_ADD_ATTEMPT:
        //
        // Check whether iSCSI initiator name is configured already.
        //
        mPrivate->InitiatorNameLength = ISCSI_NAME_MAX_SIZE;
        Status                        = gIScsiInitiatorName.Get (
                                                              &gIScsiInitiatorName,
                                                              &mPrivate->InitiatorNameLength,
                                                              mPrivate->InitiatorName
                                                              );
        if (EFI_ERROR (Status)) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Error: please configure iSCSI initiator name first!",
            NULL
            );
          break;
        }

        Status = IScsiConfigAddAttempt ();
        break;

      case KEY_DELETE_ATTEMPT:
        CopyMem (
          OldIfrNvData.DeleteAttemptList,
          IfrNvData->DeleteAttemptList,
          sizeof (IfrNvData->DeleteAttemptList)
          );
        Status = IScsiConfigDisplayDeleteAttempts (IfrNvData);
        break;

      case KEY_ORDER_ATTEMPT_CONFIG:
        //
        // Order the attempt according to user input.
        //
        CopyMem (
          OldIfrNvData.DynamicOrderedList,
          IfrNvData->DynamicOrderedList,
          sizeof (IfrNvData->DynamicOrderedList)
          );
        IScsiConfigDisplayOrderAttempts ();
        break;

      default:
        Status = IScsiConfigProcessDefault (QuestionId, IfrNvData);
        break;
    }
  } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
    switch (QuestionId) {
      case KEY_INITIATOR_NAME:
        UnicodeStrToAsciiStrS (IfrNvData->InitiatorName, IScsiName, ISCSI_NAME_MAX_SIZE);
        BufferSize = AsciiStrSize (IScsiName);

        Status = gIScsiInitiatorName.Set (&gIScsiInitiatorName, &BufferSize, IScsiName);
        if (EFI_ERROR (Status)) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid iSCSI Name!",
            NULL
            );
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_APPLY;
        break;

      case KEY_SAVE_ATTEMPT_CONFIG:
        Status = IScsiConvertIfrNvDataToAttemptConfigData (IfrNvData, Private->Current);
        if (EFI_ERROR (Status)) {
          break;
        }

        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
        break;

      case KEY_SAVE_ORDER_CHANGES:
        //
        // Sync the Attempt Order to NVR.
        //
        Status = IScsiConfigOrderAttempts (IfrNvData);
        if (EFI_ERROR (Status)) {
          break;
        }

        IScsiConfigUpdateAttempt ();
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
        break;

      case KEY_IGNORE_ORDER_CHANGES:
        CopyMem (
          IfrNvData->DynamicOrderedList,
          OldIfrNvData.DynamicOrderedList,
          sizeof (IfrNvData->DynamicOrderedList)
          );
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
        break;

      case KEY_SAVE_DELETE_ATTEMPT:
        //
        // Delete the Attempt Order from NVR
        //
        Status = IScsiConfigDeleteAttempts (IfrNvData);
        if (EFI_ERROR (Status)) {
          break;
        }

        IScsiConfigUpdateAttempt ();
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
        break;

      case KEY_IGNORE_DELETE_ATTEMPT:
        CopyMem (
          IfrNvData->DeleteAttemptList,
          OldIfrNvData.DeleteAttemptList,
          sizeof (IfrNvData->DeleteAttemptList)
          );
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
        break;

      case KEY_IP_MODE:
        switch (Value->u8) {
          case IP_MODE_IP6:
            NicInfo = IScsiGetNicInfoByIndex (Private->Current->NicIndex);
            if (NicInfo == NULL) {
              break;
            }

            if (!NicInfo->Ipv6Available) {
              //
              // Current NIC doesn't Support IPv6, hence use IPv4.
              //
              IfrNvData->IpMode = IP_MODE_IP4;

              CreatePopUp (
                EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
                &Key,
                L"Current NIC doesn't Support IPv6!",
                NULL
                );
            }

          case IP_MODE_IP4:
            ZeroMem (IfrNvData->LocalIp, sizeof (IfrNvData->LocalIp));
            ZeroMem (IfrNvData->SubnetMask, sizeof (IfrNvData->SubnetMask));
            ZeroMem (IfrNvData->Gateway, sizeof (IfrNvData->Gateway));
            ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));
            Private->Current->AutoConfigureMode = 0;
            ZeroMem (&Private->Current->SessionConfigData.LocalIp, sizeof (EFI_IP_ADDRESS));
            ZeroMem (&Private->Current->SessionConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));
            ZeroMem (&Private->Current->SessionConfigData.Gateway, sizeof (EFI_IP_ADDRESS));
            ZeroMem (&Private->Current->SessionConfigData.TargetIp, sizeof (EFI_IP_ADDRESS));

            break;
        }

        break;

      case KEY_LOCAL_IP:
        Status = NetLibStrToIp4 (IfrNvData->LocalIp, &HostIp.v4);
        if (EFI_ERROR (Status) ||
            ((Private->Current->SessionConfigData.SubnetMask.Addr[0] != 0) &&
             !NetIp4IsUnicast (NTOHL (HostIp.Addr[0]), NTOHL (*(UINT32 *)Private->Current->SessionConfigData.SubnetMask.Addr))))
        {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid IP address!",
            NULL
            );

          Status = EFI_INVALID_PARAMETER;
        } else {
          CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));
        }

        break;

      case KEY_SUBNET_MASK:
        Status = NetLibStrToIp4 (IfrNvData->SubnetMask, &SubnetMask.v4);
        if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (IScsiGetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid Subnet Mask!",
            NULL
            );

          Status = EFI_INVALID_PARAMETER;
        } else {
          CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));
        }

        break;

      case KEY_GATE_WAY:
        Status = NetLibStrToIp4 (IfrNvData->Gateway, &Gateway.v4);
        if (EFI_ERROR (Status) ||
            ((Gateway.Addr[0] != 0) &&
             (Private->Current->SessionConfigData.SubnetMask.Addr[0] != 0) &&
             !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (*(UINT32 *)Private->Current->SessionConfigData.SubnetMask.Addr))))
        {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid Gateway!",
            NULL
            );
          Status = EFI_INVALID_PARAMETER;
        } else {
          CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));
        }

        break;

      case KEY_TARGET_IP:
        UnicodeStrToAsciiStrS (IfrNvData->TargetIp, IpString, sizeof (IpString));
        Status = IScsiAsciiStrToIp (IpString, IfrNvData->IpMode, &HostIp);
        if (EFI_ERROR (Status) || !IpIsUnicast (&HostIp, IfrNvData->IpMode)) {
          //
          // The target is expressed in URL format or an invalid Ip address, just save.
          //
          Private->Current->SessionConfigData.DnsMode = TRUE;
          ZeroMem (&Private->Current->SessionConfigData.TargetIp, sizeof (Private->Current->SessionConfigData.TargetIp));
          UnicodeStrToAsciiStrS (IfrNvData->TargetIp, Private->Current->SessionConfigData.TargetUrl, ISCSI_NAME_MAX_SIZE);
        } else {
          Private->Current->SessionConfigData.DnsMode = FALSE;
          CopyMem (&Private->Current->SessionConfigData.TargetIp, &HostIp, sizeof (HostIp));
        }

        break;

      case KEY_TARGET_NAME:
        UnicodeStrToAsciiStrS (IfrNvData->TargetName, IScsiName, ISCSI_NAME_MAX_SIZE);
        Status = IScsiNormalizeName (IScsiName, AsciiStrLen (IScsiName));
        if (EFI_ERROR (Status)) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid iSCSI Name!",
            NULL
            );
        } else {
          AsciiStrCpyS (Private->Current->SessionConfigData.TargetName, ISCSI_NAME_MAX_SIZE, IScsiName);
        }

        break;

      case KEY_DHCP_ENABLE:
        if (IfrNvData->InitiatorInfoFromDhcp == 0) {
          IfrNvData->TargetInfoFromDhcp = 0;
        }

        break;

      case KEY_BOOT_LUN:
        UnicodeStrToAsciiStrS (IfrNvData->BootLun, LunString, sizeof (LunString));
        Status = IScsiAsciiStrToLun (LunString, (UINT8 *)&Lun);
        if (EFI_ERROR (Status)) {
          CreatePopUp (
            EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
            &Key,
            L"Invalid LUN string!",
            NULL
            );
        } else {
          CopyMem (Private->Current->SessionConfigData.BootLun, &Lun, sizeof (Lun));
        }

        break;

      case KEY_AUTH_TYPE:
        switch (Value->u8) {
          case ISCSI_AUTH_TYPE_CHAP:
            IfrNvData->CHAPType = ISCSI_CHAP_UNI;
            break;
          default:
            break;
        }

        break;

      case KEY_CHAP_NAME:
        UnicodeStrToAsciiStrS (
          IfrNvData->CHAPName,
          Private->Current->AuthConfigData.CHAP.CHAPName,
          sizeof (Private->Current->AuthConfigData.CHAP.CHAPName)
          );
        break;

      case KEY_CHAP_SECRET:
        UnicodeStrToAsciiStrS (
          IfrNvData->CHAPSecret,
          Private->Current->AuthConfigData.CHAP.CHAPSecret,
          sizeof (Private->Current->AuthConfigData.CHAP.CHAPSecret)
          );
        break;

      case KEY_REVERSE_CHAP_NAME:
        UnicodeStrToAsciiStrS (
          IfrNvData->ReverseCHAPName,
          Private->Current->AuthConfigData.CHAP.ReverseCHAPName,
          sizeof (Private->Current->AuthConfigData.CHAP.ReverseCHAPName)
          );
        break;

      case KEY_REVERSE_CHAP_SECRET:
        UnicodeStrToAsciiStrS (
          IfrNvData->ReverseCHAPSecret,
          Private->Current->AuthConfigData.CHAP.ReverseCHAPSecret,
          sizeof (Private->Current->AuthConfigData.CHAP.ReverseCHAPSecret)
          );
        break;

      case KEY_CONFIG_ISID:
        IScsiParseIsIdFromString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);
        IScsiConvertIsIdToString (IfrNvData->IsId, Private->Current->SessionConfigData.IsId);

        break;

      default:
        break;
    }
  }

  if (!EFI_ERROR (Status)) {
    //
    // Pass changed uncommitted data back to Form Browser.
    //
    BufferSize = sizeof (ISCSI_CONFIG_IFR_NVDATA);
    HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *)IfrNvData, NULL);
  }

  FreePool (IfrNvData);
  FreePool (IScsiName);

  return Status;
}

/**
  Initialize the iSCSI configuration form.

  @param[in]  DriverBindingHandle The iSCSI driverbinding handle.

  @retval EFI_SUCCESS             The iSCSI configuration form is initialized.
  @retval EFI_OUT_OF_RESOURCES    Failed to allocate memory.

**/
EFI_STATUS
IScsiConfigFormInit (
  IN EFI_HANDLE  DriverBindingHandle
  )
{
  EFI_STATUS                Status;
  ISCSI_FORM_CALLBACK_INFO  *CallbackInfo;

  CallbackInfo = (ISCSI_FORM_CALLBACK_INFO *)AllocateZeroPool (sizeof (ISCSI_FORM_CALLBACK_INFO));
  if (CallbackInfo == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  CallbackInfo->Signature = ISCSI_FORM_CALLBACK_INFO_SIGNATURE;
  CallbackInfo->Current   = NULL;

  CallbackInfo->ConfigAccess.ExtractConfig = IScsiFormExtractConfig;
  CallbackInfo->ConfigAccess.RouteConfig   = IScsiFormRouteConfig;
  CallbackInfo->ConfigAccess.Callback      = IScsiFormCallback;

  //
  // Install Device Path Protocol and Config Access protocol to driver handle.
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &CallbackInfo->DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mIScsiHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &CallbackInfo->ConfigAccess,
                  NULL
                  );
  ASSERT_EFI_ERROR (Status);

  //
  // Publish our HII data.
  //
  CallbackInfo->RegisteredHandle = HiiAddPackages (
                                     &gIScsiConfigGuid,
                                     CallbackInfo->DriverHandle,
                                     IScsiDxeStrings,
                                     IScsiConfigVfrBin,
                                     NULL
                                     );
  if (CallbackInfo->RegisteredHandle == NULL) {
    gBS->UninstallMultipleProtocolInterfaces (
           CallbackInfo->DriverHandle,
           &gEfiDevicePathProtocolGuid,
           &mIScsiHiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &CallbackInfo->ConfigAccess,
           NULL
           );
    FreePool (CallbackInfo);
    return EFI_OUT_OF_RESOURCES;
  }

  mCallbackInfo = CallbackInfo;

  return EFI_SUCCESS;
}

/**
  Unload the iSCSI configuration form, this includes: delete all the iSCSI
  configuration entries, uninstall the form callback protocol, and
  free the resources used.

  @param[in]  DriverBindingHandle The iSCSI driverbinding handle.

  @retval EFI_SUCCESS             The iSCSI configuration form is unloaded.
  @retval Others                  Failed to unload the form.

**/
EFI_STATUS
IScsiConfigFormUnload (
  IN EFI_HANDLE  DriverBindingHandle
  )
{
  ISCSI_ATTEMPT_CONFIG_NVDATA  *AttemptConfigData;
  ISCSI_NIC_INFO               *NicInfo;
  LIST_ENTRY                   *Entry;
  EFI_STATUS                   Status;

  while (!IsListEmpty (&mPrivate->AttemptConfigs)) {
    Entry             = NetListRemoveHead (&mPrivate->AttemptConfigs);
    AttemptConfigData = NET_LIST_USER_STRUCT (Entry, ISCSI_ATTEMPT_CONFIG_NVDATA, Link);
    FreePool (AttemptConfigData);
    mPrivate->AttemptCount--;
  }

  ASSERT (mPrivate->AttemptCount == 0);

  while (!IsListEmpty (&mPrivate->NicInfoList)) {
    Entry   = NetListRemoveHead (&mPrivate->NicInfoList);
    NicInfo = NET_LIST_USER_STRUCT (Entry, ISCSI_NIC_INFO, Link);
    FreePool (NicInfo);
    mPrivate->NicCount--;
  }

  ASSERT (mPrivate->NicCount == 0);

  FreePool (mPrivate);
  mPrivate = NULL;

  //
  // Remove HII package list.
  //
  HiiRemovePackages (mCallbackInfo->RegisteredHandle);

  //
  // Uninstall Device Path Protocol and Config Access protocol.
  //
  Status = gBS->UninstallMultipleProtocolInterfaces (
                  mCallbackInfo->DriverHandle,
                  &gEfiDevicePathProtocolGuid,
                  &mIScsiHiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  &mCallbackInfo->ConfigAccess,
                  NULL
                  );

  FreePool (mCallbackInfo);

  return Status;
}
