]> git.proxmox.com Git - mirror_edk2.git/blobdiff - MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
NetworkPkg: Move Network library and drivers from MdeModulePkg to NetworkPkg
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Dhcp4Dxe / Dhcp4Driver.c
diff --git a/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c b/MdeModulePkg/Universal/Network/Dhcp4Dxe/Dhcp4Driver.c
deleted file mode 100644 (file)
index e891b68..0000000
+++ /dev/null
@@ -1,732 +0,0 @@
-/** @file\r
-\r
-Copyright (c) 2006 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "Dhcp4Impl.h"\r
-#include "Dhcp4Driver.h"\r
-\r
-EFI_DRIVER_BINDING_PROTOCOL gDhcp4DriverBinding = {\r
-  Dhcp4DriverBindingSupported,\r
-  Dhcp4DriverBindingStart,\r
-  Dhcp4DriverBindingStop,\r
-  0xa,\r
-  NULL,\r
-  NULL\r
-};\r
-\r
-EFI_SERVICE_BINDING_PROTOCOL mDhcp4ServiceBindingTemplate = {\r
-  Dhcp4ServiceBindingCreateChild,\r
-  Dhcp4ServiceBindingDestroyChild\r
-};\r
-\r
-/**\r
-  This is the declaration of an EFI image entry point. This entry point is\r
-  the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including\r
-  both device drivers and bus drivers.\r
-\r
-  Entry point of the DHCP driver to install various protocols.\r
-\r
-  @param[in]  ImageHandle           The firmware allocated handle for the UEFI image.\r
-  @param[in]  SystemTable           A pointer to the EFI System Table.\r
-\r
-  @retval EFI_SUCCESS           The operation completed successfully.\r
-  @retval EFI_OUT_OF_RESOURCES  The request could not be completed due to a lack of resources.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Dhcp4DriverEntryPoint (\r
-  IN EFI_HANDLE             ImageHandle,\r
-  IN EFI_SYSTEM_TABLE       *SystemTable\r
-  )\r
-{\r
-  return EfiLibInstallDriverBindingComponentName2 (\r
-           ImageHandle,\r
-           SystemTable,\r
-           &gDhcp4DriverBinding,\r
-           ImageHandle,\r
-           &gDhcp4ComponentName,\r
-           &gDhcp4ComponentName2\r
-           );\r
-}\r
-\r
-\r
-/**\r
-  Test to see if this driver supports ControllerHandle. This service\r
-  is called by the EFI boot service ConnectController(). In\r
-  order to make drivers as small as possible, there are a few calling\r
-  restrictions for this service. ConnectController() must\r
-  follow these calling restrictions. If any other agent wishes to call\r
-  Supported() it must also follow these calling restrictions.\r
-\r
-  @param[in]  This                Protocol instance pointer.\r
-  @param[in]  ControllerHandle    Handle of device to test\r
-  @param[in]  RemainingDevicePath Optional parameter use to pick a specific child\r
-                                  device to start.\r
-\r
-  @retval EFI_SUCCESS         This driver supports this device\r
-  @retval EFI_ALREADY_STARTED This driver is already running on this device\r
-  @retval other               This driver does not support this device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Dhcp4DriverBindingSupported (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
-  )\r
-{\r
-  EFI_STATUS  Status;\r
-\r
-  Status = gBS->OpenProtocol (\r
-                  ControllerHandle,\r
-                  &gEfiUdp4ServiceBindingProtocolGuid,\r
-                  NULL,\r
-                  This->DriverBindingHandle,\r
-                  ControllerHandle,\r
-                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                  );\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Configure the default UDP child to receive all the DHCP traffics\r
-  on this network interface.\r
-\r
-  @param[in]  UdpIo                  The UDP IO to configure\r
-  @param[in]  Context                The context to the function\r
-\r
-  @retval EFI_SUCCESS            The UDP IO is successfully configured.\r
-  @retval Others                 Failed to configure the UDP child.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-DhcpConfigUdpIo (\r
-  IN UDP_IO                 *UdpIo,\r
-  IN VOID                   *Context\r
-  )\r
-{\r
-  EFI_UDP4_CONFIG_DATA      UdpConfigData;\r
-\r
-  UdpConfigData.AcceptBroadcast           = TRUE;\r
-  UdpConfigData.AcceptPromiscuous         = FALSE;\r
-  UdpConfigData.AcceptAnyPort             = FALSE;\r
-  UdpConfigData.AllowDuplicatePort        = TRUE;\r
-  UdpConfigData.TypeOfService             = 0;\r
-  UdpConfigData.TimeToLive                = 64;\r
-  UdpConfigData.DoNotFragment             = FALSE;\r
-  UdpConfigData.ReceiveTimeout            = 0;\r
-  UdpConfigData.TransmitTimeout           = 0;\r
-\r
-  UdpConfigData.UseDefaultAddress         = FALSE;\r
-  UdpConfigData.StationPort               = DHCP_CLIENT_PORT;\r
-  UdpConfigData.RemotePort                = DHCP_SERVER_PORT;\r
-\r
-  ZeroMem (&UdpConfigData.StationAddress, sizeof (EFI_IPv4_ADDRESS));\r
-  ZeroMem (&UdpConfigData.SubnetMask, sizeof (EFI_IPv4_ADDRESS));\r
-  ZeroMem (&UdpConfigData.RemoteAddress, sizeof (EFI_IPv4_ADDRESS));\r
-\r
-  return UdpIo->Protocol.Udp4->Configure (UdpIo->Protocol.Udp4, &UdpConfigData);;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Destroy the DHCP service. The Dhcp4 service may be partly initialized,\r
-  or partly destroyed. If a resource is destroyed, it is marked as so in\r
-  case the destroy failed and being called again later.\r
-\r
-  @param[in]  DhcpSb                 The DHCP service instance to destroy.\r
-\r
-  @retval EFI_SUCCESS            Always return success.\r
-\r
-**/\r
-EFI_STATUS\r
-Dhcp4CloseService (\r
-  IN DHCP_SERVICE           *DhcpSb\r
-  )\r
-{\r
-  DhcpCleanLease (DhcpSb);\r
-\r
-  if (DhcpSb->UdpIo != NULL) {\r
-    UdpIoFreeIo (DhcpSb->UdpIo);\r
-    DhcpSb->UdpIo = NULL;\r
-  }\r
-\r
-  if (DhcpSb->Timer != NULL) {\r
-    gBS->SetTimer (DhcpSb->Timer, TimerCancel, 0);\r
-    gBS->CloseEvent (DhcpSb->Timer);\r
-\r
-    DhcpSb->Timer = NULL;\r
-  }\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-\r
-/**\r
-  Create a new DHCP service binding instance for the controller.\r
-\r
-  @param[in]  Controller             The controller to install DHCP service binding\r
-                                     protocol onto\r
-  @param[in]  ImageHandle            The driver's image handle\r
-  @param[out] Service                The variable to receive the created DHCP service\r
-                                     instance.\r
-\r
-  @retval EFI_OUT_OF_RESOURCES   Failed to allocate resource .\r
-  @retval EFI_SUCCESS            The DHCP service instance is created.\r
-  @retval other                  Other error occurs.\r
-\r
-**/\r
-EFI_STATUS\r
-Dhcp4CreateService (\r
-  IN  EFI_HANDLE            Controller,\r
-  IN  EFI_HANDLE            ImageHandle,\r
-  OUT DHCP_SERVICE          **Service\r
-  )\r
-{\r
-  DHCP_SERVICE              *DhcpSb;\r
-  EFI_STATUS                Status;\r
-\r
-  *Service  = NULL;\r
-  DhcpSb    = AllocateZeroPool (sizeof (DHCP_SERVICE));\r
-\r
-  if (DhcpSb == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  DhcpSb->Signature       = DHCP_SERVICE_SIGNATURE;\r
-  DhcpSb->ServiceState    = DHCP_UNCONFIGED;\r
-  DhcpSb->Controller      = Controller;\r
-  DhcpSb->Image           = ImageHandle;\r
-  InitializeListHead (&DhcpSb->Children);\r
-  DhcpSb->DhcpState       = Dhcp4Stopped;\r
-  DhcpSb->Xid             = NET_RANDOM (NetRandomInitSeed ());\r
-  CopyMem (\r
-    &DhcpSb->ServiceBinding,\r
-    &mDhcp4ServiceBindingTemplate,\r
-    sizeof (EFI_SERVICE_BINDING_PROTOCOL)\r
-    );\r
-  //\r
-  // Create various resources, UdpIo, Timer, and get Mac address\r
-  //\r
-  Status = gBS->CreateEvent (\r
-                  EVT_NOTIFY_SIGNAL | EVT_TIMER,\r
-                  TPL_CALLBACK,\r
-                  DhcpOnTimerTick,\r
-                  DhcpSb,\r
-                  &DhcpSb->Timer\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  DhcpSb->UdpIo = UdpIoCreateIo (\r
-                    Controller,\r
-                    ImageHandle,\r
-                    DhcpConfigUdpIo,\r
-                    UDP_IO_UDP4_VERSION,\r
-                    NULL\r
-                    );\r
-\r
-  if (DhcpSb->UdpIo == NULL) {\r
-    Status = EFI_OUT_OF_RESOURCES;\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  DhcpSb->HwLen  = (UINT8) DhcpSb->UdpIo->SnpMode.HwAddressSize;\r
-  DhcpSb->HwType = DhcpSb->UdpIo->SnpMode.IfType;\r
-  CopyMem (&DhcpSb->Mac, &DhcpSb->UdpIo->SnpMode.CurrentAddress, sizeof (DhcpSb->Mac));\r
-\r
-  *Service       = DhcpSb;\r
-  return EFI_SUCCESS;\r
-\r
-ON_ERROR:\r
-  Dhcp4CloseService (DhcpSb);\r
-  FreePool (DhcpSb);\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Start this driver on ControllerHandle. This service is called by the\r
-  EFI boot service ConnectController(). In order to make\r
-  drivers as small as possible, there are a few calling restrictions for\r
-  this service. ConnectController() must follow these\r
-  calling restrictions. If any other agent wishes to call Start() it\r
-  must also follow these calling restrictions.\r
-\r
-  @param[in]  This                 Protocol instance pointer.\r
-  @param[in]  ControllerHandle     Handle of device to bind driver to\r
-  @param[in]  RemainingDevicePath  Optional parameter use to pick a specific child\r
-                                   device to start.\r
-\r
-  @retval EFI_SUCCESS          This driver is added to ControllerHandle\r
-  @retval EFI_ALREADY_STARTED  This driver is already running on ControllerHandle\r
-  @retval other                This driver does not support this device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Dhcp4DriverBindingStart (\r
-  IN EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                   ControllerHandle,\r
-  IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL\r
-  )\r
-{\r
-  DHCP_SERVICE              *DhcpSb;\r
-  EFI_STATUS                Status;\r
-\r
-  //\r
-  // First: test for the DHCP4 Protocol\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  ControllerHandle,\r
-                  &gEfiDhcp4ServiceBindingProtocolGuid,\r
-                  NULL,\r
-                  This->DriverBindingHandle,\r
-                  ControllerHandle,\r
-                  EFI_OPEN_PROTOCOL_TEST_PROTOCOL\r
-                  );\r
-\r
-  if (Status == EFI_SUCCESS) {\r
-    return EFI_ALREADY_STARTED;\r
-  }\r
-\r
-  Status = Dhcp4CreateService (ControllerHandle, This->DriverBindingHandle, &DhcpSb);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return Status;\r
-  }\r
-  ASSERT (DhcpSb != NULL);\r
-\r
-  //\r
-  // Start the receiving\r
-  //\r
-  Status = UdpIoRecvDatagram (DhcpSb->UdpIo, DhcpInput, DhcpSb, 0);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-  Status = gBS->SetTimer (DhcpSb->Timer, TimerPeriodic, TICKS_PER_SECOND);\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  //\r
-  // Install the Dhcp4ServiceBinding Protocol onto ControlerHandle\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  &ControllerHandle,\r
-                  &gEfiDhcp4ServiceBindingProtocolGuid,\r
-                  &DhcpSb->ServiceBinding,\r
-                  NULL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    goto ON_ERROR;\r
-  }\r
-\r
-  return Status;\r
-\r
-ON_ERROR:\r
-  Dhcp4CloseService (DhcpSb);\r
-  FreePool (DhcpSb);\r
-  return Status;\r
-}\r
-\r
-/**\r
-  Callback function which provided by user to remove one node in NetDestroyLinkList process.\r
-\r
-  @param[in]    Entry           The entry to be removed.\r
-  @param[in]    Context         Pointer to the callback context corresponds to the Context in NetDestroyLinkList.\r
-\r
-  @retval EFI_SUCCESS           The entry has been removed successfully.\r
-  @retval Others                Fail to remove the entry.\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Dhcp4DestroyChildEntry (\r
-  IN LIST_ENTRY         *Entry,\r
-  IN VOID               *Context\r
-  )\r
-{\r
-  DHCP_PROTOCOL                    *Instance;\r
-  EFI_SERVICE_BINDING_PROTOCOL     *ServiceBinding;\r
-\r
-  if (Entry == NULL || Context == NULL) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Instance = NET_LIST_USER_STRUCT_S (Entry, DHCP_PROTOCOL, Link, DHCP_PROTOCOL_SIGNATURE);\r
-  ServiceBinding = (EFI_SERVICE_BINDING_PROTOCOL *) Context;\r
-\r
-  return ServiceBinding->DestroyChild (ServiceBinding, Instance->Handle);\r
-}\r
-\r
-\r
-/**\r
-  Stop this driver on ControllerHandle. This service is called by the\r
-  EFI boot service DisconnectController(). In order to\r
-  make drivers as small as possible, there are a few calling\r
-  restrictions for this service. DisconnectController()\r
-  must follow these calling restrictions. If any other agent wishes\r
-  to call Stop() it must also follow these calling restrictions.\r
-\r
-  @param[in]  This              Protocol instance pointer.\r
-  @param[in]  ControllerHandle  Handle of device to stop driver on\r
-  @param[in]  NumberOfChildren  Number of Handles in ChildHandleBuffer. If number of\r
-                                children is zero stop the entire bus driver.\r
-  @param[in]  ChildHandleBuffer List of Child Handles to Stop.\r
-\r
-  @retval EFI_SUCCESS       This driver is removed ControllerHandle\r
-  @retval other             This driver was not removed from this device\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Dhcp4DriverBindingStop (\r
-  IN  EFI_DRIVER_BINDING_PROTOCOL  *This,\r
-  IN  EFI_HANDLE                   ControllerHandle,\r
-  IN  UINTN                        NumberOfChildren,\r
-  IN  EFI_HANDLE                   *ChildHandleBuffer\r
-  )\r
-{\r
-  EFI_SERVICE_BINDING_PROTOCOL  *ServiceBinding;\r
-  DHCP_SERVICE                  *DhcpSb;\r
-  EFI_HANDLE                    NicHandle;\r
-  EFI_STATUS                    Status;\r
-  LIST_ENTRY                    *List;\r
-  UINTN                         ListLength;\r
-\r
-  //\r
-  // DHCP driver opens UDP child, So, the ControllerHandle is the\r
-  // UDP child handle. locate the Nic handle first.\r
-  //\r
-  NicHandle = NetLibGetNicHandle (ControllerHandle, &gEfiUdp4ProtocolGuid);\r
-\r
-  if (NicHandle == NULL) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-   Status = gBS->OpenProtocol (\r
-                  NicHandle,\r
-                  &gEfiDhcp4ServiceBindingProtocolGuid,\r
-                  (VOID **) &ServiceBinding,\r
-                  This->DriverBindingHandle,\r
-                  NicHandle,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  DhcpSb = DHCP_SERVICE_FROM_THIS (ServiceBinding);\r
-  if (!IsListEmpty (&DhcpSb->Children)) {\r
-    //\r
-    // Destroy all the children instances before destory the service.\r
-    //\r
-    List = &DhcpSb->Children;\r
-    Status = NetDestroyLinkList (\r
-               List,\r
-               Dhcp4DestroyChildEntry,\r
-               ServiceBinding,\r
-               &ListLength\r
-               );\r
-    if (EFI_ERROR (Status) || ListLength != 0) {\r
-      Status = EFI_DEVICE_ERROR;\r
-    }\r
-  }\r
-\r
-  if (NumberOfChildren == 0 && !IsListEmpty (&DhcpSb->Children)) {\r
-    Status = EFI_DEVICE_ERROR;\r
-  }\r
-\r
-  if (NumberOfChildren == 0 && IsListEmpty (&DhcpSb->Children)) {\r
-    //\r
-    // Destroy the service itself if no child instance left.\r
-    //\r
-    DhcpSb->ServiceState = DHCP_DESTROY;\r
-\r
-    gBS->UninstallProtocolInterface (\r
-           NicHandle,\r
-           &gEfiDhcp4ServiceBindingProtocolGuid,\r
-           ServiceBinding\r
-           );\r
-\r
-    Dhcp4CloseService (DhcpSb);\r
-\r
-    if (gDhcpControllerNameTable != NULL) {\r
-      FreeUnicodeStringTable (gDhcpControllerNameTable);\r
-      gDhcpControllerNameTable = NULL;\r
-    }\r
-    FreePool (DhcpSb);\r
-\r
-    Status = EFI_SUCCESS;\r
-  }\r
-\r
-  return Status;\r
-}\r
-\r
-\r
-/**\r
-  Initialize a new DHCP instance.\r
-\r
-  @param  DhcpSb                 The dhcp service instance\r
-  @param  Instance               The dhcp instance to initialize\r
-\r
-**/\r
-VOID\r
-DhcpInitProtocol (\r
-  IN     DHCP_SERVICE           *DhcpSb,\r
-  IN OUT DHCP_PROTOCOL          *Instance\r
-  )\r
-{\r
-  Instance->Signature         = DHCP_PROTOCOL_SIGNATURE;\r
-  CopyMem (&Instance->Dhcp4Protocol, &mDhcp4ProtocolTemplate, sizeof (Instance->Dhcp4Protocol));\r
-  InitializeListHead (&Instance->Link);\r
-  Instance->Handle            = NULL;\r
-  Instance->Service           = DhcpSb;\r
-  Instance->InDestroy         = FALSE;\r
-  Instance->CompletionEvent   = NULL;\r
-  Instance->RenewRebindEvent  = NULL;\r
-  Instance->Token             = NULL;\r
-  Instance->UdpIo             = NULL;\r
-  Instance->ElaspedTime       = 0;\r
-  NetbufQueInit (&Instance->ResponseQueue);\r
-}\r
-\r
-\r
-/**\r
-  Creates a child handle and installs a protocol.\r
-\r
-  The CreateChild() function installs a protocol on ChildHandle.\r
-  If ChildHandle is a pointer to NULL, then a new handle is created and returned in ChildHandle.\r
-  If ChildHandle is not a pointer to NULL, then the protocol installs on the existing ChildHandle.\r
-\r
-  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
-  @param  ChildHandle Pointer to the handle of the child to create. If it is NULL,\r
-                      then a new handle is created. If it is a pointer to an existing UEFI handle,\r
-                      then the protocol is added to the existing UEFI handle.\r
-\r
-  @retval EFI_SUCCES            The protocol was added to ChildHandle.\r
-  @retval EFI_INVALID_PARAMETER ChildHandle is NULL.\r
-  @retval EFI_OUT_OF_RESOURCES  There are not enough resources available to create\r
-                                the child\r
-  @retval other                 The child handle was not created\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Dhcp4ServiceBindingCreateChild (\r
-  IN EFI_SERVICE_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                    *ChildHandle\r
-  )\r
-{\r
-  DHCP_SERVICE              *DhcpSb;\r
-  DHCP_PROTOCOL             *Instance;\r
-  EFI_STATUS                Status;\r
-  EFI_TPL                   OldTpl;\r
-  VOID                      *Udp4;\r
-\r
-  if ((This == NULL) || (ChildHandle == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  Instance = AllocatePool (sizeof (*Instance));\r
-\r
-  if (Instance == NULL) {\r
-    return EFI_OUT_OF_RESOURCES;\r
-  }\r
-\r
-  DhcpSb = DHCP_SERVICE_FROM_THIS (This);\r
-  DhcpInitProtocol (DhcpSb, Instance);\r
-\r
-  //\r
-  // Install DHCP4 onto ChildHandle\r
-  //\r
-  Status = gBS->InstallMultipleProtocolInterfaces (\r
-                  ChildHandle,\r
-                  &gEfiDhcp4ProtocolGuid,\r
-                  &Instance->Dhcp4Protocol,\r
-                  NULL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    FreePool (Instance);\r
-    return Status;\r
-  }\r
-\r
-  Instance->Handle  = *ChildHandle;\r
-\r
-  //\r
-  // Open the Udp4 protocol BY_CHILD.\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  DhcpSb->UdpIo->UdpHandle,\r
-                  &gEfiUdp4ProtocolGuid,\r
-                  (VOID **) &Udp4,\r
-                  gDhcp4DriverBinding.DriverBindingHandle,\r
-                  Instance->Handle,\r
-                  EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
-                  );\r
-  if (EFI_ERROR (Status)) {\r
-    gBS->UninstallMultipleProtocolInterfaces (\r
-           Instance->Handle,\r
-           &gEfiDhcp4ProtocolGuid,\r
-           &Instance->Dhcp4Protocol,\r
-           NULL\r
-           );\r
-\r
-    FreePool (Instance);\r
-    return Status;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-\r
-  InsertTailList (&DhcpSb->Children, &Instance->Link);\r
-  DhcpSb->NumChildren++;\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  return EFI_SUCCESS;\r
-}\r
-\r
-\r
-/**\r
-  Destroys a child handle with a protocol installed on it.\r
-\r
-  The DestroyChild() function does the opposite of CreateChild(). It removes a protocol\r
-  that was installed by CreateChild() from ChildHandle. If the removed protocol is the\r
-  last protocol on ChildHandle, then ChildHandle is destroyed.\r
-\r
-  @param  This        Pointer to the EFI_SERVICE_BINDING_PROTOCOL instance.\r
-  @param  ChildHandle Handle of the child to destroy\r
-\r
-  @retval EFI_SUCCES            The protocol was removed from ChildHandle.\r
-  @retval EFI_UNSUPPORTED       ChildHandle does not support the protocol that is being removed.\r
-  @retval EFI_INVALID_PARAMETER Child handle is NULL.\r
-  @retval EFI_ACCESS_DENIED     The protocol could not be removed from the ChildHandle\r
-                                because its services are being used.\r
-  @retval other                 The child handle was not destroyed\r
-\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-Dhcp4ServiceBindingDestroyChild (\r
-  IN EFI_SERVICE_BINDING_PROTOCOL  *This,\r
-  IN EFI_HANDLE                    ChildHandle\r
-  )\r
-{\r
-  DHCP_SERVICE              *DhcpSb;\r
-  DHCP_PROTOCOL             *Instance;\r
-  EFI_DHCP4_PROTOCOL        *Dhcp;\r
-  EFI_TPL                   OldTpl;\r
-  EFI_STATUS                Status;\r
-\r
-  if ((This == NULL) || (ChildHandle == NULL)) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // Retrieve the private context data structures\r
-  //\r
-  Status = gBS->OpenProtocol (\r
-                  ChildHandle,\r
-                  &gEfiDhcp4ProtocolGuid,\r
-                  (VOID **) &Dhcp,\r
-                  gDhcp4DriverBinding.DriverBindingHandle,\r
-                  ChildHandle,\r
-                  EFI_OPEN_PROTOCOL_GET_PROTOCOL\r
-                  );\r
-\r
-  if (EFI_ERROR (Status)) {\r
-    return EFI_UNSUPPORTED;\r
-  }\r
-\r
-  Instance  = DHCP_INSTANCE_FROM_THIS (Dhcp);\r
-  DhcpSb    = DHCP_SERVICE_FROM_THIS (This);\r
-\r
-  if (Instance->Service != DhcpSb) {\r
-    return EFI_INVALID_PARAMETER;\r
-  }\r
-\r
-  //\r
-  // A child can be destroyed more than once. For example,\r
-  // Dhcp4DriverBindingStop will destroy all of its children.\r
-  // when caller driver is being stopped, it will destroy the\r
-  // dhcp child it opens.\r
-  //\r
-  if (Instance->InDestroy) {\r
-    return EFI_SUCCESS;\r
-  }\r
-\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  Instance->InDestroy = TRUE;\r
-\r
-  //\r
-  // Close the Udp4 protocol.\r
-  //\r
-  gBS->CloseProtocol (\r
-         DhcpSb->UdpIo->UdpHandle,\r
-         &gEfiUdp4ProtocolGuid,\r
-         gDhcp4DriverBinding.DriverBindingHandle,\r
-         ChildHandle\r
-         );\r
-\r
-  //\r
-  // Uninstall the DHCP4 protocol first to enable a top down destruction.\r
-  //\r
-  gBS->RestoreTPL (OldTpl);\r
-  Status = gBS->UninstallProtocolInterface (\r
-                  ChildHandle,\r
-                  &gEfiDhcp4ProtocolGuid,\r
-                  Dhcp\r
-                  );\r
-  OldTpl = gBS->RaiseTPL (TPL_CALLBACK);\r
-  if (EFI_ERROR (Status)) {\r
-    Instance->InDestroy = FALSE;\r
-\r
-    gBS->RestoreTPL (OldTpl);\r
-    return Status;\r
-  }\r
-\r
-  if (DhcpSb->ActiveChild == Instance) {\r
-    DhcpYieldControl (DhcpSb);\r
-  }\r
-\r
-  RemoveEntryList (&Instance->Link);\r
-  DhcpSb->NumChildren--;\r
-\r
-  if (Instance->UdpIo != NULL) {\r
-    UdpIoCleanIo (Instance->UdpIo);\r
-    gBS->CloseProtocol (\r
-           Instance->UdpIo->UdpHandle,\r
-           &gEfiUdp4ProtocolGuid,\r
-           Instance->Service->Image,\r
-           Instance->Handle\r
-           );\r
-    UdpIoFreeIo (Instance->UdpIo);\r
-    Instance->UdpIo = NULL;\r
-    Instance->Token = NULL;\r
-  }\r
-\r
-  gBS->RestoreTPL (OldTpl);\r
-\r
-  FreePool (Instance);\r
-  return EFI_SUCCESS;\r
-}\r