]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/Ip4Dxe/Ip4Config2Nv.c
NetworkPkg: Apply uncrustify changes
[mirror_edk2.git] / NetworkPkg / 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
d1050b9d 11CHAR16 mIp4Config2StorageName[] = L"IP4_CONFIG2_IFR_NVDATA";\r
1f6729ff 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
d1050b9d 51 return (UINT8)(32 - Len);\r
1f6729ff 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
d1050b9d
MK
70 UINTN Index;\r
71 UINTN Number;\r
1f6729ff 72\r
73 Index = 0;\r
74\r
75 while (*Str != L'\0') {\r
1f6729ff 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
d1050b9d 90 Ip->Addr[Index] = (UINT8)Number;\r
1f6729ff 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
d1102dba 127\r
1f6729ff 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
d1050b9d
MK
136 UINTN BeginIndex;\r
137 UINTN EndIndex;\r
138 UINTN Index;\r
139 UINTN IpIndex;\r
140 CHAR16 *StrTemp;\r
141 BOOLEAN SpaceTag;\r
d1102dba 142\r
1f6729ff 143 BeginIndex = 0;\r
144 EndIndex = BeginIndex;\r
145 Index = 0;\r
146 IpIndex = 0;\r
147 StrTemp = NULL;\r
148 SpaceTag = TRUE;\r
d1102dba 149\r
1f6729ff 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
d1102dba 169\r
1f6729ff 170 Index++;\r
171 }\r
172\r
173 if (*IpCount == 0) {\r
174 return EFI_SUCCESS;\r
175 }\r
d1102dba 176\r
1f6729ff 177 //\r
178 // Allocate buffer for IpList.\r
179 //\r
d1050b9d 180 *PtrIpList = AllocateZeroPool (*IpCount * sizeof (EFI_IPv4_ADDRESS));\r
1f6729ff 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
d1050b9d
MK
191 if (!SpaceTag) {\r
192 StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));\r
1f6729ff 193 if (StrTemp == NULL) {\r
d1050b9d 194 FreePool (*PtrIpList);\r
1f6729ff 195 *PtrIpList = NULL;\r
d1050b9d 196 *IpCount = 0;\r
1f6729ff 197 return EFI_OUT_OF_RESOURCES;\r
198 }\r
d1102dba 199\r
d1050b9d 200 CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));\r
1f6729ff 201 *(StrTemp + (EndIndex - BeginIndex)) = L'\0';\r
d1102dba 202\r
1f6729ff 203 if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {\r
d1050b9d
MK
204 FreePool (StrTemp);\r
205 FreePool (*PtrIpList);\r
1f6729ff 206 *PtrIpList = NULL;\r
d1050b9d 207 *IpCount = 0;\r
1f6729ff 208 return EFI_INVALID_PARAMETER;\r
209 }\r
d1102dba 210\r
1f6729ff 211 BeginIndex = EndIndex;\r
212 IpIndex++;\r
213\r
d1050b9d 214 FreePool (StrTemp);\r
1f6729ff 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
d1102dba 224\r
1f6729ff 225 Index++;\r
d1102dba 226\r
1f6729ff 227 if (*(Str + Index) == L'\0') {\r
228 if (!SpaceTag) {\r
d1050b9d 229 StrTemp = AllocateZeroPool ((EndIndex - BeginIndex + 1) * sizeof (CHAR16));\r
1f6729ff 230 if (StrTemp == NULL) {\r
d1050b9d 231 FreePool (*PtrIpList);\r
1f6729ff 232 *PtrIpList = NULL;\r
d1050b9d 233 *IpCount = 0;\r
1f6729ff 234 return EFI_OUT_OF_RESOURCES;\r
235 }\r
d1102dba 236\r
d1050b9d 237 CopyMem (StrTemp, Str + BeginIndex, (EndIndex - BeginIndex) * sizeof (CHAR16));\r
1f6729ff 238 *(StrTemp + (EndIndex - BeginIndex)) = L'\0';\r
d1102dba 239\r
1f6729ff 240 if (Ip4Config2StrToIp (StrTemp, &((*PtrIpList)[IpIndex])) != EFI_SUCCESS) {\r
d1050b9d
MK
241 FreePool (StrTemp);\r
242 FreePool (*PtrIpList);\r
1f6729ff 243 *PtrIpList = NULL;\r
d1050b9d 244 *IpCount = 0;\r
1f6729ff 245 return EFI_INVALID_PARAMETER;\r
246 }\r
247\r
d1050b9d 248 FreePool (StrTemp);\r
1f6729ff 249 }\r
250 }\r
d1102dba 251 }\r
1f6729ff 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
d1102dba 261\r
1f6729ff 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
d1102dba
LG
271 2 * IP4_STR_MAX_SIZE,\r
272 L"%d.%d.%d.%d",\r
1f6729ff 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
1f6729ff 280/**\r
d1102dba 281 Convert the IPv4 address list into string consists of several decimal\r
1f6729ff 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
d1102dba 287 IPv4 addresses separated by space.\r
72bdc5f0
FS
288\r
289 @retval EFI_SUCCESS Operation is success.\r
290 @retval EFI_OUT_OF_RESOURCES Error occurs in allocating memory.\r
291\r
1f6729ff 292**/\r
72bdc5f0 293EFI_STATUS\r
1f6729ff 294Ip4Config2IpListToStr (\r
295 IN EFI_IPv4_ADDRESS *Ip,\r
296 IN UINTN IpCount,\r
297 OUT CHAR16 *Str\r
298 )\r
299{\r
d1050b9d
MK
300 UINTN Index;\r
301 UINTN TemIndex;\r
302 UINTN StrIndex;\r
303 CHAR16 *TempStr;\r
304 EFI_IPv4_ADDRESS *TempIp;\r
d1102dba 305\r
1f6729ff 306 Index = 0;\r
307 TemIndex = 0;\r
308 StrIndex = 0;\r
309 TempStr = NULL;\r
310 TempIp = NULL;\r
311\r
d1050b9d 312 for (Index = 0; Index < IpCount; Index++) {\r
1f6729ff 313 TempIp = Ip + Index;\r
314 if (TempStr == NULL) {\r
d1050b9d 315 TempStr = AllocateZeroPool (2 * IP4_STR_MAX_SIZE);\r
72bdc5f0
FS
316 if (TempStr == NULL) {\r
317 return EFI_OUT_OF_RESOURCES;\r
318 }\r
1f6729ff 319 }\r
320\r
321 UnicodeSPrint (\r
d1102dba
LG
322 TempStr,\r
323 2 * IP4_STR_MAX_SIZE,\r
324 L"%d.%d.%d.%d",\r
1f6729ff 325 TempIp->Addr[0],\r
326 TempIp->Addr[1],\r
327 TempIp->Addr[2],\r
328 TempIp->Addr[3]\r
329 );\r
330\r
d1050b9d 331 for (TemIndex = 0; TemIndex < IP4_STR_MAX_SIZE; TemIndex++) {\r
1f6729ff 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
d1102dba 337 }\r
d1050b9d 338\r
1f6729ff 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
d1050b9d 347 FreePool (TempStr);\r
1f6729ff 348 }\r
72bdc5f0
FS
349\r
350 return EFI_SUCCESS;\r
1f6729ff 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
d1102dba 358\r
1f6729ff 359**/\r
360VOID\r
361EFIAPI\r
362Ip4Config2ManualAddressNotify (\r
d1050b9d
MK
363 IN EFI_EVENT Event,\r
364 IN VOID *Context\r
1f6729ff 365 )\r
366{\r
d1050b9d 367 *((BOOLEAN *)Context) = TRUE;\r
1f6729ff 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
d1102dba 380\r
1f6729ff 381**/\r
382EFI_STATUS\r
383Ip4Config2ConvertConfigNvDataToIfrNvData (\r
d1050b9d
MK
384 IN IP4_CONFIG2_INSTANCE *Instance,\r
385 IN OUT IP4_CONFIG2_IFR_NVDATA *IfrNvData\r
1f6729ff 386 )\r
387{\r
d1050b9d
MK
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
1f6729ff 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
d1102dba 405\r
1f6729ff 406 if ((IfrNvData == NULL) || (Instance == NULL)) {\r
407 return EFI_INVALID_PARAMETER;\r
408 }\r
d1102dba 409\r
1f6729ff 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
d1102dba 423 //\r
1f6729ff 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
d1102dba 434\r
1f6729ff 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
d1102dba 441\r
1f6729ff 442 //\r
443 // Get the interface info.\r
444 //\r
d1050b9d
MK
445 DataSize = 0;\r
446 Status = Ip4Config2->GetData (\r
447 Ip4Config2,\r
448 Ip4Config2DataTypeInterfaceInfo,\r
449 &DataSize,\r
450 NULL\r
451 );\r
1f6729ff 452 if (Status != EFI_BUFFER_TOO_SMALL) {\r
453 return Status;\r
454 }\r
d1102dba 455\r
1f6729ff 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
d1102dba 471\r
1f6729ff 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
d1050b9d
MK
489 Status = Ip4Config2->GetData (\r
490 Ip4Config2,\r
491 Ip4Config2DataTypeDnsServer,\r
492 &DnsSize,\r
493 NULL\r
494 );\r
1f6729ff 495 if ((Status != EFI_BUFFER_TOO_SMALL) && (Status != EFI_NOT_FOUND)) {\r
496 goto Exit;\r
497 }\r
d1102dba 498\r
d1050b9d 499 DnsCount = (UINT32)(DnsSize / sizeof (EFI_IPv4_ADDRESS));\r
1f6729ff 500\r
501 if (DnsSize > 0) {\r
d1050b9d 502 DnsAddress = AllocateZeroPool (DnsSize);\r
1f6729ff 503 if (DnsAddress == NULL) {\r
504 Status = EFI_OUT_OF_RESOURCES;\r
505 goto Exit;\r
506 }\r
d1102dba 507\r
1f6729ff 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
72bdc5f0 522 Status = Ip4Config2IpListToStr (DnsAddress, DnsCount, IfrNvData->DnsAddress);\r
1f6729ff 523\r
524Exit:\r
525\r
526 if (DnsAddress != NULL) {\r
d1050b9d 527 FreePool (DnsAddress);\r
1f6729ff 528 }\r
529\r
530 if (Ip4Info != NULL) {\r
d1050b9d 531 FreePool (Ip4Info);\r
1f6729ff 532 }\r
d1102dba 533\r
1f6729ff 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
d1102dba 548\r
1f6729ff 549**/\r
550EFI_STATUS\r
551Ip4Config2ConvertIfrNvDataToConfigNvData (\r
d1050b9d
MK
552 IN IP4_CONFIG2_IFR_NVDATA *IfrFormNvData,\r
553 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
1f6729ff 554 )\r
555{\r
d1050b9d
MK
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
d1102dba 580\r
1f6729ff 581 TimeoutEvent = NULL;\r
582 SetAddressEvent = NULL;\r
583\r
d1050b9d 584 if ((Instance == NULL) || (IfrFormNvData == NULL)) {\r
1f6729ff 585 return EFI_INVALID_PARAMETER;\r
586 }\r
587\r
588 if (IfrFormNvData->Configure != TRUE) {\r
589 return EFI_SUCCESS;\r
590 }\r
d1102dba 591\r
1f6729ff 592 if (IfrFormNvData->DhcpEnable == TRUE) {\r
593 Ip4NvData->Policy = Ip4Config2PolicyDhcp;\r
d1102dba 594\r
1f6729ff 595 Status = Ip4Cfg2->SetData (\r
596 Ip4Cfg2,\r
597 Ip4Config2DataTypePolicy,\r
598 sizeof (EFI_IP4_CONFIG2_POLICY),\r
599 &Ip4NvData->Policy\r
600 );\r
d1050b9d 601 if (EFI_ERROR (Status)) {\r
1f6729ff 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
1f6729ff 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
01b5ac88
FS
615\r
616 Status = Ip4Config2StrToIp (IfrFormNvData->StationAddress, &StationAddress.v4);\r
d1102dba 617 if (EFI_ERROR (Status) ||\r
d1050b9d
MK
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
01b5ac88
FS
621 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
622 return EFI_INVALID_PARAMETER;\r
623 }\r
d1102dba 624\r
1f6729ff 625 Status = Ip4Config2StrToIp (IfrFormNvData->GatewayAddress, &Gateway.v4);\r
d1102dba 626 if (EFI_ERROR (Status) ||\r
d1050b9d
MK
627 ((Gateway.Addr[0] != 0) && (SubnetMask.Addr[0] != 0) && !NetIp4IsUnicast (NTOHL (Gateway.Addr[0]), NTOHL (SubnetMask.Addr[0]))))\r
628 {\r
1f6729ff 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
d1050b9d
MK
634 if (!EFI_ERROR (Status) && (DnsCount > 0)) {\r
635 for (Index = 0; Index < DnsCount; Index++) {\r
1f6729ff 636 CopyMem (&Ip, &DnsAddress[Index], sizeof (IP4_ADDR));\r
01b5ac88 637 if (IP4_IS_UNSPECIFIED (NTOHL (Ip)) || IP4_IS_LOCAL_BROADCAST (NTOHL (Ip))) {\r
1f6729ff 638 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);\r
d1050b9d 639 FreePool (DnsAddress);\r
1f6729ff 640 return EFI_INVALID_PARAMETER;\r
d1102dba
LG
641 }\r
642 }\r
1f6729ff 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
d1102dba 648\r
1f6729ff 649 if (Ip4NvData->ManualAddress != NULL) {\r
d1050b9d 650 FreePool (Ip4NvData->ManualAddress);\r
1f6729ff 651 }\r
d1050b9d 652\r
1f6729ff 653 Ip4NvData->ManualAddressCount = 1;\r
d1050b9d 654 Ip4NvData->ManualAddress = AllocateZeroPool (sizeof (EFI_IP4_CONFIG2_MANUAL_ADDRESS));\r
1f6729ff 655 if (Ip4NvData->ManualAddress == NULL) {\r
656 if (DnsAddress != NULL) {\r
d1050b9d 657 FreePool (DnsAddress);\r
1f6729ff 658 }\r
d1102dba 659\r
1f6729ff 660 return EFI_OUT_OF_RESOURCES;\r
661 }\r
d1050b9d
MK
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
d1102dba 665\r
1f6729ff 666 if (Ip4NvData->GatewayAddress != NULL) {\r
d1050b9d 667 FreePool (Ip4NvData->GatewayAddress);\r
1f6729ff 668 }\r
d1050b9d 669\r
1f6729ff 670 Ip4NvData->GatewayAddressCount = 1;\r
d1050b9d 671 Ip4NvData->GatewayAddress = AllocateZeroPool (sizeof (EFI_IPv4_ADDRESS));\r
1f6729ff 672 if (Ip4NvData->GatewayAddress == NULL) {\r
673 if (DnsAddress != NULL) {\r
d1050b9d 674 FreePool (DnsAddress);\r
1f6729ff 675 }\r
d1050b9d 676\r
1f6729ff 677 return EFI_OUT_OF_RESOURCES;\r
678 }\r
d1050b9d
MK
679\r
680 CopyMem (Ip4NvData->GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));\r
d1102dba 681\r
1f6729ff 682 if (Ip4NvData->DnsAddress != NULL) {\r
d1050b9d 683 FreePool (Ip4NvData->DnsAddress);\r
1f6729ff 684 }\r
d1050b9d
MK
685\r
686 Ip4NvData->DnsAddressCount = (UINT32)DnsCount;\r
1f6729ff 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
d1050b9d 698 if (EFI_ERROR (Status)) {\r
1f6729ff 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
d1102dba 728\r
1f6729ff 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
d1050b9d
MK
742 Status = Ip4Cfg2->SetData (\r
743 Ip4Cfg2,\r
744 Ip4Config2DataTypeManualAddress,\r
745 DataSize,\r
746 (VOID *)Ip4NvData->ManualAddress\r
747 );\r
1f6729ff 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
d1050b9d
MK
772 Status = Ip4Cfg2->SetData (\r
773 Ip4Cfg2,\r
774 Ip4Config2DataTypeGateway,\r
775 DataSize,\r
776 Ip4NvData->GatewayAddress\r
777 );\r
1f6729ff 778 if (EFI_ERROR (Status)) {\r
779 goto Exit;\r
780 }\r
781\r
782 //\r
783 // Set DNS addresses.\r
784 //\r
d1050b9d 785 if ((Ip4NvData->DnsAddressCount > 0) && (Ip4NvData->DnsAddress != NULL)) {\r
1f6729ff 786 DataSize = Ip4NvData->DnsAddressCount * sizeof (EFI_IPv4_ADDRESS);\r
d1050b9d
MK
787 Status = Ip4Cfg2->SetData (\r
788 Ip4Cfg2,\r
789 Ip4Config2DataTypeDnsServer,\r
790 DataSize,\r
791 Ip4NvData->DnsAddress\r
792 );\r
d1102dba 793\r
1f6729ff 794 if (EFI_ERROR (Status)) {\r
795 goto Exit;\r
d1102dba
LG
796 }\r
797 }\r
798 }\r
1f6729ff 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
d1050b9d
MK
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
1f6729ff 875 )\r
876{\r
d1050b9d
MK
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
b1d4218a 889 return EFI_INVALID_PARAMETER;\r
890 }\r
d1102dba
LG
891\r
892 Status = EFI_SUCCESS;\r
1f6729ff 893 IfrFormNvData = NULL;\r
894 ConfigRequest = NULL;\r
d1102dba 895 FormResult = NULL;\r
1f6729ff 896 Size = 0;\r
d1102dba
LG
897 AllocatedRequest = FALSE;\r
898 ConfigRequest = Request;\r
d1050b9d
MK
899 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
900 Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);\r
1f6729ff 901 BufferSize = sizeof (IP4_CONFIG2_IFR_NVDATA);\r
902 *Progress = Request;\r
d1102dba 903\r
1f6729ff 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
d1102dba 912\r
1f6729ff 913 Ip4Config2ConvertConfigNvDataToIfrNvData (Ip4Config2Instance, IfrFormNvData);\r
d1102dba 914\r
1f6729ff 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
d1050b9d
MK
922 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
923 ConfigRequest = AllocateZeroPool (Size);\r
72bdc5f0
FS
924 if (ConfigRequest == NULL) {\r
925 Status = EFI_OUT_OF_RESOURCES;\r
926 goto Failure;\r
927 }\r
d1050b9d 928\r
1f6729ff 929 AllocatedRequest = TRUE;\r
d1102dba 930\r
1f6729ff 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
d1050b9d 941 (UINT8 *)IfrFormNvData,\r
1f6729ff 942 BufferSize,\r
943 &FormResult,\r
944 Progress\r
945 );\r
946\r
947 FreePool (IfrFormNvData);\r
d1102dba 948\r
1f6729ff 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
d1102dba 961\r
d1050b9d 962 if ((Request == NULL) || HiiIsConfigHdrMatch (Request, &gIp4Config2NvDataGuid, mIp4Config2StorageName)) {\r
1f6729ff 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
6c585b52 997 beginning of the string if the failure\r
1f6729ff 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
d1050b9d
MK
1017 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
1018 IN CONST EFI_STRING Configuration,\r
1019 OUT EFI_STRING *Progress\r
1f6729ff 1020 )\r
1021{\r
d1050b9d
MK
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
1f6729ff 1027\r
1028 Status = EFI_SUCCESS;\r
1029 IfrFormNvData = NULL;\r
1030\r
d1050b9d 1031 if ((Configuration == NULL) || (Progress == NULL)) {\r
1f6729ff 1032 return EFI_INVALID_PARAMETER;\r
1033 }\r
1034\r
1035 *Progress = Configuration;\r
1036\r
d1050b9d
MK
1037 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
1038 Ip4Config2Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);\r
1f6729ff 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
d1050b9d 1057 (UINT8 *)IfrFormNvData,\r
1f6729ff 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
d1050b9d 1068 (UINT8 *)IfrFormNvData,\r
1f6729ff 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
1f6729ff 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
6c585b52 1106 callback. Currently not implemented.\r
1f6729ff 1107 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.\r
1108 @retval Others Other errors as indicated.\r
d1102dba 1109\r
1f6729ff 1110**/\r
1111EFI_STATUS\r
1112EFIAPI\r
1113Ip4FormCallback (\r
d1050b9d
MK
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
1f6729ff 1120 )\r
1121{\r
d1050b9d
MK
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
d1102dba 1135\r
1f6729ff 1136 IfrFormNvData = NULL;\r
1137 DnsCount = 0;\r
d1102dba 1138 DnsAddress = NULL;\r
1f6729ff 1139\r
1140 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
d1050b9d
MK
1141 Private = IP4_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
1142 Instance = IP4_CONFIG2_INSTANCE_FROM_FORM_CALLBACK (Private);\r
d1102dba 1143\r
1f6729ff 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
0a18956d 1150 // Retrieve uncommitted data from Browser\r
1f6729ff 1151 //\r
d1050b9d 1152 if (!HiiGetBrowserData (&gIp4Config2NvDataGuid, mIp4Config2StorageName, sizeof (IP4_CONFIG2_IFR_NVDATA), (UINT8 *)IfrFormNvData)) {\r
1f6729ff 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
d1050b9d
MK
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
1f6729ff 1166\r
d1050b9d 1167 break;\r
1f6729ff 1168\r
d1050b9d
MK
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
1f6729ff 1200 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Dns Server!", NULL);\r
d1102dba 1201 }\r
1f6729ff 1202 }\r
d1050b9d
MK
1203\r
1204 if (DnsAddress != NULL) {\r
1205 FreePool (DnsAddress);\r
1f6729ff 1206 }\r
d1102dba 1207\r
d1050b9d 1208 break;\r
d1102dba 1209\r
d1050b9d
MK
1210 case KEY_SAVE_CHANGES:\r
1211 Status = Ip4Config2ConvertIfrNvDataToConfigNvData (IfrFormNvData, Instance);\r
1212 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
1213 break;\r
1f6729ff 1214\r
d1050b9d
MK
1215 default:\r
1216 break;\r
1f6729ff 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
d1102dba 1238\r
1f6729ff 1239**/\r
1240EFI_STATUS\r
1241Ip4Config2FormInit (\r
d1050b9d 1242 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
1f6729ff 1243 )\r
1244{\r
d1050b9d
MK
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
1f6729ff 1256\r
1257 IpSb = IP4_SERVICE_FROM_IP4_CONFIG2_INSTANCE (Instance);\r
1258 ASSERT (IpSb != NULL);\r
d1102dba 1259\r
1f6729ff 1260 CallbackInfo = &Instance->CallbackInfo;\r
d1102dba 1261\r
1f6729ff 1262 CallbackInfo->Signature = IP4_FORM_CALLBACK_INFO_SIGNATURE;\r
1263\r
1264 Status = gBS->HandleProtocol (\r
1265 IpSb->Controller,\r
1266 &gEfiDevicePathProtocolGuid,\r
d1050b9d 1267 (VOID **)&ParentDevicePath\r
1f6729ff 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
d1050b9d 1287 (EFI_DEVICE_PATH_PROTOCOL *)&VendorDeviceNode\r
1f6729ff 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
d1050b9d 1318 (VOID **)&MnpSb,\r
1f6729ff 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
d1102dba
LG
1350 CallbackInfo->RegisteredHandle,\r
1351 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),\r
1f6729ff 1352 NULL\r
1353 );\r
1354 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
1355 HiiSetString (\r
d1102dba
LG
1356 CallbackInfo->RegisteredHandle,\r
1357 STRING_TOKEN (STR_IP4_CONFIG2_FORM_HELP),\r
1358 MenuString,\r
1f6729ff 1359 NULL\r
1360 );\r
1361\r
1362 UnicodeSPrint (PortString, 128, L"MAC:%s", MacString);\r
1363 HiiSetString (\r
d1102dba
LG
1364 CallbackInfo->RegisteredHandle,\r
1365 STRING_TOKEN (STR_IP4_DEVICE_FORM_HELP),\r
1366 PortString,\r
1f6729ff 1367 NULL\r
1368 );\r
d1102dba 1369\r
1f6729ff 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
d1050b9d 1389 IN OUT IP4_CONFIG2_INSTANCE *Instance\r
1f6729ff 1390 )\r
1391{\r
d1050b9d
MK
1392 IP4_SERVICE *IpSb;\r
1393 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
1394 IP4_CONFIG2_NVDATA *Ip4NvData;\r
1f6729ff 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
d1102dba 1411\r
1f6729ff 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
d1050b9d
MK
1438 if (Ip4NvData->ManualAddress != NULL) {\r
1439 FreePool (Ip4NvData->ManualAddress);\r
1f6729ff 1440 }\r
1441\r
d1050b9d
MK
1442 if (Ip4NvData->GatewayAddress != NULL) {\r
1443 FreePool (Ip4NvData->GatewayAddress);\r
1f6729ff 1444 }\r
1445\r
d1050b9d
MK
1446 if (Ip4NvData->DnsAddress != NULL) {\r
1447 FreePool (Ip4NvData->DnsAddress);\r
1f6729ff 1448 }\r
1449\r
1450 Ip4NvData->ManualAddressCount = 0;\r
1451 Ip4NvData->GatewayAddressCount = 0;\r
1452 Ip4NvData->DnsAddressCount = 0;\r
1453}\r