/** @file
  Helper functions for configuring or getting the parameters relating to Ip4.

Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>
SPDX-License-Identifier: BSD-2-Clause-Patent

**/

#include "Ip4Impl.h"

CHAR16  mIp4Config2StorageName[] = L"IP4_CONFIG2_IFR_NVDATA";

/**
  Calculate the prefix length of the IPv4 subnet mask.

  @param[in]  SubnetMask The IPv4 subnet mask.

  @return The prefix length of the subnet mask.
  @retval 0 Other errors as indicated.

**/
UINT8
GetSubnetMaskPrefixLength (
  IN EFI_IPv4_ADDRESS  *SubnetMask
  )
{
  UINT8   Len;
  UINT32  ReverseMask;

  //
  // The SubnetMask is in network byte order.
  //
  ReverseMask = SwapBytes32 (*(UINT32 *)&SubnetMask[0]);

  //
  // Reverse it.
  //
  ReverseMask = ~ReverseMask;

  if ((ReverseMask & (ReverseMask + 1)) != 0) {
    return 0;
  }

  Len = 0;

  while (ReverseMask != 0) {
    ReverseMask = ReverseMask >> 1;
    Len++;
  }

  return (UINT8)(32 - Len);
}

/**
  Convert the decimal dotted IPv4 address into the binary IPv4 address.

  @param[in]   Str             The UNICODE string.
  @param[out]  Ip              The storage to return the IPv4 address.

  @retval EFI_SUCCESS           The binary IP address is returned in Ip.
  @retval EFI_INVALID_PARAMETER The IP string is malformatted.

**/
EFI_STATUS
Ip4Config2StrToIp (
  IN  CHAR16            *Str,
  OUT EFI_IPv4_ADDRESS  *Ip
  )
{
  UINTN  Index;
  UINTN  Number;

  Index = 0;

  while (*Str != L'\0') {
    if (Index > 3) {
      return EFI_INVALID_PARAMETER;
    }

    Number = 0;
    while ((*Str >= L'0') && (*Str <= L'9')) {
      Number = Number * 10 + (*Str - L'0');
      Str++;
    }

    if (Number > 0xFF) {
      return EFI_INVALID_PARAMETER;
    }

    Ip->Addr[Index] = (UINT8)Number;

    if ((*Str != L'\0') && (*Str != L'.')) {
      //
      // The current character should be either the NULL terminator or
      // the dot delimiter.
      //
      return EFI_INVALID_PARAMETER;
    }

    if (*Str == L'.') {
      //
      // Skip the delimiter.
      //
      Str++;
    }

    Index++;
  }

  if (Index != 4) {
    return EFI_INVALID_PARAMETER;
  }

  return EFI_SUCCESS;
}

/**
  Convert the decimal dotted IPv4 addresses separated by space into the binary IPv4 address list.

  @param[in]   Str             The UNICODE string contains IPv4 addresses.
  @param[out]  PtrIpList       The storage to return the IPv4 address list.
  @param[out]  IpCount         The size of the IPv4 address list.

  @retval EFI_SUCCESS           The binary IP address list is returned in PtrIpList.
  @retval EFI_OUT_OF_RESOURCES  Error occurs in allocating memory.
  @retval EFI_INVALID_PARAMETER The IP string is malformatted.

**/
EFI_STATUS
Ip4Config2StrToIpList (
  IN  CHAR16            *Str,
  OUT EFI_IPv4_ADDRESS  **PtrIpList,
  OUT UINTN             *IpCount
  )
{
  UINTN    BeginIndex;
  UINTN    EndIndex;
  UINTN    Index;
  UINTN    IpIndex;
  CHAR16   *StrTemp;
  BOOLEAN  SpaceTag;

  BeginIndex = 0;
  EndIndex   = BeginIndex;
  Index      = 0;
  IpIndex    = 0;
  StrTemp    = NULL;
  SpaceTag   = TRUE;

  *PtrIpList = NULL;
  *IpCount   = 0;

  if (Str == NULL) {
    return EFI_SUCCESS;
  }

  //
  // Get the number of Ip.
  //
  while (*(Str + Index) != L'\0') {
    if (*(Str + Index) == L' ') {
      SpaceTag = TRUE;
    } else {
      if (SpaceTag) {
        (*IpCount)++;
        SpaceTag = FALSE;
      }
    }

    Index++;
  }

  if (*IpCount == 0) {
    return EFI_SUCCESS;
  }

  //
  // Allocate buffer for IpList.
  //
  *PtrIpList = AllocateZeroPool (*IpCount * sizeof (EFI_IPv4_ADDRESS));
  if (*PtrIpList == NULL) {
    return EFI_OUT_OF_RESOURCES;
  }

  //
  // Get IpList from Str.
  //
  Index = 0;
  while (*(Str + Index) != L'\0') {
    if (*(Str + Index) == L' ') {
      if (!SpaceTag) {
        StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));
        if (StrTemp == NULL) {
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_OUT_OF_RESOURCES;
        }

        CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));
        *(StrTemp + (EndIndex - BeginIndex)) = L'\0';

        if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {
          FreePool (StrTemp);
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_INVALID_PARAMETER;
        }

        BeginIndex = EndIndex;
        IpIndex++;

        FreePool (StrTemp);
      }

      BeginIndex++;
      EndIndex++;
      SpaceTag = TRUE;
    } else {
      EndIndex++;
      SpaceTag = FALSE;
    }

    Index++;

    if (*(Str + Index) == L'\0') {
      if (!SpaceTag) {
        StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));
        if (StrTemp == NULL) {
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_OUT_OF_RESOURCES;
        }

        CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));
        *(StrTemp + (EndIndex - BeginIndex)) = L'\0';

        if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {
          FreePool (StrTemp);
          FreePool (*PtrIpList);
          *PtrIpList = NULL;
          *IpCount   = 0;
          return EFI_INVALID_PARAMETER;
        }

        FreePool (StrTemp);
      }
    }
  }

  return EFI_SUCCESS;
}

