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