]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/Ip6Dxe/Ip6ConfigNv.c
Remove HiiUpdateForm from ExtractConfig fucntion.
[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
a3bcde70
HT
698\r
699 if ((IfInfo == NULL) || (HiiHandle == NULL) || (IfrNvData == NULL)) {\r
700 return EFI_INVALID_PARAMETER;\r
701 }\r
702\r
703 //\r
704 // Print the interface name.\r
705 //\r
706 StringId = HiiSetString (\r
707 HiiHandle,\r
708 STRING_TOKEN (STR_IP6_INTERFACE_NAME_CONTENT),\r
709 IfInfo->Name,\r
710 NULL\r
711 );\r
712 if (StringId == 0) {\r
713 return EFI_OUT_OF_RESOURCES;\r
714 }\r
715\r
716 //\r
717 // Print the interface type.\r
718 //\r
719 if (IfInfo->IfType == Ip6InterfaceTypeEthernet) {\r
720 StrCpy (PortString, IP6_ETHERNET);\r
721 } else if (IfInfo->IfType == Ip6InterfaceTypeExperimentalEthernet) {\r
722 StrCpy (PortString, IP6_EXPERIMENTAL_ETHERNET);\r
723 } else {\r
724 //\r
725 // Refer to RFC1700, chapter Number Hardware Type.\r
726 //\r
727 UnicodeSPrint (PortString, 6, L"%d", IfInfo->IfType);\r
728 }\r
729\r
730 StringId = HiiSetString (\r
731 HiiHandle,\r
732 STRING_TOKEN (STR_IP6_INTERFACE_TYPE_CONTENT),\r
733 PortString,\r
734 NULL\r
735 );\r
736 if (StringId == 0) {\r
737 return EFI_OUT_OF_RESOURCES;\r
738 }\r
739\r
740 //\r
741 // Convert the hardware address.\r
742 //\r
743 String = PortString;\r
744 ASSERT (IfInfo->HwAddressSize <= 32);\r
745\r
746 for (Index = 0; Index < IfInfo->HwAddressSize; Index++) {\r
747\r
748 if (IfInfo->HwAddress.Addr[Index] < 0x10) {\r
749 StrCpy (FormatString, L"0%x-");\r
750 } else {\r
751 StrCpy (FormatString, L"%x-");\r
752 }\r
753\r
754 Number = UnicodeSPrint (\r
755 String,\r
756 8,\r
757 (CONST CHAR16 *) FormatString,\r
758 (UINTN) IfInfo->HwAddress.Addr[Index]\r
759 );\r
760 String = String + Number;\r
761 }\r
762\r
763 if (Index != 0) {\r
764 ASSERT (String > PortString);\r
765 String--;\r
766 *String = '\0';\r
767 }\r
768\r
769 //\r
770 // Print the hardware address.\r
771 //\r
772 StringId = HiiSetString (\r
773 HiiHandle,\r
774 STRING_TOKEN (STR_IP6_MAC_ADDRESS_CONTENT),\r
775 PortString,\r
776 NULL\r
777 );\r
778 if (StringId == 0) {\r
779 return EFI_OUT_OF_RESOURCES;\r
780 }\r
781\r
e464225c 782 return EFI_SUCCESS;\r
a3bcde70
HT
783}\r
784\r
785/**\r
786 Build the address info list from list array of node in IP6_ADDRESS_INFO_ENTRY.\r
787\r
788 @param[in] Instance Points to IP6 config instance data.\r
789 @param[in] AddressType The address type.\r
790 @param[out] AddressInfo The pointer to the buffer to store the address list.\r
791 @param[out] AddressSize The address size of the address list.\r
792\r
793 @retval EFI_SUCCESS The operation finished successfully.\r
794 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
795 @retval EFI_UNSUPPORTED The AddressType is not supported.\r
796\r
797**/\r
798EFI_STATUS\r
799Ip6BuildNvAddressInfo (\r
800 IN IP6_CONFIG_INSTANCE *Instance,\r
801 IN IP6_CONFIG_NV_ADDRESS_TYPE AddressType,\r
802 OUT VOID **AddressInfo,\r
803 OUT UINTN *AddressSize\r
804 )\r
805{\r
806 IP6_CONFIG_NVDATA *Ip6NvData;\r
807 LIST_ENTRY *Entry;\r
808 LIST_ENTRY *ListHead;\r
809 IP6_ADDRESS_INFO_ENTRY *Node;\r
810 VOID *AddressList;\r
811 VOID *TmpStr;\r
812 UINTN DataSize;\r
813 EFI_IPv6_ADDRESS *Ip6Address;\r
814 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;\r
815\r
816 if ((Instance == NULL) || (AddressInfo == NULL) || (AddressSize == NULL)) {\r
817 return EFI_INVALID_PARAMETER;\r
818 }\r
819\r
820 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
821\r
822 Ip6NvData = &Instance->Ip6NvData;\r
823\r
824 if (AddressType == Ip6ConfigNvHostAddress) {\r
825 ListHead = &Ip6NvData->ManualAddress;\r
826 DataSize = sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS) * Ip6NvData->ManualAddressCount;\r
827 } else if (AddressType == Ip6ConfigNvGatewayAddress) {\r
828 ListHead = &Ip6NvData->GatewayAddress;\r
829 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->GatewayAddressCount;\r
830 } else if (AddressType == Ip6ConfigNvDnsAddress) {\r
831 ListHead = &Ip6NvData->DnsAddress;\r
832 DataSize = sizeof (EFI_IPv6_ADDRESS) * Ip6NvData->DnsAddressCount;\r
833 } else {\r
834 return EFI_UNSUPPORTED;\r
835 }\r
836\r
837 AddressList = AllocateZeroPool (DataSize);\r
838 if (AddressList == NULL) {\r
839 return EFI_OUT_OF_RESOURCES;\r
840 }\r
841\r
842 TmpStr = AddressList;\r
843\r
844 NET_LIST_FOR_EACH (Entry, ListHead) {\r
845 Node = NET_LIST_USER_STRUCT (Entry, IP6_ADDRESS_INFO_ENTRY, Link);\r
846 if (AddressType == Ip6ConfigNvHostAddress) {\r
847 ManualAddress = (EFI_IP6_CONFIG_MANUAL_ADDRESS *) AddressList;\r
848 IP6_COPY_ADDRESS (&ManualAddress->Address, &Node->AddrInfo.Address);\r
849 ManualAddress->PrefixLength = Node->AddrInfo.PrefixLength;\r
850 AddressList = (UINT8 *) AddressList + sizeof (EFI_IP6_CONFIG_MANUAL_ADDRESS);\r
851 } else {\r
852 Ip6Address = (EFI_IPv6_ADDRESS *) AddressList;\r
853 IP6_COPY_ADDRESS (Ip6Address, &Node->AddrInfo.Address);\r
854 AddressList = (UINT8 *) AddressList + sizeof (EFI_IPv6_ADDRESS);\r
855 }\r
856 }\r
857\r
858 *AddressInfo = TmpStr;\r
859 *AddressSize = DataSize;\r
860 return EFI_SUCCESS;\r
861}\r
862\r
863/**\r
864 Convert the IP6 configuration data into the IFR data.\r
865\r
866 @param[in, out] IfrNvData The IFR NV data.\r
867 @param[in] Instance The IP6 config instance data.\r
868\r
869 @retval EFI_SUCCESS The operation finished successfully.\r
870 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
871 @retval EFI_UNSUPPORTED The policy is not supported in the current implementation.\r
872 @retval Others Other errors as indicated.\r
873\r
874**/\r
875EFI_STATUS\r
876Ip6ConvertConfigNvDataToIfrNvData (\r
877 IN OUT IP6_CONFIG_IFR_NVDATA *IfrNvData,\r
878 IN IP6_CONFIG_INSTANCE *Instance\r
879 )\r
880{\r
0b2a54e2 881 IP6_CONFIG_NVDATA *Ip6NvData;\r
a3bcde70
HT
882 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
883 UINTN DataSize;\r
884 VOID *Data;\r
885 EFI_STATUS Status;\r
a3bcde70
HT
886 EFI_IP6_CONFIG_POLICY Policy;\r
887 EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS DadXmits;\r
888 EFI_HII_HANDLE HiiHandle;\r
889\r
890 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
891 return EFI_INVALID_PARAMETER;\r
892 }\r
893\r
894 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
895\r
896 Ip6Config = &Instance->Ip6Config;\r
0b2a54e2 897 Ip6NvData = &Instance->Ip6NvData;\r
a3bcde70
HT
898 Data = NULL;\r
899 DataSize = 0;\r
900 HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
901\r
902 //\r
903 // Get the current interface info.\r
904 //\r
905 Status = Ip6ConfigNvGetData (\r
906 Ip6Config,\r
907 Ip6ConfigDataTypeInterfaceInfo,\r
908 &DataSize,\r
909 (VOID **) &Data\r
910 );\r
911 if (EFI_ERROR (Status)) {\r
912 goto Exit;\r
913 }\r
914\r
915 //\r
916 // Convert the interface info to string and print.\r
917 //\r
918 Status = Ip6ConvertInterfaceInfoToString (\r
919 (EFI_IP6_CONFIG_INTERFACE_INFO *) Data,\r
920 HiiHandle,\r
921 IfrNvData\r
922 );\r
923 if (EFI_ERROR (Status)) {\r
924 goto Exit;\r
925 }\r
926\r
927 //\r
928 // Get the interface id.\r
929 //\r
930 DataSize = sizeof (EFI_IP6_CONFIG_INTERFACE_ID);\r
0b2a54e2 931 ZeroMem (&Ip6NvData->InterfaceId, DataSize);\r
a3bcde70
HT
932 Status = Ip6Config->GetData (\r
933 Ip6Config,\r
934 Ip6ConfigDataTypeAltInterfaceId,\r
935 &DataSize,\r
0b2a54e2 936 &Ip6NvData->InterfaceId\r
a3bcde70
HT
937 );\r
938 if (EFI_ERROR (Status)) {\r
939 goto Exit;\r
940 }\r
941\r
0b2a54e2 942 Ip6ConvertInterfaceIdToString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
a3bcde70
HT
943\r
944 //\r
945 // Get current policy.\r
946 //\r
947 DataSize = sizeof (EFI_IP6_CONFIG_POLICY);\r
948 Status = Ip6Config->GetData (\r
949 Ip6Config,\r
950 Ip6ConfigDataTypePolicy,\r
951 &DataSize,\r
952 &Policy\r
953 );\r
954\r
955 if (EFI_ERROR (Status)) {\r
956 goto Exit;\r
957 }\r
958\r
959 if (Policy == Ip6ConfigPolicyManual) {\r
960 IfrNvData->Policy = IP6_POLICY_MANUAL;\r
961 } else if (Policy == Ip6ConfigPolicyAutomatic) {\r
962 IfrNvData->Policy = IP6_POLICY_AUTO;\r
963 } else {\r
964 ASSERT (FALSE);\r
965 Status = EFI_UNSUPPORTED;\r
966 goto Exit;\r
967 }\r
968\r
969 //\r
970 // Get Duplicate Address Detection Transmits count.\r
971 //\r
972 DataSize = sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS);\r
973 Status = Ip6Config->GetData (\r
974 Ip6Config,\r
975 Ip6ConfigDataTypeDupAddrDetectTransmits,\r
976 &DataSize,\r
977 &DadXmits\r
978 );\r
979\r
980 if (EFI_ERROR (Status)) {\r
981 goto Exit;\r
982 }\r
983\r
984 IfrNvData->DadTransmitCount = DadXmits.DupAddrDetectTransmits;\r
985\r
a3bcde70
HT
986Exit:\r
987 if (Data != NULL) {\r
988 FreePool (Data);\r
989 }\r
990\r
991 return Status;\r
992}\r
993\r
994/**\r
995 Convert IFR data into IP6 configuration data. The policy, alternative interface\r
130df890 996 ID, and DAD transmit counts, and will be saved. \r
a3bcde70
HT
997\r
998 @param[in] IfrNvData The IFR NV data.\r
999 @param[in, out] Instance The IP6 config instance data.\r
1000\r
1001 @retval EFI_SUCCESS The operation finished successfully.\r
1002 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1003 @retval Others Other errors as indicated.\r
1004\r
1005**/\r
1006EFI_STATUS\r
130df890 1007Ip6ConvertIfrNvDataToConfigNvDataGeneral (\r
a3bcde70
HT
1008 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,\r
1009 IN OUT IP6_CONFIG_INSTANCE *Instance\r
1010 )\r
1011{\r
1012 IP6_CONFIG_NVDATA *Ip6NvData;\r
1013 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
1014 EFI_STATUS Status;\r
a3bcde70
HT
1015\r
1016 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
1017 return EFI_INVALID_PARAMETER;\r
1018 }\r
1019\r
1020 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
1021 Ip6NvData = &Instance->Ip6NvData;\r
1022 Ip6Config = &Instance->Ip6Config;\r
1023\r
1024 //\r
1025 // Update those fields which don't have INTERACTIVE attribute.\r
1026 //\r
1027 if (IfrNvData->Policy == IP6_POLICY_AUTO) {\r
1028 Ip6NvData->Policy = Ip6ConfigPolicyAutomatic;\r
1029 } else if (IfrNvData->Policy == IP6_POLICY_MANUAL) {\r
1030 Ip6NvData->Policy = Ip6ConfigPolicyManual;\r
1031 }\r
1032\r
1033 Ip6NvData->DadTransmitCount.DupAddrDetectTransmits = IfrNvData->DadTransmitCount;\r
1034\r
1035 //\r
1036 // Set the configured policy.\r
1037 //\r
1038 Status = Ip6Config->SetData (\r
1039 Ip6Config,\r
1040 Ip6ConfigDataTypePolicy,\r
1041 sizeof (EFI_IP6_CONFIG_POLICY),\r
1042 &Ip6NvData->Policy\r
1043 );\r
1044 if (EFI_ERROR (Status)) {\r
1045 return Status;\r
1046 }\r
1047\r
1048 //\r
1049 // Set the duplicate address detection transmits count.\r
1050 //\r
1051 Status = Ip6Config->SetData (\r
1052 Ip6Config,\r
1053 Ip6ConfigDataTypeDupAddrDetectTransmits,\r
1054 sizeof (EFI_IP6_CONFIG_DUP_ADDR_DETECT_TRANSMITS),\r
1055 &Ip6NvData->DadTransmitCount\r
1056 );\r
1057 if (EFI_ERROR (Status)) {\r
1058 return Status;\r
1059 }\r
1060\r
1061 //\r
1062 // Set the alternative interface ID\r
1063 //\r
1064 Status = Ip6Config->SetData (\r
1065 Ip6Config,\r
1066 Ip6ConfigDataTypeAltInterfaceId,\r
1067 sizeof (EFI_IP6_CONFIG_INTERFACE_ID),\r
1068 &Ip6NvData->InterfaceId\r
1069 );\r
1070 if (EFI_ERROR (Status)) {\r
1071 return Status;\r
1072 }\r
1073\r
130df890 1074 return EFI_SUCCESS;\r
1075}\r
1076\r
1077/**\r
1078 Convert IFR data into IP6 configuration data. The policy, configured\r
1079 manual address, gateway address, and DNS server address will be saved.\r
1080\r
1081 @param[in] IfrNvData The IFR NV data.\r
1082 @param[in, out] Instance The IP6 config instance data.\r
1083\r
1084 @retval EFI_SUCCESS The operation finished successfully.\r
1085 @retval EFI_INVALID_PARAMETER Any input parameter is invalid.\r
1086 @retval Others Other errors as indicated.\r
1087\r
1088**/\r
1089EFI_STATUS\r
1090Ip6ConvertIfrNvDataToConfigNvDataAdvanced (\r
1091 IN IP6_CONFIG_IFR_NVDATA *IfrNvData,\r
1092 IN OUT IP6_CONFIG_INSTANCE *Instance\r
1093 )\r
1094{\r
1095 IP6_CONFIG_NVDATA *Ip6NvData;\r
1096 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
1097 EFI_STATUS Status;\r
1098 EFI_IP6_CONFIG_MANUAL_ADDRESS *ManualAddress;\r
1099 EFI_IPv6_ADDRESS *Address;\r
1100 BOOLEAN IsAddressOk;\r
1101 EFI_EVENT SetAddressEvent;\r
1102 EFI_EVENT TimeoutEvent;\r
1103 UINTN DataSize;\r
1104\r
1105 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
1106 return EFI_INVALID_PARAMETER;\r
1107 }\r
a3bcde70 1108\r
130df890 1109 if (IfrNvData->Policy == IP6_POLICY_AUTO) {\r
a3bcde70
HT
1110 return EFI_SUCCESS;\r
1111 }\r
1112\r
130df890 1113 NET_CHECK_SIGNATURE (Instance, IP6_CONFIG_INSTANCE_SIGNATURE);\r
1114 Ip6NvData = &Instance->Ip6NvData;\r
1115 Ip6Config = &Instance->Ip6Config;\r
1116\r
1117 //\r
1118 // Update those fields which don't have INTERACTIVE attribute.\r
1119 //\r
1120 Ip6NvData->Policy = Ip6ConfigPolicyManual;\r
1121\r
1122 //\r
1123 // Set the configured policy.\r
1124 //\r
1125 Status = Ip6Config->SetData (\r
1126 Ip6Config,\r
1127 Ip6ConfigDataTypePolicy,\r
1128 sizeof (EFI_IP6_CONFIG_POLICY),\r
1129 &Ip6NvData->Policy\r
1130 );\r
1131 if (EFI_ERROR (Status)) {\r
1132 return Status;\r
1133 }\r
1134\r
a3bcde70
HT
1135 //\r
1136 // Create events & timers for asynchronous settings.\r
1137 //\r
1138 SetAddressEvent = NULL;\r
1139 TimeoutEvent = NULL;\r
1140 ManualAddress = NULL;\r
1141 Address = NULL;\r
1142\r
1143 Status = gBS->CreateEvent (\r
1144 EVT_NOTIFY_SIGNAL,\r
1145 TPL_NOTIFY,\r
1146 Ip6ConfigManualAddressNotify,\r
1147 &IsAddressOk,\r
1148 &SetAddressEvent\r
1149 );\r
1150 if (EFI_ERROR (Status)) {\r
1151 goto Exit;\r
1152 }\r
1153\r
1154 Status = gBS->CreateEvent (\r
1155 EVT_TIMER,\r
1156 TPL_CALLBACK,\r
1157 NULL,\r
1158 NULL,\r
1159 &TimeoutEvent\r
1160 );\r
1161 if (EFI_ERROR (Status)) {\r
1162 goto Exit;\r
1163 }\r
1164\r
1165 //\r
1166 // Set the manual address list. This is an asynchronous process.\r
1167 //\r
1168 if (!IsListEmpty (&Ip6NvData->ManualAddress) && (Ip6NvData->ManualAddressCount != 0)) {\r
1169 Status = Ip6BuildNvAddressInfo (\r
1170 Instance,\r
1171 Ip6ConfigNvHostAddress,\r
1172 (VOID **) &ManualAddress,\r
1173 &DataSize\r
1174 );\r
1175 if (EFI_ERROR (Status)) {\r
1176 goto Exit;\r
1177 }\r
1178\r
1179 IsAddressOk = FALSE;\r
1180\r
1181 Status = Ip6Config->RegisterDataNotify (\r
1182 Ip6Config,\r
1183 Ip6ConfigDataTypeManualAddress,\r
1184 SetAddressEvent\r
1185 );\r
1186 if (EFI_ERROR (Status)) {\r
1187 goto Exit;\r
1188 }\r
1189\r
1190 Status = Ip6Config->SetData (\r
1191 Ip6Config,\r
1192 Ip6ConfigDataTypeManualAddress,\r
1193 DataSize,\r
1194 (VOID *) ManualAddress\r
1195 );\r
1196 if (Status == EFI_NOT_READY) {\r
1197 gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);\r
1198 while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
1199 if (IsAddressOk) {\r
1200 Status = EFI_SUCCESS;\r
1201 }\r
1202 break;\r
1203 }\r
1204 }\r
1205\r
1206 Status = Ip6Config->UnregisterDataNotify (\r
1207 Ip6Config,\r
1208 Ip6ConfigDataTypeManualAddress,\r
1209 SetAddressEvent\r
1210 );\r
1211 if (EFI_ERROR (Status)) {\r
1212 goto Exit;\r
1213 }\r
1214 }\r
1215\r
1216 //\r
1217 // Set gateway address list.\r
1218 //\r
1219 if (!IsListEmpty (&Ip6NvData->GatewayAddress) && (Ip6NvData->GatewayAddressCount != 0)) {\r
1220 Status = Ip6BuildNvAddressInfo (\r
1221 Instance,\r
1222 Ip6ConfigNvGatewayAddress,\r
1223 (VOID **) &Address,\r
1224 &DataSize\r
1225 );\r
1226 if (EFI_ERROR (Status)) {\r
1227 goto Exit;\r
1228 }\r
1229\r
1230 Status = Ip6Config->SetData (\r
1231 Ip6Config,\r
1232 Ip6ConfigDataTypeGateway,\r
1233 DataSize,\r
1234 (VOID *) Address\r
1235 );\r
1236 if (EFI_ERROR (Status)) {\r
1237 goto Exit;\r
1238 }\r
1239\r
1240 FreePool (Address);\r
1241 Address = NULL;\r
1242 }\r
1243\r
1244 //\r
1245 // Set DNS server address list.\r
1246 //\r
1247 if (!IsListEmpty (&Ip6NvData->DnsAddress) && (Ip6NvData->DnsAddressCount != 0)) {\r
1248 Status = Ip6BuildNvAddressInfo (\r
1249 Instance,\r
1250 Ip6ConfigNvDnsAddress,\r
1251 (VOID **) &Address,\r
1252 &DataSize\r
1253 );\r
1254 if (EFI_ERROR (Status)) {\r
1255 goto Exit;\r
1256 }\r
1257\r
1258 Status = Ip6Config->SetData (\r
1259 Ip6Config,\r
1260 Ip6ConfigDataTypeDnsServer,\r
1261 DataSize,\r
1262 (VOID *) Address\r
1263 );\r
1264 if (EFI_ERROR (Status)) {\r
1265 goto Exit;\r
1266 }\r
1267 }\r
1268\r
1269 Status = EFI_SUCCESS;\r
1270\r
1271Exit:\r
1272 if (SetAddressEvent != NULL) {\r
1273 gBS->CloseEvent (SetAddressEvent);\r
1274 }\r
1275\r
1276 if (TimeoutEvent != NULL) {\r
1277 gBS->CloseEvent (TimeoutEvent);\r
1278 }\r
1279\r
1280 if (ManualAddress != NULL) {\r
1281 FreePool (ManualAddress);\r
1282 }\r
1283\r
1284 if (Address != NULL) {\r
1285 FreePool (Address);\r
1286 }\r
1287\r
1288 return Status;\r
1289}\r
1290\r
130df890 1291\r
a3bcde70
HT
1292/**\r
1293 This function allows the caller to request the current\r
1294 configuration for one or more named elements. The resulting\r
1295 string is in <ConfigAltResp> format. Any and all alternative\r
1296 configuration strings shall also be appended to the end of the\r
1297 current configuration string. If they are, they must appear\r
1298 after the current configuration. They must contain the same\r
1299 routing (GUID, NAME, PATH) as the current configuration string.\r
1300 They must have an additional description indicating the type of\r
1301 alternative configuration the string represents,\r
1302 "ALTCFG=<StringToken>". That <StringToken> (when\r
1303 converted from Hex UNICODE to binary) is a reference to a\r
1304 string in the associated string pack.\r
1305\r
1306 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1307 @param[in] Request A null-terminated Unicode string in\r
1308 <ConfigRequest> format. Note that this\r
1309 includes the routing information as well as\r
1310 the configurable name / value pairs. It is\r
1311 invalid for this string to be in\r
1312 <MultiConfigRequest> format.\r
1313 @param[out] Progress On return, points to a character in the\r
1314 Request string. Points to the string's null\r
1315 terminator if request was successful. Points\r
1316 to the most recent "&" before the first\r
1317 failing name / value pair (or the beginning\r
1318 of the string if the failure is in the first\r
1319 name / value pair) if the request was not\r
1320 successful.\r
1321 @param[out] Results A null-terminated Unicode string in\r
1322 <ConfigAltResp> format which has all values\r
1323 filled in for the names in the Request string.\r
1324 String to be allocated by the called function.\r
1325\r
1326 @retval EFI_SUCCESS The Results string is filled with the\r
1327 values corresponding to all requested\r
1328 names.\r
1329 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
1330 parts of the results that must be\r
1331 stored awaiting possible future\r
1332 protocols.\r
1333 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
1334 for the Request parameter\r
1335 would result in this type of\r
1336 error. In this case, the\r
1337 Progress parameter would be\r
1338 set to NULL.\r
1339 @retval EFI_NOT_FOUND Routing data doesn't match any\r
1340 known driver. Progress set to the\r
1341 first character in the routing header.\r
1342 Note: There is no requirement that the\r
1343 driver validate the routing data. It\r
1344 must skip the <ConfigHdr> in order to\r
1345 process the names.\r
1346 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
1347 to most recent & before the\r
1348 error or the beginning of the\r
1349 string.\r
1350 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
1351 to the & before the name in\r
1352 question. Currently not implemented.\r
1353**/\r
1354EFI_STATUS\r
1355EFIAPI\r
1356Ip6FormExtractConfig (\r
1357 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1358 IN CONST EFI_STRING Request,\r
1359 OUT EFI_STRING *Progress,\r
1360 OUT EFI_STRING *Results\r
1361 )\r
1362{\r
1363\r
1364 EFI_STATUS Status;\r
1365 IP6_FORM_CALLBACK_INFO *Private;\r
1366 IP6_CONFIG_INSTANCE *Ip6ConfigInstance;\r
1367 IP6_CONFIG_IFR_NVDATA *IfrNvData;\r
1368 EFI_STRING ConfigRequestHdr;\r
1369 EFI_STRING ConfigRequest;\r
1370 BOOLEAN AllocatedRequest;\r
1371 UINTN Size;\r
1372 UINTN BufferSize;\r
1373\r
1374 if (This == NULL || Progress == NULL || Results == NULL) {\r
1375 return EFI_INVALID_PARAMETER;\r
1376 }\r
1377\r
1378 *Progress = Request;\r
1379 if ((Request != NULL) &&\r
9bdc6592 1380 !HiiIsConfigHdrMatch (Request, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {\r
a3bcde70
HT
1381 return EFI_NOT_FOUND;\r
1382 }\r
1383\r
1384 ConfigRequestHdr = NULL;\r
1385 ConfigRequest = NULL;\r
1386 AllocatedRequest = FALSE;\r
1387 Size = 0;\r
1388\r
1389 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
1390 Ip6ConfigInstance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);\r
1391 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
1392\r
1393 IfrNvData = (IP6_CONFIG_IFR_NVDATA *) AllocateZeroPool (BufferSize);\r
1394 if (IfrNvData == NULL) {\r
1395 return EFI_OUT_OF_RESOURCES;\r
1396 }\r
1397\r
1398 Status = Ip6ConvertConfigNvDataToIfrNvData (IfrNvData, Ip6ConfigInstance);\r
1399 if (EFI_ERROR (Status)) {\r
1400 goto Exit;\r
1401 }\r
1402\r
1403 ConfigRequest = Request;\r
1404 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
1405 //\r
1406 // Request has no request element, construct full request string.\r
1407 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
1408 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator.\r
1409 //\r
1410 ConfigRequestHdr = HiiConstructConfigHdr (\r
9bdc6592 1411 &gIp6ConfigNvDataGuid,\r
a3bcde70
HT
1412 mIp6ConfigStorageName,\r
1413 Private->ChildHandle\r
1414 );\r
1415 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
1416 ConfigRequest = AllocateZeroPool (Size);\r
1417 ASSERT (ConfigRequest != NULL);\r
1418 AllocatedRequest = TRUE;\r
1419 UnicodeSPrint (\r
1420 ConfigRequest,\r
1421 Size,\r
1422 L"%s&OFFSET=0&WIDTH=%016LX",\r
1423 ConfigRequestHdr,\r
1424 (UINT64) BufferSize\r
1425 );\r
1426 FreePool (ConfigRequestHdr);\r
1427 }\r
1428\r
1429 //\r
1430 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
1431 //\r
1432 Status = gHiiConfigRouting->BlockToConfig (\r
1433 gHiiConfigRouting,\r
1434 ConfigRequest,\r
1435 (UINT8 *) IfrNvData,\r
1436 BufferSize,\r
1437 Results,\r
1438 Progress\r
1439 );\r
1440\r
1441Exit:\r
1442 FreePool (IfrNvData);\r
1443 //\r
1444 // Free the allocated config request string.\r
1445 //\r
1446 if (AllocatedRequest) {\r
1447 FreePool (ConfigRequest);\r
1448 ConfigRequest = NULL;\r
1449 }\r
1450 //\r
1451 // Set Progress string to the original request string.\r
1452 //\r
1453 if (Request == NULL) {\r
1454 *Progress = NULL;\r
1455 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
1456 *Progress = Request + StrLen (Request);\r
1457 }\r
1458\r
1459 return Status;\r
1460}\r
1461\r
1462/**\r
1463 This function applies changes in a driver's configuration.\r
1464 Input is a Configuration, which has the routing data for this\r
1465 driver followed by name / value configuration pairs. The driver\r
1466 must apply those pairs to its configurable storage. If the\r
1467 driver's configuration is stored in a linear block of data\r
1468 and the driver's name / value pairs are in <BlockConfig>\r
1469 format, it may use the ConfigToBlock helper function (above) to\r
1470 simplify the job. Currently not implemented.\r
1471\r
1472 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1473 @param[in] Configuration A null-terminated Unicode string in\r
1474 <ConfigString> format.\r
1475 @param[out] Progress A pointer to a string filled in with the\r
1476 offset of the most recent '&' before the\r
1477 first failing name / value pair (or the\r
1478 beginn ing of the string if the failure\r
1479 is in the first name / value pair) or\r
1480 the terminating NULL if all was\r
1481 successful.\r
1482\r
1483 @retval EFI_SUCCESS The results have been distributed or are\r
1484 awaiting distribution.\r
1485 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
1486 parts of the results that must be\r
1487 stored awaiting possible future\r
1488 protocols.\r
1489 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
1490 Results parameter would result\r
1491 in this type of error.\r
1492 @retval EFI_NOT_FOUND Target for the specified routing data\r
1493 was not found.\r
1494**/\r
1495EFI_STATUS\r
1496EFIAPI\r
1497Ip6FormRouteConfig (\r
1498 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1499 IN CONST EFI_STRING Configuration,\r
1500 OUT EFI_STRING *Progress\r
1501 )\r
1502{\r
1503 if (This == NULL || Configuration == NULL || Progress == NULL) {\r
1504 return EFI_INVALID_PARAMETER;\r
1505 }\r
1506\r
1507 //\r
1508 // Check routing data in <ConfigHdr>.\r
1509 // Note: if only one Storage is used, then this checking could be skipped.\r
1510 //\r
9bdc6592 1511 if (!HiiIsConfigHdrMatch (Configuration, &gIp6ConfigNvDataGuid, mIp6ConfigStorageName)) {\r
a3bcde70
HT
1512 *Progress = Configuration;\r
1513 return EFI_NOT_FOUND;\r
1514 }\r
1515\r
1516 *Progress = Configuration + StrLen (Configuration);\r
1517\r
1518 return EFI_SUCCESS;\r
1519}\r
1520\r
130df890 1521/**\r
1522 Display host addresses, route table, DNS addresses and gateway addresses in\r
1523 "IPv6 Current Setting" page.\r
1524\r
1525 @param[in] Instance The IP6 config instance data.\r
1526\r
1527 @retval EFI_SUCCESS The operation finished successfully.\r
1528 @retval Others Other errors as indicated.\r
1529\r
1530**/\r
1531EFI_STATUS\r
1532Ip6GetCurrentSetting (\r
1533 IN IP6_CONFIG_INSTANCE *Instance\r
1534 )\r
1535{\r
1536 EFI_IP6_CONFIG_PROTOCOL *Ip6Config;\r
1537 EFI_HII_HANDLE HiiHandle;\r
1538 EFI_IP6_CONFIG_INTERFACE_INFO *Data;\r
1539 UINTN DataSize;\r
1540 EFI_STATUS Status;\r
1541 CHAR16 PortString[ADDRESS_STR_MAX_SIZE];\r
1542 EFI_IP6_CONFIG_INTERFACE_INFO *IfInfo;\r
1543 \r
1544\r
1545 Ip6Config = &Instance->Ip6Config;\r
1546 HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
1547 Data = NULL;\r
1548\r
1549 //\r
1550 // Get current interface info.\r
1551 //\r
1552 Status = Ip6ConfigNvGetData (\r
1553 Ip6Config,\r
1554 Ip6ConfigDataTypeInterfaceInfo,\r
1555 &DataSize,\r
1556 (VOID **) &Data\r
1557 );\r
1558 if (EFI_ERROR (Status)) {\r
1559 return Status;\r
1560 }\r
1561\r
1562 //\r
1563 // Generate dynamic text opcode for host address and draw it.\r
1564 //\r
1565 IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data;\r
1566 Status = Ip6ConvertAddressListToString (\r
1567 PortString,\r
1568 HiiHandle,\r
1569 Ip6ConfigNvHostAddress,\r
1570 IfInfo->AddressInfo,\r
1571 IfInfo->AddressInfoCount\r
1572 );\r
1573 if (EFI_ERROR (Status)) {\r
1574 FreePool (Data);\r
1575 return Status;\r
1576 }\r
1577\r
1578 //\r
1579 // Generate the dynamic text opcode for route table and draw it.\r
1580 //\r
1581 Status = Ip6ConvertAddressListToString (\r
1582 PortString,\r
1583 HiiHandle,\r
1584 Ip6ConfigNvRouteTable,\r
1585 IfInfo->RouteTable,\r
1586 IfInfo->RouteCount\r
1587 );\r
1588 if (EFI_ERROR (Status)) {\r
1589 FreePool (Data);\r
1590 return Status;\r
1591 }\r
1592\r
1593 //\r
1594 // Get DNS server list.\r
1595 //\r
1596 FreePool (Data);\r
1597 DataSize = 0;\r
1598 Data = NULL;\r
1599 Status = Ip6ConfigNvGetData (\r
1600 Ip6Config,\r
1601 Ip6ConfigDataTypeDnsServer,\r
1602 &DataSize,\r
1603 (VOID **) &Data\r
1604 );\r
1605 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
1606 if (Data != NULL) {\r
1607 FreePool (Data);\r
1608 }\r
1609 return Status;\r
1610 }\r
1611\r
1612 if (DataSize > 0) {\r
1613 //\r
1614 // Generate the dynamic text opcode for DNS server and draw it.\r
1615 //\r
1616 Status = Ip6ConvertAddressListToString (\r
1617 PortString,\r
1618 HiiHandle,\r
1619 Ip6ConfigNvDnsAddress,\r
1620 Data,\r
1621 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
1622 );\r
1623 if (EFI_ERROR (Status)) {\r
1624 FreePool (Data);\r
1625 return Status;\r
1626 }\r
1627 }\r
1628\r
1629 //\r
1630 // Get gateway adderss list.\r
1631 //\r
1632 if (Data != NULL) {\r
1633 FreePool (Data);\r
1634 }\r
1635\r
1636 DataSize = 0;\r
1637 Data = NULL;\r
1638 Status = Ip6ConfigNvGetData (\r
1639 Ip6Config,\r
1640 Ip6ConfigDataTypeGateway,\r
1641 &DataSize,\r
1642 (VOID **) &Data\r
1643 );\r
1644 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
1645 if (Data != NULL) {\r
1646 FreePool (Data);\r
1647 }\r
1648 return Status;\r
1649 }\r
1650\r
1651 if (DataSize > 0) {\r
1652 //\r
1653 // Generate the dynamic text opcode for gateway and draw it.\r
1654 //\r
1655 Status = Ip6ConvertAddressListToString (\r
1656 PortString,\r
1657 HiiHandle,\r
1658 Ip6ConfigNvGatewayAddress,\r
1659 Data,\r
1660 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
1661 );\r
1662 if (EFI_ERROR (Status)) {\r
1663 FreePool (Data);\r
1664 return Status;\r
1665 }\r
1666 }\r
1667\r
1668 if (Data != NULL) {\r
1669 FreePool (Data);\r
1670 }\r
1671\r
1672 return EFI_SUCCESS;\r
1673}\r
1674\r
a3bcde70
HT
1675/**\r
1676 This function is called to provide results data to the driver.\r
1677 This data consists of a unique key that is used to identify\r
1678 which data is either being passed back or being asked for.\r
1679\r
1680 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1681 @param[in] Action Specifies the type of action taken by the browser.\r
1682 @param[in] QuestionId A unique value which is sent to the original\r
1683 exporting driver so that it can identify the type\r
1684 of data to expect. The format of the data tends to\r
1685 vary based on the opcode that generated the callback.\r
1686 @param[in] Type The type of value for the question.\r
1687 @param[in] Value A pointer to the data being sent to the original\r
1688 exporting driver.\r
1689 @param[out] ActionRequest On return, points to the action requested by the\r
1690 callback function.\r
1691\r
1692 @retval EFI_SUCCESS The callback successfully handled the action.\r
1693 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
1694 variable and its data.\r
1695 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1696 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
1697 callback. Currently not implemented.\r
1698 @retval EFI_INVALID_PARAMETER Passed in the wrong parameter.\r
1699 @retval Others Other errors as indicated.\r
1700\r
1701**/\r
1702EFI_STATUS\r
1703EFIAPI\r
1704Ip6FormCallback (\r
1705 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1706 IN EFI_BROWSER_ACTION Action,\r
1707 IN EFI_QUESTION_ID QuestionId,\r
1708 IN UINT8 Type,\r
1709 IN EFI_IFR_TYPE_VALUE *Value,\r
1710 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
1711 )\r
1712{\r
1713 IP6_FORM_CALLBACK_INFO *Private;\r
1714 UINTN BufferSize;\r
1715 IP6_CONFIG_IFR_NVDATA *IfrNvData;\r
a3bcde70
HT
1716 EFI_STATUS Status;\r
1717 EFI_INPUT_KEY Key;\r
1718 IP6_CONFIG_INSTANCE *Instance;\r
1719 IP6_CONFIG_NVDATA *Ip6NvData;\r
a3bcde70
HT
1720\r
1721 if (This == NULL) {\r
1722 return EFI_INVALID_PARAMETER;\r
1723 }\r
1724\r
1725 Private = IP6_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
1726 Instance = IP6_CONFIG_INSTANCE_FROM_FORM_CALLBACK (Private);\r
1727 Ip6NvData = &Instance->Ip6NvData;\r
1728\r
e0afa489 1729 if ((Action == EFI_BROWSER_ACTION_FORM_OPEN) || (Action == EFI_BROWSER_ACTION_FORM_CLOSE)){\r
1730 return EFI_SUCCESS;\r
1731 }\r
1732\r
639a76d1 1733 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
e0afa489 1734 return EFI_UNSUPPORTED;\r
1735 }\r
1736\r
1737 if ((Value == NULL) || (ActionRequest == NULL)) {\r
1738 return EFI_INVALID_PARAMETER;\r
1739 }\r
1740\r
1741 //\r
1742 // Retrieve uncommitted data from Browser\r
1743 //\r
1744\r
1745 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
1746 IfrNvData = AllocateZeroPool (BufferSize);\r
1747 if (IfrNvData == NULL) {\r
1748 return EFI_OUT_OF_RESOURCES;\r
1749 }\r
1750\r
1751 Status = EFI_SUCCESS;\r
1752\r
e0afa489 1753 HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);\r
1754\r
639a76d1
ED
1755 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
1756 switch (QuestionId) {\r
1757 case KEY_GET_CURRENT_SETTING:\r
130df890 1758 Status = Ip6GetCurrentSetting (Instance);\r
639a76d1
ED
1759 break;\r
1760\r
1761 default:\r
1762 break;\r
2d4df339 1763 }\r
639a76d1
ED
1764 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
1765 switch (QuestionId) {\r
1766 case KEY_SAVE_CONFIG_CHANGES:\r
130df890 1767 Status = Ip6ConvertIfrNvDataToConfigNvDataAdvanced (IfrNvData, Instance);\r
1768 if (EFI_ERROR (Status)) {\r
1769 break;\r
1770 }\r
1771\r
1772 Status = Ip6GetCurrentSetting (Instance);\r
1773\r
639a76d1
ED
1774 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
1775 break;\r
a3bcde70 1776\r
639a76d1 1777 case KEY_IGNORE_CONFIG_CHANGES:\r
0b2a54e2 1778 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);\r
1779 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);\r
1780 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);\r
1781\r
1782 Ip6NvData->ManualAddressCount = 0;\r
1783 Ip6NvData->GatewayAddressCount = 0;\r
1784 Ip6NvData->DnsAddressCount = 0;\r
1785\r
639a76d1
ED
1786 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
1787 break;\r
a3bcde70 1788\r
639a76d1 1789 case KEY_SAVE_CHANGES:\r
130df890 1790 Status = Ip6ConvertIfrNvDataToConfigNvDataGeneral (IfrNvData, Instance);\r
639a76d1
ED
1791 if (EFI_ERROR (Status)) {\r
1792 break;\r
1793 }\r
1794 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1795 break;\r
1796 \r
1797 case KEY_INTERFACE_ID:\r
1798 Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
1799 if (EFI_ERROR (Status)) {\r
1800 CreatePopUp (\r
1801 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1802 &Key,\r
1803 L"Invalid Interface ID!",\r
1804 NULL\r
1805 );\r
1806 }\r
1807 \r
1808 break;\r
1809 \r
1810 case KEY_MANUAL_ADDRESS:\r
1811 Status = Ip6ParseAddressListFromString (\r
1812 IfrNvData->ManualAddress,\r
1813 &Ip6NvData->ManualAddress,\r
1814 &Ip6NvData->ManualAddressCount\r
1815 );\r
1816 if (EFI_ERROR (Status)) {\r
1817 CreatePopUp (\r
1818 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1819 &Key,\r
1820 L"Invalid Host Addresses!",\r
1821 NULL\r
1822 );\r
1823 }\r
1824 \r
1825 break;\r
1826 \r
1827 case KEY_GATEWAY_ADDRESS:\r
1828 Status = Ip6ParseAddressListFromString (\r
1829 IfrNvData->GatewayAddress,\r
1830 &Ip6NvData->GatewayAddress,\r
1831 &Ip6NvData->GatewayAddressCount\r
1832 );\r
1833 if (EFI_ERROR (Status)) {\r
1834 CreatePopUp (\r
1835 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1836 &Key,\r
1837 L"Invalid Gateway Addresses!",\r
1838 NULL\r
1839 );\r
1840 }\r
1841 \r
1842 break;\r
1843 \r
1844 case KEY_DNS_ADDRESS:\r
1845 Status = Ip6ParseAddressListFromString (\r
1846 IfrNvData->DnsAddress,\r
1847 &Ip6NvData->DnsAddress,\r
1848 &Ip6NvData->DnsAddressCount\r
1849 );\r
1850 if (EFI_ERROR (Status)) {\r
1851 CreatePopUp (\r
1852 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1853 &Key,\r
1854 L"Invalid DNS Addresses!",\r
1855 NULL\r
1856 );\r
1857 }\r
1858 \r
1859 break;\r
a3bcde70 1860\r
639a76d1
ED
1861 default:\r
1862 break;\r
1863 }\r
e0afa489 1864 }\r
a3bcde70 1865\r
e0afa489 1866 if (!EFI_ERROR (Status)) {\r
1867 //\r
1868 // Pass changed uncommitted data back to Form Browser.\r
1869 //\r
1870 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
1871 HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL);\r
a3bcde70
HT
1872 }\r
1873\r
e0afa489 1874 FreePool (IfrNvData);\r
1875 return Status;\r
a3bcde70
HT
1876}\r
1877\r
1878/**\r
1879 Install HII Config Access protocol for network device and allocate resources.\r
1880\r
1881 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.\r
1882\r
1883 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
1884 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1885 @retval Others Other errors as indicated.\r
1886\r
1887**/\r
1888EFI_STATUS\r
1889Ip6ConfigFormInit (\r
1890 IN OUT IP6_CONFIG_INSTANCE *Instance\r
1891 )\r
1892{\r
1893 EFI_STATUS Status;\r
1894 IP6_SERVICE *IpSb;\r
1895 IP6_FORM_CALLBACK_INFO *CallbackInfo;\r
1896 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
1897 VENDOR_DEVICE_PATH VendorDeviceNode;\r
1898 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
1899 CHAR16 *MacString;\r
1900 CHAR16 MenuString[128];\r
1901 CHAR16 PortString[128];\r
1902 CHAR16 *OldMenuString;\r
1903 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
1904\r
1905 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);\r
1906 ASSERT (IpSb != NULL);\r
1907\r
1908 Status = gBS->HandleProtocol (\r
1909 IpSb->Controller,\r
1910 &gEfiDevicePathProtocolGuid,\r
1911 (VOID **) &ParentDevicePath\r
1912 );\r
1913 if (EFI_ERROR (Status)) {\r
1914 return Status;\r
1915 }\r
1916\r
1917 CallbackInfo = &Instance->CallbackInfo;\r
1918 CallbackInfo->Signature = IP6_FORM_CALLBACK_INFO_SIGNATURE;\r
1919\r
1920 //\r
1921 // Construct device path node for EFI HII Config Access protocol,\r
1922 // which consists of controller physical device path and one hardware\r
1923 // vendor guid node.\r
1924 //\r
1925 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
1926 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
1927 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
1928\r
9bdc6592 1929 CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);\r
a3bcde70
HT
1930\r
1931 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
1932 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (\r
1933 ParentDevicePath,\r
1934 (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode\r
1935 );\r
1936 if (CallbackInfo->HiiVendorDevicePath == NULL) {\r
1937 Status = EFI_OUT_OF_RESOURCES;\r
1938 goto Error;\r
1939 }\r
1940\r
1941 ConfigAccess = &CallbackInfo->HiiConfigAccess;\r
1942 ConfigAccess->ExtractConfig = Ip6FormExtractConfig;\r
1943 ConfigAccess->RouteConfig = Ip6FormRouteConfig;\r
1944 ConfigAccess->Callback = Ip6FormCallback;\r
1945\r
1946 //\r
1947 // Install Device Path Protocol and Config Access protocol on new handle\r
1948 //\r
1949 Status = gBS->InstallMultipleProtocolInterfaces (\r
1950 &CallbackInfo->ChildHandle,\r
1951 &gEfiDevicePathProtocolGuid,\r
1952 CallbackInfo->HiiVendorDevicePath,\r
1953 &gEfiHiiConfigAccessProtocolGuid,\r
1954 ConfigAccess,\r
1955 NULL\r
1956 );\r
1957 if (!EFI_ERROR (Status)) {\r
1958 //\r
1959 // Open the Parent Handle for the child\r
1960 //\r
1961 Status = gBS->OpenProtocol (\r
1962 IpSb->Controller,\r
1963 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
1964 (VOID **) &MnpSb,\r
1965 IpSb->Image,\r
1966 CallbackInfo->ChildHandle,\r
1967 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1968 );\r
1969 }\r
1970\r
1971 if (EFI_ERROR (Status)) {\r
1972 goto Error;\r
1973 }\r
1974\r
1975 //\r
1976 // Publish our HII data\r
1977 //\r
1978 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
9bdc6592 1979 &gIp6ConfigNvDataGuid,\r
a3bcde70
HT
1980 CallbackInfo->ChildHandle,\r
1981 Ip6DxeStrings,\r
1982 Ip6ConfigBin,\r
1983 NULL\r
1984 );\r
1985 if (CallbackInfo->RegisteredHandle == NULL) {\r
1986 Status = EFI_OUT_OF_RESOURCES;\r
1987 goto Error;\r
1988 }\r
1989\r
1990 //\r
969ebd26 1991 // Append MAC string in the menu help string and tile help string\r
a3bcde70
HT
1992 //\r
1993 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);\r
1994 if (!EFI_ERROR (Status)) {\r
1995 OldMenuString = HiiGetString (\r
1996 CallbackInfo->RegisteredHandle,\r
e07404fe 1997 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),\r
a3bcde70
HT
1998 NULL)\r
1999 ;\r
2000 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
2001 HiiSetString (\r
2002 CallbackInfo->RegisteredHandle,\r
e07404fe 2003 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),\r
a3bcde70
HT
2004 MenuString,\r
2005 NULL\r
2006 );\r
2007 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
2008 HiiSetString (\r
2009 CallbackInfo->RegisteredHandle,\r
e07404fe 2010 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP),\r
a3bcde70
HT
2011 PortString,\r
2012 NULL\r
2013 );\r
2014\r
2015 FreePool (MacString);\r
2016 FreePool (OldMenuString);\r
2017\r
2018 InitializeListHead (&Instance->Ip6NvData.ManualAddress);\r
2019 InitializeListHead (&Instance->Ip6NvData.GatewayAddress);\r
2020 InitializeListHead (&Instance->Ip6NvData.DnsAddress);\r
2021\r
2022 return EFI_SUCCESS;\r
2023 }\r
2024\r
2025Error:\r
2026 Ip6ConfigFormUnload (Instance);\r
2027 return Status;\r
2028}\r
2029\r
2030/**\r
2031 Uninstall the HII Config Access protocol for network devices and free up the resources.\r
2032\r
2033 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.\r
2034\r
2035**/\r
2036VOID\r
2037Ip6ConfigFormUnload (\r
2038 IN OUT IP6_CONFIG_INSTANCE *Instance\r
2039 )\r
2040{\r
2041 IP6_SERVICE *IpSb;\r
2042 IP6_FORM_CALLBACK_INFO *CallbackInfo;\r
2043 IP6_CONFIG_NVDATA *Ip6NvData;\r
2044\r
2045 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);\r
2046 ASSERT (IpSb != NULL);\r
2047\r
2048 CallbackInfo = &Instance->CallbackInfo;\r
2049\r
2050 if (CallbackInfo->ChildHandle != NULL) {\r
2051\r
2052 //\r
2053 // Close the child handle\r
2054 //\r
2055 gBS->CloseProtocol (\r
2056 IpSb->Controller,\r
2057 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
2058 IpSb->Image,\r
2059 CallbackInfo->ChildHandle\r
2060 );\r
2061 //\r
2062 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
2063 //\r
2064 gBS->UninstallMultipleProtocolInterfaces (\r
2065 CallbackInfo->ChildHandle,\r
2066 &gEfiDevicePathProtocolGuid,\r
2067 CallbackInfo->HiiVendorDevicePath,\r
2068 &gEfiHiiConfigAccessProtocolGuid,\r
2069 &CallbackInfo->HiiConfigAccess,\r
2070 NULL\r
2071 );\r
2072 }\r
2073\r
2074 if (CallbackInfo->HiiVendorDevicePath != NULL) {\r
2075 FreePool (CallbackInfo->HiiVendorDevicePath);\r
2076 }\r
2077\r
2078 if (CallbackInfo->RegisteredHandle != NULL) {\r
2079 //\r
2080 // Remove HII package list\r
2081 //\r
2082 HiiRemovePackages (CallbackInfo->RegisteredHandle);\r
2083 }\r
2084\r
2085 Ip6NvData = &Instance->Ip6NvData;\r
2086\r
2087 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);\r
2088 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);\r
2089 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);\r
2090\r
2091 Ip6NvData->ManualAddressCount = 0;\r
2092 Ip6NvData->GatewayAddressCount = 0;\r
2093 Ip6NvData->DnsAddressCount = 0;\r
2094}\r