/**
  Convert the IPv4 address into a dotted string.

  @param[in]   Ip   The IPv4 address.
  @param[out]  Str  The dotted IP string.

**/
VOID
Ip4Config2IpToStr (
  IN  EFI_IPv4_ADDRESS  *Ip,
  OUT CHAR16            *Str
  )
{
  UnicodeSPrint (
    Str,
    2 * IP4_STR_MAX_SIZE,
    L"%d.%d.%d.%d",
    Ip->Addr[0],
    Ip->Addr[1],
    Ip->Addr[2],
    Ip->Addr[3]
    );
}

/**
  Convert the IPv4 address list into string consists of several decimal
  dotted IPv4 addresses separated by space.

  @param[in]   Ip        The IPv4 address list.
  @param[in]   IpCount   The size of IPv4 address list.
  @param[out]  Str       The string contains several decimal dotted
                         IPv4 addresses separated by space.

  @retval EFI_SUCCESS           Operation is success.
  @retval EFI_OUT_OF_RESOURCES  Error occurs in allocating memory.

**/
EFI_STATUS
Ip4Config2IpListToStr (
  IN  EFI_IPv4_ADDRESS  *Ip,
  IN  UINTN             IpCount,
  OUT CHAR16            *Str
  )
{
  UINTN             Index;
  UINTN             TemIndex;
  UINTN             StrIndex;
  CHAR16            *TempStr;
  EFI_IPv4_ADDRESS  *TempIp;

  Index    = 0;
  TemIndex = 0;
  StrIndex = 0;
  TempStr  = NULL;
  TempIp   = NULL;

  for (Index = 0; Index < IpCount; Index++) {
    TempIp = Ip + Index;
    if (TempStr == NULL) {
      TempStr = AllocateZeroPool (2 * IP4_STR_MAX_SIZE);
      if (TempStr == NULL) {
        return EFI_OUT_OF_RESOURCES;
      }
    }

    UnicodeSPrint (
      TempStr,
      2 * IP4_STR_MAX_SIZE,
      L"%d.%d.%d.%d",
      TempIp->Addr[0],
      TempIp->Addr[1],
      TempIp->Addr[2],
      TempIp->Addr[3]
      );

    for (TemIndex = 0; TemIndex < IP4_STR_MAX_SIZE; TemIndex++) {
      if (*(TempStr + TemIndex) == L'\0') {
        if (Index == IpCount - 1) {
          Str[StrIndex++] = L'\0';
        } else {
          Str[StrIndex++] = L' ';
        }

        break;
      } else {
        Str[StrIndex++] = *(TempStr + TemIndex);
      }
    }
  }

  if (TempStr != NULL) {
    FreePool (TempStr);
  }

  return EFI_SUCCESS;
}

/**
  The notify function of create event when performing a manual configuration.

  @param[in]    Event        The pointer of Event.
  @param[in]    Context      The pointer of Context.

**/
VOID
EFIAPI
Ip4Config2ManualAddressNotify (
  IN EFI_EVENT  Event,
  IN VOID       *Context
  )
{
  *((BOOLEAN *)Context) = TRUE;
}

