Home | History | Annotate | Download | only in HttpBootDxe
      1 /** @file
      2   Driver Binding functions implementation for UEFI HTTP boot.
      3 
      4 Copyright (c) 2015 - 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials are licensed and made available under
      6 the terms and conditions of the BSD License that accompanies this distribution.
      7 The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php.
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 #include "HttpBootDxe.h"
     16 
     17 ///
     18 /// Driver Binding Protocol instance
     19 ///
     20 EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp4DxeDriverBinding = {
     21   HttpBootIp4DxeDriverBindingSupported,
     22   HttpBootIp4DxeDriverBindingStart,
     23   HttpBootIp4DxeDriverBindingStop,
     24   HTTP_BOOT_DXE_VERSION,
     25   NULL,
     26   NULL
     27 };
     28 
     29 EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp6DxeDriverBinding = {
     30   HttpBootIp6DxeDriverBindingSupported,
     31   HttpBootIp6DxeDriverBindingStart,
     32   HttpBootIp6DxeDriverBindingStop,
     33   HTTP_BOOT_DXE_VERSION,
     34   NULL,
     35   NULL
     36 };
     37 
     38 /**
     39   Destroy the HTTP child based on IPv4 stack.
     40 
     41   @param[in]  This              Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
     42   @param[in]  Private           Pointer to HTTP_BOOT_PRIVATE_DATA.
     43 
     44 **/
     45 VOID
     46 HttpBootDestroyIp4Children (
     47   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
     48   IN HTTP_BOOT_PRIVATE_DATA       *Private
     49   )
     50 {
     51   ASSERT (This != NULL);
     52   ASSERT (Private != NULL);
     53 
     54   if (Private->Dhcp4Child != NULL) {
     55     gBS->CloseProtocol (
     56            Private->Dhcp4Child,
     57            &gEfiDhcp4ProtocolGuid,
     58            This->DriverBindingHandle,
     59            Private->Controller
     60            );
     61 
     62     NetLibDestroyServiceChild (
     63       Private->Controller,
     64       This->DriverBindingHandle,
     65       &gEfiDhcp4ServiceBindingProtocolGuid,
     66       Private->Dhcp4Child
     67       );
     68   }
     69 
     70   if (Private->HttpCreated) {
     71     HttpIoDestroyIo (&Private->HttpIo);
     72     Private->HttpCreated = FALSE;
     73   }
     74 
     75   if (Private->Ip4Nic != NULL) {
     76 
     77     gBS->CloseProtocol (
     78            Private->Controller,
     79            &gEfiCallerIdGuid,
     80            This->DriverBindingHandle,
     81            Private->Ip4Nic->Controller
     82            );
     83 
     84     gBS->UninstallMultipleProtocolInterfaces (
     85            Private->Ip4Nic->Controller,
     86            &gEfiLoadFileProtocolGuid,
     87            &Private->Ip4Nic->LoadFile,
     88            &gEfiDevicePathProtocolGuid,
     89            Private->Ip4Nic->DevicePath,
     90            NULL
     91            );
     92     FreePool (Private->Ip4Nic);
     93     Private->Ip4Nic = NULL;
     94   }
     95 
     96 }
     97 
     98 /**
     99   Destroy the HTTP child based on IPv6 stack.
    100 
    101   @param[in]  This              Pointer to the EFI_DRIVER_BINDING_PROTOCOL.
    102   @param[in]  Private           Pointer to HTTP_BOOT_PRIVATE_DATA.
    103 
    104 **/
    105 VOID
    106 HttpBootDestroyIp6Children (
    107   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    108   IN HTTP_BOOT_PRIVATE_DATA       *Private
    109   )
    110 {
    111   ASSERT (This != NULL);
    112   ASSERT (Private != NULL);
    113 
    114   if (Private->Ip6Child != NULL) {
    115     gBS->CloseProtocol (
    116            Private->Ip6Child,
    117            &gEfiIp6ProtocolGuid,
    118            This->DriverBindingHandle,
    119            Private->Controller
    120            );
    121 
    122     NetLibDestroyServiceChild (
    123       Private->Controller,
    124       This->DriverBindingHandle,
    125       &gEfiIp6ServiceBindingProtocolGuid,
    126       Private->Ip6Child
    127       );
    128   }
    129 
    130   if (Private->Dhcp6Child != NULL) {
    131     gBS->CloseProtocol (
    132            Private->Dhcp6Child,
    133            &gEfiDhcp6ProtocolGuid,
    134            This->DriverBindingHandle,
    135            Private->Controller
    136            );
    137 
    138     NetLibDestroyServiceChild (
    139       Private->Controller,
    140       This->DriverBindingHandle,
    141       &gEfiDhcp6ServiceBindingProtocolGuid,
    142       Private->Dhcp6Child
    143       );
    144   }
    145 
    146   if (Private->HttpCreated) {
    147     HttpIoDestroyIo(&Private->HttpIo);
    148     Private->HttpCreated = FALSE;
    149   }
    150 
    151   if (Private->Ip6Nic != NULL) {
    152 
    153     gBS->CloseProtocol (
    154            Private->Controller,
    155            &gEfiCallerIdGuid,
    156            This->DriverBindingHandle,
    157            Private->Ip6Nic->Controller
    158            );
    159 
    160     gBS->UninstallMultipleProtocolInterfaces (
    161            Private->Ip6Nic->Controller,
    162            &gEfiLoadFileProtocolGuid,
    163            &Private->Ip6Nic->LoadFile,
    164            &gEfiDevicePathProtocolGuid,
    165            Private->Ip6Nic->DevicePath,
    166            NULL
    167            );
    168     FreePool (Private->Ip6Nic);
    169     Private->Ip6Nic = NULL;
    170   }
    171 }
    172 
    173 /**
    174   Tests to see if this driver supports a given controller. If a child device is provided,
    175   it further tests to see if this driver supports creating a handle for the specified child device.
    176 
    177   This function checks to see if the driver specified by This supports the device specified by
    178   ControllerHandle. Drivers will typically use the device path attached to
    179   ControllerHandle and/or the services from the bus I/O abstraction attached to
    180   ControllerHandle to determine if the driver supports ControllerHandle. This function
    181   may be called many times during platform initialization. In order to reduce boot times, the tests
    182   performed by this function must be very small, and take as little time as possible to execute. This
    183   function must not change the state of any hardware devices, and this function must be aware that the
    184   device specified by ControllerHandle may already be managed by the same driver or a
    185   different driver. This function must match its calls to AllocatePages() with FreePages(),
    186   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
    187   Because ControllerHandle may have been previously started by the same driver, if a protocol is
    188   already in the opened state, then it must not be closed with CloseProtocol(). This is required
    189   to guarantee the state of ControllerHandle is not modified by this function.
    190 
    191   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    192   @param[in]  ControllerHandle     The handle of the controller to test. This handle
    193                                    must support a protocol interface that supplies
    194                                    an I/O abstraction to the driver.
    195   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    196                                    parameter is ignored by device drivers, and is optional for bus
    197                                    drivers. For bus drivers, if this parameter is not NULL, then
    198                                    the bus driver must determine if the bus controller specified
    199                                    by ControllerHandle and the child controller specified
    200                                    by RemainingDevicePath are both supported by this
    201                                    bus driver.
    202 
    203   @retval EFI_SUCCESS              The device specified by ControllerHandle and
    204                                    RemainingDevicePath is supported by the driver specified by This.
    205   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
    206                                    RemainingDevicePath is already being managed by the driver
    207                                    specified by This.
    208   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
    209                                    RemainingDevicePath is already being managed by a different
    210                                    driver or an application that requires exclusive access.
    211                                    Currently not implemented.
    212   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
    213                                    RemainingDevicePath is not supported by the driver specified by This.
    214 **/
    215 EFI_STATUS
    216 EFIAPI
    217 HttpBootIp4DxeDriverBindingSupported (
    218   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    219   IN EFI_HANDLE                   ControllerHandle,
    220   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    221   )
    222 {
    223   EFI_STATUS                    Status;
    224 
    225   //
    226   // Try to open the DHCP4, HTTP4 and Device Path protocol.
    227   //
    228   Status = gBS->OpenProtocol (
    229                   ControllerHandle,
    230                   &gEfiDhcp4ServiceBindingProtocolGuid,
    231                   NULL,
    232                   This->DriverBindingHandle,
    233                   ControllerHandle,
    234                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
    235                   );
    236   if (EFI_ERROR (Status)) {
    237     return Status;
    238   }
    239 
    240   Status = gBS->OpenProtocol (
    241                   ControllerHandle,
    242                   &gEfiHttpServiceBindingProtocolGuid,
    243                   NULL,
    244                   This->DriverBindingHandle,
    245                   ControllerHandle,
    246                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
    247                   );
    248   if (EFI_ERROR (Status)) {
    249     return Status;
    250   }
    251 
    252   Status = gBS->OpenProtocol (
    253                   ControllerHandle,
    254                   &gEfiDevicePathProtocolGuid,
    255                   NULL,
    256                   This->DriverBindingHandle,
    257                   ControllerHandle,
    258                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
    259                   );
    260 
    261   return Status;
    262 }
    263 
    264 
    265 /**
    266   Starts a device controller or a bus controller.
    267 
    268   The Start() function is designed to be invoked from the EFI boot service ConnectController().
    269   As a result, much of the error checking on the parameters to Start() has been moved into this
    270   common boot service. It is legal to call Start() from other locations,
    271   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
    272   1. ControllerHandle must be a valid EFI_HANDLE.
    273   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
    274      EFI_DEVICE_PATH_PROTOCOL.
    275   3. Prior to calling Start(), the Supported() function for the driver specified by This must
    276      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
    277 
    278   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    279   @param[in]  ControllerHandle     The handle of the controller to start. This handle
    280                                    must support a protocol interface that supplies
    281                                    an I/O abstraction to the driver.
    282   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    283                                    parameter is ignored by device drivers, and is optional for bus
    284                                    drivers. For a bus driver, if this parameter is NULL, then handles
    285                                    for all the children of Controller are created by this driver.
    286                                    If this parameter is not NULL and the first Device Path Node is
    287                                    not the End of Device Path Node, then only the handle for the
    288                                    child device specified by the first Device Path Node of
    289                                    RemainingDevicePath is created by this driver.
    290                                    If the first Device Path Node of RemainingDevicePath is
    291                                    the End of Device Path Node, no child handle is created by this
    292                                    driver.
    293 
    294   @retval EFI_SUCCESS              The device was started.
    295   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
    296   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
    297   @retval Others                   The driver failded to start the device.
    298 
    299 **/
    300 EFI_STATUS
    301 EFIAPI
    302 HttpBootIp4DxeDriverBindingStart (
    303   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    304   IN EFI_HANDLE                   ControllerHandle,
    305   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    306   )
    307 {
    308   EFI_STATUS                 Status;
    309   HTTP_BOOT_PRIVATE_DATA     *Private;
    310   EFI_DEV_PATH               *Node;
    311   EFI_DEVICE_PATH_PROTOCOL   *DevicePath;
    312   UINT32                     *Id;
    313 
    314   Status = gBS->OpenProtocol (
    315                   ControllerHandle,
    316                   &gEfiCallerIdGuid,
    317                   (VOID **) &Id,
    318                   This->DriverBindingHandle,
    319                   ControllerHandle,
    320                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    321                   );
    322 
    323   if (!EFI_ERROR (Status)) {
    324     Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id);
    325   } else {
    326     //
    327     // Initialize the private data structure.
    328     //
    329     Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
    330     if (Private == NULL) {
    331       return EFI_OUT_OF_RESOURCES;
    332     }
    333     Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
    334     Private->Controller = ControllerHandle;
    335     InitializeListHead (&Private->CacheList);
    336     //
    337     // Get the NII interface if it exists, it's not required.
    338     //
    339     Status = gBS->OpenProtocol (
    340                     ControllerHandle,
    341                     &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
    342                     (VOID **) &Private->Nii,
    343                     This->DriverBindingHandle,
    344                     ControllerHandle,
    345                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    346                     );
    347     if (EFI_ERROR (Status)) {
    348       Private->Nii = NULL;
    349     }
    350 
    351     //
    352     // Open Device Path Protocol to prepare for appending IP and URI node.
    353     //
    354     Status = gBS->OpenProtocol (
    355                     ControllerHandle,
    356                     &gEfiDevicePathProtocolGuid,
    357                     (VOID **) &Private->ParentDevicePath,
    358                     This->DriverBindingHandle,
    359                     ControllerHandle,
    360                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    361                     );
    362     if (EFI_ERROR (Status)) {
    363       goto ON_ERROR;
    364     }
    365 
    366     //
    367     // Initialize the HII configuration form.
    368     //
    369     Status = HttpBootConfigFormInit (Private);
    370     if (EFI_ERROR (Status)) {
    371       goto ON_ERROR;
    372     }
    373 
    374     //
    375     // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
    376     // NIC handle and the private data.
    377     //
    378     Status = gBS->InstallProtocolInterface (
    379                     &ControllerHandle,
    380                     &gEfiCallerIdGuid,
    381                     EFI_NATIVE_INTERFACE,
    382                     &Private->Id
    383                     );
    384     if (EFI_ERROR (Status)) {
    385       goto ON_ERROR;
    386     }
    387 
    388   }
    389 
    390   if (Private->Ip4Nic != NULL) {
    391     //
    392     // Already created before
    393     //
    394     return EFI_SUCCESS;
    395   }
    396 
    397   Private->Ip4Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
    398   if (Private->Ip4Nic == NULL) {
    399     return EFI_OUT_OF_RESOURCES;
    400   }
    401   Private->Ip4Nic->Private     = Private;
    402   Private->Ip4Nic->ImageHandle = This->DriverBindingHandle;
    403   Private->Ip4Nic->Signature   = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
    404 
    405   //
    406   // Create DHCP4 child instance.
    407   //
    408   Status = NetLibCreateServiceChild (
    409              ControllerHandle,
    410              This->DriverBindingHandle,
    411              &gEfiDhcp4ServiceBindingProtocolGuid,
    412              &Private->Dhcp4Child
    413              );
    414   if (EFI_ERROR (Status)) {
    415     goto ON_ERROR;
    416   }
    417 
    418   Status = gBS->OpenProtocol (
    419                   Private->Dhcp4Child,
    420                   &gEfiDhcp4ProtocolGuid,
    421                   (VOID **) &Private->Dhcp4,
    422                   This->DriverBindingHandle,
    423                   ControllerHandle,
    424                   EFI_OPEN_PROTOCOL_BY_DRIVER
    425                   );
    426   if (EFI_ERROR (Status)) {
    427     goto ON_ERROR;
    428   }
    429 
    430   //
    431   // Get the Ip4Config2 protocol, it's required to configure the default gateway address.
    432   //
    433   Status = gBS->OpenProtocol (
    434                   ControllerHandle,
    435                   &gEfiIp4Config2ProtocolGuid,
    436                   (VOID **) &Private->Ip4Config2,
    437                   This->DriverBindingHandle,
    438                   ControllerHandle,
    439                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    440                   );
    441   if (EFI_ERROR (Status)) {
    442     goto ON_ERROR;
    443   }
    444 
    445   //
    446   // Append IPv4 device path node.
    447   //
    448   Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
    449   if (Node == NULL) {
    450     Status = EFI_OUT_OF_RESOURCES;
    451     goto ON_ERROR;
    452   }
    453   Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
    454   Node->Ipv4.Header.SubType = MSG_IPv4_DP;
    455   SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));
    456   Node->Ipv4.StaticIpAddress = FALSE;
    457   DevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
    458   FreePool (Node);
    459   if (DevicePath == NULL) {
    460     Status = EFI_OUT_OF_RESOURCES;
    461     goto ON_ERROR;
    462   }
    463 
    464   //
    465   // Append URI device path node.
    466   //
    467   Node = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
    468   if (Node == NULL) {
    469     Status = EFI_OUT_OF_RESOURCES;
    470     goto ON_ERROR;
    471   }
    472   Node->DevPath.Type = MESSAGING_DEVICE_PATH;
    473   Node->DevPath.SubType = MSG_URI_DP;
    474   SetDevicePathNodeLength (Node, sizeof (EFI_DEVICE_PATH_PROTOCOL));
    475   Private->Ip4Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
    476   FreePool (Node);
    477   FreePool (DevicePath);
    478   if (Private->Ip4Nic->DevicePath == NULL) {
    479     Status = EFI_OUT_OF_RESOURCES;
    480     goto ON_ERROR;
    481   }
    482 
    483   //
    484   // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
    485   //
    486   CopyMem (&Private->Ip4Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (EFI_LOAD_FILE_PROTOCOL));
    487   Status = gBS->InstallMultipleProtocolInterfaces (
    488                   &Private->Ip4Nic->Controller,
    489                   &gEfiLoadFileProtocolGuid,
    490                   &Private->Ip4Nic->LoadFile,
    491                   &gEfiDevicePathProtocolGuid,
    492                   Private->Ip4Nic->DevicePath,
    493                   NULL
    494                   );
    495   if (EFI_ERROR (Status)) {
    496     goto ON_ERROR;
    497   }
    498 
    499   //
    500   // Open the Caller Id child to setup a parent-child relationship between
    501   // real NIC handle and the HTTP boot Ipv4 NIC handle.
    502   //
    503   Status = gBS->OpenProtocol (
    504                   ControllerHandle,
    505                   &gEfiCallerIdGuid,
    506                   (VOID **) &Id,
    507                   This->DriverBindingHandle,
    508                   Private->Ip4Nic->Controller,
    509                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
    510                   );
    511   if (EFI_ERROR (Status)) {
    512     goto ON_ERROR;
    513   }
    514 
    515   return EFI_SUCCESS;
    516 
    517 
    518 ON_ERROR:
    519 
    520   HttpBootDestroyIp4Children (This, Private);
    521   HttpBootConfigFormUnload (Private);
    522   FreePool (Private);
    523 
    524   return Status;
    525 }
    526 
    527 
    528 /**
    529   Stops a device controller or a bus controller.
    530 
    531   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
    532   As a result, much of the error checking on the parameters to Stop() has been moved
    533   into this common boot service. It is legal to call Stop() from other locations,
    534   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
    535   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
    536      same driver's Start() function.
    537   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
    538      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
    539      Start() function, and the Start() function must have called OpenProtocol() on
    540      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
    541 
    542   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    543   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
    544                                 support a bus specific I/O protocol for the driver
    545                                 to use to stop the device.
    546   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
    547   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
    548                                 if NumberOfChildren is 0.
    549 
    550   @retval EFI_SUCCESS           The device was stopped.
    551   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
    552 
    553 **/
    554 EFI_STATUS
    555 EFIAPI
    556 HttpBootIp4DxeDriverBindingStop (
    557   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    558   IN EFI_HANDLE                   ControllerHandle,
    559   IN UINTN                        NumberOfChildren,
    560   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
    561   )
    562 {
    563   EFI_STATUS                      Status;
    564   EFI_LOAD_FILE_PROTOCOL          *LoadFile;
    565   HTTP_BOOT_PRIVATE_DATA          *Private;
    566   EFI_HANDLE                      NicHandle;
    567   UINT32                          *Id;
    568 
    569   //
    570   // Try to get the Load File Protocol from the controller handle.
    571   //
    572   Status = gBS->OpenProtocol (
    573                   ControllerHandle,
    574                   &gEfiLoadFileProtocolGuid,
    575                   (VOID **) &LoadFile,
    576                   This->DriverBindingHandle,
    577                   ControllerHandle,
    578                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    579                   );
    580   if (EFI_ERROR (Status)) {
    581     //
    582     // If failed, try to find the NIC handle for this controller.
    583     //
    584     NicHandle = HttpBootGetNicByIp4Children (ControllerHandle);
    585     if (NicHandle == NULL) {
    586       return EFI_SUCCESS;
    587     }
    588 
    589     //
    590     // Try to retrieve the private data by the Caller Id Guid.
    591     //
    592     Status = gBS->OpenProtocol (
    593                     NicHandle,
    594                     &gEfiCallerIdGuid,
    595                     (VOID **) &Id,
    596                     This->DriverBindingHandle,
    597                     ControllerHandle,
    598                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    599                     );
    600     if (EFI_ERROR (Status)) {
    601       return Status;
    602     }
    603     Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
    604   } else {
    605     Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
    606     NicHandle = Private->Controller;
    607   }
    608 
    609   //
    610   // Disable the HTTP boot function.
    611   //
    612   Status = HttpBootStop (Private);
    613   if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {
    614     return Status;
    615   }
    616 
    617   //
    618   // Destory all child instance and uninstall protocol interface.
    619   //
    620   HttpBootDestroyIp4Children (This, Private);
    621 
    622   if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
    623     //
    624     // Release the cached data.
    625     //
    626     HttpBootFreeCacheList (Private);
    627 
    628     //
    629     // Unload the config form.
    630     //
    631     HttpBootConfigFormUnload (Private);
    632 
    633     gBS->UninstallProtocolInterface (
    634            NicHandle,
    635            &gEfiCallerIdGuid,
    636            &Private->Id
    637            );
    638     FreePool (Private);
    639 
    640   }
    641 
    642   return EFI_SUCCESS;
    643 }
    644 
    645 /**
    646   Tests to see if this driver supports a given controller. If a child device is provided,
    647   it further tests to see if this driver supports creating a handle for the specified child device.
    648 
    649   This function checks to see if the driver specified by This supports the device specified by
    650   ControllerHandle. Drivers will typically use the device path attached to
    651   ControllerHandle and/or the services from the bus I/O abstraction attached to
    652   ControllerHandle to determine if the driver supports ControllerHandle. This function
    653   may be called many times during platform initialization. In order to reduce boot times, the tests
    654   performed by this function must be very small, and take as little time as possible to execute. This
    655   function must not change the state of any hardware devices, and this function must be aware that the
    656   device specified by ControllerHandle may already be managed by the same driver or a
    657   different driver. This function must match its calls to AllocatePages() with FreePages(),
    658   AllocatePool() with FreePool(), and OpenProtocol() with CloseProtocol().
    659   Because ControllerHandle may have been previously started by the same driver, if a protocol is
    660   already in the opened state, then it must not be closed with CloseProtocol(). This is required
    661   to guarantee the state of ControllerHandle is not modified by this function.
    662 
    663   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    664   @param[in]  ControllerHandle     The handle of the controller to test. This handle
    665                                    must support a protocol interface that supplies
    666                                    an I/O abstraction to the driver.
    667   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    668                                    parameter is ignored by device drivers, and is optional for bus
    669                                    drivers. For bus drivers, if this parameter is not NULL, then
    670                                    the bus driver must determine if the bus controller specified
    671                                    by ControllerHandle and the child controller specified
    672                                    by RemainingDevicePath are both supported by this
    673                                    bus driver.
    674 
    675   @retval EFI_SUCCESS              The device specified by ControllerHandle and
    676                                    RemainingDevicePath is supported by the driver specified by This.
    677   @retval EFI_ALREADY_STARTED      The device specified by ControllerHandle and
    678                                    RemainingDevicePath is already being managed by the driver
    679                                    specified by This.
    680   @retval EFI_ACCESS_DENIED        The device specified by ControllerHandle and
    681                                    RemainingDevicePath is already being managed by a different
    682                                    driver or an application that requires exclusive access.
    683                                    Currently not implemented.
    684   @retval EFI_UNSUPPORTED          The device specified by ControllerHandle and
    685                                    RemainingDevicePath is not supported by the driver specified by This.
    686 **/
    687 EFI_STATUS
    688 EFIAPI
    689 HttpBootIp6DxeDriverBindingSupported (
    690   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    691   IN EFI_HANDLE                   ControllerHandle,
    692   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    693   )
    694 {
    695   EFI_STATUS                    Status;
    696 
    697   //
    698   // Try to open the DHCP6, HTTP and Device Path protocol.
    699   //
    700   Status = gBS->OpenProtocol (
    701                   ControllerHandle,
    702                   &gEfiDhcp6ServiceBindingProtocolGuid,
    703                   NULL,
    704                   This->DriverBindingHandle,
    705                   ControllerHandle,
    706                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
    707                   );
    708   if (EFI_ERROR (Status)) {
    709     return Status;
    710   }
    711 
    712   Status = gBS->OpenProtocol (
    713                   ControllerHandle,
    714                   &gEfiHttpServiceBindingProtocolGuid,
    715                   NULL,
    716                   This->DriverBindingHandle,
    717                   ControllerHandle,
    718                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
    719                   );
    720   if (EFI_ERROR (Status)) {
    721     return Status;
    722   }
    723 
    724   Status = gBS->OpenProtocol (
    725                   ControllerHandle,
    726                   &gEfiDevicePathProtocolGuid,
    727                   NULL,
    728                   This->DriverBindingHandle,
    729                   ControllerHandle,
    730                   EFI_OPEN_PROTOCOL_TEST_PROTOCOL
    731                   );
    732 
    733   return Status;
    734 
    735 }
    736 
    737 /**
    738   Starts a device controller or a bus controller.
    739 
    740   The Start() function is designed to be invoked from the EFI boot service ConnectController().
    741   As a result, much of the error checking on the parameters to Start() has been moved into this
    742   common boot service. It is legal to call Start() from other locations,
    743   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
    744   1. ControllerHandle must be a valid EFI_HANDLE.
    745   2. If RemainingDevicePath is not NULL, then it must be a pointer to a naturally aligned
    746      EFI_DEVICE_PATH_PROTOCOL.
    747   3. Prior to calling Start(), the Supported() function for the driver specified by This must
    748      have been called with the same calling parameters, and Supported() must have returned EFI_SUCCESS.
    749 
    750   @param[in]  This                 A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
    751   @param[in]  ControllerHandle     The handle of the controller to start. This handle
    752                                    must support a protocol interface that supplies
    753                                    an I/O abstraction to the driver.
    754   @param[in]  RemainingDevicePath  A pointer to the remaining portion of a device path.  This
    755                                    parameter is ignored by device drivers, and is optional for bus
    756                                    drivers. For a bus driver, if this parameter is NULL, then handles
    757                                    for all the children of Controller are created by this driver.
    758                                    If this parameter is not NULL and the first Device Path Node is
    759                                    not the End of Device Path Node, then only the handle for the
    760                                    child device specified by the first Device Path Node of
    761                                    RemainingDevicePath is created by this driver.
    762                                    If the first Device Path Node of RemainingDevicePath is
    763                                    the End of Device Path Node, no child handle is created by this
    764                                    driver.
    765 
    766   @retval EFI_SUCCESS              The device was started.
    767   @retval EFI_DEVICE_ERROR         The device could not be started due to a device error.Currently not implemented.
    768   @retval EFI_OUT_OF_RESOURCES     The request could not be completed due to a lack of resources.
    769   @retval Others                   The driver failded to start the device.
    770 
    771 **/
    772 EFI_STATUS
    773 EFIAPI
    774 HttpBootIp6DxeDriverBindingStart (
    775   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
    776   IN EFI_HANDLE                   ControllerHandle,
    777   IN EFI_DEVICE_PATH_PROTOCOL     *RemainingDevicePath OPTIONAL
    778   )
    779 {
    780   EFI_STATUS                 Status;
    781   HTTP_BOOT_PRIVATE_DATA     *Private;
    782   EFI_DEV_PATH               *Node;
    783   EFI_DEVICE_PATH_PROTOCOL   *DevicePath;
    784   UINT32                     *Id;
    785 
    786   Status = gBS->OpenProtocol (
    787                   ControllerHandle,
    788                   &gEfiCallerIdGuid,
    789                   (VOID **) &Id,
    790                   This->DriverBindingHandle,
    791                   ControllerHandle,
    792                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    793                   );
    794 
    795   if (!EFI_ERROR (Status)) {
    796     Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID(Id);
    797   } else {
    798     //
    799     // Initialize the private data structure.
    800     //
    801     Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
    802     if (Private == NULL) {
    803       return EFI_OUT_OF_RESOURCES;
    804     }
    805     Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
    806     Private->Controller = ControllerHandle;
    807     InitializeListHead (&Private->CacheList);
    808     //
    809     // Get the NII interface if it exists, it's not required.
    810     //
    811     Status = gBS->OpenProtocol (
    812                     ControllerHandle,
    813                     &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
    814                     (VOID **) &Private->Nii,
    815                     This->DriverBindingHandle,
    816                     ControllerHandle,
    817                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    818                     );
    819     if (EFI_ERROR (Status)) {
    820       Private->Nii = NULL;
    821     }
    822 
    823     //
    824     // Open Device Path Protocol to prepare for appending IP and URI node.
    825     //
    826     Status = gBS->OpenProtocol (
    827                     ControllerHandle,
    828                     &gEfiDevicePathProtocolGuid,
    829                     (VOID **) &Private->ParentDevicePath,
    830                     This->DriverBindingHandle,
    831                     ControllerHandle,
    832                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
    833                     );
    834     if (EFI_ERROR (Status)) {
    835       goto ON_ERROR;
    836     }
    837 
    838     //
    839     // Initialize the HII configuration form.
    840     //
    841     Status = HttpBootConfigFormInit (Private);
    842     if (EFI_ERROR (Status)) {
    843       goto ON_ERROR;
    844     }
    845 
    846     //
    847     // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
    848     // NIC handle and the private data.
    849     //
    850     Status = gBS->InstallProtocolInterface (
    851                     &ControllerHandle,
    852                     &gEfiCallerIdGuid,
    853                     EFI_NATIVE_INTERFACE,
    854                     &Private->Id
    855                     );
    856     if (EFI_ERROR (Status)) {
    857       goto ON_ERROR;
    858     }
    859 
    860   }
    861 
    862   if (Private->Ip6Nic != NULL) {
    863     //
    864     // Already created before
    865     //
    866     return EFI_SUCCESS;
    867   }
    868 
    869   Private->Ip6Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
    870   if (Private->Ip6Nic == NULL) {
    871     return EFI_OUT_OF_RESOURCES;
    872   }
    873   Private->Ip6Nic->Private     = Private;
    874   Private->Ip6Nic->ImageHandle = This->DriverBindingHandle;
    875   Private->Ip6Nic->Signature   = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
    876 
    877   //
    878   // Create Dhcp6 child and open Dhcp6 protocol
    879   Status = NetLibCreateServiceChild (
    880              ControllerHandle,
    881              This->DriverBindingHandle,
    882              &gEfiDhcp6ServiceBindingProtocolGuid,
    883              &Private->Dhcp6Child
    884              );
    885   if (EFI_ERROR (Status)) {
    886     goto ON_ERROR;
    887   }
    888 
    889   Status = gBS->OpenProtocol (
    890                   Private->Dhcp6Child,
    891                   &gEfiDhcp6ProtocolGuid,
    892                   (VOID **) &Private->Dhcp6,
    893                   This->DriverBindingHandle,
    894                   ControllerHandle,
    895                   EFI_OPEN_PROTOCOL_BY_DRIVER
    896                   );
    897   if (EFI_ERROR (Status)) {
    898     goto ON_ERROR;
    899   }
    900 
    901   //
    902   // Create Ip6 child and open Ip6 protocol for background ICMP packets.
    903   //
    904   Status = NetLibCreateServiceChild (
    905               ControllerHandle,
    906               This->DriverBindingHandle,
    907               &gEfiIp6ServiceBindingProtocolGuid,
    908               &Private->Ip6Child
    909               );
    910   if (EFI_ERROR (Status)) {
    911     goto ON_ERROR;
    912   }
    913 
    914   Status = gBS->OpenProtocol (
    915                   Private->Ip6Child,
    916                   &gEfiIp6ProtocolGuid,
    917                   (VOID **) &Private->Ip6,
    918                   This->DriverBindingHandle,
    919                   ControllerHandle,
    920                   EFI_OPEN_PROTOCOL_BY_DRIVER
    921                   );
    922   if (EFI_ERROR (Status)) {
    923     goto ON_ERROR;
    924   }
    925 
    926   //
    927   // Locate Ip6Config protocol, it's required to configure the default gateway address.
    928   //
    929   Status = gBS->OpenProtocol (
    930                   ControllerHandle,
    931                   &gEfiIp6ConfigProtocolGuid,
    932                   (VOID **) &Private->Ip6Config,
    933                   This->DriverBindingHandle,
    934                   ControllerHandle,
    935                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
    936                   );
    937   if (EFI_ERROR (Status)) {
    938     goto ON_ERROR;
    939   }
    940 
    941   //
    942   // Append IPv6 device path node.
    943   //
    944   Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
    945   if (Node == NULL) {
    946     Status = EFI_OUT_OF_RESOURCES;
    947     goto ON_ERROR;
    948   }
    949   Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
    950   Node->Ipv6.Header.SubType = MSG_IPv6_DP;
    951   Node->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;
    952   SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));
    953   DevicePath = AppendDevicePathNode(Private->ParentDevicePath, (EFI_DEVICE_PATH*) Node);
    954   FreePool(Node);
    955   if (DevicePath == NULL) {
    956     Status = EFI_OUT_OF_RESOURCES;
    957     goto ON_ERROR;
    958   }
    959 
    960   //
    961   // Append URI device path node.
    962   //
    963   Node = AllocateZeroPool (sizeof (EFI_DEVICE_PATH_PROTOCOL));
    964   if (Node == NULL) {
    965     Status = EFI_OUT_OF_RESOURCES;
    966     goto ON_ERROR;
    967   }
    968   Node->DevPath.Type = MESSAGING_DEVICE_PATH;
    969   Node->DevPath.SubType = MSG_URI_DP;
    970   SetDevicePathNodeLength (Node, sizeof (EFI_DEVICE_PATH_PROTOCOL));
    971   Private->Ip6Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL*) Node);
    972   FreePool (Node);
    973   FreePool (DevicePath);
    974   if (Private->Ip6Nic->DevicePath == NULL) {
    975     Status = EFI_OUT_OF_RESOURCES;
    976     goto ON_ERROR;
    977   }
    978 
    979   //
    980   // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
    981   //
    982   CopyMem (&Private->Ip6Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (Private->LoadFile));
    983   Status = gBS->InstallMultipleProtocolInterfaces (
    984                   &Private->Ip6Nic->Controller,
    985                   &gEfiLoadFileProtocolGuid,
    986                   &Private->Ip6Nic->LoadFile,
    987                   &gEfiDevicePathProtocolGuid,
    988                   Private->Ip6Nic->DevicePath,
    989                   NULL
    990                   );
    991   if (EFI_ERROR (Status)) {
    992     goto ON_ERROR;
    993   }
    994 
    995   //
    996   // Open the Caller Id child to setup a parent-child relationship between
    997   // real NIC handle and the HTTP boot child handle.
    998   //
    999   Status = gBS->OpenProtocol (
   1000                   ControllerHandle,
   1001                   &gEfiCallerIdGuid,
   1002                   (VOID **) &Id,
   1003                   This->DriverBindingHandle,
   1004                   Private->Ip6Nic->Controller,
   1005                   EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
   1006                   );
   1007   if (EFI_ERROR (Status)) {
   1008     goto ON_ERROR;
   1009   }
   1010 
   1011   return EFI_SUCCESS;
   1012 
   1013 ON_ERROR:
   1014 
   1015   HttpBootDestroyIp6Children(This, Private);
   1016   HttpBootConfigFormUnload (Private);
   1017   FreePool (Private);
   1018 
   1019   return Status;
   1020 }
   1021 
   1022 /**
   1023   Stops a device controller or a bus controller.
   1024 
   1025   The Stop() function is designed to be invoked from the EFI boot service DisconnectController().
   1026   As a result, much of the error checking on the parameters to Stop() has been moved
   1027   into this common boot service. It is legal to call Stop() from other locations,
   1028   but the following calling restrictions must be followed, or the system behavior will not be deterministic.
   1029   1. ControllerHandle must be a valid EFI_HANDLE that was used on a previous call to this
   1030      same driver's Start() function.
   1031   2. The first NumberOfChildren handles of ChildHandleBuffer must all be a valid
   1032      EFI_HANDLE. In addition, all of these handles must have been created in this driver's
   1033      Start() function, and the Start() function must have called OpenProtocol() on
   1034      ControllerHandle with an Attribute of EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER.
   1035 
   1036   @param[in]  This              A pointer to the EFI_DRIVER_BINDING_PROTOCOL instance.
   1037   @param[in]  ControllerHandle  A handle to the device being stopped. The handle must
   1038                                 support a bus specific I/O protocol for the driver
   1039                                 to use to stop the device.
   1040   @param[in]  NumberOfChildren  The number of child device handles in ChildHandleBuffer.
   1041   @param[in]  ChildHandleBuffer An array of child handles to be freed. May be NULL
   1042                                 if NumberOfChildren is 0.
   1043 
   1044   @retval EFI_SUCCESS           The device was stopped.
   1045   @retval EFI_DEVICE_ERROR      The device could not be stopped due to a device error.
   1046 
   1047 **/
   1048 EFI_STATUS
   1049 EFIAPI
   1050 HttpBootIp6DxeDriverBindingStop (
   1051   IN EFI_DRIVER_BINDING_PROTOCOL  *This,
   1052   IN EFI_HANDLE                   ControllerHandle,
   1053   IN UINTN                        NumberOfChildren,
   1054   IN EFI_HANDLE                   *ChildHandleBuffer OPTIONAL
   1055   )
   1056 {
   1057   EFI_STATUS                      Status;
   1058   EFI_LOAD_FILE_PROTOCOL          *LoadFile;
   1059   HTTP_BOOT_PRIVATE_DATA          *Private;
   1060   EFI_HANDLE                      NicHandle;
   1061   UINT32                          *Id;
   1062 
   1063   //
   1064   // Try to get the Load File Protocol from the controller handle.
   1065   //
   1066   Status = gBS->OpenProtocol (
   1067                   ControllerHandle,
   1068                   &gEfiLoadFileProtocolGuid,
   1069                   (VOID **) &LoadFile,
   1070                   This->DriverBindingHandle,
   1071                   ControllerHandle,
   1072                   EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1073                   );
   1074   if (EFI_ERROR (Status)) {
   1075     //
   1076     // If failed, try to find the NIC handle for this controller.
   1077     //
   1078     NicHandle = HttpBootGetNicByIp6Children (ControllerHandle);
   1079     if (NicHandle == NULL) {
   1080       return EFI_SUCCESS;
   1081     }
   1082 
   1083     //
   1084     // Try to retrieve the private data by the Caller Id Guid.
   1085     //
   1086     Status = gBS->OpenProtocol (
   1087                     NicHandle,
   1088                     &gEfiCallerIdGuid,
   1089                     (VOID **) &Id,
   1090                     This->DriverBindingHandle,
   1091                     ControllerHandle,
   1092                     EFI_OPEN_PROTOCOL_GET_PROTOCOL
   1093                     );
   1094     if (EFI_ERROR (Status)) {
   1095       return Status;
   1096     }
   1097     Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
   1098   } else {
   1099     Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
   1100     NicHandle = Private->Controller;
   1101   }
   1102 
   1103   //
   1104   // Disable the HTTP boot function.
   1105   //
   1106   Status = HttpBootStop (Private);
   1107   if (Status != EFI_SUCCESS && Status != EFI_NOT_STARTED) {
   1108     return Status;
   1109   }
   1110 
   1111   //
   1112   // Destory all child instance and uninstall protocol interface.
   1113   //
   1114   HttpBootDestroyIp6Children (This, Private);
   1115 
   1116   if (Private->Ip4Nic == NULL && Private->Ip6Nic == NULL) {
   1117     //
   1118     // Release the cached data.
   1119     //
   1120     HttpBootFreeCacheList (Private);
   1121 
   1122     //
   1123     // Unload the config form.
   1124     //
   1125     HttpBootConfigFormUnload (Private);
   1126 
   1127     gBS->UninstallProtocolInterface (
   1128            NicHandle,
   1129            &gEfiCallerIdGuid,
   1130            &Private->Id
   1131            );
   1132     FreePool (Private);
   1133 
   1134   }
   1135 
   1136   return EFI_SUCCESS;
   1137 }
   1138 /**
   1139   This is the declaration of an EFI image entry point. This entry point is
   1140   the same for UEFI Applications, UEFI OS Loaders, and UEFI Drivers including
   1141   both device drivers and bus drivers.
   1142 
   1143   @param[in]  ImageHandle       The firmware allocated handle for the UEFI image.
   1144   @param[in]  SystemTable       A pointer to the EFI System Table.
   1145 
   1146   @retval EFI_SUCCESS           The operation completed successfully.
   1147   @retval Others                An unexpected error occurred.
   1148 
   1149 **/
   1150 EFI_STATUS
   1151 EFIAPI
   1152 HttpBootDxeDriverEntryPoint (
   1153   IN EFI_HANDLE        ImageHandle,
   1154   IN EFI_SYSTEM_TABLE  *SystemTable
   1155   )
   1156 {
   1157   EFI_STATUS   Status;
   1158 
   1159   //
   1160   // Install UEFI Driver Model protocol(s).
   1161   //
   1162   Status = EfiLibInstallDriverBindingComponentName2 (
   1163              ImageHandle,
   1164              SystemTable,
   1165              &gHttpBootIp4DxeDriverBinding,
   1166              ImageHandle,
   1167              &gHttpBootDxeComponentName,
   1168              &gHttpBootDxeComponentName2
   1169              );
   1170   if (EFI_ERROR (Status)) {
   1171     return Status;
   1172   }
   1173 
   1174   Status = EfiLibInstallDriverBindingComponentName2 (
   1175              ImageHandle,
   1176              SystemTable,
   1177              &gHttpBootIp6DxeDriverBinding,
   1178              NULL,
   1179              &gHttpBootDxeComponentName,
   1180              &gHttpBootDxeComponentName2
   1181              );
   1182   if (EFI_ERROR (Status)) {
   1183     gBS->UninstallMultipleProtocolInterfaces(
   1184            ImageHandle,
   1185            &gEfiDriverBindingProtocolGuid,
   1186            &gHttpBootIp4DxeDriverBinding,
   1187            &gEfiComponentName2ProtocolGuid,
   1188            &gHttpBootDxeComponentName2,
   1189            &gEfiComponentNameProtocolGuid,
   1190            &gHttpBootDxeComponentName,
   1191            NULL
   1192            );
   1193   }
   1194   return Status;
   1195 }
   1196 
   1197