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