/**
  Convert the network configuration data into the IFR data.

  @param[in]       Instance          The IP4 config2 instance.
  @param[in, out]  IfrNvData         The IFR nv data.

  @retval EFI_SUCCESS            The configure parameter to IFR data was
                                 set successfully.
  @retval EFI_INVALID_PARAMETER  Source instance or target IFR data is not available.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
Ip4Config2ConvertConfigNvDataToIfrNvData (
  IN     IP4_CONFIG2_INSTANCE    *Instance,
  IN OUT IP4_CONFIG2_IFR_NVDATA  *IfrNvData
  )
{
  IP4_SERVICE                     *IpSb;
  EFI_IP4_CONFIG2_PROTOCOL        *Ip4Config2;
  EFI_IP4_CONFIG2_INTERFACE_INFO  *Ip4Info;
  EFI_IP4_CONFIG2_POLICY          Policy;
  UINTN                           DataSize;
  UINTN                           GatewaySize;
  EFI_IPv4_ADDRESS                GatewayAddress;
  EFI_STATUS                      Status;
  UINTN                           DnsSize;
  UINTN                           DnsCount;
  EFI_IPv4_ADDRESS                *DnsAddress;

  Status      = EFI_SUCCESS;
  Ip4Config2  = &Instance->Ip4Config2;
  Ip4Info     = NULL;
  DnsAddress  = NULL;
  GatewaySize = sizeof (EFI_IPv4_ADDRESS);

  if ((IfrNvData == NULL) || (Instance == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  NET_CHECK_SIGNATURE (Instance, IP4_CONFIG2_INSTANCE_SIGNATURE);

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);

  if (IpSb->DefaultInterface->Configured) {
    IfrNvData->Configure = 1;
  } else {
    IfrNvData->Configure = 0;
    goto Exit;
  }

  //
  // Get the Policy info.
  //
  DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);
  Status   = Ip4Config2->GetData (
                           Ip4Config2,
                           Ip4Config2DataTypePolicy,
                           &DataSize,
                           &Policy
                           );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  if (Policy == Ip4Config2PolicyStatic) {
    IfrNvData->DhcpEnable = FALSE;
  } else if (Policy == Ip4Config2PolicyDhcp) {
    IfrNvData->DhcpEnable = TRUE;
    goto Exit;
  }

  //
  // Get the interface info.
  //
  DataSize = 0;
  Status   = Ip4Config2->GetData (
                           Ip4Config2,
                           Ip4Config2DataTypeInterfaceInfo,
                           &DataSize,
                           NULL
                           );
  if (Status != EFI_BUFFER_TOO_SMALL) {
    return Status;
  }

  Ip4Info = AllocateZeroPool (DataSize);
  if (Ip4Info == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    return Status;
  }

  Status = Ip4Config2->GetData (
                         Ip4Config2,
                         Ip4Config2DataTypeInterfaceInfo,
                         &DataSize,
                         Ip4Info
                         );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Get the Gateway info.
  //
  Status = Ip4Config2->GetData (
                         Ip4Config2,
                         Ip4Config2DataTypeGateway,
                         &GatewaySize,
                         &GatewayAddress
                         );
  if (EFI_ERROR (Status)) {
    goto Exit;
  }

  //
  // Get the Dns info.
  //
  DnsSize = 0;
  Status  = Ip4Config2->GetData (
                          Ip4Config2,
                          Ip4Config2DataTypeDnsServer,
                          &DnsSize,
                          NULL
                          );
  if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {
    goto Exit;
  }

  DnsCount = (UINT32)(DnsSize / sizeof (EFI_IPv4_ADDRESS));

  if (DnsSize > 0) {
    DnsAddress = AllocateZeroPool (DnsSize);
    if (DnsAddress == NULL) {
      Status = EFI_OUT_OF_RESOURCES;
      goto Exit;
    }

    Status = Ip4Config2->GetData (
                           Ip4Config2,
                           Ip4Config2DataTypeDnsServer,
                           &DnsSize,
                           DnsAddress
                           );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }
  }

  Ip4Config2IpToStr (&Ip4Info->StationAddress, IfrNvData->StationAddress);
  Ip4Config2IpToStr (&Ip4Info->SubnetMask, IfrNvData->SubnetMask);
  Ip4Config2IpToStr (&GatewayAddress, IfrNvData->GatewayAddress);
  Status = Ip4Config2IpListToStr (DnsAddress, DnsCount, IfrNvData->DnsAddress);

Exit:

  if (DnsAddress != NULL) {
    FreePool (DnsAddress);
  }

  if (Ip4Info != NULL) {
    FreePool (Ip4Info);
  }

  return Status;
}

/**
  Convert the IFR data into the network configuration data and set the IP
  configure parameters for the NIC.

  @param[in]       IfrFormNvData     The IFR NV data.
  @param[in, out]  Instance          The IP4 config2 instance.

  @retval EFI_SUCCESS            The configure parameter for this NIC was
                                 set successfully.
  @retval EFI_INVALID_PARAMETER  The address information for setting is invalid.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
Ip4Config2ConvertIfrNvDataToConfigNvData (
  IN     IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData,
  IN OUT IP4_CONFIG2_INSTANCE    *Instance
  )
{
  EFI_STATUS                Status;
  EFI_IP4_CONFIG2_PROTOCOL  *Ip4Cfg2;
  IP4_CONFIG2_NVDATA        *Ip4NvData;

  EFI_IP_ADDRESS    StationAddress;
  EFI_IP_ADDRESS    SubnetMask;
  EFI_IP_ADDRESS    Gateway;
  IP4_ADDR          Ip;
  EFI_IPv4_ADDRESS  *DnsAddress;
  UINTN             DnsCount;
  UINTN             Index;

  EFI_EVENT      TimeoutEvent;
  EFI_EVENT      SetAddressEvent;
  BOOLEAN        IsAddressOk;
  UINTN          DataSize;
  EFI_INPUT_KEY  Key;

  Status    = EFI_SUCCESS;
  Ip4Cfg2   = &Instance->Ip4Config2;
  Ip4NvData = &Instance->Ip4NvData;

  DnsCount   = 0;
  DnsAddress = NULL;

  TimeoutEvent    = NULL;
  SetAddressEvent = NULL;

  if ((Instance == NULL) || (IfrFormNvData == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  if (IfrFormNvData->Configure != TRUE) {
    if (Ip4NvData->DnsAddress != NULL) {
      FreePool (Ip4NvData->DnsAddress);
      Ip4NvData->DnsAddress      = NULL;
      Ip4NvData->DnsAddressCount = 0;
    }

    if (Ip4NvData->GatewayAddress != NULL) {
      FreePool (Ip4NvData->GatewayAddress);
      Ip4NvData->GatewayAddress      = NULL;
      Ip4NvData->GatewayAddressCount = 0;
    }

    if (Ip4NvData->ManualAddress != NULL) {
      FreePool (Ip4NvData->ManualAddress);
      Ip4NvData->ManualAddress      = NULL;
      Ip4NvData->ManualAddressCount = 0;
    }

    Ip4NvData->Policy = Ip4Config2PolicyDhcp;
    Status            = Ip4Cfg2->SetData (
                                   Ip4Cfg2,
                                   Ip4Config2DataTypePolicy,
                                   sizeof (EFI_IP4_CONFIG2_POLICY),
                                   &Ip4NvData->Policy
                                   );
    return EFI_SUCCESS;
  }

  if (IfrFormNvData->DhcpEnable == TRUE) {
    Ip4NvData->Policy = Ip4Config2PolicyDhcp;

    Status = Ip4Cfg2->SetData (
                        Ip4Cfg2,
                        Ip4Config2DataTypePolicy,
                        sizeof (EFI_IP4_CONFIG2_POLICY),
                        &Ip4NvData->Policy
                        );
    if (EFI_ERROR (Status)) {
      return Status;
    }
  } else {
    //
    // Get Ip4NvData from IfrFormNvData if it is valid.
    //
    Ip4NvData->Policy = Ip4Config2PolicyStatic;

    Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);
    if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);
      return EFI_INVALID_PARAMETER;
    }

    Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);
    if (EFI_ERROR (Status) ||
        ((SubnetMask.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0]))) ||
        !Ip4StationAddressValid (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0])))
    {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);
      return EFI_INVALID_PARAMETER;
    }

    Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);
    if (EFI_ERROR (Status) ||
        ((Gateway.Addr[0] != 0) && (SubnetMask.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (SubnetMask.Addr[0]))))
    {
      CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);
      return EFI_INVALID_PARAMETER;
    }

    Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount);
    if (!EFI_ERROR (Status) && (DnsCount > 0)) {
      for (Index = 0; Index < DnsCount; Index++) {
        CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));
        if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
          FreePool (DnsAddress);
          return EFI_INVALID_PARAMETER;
        }
      }
    } else {
      if (EFI_ERROR (Status)) {
        CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
      }
    }

    if (Ip4NvData->ManualAddress != NULL) {
      FreePool (Ip4NvData->ManualAddress);
    }

    Ip4NvData->ManualAddressCount = 1;
    Ip4NvData->ManualAddress      = AllocateZeroPool (sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS));
    if (Ip4NvData->ManualAddress == NULL) {
      if (DnsAddress != NULL) {
        FreePool (DnsAddress);
      }

      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (&Ip4NvData->ManualAddress->Address, &StationAddress.v4, sizeof (EFI_IPv4_ADDRESS));
    CopyMem (&Ip4NvData->ManualAddress->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));

    if (Ip4NvData->GatewayAddress != NULL) {
      FreePool (Ip4NvData->GatewayAddress);
    }

    Ip4NvData->GatewayAddressCount = 1;
    Ip4NvData->GatewayAddress      = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));
    if (Ip4NvData->GatewayAddress == NULL) {
      if (DnsAddress != NULL) {
        FreePool (DnsAddress);
      }

      return EFI_OUT_OF_RESOURCES;
    }

    CopyMem (Ip4NvData->GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));

    if (Ip4NvData->DnsAddress != NULL) {
      FreePool (Ip4NvData->DnsAddress);
    }

    Ip4NvData->DnsAddressCount = (UINT32)DnsCount;
    Ip4NvData->DnsAddress      = DnsAddress;

    //
    // Setting Ip4NvData.
    //
    Status = Ip4Cfg2->SetData (
                        Ip4Cfg2,
                        Ip4Config2DataTypePolicy,
                        sizeof (EFI_IP4_CONFIG2_POLICY),
                        &Ip4NvData->Policy
                        );
    if (EFI_ERROR (Status)) {
      return Status;
    }

    //
    // Create events & timers for asynchronous settings.
    //
    Status = gBS->CreateEvent (
                    EVT_TIMER,
                    TPL_CALLBACK,
                    NULL,
                    NULL,
                    &TimeoutEvent
                    );
    if (EFI_ERROR (Status)) {
      return EFI_OUT_OF_RESOURCES;
    }

    Status = gBS->CreateEvent (
                    EVT_NOTIFY_SIGNAL,
                    TPL_NOTIFY,
                    Ip4Config2ManualAddressNotify,
                    &IsAddressOk,
                    &SetAddressEvent
                    );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    IsAddressOk = FALSE;

    Status = Ip4Cfg2->RegisterDataNotify (
                        Ip4Cfg2,
                        Ip4Config2DataTypeManualAddress,
                        SetAddressEvent
                        );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    //
    // Set ManualAddress.
    //
    DataSize = Ip4NvData->ManualAddressCount * sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS);
    Status   = Ip4Cfg2->SetData (
                          Ip4Cfg2,
                          Ip4Config2DataTypeManualAddress,
                          DataSize,
                          (VOID *)Ip4NvData->ManualAddress
                          );

    if (Status == EFI_NOT_READY) {
      gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);
      while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
        if (IsAddressOk) {
          Status = EFI_SUCCESS;
          break;
        }
      }
    }

    Ip4Cfg2->UnregisterDataNotify (
               Ip4Cfg2,
               Ip4Config2DataTypeManualAddress,
               SetAddressEvent
               );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    //
    // Set gateway.
    //
    DataSize = Ip4NvData->GatewayAddressCount * sizeof (EFI_IPv4_ADDRESS);
    Status   = Ip4Cfg2->SetData (
                          Ip4Cfg2,
                          Ip4Config2DataTypeGateway,
                          DataSize,
                          Ip4NvData->GatewayAddress
                          );
    if (EFI_ERROR (Status)) {
      goto Exit;
    }

    //
    // Set DNS addresses.
    //
    if ((Ip4NvData->DnsAddressCount > 0) && (Ip4NvData->DnsAddress != NULL)) {
      DataSize = Ip4NvData->DnsAddressCount * sizeof (EFI_IPv4_ADDRESS);
      Status   = Ip4Cfg2->SetData (
                            Ip4Cfg2,
                            Ip4Config2DataTypeDnsServer,
                            DataSize,
                            Ip4NvData->DnsAddress
                            );

      if (EFI_ERROR (Status)) {
        goto Exit;
      }
    }
  }

Exit:
  if (SetAddressEvent != NULL) {
    gBS->CloseEvent (SetAddressEvent);
  }

  if (TimeoutEvent != NULL) {
    gBS->CloseEvent (TimeoutEvent);
  }

  return Status;
}

/**
  This function allows the caller to request the current
  configuration for one or more named elements. The resulting
  string is in <ConfigAltResp> format. Any and all alternative
  configuration strings shall also be appended to the end of the
  current configuration string. If they are, they must appear
  after the current configuration. They must contain the same
  routing (GUID, NAME, PATH) as the current configuration string.
  They must have an additional description indicating the type of
  alternative configuration the string represents,
  "ALTCFG=<StringToken>". That <StringToken> (when
  converted from Hex UNICODE to binary) is a reference to a
  string in the associated string pack.

  @param[in] This       Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in] Request    A null-terminated Unicode string in
                        <ConfigRequest> format. Note that this
                        includes the routing information as well as
                        the configurable name / value pairs. It is
                        invalid for this string to be in
                        <MultiConfigRequest> format.
  @param[out] Progress  On return, points to a character in the
                        Request string. Points to the string's null
                        terminator if request was successful. Points
                        to the most recent "&" before the first
                        failing name / value pair (or the beginning
                        of the string if the failure is in the first
                        name / value pair) if the request was not
                        successful.
  @param[out] Results   A null-terminated Unicode string in
                        <ConfigAltResp> format which has all values
                        filled in for the names in the Request string.
                        String to be allocated by the called function.

  @retval EFI_SUCCESS             The Results string is filled with the
                                  values corresponding to all requested
                                  names.
  @retval EFI_OUT_OF_RESOURCES    Not enough memory to store the
                                  parts of the results that must be
                                  stored awaiting possible future
                                  protocols.
  @retval EFI_NOT_FOUND           Routing data doesn't match any
                                  known driver. Progress set to the
                                  first character in the routing header.
                                  Note: There is no requirement that the
                                  driver validate the routing data. It
                                  must skip the <ConfigHdr> in order to
                                  process the names.
  @retval EFI_INVALID_PARAMETER   Illegal syntax. Progress set
                                  to most recent & before the
                                  error or the beginning of the
                                  string.
  @retval EFI_INVALID_PARAMETER   Unknown name. Progress points
                                  to the & before the name in
                                  question.Currently not implemented.
**/
EFI_STATUS
EFIAPI
Ip4FormExtractConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Request,
  OUT EFI_STRING                            *Progress,
  OUT EFI_STRING                            *Results
  )
{
  EFI_STATUS              Status;
  IP4_CONFIG2_INSTANCE    *Ip4Config2Instance;
  IP4_FORM_CALLBACK_INFO  *Private;
  IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData;
  EFI_STRING              ConfigRequestHdr;
  EFI_STRING              ConfigRequest;
  BOOLEAN                 AllocatedRequest;
  EFI_STRING              FormResult;
  UINTN                   Size;
  UINTN                   BufferSize;

  if ((Progress == NULL) || (Results == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  Status             = EFI_SUCCESS;
  IfrFormNvData      = NULL;
  ConfigRequest      = NULL;
  FormResult         = NULL;
  Size               = 0;
  AllocatedRequest   = FALSE;
  ConfigRequest      = Request;
  Private            = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
  Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);
  BufferSize         = sizeof (IP4_CONFIG2_IFR_NVDATA);
  *Progress          = Request;

  //
  // Check Request data in <ConfigHdr>.
  //
  if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {
    IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));
    if (IfrFormNvData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance, IfrFormNvData);

    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 (&gIp4Config2NvDataGuid, mIp4Config2StorageName, Private->ChildHandle);
      Size             = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
      ConfigRequest    = AllocateZeroPool (Size);
      if (ConfigRequest == NULL) {
        Status = EFI_OUT_OF_RESOURCES;
        goto Failure;
      }

      AllocatedRequest = TRUE;

      UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
      FreePool (ConfigRequestHdr);
    }

    //
    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
    //
    Status = gHiiConfigRouting->BlockToConfig (
                                  gHiiConfigRouting,
                                  ConfigRequest,
                                  (UINT8 *)IfrFormNvData,
                                  BufferSize,
                                  &FormResult,
                                  Progress
                                  );

    FreePool (IfrFormNvData);

    //
    // Free the allocated config request string.
    //
    if (AllocatedRequest) {
      FreePool (ConfigRequest);
      ConfigRequest = NULL;
    }

    if (EFI_ERROR (Status)) {
      goto Failure;
    }
  }

  if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {
    *Results = FormResult;
  } else {
    return EFI_NOT_FOUND;
  }

