]> git.proxmox.com Git - mirror_edk2.git/blame_incremental - NetworkPkg/Ip4Dxe/Ip4Config2Nv.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / Ip4Dxe / Ip4Config2Nv.c
... / ...
CommitLineData
1/** @file\r
2 Helper functions for configuring or getting the parameters relating to Ip4.\r
3\r
4Copyright (c) 2015 - 2018, Intel Corporation. All rights reserved.<BR>\r
5SPDX-License-Identifier: BSD-2-Clause-Patent\r
6\r
7**/\r
8\r
9#include "Ip4Impl.h"\r
10\r
11CHAR16 mIp4Config2StorageName[] = L"IP4_CONFIG2_IFR_NVDATA";\r
12\r
13/**\r
14 Calculate the prefix length of the IPv4 subnet mask.\r
15\r
16 @param[in] SubnetMask The IPv4 subnet mask.\r
17\r
18 @return The prefix length of the subnet mask.\r
19 @retval 0 Other errors as indicated.\r
20\r
21**/\r
22UINT8\r
23GetSubnetMaskPrefixLength (\r
24 IN EFI_IPv4_ADDRESS *SubnetMask\r
25 )\r
26{\r
27 UINT8 Len;\r
28 UINT32 ReverseMask;\r
29\r
30 //\r
31 // The SubnetMask is in network byte order.\r
32 //\r
33 ReverseMask = SwapBytes32 (*(UINT32 *)&SubnetMask[0]);\r
34\r
35 //\r
36 // Reverse it.\r
37 //\r
38 ReverseMask = ~ReverseMask;\r
39\r
40 if ((ReverseMask & (ReverseMask + 1)) != 0) {\r
41 return 0;\r
42 }\r
43\r
44 Len = 0;\r
45\r
46 while (ReverseMask != 0) {\r
47 ReverseMask = ReverseMask >> 1;\r
48 Len++;\r
49 }\r
50\r
51 return (UINT8)(32 - Len);\r
52}\r
53\r
54/**\r
55 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
56\r
57 @param[in] Str The UNICODE string.\r
58 @param[out] Ip The storage to return the IPv4 address.\r
59\r
60 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
61 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
62\r
63**/\r
64EFI_STATUS\r
65Ip4Config2StrToIp (\r
66 IN CHAR16 *Str,\r
67 OUT EFI_IPv4_ADDRESS *Ip\r
68 )\r
69{\r
70 UINTN Index;\r
71 UINTN Number;\r
72\r
73 Index = 0;\r
74\r
75 while (*Str != L'\0') {\r
76 if (Index > 3) {\r
77 return EFI_INVALID_PARAMETER;\r
78 }\r
79\r
80 Number = 0;\r
81 while ((*Str >= L'0') && (*Str <= L'9')) {\r
82 Number = Number * 10 + (*Str - L'0');\r
83 Str++;\r
84 }\r
85\r
86 if (Number > 0xFF) {\r
87 return EFI_INVALID_PARAMETER;\r
88 }\r
89\r
90 Ip->Addr[Index] = (UINT8)Number;\r
91\r
92 if ((*Str != L'\0') && (*Str != L'.')) {\r
93 //\r
94 // The current character should be either the NULL terminator or\r
95 // the dot delimiter.\r
96 //\r
97 return EFI_INVALID_PARAMETER;\r
98 }\r
99\r
100 if (*Str == L'.') {\r
101 //\r
102 // Skip the delimiter.\r
103 //\r
104 Str++;\r
105 }\r
106\r
107 Index++;\r
108 }\r
109\r
110 if (Index != 4) {\r
111 return EFI_INVALID_PARAMETER;\r
112 }\r
113\r
114 return EFI_SUCCESS;\r
115}\r
116\r
117/**\r
118 Convert the decimal dotted IPv4 addresses separated by space into the binary IPv4 address list.\r
119\r
120 @param[in] Str The UNICODE string contains IPv4 addresses.\r
121 @param[out] PtrIpList The storage to return the IPv4 address list.\r
122 @param[out] IpCount The size of the IPv4 address list.\r
123\r
124 @retval EFI_SUCCESS The binary IP address list is returned in PtrIpList.\r
125 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.\r
126 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
127\r
128**/\r
129EFI_STATUS\r
130Ip4Config2StrToIpList (\r
131 IN CHAR16 *Str,\r
132 OUT EFI_IPv4_ADDRESS **PtrIpList,\r
133 OUT UINTN *IpCount\r
134 )\r
135{\r
136 UINTN BeginIndex;\r
137 UINTN EndIndex;\r
138 UINTN Index;\r
139 UINTN IpIndex;\r
140 CHAR16 *StrTemp;\r
141 BOOLEAN SpaceTag;\r
142\r
143 BeginIndex = 0;\r
144 EndIndex = BeginIndex;\r
145 Index = 0;\r
146 IpIndex = 0;\r
147 StrTemp = NULL;\r
148 SpaceTag = TRUE;\r
149\r
150 *PtrIpList = NULL;\r
151 *IpCount = 0;\r
152\r
153 if (Str == NULL) {\r
154 return EFI_SUCCESS;\r
155 }\r
156\r
157 //\r
158 // Get the number of Ip.\r
159 //\r
160 while (*(Str + Index) != L'\0') {\r
161 if (*(Str + Index) == L' ') {\r
162 SpaceTag = TRUE;\r
163 } else {\r
164 if (SpaceTag) {\r
165 (*IpCount)++;\r
166 SpaceTag = FALSE;\r
167 }\r
168 }\r
169\r
170 Index++;\r
171 }\r
172\r
173 if (*IpCount == 0) {\r
174 return EFI_SUCCESS;\r
175 }\r
176\r
177 //\r
178 // Allocate buffer for IpList.\r
179 //\r
180 *PtrIpList = AllocateZeroPool (*IpCount * sizeof (EFI_IPv4_ADDRESS));\r
181 if (*PtrIpList == NULL) {\r
182 return EFI_OUT_OF_RESOURCES;\r
183 }\r
184\r
185 //\r
186 // Get IpList from Str.\r
187 //\r
188 Index = 0;\r
189 while (*(Str + Index) != L'\0') {\r
190 if (*(Str + Index) == L' ') {\r
191 if (!SpaceTag) {\r
192 StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));\r
193 if (StrTemp == NULL) {\r
194 FreePool (*PtrIpList);\r
195 *PtrIpList = NULL;\r
196 *IpCount = 0;\r
197 return EFI_OUT_OF_RESOURCES;\r
198 }\r
199\r
200 CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));\r
201 *(StrTemp + (EndIndex - BeginIndex)) = L'\0';\r
202\r
203 if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {\r
204 FreePool (StrTemp);\r
205 FreePool (*PtrIpList);\r
206 *PtrIpList = NULL;\r
207 *IpCount = 0;\r
208 return EFI_INVALID_PARAMETER;\r
209 }\r
210\r
211 BeginIndex = EndIndex;\r
212 IpIndex++;\r
213\r
214 FreePool (StrTemp);\r
215 }\r
216\r
217 BeginIndex++;\r
218 EndIndex++;\r
219 SpaceTag = TRUE;\r
220 } else {\r
221 EndIndex++;\r
222 SpaceTag = FALSE;\r
223 }\r
224\r
225 Index++;\r
226\r
227 if (*(Str + Index) == L'\0') {\r
228 if (!SpaceTag) {\r
229 StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));\r
230 if (StrTemp == NULL) {\r
231 FreePool (*PtrIpList);\r
232 *PtrIpList = NULL;\r
233 *IpCount = 0;\r
234 return EFI_OUT_OF_RESOURCES;\r
235 }\r
236\r
237 CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));\r
238 *(StrTemp + (EndIndex - BeginIndex)) = L'\0';\r
239\r
240 if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {\r
241 FreePool (StrTemp);\r
242 FreePool (*PtrIpList);\r
243 *PtrIpList = NULL;\r
244 *IpCount = 0;\r
245 return EFI_INVALID_PARAMETER;\r
246 }\r
247\r
248 FreePool (StrTemp);\r
249 }\r
250 }\r
251 }\r
252\r
253 return EFI_SUCCESS;\r
254}\r
255\r
256/**\r
257 Convert the IPv4 address into a dotted string.\r
258\r
259 @param[in] Ip The IPv4 address.\r
260 @param[out] Str The dotted IP string.\r
261\r
262**/\r
263VOID\r
264Ip4Config2IpToStr (\r
265 IN EFI_IPv4_ADDRESS *Ip,\r
266 OUT CHAR16 *Str\r
267 )\r
268{\r
269 UnicodeSPrint (\r
270 Str,\r
271 2 * IP4_STR_MAX_SIZE,\r
272 L"%d.%d.%d.%d",\r
273 Ip->Addr[0],\r
274 Ip->Addr[1],\r
275 Ip->Addr[2],\r
276 Ip->Addr[3]\r
277 );\r
278}\r
279\r
280/**\r
281 Convert the IPv4 address list into string consists of several decimal\r
282 dotted IPv4 addresses separated by space.\r
283\r
284 @param[in] Ip The IPv4 address list.\r
285 @param[in] IpCount The size of IPv4 address list.\r
286 @param[out] Str The string contains several decimal dotted\r
287 IPv4 addresses separated by space.\r
288\r
289 @retval EFI_SUCCESS Operation is success.\r
290 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.\r
291\r
292**/\r
293EFI_STATUS\r
294Ip4Config2IpListToStr (\r
295 IN EFI_IPv4_ADDRESS *Ip,\r
296 IN UINTN IpCount,\r
297 OUT CHAR16 *Str\r
298 )\r
299{\r
300 UINTN Index;\r
301 UINTN TemIndex;\r
302 UINTN StrIndex;\r
303 CHAR16 *TempStr;\r
304 EFI_IPv4_ADDRESS *TempIp;\r
305\r
306 Index = 0;\r
307 TemIndex = 0;\r
308 StrIndex = 0;\r
309 TempStr = NULL;\r
310 TempIp = NULL;\r
311\r
312 for (Index = 0; Index < IpCount; Index++) {\r
313 TempIp = Ip + Index;\r
314 if (TempStr == NULL) {\r
315 TempStr = AllocateZeroPool (2 * IP4_STR_MAX_SIZE);\r
316 if (TempStr == NULL) {\r
317 return EFI_OUT_OF_RESOURCES;\r
318 }\r
319 }\r
320\r
321 UnicodeSPrint (\r
322 TempStr,\r
323 2 * IP4_STR_MAX_SIZE,\r
324 L"%d.%d.%d.%d",\r
325 TempIp->Addr[0],\r
326 TempIp->Addr[1],\r
327 TempIp->Addr[2],\r
328 TempIp->Addr[3]\r
329 );\r
330\r
331 for (TemIndex = 0; TemIndex < IP4_STR_MAX_SIZE; TemIndex++) {\r
332 if (*(TempStr + TemIndex) == L'\0') {\r
333 if (Index == IpCount - 1) {\r
334 Str[StrIndex++] = L'\0';\r
335 } else {\r
336 Str[StrIndex++] = L' ';\r
337 }\r
338\r
339 break;\r
340 } else {\r
341 Str[StrIndex++] = *(TempStr + TemIndex);\r
342 }\r
343 }\r
344 }\r
345\r
346 if (TempStr != NULL) {\r
347 FreePool (TempStr);\r
348 }\r
349\r
350 return EFI_SUCCESS;\r
351}\r
352\r
353/**\r
354 The notify function of create event when performing a manual configuration.\r
355\r
356 @param[in] Event The pointer of Event.\r
357 @param[in] Context The pointer of Context.\r
358\r
359**/\r
360VOID\r
361EFIAPI\r
362Ip4Config2ManualAddressNotify (\r
363 IN EFI_EVENT Event,\r
364 IN VOID *Context\r
365 )\r
366{\r
367 *((BOOLEAN *)Context) = TRUE;\r
368}\r
369\r
370/**\r
371 Convert the network configuration data into the IFR data.\r
372\r
373 @param[in] Instance The IP4 config2 instance.\r
374 @param[in, out] IfrNvData The IFR nv data.\r
375\r
376 @retval EFI_SUCCESS The configure parameter to IFR data was\r
377 set successfully.\r
378 @retval EFI_INVALID_PARAMETER Source instance or target IFR data is not available.\r
379 @retval Others Other errors as indicated.\r
380\r
381**/\r
382EFI_STATUS\r
383Ip4Config2ConvertConfigNvDataToIfrNvData (\r
384 IN IP4_CONFIG2_INSTANCE *Instance,\r
385 IN OUT IP4_CONFIG2_IFR_NVDATA *IfrNvData\r
386 )\r
387{\r
388 IP4_SERVICE *IpSb;\r
389 EFI_IP4_CONFIG2_PROTOCOL *Ip4Config2;\r
390 EFI_IP4_CONFIG2_INTERFACE_INFO *Ip4Info;\r
391 EFI_IP4_CONFIG2_POLICY Policy;\r
392 UINTN DataSize;\r
393 UINTN GatewaySize;\r
394 EFI_IPv4_ADDRESS GatewayAddress;\r
395 EFI_STATUS Status;\r
396 UINTN DnsSize;\r
397 UINTN DnsCount;\r
398 EFI_IPv4_ADDRESS *DnsAddress;\r
399\r
400 Status = EFI_SUCCESS;\r
401 Ip4Config2 = &Instance->Ip4Config2;\r
402 Ip4Info = NULL;\r
403 DnsAddress = NULL;\r
404 GatewaySize = sizeof (EFI_IPv4_ADDRESS);\r
405\r
406 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
407 return EFI_INVALID_PARAMETER;\r
408 }\r
409\r
410 NET_CHECK_SIGNATURE (Instance, IP4_CONFIG2_INSTANCE_SIGNATURE);\r
411\r
412 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
413\r
414 if (IpSb->DefaultInterface->Configured) {\r
415 IfrNvData->Configure = 1;\r
416 } else {\r
417 IfrNvData->Configure = 0;\r
418 goto Exit;\r
419 }\r
420\r
421 //\r
422 // Get the Policy info.\r
423 //\r
424 DataSize = sizeof (EFI_IP4_CONFIG2_POLICY);\r
425 Status = Ip4Config2->GetData (\r
426 Ip4Config2,\r
427 Ip4Config2DataTypePolicy,\r
428 &DataSize,\r
429 &Policy\r
430 );\r
431 if (EFI_ERROR (Status)) {\r
432 goto Exit;\r
433 }\r
434\r
435 if (Policy == Ip4Config2PolicyStatic) {\r
436 IfrNvData->DhcpEnable = FALSE;\r
437 } else if (Policy == Ip4Config2PolicyDhcp) {\r
438 IfrNvData->DhcpEnable = TRUE;\r
439 goto Exit;\r
440 }\r
441\r
442 //\r
443 // Get the interface info.\r
444 //\r
445 DataSize = 0;\r
446 Status = Ip4Config2->GetData (\r
447 Ip4Config2,\r
448 Ip4Config2DataTypeInterfaceInfo,\r
449 &DataSize,\r
450 NULL\r
451 );\r
452 if (Status != EFI_BUFFER_TOO_SMALL) {\r
453 return Status;\r
454 }\r
455\r
456 Ip4Info = AllocateZeroPool (DataSize);\r
457 if (Ip4Info == NULL) {\r
458 Status = EFI_OUT_OF_RESOURCES;\r
459 return Status;\r
460 }\r
461\r
462 Status = Ip4Config2->GetData (\r
463 Ip4Config2,\r
464 Ip4Config2DataTypeInterfaceInfo,\r
465 &DataSize,\r
466 Ip4Info\r
467 );\r
468 if (EFI_ERROR (Status)) {\r
469 goto Exit;\r
470 }\r
471\r
472 //\r
473 // Get the Gateway info.\r
474 //\r
475 Status = Ip4Config2->GetData (\r
476 Ip4Config2,\r
477 Ip4Config2DataTypeGateway,\r
478 &GatewaySize,\r
479 &GatewayAddress\r
480 );\r
481 if (EFI_ERROR (Status)) {\r
482 goto Exit;\r
483 }\r
484\r
485 //\r
486 // Get the Dns info.\r
487 //\r
488 DnsSize = 0;\r
489 Status = Ip4Config2->GetData (\r
490 Ip4Config2,\r
491 Ip4Config2DataTypeDnsServer,\r
492 &DnsSize,\r
493 NULL\r
494 );\r
495 if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {\r
496 goto Exit;\r
497 }\r
498\r
499 DnsCount = (UINT32)(DnsSize / sizeof (EFI_IPv4_ADDRESS));\r
500\r
501 if (DnsSize > 0) {\r
502 DnsAddress = AllocateZeroPool (DnsSize);\r
503 if (DnsAddress == NULL) {\r
504 Status = EFI_OUT_OF_RESOURCES;\r
505 goto Exit;\r
506 }\r
507\r
508 Status = Ip4Config2->GetData (\r
509 Ip4Config2,\r
510 Ip4Config2DataTypeDnsServer,\r
511 &DnsSize,\r
512 DnsAddress\r
513 );\r
514 if (EFI_ERROR (Status)) {\r
515 goto Exit;\r
516 }\r
517 }\r
518\r
519 Ip4Config2IpToStr (&Ip4Info->StationAddress, IfrNvData->StationAddress);\r
520 Ip4Config2IpToStr (&Ip4Info->SubnetMask, IfrNvData->SubnetMask);\r
521 Ip4Config2IpToStr (&GatewayAddress, IfrNvData->GatewayAddress);\r
522 Status = Ip4Config2IpListToStr (DnsAddress, DnsCount, IfrNvData->DnsAddress);\r
523\r
524Exit:\r
525\r
526 if (DnsAddress != NULL) {\r
527 FreePool (DnsAddress);\r
528 }\r
529\r
530 if (Ip4Info != NULL) {\r
531 FreePool (Ip4Info);\r
532 }\r
533\r
534 return Status;\r
535}\r
536\r
537/**\r
538 Convert the IFR data into the network configuration data and set the IP\r
539 configure parameters for the NIC.\r
540\r
541 @param[in] IfrFormNvData The IFR NV data.\r
542 @param[in, out] Instance The IP4 config2 instance.\r
543\r
544 @retval EFI_SUCCESS The configure parameter for this NIC was\r
545 set successfully.\r
546 @retval EFI_INVALID_PARAMETER The address information for setting is invalid.\r
547 @retval Others Other errors as indicated.\r
548\r
549**/\r
550EFI_STATUS\r
551Ip4Config2ConvertIfrNvDataToConfigNvData (\r
552 IN IP4_CONFIG2_IFR_NVDATA *IfrFormNvData,\r
553 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
554 )\r
555{\r
556 EFI_STATUS Status;\r
557 EFI_IP4_CONFIG2_PROTOCOL *Ip4Cfg2;\r
558 IP4_CONFIG2_NVDATA *Ip4NvData;\r
559\r
560 EFI_IP_ADDRESS StationAddress;\r
561 EFI_IP_ADDRESS SubnetMask;\r
562 EFI_IP_ADDRESS Gateway;\r
563 IP4_ADDR Ip;\r
564 EFI_IPv4_ADDRESS *DnsAddress;\r
565 UINTN DnsCount;\r
566 UINTN Index;\r
567\r
568 EFI_EVENT TimeoutEvent;\r
569 EFI_EVENT SetAddressEvent;\r
570 BOOLEAN IsAddressOk;\r
571 UINTN DataSize;\r
572 EFI_INPUT_KEY Key;\r
573\r
574 Status = EFI_SUCCESS;\r
575 Ip4Cfg2 = &Instance->Ip4Config2;\r
576 Ip4NvData = &Instance->Ip4NvData;\r
577\r
578 DnsCount = 0;\r
579 DnsAddress = NULL;\r
580\r
581 TimeoutEvent = NULL;\r
582 SetAddressEvent = NULL;\r
583\r
584 if ((Instance == NULL) || (IfrFormNvData == NULL)) {\r
585 return EFI_INVALID_PARAMETER;\r
586 }\r
587\r
588 if (IfrFormNvData->Configure != TRUE) {\r
589 return EFI_SUCCESS;\r
590 }\r
591\r
592 if (IfrFormNvData->DhcpEnable == TRUE) {\r
593 Ip4NvData->Policy = Ip4Config2PolicyDhcp;\r
594\r
595 Status = Ip4Cfg2->SetData (\r
596 Ip4Cfg2,\r
597 Ip4Config2DataTypePolicy,\r
598 sizeof (EFI_IP4_CONFIG2_POLICY),\r
599 &Ip4NvData->Policy\r
600 );\r
601 if (EFI_ERROR (Status)) {\r
602 return Status;\r
603 }\r
604 } else {\r
605 //\r
606 // Get Ip4NvData from IfrFormNvData if it is valid.\r
607 //\r
608 Ip4NvData->Policy = Ip4Config2PolicyStatic;\r
609\r
610 Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);\r
611 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
612 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);\r
613 return EFI_INVALID_PARAMETER;\r
614 }\r
615\r
616 Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);\r
617 if (EFI_ERROR (Status) ||\r
618 ((SubnetMask.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0]))) ||\r
619 !Ip4StationAddressValid (NTOHL (StationAddress.Addr[0]), NTOHL (SubnetMask.Addr[0])))\r
620 {\r
621 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
622 return EFI_INVALID_PARAMETER;\r
623 }\r
624\r
625 Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);\r
626 if (EFI_ERROR (Status) ||\r
627 ((Gateway.Addr[0] != 0) && (SubnetMask.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (SubnetMask.Addr[0]))))\r
628 {\r
629 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
630 return EFI_INVALID_PARAMETER;\r
631 }\r
632\r
633 Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount);\r
634 if (!EFI_ERROR (Status) && (DnsCount > 0)) {\r
635 for (Index = 0; Index < DnsCount; Index++) {\r
636 CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));\r
637 if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {\r
638 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);\r
639 FreePool (DnsAddress);\r
640 return EFI_INVALID_PARAMETER;\r
641 }\r
642 }\r
643 } else {\r
644 if (EFI_ERROR (Status)) {\r
645 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);\r
646 }\r
647 }\r
648\r
649 if (Ip4NvData->ManualAddress != NULL) {\r
650 FreePool (Ip4NvData->ManualAddress);\r
651 }\r
652\r
653 Ip4NvData->ManualAddressCount = 1;\r
654 Ip4NvData->ManualAddress = AllocateZeroPool (sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS));\r
655 if (Ip4NvData->ManualAddress == NULL) {\r
656 if (DnsAddress != NULL) {\r
657 FreePool (DnsAddress);\r
658 }\r
659\r
660 return EFI_OUT_OF_RESOURCES;\r
661 }\r
662\r
663 CopyMem (&Ip4NvData->ManualAddress->Address, &StationAddress.v4, sizeof (EFI_IPv4_ADDRESS));\r
664 CopyMem (&Ip4NvData->ManualAddress->SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
665\r
666 if (Ip4NvData->GatewayAddress != NULL) {\r
667 FreePool (Ip4NvData->GatewayAddress);\r
668 }\r
669\r
670 Ip4NvData->GatewayAddressCount = 1;\r
671 Ip4NvData->GatewayAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));\r
672 if (Ip4NvData->GatewayAddress == NULL) {\r
673 if (DnsAddress != NULL) {\r
674 FreePool (DnsAddress);\r
675 }\r
676\r
677 return EFI_OUT_OF_RESOURCES;\r
678 }\r
679\r
680 CopyMem (Ip4NvData->GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));\r
681\r
682 if (Ip4NvData->DnsAddress != NULL) {\r
683 FreePool (Ip4NvData->DnsAddress);\r
684 }\r
685\r
686 Ip4NvData->DnsAddressCount = (UINT32)DnsCount;\r
687 Ip4NvData->DnsAddress = DnsAddress;\r
688\r
689 //\r
690 // Setting Ip4NvData.\r
691 //\r
692 Status = Ip4Cfg2->SetData (\r
693 Ip4Cfg2,\r
694 Ip4Config2DataTypePolicy,\r
695 sizeof (EFI_IP4_CONFIG2_POLICY),\r
696 &Ip4NvData->Policy\r
697 );\r
698 if (EFI_ERROR (Status)) {\r
699 return Status;\r
700 }\r
701\r
702 //\r
703 // Create events & timers for asynchronous settings.\r
704 //\r
705 Status = gBS->CreateEvent (\r
706 EVT_TIMER,\r
707 TPL_CALLBACK,\r
708 NULL,\r
709 NULL,\r
710 &TimeoutEvent\r
711 );\r
712 if (EFI_ERROR (Status)) {\r
713 return EFI_OUT_OF_RESOURCES;\r
714 }\r
715\r
716 Status = gBS->CreateEvent (\r
717 EVT_NOTIFY_SIGNAL,\r
718 TPL_NOTIFY,\r
719 Ip4Config2ManualAddressNotify,\r
720 &IsAddressOk,\r
721 &SetAddressEvent\r
722 );\r
723 if (EFI_ERROR (Status)) {\r
724 goto Exit;\r
725 }\r
726\r
727 IsAddressOk = FALSE;\r
728\r
729 Status = Ip4Cfg2->RegisterDataNotify (\r
730 Ip4Cfg2,\r
731 Ip4Config2DataTypeManualAddress,\r
732 SetAddressEvent\r
733 );\r
734 if (EFI_ERROR (Status)) {\r
735 goto Exit;\r
736 }\r
737\r
738 //\r
739 // Set ManualAddress.\r
740 //\r
741 DataSize = Ip4NvData->ManualAddressCount * sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS);\r
742 Status = Ip4Cfg2->SetData (\r
743 Ip4Cfg2,\r
744 Ip4Config2DataTypeManualAddress,\r
745 DataSize,\r
746 (VOID *)Ip4NvData->ManualAddress\r
747 );\r
748\r
749 if (Status == EFI_NOT_READY) {\r
750 gBS->SetTimer (TimeoutEvent, TimerRelative, 50000000);\r
751 while (EFI_ERROR (gBS->CheckEvent (TimeoutEvent))) {\r
752 if (IsAddressOk) {\r
753 Status = EFI_SUCCESS;\r
754 break;\r
755 }\r
756 }\r
757 }\r
758\r
759 Ip4Cfg2->UnregisterDataNotify (\r
760 Ip4Cfg2,\r
761 Ip4Config2DataTypeManualAddress,\r
762 SetAddressEvent\r
763 );\r
764 if (EFI_ERROR (Status)) {\r
765 goto Exit;\r
766 }\r
767\r
768 //\r
769 // Set gateway.\r
770 //\r
771 DataSize = Ip4NvData->GatewayAddressCount * sizeof (EFI_IPv4_ADDRESS);\r
772 Status = Ip4Cfg2->SetData (\r
773 Ip4Cfg2,\r
774 Ip4Config2DataTypeGateway,\r
775 DataSize,\r
776 Ip4NvData->GatewayAddress\r
777 );\r
778 if (EFI_ERROR (Status)) {\r
779 goto Exit;\r
780 }\r
781\r
782 //\r
783 // Set DNS addresses.\r
784 //\r
785 if ((Ip4NvData->DnsAddressCount > 0) && (Ip4NvData->DnsAddress != NULL)) {\r
786 DataSize = Ip4NvData->DnsAddressCount * sizeof (EFI_IPv4_ADDRESS);\r
787 Status = Ip4Cfg2->SetData (\r
788 Ip4Cfg2,\r
789 Ip4Config2DataTypeDnsServer,\r
790 DataSize,\r
791 Ip4NvData->DnsAddress\r
792 );\r
793\r
794 if (EFI_ERROR (Status)) {\r
795 goto Exit;\r
796 }\r
797 }\r
798 }\r
799\r
800Exit:\r
801 if (SetAddressEvent != NULL) {\r
802 gBS->CloseEvent (SetAddressEvent);\r
803 }\r
804\r
805 if (TimeoutEvent != NULL) {\r
806 gBS->CloseEvent (TimeoutEvent);\r
807 }\r
808\r
809 return Status;\r
810}\r
811\r
812/**\r
813 This function allows the caller to request the current\r
814 configuration for one or more named elements. The resulting\r
815 string is in <ConfigAltResp> format. Any and all alternative\r
816 configuration strings shall also be appended to the end of the\r
817 current configuration string. If they are, they must appear\r
818 after the current configuration. They must contain the same\r
819 routing (GUID, NAME, PATH) as the current configuration string.\r
820 They must have an additional description indicating the type of\r
821 alternative configuration the string represents,\r
822 "ALTCFG=<StringToken>". That <StringToken> (when\r
823 converted from Hex UNICODE to binary) is a reference to a\r
824 string in the associated string pack.\r
825\r
826 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
827 @param[in] Request A null-terminated Unicode string in\r
828 <ConfigRequest> format. Note that this\r
829 includes the routing information as well as\r
830 the configurable name / value pairs. It is\r
831 invalid for this string to be in\r
832 <MultiConfigRequest> format.\r
833 @param[out] Progress On return, points to a character in the\r
834 Request string. Points to the string's null\r
835 terminator if request was successful. Points\r
836 to the most recent "&" before the first\r
837 failing name / value pair (or the beginning\r
838 of the string if the failure is in the first\r
839 name / value pair) if the request was not\r
840 successful.\r
841 @param[out] Results A null-terminated Unicode string in\r
842 <ConfigAltResp> format which has all values\r
843 filled in for the names in the Request string.\r
844 String to be allocated by the called function.\r
845\r
846 @retval EFI_SUCCESS The Results string is filled with the\r
847 values corresponding to all requested\r
848 names.\r
849 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
850 parts of the results that must be\r
851 stored awaiting possible future\r
852 protocols.\r
853 @retval EFI_NOT_FOUND Routing data doesn't match any\r
854 known driver. Progress set to the\r
855 first character in the routing header.\r
856 Note: There is no requirement that the\r
857 driver validate the routing data. It\r
858 must skip the <ConfigHdr> in order to\r
859 process the names.\r
860 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
861 to most recent & before the\r
862 error or the beginning of the\r
863 string.\r
864 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
865 to the & before the name in\r
866 question.Currently not implemented.\r
867**/\r
868EFI_STATUS\r
869EFIAPI\r
870Ip4FormExtractConfig (\r
871 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
872 IN CONST EFI_STRING Request,\r
873 OUT EFI_STRING *Progress,\r
874 OUT EFI_STRING *Results\r
875 )\r
876{\r
877 EFI_STATUS Status;\r
878 IP4_CONFIG2_INSTANCE *Ip4Config2Instance;\r
879 IP4_FORM_CALLBACK_INFO *Private;\r
880 IP4_CONFIG2_IFR_NVDATA *IfrFormNvData;\r
881 EFI_STRING ConfigRequestHdr;\r
882 EFI_STRING ConfigRequest;\r
883 BOOLEAN AllocatedRequest;\r
884 EFI_STRING FormResult;\r
885 UINTN Size;\r
886 UINTN BufferSize;\r
887\r
888 if ((Progress == NULL) || (Results == NULL)) {\r
889 return EFI_INVALID_PARAMETER;\r
890 }\r
891\r
892 Status = EFI_SUCCESS;\r
893 IfrFormNvData = NULL;\r
894 ConfigRequest = NULL;\r
895 FormResult = NULL;\r
896 Size = 0;\r
897 AllocatedRequest = FALSE;\r
898 ConfigRequest = Request;\r
899 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
900 Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);\r
901 BufferSize = sizeof (IP4_CONFIG2_IFR_NVDATA);\r
902 *Progress = Request;\r
903\r
904 //\r
905 // Check Request data in <ConfigHdr>.\r
906 //\r
907 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {\r
908 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));\r
909 if (IfrFormNvData == NULL) {\r
910 return EFI_OUT_OF_RESOURCES;\r
911 }\r
912\r
913 Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance, IfrFormNvData);\r
914\r
915 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
916 //\r
917 // Request has no request element, construct full request string.\r
918 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
919 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
920 //\r
921 ConfigRequestHdr = HiiConstructConfigHdr (&gIp4Config2NvDataGuid, mIp4Config2StorageName, Private->ChildHandle);\r
922 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
923 ConfigRequest = AllocateZeroPool (Size);\r
924 if (ConfigRequest == NULL) {\r
925 Status = EFI_OUT_OF_RESOURCES;\r
926 goto Failure;\r
927 }\r
928\r
929 AllocatedRequest = TRUE;\r
930\r
931 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
932 FreePool (ConfigRequestHdr);\r
933 }\r
934\r
935 //\r
936 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
937 //\r
938 Status = gHiiConfigRouting->BlockToConfig (\r
939 gHiiConfigRouting,\r
940 ConfigRequest,\r
941 (UINT8 *)IfrFormNvData,\r
942 BufferSize,\r
943 &FormResult,\r
944 Progress\r
945 );\r
946\r
947 FreePool (IfrFormNvData);\r
948\r
949 //\r
950 // Free the allocated config request string.\r
951 //\r
952 if (AllocatedRequest) {\r
953 FreePool (ConfigRequest);\r
954 ConfigRequest = NULL;\r
955 }\r
956\r
957 if (EFI_ERROR (Status)) {\r
958 goto Failure;\r
959 }\r
960 }\r
961\r
962 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {\r
963 *Results = FormResult;\r
964 } else {\r
965 return EFI_NOT_FOUND;\r
966 }\r
967\r
968Failure:\r
969 //\r
970 // Set Progress string to the original request string.\r
971 //\r
972 if (Request == NULL) {\r
973 *Progress = NULL;\r
974 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
975 *Progress = Request + StrLen (Request);\r
976 }\r
977\r
978 return Status;\r
979}\r
980\r
981/**\r
982 This function applies changes in a driver's configuration.\r
983 Input is a Configuration, which has the routing data for this\r
984 driver followed by name / value configuration pairs. The driver\r
985 must apply those pairs to its configurable storage. If the\r
986 driver's configuration is stored in a linear block of data\r
987 and the driver's name / value pairs are in <BlockConfig>\r
988 format, it may use the ConfigToBlock helper function (above) to\r
989 simplify the job. Currently not implemented.\r
990\r
991 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
992 @param[in] Configuration A null-terminated Unicode string in\r
993 <ConfigString> format.\r
994 @param[out] Progress A pointer to a string filled in with the\r
995 offset of the most recent '&' before the\r
996 first failing name / value pair (or the\r
997 beginning of the string if the failure\r
998 is in the first name / value pair) or\r
999 the terminating NULL if all was\r
1000 successful.\r
1001\r
1002 @retval EFI_SUCCESS The results have been distributed or are\r
1003 awaiting distribution.\r
1004 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
1005 parts of the results that must be\r
1006 stored awaiting possible future\r
1007 protocols.\r
1008 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
1009 Results parameter would result\r
1010 in this type of error.\r
1011 @retval EFI_NOT_FOUND Target for the specified routing data\r
1012 was not found.\r
1013**/\r
1014EFI_STATUS\r
1015EFIAPI\r
1016Ip4FormRouteConfig (\r
1017 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1018 IN CONST EFI_STRING Configuration,\r
1019 OUT EFI_STRING *Progress\r
1020 )\r
1021{\r
1022 EFI_STATUS Status;\r
1023 UINTN BufferSize;\r
1024 IP4_CONFIG2_IFR_NVDATA *IfrFormNvData;\r
1025 IP4_CONFIG2_INSTANCE *Ip4Config2Instance;\r
1026 IP4_FORM_CALLBACK_INFO *Private;\r
1027\r
1028 Status = EFI_SUCCESS;\r
1029 IfrFormNvData = NULL;\r
1030\r
1031 if ((Configuration == NULL) || (Progress == NULL)) {\r
1032 return EFI_INVALID_PARAMETER;\r
1033 }\r
1034\r
1035 *Progress = Configuration;\r
1036\r
1037 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
1038 Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);\r
1039\r
1040 //\r
1041 // Check Routing data in <ConfigHdr>.\r
1042 //\r
1043 if (HiiIsConfigHdrMatch (Configuration, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {\r
1044 //\r
1045 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
1046 //\r
1047 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));\r
1048 if (IfrFormNvData == NULL) {\r
1049 return EFI_OUT_OF_RESOURCES;\r
1050 }\r
1051\r
1052 BufferSize = 0;\r
1053\r
1054 Status = gHiiConfigRouting->ConfigToBlock (\r
1055 gHiiConfigRouting,\r
1056 Configuration,\r
1057 (UINT8 *)IfrFormNvData,\r
1058 &BufferSize,\r
1059 Progress\r
1060 );\r
1061 if (Status != EFI_BUFFER_TOO_SMALL) {\r
1062 return Status;\r
1063 }\r
1064\r
1065 Status = gHiiConfigRouting->ConfigToBlock (\r
1066 gHiiConfigRouting,\r
1067 Configuration,\r
1068 (UINT8 *)IfrFormNvData,\r
1069 &BufferSize,\r
1070 Progress\r
1071 );\r
1072 if (!EFI_ERROR (Status)) {\r
1073 Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Ip4Config2Instance);\r
1074 }\r
1075\r
1076 FreePool (IfrFormNvData);\r
1077 } else {\r
1078 return EFI_NOT_FOUND;\r
1079 }\r
1080\r
1081 return Status;\r
1082}\r
1083\r
1084/**\r
1085 This function is called to provide results data to the driver.\r
1086 This data consists of a unique key that is used to identify\r
1087 which data is either being passed back or being asked for.\r
1088\r
1089 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
1090 @param[in] Action Specifies the type of action taken by the browser.\r
1091 @param[in] QuestionId A unique value which is sent to the original\r
1092 exporting driver so that it can identify the type\r
1093 of data to expect. The format of the data tends to\r
1094 vary based on the opcode that enerated the callback.\r
1095 @param[in] Type The type of value for the question.\r
1096 @param[in] Value A pointer to the data being sent to the original\r
1097 exporting driver.\r
1098 @param[out] ActionRequest On return, points to the action requested by the\r
1099 callback function.\r
1100\r
1101 @retval EFI_SUCCESS The callback successfully handled the action.\r
1102 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
1103 variable and its data.\r
1104 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
1105 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
1106 callback. Currently not implemented.\r
1107 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.\r
1108 @retval Others Other errors as indicated.\r
1109\r
1110**/\r
1111EFI_STATUS\r
1112EFIAPI\r
1113Ip4FormCallback (\r
1114 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1115 IN EFI_BROWSER_ACTION Action,\r
1116 IN EFI_QUESTION_ID QuestionId,\r
1117 IN UINT8 Type,\r
1118 IN EFI_IFR_TYPE_VALUE *Value,\r
1119 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
1120 )\r
1121{\r
1122 EFI_STATUS Status;\r
1123 IP4_CONFIG2_INSTANCE *Instance;\r
1124 IP4_CONFIG2_IFR_NVDATA *IfrFormNvData;\r
1125 IP4_FORM_CALLBACK_INFO *Private;\r
1126\r
1127 EFI_IP_ADDRESS StationAddress;\r
1128 EFI_IP_ADDRESS SubnetMask;\r
1129 EFI_IP_ADDRESS Gateway;\r
1130 IP4_ADDR Ip;\r
1131 EFI_IPv4_ADDRESS *DnsAddress;\r
1132 UINTN DnsCount;\r
1133 UINTN Index;\r
1134 EFI_INPUT_KEY Key;\r
1135\r
1136 IfrFormNvData = NULL;\r
1137 DnsCount = 0;\r
1138 DnsAddress = NULL;\r
1139\r
1140 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
1141 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
1142 Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);\r
1143\r
1144 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG2_IFR_NVDATA));\r
1145 if (IfrFormNvData == NULL) {\r
1146 return EFI_OUT_OF_RESOURCES;\r
1147 }\r
1148\r
1149 //\r
1150 // Retrieve uncommitted data from Browser\r
1151 //\r
1152 if (!HiiGetBrowserData (&gIp4Config2NvDataGuid, mIp4Config2StorageName, sizeof (IP4_CONFIG2_IFR_NVDATA), (UINT8 *)IfrFormNvData)) {\r
1153 FreePool (IfrFormNvData);\r
1154 return EFI_NOT_FOUND;\r
1155 }\r
1156\r
1157 Status = EFI_SUCCESS;\r
1158\r
1159 switch (QuestionId) {\r
1160 case KEY_LOCAL_IP:\r
1161 Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);\r
1162 if (EFI_ERROR (Status) || IP4_IS_UNSPECIFIED (NTOHL (StationAddress.Addr[0])) || IP4_IS_LOCAL_BROADCAST (NTOHL (StationAddress.Addr[0]))) {\r
1163 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
1164 Status = EFI_INVALID_PARAMETER;\r
1165 }\r
1166\r
1167 break;\r
1168\r
1169 case KEY_SUBNET_MASK:\r
1170 Status = Ip4Config2StrToIp (IfrFormNvData->SubnetMask, &SubnetMask.v4);\r
1171 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
1172 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Subnet Mask!", NULL);\r
1173 Status = EFI_INVALID_PARAMETER;\r
1174 }\r
1175\r
1176 break;\r
1177\r
1178 case KEY_GATE_WAY:\r
1179 Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);\r
1180 if (EFI_ERROR (Status) || IP4_IS_LOCAL_BROADCAST (NTOHL (Gateway.Addr[0]))) {\r
1181 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
1182 Status = EFI_INVALID_PARAMETER;\r
1183 }\r
1184\r
1185 break;\r
1186\r
1187 case KEY_DNS:\r
1188 Status = Ip4Config2StrToIpList (IfrFormNvData->DnsAddress, &DnsAddress, &DnsCount);\r
1189 if (!EFI_ERROR (Status) && (DnsCount > 0)) {\r
1190 for (Index = 0; Index < DnsCount; Index++) {\r
1191 CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));\r
1192 if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {\r
1193 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);\r
1194 Status = EFI_INVALID_PARAMETER;\r
1195 break;\r
1196 }\r
1197 }\r
1198 } else {\r
1199 if (EFI_ERROR (Status)) {\r
1200 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);\r
1201 }\r
1202 }\r
1203\r
1204 if (DnsAddress != NULL) {\r
1205 FreePool (DnsAddress);\r
1206 }\r
1207\r
1208 break;\r
1209\r
1210 case KEY_SAVE_CHANGES:\r
1211 Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Instance);\r
1212 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1213 break;\r
1214\r
1215 default:\r
1216 break;\r
1217 }\r
1218\r
1219 FreePool (IfrFormNvData);\r
1220\r
1221 return Status;\r
1222 }\r
1223\r
1224 //\r
1225 // All other action return unsupported.\r
1226 //\r
1227 return EFI_UNSUPPORTED;\r
1228}\r
1229\r
1230/**\r
1231 Install HII Config Access protocol for network device and allocate resource.\r
1232\r
1233 @param[in, out] Instance The IP4 config2 Instance.\r
1234\r
1235 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
1236 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1237 @retval Others Other errors as indicated.\r
1238\r
1239**/\r
1240EFI_STATUS\r
1241Ip4Config2FormInit (\r
1242 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
1243 )\r
1244{\r
1245 EFI_STATUS Status;\r
1246 IP4_SERVICE *IpSb;\r
1247 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
1248 EFI_HII_CONFIG_ACCESS_PROTOCOL *ConfigAccess;\r
1249 VENDOR_DEVICE_PATH VendorDeviceNode;\r
1250 EFI_SERVICE_BINDING_PROTOCOL *MnpSb;\r
1251 CHAR16 *MacString;\r
1252 CHAR16 MenuString[128];\r
1253 CHAR16 PortString[128];\r
1254 CHAR16 *OldMenuString;\r
1255 EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath;\r
1256\r
1257 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1258 ASSERT (IpSb != NULL);\r
1259\r
1260 CallbackInfo = &Instance->CallbackInfo;\r
1261\r
1262 CallbackInfo->Signature = IP4_FORM_CALLBACK_INFO_SIGNATURE;\r
1263\r
1264 Status = gBS->HandleProtocol (\r
1265 IpSb->Controller,\r
1266 &gEfiDevicePathProtocolGuid,\r
1267 (VOID **)&ParentDevicePath\r
1268 );\r
1269 if (EFI_ERROR (Status)) {\r
1270 return Status;\r
1271 }\r
1272\r
1273 //\r
1274 // Construct device path node for EFI HII Config Access protocol,\r
1275 // which consists of controller physical device path and one hardware\r
1276 // vendor guid node.\r
1277 //\r
1278 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
1279 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
1280 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
1281\r
1282 CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);\r
1283\r
1284 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
1285 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (\r
1286 ParentDevicePath,\r
1287 (EFI_DEVICE_PATH_PROTOCOL *)&VendorDeviceNode\r
1288 );\r
1289 if (CallbackInfo->HiiVendorDevicePath == NULL) {\r
1290 Status = EFI_OUT_OF_RESOURCES;\r
1291 goto Error;\r
1292 }\r
1293\r
1294 ConfigAccess = &CallbackInfo->HiiConfigAccessProtocol;\r
1295 ConfigAccess->ExtractConfig = Ip4FormExtractConfig;\r
1296 ConfigAccess->RouteConfig = Ip4FormRouteConfig;\r
1297 ConfigAccess->Callback = Ip4FormCallback;\r
1298\r
1299 //\r
1300 // Install Device Path Protocol and Config Access protocol on new handle\r
1301 //\r
1302 Status = gBS->InstallMultipleProtocolInterfaces (\r
1303 &CallbackInfo->ChildHandle,\r
1304 &gEfiDevicePathProtocolGuid,\r
1305 CallbackInfo->HiiVendorDevicePath,\r
1306 &gEfiHiiConfigAccessProtocolGuid,\r
1307 ConfigAccess,\r
1308 NULL\r
1309 );\r
1310\r
1311 if (!EFI_ERROR (Status)) {\r
1312 //\r
1313 // Open the Parent Handle for the child\r
1314 //\r
1315 Status = gBS->OpenProtocol (\r
1316 IpSb->Controller,\r
1317 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
1318 (VOID **)&MnpSb,\r
1319 IpSb->Image,\r
1320 CallbackInfo->ChildHandle,\r
1321 EFI_OPEN_PROTOCOL_BY_CHILD_CONTROLLER\r
1322 );\r
1323 }\r
1324\r
1325 if (EFI_ERROR (Status)) {\r
1326 goto Error;\r
1327 }\r
1328\r
1329 //\r
1330 // Publish our HII data\r
1331 //\r
1332 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
1333 &gIp4Config2NvDataGuid,\r
1334 CallbackInfo->ChildHandle,\r
1335 Ip4DxeStrings,\r
1336 Ip4Config2Bin,\r
1337 NULL\r
1338 );\r
1339 if (CallbackInfo->RegisteredHandle == NULL) {\r
1340 Status = EFI_OUT_OF_RESOURCES;\r
1341 goto Error;\r
1342 }\r
1343\r
1344 //\r
1345 // Append MAC string in the menu help string and tile help string\r
1346 //\r
1347 Status = NetLibGetMacString (IpSb->Controller, IpSb->Image, &MacString);\r
1348 if (!EFI_ERROR (Status)) {\r
1349 OldMenuString = HiiGetString (\r
1350 CallbackInfo->RegisteredHandle,\r
1351 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),\r
1352 NULL\r
1353 );\r
1354 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
1355 HiiSetString (\r
1356 CallbackInfo->RegisteredHandle,\r
1357 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),\r
1358 MenuString,\r
1359 NULL\r
1360 );\r
1361\r
1362 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
1363 HiiSetString (\r
1364 CallbackInfo->RegisteredHandle,\r
1365 STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP),\r
1366 PortString,\r
1367 NULL\r
1368 );\r
1369\r
1370 FreePool (MacString);\r
1371 FreePool (OldMenuString);\r
1372\r
1373 return EFI_SUCCESS;\r
1374 }\r
1375\r
1376Error:\r
1377 Ip4Config2FormUnload (Instance);\r
1378 return Status;\r
1379}\r
1380\r
1381/**\r
1382 Uninstall the HII Config Access protocol for network devices and free up the resources.\r
1383\r
1384 @param[in, out] Instance The IP4 config2 instance to unload a form.\r
1385\r
1386**/\r
1387VOID\r
1388Ip4Config2FormUnload (\r
1389 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
1390 )\r
1391{\r
1392 IP4_SERVICE *IpSb;\r
1393 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
1394 IP4_CONFIG2_NVDATA *Ip4NvData;\r
1395\r
1396 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1397 ASSERT (IpSb != NULL);\r
1398\r
1399 CallbackInfo = &Instance->CallbackInfo;\r
1400\r
1401 if (CallbackInfo->ChildHandle != NULL) {\r
1402 //\r
1403 // Close the child handle\r
1404 //\r
1405 gBS->CloseProtocol (\r
1406 IpSb->Controller,\r
1407 &gEfiManagedNetworkServiceBindingProtocolGuid,\r
1408 IpSb->Image,\r
1409 CallbackInfo->ChildHandle\r
1410 );\r
1411\r
1412 //\r
1413 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
1414 //\r
1415 gBS->UninstallMultipleProtocolInterfaces (\r
1416 CallbackInfo->ChildHandle,\r
1417 &gEfiDevicePathProtocolGuid,\r
1418 CallbackInfo->HiiVendorDevicePath,\r
1419 &gEfiHiiConfigAccessProtocolGuid,\r
1420 &CallbackInfo->HiiConfigAccessProtocol,\r
1421 NULL\r
1422 );\r
1423 }\r
1424\r
1425 if (CallbackInfo->HiiVendorDevicePath != NULL) {\r
1426 FreePool (CallbackInfo->HiiVendorDevicePath);\r
1427 }\r
1428\r
1429 if (CallbackInfo->RegisteredHandle != NULL) {\r
1430 //\r
1431 // Remove HII package list\r
1432 //\r
1433 HiiRemovePackages (CallbackInfo->RegisteredHandle);\r
1434 }\r
1435\r
1436 Ip4NvData = &Instance->Ip4NvData;\r
1437\r
1438 if (Ip4NvData->ManualAddress != NULL) {\r
1439 FreePool (Ip4NvData->ManualAddress);\r
1440 }\r
1441\r
1442 if (Ip4NvData->GatewayAddress != NULL) {\r
1443 FreePool (Ip4NvData->GatewayAddress);\r
1444 }\r
1445\r
1446 if (Ip4NvData->DnsAddress != NULL) {\r
1447 FreePool (Ip4NvData->DnsAddress);\r
1448 }\r
1449\r
1450 Ip4NvData->ManualAddressCount = 0;\r
1451 Ip4NvData->GatewayAddressCount = 0;\r
1452 Ip4NvData->DnsAddressCount = 0;\r
1453}\r