/** @file
  Helper functions for configuring or getting the parameters relating to iSCSI.

Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
This program and the accompanying materials
are licensed and made available under the terms and conditions of the BSD License
which accompanies this distribution.  The full text of the license may be found at
http://opensource.org/licenses/bsd-license.php

THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.

**/

#include "IScsiImpl.h"

CHAR16          mVendorStorageName[]     = L"ISCSI_CONFIG_IFR_NVDATA";
BOOLEAN         mIScsiDeviceListUpdated  = FALSE;
UINTN           mNumberOfIScsiDevices    = 0;
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) {
    UnicodeSPrint (
      PortString,
      (UINTN) ISCSI_NAME_IFR_MAX_SIZE,
      L"Error! Input is incorrect, please input 6 hex numbers!\n"
      );

    CreatePopUp (
      EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
      &Key,
      PortString,
      NULL
      );

    return EFI_INVALID_PARAMETER;
  }

  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 neccessary
                                 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);
    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);

    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'/';
     } 
  }
}

/**
  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_ABOTRED            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);
    if (AttemptConfigData == NULL) {
      Status = EFI_NOT_FOUND;
      goto Error;
    }

    //
    // 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 stroage 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;

  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:
      case IP_MODE_IP4:
        ZeroMem (IfrNvData->TargetIp, sizeof (IfrNvData->TargetIp));
        Private->Current->AutoConfigureMode = 0;

        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;
}
