]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c
add security check.
[mirror_edk2.git] / MdeModulePkg / Universal / Network / Ip4ConfigDxe / Ip4ConfigNv.c
CommitLineData
63886849 1/** @file\r
2 Helper functions for configuring or getting the parameters relating to Ip4.\r
3\r
4Copyright (c) 2009, Intel Corporation.<BR>\r
5All rights reserved. This program and the accompanying materials\r
6are licensed and made available under the terms and conditions of the BSD License\r
7which accompanies this distribution. The full text of the license may be found at\r
8http://opensource.org/licenses/bsd-license.php\r
9\r
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,\r
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.\r
12\r
13**/\r
14\r
15#include "Ip4ConfigNv.h"\r
16\r
17GLOBAL_REMOVE_IF_UNREFERENCED CONST CHAR8 Ip4HexString[] = "0123456789ABCDEFabcdef";\r
18\r
19UINTN mNumberOfIp4Devices = 0;\r
20\r
21IP4_FORM_CALLBACK_INFO *mCallbackInfo = NULL;\r
22\r
23LIST_ENTRY mIp4ConfigFormList = {\r
24 &mIp4ConfigFormList,\r
25 &mIp4ConfigFormList\r
26};\r
27\r
28HII_VENDOR_DEVICE_PATH mIp4ConifgHiiVendorDevicePath = {\r
29 {\r
30 {\r
31 HARDWARE_DEVICE_PATH,\r
32 HW_VENDOR_DP,\r
33 {\r
34 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
35 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
36 }\r
37 },\r
38 //\r
39 // {6D3FD906-42B9-4220-9E63-9D8C972D58EE}\r
40 //\r
41 { 0x6d3fd906, 0x42b9, 0x4220, { 0x9e, 0x63, 0x9d, 0x8c, 0x97, 0x2d, 0x58, 0xee } }\r
42 },\r
43 {\r
44 END_DEVICE_PATH_TYPE,\r
45 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
46 {\r
47 (UINT8) (END_DEVICE_PATH_LENGTH),\r
48 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
49 }\r
50 }\r
51};\r
52\r
53/**\r
54 Convert the mac address into a hexadecimal encoded "-" seperated string.\r
55\r
56 @param[in] Mac The mac address.\r
57 @param[in] Len Length in bytes of the mac address.\r
58 @param[out] Str The storage to return the mac string.\r
59\r
60**/\r
61VOID\r
62Ip4MacAddrToStr (\r
63 IN EFI_MAC_ADDRESS *Mac,\r
64 IN UINT32 Len,\r
65 OUT CHAR16 *Str\r
66 )\r
67{\r
68 UINT32 Index;\r
69\r
70 for (Index = 0; Index < Len; Index++) {\r
71 Str[3 * Index] = (CHAR16) Ip4HexString[(Mac->Addr[Index] >> 4) & 0x0F];\r
72 Str[3 * Index + 1] = (CHAR16) Ip4HexString[Mac->Addr[Index] & 0x0F];\r
73 Str[3 * Index + 2] = L'-';\r
74 }\r
75\r
76 Str[3 * Index - 1] = L'\0';\r
77}\r
78\r
79/**\r
80 Calculate the prefix length of the IPv4 subnet mask.\r
81\r
82 @param[in] SubnetMask The IPv4 subnet mask.\r
83\r
84 @return The prefix length of the subnet mask.\r
85 @retval 0 Other errors as indicated.\r
86**/\r
87UINT8\r
88GetSubnetMaskPrefixLength (\r
89 IN EFI_IPv4_ADDRESS *SubnetMask\r
90 )\r
91{\r
92 UINT8 Len;\r
93 UINT32 ReverseMask;\r
94\r
95 //\r
96 // The SubnetMask is in network byte order.\r
97 //\r
98 ReverseMask = (SubnetMask->Addr[0] << 24) | (SubnetMask->Addr[1] << 16) | (SubnetMask->Addr[2] << 8) | (SubnetMask->Addr[3]);\r
99\r
100 //\r
101 // Reverse it.\r
102 //\r
103 ReverseMask = ~ReverseMask;\r
104\r
105 if ((ReverseMask & (ReverseMask + 1)) != 0) {\r
106 return 0;\r
107 }\r
108\r
109 Len = 0;\r
110\r
111 while (ReverseMask != 0) {\r
112 ReverseMask = ReverseMask >> 1;\r
113 Len++;\r
114 }\r
115\r
116 return (UINT8) (32 - Len);\r
117}\r
118\r
119/**\r
120 Convert the decimal dotted IPv4 address into the binary IPv4 address.\r
121\r
122 @param[in] Str The UNICODE string.\r
123 @param[out] Ip The storage to return the ASCII string.\r
124\r
125 @retval EFI_SUCCESS The binary IP address is returned in Ip.\r
126 @retval EFI_INVALID_PARAMETER The IP string is malformatted.\r
127**/\r
128EFI_STATUS\r
129Ip4AsciiStrToIp (\r
130 IN CHAR8 *Str,\r
131 OUT EFI_IPv4_ADDRESS *Ip\r
132 )\r
133{\r
134 UINTN Index;\r
135 UINTN Number;\r
136\r
137 Index = 0;\r
138\r
139 while (*Str != 0) {\r
140\r
141 if (Index > 3) {\r
142 return EFI_INVALID_PARAMETER;\r
143 }\r
144\r
145 Number = 0;\r
146 while (NET_IS_DIGIT (*Str)) {\r
147 Number = Number * 10 + (*Str - '0');\r
148 Str++;\r
149 }\r
150\r
151 if (Number > 0xFF) {\r
152 return EFI_INVALID_PARAMETER;\r
153 }\r
154\r
155 Ip->Addr[Index] = (UINT8) Number;\r
156\r
157 if ((*Str != '\0') && (*Str != '.')) {\r
158 //\r
159 // The current character should be either the NULL terminator or\r
160 // the dot delimiter.\r
161 //\r
162 return EFI_INVALID_PARAMETER;\r
163 }\r
164\r
165 if (*Str == '.') {\r
166 //\r
167 // Skip the delimiter.\r
168 //\r
169 Str++;\r
170 }\r
171\r
172 Index++;\r
173 }\r
174\r
175 if (Index != 4) {\r
176 return EFI_INVALID_PARAMETER;\r
177 }\r
178\r
179 return EFI_SUCCESS;\r
180}\r
181\r
182/**\r
183 Convert the IPv4 address into a dotted string.\r
184\r
185 @param[in] Ip The IPv4 address.\r
186 @param[out] Str The dotted IP string.\r
187**/\r
188VOID\r
189Ip4ConfigIpToStr (\r
190 IN EFI_IPv4_ADDRESS *Ip,\r
191 OUT CHAR16 *Str\r
192 )\r
193{\r
194 UnicodeSPrint (Str, 2 * IP4_STR_MAX_SIZE, L"%d.%d.%d.%d", Ip->Addr[0], Ip->Addr[1], Ip->Addr[2], Ip->Addr[3]);\r
195}\r
196\r
197\r
198/**\r
199 Convert the network configuration data into the IFR data.\r
200\r
201 @param[in] ConfigFormEntry The IP4 configuration form entry.\r
202 @param[out] IfrNvData The IFR nv data.\r
203**/\r
204VOID\r
205Ip4ConfigConvertDeviceConfigDataToIfrNvData (\r
206 IN IP4_CONFIG_INSTANCE *Ip4ConfigInstance,\r
207 OUT IP4_CONFIG_IFR_NVDATA *IfrFormNvData\r
208 )\r
209{\r
210 EFI_STATUS Status;\r
211 NIC_IP4_CONFIG_INFO *NicConfig;\r
212 UINTN ConfigLen;\r
213\r
214 IfrFormNvData->DhcpEnable = 1;\r
215\r
216 ConfigLen = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * 2;\r
217 NicConfig = AllocateZeroPool (ConfigLen);\r
218 ASSERT (NicConfig != NULL);\r
219 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, NicConfig);\r
220 if (!EFI_ERROR (Status)) {\r
221 if (NicConfig->Source == IP4_CONFIG_SOURCE_DHCP) {\r
222 IfrFormNvData->DhcpEnable = 1;\r
223 } else {\r
224 IfrFormNvData->DhcpEnable = 0;\r
225 Ip4ConfigIpToStr (&NicConfig->Ip4Info.StationAddress, IfrFormNvData->StationAddress);\r
226 Ip4ConfigIpToStr (&NicConfig->Ip4Info.SubnetMask, IfrFormNvData->SubnetMask);\r
227 Ip4ConfigIpToStr (&NicConfig->Ip4Info.RouteTable[1].GatewayAddress, IfrFormNvData->GatewayAddress);\r
228 }\r
229 }\r
230 FreePool (NicConfig);\r
231}\r
232\r
233/**\r
234 Get the IP4 configuration form entry by the index of the goto opcode actived.\r
235\r
236 @param[in] Index The 0-based index of the goto opcode actived.\r
237\r
238 @return The IP4 configuration form entry found.\r
239**/\r
240IP4CONFIG_FORM_ENTRY *\r
241Ip4GetConfigFormEntryByIndex (\r
242 IN UINT32 Index\r
243 )\r
244{\r
245 UINT32 CurrentIndex;\r
246 LIST_ENTRY *Entry;\r
247 IP4CONFIG_FORM_ENTRY *ConfigFormEntry;\r
248\r
249 CurrentIndex = 0;\r
250 ConfigFormEntry = NULL;\r
251\r
252 NET_LIST_FOR_EACH (Entry, &mIp4ConfigFormList) {\r
253 if (CurrentIndex == Index) {\r
254 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, IP4CONFIG_FORM_ENTRY, Link);\r
255 break;\r
256 }\r
257\r
258 CurrentIndex++;\r
259 }\r
260\r
261 return ConfigFormEntry;\r
262}\r
263\r
264/**\r
265 This function allows the caller to request the current\r
266 configuration for one or more named elements. The resulting\r
267 string is in <ConfigAltResp> format. Any and all alternative\r
268 configuration strings shall also be appended to the end of the\r
269 current configuration string. If they are, they must appear\r
270 after the current configuration. They must contain the same\r
271 routing (GUID, NAME, PATH) as the current configuration string.\r
272 They must have an additional description indicating the type of\r
273 alternative configuration the string represents,\r
274 "ALTCFG=<StringToken>". That <StringToken> (when\r
275 converted from Hex UNICODE to binary) is a reference to a\r
276 string in the associated string pack.\r
277\r
278 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
279 @param[in] Request A null-terminated Unicode string in\r
280 <ConfigRequest> format. Note that this\r
281 includes the routing information as well as\r
282 the configurable name / value pairs. It is\r
283 invalid for this string to be in\r
284 <MultiConfigRequest> format.\r
285 @param[out] Progress On return, points to a character in the\r
286 Request string. Points to the string's null\r
287 terminator if request was successful. Points\r
288 to the most recent "&" before the first\r
289 failing name / value pair (or the beginning\r
290 of the string if the failure is in the first\r
291 name / value pair) if the request was not\r
292 successful.\r
293 @param[out] Results A null-terminated Unicode string in\r
294 <ConfigAltResp> format which has all values\r
295 filled in for the names in the Request string.\r
296 String to be allocated by the called function.\r
297\r
298 @retval EFI_SUCCESS The Results string is filled with the\r
299 values corresponding to all requested\r
300 names.\r
301 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
302 parts of the results that must be\r
303 stored awaiting possible future\r
304 protocols.\r
305 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
306 for the Request parameter\r
307 would result in this type of\r
308 error. In this case, the\r
309 Progress parameter would be\r
310 set to NULL.\r
311 @retval EFI_NOT_FOUND Routing data doesn't match any\r
312 known driver. Progress set to the\r
313 first character in the routing header.\r
314 Note: There is no requirement that the\r
315 driver validate the routing data. It\r
316 must skip the <ConfigHdr> in order to\r
317 process the names.\r
318 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
319 to most recent & before the\r
320 error or the beginning of the\r
321 string.\r
322 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
323 to the & before the name in\r
324 question.Currently not implemented.\r
325**/\r
326EFI_STATUS\r
327EFIAPI\r
328Ip4DeviceExtractConfig (\r
329 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
330 IN CONST EFI_STRING Request,\r
331 OUT EFI_STRING *Progress,\r
332 OUT EFI_STRING *Results\r
333 )\r
334{\r
335 EFI_STATUS Status;\r
336 UINTN ConfigLen;\r
337 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
338 IP4_FORM_CALLBACK_INFO *Private;\r
339 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
340 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
341\r
342 if (Request == NULL) {\r
343 return EFI_INVALID_PARAMETER;\r
344 }\r
345\r
346 *Progress = Request;\r
347\r
391a0724 348 //\r
349 // Check Request data in <ConfigHdr>.\r
350 //\r
351 if (!HiiIsConfigHdrMatch (Request, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
352 return EFI_NOT_FOUND;\r
353 }\r
354\r
63886849 355 Private = IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
356 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_IP4FORM_CALLBACK_INFO (Private);\r
357\r
358 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
359 if (IfrDeviceNvData == NULL) {\r
360 return EFI_OUT_OF_RESOURCES;\r
361 }\r
362\r
363 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, IfrDeviceNvData);\r
364 if (EFI_ERROR (Status)) {\r
365 FreePool (IfrDeviceNvData);\r
366 return EFI_NOT_FOUND;\r
367 }\r
368\r
369 //\r
370 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
371 //\r
372 HiiConfigRouting = Private->ConfigRouting;\r
373 Status = HiiConfigRouting->BlockToConfig (\r
374 HiiConfigRouting,\r
375 Request,\r
376 (UINT8 *) IfrDeviceNvData,\r
377 NIC_ITEM_CONFIG_SIZE,\r
378 Results,\r
379 Progress\r
380 );\r
381\r
63886849 382 FreePool (IfrDeviceNvData);\r
383\r
384 return Status;\r
385}\r
386\r
387/**\r
388 This function applies changes in a driver's configuration.\r
389 Input is a Configuration, which has the routing data for this\r
390 driver followed by name / value configuration pairs. The driver\r
391 must apply those pairs to its configurable storage. If the\r
392 driver's configuration is stored in a linear block of data\r
393 and the driver's name / value pairs are in <BlockConfig>\r
394 format, it may use the ConfigToBlock helper function (above) to\r
395 simplify the job. Currently not implemented.\r
396\r
397 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
398 @param[in] Configuration A null-terminated Unicode string in\r
399 <ConfigString> format.\r
400 @param[out] Progress A pointer to a string filled in with the\r
401 offset of the most recent '&' before the\r
402 first failing name / value pair (or the\r
403 beginn ing of the string if the failure\r
404 is in the first name / value pair) or\r
405 the terminating NULL if all was\r
406 successful.\r
407\r
408 @retval EFI_SUCCESS The results have been distributed or are\r
409 awaiting distribution.\r
410 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
411 parts of the results that must be\r
412 stored awaiting possible future\r
413 protocols.\r
414 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
415 Results parameter would result\r
416 in this type of error.\r
417 @retval EFI_NOT_FOUND Target for the specified routing data\r
418 was not found.\r
419**/\r
420EFI_STATUS\r
421EFIAPI\r
422Ip4DeviceRouteConfig (\r
423 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
424 IN CONST EFI_STRING Configuration,\r
425 OUT EFI_STRING *Progress\r
426 )\r
427{\r
428 EFI_STATUS Status;\r
429 UINTN BufferSize;\r
430 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
391a0724 431 NIC_IP4_CONFIG_INFO *NicInfo;\r
63886849 432 IP4_FORM_CALLBACK_INFO *Private;\r
433 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
434 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
435 EFI_MAC_ADDRESS ZeroMac;\r
436\r
437 if (Configuration == NULL) {\r
438 return EFI_INVALID_PARAMETER;\r
439 }\r
440\r
441 *Progress = Configuration;\r
442\r
391a0724 443 //\r
444 // Check Routing data in <ConfigHdr>.\r
445 //\r
446 if (!HiiIsConfigHdrMatch (Configuration, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
447 return EFI_NOT_FOUND;\r
448 }\r
449\r
63886849 450 Private = IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
451 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_IP4FORM_CALLBACK_INFO (Private);\r
452\r
453 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
454 if (IfrDeviceNvData == NULL) {\r
455 return EFI_OUT_OF_RESOURCES;\r
456 }\r
457\r
458 //\r
459 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
460 //\r
461 HiiConfigRouting = Private->ConfigRouting;\r
462 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
463 Status = HiiConfigRouting->ConfigToBlock (\r
464 HiiConfigRouting,\r
465 Configuration,\r
466 (UINT8 *) IfrDeviceNvData,\r
467 &BufferSize,\r
468 Progress\r
469 );\r
470 if (!EFI_ERROR (Status)) {\r
471 ZeroMem (&ZeroMac, sizeof (EFI_MAC_ADDRESS));\r
472 if (CompareMem (&IfrDeviceNvData->NicAddr.MacAddr, &ZeroMac, IfrDeviceNvData->NicAddr.Len) != 0) {\r
391a0724 473 BufferSize = sizeof (NIC_IP4_CONFIG_INFO) + sizeof (EFI_IP4_ROUTE_TABLE) * IfrDeviceNvData->Ip4Info.RouteTableSize;\r
474 NicInfo = AllocateCopyPool (BufferSize, IfrDeviceNvData); \r
475 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
63886849 476 } else {\r
477 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE);\r
478 }\r
479 }\r
480\r
63886849 481 FreePool (IfrDeviceNvData);\r
482 return Status;\r
483\r
484}\r
485\r
486/**\r
487 This function allows the caller to request the current\r
488 configuration for one or more named elements. The resulting\r
489 string is in <ConfigAltResp> format. Any and all alternative\r
490 configuration strings shall also be appended to the end of the\r
491 current configuration string. If they are, they must appear\r
492 after the current configuration. They must contain the same\r
493 routing (GUID, NAME, PATH) as the current configuration string.\r
494 They must have an additional description indicating the type of\r
495 alternative configuration the string represents,\r
496 "ALTCFG=<StringToken>". That <StringToken> (when\r
497 converted from Hex UNICODE to binary) is a reference to a\r
498 string in the associated string pack.\r
499\r
500 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
501 @param[in] Request A null-terminated Unicode string in\r
502 <ConfigRequest> format. Note that this\r
503 includes the routing information as well as\r
504 the configurable name / value pairs. It is\r
505 invalid for this string to be in\r
506 <MultiConfigRequest> format.\r
507 @param[out] Progress On return, points to a character in the\r
508 Request string. Points to the string's null\r
509 terminator if request was successful. Points\r
510 to the most recent "&" before the first\r
511 failing name / value pair (or the beginning\r
512 of the string if the failure is in the first\r
513 name / value pair) if the request was not\r
514 successful.\r
515 @param[out] Results A null-terminated Unicode string in\r
516 <ConfigAltResp> format which has all values\r
517 filled in for the names in the Request string.\r
518 String to be allocated by the called function.\r
519\r
520 @retval EFI_SUCCESS The Results string is filled with the\r
521 values corresponding to all requested\r
522 names.\r
523 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
524 parts of the results that must be\r
525 stored awaiting possible future\r
526 protocols.\r
527 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
528 for the Request parameter\r
529 would result in this type of\r
530 error. In this case, the\r
531 Progress parameter would be\r
532 set to NULL.\r
533 @retval EFI_NOT_FOUND Routing data doesn't match any\r
534 known driver. Progress set to the\r
535 first character in the routing header.\r
536 Note: There is no requirement that the\r
537 driver validate the routing data. It\r
538 must skip the <ConfigHdr> in order to\r
539 process the names.\r
540 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
541 to most recent & before the\r
542 error or the beginning of the\r
543 string.\r
544 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
545 to the & before the name in\r
546 question.Currently not implemented.\r
547**/\r
548EFI_STATUS\r
549EFIAPI\r
550Ip4FormExtractConfig (\r
551 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
552 IN CONST EFI_STRING Request,\r
553 OUT EFI_STRING *Progress,\r
554 OUT EFI_STRING *Results\r
555 )\r
556{\r
ae79d2f9
LG
557 if (Request == NULL || Progress == NULL || Results == NULL) {\r
558 return EFI_INVALID_PARAMETER;\r
559 }\r
391a0724 560 *Progress = Request;\r
63886849 561 return EFI_NOT_FOUND;\r
562}\r
563\r
564/**\r
565 This function applies changes in a driver's configuration.\r
566 Input is a Configuration, which has the routing data for this\r
567 driver followed by name / value configuration pairs. The driver\r
568 must apply those pairs to its configurable storage. If the\r
569 driver's configuration is stored in a linear block of data\r
570 and the driver's name / value pairs are in <BlockConfig>\r
571 format, it may use the ConfigToBlock helper function (above) to\r
572 simplify the job. Currently not implemented.\r
573\r
574 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
575 @param[in] Configuration A null-terminated Unicode string in\r
576 <ConfigString> format.\r
577 @param[out] Progress A pointer to a string filled in with the\r
578 offset of the most recent '&' before the\r
579 first failing name / value pair (or the\r
580 beginn ing of the string if the failure\r
581 is in the first name / value pair) or\r
582 the terminating NULL if all was\r
583 successful.\r
584\r
585 @retval EFI_SUCCESS The results have been distributed or are\r
586 awaiting distribution.\r
587 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
588 parts of the results that must be\r
589 stored awaiting possible future\r
590 protocols.\r
591 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
592 Results parameter would result\r
593 in this type of error.\r
594 @retval EFI_NOT_FOUND Target for the specified routing data\r
595 was not found.\r
596**/\r
597EFI_STATUS\r
598EFIAPI\r
599Ip4FormRouteConfig (\r
600 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
601 IN CONST EFI_STRING Configuration,\r
602 OUT EFI_STRING *Progress\r
603 )\r
604{\r
ae79d2f9
LG
605 if (Configuration == NULL || Progress == NULL) {\r
606 return EFI_INVALID_PARAMETER;\r
607 }\r
608\r
609 *Progress = Configuration;\r
610 if (!HiiIsConfigHdrMatch (Configuration, &gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE)) {\r
611 return EFI_NOT_FOUND;\r
612 }\r
613\r
614 *Progress = Configuration + StrLen (Configuration);\r
615 return EFI_SUCCESS;\r
63886849 616}\r
617\r
618/**\r
619 This function is called to provide results data to the driver.\r
620 This data consists of a unique key that is used to identify\r
621 which data is either being passed back or being asked for.\r
622\r
623 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
624 @param[in] Action Specifies the type of action taken by the browser.\r
625 @param[in] QuestionId A unique value which is sent to the original\r
626 exporting driver so that it can identify the type\r
627 of data to expect. The format of the data tends to\r
628 vary based on the opcode that enerated the callback.\r
629 @param[in] Type The type of value for the question.\r
630 @param[in] Value A pointer to the data being sent to the original\r
631 exporting driver.\r
632 @param[out] ActionRequest On return, points to the action requested by the\r
633 callback function.\r
634\r
635 @retval EFI_SUCCESS The callback successfully handled the action.\r
636 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
637 variable and its data.\r
638 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
639 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
640 callback.Currently not implemented.\r
641 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.\r
642 @retval Others Other errors as indicated.\r
643**/\r
644EFI_STATUS\r
645EFIAPI\r
646Ip4FormCallback (\r
647 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
648 IN EFI_BROWSER_ACTION Action,\r
649 IN EFI_QUESTION_ID QuestionId,\r
650 IN UINT8 Type,\r
651 IN EFI_IFR_TYPE_VALUE *Value,\r
652 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
653 )\r
654{\r
655 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
656 IP4_FORM_CALLBACK_INFO *Private;\r
657 CHAR8 Ip4String[IP4_STR_MAX_SIZE];\r
658 CHAR16 PortString[128];\r
659 EFI_STRING_ID DeviceFormTitleToken;\r
660 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
661 IP4CONFIG_FORM_ENTRY *ConfigFormEntry;\r
662 EFI_IP_ADDRESS HostIp;\r
663 EFI_IP_ADDRESS SubnetMask;\r
664 EFI_IP_ADDRESS Gateway;\r
665 EFI_STATUS Status;\r
666 EFI_INPUT_KEY Key;\r
667 NIC_IP4_CONFIG_INFO *NicInfo;\r
668 EFI_IP_ADDRESS Ip;\r
669\r
670 ConfigFormEntry = NULL;\r
671\r
672 Private = IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
673\r
674 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
675 if (IfrFormNvData == NULL) {\r
676 return EFI_OUT_OF_RESOURCES;\r
677 }\r
678\r
679 //\r
680 // Retrive uncommitted data from Browser\r
681 //\r
682 if (!HiiGetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) {\r
683 FreePool (IfrFormNvData);\r
684 return EFI_NOT_FOUND;\r
685 }\r
686\r
687 Status = EFI_SUCCESS;\r
688\r
689 switch (QuestionId) {\r
690\r
691 case KEY_DHCP_ENABLE:\r
692 if (IfrFormNvData->DhcpEnable == 0) {\r
693 Private->Current->SessionConfigData.Enabled = FALSE;\r
694 } else {\r
695 Private->Current->SessionConfigData.Enabled = TRUE;\r
696 }\r
697\r
698 break;\r
699\r
700 case KEY_LOCAL_IP:\r
701 UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String);\r
702 Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4);\r
703 if (EFI_ERROR (Status) || !Ip4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
704 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
705 Status = EFI_INVALID_PARAMETER;\r
706 } else {\r
707 CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
708 }\r
709\r
710 break;\r
711\r
712 case KEY_SUBNET_MASK:\r
713 UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String);\r
714 Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4);\r
715 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
716 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL);\r
717 Status = EFI_INVALID_PARAMETER;\r
718 } else {\r
719 CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
720 }\r
721\r
722 break;\r
723\r
724 case KEY_GATE_WAY:\r
725 UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String);\r
726 Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4);\r
727 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !Ip4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
728 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
729 Status = EFI_INVALID_PARAMETER;\r
730 } else {\r
731 CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
732 }\r
733\r
734 break;\r
735\r
736 case KEY_SAVE_CHANGES:\r
737 Ip4ConfigInstance = Private->Current->Ip4ConfigInstance;\r
738 NicInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE));\r
894d038a 739 ASSERT (NicInfo != NULL);\r
740\r
63886849 741 NicInfo->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (NicInfo + 1);\r
742\r
743 if (!Private->Current->SessionConfigData.Enabled) {\r
744 CopyMem (&HostIp.v4, &Private->Current->SessionConfigData.LocalIp, sizeof (HostIp.v4));\r
745 CopyMem (&SubnetMask.v4, &Private->Current->SessionConfigData.SubnetMask, sizeof (SubnetMask.v4));\r
746 CopyMem (&Gateway.v4, &Private->Current->SessionConfigData.Gateway, sizeof (Gateway.v4));\r
747\r
748 if ((Gateway.Addr[0] != 0)) {\r
749 if (SubnetMask.Addr[0] == 0) {\r
750 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL);\r
751 Status = EFI_INVALID_PARAMETER;\r
752 break;\r
753 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
754 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL);\r
755 Status = EFI_INVALID_PARAMETER;\r
756 break;\r
757 }\r
758 }\r
759\r
760 NicInfo->Source = IP4_CONFIG_SOURCE_STATIC;\r
761 NicInfo->Ip4Info.RouteTableSize = 2;\r
762\r
763 CopyMem (&NicInfo->Ip4Info.StationAddress, &HostIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
764 CopyMem (&NicInfo->Ip4Info.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
765\r
766 Ip.Addr[0] = HostIp.Addr[0] & SubnetMask.Addr[0];\r
767\r
768 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS));\r
769 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
770 CopyMem (&NicInfo->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));\r
771 } else {\r
772 NicInfo->Source = IP4_CONFIG_SOURCE_DHCP;\r
773 }\r
774\r
775 NicInfo->Perment = TRUE;\r
776 CopyMem (&NicInfo->NicAddr, &Ip4ConfigInstance->NicAddr, sizeof (NIC_ADDR));\r
777\r
778 EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
779\r
780 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
781 break;\r
782\r
783 default:\r
784 if ((QuestionId >= KEY_DEVICE_ENTRY_BASE) && (QuestionId < (mNumberOfIp4Devices + KEY_DEVICE_ENTRY_BASE))) {\r
785 //\r
786 // In case goto the device configuration form, update the device form title.\r
787 //\r
788 ConfigFormEntry = Ip4GetConfigFormEntryByIndex ((UINT32) (QuestionId - KEY_DEVICE_ENTRY_BASE));\r
789 ASSERT (ConfigFormEntry != NULL);\r
790\r
791 Ip4ConfigInstance = ConfigFormEntry->Ip4ConfigInstance;\r
792\r
793 UnicodeSPrint (PortString, (UINTN) 128, L"Port %s", ConfigFormEntry->MacString);\r
794 DeviceFormTitleToken = (EFI_STRING_ID) STR_IP4_DEVICE_FORM_TITLE;\r
795 HiiSetString (Private->RegisteredHandle, DeviceFormTitleToken, PortString, NULL);\r
796\r
797 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance, IfrFormNvData);\r
798\r
799 Private->Current = ConfigFormEntry;\r
800 }\r
801\r
802 break;\r
803 }\r
804\r
805 if (!EFI_ERROR (Status)) {\r
806\r
807 //\r
808 // Pass changed uncommitted data back to Form Browser\r
809 //\r
810 HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL);\r
811 }\r
812\r
813 FreePool (IfrFormNvData);\r
814 return Status;\r
815}\r
816\r
817/**\r
818 Install HII Config Access protocol for network device and allocate resource.\r
819\r
820 @param[in] Instance The IP4 Config instance.\r
821\r
822 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
823 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
824 @retval Others Other errors as indicated.\r
825**/\r
826EFI_STATUS\r
827Ip4ConfigDeviceInit (\r
828 IN IP4_CONFIG_INSTANCE *Instance\r
829 )\r
830{\r
831 EFI_STATUS Status;\r
832 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
833 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
834\r
835 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);\r
836 if (EFI_ERROR (Status)) {\r
837 return Status;\r
838 }\r
839\r
840 CallbackInfo = &Instance->Ip4FormCallbackInfo;\r
841\r
842 CallbackInfo->Signature = IP4CONFIG_FORM_CALLBACK_INFO_SIGNATURE;\r
843 CallbackInfo->HiiDatabase = HiiDatabase;\r
844\r
845 CallbackInfo->ConfigAccess.ExtractConfig = Ip4DeviceExtractConfig;\r
846 CallbackInfo->ConfigAccess.RouteConfig = Ip4DeviceRouteConfig;\r
847 CallbackInfo->ConfigAccess.Callback = NULL;\r
848\r
849 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&CallbackInfo->ConfigRouting);\r
850 if (EFI_ERROR (Status)) {\r
851 return Status;\r
852 }\r
853\r
854 CallbackInfo->DriverHandle = Instance->Controller;\r
855 //\r
856 // Install Device Path Protocol and Config Access protocol to driver handle\r
857 //\r
858 Status = gBS->InstallMultipleProtocolInterfaces (\r
859 &CallbackInfo->DriverHandle,\r
860 &gEfiHiiConfigAccessProtocolGuid,\r
861 &CallbackInfo->ConfigAccess,\r
862 NULL\r
863 );\r
864 ASSERT_EFI_ERROR (Status);\r
865\r
866 return Status;\r
867}\r
868\r
869/**\r
870 Uninstall HII Config Access protocol for network device and free resource.\r
871\r
872 @param[in] Instance The IP4 Config instance.\r
873\r
874 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.\r
875 @retval Others Other errors as indicated.\r
876**/\r
877EFI_STATUS\r
878Ip4ConfigDeviceUnload (\r
879 IN IP4_CONFIG_INSTANCE *Instance\r
880 )\r
881{\r
882 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
883\r
884 CallbackInfo = &Instance->Ip4FormCallbackInfo;\r
885\r
886 Ip4ConfigUpdateForm (Instance, FALSE);\r
887\r
888 //\r
889 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
890 //\r
891 gBS->UninstallMultipleProtocolInterfaces (\r
892 CallbackInfo->DriverHandle,\r
893 &gEfiHiiConfigAccessProtocolGuid,\r
894 &CallbackInfo->ConfigAccess,\r
895 NULL\r
896 );\r
897\r
898 return EFI_SUCCESS;\r
899}\r
900\r
901/**\r
902 Unload the network configuration form, this includes: delete all the network\r
903 device configuration entries, uninstall the form callback protocol and\r
904 free the resources used.\r
905\r
906 @retval EFI_SUCCESS The network configuration form is unloaded.\r
907**/\r
908EFI_STATUS\r
909Ip4ConfigFormUnload (\r
910 VOID\r
911 )\r
912{\r
913 IP4CONFIG_FORM_ENTRY *ConfigFormEntry;\r
914\r
915 while (!IsListEmpty (&mIp4ConfigFormList)) {\r
916 //\r
917 // Uninstall the device forms as the network driver instance may fail to\r
918 // control the controller but still install the device configuration form.\r
919 // In such case, upon driver unloading, the driver instance's driverbinding.\r
920 // stop () won't be called, so we have to take this chance here to uninstall\r
921 // the device form.\r
922 //\r
923 ConfigFormEntry = NET_LIST_USER_STRUCT (mIp4ConfigFormList.ForwardLink, IP4CONFIG_FORM_ENTRY, Link);\r
924 Ip4ConfigUpdateForm (ConfigFormEntry->Ip4ConfigInstance, FALSE);\r
925 }\r
926\r
927 //\r
928 // Remove HII package list\r
929 //\r
930 mCallbackInfo->HiiDatabase->RemovePackageList (\r
931 mCallbackInfo->HiiDatabase,\r
932 mCallbackInfo->RegisteredHandle\r
933 );\r
934\r
935 //\r
936 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
937 //\r
938 gBS->UninstallMultipleProtocolInterfaces (\r
939 mCallbackInfo->DriverHandle,\r
940 &gEfiDevicePathProtocolGuid,\r
941 &mIp4ConifgHiiVendorDevicePath,\r
942 &gEfiHiiConfigAccessProtocolGuid,\r
943 &mCallbackInfo->ConfigAccess,\r
944 NULL\r
945 );\r
946\r
947 FreePool (mCallbackInfo);\r
948\r
949 return EFI_SUCCESS;\r
950}\r
951\r
952/**\r
953 Updates the network configuration form to add/delete an entry for the network\r
954 device specified by the Instance.\r
955\r
956 @param[in] Instance The IP4 Config instance.\r
957 @param[in] AddForm Whether to add or delete a form entry.\r
958\r
959 @retval EFI_SUCCESS The network configuration form is updated.\r
960 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
961 @retval Others Other errors as indicated.\r
962**/\r
963EFI_STATUS\r
964Ip4ConfigUpdateForm (\r
965 IN IP4_CONFIG_INSTANCE *Instance,\r
966 IN BOOLEAN AddForm\r
967 )\r
968{\r
969 LIST_ENTRY *Entry;\r
970 IP4CONFIG_FORM_ENTRY *ConfigFormEntry;\r
971 BOOLEAN EntryExisted;\r
972 EFI_STATUS Status;\r
973 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
974 CHAR16 PortString[128];\r
975 UINT16 FormIndex;\r
976 VOID *StartOpCodeHandle;\r
977 VOID *EndOpCodeHandle;\r
978 EFI_IFR_GUID_LABEL *StartLabel;\r
979 EFI_IFR_GUID_LABEL *EndLabel;\r
980\r
981 ConfigFormEntry = NULL;\r
982 EntryExisted = FALSE;\r
983\r
984 NET_LIST_FOR_EACH (Entry, &mIp4ConfigFormList) {\r
985 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, IP4CONFIG_FORM_ENTRY, Link);\r
986\r
987 if (ConfigFormEntry->Controller == Instance->Controller) {\r
988 EntryExisted = TRUE;\r
989 break;\r
990 }\r
991 }\r
992\r
993 if (AddForm) {\r
994 if (EntryExisted) {\r
995 return EFI_SUCCESS;\r
996 } else {\r
997 //\r
998 // Add a new form.\r
999 //\r
1000 ConfigFormEntry = (IP4CONFIG_FORM_ENTRY *) AllocateZeroPool (sizeof (IP4CONFIG_FORM_ENTRY));\r
1001 if (ConfigFormEntry == NULL) {\r
1002 return EFI_OUT_OF_RESOURCES;\r
1003 }\r
1004\r
1005 ConfigFormEntry->Ip4ConfigInstance = Instance;\r
1006 InitializeListHead (&ConfigFormEntry->Link);\r
1007 ConfigFormEntry->Controller = Instance->Controller;\r
1008\r
1009 //\r
1010 // Get the simple network protocol and convert the MAC address into\r
1011 // the formatted string.\r
1012 //\r
1013 Status = gBS->HandleProtocol (\r
1014 Instance->Controller,\r
1015 &gEfiSimpleNetworkProtocolGuid,\r
1016 (VOID **)&Snp\r
1017 );\r
1018 ASSERT (Status == EFI_SUCCESS);\r
1019\r
1020 Ip4MacAddrToStr (&Snp->Mode->PermanentAddress, Snp->Mode->HwAddressSize, ConfigFormEntry->MacString);\r
1021\r
1022 //\r
1023 // Compose the Port string and create a new EFI_STRING_ID.\r
1024 //\r
1025 UnicodeSPrint (PortString, 128, L"%s %s", Instance->NicName, ConfigFormEntry->MacString);\r
1026 ConfigFormEntry->PortTitleToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, PortString, NULL);\r
1027\r
1028 //\r
1029 // Compose the help string of this port and create a new EFI_STRING_ID.\r
1030 //\r
1031 UnicodeSPrint (PortString, 128, L"Set the network parameters on eth%d %s", 0, ConfigFormEntry->MacString);\r
1032 ConfigFormEntry->PortTitleHelpToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, PortString, NULL);\r
1033\r
1034 InsertTailList (&mIp4ConfigFormList, &ConfigFormEntry->Link);\r
1035 mNumberOfIp4Devices++;\r
1036 }\r
1037 } else {\r
1038 ASSERT (EntryExisted);\r
1039\r
1040 mNumberOfIp4Devices--;\r
1041 RemoveEntryList (&ConfigFormEntry->Link);\r
1042 gBS->FreePool (ConfigFormEntry);\r
1043 }\r
1044\r
1045 //\r
1046 // Init OpCode Handle\r
1047 //\r
1048 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1049 ASSERT (StartOpCodeHandle != NULL);\r
1050\r
1051 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1052 ASSERT (EndOpCodeHandle != NULL);\r
1053\r
1054 //\r
1055 // Create Hii Extend Label OpCode as the start opcode\r
1056 //\r
1057 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1058 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1059 StartLabel->Number = DEVICE_ENTRY_LABEL;\r
1060\r
1061 //\r
1062 // Create Hii Extend Label OpCode as the end opcode\r
1063 //\r
1064 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1065 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1066 EndLabel->Number = LABEL_END;\r
1067\r
1068 FormIndex = 0;\r
1069\r
1070 FormIndex = 0;\r
1071 NET_LIST_FOR_EACH (Entry, &mIp4ConfigFormList) {\r
1072 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, IP4CONFIG_FORM_ENTRY, Link);\r
1073\r
1074 HiiCreateGotoOpCode (\r
1075 StartOpCodeHandle, // Container for dynamic created opcodes\r
1076 FORMID_DEVICE_FORM, // Target Form ID\r
1077 ConfigFormEntry->PortTitleToken, // Prompt text\r
1078 ConfigFormEntry->PortTitleHelpToken, // Help text\r
1079 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1080 (UINT16)(KEY_DEVICE_ENTRY_BASE + FormIndex) // Question ID\r
1081 );\r
1082\r
1083 FormIndex++;\r
1084 }\r
1085\r
1086 HiiUpdateForm (\r
1087 mCallbackInfo->RegisteredHandle,\r
1088 &gEfiNicIp4ConfigVariableGuid,\r
1089 FORMID_MAIN_FORM,\r
1090 StartOpCodeHandle, // Label DEVICE_ENTRY_LABEL\r
1091 EndOpCodeHandle // LABEL_END\r
1092 );\r
1093\r
1094 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1095 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1096\r
1097 return EFI_SUCCESS;\r
1098}\r
1099\r
1100/**\r
1101 Initialize the network configuration form, this includes: delete all the network\r
1102 device configuration entries, install the form callback protocol and\r
1103 allocate the resources used.\r
1104\r
1105 @retval EFI_SUCCESS The network configuration form is unloaded.\r
1106 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1107**/\r
1108EFI_STATUS\r
1109Ip4ConfigFormInit (\r
1110 VOID\r
1111 )\r
1112{\r
1113 EFI_STATUS Status;\r
1114 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
1115 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
1116\r
1117 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);\r
1118 if (EFI_ERROR (Status)) {\r
1119 return Status;\r
1120 }\r
1121\r
1122 CallbackInfo = (IP4_FORM_CALLBACK_INFO *) AllocateZeroPool (sizeof (IP4_FORM_CALLBACK_INFO));\r
1123 if (CallbackInfo == NULL) {\r
1124 return EFI_OUT_OF_RESOURCES;\r
1125 }\r
1126\r
1127 CallbackInfo->Signature = IP4CONFIG_FORM_CALLBACK_INFO_SIGNATURE;\r
1128 CallbackInfo->HiiDatabase = HiiDatabase;\r
1129\r
1130 CallbackInfo->ConfigAccess.ExtractConfig = Ip4FormExtractConfig;\r
1131 CallbackInfo->ConfigAccess.RouteConfig = Ip4FormRouteConfig;\r
1132 CallbackInfo->ConfigAccess.Callback = Ip4FormCallback;\r
1133\r
1134 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&CallbackInfo->ConfigRouting);\r
1135 if (EFI_ERROR (Status)) {\r
1136 return Status;\r
1137 }\r
1138\r
1139 CallbackInfo->DriverHandle = NULL;\r
1140 //\r
1141 // Install Device Path Protocol and Config Access protocol to driver handle\r
1142 //\r
1143 Status = gBS->InstallMultipleProtocolInterfaces (\r
1144 &CallbackInfo->DriverHandle,\r
1145 &gEfiDevicePathProtocolGuid,\r
1146 &mIp4ConifgHiiVendorDevicePath,\r
1147 &gEfiHiiConfigAccessProtocolGuid,\r
1148 &CallbackInfo->ConfigAccess,\r
1149 NULL\r
1150 );\r
1151 ASSERT_EFI_ERROR (Status);\r
1152\r
1153 //\r
1154 // Publish our HII data\r
1155 //\r
1156 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
1157 &gEfiNicIp4ConfigVariableGuid,\r
1158 CallbackInfo->DriverHandle,\r
1159 Ip4ConfigDxeStrings,\r
1160 Ip4ConfigDxeBin,\r
1161 NULL\r
1162 );\r
1163 if (CallbackInfo->RegisteredHandle == NULL) {\r
1164 return EFI_OUT_OF_RESOURCES;\r
1165 }\r
1166\r
1167 mCallbackInfo = CallbackInfo;\r
1168\r
1169 return Status;\r
1170}\r