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