]> 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
1652 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {\r
1653 //\r
1654 // Update main Form when main Form is opened.\r
1655 // This will be done only in FORM_OPEN CallBack of question with KEY_INTERFACE_ID from main Form.\r
1656 //\r
1657 if (QuestionId != KEY_INTERFACE_ID) {\r
1658 return EFI_SUCCESS;\r
1659 }\r
1660\r
1661 Ip6Config = &Instance->Ip6Config;\r
1662 HiiHandle = Instance->CallbackInfo.RegisteredHandle;\r
1663\r
1664 //\r
1665 // Get the current interface info.\r
1666 //\r
1667 Status = Ip6ConfigNvGetData (\r
1668 Ip6Config,\r
1669 Ip6ConfigDataTypeInterfaceInfo,\r
1670 &DataSize,\r
1671 (VOID **) &Data\r
1672 );\r
1673 if (EFI_ERROR (Status)) {\r
1674 goto Exit;\r
1675 }\r
1676\r
1677 //\r
1678 // Generate the dynamic text opcode for host address and draw it.\r
1679 //\r
1680 IfInfo = (EFI_IP6_CONFIG_INTERFACE_INFO *) Data;\r
1681 Status = Ip6ConvertAddressListToString (\r
1682 PortString,\r
1683 HiiHandle,\r
1684 Ip6ConfigNvHostAddress,\r
1685 IfInfo->AddressInfo,\r
1686 IfInfo->AddressInfoCount\r
1687 );\r
1688 if (EFI_ERROR (Status)) {\r
1689 goto Exit;\r
1690 }\r
1691\r
1692 //\r
1693 // Generate the dynamic text opcode for route table and draw it.\r
1694 //\r
1695 Status = Ip6ConvertAddressListToString (\r
1696 PortString,\r
1697 HiiHandle,\r
1698 Ip6ConfigNvRouteTable,\r
1699 IfInfo->RouteTable,\r
1700 IfInfo->RouteCount\r
1701 );\r
1702 if (EFI_ERROR (Status)) {\r
1703 goto Exit;\r
1704 }\r
1705\r
1706 //\r
1707 // Get DNS server list.\r
1708 //\r
1709 DataSize = 0;\r
1710 Status = Ip6ConfigNvGetData (\r
1711 Ip6Config,\r
1712 Ip6ConfigDataTypeDnsServer,\r
1713 &DataSize,\r
1714 (VOID **) &Data\r
1715 );\r
1716 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
1717 goto Exit;\r
1718 }\r
1719\r
1720 if (DataSize > 0) {\r
1721 //\r
1722 // Generate the dynamic text opcode for DNS server and draw it.\r
1723 //\r
1724 Status = Ip6ConvertAddressListToString (\r
1725 PortString,\r
1726 HiiHandle,\r
1727 Ip6ConfigNvDnsAddress,\r
1728 Data,\r
1729 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
1730 );\r
1731 if (EFI_ERROR (Status)) {\r
1732 goto Exit;\r
1733 }\r
1734 }\r
1735\r
1736 //\r
1737 // Get gateway adderss list.\r
1738 //\r
1739 DataSize = 0;\r
1740 Status = Ip6ConfigNvGetData (\r
1741 Ip6Config,\r
1742 Ip6ConfigDataTypeGateway,\r
1743 &DataSize,\r
1744 (VOID **) &Data\r
1745 );\r
1746 if (EFI_ERROR (Status) && (Status != EFI_NOT_FOUND)) {\r
1747 goto Exit;\r
1748 }\r
1749\r
1750 if (DataSize > 0) {\r
1751 //\r
1752 // Generate the dynamic text opcode for gateway and draw it.\r
1753 //\r
1754 Status = Ip6ConvertAddressListToString (\r
1755 PortString,\r
1756 HiiHandle,\r
1757 Ip6ConfigNvGatewayAddress,\r
1758 Data,\r
1759 DataSize / sizeof (EFI_IPv6_ADDRESS)\r
1760 );\r
1761 if (EFI_ERROR (Status)) {\r
1762 goto Exit;\r
1763 }\r
1764 }\r
1765\r
1766Exit:\r
1767 FreePool (Data);\r
1768 return Status;\r
1769 }\r
1770\r
1771 if (Action == EFI_BROWSER_ACTION_FORM_CLOSE) {\r
1772 //\r
1773 // Do nothing for UEFI FORM_CLOSE action\r
1774 //\r
1775 return EFI_SUCCESS;\r
1776 }\r
1777\r
2d4df339
ED
1778 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
1779 if ((Value == NULL) || (ActionRequest == NULL)) {\r
1780 return EFI_INVALID_PARAMETER;\r
1781 }\r
a3bcde70 1782\r
2d4df339
ED
1783 //\r
1784 // Retrieve uncommitted data from Browser\r
1785 //\r
a3bcde70 1786\r
2d4df339
ED
1787 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
1788 IfrNvData = AllocateZeroPool (BufferSize);\r
1789 if (IfrNvData == NULL) {\r
1790 return EFI_OUT_OF_RESOURCES;\r
1791 }\r
a3bcde70 1792\r
2d4df339 1793 Status = EFI_SUCCESS;\r
a3bcde70 1794\r
2d4df339 1795 ZeroMem (&OldIfrNvData, BufferSize);\r
a3bcde70 1796\r
2d4df339 1797 HiiGetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData);\r
a3bcde70 1798\r
2d4df339 1799 CopyMem (&OldIfrNvData, IfrNvData, BufferSize);\r
a3bcde70 1800\r
2d4df339
ED
1801 switch (QuestionId) {\r
1802 case KEY_INTERFACE_ID:\r
1803 Status = Ip6ParseInterfaceIdFromString (IfrNvData->InterfaceId, &Ip6NvData->InterfaceId);\r
1804 if (EFI_ERROR (Status)) {\r
1805 CreatePopUp (\r
1806 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1807 &Key,\r
1808 L"Invalid Interface ID!",\r
1809 NULL\r
1810 );\r
1811 }\r
a3bcde70 1812\r
2d4df339 1813 break;\r
a3bcde70 1814\r
2d4df339
ED
1815 case KEY_MANUAL_ADDRESS:\r
1816 Status = Ip6ParseAddressListFromString (\r
1817 IfrNvData->ManualAddress,\r
1818 &Ip6NvData->ManualAddress,\r
1819 &Ip6NvData->ManualAddressCount\r
1820 );\r
1821 if (EFI_ERROR (Status)) {\r
1822 CreatePopUp (\r
1823 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1824 &Key,\r
1825 L"Invalid Host Addresses!",\r
1826 NULL\r
1827 );\r
1828 }\r
a3bcde70 1829\r
2d4df339 1830 break;\r
a3bcde70 1831\r
2d4df339
ED
1832 case KEY_GATEWAY_ADDRESS:\r
1833 Status = Ip6ParseAddressListFromString (\r
1834 IfrNvData->GatewayAddress,\r
1835 &Ip6NvData->GatewayAddress,\r
1836 &Ip6NvData->GatewayAddressCount\r
1837 );\r
1838 if (EFI_ERROR (Status)) {\r
1839 CreatePopUp (\r
1840 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1841 &Key,\r
1842 L"Invalid Gateway Addresses!",\r
1843 NULL\r
1844 );\r
1845 }\r
a3bcde70 1846\r
2d4df339 1847 break;\r
a3bcde70 1848\r
2d4df339
ED
1849 case KEY_DNS_ADDRESS:\r
1850 Status = Ip6ParseAddressListFromString (\r
1851 IfrNvData->DnsAddress,\r
1852 &Ip6NvData->DnsAddress,\r
1853 &Ip6NvData->DnsAddressCount\r
1854 );\r
1855 if (EFI_ERROR (Status)) {\r
1856 CreatePopUp (\r
1857 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
1858 &Key,\r
1859 L"Invalid DNS Addresses!",\r
1860 NULL\r
1861 );\r
1862 }\r
a3bcde70 1863\r
2d4df339 1864 break;\r
a3bcde70 1865\r
2d4df339
ED
1866 case KEY_SAVE_CONFIG_CHANGES:\r
1867 CopyMem (&OldIfrNvData, IfrNvData, sizeof (IP6_CONFIG_IFR_NVDATA));\r
1868 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1869 break;\r
a3bcde70 1870\r
2d4df339
ED
1871 case KEY_IGNORE_CONFIG_CHANGES:\r
1872 CopyMem (IfrNvData, &OldIfrNvData, sizeof (IP6_CONFIG_IFR_NVDATA));\r
1873 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1874 break;\r
a3bcde70 1875\r
2d4df339
ED
1876 case KEY_SAVE_CHANGES:\r
1877 Status = Ip6ConvertIfrNvDataToConfigNvData (IfrNvData, Instance);\r
1878 if (EFI_ERROR (Status)) {\r
1879 break;\r
1880 }\r
1881\r
1882 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
a3bcde70 1883 break;\r
a3bcde70 1884\r
2d4df339
ED
1885 default:\r
1886 break;\r
1887 }\r
a3bcde70 1888\r
2d4df339
ED
1889 if (!EFI_ERROR (Status)) {\r
1890 //\r
1891 // Pass changed uncommitted data back to Form Browser.\r
1892 //\r
1893 BufferSize = sizeof (IP6_CONFIG_IFR_NVDATA);\r
1894 HiiSetBrowserData (NULL, NULL, BufferSize, (UINT8 *) IfrNvData, NULL);\r
1895 }\r
a3bcde70 1896\r
2d4df339
ED
1897 FreePool (IfrNvData);\r
1898 return Status;\r
a3bcde70
HT
1899 }\r
1900\r
2d4df339
ED
1901 //\r
1902 // All other action return unsupported.\r
1903 //\r
1904 return EFI_UNSUPPORTED;\r
a3bcde70
HT
1905}\r
1906\r
1907/**\r
1908 Install HII Config Access protocol for network device and allocate resources.\r
1909\r
1910 @param[in, out] Instance The IP6_CONFIG_INSTANCE to create a form.\r
1911\r
1912 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
1913 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1914 @retval Others Other errors as indicated.\r
1915\r
1916**/\r
1917EFI_STATUS\r
1918Ip6ConfigFormInit (\r
1919 IN OUT IP6_CONFIG_INSTANCE *Instance\r
1920 )\r
1921{\r
1922 EFI_STATUS Status;\r
1923 IP6_SERVICE *IpSb;\r
1924 IP6_FORM_CALLBACK_INFO *CallbackInfo;\r
1925 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
1926 VENDOR_DEVICE_PATH VendorDeviceNode;\r
1927 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
1928 CHAR16 *MacString;\r
1929 CHAR16 MenuString[128];\r
1930 CHAR16 PortString[128];\r
1931 CHAR16 *OldMenuString;\r
1932 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
1933\r
1934 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);\r
1935 ASSERT (IpSb != NULL);\r
1936\r
1937 Status = gBS->HandleProtocol (\r
1938 IpSb->Controller,\r
1939 &gEfiDevicePathProtocolGuid,\r
1940 (VOID **) &ParentDevicePath\r
1941 );\r
1942 if (EFI_ERROR (Status)) {\r
1943 return Status;\r
1944 }\r
1945\r
1946 CallbackInfo = &Instance->CallbackInfo;\r
1947 CallbackInfo->Signature = IP6_FORM_CALLBACK_INFO_SIGNATURE;\r
1948\r
1949 //\r
1950 // Construct device path node for EFI HII Config Access protocol,\r
1951 // which consists of controller physical device path and one hardware\r
1952 // vendor guid node.\r
1953 //\r
1954 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
1955 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
1956 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
1957\r
1958 CopyGuid (&VendorDeviceNode.Guid, &mIp6HiiVendorDevicePathGuid);\r
1959\r
1960 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
1961 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (\r
1962 ParentDevicePath,\r
1963 (EFI_DEVICE_PATH_PROTOCOL *) &VendorDeviceNode\r
1964 );\r
1965 if (CallbackInfo->HiiVendorDevicePath == NULL) {\r
1966 Status = EFI_OUT_OF_RESOURCES;\r
1967 goto Error;\r
1968 }\r
1969\r
1970 ConfigAccess = &CallbackInfo->HiiConfigAccess;\r
1971 ConfigAccess->ExtractConfig = Ip6FormExtractConfig;\r
1972 ConfigAccess->RouteConfig = Ip6FormRouteConfig;\r
1973 ConfigAccess->Callback = Ip6FormCallback;\r
1974\r
1975 //\r
1976 // Install Device Path Protocol and Config Access protocol on new handle\r
1977 //\r
1978 Status = gBS->InstallMultipleProtocolInterfaces (\r
1979 &CallbackInfo->ChildHandle,\r
1980 &gEfiDevicePathProtocolGuid,\r
1981 CallbackInfo->HiiVendorDevicePath,\r
1982 &gEfiHiiConfigAccessProtocolGuid,\r
1983 ConfigAccess,\r
1984 NULL\r
1985 );\r
1986 if (!EFI_ERROR (Status)) {\r
1987 //\r
1988 // Open the Parent Handle for the child\r
1989 //\r
1990 Status = gBS->OpenProtocol (\r
1991 IpSb->Controller,\r
1992 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
1993 (VOID **) &MnpSb,\r
1994 IpSb->Image,\r
1995 CallbackInfo->ChildHandle,\r
1996 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1997 );\r
1998 }\r
1999\r
2000 if (EFI_ERROR (Status)) {\r
2001 goto Error;\r
2002 }\r
2003\r
2004 //\r
2005 // Publish our HII data\r
2006 //\r
2007 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
2008 &mIp6ConfigNvDataGuid,\r
2009 CallbackInfo->ChildHandle,\r
2010 Ip6DxeStrings,\r
2011 Ip6ConfigBin,\r
2012 NULL\r
2013 );\r
2014 if (CallbackInfo->RegisteredHandle == NULL) {\r
2015 Status = EFI_OUT_OF_RESOURCES;\r
2016 goto Error;\r
2017 }\r
2018\r
2019 //\r
969ebd26 2020 // Append MAC string in the menu help string and tile help string\r
a3bcde70
HT
2021 //\r
2022 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);\r
2023 if (!EFI_ERROR (Status)) {\r
2024 OldMenuString = HiiGetString (\r
2025 CallbackInfo->RegisteredHandle,\r
e07404fe 2026 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),\r
a3bcde70
HT
2027 NULL)\r
2028 ;\r
2029 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
2030 HiiSetString (\r
2031 CallbackInfo->RegisteredHandle,\r
e07404fe 2032 STRING_TOKEN (STR_IP6_CONFIG_FORM_HELP),\r
a3bcde70
HT
2033 MenuString,\r
2034 NULL\r
2035 );\r
2036 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
2037 HiiSetString (\r
2038 CallbackInfo->RegisteredHandle,\r
e07404fe 2039 STRING_TOKEN (STR_IP6_DEVICE_FORM_HELP),\r
a3bcde70
HT
2040 PortString,\r
2041 NULL\r
2042 );\r
2043\r
2044 FreePool (MacString);\r
2045 FreePool (OldMenuString);\r
2046\r
2047 InitializeListHead (&Instance->Ip6NvData.ManualAddress);\r
2048 InitializeListHead (&Instance->Ip6NvData.GatewayAddress);\r
2049 InitializeListHead (&Instance->Ip6NvData.DnsAddress);\r
2050\r
2051 return EFI_SUCCESS;\r
2052 }\r
2053\r
2054Error:\r
2055 Ip6ConfigFormUnload (Instance);\r
2056 return Status;\r
2057}\r
2058\r
2059/**\r
2060 Uninstall the HII Config Access protocol for network devices and free up the resources.\r
2061\r
2062 @param[in, out] Instance The IP6_CONFIG_INSTANCE to unload a form.\r
2063\r
2064**/\r
2065VOID\r
2066Ip6ConfigFormUnload (\r
2067 IN OUT IP6_CONFIG_INSTANCE *Instance\r
2068 )\r
2069{\r
2070 IP6_SERVICE *IpSb;\r
2071 IP6_FORM_CALLBACK_INFO *CallbackInfo;\r
2072 IP6_CONFIG_NVDATA *Ip6NvData;\r
2073\r
2074 IpSb = IP6_SERVICE_FROM_IP6_CONFIG_INSTANCE (Instance);\r
2075 ASSERT (IpSb != NULL);\r
2076\r
2077 CallbackInfo = &Instance->CallbackInfo;\r
2078\r
2079 if (CallbackInfo->ChildHandle != NULL) {\r
2080\r
2081 //\r
2082 // Close the child handle\r
2083 //\r
2084 gBS->CloseProtocol (\r
2085 IpSb->Controller,\r
2086 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
2087 IpSb->Image,\r
2088 CallbackInfo->ChildHandle\r
2089 );\r
2090 //\r
2091 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
2092 //\r
2093 gBS->UninstallMultipleProtocolInterfaces (\r
2094 CallbackInfo->ChildHandle,\r
2095 &gEfiDevicePathProtocolGuid,\r
2096 CallbackInfo->HiiVendorDevicePath,\r
2097 &gEfiHiiConfigAccessProtocolGuid,\r
2098 &CallbackInfo->HiiConfigAccess,\r
2099 NULL\r
2100 );\r
2101 }\r
2102\r
2103 if (CallbackInfo->HiiVendorDevicePath != NULL) {\r
2104 FreePool (CallbackInfo->HiiVendorDevicePath);\r
2105 }\r
2106\r
2107 if (CallbackInfo->RegisteredHandle != NULL) {\r
2108 //\r
2109 // Remove HII package list\r
2110 //\r
2111 HiiRemovePackages (CallbackInfo->RegisteredHandle);\r
2112 }\r
2113\r
2114 Ip6NvData = &Instance->Ip6NvData;\r
2115\r
2116 Ip6FreeAddressInfoList (&Ip6NvData->ManualAddress);\r
2117 Ip6FreeAddressInfoList (&Ip6NvData->GatewayAddress);\r
2118 Ip6FreeAddressInfoList (&Ip6NvData->DnsAddress);\r
2119\r
2120 Ip6NvData->ManualAddressCount = 0;\r
2121 Ip6NvData->GatewayAddressCount = 0;\r
2122 Ip6NvData->DnsAddressCount = 0;\r
2123}\r