Failure:
  //
  // Set Progress string to the original request string.
  //
  if (Request == NULL) {
    *Progress = NULL;
  } else if (StrStr (Request, L"OFFSET") == NULL) {
    *Progress = Request + StrLen (Request);
  }

  return Status;
}

/**
  This function applies changes in a driver's configuration.
  Input is a Configuration, which has the routing data for this
  driver followed by name / value configuration pairs. The driver
  must apply those pairs to its configurable storage. If the
  driver's configuration is stored in a linear block of data
  and the driver's name / value pairs are in <BlockConfig>
  format, it may use the ConfigToBlock helper function (above) to
  simplify the job. Currently not implemented.

  @param[in]  This           Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
  @param[in]  Configuration  A null-terminated Unicode string in
                             <ConfigString> format.
  @param[out] Progress       A pointer to a string filled in with the
                             offset of the most recent '&' before the
                             first failing name / value pair (or the
                             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_MEMORY       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
Ip4FormRouteConfig (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  CONST EFI_STRING                      Configuration,
  OUT EFI_STRING                            *Progress
  )
{
  EFI_STATUS              Status;
  UINTN                   BufferSize;
  IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData;
  IP4_CONFIG2_INSTANCE    *Ip4Config2Instance;
  IP4_FORM_CALLBACK_INFO  *Private;

  Status        = EFI_SUCCESS;
  IfrFormNvData = NULL;

  if ((Configuration == NULL) || (Progress == NULL)) {
    return EFI_INVALID_PARAMETER;
  }

  *Progress = Configuration;

  Private            = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
  Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);

  //
  // Check Routing data in <ConfigHdr>.
  //
  if (HiiIsConfigHdrMatch (Configuration, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {
    //
    // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
    //
    IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));
    if (IfrFormNvData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    BufferSize = 0;

    Status = gHiiConfigRouting->ConfigToBlock (
                                  gHiiConfigRouting,
                                  Configuration,
                                  (UINT8 *)IfrFormNvData,
                                  &BufferSize,
                                  Progress
                                  );
    if (Status != EFI_BUFFER_TOO_SMALL) {
      return Status;
    }

    Status = gHiiConfigRouting->ConfigToBlock (
                                  gHiiConfigRouting,
                                  Configuration,
                                  (UINT8 *)IfrFormNvData,
                                  &BufferSize,
                                  Progress
                                  );
    if (!EFI_ERROR (Status)) {
      Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Ip4Config2Instance);
    }

    FreePool (IfrFormNvData);
  } else {
    return EFI_NOT_FOUND;
  }

  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 enerated the callback.
  @param[in]  Type               The type of value for the question.
  @param[in]  Value              A pointer to the data being sent to the original
                                 exporting driver.
  @param[out] ActionRequest      On return, points to the action requested by the
                                 callback function.

  @retval EFI_SUCCESS            The callback successfully handled the action.
  @retval EFI_OUT_OF_RESOURCES   Not enough storage is available to hold the
                                 variable and its data.
  @retval EFI_DEVICE_ERROR       The variable could not be saved.
  @retval EFI_UNSUPPORTED        The specified Action is not supported by the
                                 callback. Currently not implemented.
  @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.
  @retval Others                 Other errors as indicated.

**/
EFI_STATUS
EFIAPI
Ip4FormCallback (
  IN  CONST EFI_HII_CONFIG_ACCESS_PROTOCOL  *This,
  IN  EFI_BROWSER_ACTION                    Action,
  IN  EFI_QUESTION_ID                       QuestionId,
  IN  UINT8                                 Type,
  IN  EFI_IFR_TYPE_VALUE                    *Value,
  OUT EFI_BROWSER_ACTION_REQUEST            *ActionRequest
  )
{
  EFI_STATUS              Status;
  IP4_CONFIG2_INSTANCE    *Instance;
  IP4_CONFIG2_IFR_NVDATA  *IfrFormNvData;
  IP4_FORM_CALLBACK_INFO  *Private;

  EFI_IP_ADDRESS    StationAddress;
  EFI_IP_ADDRESS    SubnetMask;
  EFI_IP_ADDRESS    Gateway;
  IP4_ADDR          Ip;
  EFI_IPv4_ADDRESS  *DnsAddress;
  UINTN             DnsCount;
  UINTN             Index;
  EFI_INPUT_KEY     Key;

  IfrFormNvData = NULL;
  DnsCount      = 0;
  DnsAddress    = NULL;

  if (Action == EFI_BROWSER_ACTION_CHANGED) {
    Private  = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
    Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);

    IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));
    if (IfrFormNvData == NULL) {
      return EFI_OUT_OF_RESOURCES;
    }

    //
    // Retrieve uncommitted data from Browser
    //
    if (!HiiGetBrowserData (&gIp4Config2NvDataGuid, mIp4Config2StorageName, sizeof (IP4_CONFIG2_IFR_NVDATA), (UINT8 *)IfrFormNvData)) {
      FreePool (IfrFormNvData);
      return EFI_NOT_FOUND;
    }

    Status = EFI_SUCCESS;

    switch (QuestionId) {
      case KEY_LOCAL_IP:
        Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);
        if (EFI_ERROR (Status) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress.Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress.Addr[0]))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);
          Status = EFI_INVALID_PARAMETER;
        }

        break;

      case KEY_SUBNET_MASK:
        Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);
        if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);
          Status = EFI_INVALID_PARAMETER;
        }

        break;

      case KEY_GATE_WAY:
        Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);
        if (EFI_ERROR (Status) || IP4_IS_LOCAL_BROADCAST (NTOHL (Gateway.Addr[0]))) {
          CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);
          Status = EFI_INVALID_PARAMETER;
        }

        break;

      case KEY_DNS:
        Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount);
        if (!EFI_ERROR (Status) && (DnsCount > 0)) {
          for (Index = 0; Index < DnsCount; Index++) {
            CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));
            if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {
              CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
              Status = EFI_INVALID_PARAMETER;
              break;
            }
          }
        } else {
          if (EFI_ERROR (Status)) {
            CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);
          }
        }

        if (DnsAddress != NULL) {
          FreePool (DnsAddress);
        }

        break;

      case KEY_SAVE_CHANGES:
        Status         = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Instance);
        *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
        break;

      default:
        break;
    }

    FreePool (IfrFormNvData);

    return Status;
  }

  //
  // All other action return unsupported.
  //
  return EFI_UNSUPPORTED;
}

