]> git.proxmox.com Git - mirror_edk2.git/blob - NetworkPkg/Ip6Dxe/Ip6ConfigNv.c
Remove HiiUpdateForm from ExtractConfig fucntion.
[mirror_edk2.git] / NetworkPkg / Ip6Dxe / Ip6ConfigNv.c
1 /** @file
2 Helper functions for configuring or obtaining the parameters relating to IP6.
3
4 Copyright (c) 2010 - 2013, Intel Corporation. All rights reserved.<BR>
5
6 This program and the accompanying materials
7 are licensed and made available under the terms and conditions of the BSD License
8 which accompanies this distribution. The full text of the license may be found at
9 http://opensource.org/licenses/bsd-license.php.
10
11 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
12 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
13
14 **/
15
16 #include "Ip6Impl.h"
17
18 CHAR16 mIp6ConfigStorageName[] = L"IP6_CONFIG_IFR_NVDATA";
19
20 /**
21 The notify function of create event when performing a manual configuration.
22
23 @param[in] Event The pointer of Event.
24 @param[in] Context The pointer of Context.
25
26 **/
27 VOID
28 EFIAPI
29 Ip6ConfigManualAddressNotify (
30 IN EFI_EVENT Event,
31 IN VOID *Context
32 )
33 {
34 *((BOOLEAN *) Context) = TRUE;
35 }
36
37 /**
38 Get the configuration data for the EFI IPv6 network stack running on the
39 communication. It is a help function to the call EfiIp6ConfigGetData().
40
41 @param[in] Ip6Config The pointer to the EFI_IP6_CONFIG_PROTOCOL instance.
42 @param[in] DataType The type of data to get.
43 @param[out] DataSize The size of buffer required in bytes.
44 @param[out] Data The data buffer in which the configuration data is returned. The
45 type of the data buffer associated with the DataType.
46 It is the caller's responsibility to free the resource.
47
48 @retval EFI_SUCCESS The specified configuration data was obtained successfully.
49 @retval EFI_INVALID_PARAMETER One or more of the followings are TRUE:
50 - Ip6Config is NULL or invalid.
51 - DataSize is NULL.
52 - Data is NULL.
53 @retval EFI_OUT_OF_RESOURCES Fail to perform the operation due to lack of resources.
54 @retval EFI_NOT_READY The specified configuration data is not ready due to an
55 asynchronous configuration process already in progress.
56 @retval EFI_NOT_FOUND The specified configuration data was not found.
57
58 **/
59 EFI_STATUS
60 Ip6ConfigNvGetData (
61 IN EFI_IP6_CONFIG_PROTOCOL *Ip6Config,
62 IN EFI_IP6_CONFIG_DATA_TYPE DataType,
63 OUT UINTN *DataSize,
64 OUT VOID **Data
65 )
66 {
67 UINTN BufferSize;
68 VOID *Buffer;
69 EFI_STATUS Status;
70
71 if ((Ip6Config == NULL) || (Data == NULL) || (DataSize == NULL)) {
72 return EFI_INVALID_PARAMETER;
73 }
74
75 BufferSize = 0;
76 Status = Ip6Config->GetData (
77 Ip6Config,
78 DataType,
79 &BufferSize,
80 NULL
81 );
82 if (Status != EFI_BUFFER_TOO_SMALL) {
83 return Status;
84 }
85
86 Buffer = AllocateZeroPool (BufferSize);
87 if (Buffer == NULL) {
88 return EFI_OUT_OF_RESOURCES;
89 }
90
91 Status = Ip6Config->GetData (
92 Ip6Config,
93 DataType,
94 &BufferSize,
95 Buffer
96 );
97 if (EFI_ERROR (Status)) {
98 FreePool (Buffer);
99 return Status;
100 }
101
102 *DataSize = BufferSize;
103 *Data = Buffer;
104
105 return EFI_SUCCESS;
106 }
107
108 /**
109 Free all nodes in IP6_ADDRESS_INFO_ENTRY in the list array specified
110 with ListHead.
111
112 @param[in] ListHead The head of the list array in IP6_ADDRESS_INFO_ENTRY.
113
114 **/
115 VOID
116 Ip6FreeAddressInfoList (
117 IN LIST_ENTRY *ListHead
118 )
119 {
120 IP6_ADDRESS_INFO_ENTRY *Node;
121 LIST_ENTRY *Entry;
122 LIST_ENTRY *NextEntry;
123
124 NET_LIST_FOR_EACH_SAFE (Entry, NextEntry, ListHead) {
125 Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);
126 RemoveEntryList (&Node->Link);
127 FreePool (Node);
128 }
129 }
130
131 /**
132 Convert the IPv6 address into a formatted string.
133
134 @param[in] Ip6 The IPv6 address.
135 @param[out] Str The formatted IP string.
136
137 **/
138 VOID
139 Ip6ToStr (
140 IN EFI_IPv6_ADDRESS *Ip6,
141 OUT CHAR16 *Str
142 )
143 {
144 UINTN Index;
145 BOOLEAN Short;
146 UINTN Number;
147 CHAR16 FormatString[8];
148
149 Short = FALSE;
150
151 for (Index = 0; Index < 15; Index = Index + 2) {
152 if (!Short &&
153 Index % 2 == 0 &&
154 Ip6->Addr[Index] == 0 &&
155 Ip6->Addr[Index + 1] == 0
156 ) {
157 //
158 // Deal with the case of ::.
159 //
160 if (Index == 0) {
161 *Str = L':';
162 *(Str + 1) = L':';
163 Str = Str + 2;
164 } else {
165 *Str = L':';
166 Str = Str + 1;
167 }
168
169 while ((Index < 15) && (Ip6->Addr[Index] == 0) && (Ip6->Addr[Index + 1] == 0)) {
170 Index = Index + 2;
171 }
172
173 Short = TRUE;
174
175 if (Index == 16) {
176 //
177 // :: is at the end of the address.
178 //
179 *Str = L'\0';
180 break;
181 }
182 }
183
184 ASSERT (Index < 15);
185
186 if (Ip6->Addr[Index] == 0) {
187 Number = UnicodeSPrint (Str, 2 * IP6_STR_MAX_SIZE, L"%x:", (UINTN) Ip6->Addr[Index + 1]);
188 } else {
189 if (Ip6->Addr[Index + 1] < 0x10) {
190 CopyMem (FormatString, L"%x0%x:", StrSize (L"%x0%x:"));
191 } else {
192 CopyMem (FormatString, L"%x%x:", StrSize (L"%x%x:"));
193 }
194
195 Number = UnicodeSPrint (
196 Str,
197 2 * IP6_STR_MAX_SIZE,
198 (CONST CHAR16 *) FormatString,
199 (UINTN) Ip6->Addr[Index],
200 (UINTN) Ip6->Addr[Index + 1]
201 );
202 }
203
204 Str = Str + Number;
205
206 if (Index + 2 == 16) {
207 *Str = L'\0';
208 if (*(Str - 1) == L':') {
209 *(Str - 1) = L'\0';
210 }
211 }
212 }
213 }
214
215 /**
216 Convert EFI_IP6_CONFIG_INTERFACE_ID to string format.
217
218 @param[out] String The buffer to store the converted string.
219 @param[in] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
220
221 @retval EFI_SUCCESS The string converted successfully.
222 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
223
224 **/
225 EFI_STATUS
226 Ip6ConvertInterfaceIdToString (
227 OUT CHAR16 *String,
228 IN EFI_IP6_CONFIG_INTERFACE_ID *IfId
229 )
230 {
231 UINT8 Index;
232 UINTN Number;
233
234 if ((String == NULL) || (IfId == NULL)) {
235 return EFI_INVALID_PARAMETER;
236 }
237
238 for (Index = 0; Index < 8; Index++) {
239 Number = UnicodeSPrint (
240 String,
241 2 * INTERFACE_ID_STR_STORAGE,
242 L"%x:",
243 (UINTN) IfId->Id[Index]
244 );
245 String = String + Number;
246 }
247
248 *(String - 1) = '\0';
249
250 return EFI_SUCCESS;
251 }
252
253 /**
254 Parse InterfaceId in string format and convert it to EFI_IP6_CONFIG_INTERFACE_ID.
255
256 @param[in] String The buffer of the string to be parsed.
257 @param[out] IfId The pointer of EFI_IP6_CONFIG_INTERFACE_ID.
258
259 @retval EFI_SUCCESS The operation finished successfully.
260 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
261
262 **/
263 EFI_STATUS
264 Ip6ParseInterfaceIdFromString (
265 IN CONST CHAR16 *String,
266 OUT EFI_IP6_CONFIG_INTERFACE_ID *IfId
267 )
268 {
269 UINT8 Index;
270 CHAR16 *IfIdStr;
271 CHAR16 *TempStr;
272 UINTN NodeVal;
273
274 if ((String == NULL) || (IfId == NULL)) {
275 return EFI_INVALID_PARAMETER;
276 }
277
278 IfIdStr = (CHAR16 *) String;
279
280 ZeroMem (IfId, sizeof (EFI_IP6_CONFIG_INTERFACE_ID));
281
282 for (Index = 0; Index < 8; Index++) {
283 TempStr = IfIdStr;
284
285 while ((*IfIdStr != L'\0') && (*IfIdStr != L':')) {
286 IfIdStr++;
287 }
288
289 //
290 // The InterfaceId format is X:X:X:X, the number of X should not exceed 8.
291 // If the number of X is less than 8, zero is appended to the InterfaceId.
292 //
293 if ((*IfIdStr == ':') && (Index == 7)) {
294 return EFI_INVALID_PARAMETER;
295 }
296
297 //
298 // Convert the string to interface id. AsciiStrHexToUintn stops at the
299 // first character that is not a valid hex character, ':' or '\0' here.
300 //
301 NodeVal = StrHexToUintn (TempStr);
302 if (NodeVal > 0xFF) {
303 return EFI_INVALID_PARAMETER;
304 }
305
306 IfId->Id[Index] = (UINT8) NodeVal;
307
308 IfIdStr++;
309 }
310
311 return EFI_SUCCESS;
312 }
313
314 /**
315 Create Hii Extend Label OpCode as the start opcode and end opcode. It is
316 a help function.
317
318 @param[in] StartLabelNumber The number of start label.
319 @param[out] StartOpCodeHandle Points to the start opcode handle.
320 @param[out] StartLabel Points to the created start opcode.
321 @param[out] EndOpCodeHandle Points to the end opcode handle.
322 @param[out] EndLabel Points to the created end opcode.
323
324 @retval EFI_OUT_OF_RESOURCES Does not have sufficient resources to finish this
325 operation.
326 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
327 @retval EFI_SUCCESS The operation completed successfully.
328
329 **/
330 EFI_STATUS
331 Ip6CreateOpCode (
332 IN UINT16 StartLabelNumber,
333 OUT VOID **StartOpCodeHandle,
334 OUT EFI_IFR_GUID_LABEL **StartLabel,
335 OUT VOID **EndOpCodeHandle,
336 OUT EFI_IFR_GUID_LABEL **EndLabel
337 )
338 {
339 EFI_STATUS Status;
340 EFI_IFR_GUID_LABEL *InternalStartLabel;
341 EFI_IFR_GUID_LABEL *InternalEndLabel;
342
343 if (StartOpCodeHandle == NULL || StartLabel == NULL || EndOpCodeHandle == NULL || EndLabel == NULL) {
344 return EFI_INVALID_PARAMETER;
345 }
346
347 *StartOpCodeHandle = NULL;
348 *EndOpCodeHandle = NULL;
349 Status = EFI_OUT_OF_RESOURCES;
350
351 //
352 // Initialize the container for dynamic opcodes.
353 //
354 *StartOpCodeHandle = HiiAllocateOpCodeHandle ();
355 if (*StartOpCodeHandle == NULL) {
356 return Status;
357 }
358
359 *EndOpCodeHandle = HiiAllocateOpCodeHandle ();
360 if (*EndOpCodeHandle == NULL) {
361 goto Exit;
362 }
363
364 //
365 // Create Hii Extend Label OpCode as the start opcode.
366 //
367 InternalStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
368 *StartOpCodeHandle,
369 &gEfiIfrTianoGuid,
370 NULL,
371 sizeof (EFI_IFR_GUID_LABEL)
372 );
373 if (InternalStartLabel == NULL) {
374 goto Exit;
375 }
376
377 InternalStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
378 InternalStartLabel->Number = StartLabelNumber;
379
380 //
381 // Create Hii Extend Label OpCode as the end opcode.
382 //
383 InternalEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (
384 *EndOpCodeHandle,
385 &gEfiIfrTianoGuid,
386 NULL,
387 sizeof (EFI_IFR_GUID_LABEL)
388 );
389 if (InternalEndLabel == NULL) {
390 goto Exit;
391 }
392
393 InternalEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
394 InternalEndLabel->Number = LABEL_END;
395
396 *StartLabel = InternalStartLabel;
397 *EndLabel = InternalEndLabel;
398
399 return EFI_SUCCESS;
400
401 Exit:
402
403 if (*StartOpCodeHandle != NULL) {
404 HiiFreeOpCodeHandle (*StartOpCodeHandle);
405 }
406
407 if (*EndOpCodeHandle != NULL) {
408 HiiFreeOpCodeHandle (*EndOpCodeHandle);
409 }
410
411 return Status;
412 }
413
414 /**
415 This function converts the different format of address list to string format and
416 then generates the corresponding text opcode to illustarate the address info in
417 IP6 configuration page. Currently, the following formats are supported:
418 EFI_IP6_ADDRESS_INFO AddressType: Ip6ConfigNvHostAddress;
419 EFI_IPv6_ADDRESS AddressType: Ip6ConfigNvGatewayAddress and Ip6ConfigNvDnsAddress;
420 EFI_IP6_ROUTE_TABLE AddressType: Ip6ConfigNvRouteTable.
421
422 @param[in, out] String The pointer to the buffer to store the converted
423 string.
424 @param[in] HiiHandle A handle that was previously registered in the
425 HII Database.
426 @param[in] AddressType The address type.
427 @param[in] AddressInfo Pointer to the address list.
428 @param[in] AddressCount The address count of the address list.
429
430 @retval EFI_SUCCESS The operation finished successfully.
431 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
432 @retval EFI_UNSUPPORTED The AddressType is not supported.
433
434
435 **/
436 EFI_STATUS
437 Ip6ConvertAddressListToString (
438 IN OUT CHAR16 *String,
439 IN EFI_HII_HANDLE HiiHandle,
440 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType,
441 IN VOID *AddressInfo,
442 IN UINTN AddressCount
443 )
444 {
445 UINTN Index;
446 UINTN Number;
447 CHAR16 *TempStr;
448 EFI_STATUS Status;
449 VOID *StartOpCodeHandle;
450 EFI_IFR_GUID_LABEL *StartLabel;
451 VOID *EndOpCodeHandle;
452 EFI_IFR_GUID_LABEL *EndLabel;
453 UINT16 StartLabelNumber;
454 EFI_STRING_ID TextTwo;
455 UINT8 *AddressHead;
456 UINT8 PrefixLength;
457 EFI_IPv6_ADDRESS *Address;
458
459 if ((String == NULL) || (HiiHandle == NULL) || (AddressInfo == NULL)) {
460 return EFI_INVALID_PARAMETER;
461 }
462
463 if (AddressType == Ip6ConfigNvHostAddress) {
464 StartLabelNumber = HOST_ADDRESS_LABEL;
465 } else if (AddressType == Ip6ConfigNvGatewayAddress) {
466 StartLabelNumber = GATEWAY_ADDRESS_LABEL;
467 } else if (AddressType == Ip6ConfigNvDnsAddress) {
468 StartLabelNumber = DNS_ADDRESS_LABEL;
469 } else if (AddressType == Ip6ConfigNvRouteTable) {
470 StartLabelNumber = ROUTE_TABLE_LABEL;
471 } else {
472 ASSERT (FALSE);
473 return EFI_UNSUPPORTED;
474 }
475
476 Status = Ip6CreateOpCode (
477 StartLabelNumber,
478 &StartOpCodeHandle,
479 &StartLabel,
480 &EndOpCodeHandle,
481 &EndLabel
482 );
483 if (EFI_ERROR (Status)) {
484 return Status;
485 }
486
487 AddressHead = (UINT8 *) AddressInfo;
488
489 for (Index = 0; Index < AddressCount; Index++) {
490 if (AddressType == Ip6ConfigNvHostAddress) {
491 AddressInfo = AddressHead + sizeof (EFI_IP6_ADDRESS_INFO) * Index;
492 Address = &((EFI_IP6_ADDRESS_INFO *) AddressInfo)->Address;
493 } else if (AddressType == Ip6ConfigNvRouteTable) {
494 AddressInfo = AddressHead + sizeof (EFI_IP6_ROUTE_TABLE) * Index;
495 Address = &((EFI_IP6_ROUTE_TABLE *) AddressInfo)->Destination;
496 } else {
497 AddressInfo = AddressHead + sizeof (EFI_IPv6_ADDRESS) * Index;
498 Address = AddressInfo;
499 }
500
501 //
502 // Convert the IP address info to string.
503 //
504 Ip6ToStr (Address, String);
505 TempStr = String + StrLen (String);
506
507 if ((AddressType == Ip6ConfigNvHostAddress) || (AddressType == Ip6ConfigNvRouteTable)) {
508 if (AddressType == Ip6ConfigNvHostAddress) {
509 PrefixLength = ((EFI_IP6_ADDRESS_INFO *) AddressInfo)->PrefixLength;
510 } else {
511 PrefixLength = ((EFI_IP6_ROUTE_TABLE *) AddressInfo)->PrefixLength;
512 }
513
514 //
515 // Append the prefix length to the string.
516 //
517 *TempStr = L'/';
518 TempStr++;
519 Number = UnicodeSPrint (TempStr, 6, L"%d", PrefixLength);
520 TempStr = TempStr + Number;
521 }
522
523 if (AddressType == Ip6ConfigNvRouteTable) {
524 //
525 // Append " >> " to the string.
526 //
527 Number = UnicodeSPrint (TempStr, 8, L" >> ");
528 TempStr = TempStr + Number;
529
530 //
531 // Append the gateway address to the string.
532 //
533 Ip6ToStr (&((EFI_IP6_ROUTE_TABLE *) AddressInfo)->Gateway, TempStr);
534 TempStr = TempStr + StrLen (TempStr);
535 }
536
537 //
538 // Generate a text opcode and update the UI.
539 //
540 TextTwo = HiiSetString (HiiHandle, 0, String, NULL);
541 if (TextTwo == 0) {
542 Status = EFI_INVALID_PARAMETER;
543 goto Exit;
544 }
545
546 HiiCreateTextOpCode (StartOpCodeHandle, STR_NULL, STR_NULL, TextTwo);
547
548 String = TempStr;
549 *String = IP6_ADDRESS_DELIMITER;
550 String++;
551 }
552
553 *(String - 1) = '\0';
554
555 Status = HiiUpdateForm (
556 HiiHandle, // HII handle
557 &gIp6ConfigNvDataGuid, // Formset GUID
558 FORMID_MAIN_FORM, // Form ID
559 StartOpCodeHandle, // Label for where to insert opcodes
560 EndOpCodeHandle // Replace data
561 );
562
563 Exit:
564 HiiFreeOpCodeHandle (StartOpCodeHandle);
565 HiiFreeOpCodeHandle (EndOpCodeHandle);
566
567 return Status;
568 }
569
570 /**
571 Parse address list in string format and convert it to a list array of node in
572 IP6_ADDRESS_INFO_ENTRY.
573
574 @param[in] String The buffer to string to be parsed.
575 @param[out] ListHead The list head of array.
576 @param[out] AddressCount The number of list nodes in the array.
577
578 @retval EFI_SUCCESS The operation finished successfully.
579 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
580 @retval EFI_OUT_OF_RESOURCES Failed to perform the operation due to lack of resource.
581
582 **/
583 EFI_STATUS
584 Ip6ParseAddressListFromString (
585 IN CONST CHAR16 *String,
586 OUT LIST_ENTRY *ListHead,
587 OUT UINT32 *AddressCount
588 )
589 {
590 EFI_STATUS Status;
591 CHAR16 *LocalString;
592 CHAR16 *Temp;
593 CHAR16 *TempStr;
594 EFI_IP6_ADDRESS_INFO AddressInfo;
595 IP6_ADDRESS_INFO_ENTRY *Node;
596 BOOLEAN Last;
597 UINT32 Count;
598
599 if ((String == NULL) || (ListHead == NULL) || (AddressCount == NULL)) {
600 return EFI_INVALID_PARAMETER;
601 }
602
603 LocalString = (CHAR16 *) AllocateCopyPool (StrSize (String), String);
604 if (LocalString == NULL) {
605 return EFI_OUT_OF_RESOURCES;
606 }
607
608 //
609 // Clean the original address list.
610 //
611 Ip6FreeAddressInfoList (ListHead);
612
613 Temp = LocalString;
614 Last = FALSE;
615 Count = 0;
616
617 while (*LocalString != L'\0') {
618 TempStr = LocalString;
619 while ((*LocalString != L'\0') && (*LocalString != IP6_ADDRESS_DELIMITER)) {
620 LocalString++;
621 }
622
623 if (*LocalString == L'\0') {
624 Last = TRUE;
625 }
626
627 *LocalString = L'\0';
628
629 Status = NetLibStrToIp6andPrefix (TempStr, &AddressInfo.Address, &AddressInfo.PrefixLength);
630 if (EFI_ERROR (Status)) {
631 goto Error;
632 }
633
634 if (AddressInfo.PrefixLength == 0xFF) {
635 AddressInfo.PrefixLength = 0;
636 }
637
638 if (!NetIp6IsValidUnicast (&AddressInfo.Address)) {
639 Status = EFI_INVALID_PARAMETER;
640 goto Error;
641 }
642
643 Node = AllocatePool (sizeof (IP6_ADDRESS_INFO_ENTRY));
644 if (Node == NULL) {
645 Status = EFI_OUT_OF_RESOURCES;
646 goto Error;
647 }
648
649 CopyMem (&Node->AddrInfo, &AddressInfo, sizeof (EFI_IP6_ADDRESS_INFO));
650 InsertTailList (ListHead, &Node->Link);
651 Count++;
652
653 if (Last) {
654 break;
655 }
656
657 LocalString++;
658 }
659
660 FreePool (Temp);
661 *AddressCount = Count;
662 return EFI_SUCCESS;
663
664 Error:
665 Ip6FreeAddressInfoList (ListHead);
666 FreePool (Temp);
667 return Status;
668 }
669
670 /**
671 This function converts the interface info to string and draws it to the IP6 UI.
672 The interface information includes interface name, interface type, hardware
673 address and route table information.
674
675 @param[in] IfInfo The pointer of EFI_IP6_CONFIG_INTERFACE_INFO.
676 @param[in] HiiHandle The handle that was previously registered in the
677 HII Database.
678 @param[in, out] IfrNvData Points to IP6_CONFIG_IFR_NVDATA.
679
680 @retval EFI_SUCCESS The operation finished successfully.
681 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
682 @retval EFI_OUT_OF_RESOURCES The operation failed due to lack of resources.
683
684 **/
685 EFI_STATUS
686 Ip6ConvertInterfaceInfoToString (
687 IN EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo,
688 IN EFI_HII_HANDLE HiiHandle,
689 IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData
690 )
691 {
692 UINT32 Index;
693 UINTN Number;
694 CHAR16 *String;
695 CHAR16 PortString[ADDRESS_STR_MAX_SIZE];
696 CHAR16 FormatString[8];
697 EFI_STRING_ID StringId;
698
699 if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) {
700 return EFI_INVALID_PARAMETER;
701 }
702
703 //
704 // Print the interface name.
705 //
706 StringId = HiiSetString (
707 HiiHandle,
708 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT),
709 IfInfo->Name,
710 NULL
711 );
712 if (StringId == 0) {
713 return EFI_OUT_OF_RESOURCES;
714 }
715
716 //
717 // Print the interface type.
718 //
719 if (IfInfo->IfType == Ip6InterfaceTypeEthernet) {
720 StrCpy (PortString, IP6_ETHERNET);
721 } else if (IfInfo->IfType == Ip6InterfaceTypeExperimentalEthernet) {
722 StrCpy (PortString, IP6_EXPERIMENTAL_ETHERNET);
723 } else {
724 //
725 // Refer to RFC1700, chapter Number Hardware Type.
726 //
727 UnicodeSPrint (PortString, 6, L"%d", IfInfo->IfType);
728 }
729
730 StringId = HiiSetString (
731 HiiHandle,
732 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT),
733 PortString,
734 NULL
735 );
736 if (StringId == 0) {
737 return EFI_OUT_OF_RESOURCES;
738 }
739
740 //
741 // Convert the hardware address.
742 //
743 String = PortString;
744 ASSERT (IfInfo->HwAddressSize <= 32);
745
746 for (Index = 0; Index < IfInfo->HwAddressSize; Index++) {
747
748 if (IfInfo->HwAddress.Addr[Index] < 0x10) {
749 StrCpy (FormatString, L"0%x-");
750 } else {
751 StrCpy (FormatString, L"%x-");
752 }
753
754 Number = UnicodeSPrint (
755 String,
756 8,
757 (CONST CHAR16 *) FormatString,
758 (UINTN) IfInfo->HwAddress.Addr[Index]
759 );
760 String = String + Number;
761 }
762
763 if (Index != 0) {
764 ASSERT (String > PortString);
765 String--;
766 *String = '\0';
767 }
768
769 //
770 // Print the hardware address.
771 //
772 StringId = HiiSetString (
773 HiiHandle,
774 STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT),
775 PortString,
776 NULL
777 );
778 if (StringId == 0) {
779 return EFI_OUT_OF_RESOURCES;
780 }
781
782 return EFI_SUCCESS;
783 }
784
785 /**
786 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.
787
788 @param[in] Instance Points to IP6 config instance data.
789 @param[in] AddressType The address type.
790 @param[out] AddressInfo The pointer to the buffer to store the address list.
791 @param[out] AddressSize The address size of the address list.
792
793 @retval EFI_SUCCESS The operation finished successfully.
794 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
795 @retval EFI_UNSUPPORTED The AddressType is not supported.
796
797 **/
798 EFI_STATUS
799 Ip6BuildNvAddressInfo (
800 IN IP6_CONFIG_INSTANCE *Instance,
801 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType,
802 OUT VOID **AddressInfo,
803 OUT UINTN *AddressSize
804 )
805 {
806 IP6_CONFIG_NVDATA *Ip6NvData;
807 LIST_ENTRY *Entry;
808 LIST_ENTRY *ListHead;
809 IP6_ADDRESS_INFO_ENTRY *Node;
810 VOID *AddressList;
811 VOID *TmpStr;
812 UINTN DataSize;
813 EFI_IPv6_ADDRESS *Ip6Address;
814 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;
815
816 if ((Instance == NULL) || (AddressInfo == NULL) || (AddressSize == NULL)) {
817 return EFI_INVALID_PARAMETER;
818 }
819
820 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
821
822 Ip6NvData = &Instance->Ip6NvData;
823
824 if (AddressType == Ip6ConfigNvHostAddress) {
825 ListHead = &Ip6NvData->ManualAddress;
826 DataSize = sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS) * Ip6NvData->ManualAddressCount;
827 } else if (AddressType == Ip6ConfigNvGatewayAddress) {
828 ListHead = &Ip6NvData->GatewayAddress;
829 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->GatewayAddressCount;
830 } else if (AddressType == Ip6ConfigNvDnsAddress) {
831 ListHead = &Ip6NvData->DnsAddress;
832 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->DnsAddressCount;
833 } else {
834 return EFI_UNSUPPORTED;
835 }
836
837 AddressList = AllocateZeroPool (DataSize);
838 if (AddressList == NULL) {
839 return EFI_OUT_OF_RESOURCES;
840 }
841
842 TmpStr = AddressList;
843
844 NET_LIST_FOR_EACH (Entry, ListHead) {
845 Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);
846 if (AddressType == Ip6ConfigNvHostAddress) {
847 ManualAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) AddressList;
848 IP6_COPY_ADDRESS (&ManualAddress->Address, &Node->AddrInfo.Address);
849 ManualAddress->PrefixLength = Node->AddrInfo.PrefixLength;
850 AddressList = (UINT8 *) AddressList + sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);
851 } else {
852 Ip6Address = (EFI_IPv6_ADDRESS *) AddressList;
853 IP6_COPY_ADDRESS (Ip6Address, &Node->AddrInfo.Address);
854 AddressList = (UINT8 *) AddressList + sizeof (EFI_IPv6_ADDRESS);
855 }
856 }
857
858 *AddressInfo = TmpStr;
859 *AddressSize = DataSize;
860 return EFI_SUCCESS;
861 }
862
863 /**
864 Convert the IP6 configuration data into the IFR data.
865
866 @param[in, out] IfrNvData The IFR NV data.
867 @param[in] Instance The IP6 config instance data.
868
869 @retval EFI_SUCCESS The operation finished successfully.
870 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
871 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.
872 @retval Others Other errors as indicated.
873
874 **/
875 EFI_STATUS
876 Ip6ConvertConfigNvDataToIfrNvData (
877 IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData,
878 IN IP6_CONFIG_INSTANCE *Instance
879 )
880 {
881 IP6_CONFIG_NVDATA *Ip6NvData;
882 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
883 UINTN DataSize;
884 VOID *Data;
885 EFI_STATUS Status;
886 EFI_IP6_CONFIG_POLICY Policy;
887 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits;
888 EFI_HII_HANDLE HiiHandle;
889
890 if ((IfrNvData == NULL) || (Instance == NULL)) {
891 return EFI_INVALID_PARAMETER;
892 }
893
894 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
895
896 Ip6Config = &Instance->Ip6Config;
897 Ip6NvData = &Instance->Ip6NvData;
898 Data = NULL;
899 DataSize = 0;
900 HiiHandle = Instance->CallbackInfo.RegisteredHandle;
901
902 //
903 // Get the current interface info.
904 //
905 Status = Ip6ConfigNvGetData (
906 Ip6Config,
907 Ip6ConfigDataTypeInterfaceInfo,
908 &DataSize,
909 (VOID **) &Data
910 );
911 if (EFI_ERROR (Status)) {
912 goto Exit;
913 }
914
915 //
916 // Convert the interface info to string and print.
917 //
918 Status = Ip6ConvertInterfaceInfoToString (
919 (EFI_IP6_CONFIG_INTERFACE_INFO *) Data,
920 HiiHandle,
921 IfrNvData
922 );
923 if (EFI_ERROR (Status)) {
924 goto Exit;
925 }
926
927 //
928 // Get the interface id.
929 //
930 DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);
931 ZeroMem (&Ip6NvData->InterfaceId, DataSize);
932 Status = Ip6Config->GetData (
933 Ip6Config,
934 Ip6ConfigDataTypeAltInterfaceId,
935 &DataSize,
936 &Ip6NvData->InterfaceId
937 );
938 if (EFI_ERROR (Status)) {
939 goto Exit;
940 }
941
942 Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);
943
944 //
945 // Get current policy.
946 //
947 DataSize = sizeof (EFI_IP6_CONFIG_POLICY);
948 Status = Ip6Config->GetData (
949 Ip6Config,
950 Ip6ConfigDataTypePolicy,
951 &DataSize,
952 &Policy
953 );
954
955 if (EFI_ERROR (Status)) {
956 goto Exit;
957 }
958
959 if (Policy == Ip6ConfigPolicyManual) {
960 IfrNvData->Policy = IP6_POLICY_MANUAL;
961 } else if (Policy == Ip6ConfigPolicyAutomatic) {
962 IfrNvData->Policy = IP6_POLICY_AUTO;
963 } else {
964 ASSERT (FALSE);
965 Status = EFI_UNSUPPORTED;
966 goto Exit;
967 }
968
969 //
970 // Get Duplicate Address Detection Transmits count.
971 //
972 DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);
973 Status = Ip6Config->GetData (
974 Ip6Config,
975 Ip6ConfigDataTypeDupAddrDetectTransmits,
976 &DataSize,
977 &DadXmits
978 );
979
980 if (EFI_ERROR (Status)) {
981 goto Exit;
982 }
983
984 IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits;
985
986 Exit:
987 if (Data != NULL) {
988 FreePool (Data);
989 }
990
991 return Status;
992 }
993
994 /**
995 Convert IFR data into IP6 configuration data. The policy, alternative interface
996 ID, and DAD transmit counts, and will be saved.
997
998 @param[in] IfrNvData The IFR NV data.
999 @param[in, out] Instance The IP6 config instance data.
1000
1001 @retval EFI_SUCCESS The operation finished successfully.
1002 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1003 @retval Others Other errors as indicated.
1004
1005 **/
1006 EFI_STATUS
1007 Ip6ConvertIfrNvDataToConfigNvDataGeneral (
1008 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,
1009 IN OUT IP6_CONFIG_INSTANCE *Instance
1010 )
1011 {
1012 IP6_CONFIG_NVDATA *Ip6NvData;
1013 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
1014 EFI_STATUS Status;
1015
1016 if ((IfrNvData == NULL) || (Instance == NULL)) {
1017 return EFI_INVALID_PARAMETER;
1018 }
1019
1020 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
1021 Ip6NvData = &Instance->Ip6NvData;
1022 Ip6Config = &Instance->Ip6Config;
1023
1024 //
1025 // Update those fields which don't have INTERACTIVE attribute.
1026 //
1027 if (IfrNvData->Policy == IP6_POLICY_AUTO) {
1028 Ip6NvData->Policy = Ip6ConfigPolicyAutomatic;
1029 } else if (IfrNvData->Policy == IP6_POLICY_MANUAL) {
1030 Ip6NvData->Policy = Ip6ConfigPolicyManual;
1031 }
1032
1033 Ip6NvData->DadTransmitCount.DupAddrDetectTransmits = IfrNvData->DadTransmitCount;
1034
1035 //
1036 // Set the configured policy.
1037 //
1038 Status = Ip6Config->SetData (
1039 Ip6Config,
1040 Ip6ConfigDataTypePolicy,
1041 sizeof (EFI_IP6_CONFIG_POLICY),
1042 &Ip6NvData->Policy
1043 );
1044 if (EFI_ERROR (Status)) {
1045 return Status;
1046 }
1047
1048 //
1049 // Set the duplicate address detection transmits count.
1050 //
1051 Status = Ip6Config->SetData (
1052 Ip6Config,
1053 Ip6ConfigDataTypeDupAddrDetectTransmits,
1054 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),
1055 &Ip6NvData->DadTransmitCount
1056 );
1057 if (EFI_ERROR (Status)) {
1058 return Status;
1059 }
1060
1061 //
1062 // Set the alternative interface ID
1063 //
1064 Status = Ip6Config->SetData (
1065 Ip6Config,
1066 Ip6ConfigDataTypeAltInterfaceId,
1067 sizeof (EFI_IP6_CONFIG_INTERFACE_ID),
1068 &Ip6NvData->InterfaceId
1069 );
1070 if (EFI_ERROR (Status)) {
1071 return Status;
1072 }
1073
1074 return EFI_SUCCESS;
1075 }
1076
1077 /**
1078 Convert IFR data into IP6 configuration data. The policy, configured
1079 manual address, gateway address, and DNS server address will be saved.
1080
1081 @param[in] IfrNvData The IFR NV data.
1082 @param[in, out] Instance The IP6 config instance data.
1083
1084 @retval EFI_SUCCESS The operation finished successfully.
1085 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.
1086 @retval Others Other errors as indicated.
1087
1088 **/
1089 EFI_STATUS
1090 Ip6ConvertIfrNvDataToConfigNvDataAdvanced (
1091 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,
1092 IN OUT IP6_CONFIG_INSTANCE *Instance
1093 )
1094 {
1095 IP6_CONFIG_NVDATA *Ip6NvData;
1096 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
1097 EFI_STATUS Status;
1098 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;
1099 EFI_IPv6_ADDRESS *Address;
1100 BOOLEAN IsAddressOk;
1101 EFI_EVENT SetAddressEvent;
1102 EFI_EVENT TimeoutEvent;
1103 UINTN DataSize;
1104
1105 if ((IfrNvData == NULL) || (Instance == NULL)) {
1106 return EFI_INVALID_PARAMETER;
1107 }
1108
1109 if (IfrNvData->Policy == IP6_POLICY_AUTO) {
1110 return EFI_SUCCESS;
1111 }
1112
1113 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);
1114 Ip6NvData = &Instance->Ip6NvData;
1115 Ip6Config = &Instance->Ip6Config;
1116
1117 //
1118 // Update those fields which don't have INTERACTIVE attribute.
1119 //
1120 Ip6NvData->Policy = Ip6ConfigPolicyManual;
1121
1122 //
1123 // Set the configured policy.
1124 //
1125 Status = Ip6Config->SetData (
1126 Ip6Config,
1127 Ip6ConfigDataTypePolicy,
1128 sizeof (EFI_IP6_CONFIG_POLICY),
1129 &Ip6NvData->Policy
1130 );
1131 if (EFI_ERROR (Status)) {
1132 return Status;
1133 }
1134
1135 //
1136 // Create events & timers for asynchronous settings.
1137 //
1138 SetAddressEvent = NULL;
1139 TimeoutEvent = NULL;
1140 ManualAddress = NULL;
1141 Address = NULL;
1142
1143 Status = gBS->CreateEvent (
1144 EVT_NOTIFY_SIGNAL,
1145 TPL_NOTIFY,
1146 Ip6ConfigManualAddressNotify,
1147 &IsAddressOk,
1148 &SetAddressEvent
1149 );
1150 if (EFI_ERROR (Status)) {
1151 goto Exit;
1152 }
1153
1154 Status = gBS->CreateEvent (
1155 EVT_TIMER,
1156 TPL_CALLBACK,
1157 NULL,
1158 NULL,
1159 &TimeoutEvent
1160 );
1161 if (EFI_ERROR (Status)) {
1162 goto Exit;
1163 }
1164
1165 //
1166 // Set the manual address list. This is an asynchronous process.
1167 //
1168 if (!IsListEmpty (&Ip6NvData->ManualAddress) && (Ip6NvData->ManualAddressCount != 0)) {
1169 Status = Ip6BuildNvAddressInfo (
1170 Instance,
1171 Ip6ConfigNvHostAddress,
1172 (VOID **) &ManualAddress,
1173 &DataSize
1174 );
1175 if (EFI_ERROR (Status)) {
1176 goto Exit;
1177 }
1178
1179 IsAddressOk = FALSE;
1180
1181 Status = Ip6Config->RegisterDataNotify (
1182 Ip6Config,
1183 Ip6ConfigDataTypeManualAddress,
1184 SetAddressEvent
1185 );
1186 if (EFI_ERROR (Status)) {
1187 goto Exit;
1188 }
1189
1190 Status = Ip6Config->SetData (
1191 Ip6Config,
1192 Ip6ConfigDataTypeManualAddress,
1193 DataSize,
1194 (VOID *) ManualAddress
1195 );
1196 if (Status == EFI_NOT_READY) {
1197 gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);
1198 while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {
1199 if (IsAddressOk) {
1200 Status = EFI_SUCCESS;
1201 }
1202 break;
1203 }
1204 }
1205
1206 Status = Ip6Config->UnregisterDataNotify (
1207 Ip6Config,
1208 Ip6ConfigDataTypeManualAddress,
1209 SetAddressEvent
1210 );
1211 if (EFI_ERROR (Status)) {
1212 goto Exit;
1213 }
1214 }
1215
1216 //
1217 // Set gateway address list.
1218 //
1219 if (!IsListEmpty (&Ip6NvData->GatewayAddress) && (Ip6NvData->GatewayAddressCount != 0)) {
1220 Status = Ip6BuildNvAddressInfo (
1221 Instance,
1222 Ip6ConfigNvGatewayAddress,
1223 (VOID **) &Address,
1224 &DataSize
1225 );
1226 if (EFI_ERROR (Status)) {
1227 goto Exit;
1228 }
1229
1230 Status = Ip6Config->SetData (
1231 Ip6Config,
1232 Ip6ConfigDataTypeGateway,
1233 DataSize,
1234 (VOID *) Address
1235 );
1236 if (EFI_ERROR (Status)) {
1237 goto Exit;
1238 }
1239
1240 FreePool (Address);
1241 Address = NULL;
1242 }
1243
1244 //
1245 // Set DNS server address list.
1246 //
1247 if (!IsListEmpty (&Ip6NvData->DnsAddress) && (Ip6NvData->DnsAddressCount != 0)) {
1248 Status = Ip6BuildNvAddressInfo (
1249 Instance,
1250 Ip6ConfigNvDnsAddress,
1251 (VOID **) &Address,
1252 &DataSize
1253 );
1254 if (EFI_ERROR (Status)) {
1255 goto Exit;
1256 }
1257
1258 Status = Ip6Config->SetData (
1259 Ip6Config,
1260 Ip6ConfigDataTypeDnsServer,
1261 DataSize,
1262 (VOID *) Address
1263 );
1264 if (EFI_ERROR (Status)) {
1265 goto Exit;
1266 }
1267 }
1268
1269 Status = EFI_SUCCESS;
1270
1271 Exit:
1272 if (SetAddressEvent != NULL) {
1273 gBS->CloseEvent (SetAddressEvent);
1274 }
1275
1276 if (TimeoutEvent != NULL) {
1277 gBS->CloseEvent (TimeoutEvent);
1278 }
1279
1280 if (ManualAddress != NULL) {
1281 FreePool (ManualAddress);
1282 }
1283
1284 if (Address != NULL) {
1285 FreePool (Address);
1286 }
1287
1288 return Status;
1289 }
1290
1291
1292 /**
1293 This function allows the caller to request the current
1294 configuration for one or more named elements. The resulting
1295 string is in <ConfigAltResp> format. Any and all alternative
1296 configuration strings shall also be appended to the end of the
1297 current configuration string. If they are, they must appear
1298 after the current configuration. They must contain the same
1299 routing (GUID, NAME, PATH) as the current configuration string.
1300 They must have an additional description indicating the type of
1301 alternative configuration the string represents,
1302 "ALTCFG=<StringToken>". That <StringToken> (when
1303 converted from Hex UNICODE to binary) is a reference to a
1304 string in the associated string pack.
1305
1306 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1307 @param[in] Request A null-terminated Unicode string in
1308 <ConfigRequest> format. Note that this
1309 includes the routing information as well as
1310 the configurable name / value pairs. It is
1311 invalid for this string to be in
1312 <MultiConfigRequest> format.
1313 @param[out] Progress On return, points to a character in the
1314 Request string. Points to the string's null
1315 terminator if request was successful. Points
1316 to the most recent "&" before the first
1317 failing name / value pair (or the beginning
1318 of the string if the failure is in the first
1319 name / value pair) if the request was not
1320 successful.
1321 @param[out] Results A null-terminated Unicode string in
1322 <ConfigAltResp> format which has all values
1323 filled in for the names in the Request string.
1324 String to be allocated by the called function.
1325
1326 @retval EFI_SUCCESS The Results string is filled with the
1327 values corresponding to all requested
1328 names.
1329 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
1330 parts of the results that must be
1331 stored awaiting possible future
1332 protocols.
1333 @retval EFI_INVALID_PARAMETER For example, passing in a NULL
1334 for the Request parameter
1335 would result in this type of
1336 error. In this case, the
1337 Progress parameter would be
1338 set to NULL.
1339 @retval EFI_NOT_FOUND Routing data doesn't match any
1340 known driver. Progress set to the
1341 first character in the routing header.
1342 Note: There is no requirement that the
1343 driver validate the routing data. It
1344 must skip the <ConfigHdr> in order to
1345 process the names.
1346 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set
1347 to most recent & before the
1348 error or the beginning of the
1349 string.
1350 @retval EFI_INVALID_PARAMETER Unknown name. Progress points
1351 to the & before the name in
1352 question. Currently not implemented.
1353 **/
1354 EFI_STATUS
1355 EFIAPI
1356 Ip6FormExtractConfig (
1357 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1358 IN CONST EFI_STRING Request,
1359 OUT EFI_STRING *Progress,
1360 OUT EFI_STRING *Results
1361 )
1362 {
1363
1364 EFI_STATUS Status;
1365 IP6_FORM_CALLBACK_INFO *Private;
1366 IP6_CONFIG_INSTANCE *Ip6ConfigInstance;
1367 IP6_CONFIG_IFR_NVDATA *IfrNvData;
1368 EFI_STRING ConfigRequestHdr;
1369 EFI_STRING ConfigRequest;
1370 BOOLEAN AllocatedRequest;
1371 UINTN Size;
1372 UINTN BufferSize;
1373
1374 if (This == NULL || Progress == NULL || Results == NULL) {
1375 return EFI_INVALID_PARAMETER;
1376 }
1377
1378 *Progress = Request;
1379 if ((Request != NULL) &&
1380 !HiiIsConfigHdrMatch (Request, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {
1381 return EFI_NOT_FOUND;
1382 }
1383
1384 ConfigRequestHdr = NULL;
1385 ConfigRequest = NULL;
1386 AllocatedRequest = FALSE;
1387 Size = 0;
1388
1389 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
1390 Ip6ConfigInstance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);
1391 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
1392
1393 IfrNvData = (IP6_CONFIG_IFR_NVDATA *) AllocateZeroPool (BufferSize);
1394 if (IfrNvData == NULL) {
1395 return EFI_OUT_OF_RESOURCES;
1396 }
1397
1398 Status = Ip6ConvertConfigNvDataToIfrNvData (IfrNvData, Ip6ConfigInstance);
1399 if (EFI_ERROR (Status)) {
1400 goto Exit;
1401 }
1402
1403 ConfigRequest = Request;
1404 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
1405 //
1406 // Request has no request element, construct full request string.
1407 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
1408 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.
1409 //
1410 ConfigRequestHdr = HiiConstructConfigHdr (
1411 &gIp6ConfigNvDataGuid,
1412 mIp6ConfigStorageName,
1413 Private->ChildHandle
1414 );
1415 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
1416 ConfigRequest = AllocateZeroPool (Size);
1417 ASSERT (ConfigRequest != NULL);
1418 AllocatedRequest = TRUE;
1419 UnicodeSPrint (
1420 ConfigRequest,
1421 Size,
1422 L"%s&OFFSET=0&WIDTH=%016LX",
1423 ConfigRequestHdr,
1424 (UINT64) BufferSize
1425 );
1426 FreePool (ConfigRequestHdr);
1427 }
1428
1429 //
1430 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
1431 //
1432 Status = gHiiConfigRouting->BlockToConfig (
1433 gHiiConfigRouting,
1434 ConfigRequest,
1435 (UINT8 *) IfrNvData,
1436 BufferSize,
1437 Results,
1438 Progress
1439 );
1440
1441 Exit:
1442 FreePool (IfrNvData);
1443 //
1444 // Free the allocated config request string.
1445 //
1446 if (AllocatedRequest) {
1447 FreePool (ConfigRequest);
1448 ConfigRequest = NULL;
1449 }
1450 //
1451 // Set Progress string to the original request string.
1452 //
1453 if (Request == NULL) {
1454 *Progress = NULL;
1455 } else if (StrStr (Request, L"OFFSET") == NULL) {
1456 *Progress = Request + StrLen (Request);
1457 }
1458
1459 return Status;
1460 }
1461
1462 /**
1463 This function applies changes in a driver's configuration.
1464 Input is a Configuration, which has the routing data for this
1465 driver followed by name / value configuration pairs. The driver
1466 must apply those pairs to its configurable storage. If the
1467 driver's configuration is stored in a linear block of data
1468 and the driver's name / value pairs are in <BlockConfig>
1469 format, it may use the ConfigToBlock helper function (above) to
1470 simplify the job. Currently not implemented.
1471
1472 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1473 @param[in] Configuration A null-terminated Unicode string in
1474 <ConfigString> format.
1475 @param[out] Progress A pointer to a string filled in with the
1476 offset of the most recent '&' before the
1477 first failing name / value pair (or the
1478 beginn ing of the string if the failure
1479 is in the first name / value pair) or
1480 the terminating NULL if all was
1481 successful.
1482
1483 @retval EFI_SUCCESS The results have been distributed or are
1484 awaiting distribution.
1485 @retval EFI_OUT_OF_MEMORY Not enough memory to store the
1486 parts of the results that must be
1487 stored awaiting possible future
1488 protocols.
1489 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
1490 Results parameter would result
1491 in this type of error.
1492 @retval EFI_NOT_FOUND Target for the specified routing data
1493 was not found.
1494 **/
1495 EFI_STATUS
1496 EFIAPI
1497 Ip6FormRouteConfig (
1498 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1499 IN CONST EFI_STRING Configuration,
1500 OUT EFI_STRING *Progress
1501 )
1502 {
1503 if (This == NULL || Configuration == NULL || Progress == NULL) {
1504 return EFI_INVALID_PARAMETER;
1505 }
1506
1507 //
1508 // Check routing data in <ConfigHdr>.
1509 // Note: if only one Storage is used, then this checking could be skipped.
1510 //
1511 if (!HiiIsConfigHdrMatch (Configuration, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {
1512 *Progress = Configuration;
1513 return EFI_NOT_FOUND;
1514 }
1515
1516 *Progress = Configuration + StrLen (Configuration);
1517
1518 return EFI_SUCCESS;
1519 }
1520
1521 /**
1522 Display host addresses, route table, DNS addresses and gateway addresses in
1523 "IPv6 Current Setting" page.
1524
1525 @param[in] Instance The IP6 config instance data.
1526
1527 @retval EFI_SUCCESS The operation finished successfully.
1528 @retval Others Other errors as indicated.
1529
1530 **/
1531 EFI_STATUS
1532 Ip6GetCurrentSetting (
1533 IN IP6_CONFIG_INSTANCE *Instance
1534 )
1535 {
1536 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;
1537 EFI_HII_HANDLE HiiHandle;
1538 EFI_IP6_CONFIG_INTERFACE_INFO *Data;
1539 UINTN DataSize;
1540 EFI_STATUS Status;
1541 CHAR16 PortString[ADDRESS_STR_MAX_SIZE];
1542 EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;
1543
1544
1545 Ip6Config = &Instance->Ip6Config;
1546 HiiHandle = Instance->CallbackInfo.RegisteredHandle;
1547 Data = NULL;
1548
1549 //
1550 // Get current interface info.
1551 //
1552 Status = Ip6ConfigNvGetData (
1553 Ip6Config,
1554 Ip6ConfigDataTypeInterfaceInfo,
1555 &DataSize,
1556 (VOID **) &Data
1557 );
1558 if (EFI_ERROR (Status)) {
1559 return Status;
1560 }
1561
1562 //
1563 // Generate dynamic text opcode for host address and draw it.
1564 //
1565 IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data;
1566 Status = Ip6ConvertAddressListToString (
1567 PortString,
1568 HiiHandle,
1569 Ip6ConfigNvHostAddress,
1570 IfInfo->AddressInfo,
1571 IfInfo->AddressInfoCount
1572 );
1573 if (EFI_ERROR (Status)) {
1574 FreePool (Data);
1575 return Status;
1576 }
1577
1578 //
1579 // Generate the dynamic text opcode for route table and draw it.
1580 //
1581 Status = Ip6ConvertAddressListToString (
1582 PortString,
1583 HiiHandle,
1584 Ip6ConfigNvRouteTable,
1585 IfInfo->RouteTable,
1586 IfInfo->RouteCount
1587 );
1588 if (EFI_ERROR (Status)) {
1589 FreePool (Data);
1590 return Status;
1591 }
1592
1593 //
1594 // Get DNS server list.
1595 //
1596 FreePool (Data);
1597 DataSize = 0;
1598 Data = NULL;
1599 Status = Ip6ConfigNvGetData (
1600 Ip6Config,
1601 Ip6ConfigDataTypeDnsServer,
1602 &DataSize,
1603 (VOID **) &Data
1604 );
1605 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
1606 if (Data != NULL) {
1607 FreePool (Data);
1608 }
1609 return Status;
1610 }
1611
1612 if (DataSize > 0) {
1613 //
1614 // Generate the dynamic text opcode for DNS server and draw it.
1615 //
1616 Status = Ip6ConvertAddressListToString (
1617 PortString,
1618 HiiHandle,
1619 Ip6ConfigNvDnsAddress,
1620 Data,
1621 DataSize / sizeof (EFI_IPv6_ADDRESS)
1622 );
1623 if (EFI_ERROR (Status)) {
1624 FreePool (Data);
1625 return Status;
1626 }
1627 }
1628
1629 //
1630 // Get gateway adderss list.
1631 //
1632 if (Data != NULL) {
1633 FreePool (Data);
1634 }
1635
1636 DataSize = 0;
1637 Data = NULL;
1638 Status = Ip6ConfigNvGetData (
1639 Ip6Config,
1640 Ip6ConfigDataTypeGateway,
1641 &DataSize,
1642 (VOID **) &Data
1643 );
1644 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {
1645 if (Data != NULL) {
1646 FreePool (Data);
1647 }
1648 return Status;
1649 }
1650
1651 if (DataSize > 0) {
1652 //
1653 // Generate the dynamic text opcode for gateway and draw it.
1654 //
1655 Status = Ip6ConvertAddressListToString (
1656 PortString,
1657 HiiHandle,
1658 Ip6ConfigNvGatewayAddress,
1659 Data,
1660 DataSize / sizeof (EFI_IPv6_ADDRESS)
1661 );
1662 if (EFI_ERROR (Status)) {
1663 FreePool (Data);
1664 return Status;
1665 }
1666 }
1667
1668 if (Data != NULL) {
1669 FreePool (Data);
1670 }
1671
1672 return EFI_SUCCESS;
1673 }
1674
1675 /**
1676 This function is called to provide results data to the driver.
1677 This data consists of a unique key that is used to identify
1678 which data is either being passed back or being asked for.
1679
1680 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1681 @param[in] Action Specifies the type of action taken by the browser.
1682 @param[in] QuestionId A unique value which is sent to the original
1683 exporting driver so that it can identify the type
1684 of data to expect. The format of the data tends to
1685 vary based on the opcode that generated the callback.
1686 @param[in] Type The type of value for the question.
1687 @param[in] Value A pointer to the data being sent to the original
1688 exporting driver.
1689 @param[out] ActionRequest On return, points to the action requested by the
1690 callback function.
1691
1692 @retval EFI_SUCCESS The callback successfully handled the action.
1693 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the
1694 variable and its data.
1695 @retval EFI_DEVICE_ERROR The variable could not be saved.
1696 @retval EFI_UNSUPPORTED The specified Action is not supported by the
1697 callback. Currently not implemented.
1698 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.
1699 @retval Others Other errors as indicated.
1700
1701 **/
1702 EFI_STATUS
1703 EFIAPI
1704 Ip6FormCallback (
1705 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1706 IN EFI_BROWSER_ACTION Action,
1707 IN EFI_QUESTION_ID QuestionId,
1708 IN UINT8 Type,
1709 IN EFI_IFR_TYPE_VALUE *Value,
1710 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1711 )
1712 {
1713 IP6_FORM_CALLBACK_INFO *Private;
1714 UINTN BufferSize;
1715 IP6_CONFIG_IFR_NVDATA *IfrNvData;
1716 EFI_STATUS Status;
1717 EFI_INPUT_KEY Key;
1718 IP6_CONFIG_INSTANCE *Instance;
1719 IP6_CONFIG_NVDATA *Ip6NvData;
1720
1721 if (This == NULL) {
1722 return EFI_INVALID_PARAMETER;
1723 }
1724
1725 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);
1726 Instance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);
1727 Ip6NvData = &Instance->Ip6NvData;
1728
1729 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)){
1730 return EFI_SUCCESS;
1731 }
1732
1733 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {
1734 return EFI_UNSUPPORTED;
1735 }
1736
1737 if ((Value == NULL) || (ActionRequest == NULL)) {
1738 return EFI_INVALID_PARAMETER;
1739 }
1740
1741 //
1742 // Retrieve uncommitted data from Browser
1743 //
1744
1745 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
1746 IfrNvData = AllocateZeroPool (BufferSize);
1747 if (IfrNvData == NULL) {
1748 return EFI_OUT_OF_RESOURCES;
1749 }
1750
1751 Status = EFI_SUCCESS;
1752
1753 HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);
1754
1755 if (Action == EFI_BROWSER_ACTION_CHANGING) {
1756 switch (QuestionId) {
1757 case KEY_GET_CURRENT_SETTING:
1758 Status = Ip6GetCurrentSetting (Instance);
1759 break;
1760
1761 default:
1762 break;
1763 }
1764 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
1765 switch (QuestionId) {
1766 case KEY_SAVE_CONFIG_CHANGES:
1767 Status = Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData, Instance);
1768 if (EFI_ERROR (Status)) {
1769 break;
1770 }
1771
1772 Status = Ip6GetCurrentSetting (Instance);
1773
1774 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1775 break;
1776
1777 case KEY_IGNORE_CONFIG_CHANGES:
1778 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);
1779 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);
1780 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);
1781
1782 Ip6NvData->ManualAddressCount = 0;
1783 Ip6NvData->GatewayAddressCount = 0;
1784 Ip6NvData->DnsAddressCount = 0;
1785
1786 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1787 break;
1788
1789 case KEY_SAVE_CHANGES:
1790 Status = Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData, Instance);
1791 if (EFI_ERROR (Status)) {
1792 break;
1793 }
1794 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;
1795 break;
1796
1797 case KEY_INTERFACE_ID:
1798 Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);
1799 if (EFI_ERROR (Status)) {
1800 CreatePopUp (
1801 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1802 &Key,
1803 L"Invalid Interface ID!",
1804 NULL
1805 );
1806 }
1807
1808 break;
1809
1810 case KEY_MANUAL_ADDRESS:
1811 Status = Ip6ParseAddressListFromString (
1812 IfrNvData->ManualAddress,
1813 &Ip6NvData->ManualAddress,
1814 &Ip6NvData->ManualAddressCount
1815 );
1816 if (EFI_ERROR (Status)) {
1817 CreatePopUp (
1818 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1819 &Key,
1820 L"Invalid Host Addresses!",
1821 NULL
1822 );
1823 }
1824
1825 break;
1826
1827 case KEY_GATEWAY_ADDRESS:
1828 Status = Ip6ParseAddressListFromString (
1829 IfrNvData->GatewayAddress,
1830 &Ip6NvData->GatewayAddress,
1831 &Ip6NvData->GatewayAddressCount
1832 );
1833 if (EFI_ERROR (Status)) {
1834 CreatePopUp (
1835 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1836 &Key,
1837 L"Invalid Gateway Addresses!",
1838 NULL
1839 );
1840 }
1841
1842 break;
1843
1844 case KEY_DNS_ADDRESS:
1845 Status = Ip6ParseAddressListFromString (
1846 IfrNvData->DnsAddress,
1847 &Ip6NvData->DnsAddress,
1848 &Ip6NvData->DnsAddressCount
1849 );
1850 if (EFI_ERROR (Status)) {
1851 CreatePopUp (
1852 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,
1853 &Key,
1854 L"Invalid DNS Addresses!",
1855 NULL
1856 );
1857 }
1858
1859 break;
1860
1861 default:
1862 break;
1863 }
1864 }
1865
1866 if (!EFI_ERROR (Status)) {
1867 //
1868 // Pass changed uncommitted data back to Form Browser.
1869 //
1870 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);
1871 HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL);
1872 }
1873
1874 FreePool (IfrNvData);
1875 return Status;
1876 }
1877
1878 /**
1879 Install HII Config Access protocol for network device and allocate resources.
1880
1881 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.
1882
1883 @retval EFI_SUCCESS The HII Config Access protocol is installed.
1884 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.
1885 @retval Others Other errors as indicated.
1886
1887 **/
1888 EFI_STATUS
1889 Ip6ConfigFormInit (
1890 IN OUT IP6_CONFIG_INSTANCE *Instance
1891 )
1892 {
1893 EFI_STATUS Status;
1894 IP6_SERVICE *IpSb;
1895 IP6_FORM_CALLBACK_INFO *CallbackInfo;
1896 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;
1897 VENDOR_DEVICE_PATH VendorDeviceNode;
1898 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;
1899 CHAR16 *MacString;
1900 CHAR16 MenuString[128];
1901 CHAR16 PortString[128];
1902 CHAR16 *OldMenuString;
1903 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;
1904
1905 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
1906 ASSERT (IpSb != NULL);
1907
1908 Status = gBS->HandleProtocol (
1909 IpSb->Controller,
1910 &gEfiDevicePathProtocolGuid,
1911 (VOID **) &ParentDevicePath
1912 );
1913 if (EFI_ERROR (Status)) {
1914 return Status;
1915 }
1916
1917 CallbackInfo = &Instance->CallbackInfo;
1918 CallbackInfo->Signature = IP6_FORM_CALLBACK_INFO_SIGNATURE;
1919
1920 //
1921 // Construct device path node for EFI HII Config Access protocol,
1922 // which consists of controller physical device path and one hardware
1923 // vendor guid node.
1924 //
1925 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));
1926 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;
1927 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;
1928
1929 CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);
1930
1931 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));
1932 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (
1933 ParentDevicePath,
1934 (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode
1935 );
1936 if (CallbackInfo->HiiVendorDevicePath == NULL) {
1937 Status = EFI_OUT_OF_RESOURCES;
1938 goto Error;
1939 }
1940
1941 ConfigAccess = &CallbackInfo->HiiConfigAccess;
1942 ConfigAccess->ExtractConfig = Ip6FormExtractConfig;
1943 ConfigAccess->RouteConfig = Ip6FormRouteConfig;
1944 ConfigAccess->Callback = Ip6FormCallback;
1945
1946 //
1947 // Install Device Path Protocol and Config Access protocol on new handle
1948 //
1949 Status = gBS->InstallMultipleProtocolInterfaces (
1950 &CallbackInfo->ChildHandle,
1951 &gEfiDevicePathProtocolGuid,
1952 CallbackInfo->HiiVendorDevicePath,
1953 &gEfiHiiConfigAccessProtocolGuid,
1954 ConfigAccess,
1955 NULL
1956 );
1957 if (!EFI_ERROR (Status)) {
1958 //
1959 // Open the Parent Handle for the child
1960 //
1961 Status = gBS->OpenProtocol (
1962 IpSb->Controller,
1963 &gEfiManagedNetworkServiceBindingProtocolGuid,
1964 (VOID **) &MnpSb,
1965 IpSb->Image,
1966 CallbackInfo->ChildHandle,
1967 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER
1968 );
1969 }
1970
1971 if (EFI_ERROR (Status)) {
1972 goto Error;
1973 }
1974
1975 //
1976 // Publish our HII data
1977 //
1978 CallbackInfo->RegisteredHandle = HiiAddPackages (
1979 &gIp6ConfigNvDataGuid,
1980 CallbackInfo->ChildHandle,
1981 Ip6DxeStrings,
1982 Ip6ConfigBin,
1983 NULL
1984 );
1985 if (CallbackInfo->RegisteredHandle == NULL) {
1986 Status = EFI_OUT_OF_RESOURCES;
1987 goto Error;
1988 }
1989
1990 //
1991 // Append MAC string in the menu help string and tile help string
1992 //
1993 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);
1994 if (!EFI_ERROR (Status)) {
1995 OldMenuString = HiiGetString (
1996 CallbackInfo->RegisteredHandle,
1997 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),
1998 NULL)
1999 ;
2000 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);
2001 HiiSetString (
2002 CallbackInfo->RegisteredHandle,
2003 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),
2004 MenuString,
2005 NULL
2006 );
2007 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);
2008 HiiSetString (
2009 CallbackInfo->RegisteredHandle,
2010 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP),
2011 PortString,
2012 NULL
2013 );
2014
2015 FreePool (MacString);
2016 FreePool (OldMenuString);
2017
2018 InitializeListHead (&Instance->Ip6NvData.ManualAddress);
2019 InitializeListHead (&Instance->Ip6NvData.GatewayAddress);
2020 InitializeListHead (&Instance->Ip6NvData.DnsAddress);
2021
2022 return EFI_SUCCESS;
2023 }
2024
2025 Error:
2026 Ip6ConfigFormUnload (Instance);
2027 return Status;
2028 }
2029
2030 /**
2031 Uninstall the HII Config Access protocol for network devices and free up the resources.
2032
2033 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.
2034
2035 **/
2036 VOID
2037 Ip6ConfigFormUnload (
2038 IN OUT IP6_CONFIG_INSTANCE *Instance
2039 )
2040 {
2041 IP6_SERVICE *IpSb;
2042 IP6_FORM_CALLBACK_INFO *CallbackInfo;
2043 IP6_CONFIG_NVDATA *Ip6NvData;
2044
2045 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);
2046 ASSERT (IpSb != NULL);
2047
2048 CallbackInfo = &Instance->CallbackInfo;
2049
2050 if (CallbackInfo->ChildHandle != NULL) {
2051
2052 //
2053 // Close the child handle
2054 //
2055 gBS->CloseProtocol (
2056 IpSb->Controller,
2057 &gEfiManagedNetworkServiceBindingProtocolGuid,
2058 IpSb->Image,
2059 CallbackInfo->ChildHandle
2060 );
2061 //
2062 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL
2063 //
2064 gBS->UninstallMultipleProtocolInterfaces (
2065 CallbackInfo->ChildHandle,
2066 &gEfiDevicePathProtocolGuid,
2067 CallbackInfo->HiiVendorDevicePath,
2068 &gEfiHiiConfigAccessProtocolGuid,
2069 &CallbackInfo->HiiConfigAccess,
2070 NULL
2071 );
2072 }
2073
2074 if (CallbackInfo->HiiVendorDevicePath != NULL) {
2075 FreePool (CallbackInfo->HiiVendorDevicePath);
2076 }
2077
2078 if (CallbackInfo->RegisteredHandle != NULL) {
2079 //
2080 // Remove HII package list
2081 //
2082 HiiRemovePackages (CallbackInfo->RegisteredHandle);
2083 }
2084
2085 Ip6NvData = &Instance->Ip6NvData;
2086
2087 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);
2088 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);
2089 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);
2090
2091 Ip6NvData->ManualAddressCount = 0;
2092 Ip6NvData->GatewayAddressCount = 0;
2093 Ip6NvData->DnsAddressCount = 0;
2094 }