TianoCore EDK2 master
Loading...
Searching...
No Matches
HttpBootDxe.c
Go to the documentation of this file.
1
9#include "HttpBootDxe.h"
10
18 HTTP_BOOT_DXE_VERSION,
19 NULL,
20 NULL
21};
22
23EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp6DxeDriverBinding = {
27 HTTP_BOOT_DXE_VERSION,
28 NULL,
29 NULL
30};
31
45 OUT BOOLEAN *Ipv6Support
46 )
47{
48 EFI_HANDLE Handle;
50 EFI_STATUS Status;
51 EFI_GUID *InfoTypesBuffer;
52 UINTN InfoTypeBufferCount;
53 UINTN TypeIndex;
54 BOOLEAN Supported;
55 VOID *InfoBlock;
56 UINTN InfoBlockSize;
57
58 ASSERT (Private != NULL && Ipv6Support != NULL);
59
60 //
61 // Check whether the UNDI supports IPv6 by NII protocol.
62 //
63 if (Private->Nii != NULL) {
64 *Ipv6Support = Private->Nii->Ipv6Supported;
65 return EFI_SUCCESS;
66 }
67
68 //
69 // Get the NIC handle by SNP protocol.
70 //
71 Handle = NetLibGetSnpHandle (Private->Controller, NULL);
72 if (Handle == NULL) {
73 return EFI_NOT_FOUND;
74 }
75
76 Aip = NULL;
77 Status = gBS->HandleProtocol (
78 Handle,
79 &gEfiAdapterInformationProtocolGuid,
80 (VOID *)&Aip
81 );
82 if (EFI_ERROR (Status) || (Aip == NULL)) {
83 return EFI_NOT_FOUND;
84 }
85
86 InfoTypesBuffer = NULL;
87 InfoTypeBufferCount = 0;
88 Status = Aip->GetSupportedTypes (Aip, &InfoTypesBuffer, &InfoTypeBufferCount);
89 if (EFI_ERROR (Status) || (InfoTypesBuffer == NULL)) {
90 FreePool (InfoTypesBuffer);
91 return EFI_NOT_FOUND;
92 }
93
94 Supported = FALSE;
95 for (TypeIndex = 0; TypeIndex < InfoTypeBufferCount; TypeIndex++) {
96 if (CompareGuid (&InfoTypesBuffer[TypeIndex], &gEfiAdapterInfoUndiIpv6SupportGuid)) {
97 Supported = TRUE;
98 break;
99 }
100 }
101
102 FreePool (InfoTypesBuffer);
103 if (!Supported) {
104 return EFI_NOT_FOUND;
105 }
106
107 //
108 // We now have adapter information block.
109 //
110 InfoBlock = NULL;
111 InfoBlockSize = 0;
112 Status = Aip->GetInformation (Aip, &gEfiAdapterInfoUndiIpv6SupportGuid, &InfoBlock, &InfoBlockSize);
113 if (EFI_ERROR (Status) || (InfoBlock == NULL)) {
114 FreePool (InfoBlock);
115 return EFI_NOT_FOUND;
116 }
117
118 *Ipv6Support = ((EFI_ADAPTER_INFO_UNDI_IPV6_SUPPORT *)InfoBlock)->Ipv6Support;
119 FreePool (InfoBlock);
120
121 return EFI_SUCCESS;
122}
123
131VOID
135 )
136{
137 ASSERT (This != NULL);
138 ASSERT (Private != NULL);
139
140 if (Private->Dhcp4Child != NULL) {
141 gBS->CloseProtocol (
142 Private->Dhcp4Child,
143 &gEfiDhcp4ProtocolGuid,
144 This->DriverBindingHandle,
145 Private->Controller
146 );
147
149 Private->Controller,
150 This->DriverBindingHandle,
151 &gEfiDhcp4ServiceBindingProtocolGuid,
152 Private->Dhcp4Child
153 );
154 }
155
156 if ((Private->Ip6Nic == NULL) && Private->HttpCreated) {
157 HttpIoDestroyIo (&Private->HttpIo);
158 Private->HttpCreated = FALSE;
159 }
160
161 if (Private->Ip4Nic != NULL) {
162 gBS->CloseProtocol (
163 Private->Controller,
164 &gEfiCallerIdGuid,
165 This->DriverBindingHandle,
166 Private->Ip4Nic->Controller
167 );
168
169 gBS->UninstallMultipleProtocolInterfaces (
170 Private->Ip4Nic->Controller,
171 &gEfiLoadFileProtocolGuid,
172 &Private->Ip4Nic->LoadFile,
173 &gEfiDevicePathProtocolGuid,
174 Private->Ip4Nic->DevicePath,
175 NULL
176 );
177 FreePool (Private->Ip4Nic);
178 Private->Ip4Nic = NULL;
179 }
180}
181
189VOID
193 )
194{
195 ASSERT (This != NULL);
196 ASSERT (Private != NULL);
197
198 if (Private->Ip6Child != NULL) {
199 gBS->CloseProtocol (
200 Private->Ip6Child,
201 &gEfiIp6ProtocolGuid,
202 This->DriverBindingHandle,
203 Private->Controller
204 );
205
207 Private->Controller,
208 This->DriverBindingHandle,
209 &gEfiIp6ServiceBindingProtocolGuid,
210 Private->Ip6Child
211 );
212 }
213
214 if (Private->Dhcp6Child != NULL) {
215 gBS->CloseProtocol (
216 Private->Dhcp6Child,
217 &gEfiDhcp6ProtocolGuid,
218 This->DriverBindingHandle,
219 Private->Controller
220 );
221
223 Private->Controller,
224 This->DriverBindingHandle,
225 &gEfiDhcp6ServiceBindingProtocolGuid,
226 Private->Dhcp6Child
227 );
228 }
229
230 if ((Private->Ip4Nic == NULL) && Private->HttpCreated) {
231 HttpIoDestroyIo (&Private->HttpIo);
232 Private->HttpCreated = FALSE;
233 }
234
235 if (Private->Ip6Nic != NULL) {
236 gBS->CloseProtocol (
237 Private->Controller,
238 &gEfiCallerIdGuid,
239 This->DriverBindingHandle,
240 Private->Ip6Nic->Controller
241 );
242
243 gBS->UninstallMultipleProtocolInterfaces (
244 Private->Ip6Nic->Controller,
245 &gEfiLoadFileProtocolGuid,
246 &Private->Ip6Nic->LoadFile,
247 &gEfiDevicePathProtocolGuid,
248 Private->Ip6Nic->DevicePath,
249 NULL
250 );
251 FreePool (Private->Ip6Nic);
252 Private->Ip6Nic = NULL;
253 }
254}
255
299EFIAPI
302 IN EFI_HANDLE ControllerHandle,
303 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
304 )
305{
306 EFI_STATUS Status;
307
308 //
309 // Try to open the DHCP4, HTTP4 and Device Path protocol.
310 //
311 Status = gBS->OpenProtocol (
312 ControllerHandle,
313 &gEfiDhcp4ServiceBindingProtocolGuid,
314 NULL,
315 This->DriverBindingHandle,
316 ControllerHandle,
317 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
318 );
319 if (EFI_ERROR (Status)) {
320 return Status;
321 }
322
323 Status = gBS->OpenProtocol (
324 ControllerHandle,
325 &gEfiHttpServiceBindingProtocolGuid,
326 NULL,
327 This->DriverBindingHandle,
328 ControllerHandle,
329 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
330 );
331 if (EFI_ERROR (Status)) {
332 return Status;
333 }
334
335 Status = gBS->OpenProtocol (
336 ControllerHandle,
337 &gEfiDevicePathProtocolGuid,
338 NULL,
339 This->DriverBindingHandle,
340 ControllerHandle,
341 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
342 );
343
344 return Status;
345}
346
383EFIAPI
386 IN EFI_HANDLE ControllerHandle,
387 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
388 )
389{
390 EFI_STATUS Status;
391 HTTP_BOOT_PRIVATE_DATA *Private;
392 EFI_DEV_PATH *Node;
393 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
394 UINT32 *Id;
395 BOOLEAN FirstStart;
396
397 FirstStart = FALSE;
398
399 Status = gBS->OpenProtocol (
400 ControllerHandle,
401 &gEfiCallerIdGuid,
402 (VOID **)&Id,
403 This->DriverBindingHandle,
404 ControllerHandle,
405 EFI_OPEN_PROTOCOL_GET_PROTOCOL
406 );
407
408 if (!EFI_ERROR (Status)) {
409 Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
410 } else {
411 FirstStart = TRUE;
412
413 //
414 // Initialize the private data structure.
415 //
416 Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
417 if (Private == NULL) {
418 return EFI_OUT_OF_RESOURCES;
419 }
420
421 Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
422 Private->Controller = ControllerHandle;
423 InitializeListHead (&Private->CacheList);
424 //
425 // Get the NII interface if it exists, it's not required.
426 //
427 Status = gBS->OpenProtocol (
428 ControllerHandle,
429 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
430 (VOID **)&Private->Nii,
431 This->DriverBindingHandle,
432 ControllerHandle,
433 EFI_OPEN_PROTOCOL_GET_PROTOCOL
434 );
435 if (EFI_ERROR (Status)) {
436 Private->Nii = NULL;
437 }
438
439 //
440 // Open Device Path Protocol to prepare for appending IP and URI node.
441 //
442 Status = gBS->OpenProtocol (
443 ControllerHandle,
444 &gEfiDevicePathProtocolGuid,
445 (VOID **)&Private->ParentDevicePath,
446 This->DriverBindingHandle,
447 ControllerHandle,
448 EFI_OPEN_PROTOCOL_GET_PROTOCOL
449 );
450 if (EFI_ERROR (Status)) {
451 goto ON_ERROR;
452 }
453
454 //
455 // Initialize the HII configuration form.
456 //
457 Status = HttpBootConfigFormInit (Private);
458 if (EFI_ERROR (Status)) {
459 goto ON_ERROR;
460 }
461
462 //
463 // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
464 // NIC handle and the private data.
465 //
466 Status = gBS->InstallProtocolInterface (
467 &ControllerHandle,
468 &gEfiCallerIdGuid,
470 &Private->Id
471 );
472 if (EFI_ERROR (Status)) {
473 goto ON_ERROR;
474 }
475 }
476
477 if (Private->Ip4Nic != NULL) {
478 //
479 // Already created before
480 //
481 return EFI_SUCCESS;
482 }
483
484 Private->Ip4Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
485 if (Private->Ip4Nic == NULL) {
486 Status = EFI_OUT_OF_RESOURCES;
487 goto ON_ERROR;
488 }
489
490 Private->Ip4Nic->Private = Private;
491 Private->Ip4Nic->ImageHandle = This->DriverBindingHandle;
492 Private->Ip4Nic->Signature = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
493
494 //
495 // Create DHCP4 child instance.
496 //
497 Status = NetLibCreateServiceChild (
498 ControllerHandle,
499 This->DriverBindingHandle,
500 &gEfiDhcp4ServiceBindingProtocolGuid,
501 &Private->Dhcp4Child
502 );
503 if (EFI_ERROR (Status)) {
504 goto ON_ERROR;
505 }
506
507 Status = gBS->OpenProtocol (
508 Private->Dhcp4Child,
509 &gEfiDhcp4ProtocolGuid,
510 (VOID **)&Private->Dhcp4,
511 This->DriverBindingHandle,
512 ControllerHandle,
513 EFI_OPEN_PROTOCOL_BY_DRIVER
514 );
515 if (EFI_ERROR (Status)) {
516 goto ON_ERROR;
517 }
518
519 //
520 // Get the Ip4Config2 protocol, it's required to configure the default gateway address.
521 //
522 Status = gBS->OpenProtocol (
523 ControllerHandle,
524 &gEfiIp4Config2ProtocolGuid,
525 (VOID **)&Private->Ip4Config2,
526 This->DriverBindingHandle,
527 ControllerHandle,
528 EFI_OPEN_PROTOCOL_GET_PROTOCOL
529 );
530 if (EFI_ERROR (Status)) {
531 goto ON_ERROR;
532 }
533
534 //
535 // Append IPv4 device path node.
536 //
537 Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));
538 if (Node == NULL) {
539 Status = EFI_OUT_OF_RESOURCES;
540 goto ON_ERROR;
541 }
542
543 Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;
544 Node->Ipv4.Header.SubType = MSG_IPv4_DP;
546 Node->Ipv4.StaticIpAddress = FALSE;
547 DevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);
548 FreePool (Node);
549 if (DevicePath == NULL) {
550 Status = EFI_OUT_OF_RESOURCES;
551 goto ON_ERROR;
552 }
553
554 //
555 // Append URI device path node.
556 //
558 if (Node == NULL) {
559 Status = EFI_OUT_OF_RESOURCES;
560 goto ON_ERROR;
561 }
562
563 Node->DevPath.Type = MESSAGING_DEVICE_PATH;
564 Node->DevPath.SubType = MSG_URI_DP;
566 Private->Ip4Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);
567 FreePool (Node);
568 FreePool (DevicePath);
569 if (Private->Ip4Nic->DevicePath == NULL) {
570 Status = EFI_OUT_OF_RESOURCES;
571 goto ON_ERROR;
572 }
573
574 //
575 // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
576 //
577 CopyMem (&Private->Ip4Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (EFI_LOAD_FILE_PROTOCOL));
578 Status = gBS->InstallMultipleProtocolInterfaces (
579 &Private->Ip4Nic->Controller,
580 &gEfiLoadFileProtocolGuid,
581 &Private->Ip4Nic->LoadFile,
582 &gEfiDevicePathProtocolGuid,
583 Private->Ip4Nic->DevicePath,
584 NULL
585 );
586 if (EFI_ERROR (Status)) {
587 goto ON_ERROR;
588 }
589
590 //
591 // Open the Caller Id child to setup a parent-child relationship between
592 // real NIC handle and the HTTP boot Ipv4 NIC handle.
593 //
594 Status = gBS->OpenProtocol (
595 ControllerHandle,
596 &gEfiCallerIdGuid,
597 (VOID **)&Id,
598 This->DriverBindingHandle,
599 Private->Ip4Nic->Controller,
600 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
601 );
602 if (EFI_ERROR (Status)) {
603 goto ON_ERROR;
604 }
605
606 return EFI_SUCCESS;
607
608ON_ERROR:
609 if (Private != NULL) {
610 if (FirstStart) {
611 gBS->UninstallProtocolInterface (
612 ControllerHandle,
613 &gEfiCallerIdGuid,
614 &Private->Id
615 );
616 }
617
618 HttpBootDestroyIp4Children (This, Private);
619 HttpBootConfigFormUnload (Private);
620
621 if (FirstStart) {
622 FreePool (Private);
623 }
624 }
625
626 return Status;
627}
628
656EFIAPI
659 IN EFI_HANDLE ControllerHandle,
660 IN UINTN NumberOfChildren,
661 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
662 )
663{
664 EFI_STATUS Status;
665 EFI_LOAD_FILE_PROTOCOL *LoadFile;
666 HTTP_BOOT_PRIVATE_DATA *Private;
667 EFI_HANDLE NicHandle;
668 UINT32 *Id;
669
670 //
671 // Try to get the Load File Protocol from the controller handle.
672 //
673 Status = gBS->OpenProtocol (
674 ControllerHandle,
675 &gEfiLoadFileProtocolGuid,
676 (VOID **)&LoadFile,
677 This->DriverBindingHandle,
678 ControllerHandle,
679 EFI_OPEN_PROTOCOL_GET_PROTOCOL
680 );
681 if (EFI_ERROR (Status)) {
682 //
683 // If failed, try to find the NIC handle for this controller.
684 //
685 NicHandle = HttpBootGetNicByIp4Children (ControllerHandle);
686 if (NicHandle == NULL) {
687 return EFI_SUCCESS;
688 }
689
690 //
691 // Try to retrieve the private data by the Caller Id Guid.
692 //
693 Status = gBS->OpenProtocol (
694 NicHandle,
695 &gEfiCallerIdGuid,
696 (VOID **)&Id,
697 This->DriverBindingHandle,
698 ControllerHandle,
699 EFI_OPEN_PROTOCOL_GET_PROTOCOL
700 );
701 if (EFI_ERROR (Status)) {
702 return Status;
703 }
704
705 Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
706 } else {
707 Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
708 NicHandle = Private->Controller;
709 }
710
711 //
712 // Disable the HTTP boot function.
713 //
714 Status = HttpBootStop (Private);
715 if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_STARTED)) {
716 return Status;
717 }
718
719 //
720 // Destroy all child instance and uninstall protocol interface.
721 //
722 HttpBootDestroyIp4Children (This, Private);
723
724 if ((Private->Ip4Nic == NULL) && (Private->Ip6Nic == NULL)) {
725 //
726 // Release the cached data.
727 //
728 HttpBootFreeCacheList (Private);
729
730 //
731 // Unload the config form.
732 //
733 HttpBootConfigFormUnload (Private);
734
735 gBS->UninstallProtocolInterface (
736 NicHandle,
737 &gEfiCallerIdGuid,
738 &Private->Id
739 );
740 FreePool (Private);
741 }
742
743 return EFI_SUCCESS;
744}
745
789EFIAPI
792 IN EFI_HANDLE ControllerHandle,
793 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
794 )
795{
796 EFI_STATUS Status;
797
798 //
799 // Try to open the DHCP6, HTTP and Device Path protocol.
800 //
801 Status = gBS->OpenProtocol (
802 ControllerHandle,
803 &gEfiDhcp6ServiceBindingProtocolGuid,
804 NULL,
805 This->DriverBindingHandle,
806 ControllerHandle,
807 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
808 );
809 if (EFI_ERROR (Status)) {
810 return Status;
811 }
812
813 Status = gBS->OpenProtocol (
814 ControllerHandle,
815 &gEfiHttpServiceBindingProtocolGuid,
816 NULL,
817 This->DriverBindingHandle,
818 ControllerHandle,
819 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
820 );
821 if (EFI_ERROR (Status)) {
822 return Status;
823 }
824
825 Status = gBS->OpenProtocol (
826 ControllerHandle,
827 &gEfiDevicePathProtocolGuid,
828 NULL,
829 This->DriverBindingHandle,
830 ControllerHandle,
831 EFI_OPEN_PROTOCOL_TEST_PROTOCOL
832 );
833
834 return Status;
835}
836
873EFIAPI
876 IN EFI_HANDLE ControllerHandle,
877 IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL
878 )
879{
880 EFI_STATUS Status;
881 HTTP_BOOT_PRIVATE_DATA *Private;
882 EFI_DEV_PATH *Node;
883 EFI_DEVICE_PATH_PROTOCOL *DevicePath;
884 UINT32 *Id;
885 BOOLEAN Ipv6Available;
886 BOOLEAN FirstStart;
887
888 FirstStart = FALSE;
889
890 Status = gBS->OpenProtocol (
891 ControllerHandle,
892 &gEfiCallerIdGuid,
893 (VOID **)&Id,
894 This->DriverBindingHandle,
895 ControllerHandle,
896 EFI_OPEN_PROTOCOL_GET_PROTOCOL
897 );
898
899 if (!EFI_ERROR (Status)) {
900 Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
901 } else {
902 FirstStart = TRUE;
903
904 //
905 // Initialize the private data structure.
906 //
907 Private = AllocateZeroPool (sizeof (HTTP_BOOT_PRIVATE_DATA));
908 if (Private == NULL) {
909 return EFI_OUT_OF_RESOURCES;
910 }
911
912 Private->Signature = HTTP_BOOT_PRIVATE_DATA_SIGNATURE;
913 Private->Controller = ControllerHandle;
914 InitializeListHead (&Private->CacheList);
915 //
916 // Get the NII interface if it exists, it's not required.
917 //
918 Status = gBS->OpenProtocol (
919 ControllerHandle,
920 &gEfiNetworkInterfaceIdentifierProtocolGuid_31,
921 (VOID **)&Private->Nii,
922 This->DriverBindingHandle,
923 ControllerHandle,
924 EFI_OPEN_PROTOCOL_GET_PROTOCOL
925 );
926 if (EFI_ERROR (Status)) {
927 Private->Nii = NULL;
928 }
929
930 //
931 // Open Device Path Protocol to prepare for appending IP and URI node.
932 //
933 Status = gBS->OpenProtocol (
934 ControllerHandle,
935 &gEfiDevicePathProtocolGuid,
936 (VOID **)&Private->ParentDevicePath,
937 This->DriverBindingHandle,
938 ControllerHandle,
939 EFI_OPEN_PROTOCOL_GET_PROTOCOL
940 );
941 if (EFI_ERROR (Status)) {
942 goto ON_ERROR;
943 }
944
945 //
946 // Initialize the HII configuration form.
947 //
948 Status = HttpBootConfigFormInit (Private);
949 if (EFI_ERROR (Status)) {
950 goto ON_ERROR;
951 }
952
953 //
954 // Install a protocol with Caller Id Guid to the NIC, this is just to build the relationship between
955 // NIC handle and the private data.
956 //
957 Status = gBS->InstallProtocolInterface (
958 &ControllerHandle,
959 &gEfiCallerIdGuid,
961 &Private->Id
962 );
963 if (EFI_ERROR (Status)) {
964 goto ON_ERROR;
965 }
966 }
967
968 //
969 // Set IPv6 available flag.
970 //
971 Status = HttpBootCheckIpv6Support (Private, &Ipv6Available);
972 if (EFI_ERROR (Status)) {
973 //
974 // Fail to get the data whether UNDI supports IPv6.
975 // Set default value to TRUE.
976 //
977 Ipv6Available = TRUE;
978 }
979
980 if (!Ipv6Available) {
981 Status = EFI_UNSUPPORTED;
982 goto ON_ERROR;
983 }
984
985 if (Private->Ip6Nic != NULL) {
986 //
987 // Already created before
988 //
989 return EFI_SUCCESS;
990 }
991
992 Private->Ip6Nic = AllocateZeroPool (sizeof (HTTP_BOOT_VIRTUAL_NIC));
993 if (Private->Ip6Nic == NULL) {
994 Status = EFI_OUT_OF_RESOURCES;
995 goto ON_ERROR;
996 }
997
998 Private->Ip6Nic->Private = Private;
999 Private->Ip6Nic->ImageHandle = This->DriverBindingHandle;
1000 Private->Ip6Nic->Signature = HTTP_BOOT_VIRTUAL_NIC_SIGNATURE;
1001
1002 //
1003 // Create Dhcp6 child and open Dhcp6 protocol
1004 Status = NetLibCreateServiceChild (
1005 ControllerHandle,
1006 This->DriverBindingHandle,
1007 &gEfiDhcp6ServiceBindingProtocolGuid,
1008 &Private->Dhcp6Child
1009 );
1010 if (EFI_ERROR (Status)) {
1011 goto ON_ERROR;
1012 }
1013
1014 Status = gBS->OpenProtocol (
1015 Private->Dhcp6Child,
1016 &gEfiDhcp6ProtocolGuid,
1017 (VOID **)&Private->Dhcp6,
1018 This->DriverBindingHandle,
1019 ControllerHandle,
1020 EFI_OPEN_PROTOCOL_BY_DRIVER
1021 );
1022 if (EFI_ERROR (Status)) {
1023 goto ON_ERROR;
1024 }
1025
1026 //
1027 // Create Ip6 child and open Ip6 protocol for background ICMP packets.
1028 //
1029 Status = NetLibCreateServiceChild (
1030 ControllerHandle,
1031 This->DriverBindingHandle,
1032 &gEfiIp6ServiceBindingProtocolGuid,
1033 &Private->Ip6Child
1034 );
1035 if (EFI_ERROR (Status)) {
1036 goto ON_ERROR;
1037 }
1038
1039 Status = gBS->OpenProtocol (
1040 Private->Ip6Child,
1041 &gEfiIp6ProtocolGuid,
1042 (VOID **)&Private->Ip6,
1043 This->DriverBindingHandle,
1044 ControllerHandle,
1045 EFI_OPEN_PROTOCOL_BY_DRIVER
1046 );
1047 if (EFI_ERROR (Status)) {
1048 goto ON_ERROR;
1049 }
1050
1051 //
1052 // Locate Ip6Config protocol, it's required to configure the default gateway address.
1053 //
1054 Status = gBS->OpenProtocol (
1055 ControllerHandle,
1056 &gEfiIp6ConfigProtocolGuid,
1057 (VOID **)&Private->Ip6Config,
1058 This->DriverBindingHandle,
1059 ControllerHandle,
1060 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1061 );
1062 if (EFI_ERROR (Status)) {
1063 goto ON_ERROR;
1064 }
1065
1066 //
1067 // Append IPv6 device path node.
1068 //
1069 Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));
1070 if (Node == NULL) {
1071 Status = EFI_OUT_OF_RESOURCES;
1072 goto ON_ERROR;
1073 }
1074
1075 Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;
1076 Node->Ipv6.Header.SubType = MSG_IPv6_DP;
1077 Node->Ipv6.PrefixLength = IP6_PREFIX_LENGTH;
1079 DevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH *)Node);
1080 FreePool (Node);
1081 if (DevicePath == NULL) {
1082 Status = EFI_OUT_OF_RESOURCES;
1083 goto ON_ERROR;
1084 }
1085
1086 //
1087 // Append URI device path node.
1088 //
1090 if (Node == NULL) {
1091 Status = EFI_OUT_OF_RESOURCES;
1092 goto ON_ERROR;
1093 }
1094
1095 Node->DevPath.Type = MESSAGING_DEVICE_PATH;
1096 Node->DevPath.SubType = MSG_URI_DP;
1098 Private->Ip6Nic->DevicePath = AppendDevicePathNode (DevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);
1099 FreePool (Node);
1100 FreePool (DevicePath);
1101 if (Private->Ip6Nic->DevicePath == NULL) {
1102 Status = EFI_OUT_OF_RESOURCES;
1103 goto ON_ERROR;
1104 }
1105
1106 //
1107 // Create a child handle for the HTTP boot and install DevPath and Load file protocol on it.
1108 //
1109 CopyMem (&Private->Ip6Nic->LoadFile, &gHttpBootDxeLoadFile, sizeof (Private->LoadFile));
1110 Status = gBS->InstallMultipleProtocolInterfaces (
1111 &Private->Ip6Nic->Controller,
1112 &gEfiLoadFileProtocolGuid,
1113 &Private->Ip6Nic->LoadFile,
1114 &gEfiDevicePathProtocolGuid,
1115 Private->Ip6Nic->DevicePath,
1116 NULL
1117 );
1118 if (EFI_ERROR (Status)) {
1119 goto ON_ERROR;
1120 }
1121
1122 //
1123 // Open the Caller Id child to setup a parent-child relationship between
1124 // real NIC handle and the HTTP boot child handle.
1125 //
1126 Status = gBS->OpenProtocol (
1127 ControllerHandle,
1128 &gEfiCallerIdGuid,
1129 (VOID **)&Id,
1130 This->DriverBindingHandle,
1131 Private->Ip6Nic->Controller,
1132 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1133 );
1134 if (EFI_ERROR (Status)) {
1135 goto ON_ERROR;
1136 }
1137
1138 return EFI_SUCCESS;
1139
1140ON_ERROR:
1141 if (Private != NULL) {
1142 if (FirstStart) {
1143 gBS->UninstallProtocolInterface (
1144 ControllerHandle,
1145 &gEfiCallerIdGuid,
1146 &Private->Id
1147 );
1148 }
1149
1150 HttpBootDestroyIp6Children (This, Private);
1151 HttpBootConfigFormUnload (Private);
1152
1153 if (FirstStart) {
1154 FreePool (Private);
1155 }
1156 }
1157
1158 return Status;
1159}
1160
1188EFIAPI
1191 IN EFI_HANDLE ControllerHandle,
1192 IN UINTN NumberOfChildren,
1193 IN EFI_HANDLE *ChildHandleBuffer OPTIONAL
1194 )
1195{
1196 EFI_STATUS Status;
1197 EFI_LOAD_FILE_PROTOCOL *LoadFile;
1198 HTTP_BOOT_PRIVATE_DATA *Private;
1199 EFI_HANDLE NicHandle;
1200 UINT32 *Id;
1201
1202 //
1203 // Try to get the Load File Protocol from the controller handle.
1204 //
1205 Status = gBS->OpenProtocol (
1206 ControllerHandle,
1207 &gEfiLoadFileProtocolGuid,
1208 (VOID **)&LoadFile,
1209 This->DriverBindingHandle,
1210 ControllerHandle,
1211 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1212 );
1213 if (EFI_ERROR (Status)) {
1214 //
1215 // If failed, try to find the NIC handle for this controller.
1216 //
1217 NicHandle = HttpBootGetNicByIp6Children (ControllerHandle);
1218 if (NicHandle == NULL) {
1219 return EFI_SUCCESS;
1220 }
1221
1222 //
1223 // Try to retrieve the private data by the Caller Id Guid.
1224 //
1225 Status = gBS->OpenProtocol (
1226 NicHandle,
1227 &gEfiCallerIdGuid,
1228 (VOID **)&Id,
1229 This->DriverBindingHandle,
1230 ControllerHandle,
1231 EFI_OPEN_PROTOCOL_GET_PROTOCOL
1232 );
1233 if (EFI_ERROR (Status)) {
1234 return Status;
1235 }
1236
1237 Private = HTTP_BOOT_PRIVATE_DATA_FROM_ID (Id);
1238 } else {
1239 Private = HTTP_BOOT_PRIVATE_DATA_FROM_LOADFILE (LoadFile);
1240 NicHandle = Private->Controller;
1241 }
1242
1243 //
1244 // Disable the HTTP boot function.
1245 //
1246 Status = HttpBootStop (Private);
1247 if ((Status != EFI_SUCCESS) && (Status != EFI_NOT_STARTED)) {
1248 return Status;
1249 }
1250
1251 //
1252 // Destroy all child instance and uninstall protocol interface.
1253 //
1254 HttpBootDestroyIp6Children (This, Private);
1255
1256 if ((Private->Ip4Nic == NULL) && (Private->Ip6Nic == NULL)) {
1257 //
1258 // Release the cached data.
1259 //
1260 HttpBootFreeCacheList (Private);
1261
1262 //
1263 // Unload the config form.
1264 //
1265 HttpBootConfigFormUnload (Private);
1266
1267 gBS->UninstallProtocolInterface (
1268 NicHandle,
1269 &gEfiCallerIdGuid,
1270 &Private->Id
1271 );
1272 FreePool (Private);
1273 }
1274
1275 return EFI_SUCCESS;
1276}
1277
1291EFIAPI
1293 IN EFI_HANDLE ImageHandle,
1294 IN EFI_SYSTEM_TABLE *SystemTable
1295 )
1296{
1297 EFI_STATUS Status;
1298
1299 //
1300 // Install UEFI Driver Model protocol(s).
1301 //
1303 ImageHandle,
1304 SystemTable,
1306 ImageHandle,
1309 );
1310 if (EFI_ERROR (Status)) {
1311 return Status;
1312 }
1313
1315 ImageHandle,
1316 SystemTable,
1317 &gHttpBootIp6DxeDriverBinding,
1318 NULL,
1321 );
1322 if (EFI_ERROR (Status)) {
1327 );
1328 }
1329
1330 return Status;
1331}
UINT64 UINTN
LIST_ENTRY *EFIAPI InitializeListHead(IN OUT LIST_ENTRY *ListHead)
Definition: LinkedList.c:182
VOID *EFIAPI CopyMem(OUT VOID *DestinationBuffer, IN CONST VOID *SourceBuffer, IN UINTN Length)
BOOLEAN EFIAPI CompareGuid(IN CONST GUID *Guid1, IN CONST GUID *Guid2)
Definition: MemLibGuid.c:73
#define MSG_IPv6_DP
Definition: DevicePath.h:607
#define MSG_IPv4_DP
Definition: DevicePath.h:566
#define MSG_URI_DP
Definition: DevicePath.h:879
#define MESSAGING_DEVICE_PATH
Definition: DevicePath.h:321
UINT16 EFIAPI SetDevicePathNodeLength(IN OUT VOID *Node, IN UINTN Length)
EFI_DEVICE_PATH_PROTOCOL *EFIAPI AppendDevicePathNode(IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePath OPTIONAL, IN CONST EFI_DEVICE_PATH_PROTOCOL *DevicePathNode OPTIONAL)
VOID *EFIAPI AllocateZeroPool(IN UINTN AllocationSize)
VOID EFIAPI FreePool(IN VOID *Buffer)
VOID HttpBootFreeCacheList(IN HTTP_BOOT_PRIVATE_DATA *Private)
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME_PROTOCOL gHttpBootDxeComponentName
GLOBAL_REMOVE_IF_UNREFERENCED EFI_COMPONENT_NAME2_PROTOCOL gHttpBootDxeComponentName2
EFI_STATUS HttpBootConfigFormInit(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootConfigFormUnload(IN HTTP_BOOT_PRIVATE_DATA *Private)
EFI_STATUS HttpBootCheckIpv6Support(IN HTTP_BOOT_PRIVATE_DATA *Private, OUT BOOLEAN *Ipv6Support)
Definition: HttpBootDxe.c:43
EFI_STATUS EFIAPI HttpBootIp6DxeDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: HttpBootDxe.c:1189
VOID HttpBootDestroyIp4Children(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN HTTP_BOOT_PRIVATE_DATA *Private)
Definition: HttpBootDxe.c:132
EFI_STATUS EFIAPI HttpBootIp4DxeDriverBindingStop(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN UINTN NumberOfChildren, IN EFI_HANDLE *ChildHandleBuffer OPTIONAL)
Definition: HttpBootDxe.c:657
VOID HttpBootDestroyIp6Children(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN HTTP_BOOT_PRIVATE_DATA *Private)
Definition: HttpBootDxe.c:190
EFI_STATUS EFIAPI HttpBootIp4DxeDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: HttpBootDxe.c:300
EFI_STATUS EFIAPI HttpBootIp6DxeDriverBindingSupported(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: HttpBootDxe.c:790
EFI_STATUS EFIAPI HttpBootIp4DxeDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: HttpBootDxe.c:384
EFI_STATUS EFIAPI HttpBootDxeDriverEntryPoint(IN EFI_HANDLE ImageHandle, IN EFI_SYSTEM_TABLE *SystemTable)
Definition: HttpBootDxe.c:1292
EFI_DRIVER_BINDING_PROTOCOL gHttpBootIp4DxeDriverBinding
Definition: HttpBootDxe.c:14
EFI_STATUS EFIAPI HttpBootIp6DxeDriverBindingStart(IN EFI_DRIVER_BINDING_PROTOCOL *This, IN EFI_HANDLE ControllerHandle, IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath OPTIONAL)
Definition: HttpBootDxe.c:874
EFI_LOAD_FILE_PROTOCOL gHttpBootDxeLoadFile
Definition: HttpBootImpl.c:759
EFI_STATUS HttpBootStop(IN HTTP_BOOT_PRIVATE_DATA *Private)
Definition: HttpBootImpl.c:539
EFI_HANDLE HttpBootGetNicByIp4Children(IN EFI_HANDLE ControllerHandle)
EFI_HANDLE HttpBootGetNicByIp6Children(IN EFI_HANDLE ControllerHandle)
VOID HttpIoDestroyIo(IN HTTP_IO *HttpIo)
Definition: DxeHttpIoLib.c:62
#define NULL
Definition: Base.h:319
#define TRUE
Definition: Base.h:301
#define FALSE
Definition: Base.h:307
#define IN
Definition: Base.h:279
#define OUT
Definition: Base.h:284
EFI_STATUS EFIAPI NetLibCreateServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN OUT EFI_HANDLE *ChildHandle)
Definition: DxeNetLib.c:1967
EFI_STATUS EFIAPI NetLibDestroyServiceChild(IN EFI_HANDLE Controller, IN EFI_HANDLE Image, IN EFI_GUID *ServiceBindingGuid, IN EFI_HANDLE ChildHandle)
Definition: DxeNetLib.c:2020
EFI_HANDLE EFIAPI NetLibGetSnpHandle(IN EFI_HANDLE ServiceHandle, OUT EFI_SIMPLE_NETWORK_PROTOCOL **Snp OPTIONAL)
Definition: DxeNetLib.c:2073
RETURN_STATUS EFI_STATUS
Definition: UefiBaseType.h:29
VOID * EFI_HANDLE
Definition: UefiBaseType.h:33
#define EFI_SUCCESS
Definition: UefiBaseType.h:112
EFI_BOOT_SERVICES * gBS
EFI_STATUS EFIAPI EfiLibUninstallDriverBindingComponentName2(IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
EFI_STATUS EFIAPI EfiLibInstallDriverBindingComponentName2(IN CONST EFI_HANDLE ImageHandle, IN CONST EFI_SYSTEM_TABLE *SystemTable, IN EFI_DRIVER_BINDING_PROTOCOL *DriverBinding, IN EFI_HANDLE DriverBindingHandle, IN CONST EFI_COMPONENT_NAME_PROTOCOL *ComponentName OPTIONAL, IN CONST EFI_COMPONENT_NAME2_PROTOCOL *ComponentName2 OPTIONAL)
@ EFI_NATIVE_INTERFACE
Definition: UefiSpec.h:1193
Definition: Base.h:213
BOOLEAN StaticIpAddress
Definition: DevicePath.h:593