/**
  Install HII Config Access protocol for network device and allocate resource.

  @param[in, out]  Instance        The IP4 config2 Instance.

  @retval EFI_SUCCESS              The HII Config Access protocol is installed.
  @retval EFI_OUT_OF_RESOURCES     Failed to allocate memory.
  @retval Others                   Other errors as indicated.

**/
EFI_STATUS
Ip4Config2FormInit (
  IN OUT IP4_CONFIG2_INSTANCE  *Instance
  )
{
  EFI_STATUS                      Status;
  IP4_SERVICE                     *IpSb;
  IP4_FORM_CALLBACK_INFO          *CallbackInfo;
  EFI_HII_CONFIG_ACCESS_PROTOCOL  *ConfigAccess;
  VENDOR_DEVICE_PATH              VendorDeviceNode;
  EFI_SERVICE_BINDING_PROTOCOL    *MnpSb;
  CHAR16                          *MacString;
  CHAR16                          MenuString[128];
  CHAR16                          PortString[128];
  CHAR16                          *OldMenuString;
  EFI_DEVICE_PATH_PROTOCOL        *ParentDevicePath;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  ASSERT (IpSb != NULL);

  CallbackInfo = &Instance->CallbackInfo;

  CallbackInfo->Signature = IP4_FORM_CALLBACK_INFO_SIGNATURE;

  Status = gBS->HandleProtocol (
                  IpSb->Controller,
                  &gEfiDevicePathProtocolGuid,
                  (VOID **)&ParentDevicePath
                  );
  if (EFI_ERROR (Status)) {
    return Status;
  }

  //
  // Construct device path node for EFI HII Config Access protocol,
  // which consists of controller physical device path and one hardware
  // vendor guid node.
  //
  ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
  VendorDeviceNode.Header.Type    = HARDWARE_DEVICE_PATH;
  VendorDeviceNode.Header.SubType = HW_VENDOR_DP;

  CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);

  SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
  CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
                                        ParentDevicePath,
                                        (EFI_DEVICE_PATH_PROTOCOL *)&VendorDeviceNode
                                        );
  if (CallbackInfo->HiiVendorDevicePath == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  ConfigAccess                = &CallbackInfo->HiiConfigAccessProtocol;
  ConfigAccess->ExtractConfig = Ip4FormExtractConfig;
  ConfigAccess->RouteConfig   = Ip4FormRouteConfig;
  ConfigAccess->Callback      = Ip4FormCallback;

  //
  // Install Device Path Protocol and Config Access protocol on new handle
  //
  Status = gBS->InstallMultipleProtocolInterfaces (
                  &CallbackInfo->ChildHandle,
                  &gEfiDevicePathProtocolGuid,
                  CallbackInfo->HiiVendorDevicePath,
                  &gEfiHiiConfigAccessProtocolGuid,
                  ConfigAccess,
                  NULL
                  );

  if (!EFI_ERROR (Status)) {
    //
    // Open the Parent Handle for the child
    //
    Status = gBS->OpenProtocol (
                    IpSb->Controller,
                    &gEfiManagedNetworkServiceBindingProtocolGuid,
                    (VOID **)&MnpSb,
                    IpSb->Image,
                    CallbackInfo->ChildHandle,
                    EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
                    );
  }

  if (EFI_ERROR (Status)) {
    goto Error;
  }

  //
  // Publish our HII data
  //
  CallbackInfo->RegisteredHandle = HiiAddPackages (
                                     &gIp4Config2NvDataGuid,
                                     CallbackInfo->ChildHandle,
                                     Ip4DxeStrings,
                                     Ip4Config2Bin,
                                     NULL
                                     );
  if (CallbackInfo->RegisteredHandle == NULL) {
    Status = EFI_OUT_OF_RESOURCES;
    goto Error;
  }

  //
  // Append MAC string in the menu help string and tile help string
  //
  Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);
  if (!EFI_ERROR (Status)) {
    OldMenuString = HiiGetString (
                      CallbackInfo->RegisteredHandle,
                      STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),
                      NULL
                      );
    UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
    HiiSetString (
      CallbackInfo->RegisteredHandle,
      STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),
      MenuString,
      NULL
      );

    UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);
    HiiSetString (
      CallbackInfo->RegisteredHandle,
      STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP),
      PortString,
      NULL
      );

    FreePool (MacString);
    FreePool (OldMenuString);

    return EFI_SUCCESS;
  }

