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