Error:
  Ip4Config2FormUnload (Instance);
  return Status;
}

/**
  Uninstall the HII Config Access protocol for network devices and free up the resources.

  @param[in, out]  Instance      The IP4 config2 instance to unload a form.

**/
VOID
Ip4Config2FormUnload (
  IN OUT IP4_CONFIG2_INSTANCE  *Instance
  )
{
  IP4_SERVICE             *IpSb;
  IP4_FORM_CALLBACK_INFO  *CallbackInfo;
  IP4_CONFIG2_NVDATA      *Ip4NvData;

  IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);
  ASSERT (IpSb != NULL);

  CallbackInfo = &Instance->CallbackInfo;

  if (CallbackInfo->ChildHandle != NULL) {
    //
    // Close the child handle
    //
    gBS->CloseProtocol (
           IpSb->Controller,
           &gEfiManagedNetworkServiceBindingProtocolGuid,
           IpSb->Image,
           CallbackInfo->ChildHandle
           );

    //
    // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
    //
    gBS->UninstallMultipleProtocolInterfaces (
           CallbackInfo->ChildHandle,
           &gEfiDevicePathProtocolGuid,
           CallbackInfo->HiiVendorDevicePath,
           &gEfiHiiConfigAccessProtocolGuid,
           &CallbackInfo->HiiConfigAccessProtocol,
           NULL
           );
  }

  if (CallbackInfo->HiiVendorDevicePath != NULL) {
    FreePool (CallbackInfo->HiiVendorDevicePath);
  }

  if (CallbackInfo->RegisteredHandle != NULL) {
    //
    // Remove HII package list
    //
    HiiRemovePackages (CallbackInfo->RegisteredHandle);
  }

  Ip4NvData = &Instance->Ip4NvData;

  if (Ip4NvData->ManualAddress != NULL) {
    FreePool (Ip4NvData->ManualAddress);
  }

  if (Ip4NvData->GatewayAddress != NULL) {
    FreePool (Ip4NvData->GatewayAddress);
  }

  if (Ip4NvData->DnsAddress != NULL) {
    FreePool (Ip4NvData->DnsAddress);
  }

  Ip4NvData->ManualAddressCount  = 0;
  Ip4NvData->GatewayAddressCount = 0;
  Ip4NvData->DnsAddressCount     = 0;
}
