]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Universal/Network/Ip4ConfigDxe/Ip4ConfigNv.c
Fix K8 and Sct failure.
[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
348 Private = IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
349 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_IP4FORM_CALLBACK_INFO (Private);\r
350\r
351 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
352 if (IfrDeviceNvData == NULL) {\r
353 return EFI_OUT_OF_RESOURCES;\r
354 }\r
355\r
356 Status = EfiNicIp4ConfigGetInfo (Ip4ConfigInstance, &ConfigLen, IfrDeviceNvData);\r
357 if (EFI_ERROR (Status)) {\r
358 FreePool (IfrDeviceNvData);\r
359 return EFI_NOT_FOUND;\r
360 }\r
361\r
362 //\r
363 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
364 //\r
365 HiiConfigRouting = Private->ConfigRouting;\r
366 Status = HiiConfigRouting->BlockToConfig (\r
367 HiiConfigRouting,\r
368 Request,\r
369 (UINT8 *) IfrDeviceNvData,\r
370 NIC_ITEM_CONFIG_SIZE,\r
371 Results,\r
372 Progress\r
373 );\r
374\r
375 *Progress = Request + StrLen (Request);\r
376 FreePool (IfrDeviceNvData);\r
377\r
378 return Status;\r
379}\r
380\r
381/**\r
382 This function applies changes in a driver's configuration.\r
383 Input is a Configuration, which has the routing data for this\r
384 driver followed by name / value configuration pairs. The driver\r
385 must apply those pairs to its configurable storage. If the\r
386 driver's configuration is stored in a linear block of data\r
387 and the driver's name / value pairs are in <BlockConfig>\r
388 format, it may use the ConfigToBlock helper function (above) to\r
389 simplify the job. Currently not implemented.\r
390\r
391 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
392 @param[in] Configuration A null-terminated Unicode string in\r
393 <ConfigString> format.\r
394 @param[out] Progress A pointer to a string filled in with the\r
395 offset of the most recent '&' before the\r
396 first failing name / value pair (or the\r
397 beginn ing of the string if the failure\r
398 is in the first name / value pair) or\r
399 the terminating NULL if all was\r
400 successful.\r
401\r
402 @retval EFI_SUCCESS The results have been distributed or are\r
403 awaiting distribution.\r
404 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
405 parts of the results that must be\r
406 stored awaiting possible future\r
407 protocols.\r
408 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
409 Results parameter would result\r
410 in this type of error.\r
411 @retval EFI_NOT_FOUND Target for the specified routing data\r
412 was not found.\r
413**/\r
414EFI_STATUS\r
415EFIAPI\r
416Ip4DeviceRouteConfig (\r
417 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
418 IN CONST EFI_STRING Configuration,\r
419 OUT EFI_STRING *Progress\r
420 )\r
421{\r
422 EFI_STATUS Status;\r
423 UINTN BufferSize;\r
424 NIC_IP4_CONFIG_INFO *IfrDeviceNvData;\r
425 IP4_FORM_CALLBACK_INFO *Private;\r
426 EFI_HII_CONFIG_ROUTING_PROTOCOL *HiiConfigRouting;\r
427 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
428 EFI_MAC_ADDRESS ZeroMac;\r
429\r
430 if (Configuration == NULL) {\r
431 return EFI_INVALID_PARAMETER;\r
432 }\r
433\r
434 *Progress = Configuration;\r
435\r
436 Private = IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
437 Ip4ConfigInstance = IP4_CONFIG_INSTANCE_FROM_IP4FORM_CALLBACK_INFO (Private);\r
438\r
439 IfrDeviceNvData = AllocateZeroPool (NIC_ITEM_CONFIG_SIZE);\r
440 if (IfrDeviceNvData == NULL) {\r
441 return EFI_OUT_OF_RESOURCES;\r
442 }\r
443\r
444 //\r
445 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
446 //\r
447 HiiConfigRouting = Private->ConfigRouting;\r
448 BufferSize = NIC_ITEM_CONFIG_SIZE;\r
449 Status = HiiConfigRouting->ConfigToBlock (\r
450 HiiConfigRouting,\r
451 Configuration,\r
452 (UINT8 *) IfrDeviceNvData,\r
453 &BufferSize,\r
454 Progress\r
455 );\r
456 if (!EFI_ERROR (Status)) {\r
457 ZeroMem (&ZeroMac, sizeof (EFI_MAC_ADDRESS));\r
458 if (CompareMem (&IfrDeviceNvData->NicAddr.MacAddr, &ZeroMac, IfrDeviceNvData->NicAddr.Len) != 0) {\r
459 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, IfrDeviceNvData, TRUE);\r
460 } else {\r
461 Status = EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NULL, TRUE);\r
462 }\r
463 }\r
464\r
465 *Progress = Configuration + StrLen (Configuration);\r
466 FreePool (IfrDeviceNvData);\r
467 return Status;\r
468\r
469}\r
470\r
471/**\r
472 This function allows the caller to request the current\r
473 configuration for one or more named elements. The resulting\r
474 string is in <ConfigAltResp> format. Any and all alternative\r
475 configuration strings shall also be appended to the end of the\r
476 current configuration string. If they are, they must appear\r
477 after the current configuration. They must contain the same\r
478 routing (GUID, NAME, PATH) as the current configuration string.\r
479 They must have an additional description indicating the type of\r
480 alternative configuration the string represents,\r
481 "ALTCFG=<StringToken>". That <StringToken> (when\r
482 converted from Hex UNICODE to binary) is a reference to a\r
483 string in the associated string pack.\r
484\r
485 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
486 @param[in] Request A null-terminated Unicode string in\r
487 <ConfigRequest> format. Note that this\r
488 includes the routing information as well as\r
489 the configurable name / value pairs. It is\r
490 invalid for this string to be in\r
491 <MultiConfigRequest> format.\r
492 @param[out] Progress On return, points to a character in the\r
493 Request string. Points to the string's null\r
494 terminator if request was successful. Points\r
495 to the most recent "&" before the first\r
496 failing name / value pair (or the beginning\r
497 of the string if the failure is in the first\r
498 name / value pair) if the request was not\r
499 successful.\r
500 @param[out] Results A null-terminated Unicode string in\r
501 <ConfigAltResp> format which has all values\r
502 filled in for the names in the Request string.\r
503 String to be allocated by the called function.\r
504\r
505 @retval EFI_SUCCESS The Results string is filled with the\r
506 values corresponding to all requested\r
507 names.\r
508 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
509 parts of the results that must be\r
510 stored awaiting possible future\r
511 protocols.\r
512 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
513 for the Request parameter\r
514 would result in this type of\r
515 error. In this case, the\r
516 Progress parameter would be\r
517 set to NULL.\r
518 @retval EFI_NOT_FOUND Routing data doesn't match any\r
519 known driver. Progress set to the\r
520 first character in the routing header.\r
521 Note: There is no requirement that the\r
522 driver validate the routing data. It\r
523 must skip the <ConfigHdr> in order to\r
524 process the names.\r
525 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
526 to most recent & before the\r
527 error or the beginning of the\r
528 string.\r
529 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
530 to the & before the name in\r
531 question.Currently not implemented.\r
532**/\r
533EFI_STATUS\r
534EFIAPI\r
535Ip4FormExtractConfig (\r
536 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
537 IN CONST EFI_STRING Request,\r
538 OUT EFI_STRING *Progress,\r
539 OUT EFI_STRING *Results\r
540 )\r
541{\r
542 return EFI_NOT_FOUND;\r
543}\r
544\r
545/**\r
546 This function applies changes in a driver's configuration.\r
547 Input is a Configuration, which has the routing data for this\r
548 driver followed by name / value configuration pairs. The driver\r
549 must apply those pairs to its configurable storage. If the\r
550 driver's configuration is stored in a linear block of data\r
551 and the driver's name / value pairs are in <BlockConfig>\r
552 format, it may use the ConfigToBlock helper function (above) to\r
553 simplify the job. Currently not implemented.\r
554\r
555 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
556 @param[in] Configuration A null-terminated Unicode string in\r
557 <ConfigString> format.\r
558 @param[out] Progress A pointer to a string filled in with the\r
559 offset of the most recent '&' before the\r
560 first failing name / value pair (or the\r
561 beginn ing of the string if the failure\r
562 is in the first name / value pair) or\r
563 the terminating NULL if all was\r
564 successful.\r
565\r
566 @retval EFI_SUCCESS The results have been distributed or are\r
567 awaiting distribution.\r
568 @retval EFI_OUT_OF_MEMORY Not enough memory to store the\r
569 parts of the results that must be\r
570 stored awaiting possible future\r
571 protocols.\r
572 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
573 Results parameter would result\r
574 in this type of error.\r
575 @retval EFI_NOT_FOUND Target for the specified routing data\r
576 was not found.\r
577**/\r
578EFI_STATUS\r
579EFIAPI\r
580Ip4FormRouteConfig (\r
581 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
582 IN CONST EFI_STRING Configuration,\r
583 OUT EFI_STRING *Progress\r
584 )\r
585{\r
586 return EFI_NOT_FOUND;\r
587}\r
588\r
589/**\r
590 This function is called to provide results data to the driver.\r
591 This data consists of a unique key that is used to identify\r
592 which data is either being passed back or being asked for.\r
593\r
594 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
595 @param[in] Action Specifies the type of action taken by the browser.\r
596 @param[in] QuestionId A unique value which is sent to the original\r
597 exporting driver so that it can identify the type\r
598 of data to expect. The format of the data tends to\r
599 vary based on the opcode that enerated the callback.\r
600 @param[in] Type The type of value for the question.\r
601 @param[in] Value A pointer to the data being sent to the original\r
602 exporting driver.\r
603 @param[out] ActionRequest On return, points to the action requested by the\r
604 callback function.\r
605\r
606 @retval EFI_SUCCESS The callback successfully handled the action.\r
607 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
608 variable and its data.\r
609 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
610 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
611 callback.Currently not implemented.\r
612 @retval EFI_INVALID_PARAMETERS Passing in wrong parameter.\r
613 @retval Others Other errors as indicated.\r
614**/\r
615EFI_STATUS\r
616EFIAPI\r
617Ip4FormCallback (\r
618 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
619 IN EFI_BROWSER_ACTION Action,\r
620 IN EFI_QUESTION_ID QuestionId,\r
621 IN UINT8 Type,\r
622 IN EFI_IFR_TYPE_VALUE *Value,\r
623 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
624 )\r
625{\r
626 IP4_CONFIG_INSTANCE *Ip4ConfigInstance;\r
627 IP4_FORM_CALLBACK_INFO *Private;\r
628 CHAR8 Ip4String[IP4_STR_MAX_SIZE];\r
629 CHAR16 PortString[128];\r
630 EFI_STRING_ID DeviceFormTitleToken;\r
631 IP4_CONFIG_IFR_NVDATA *IfrFormNvData;\r
632 IP4CONFIG_FORM_ENTRY *ConfigFormEntry;\r
633 EFI_IP_ADDRESS HostIp;\r
634 EFI_IP_ADDRESS SubnetMask;\r
635 EFI_IP_ADDRESS Gateway;\r
636 EFI_STATUS Status;\r
637 EFI_INPUT_KEY Key;\r
638 NIC_IP4_CONFIG_INFO *NicInfo;\r
639 EFI_IP_ADDRESS Ip;\r
640\r
641 ConfigFormEntry = NULL;\r
642\r
643 Private = IP4CONFIG_FORM_CALLBACK_INFO_FROM_FORM_CALLBACK (This);\r
644\r
645 IfrFormNvData = AllocateZeroPool (sizeof (IP4_CONFIG_IFR_NVDATA));\r
646 if (IfrFormNvData == NULL) {\r
647 return EFI_OUT_OF_RESOURCES;\r
648 }\r
649\r
650 //\r
651 // Retrive uncommitted data from Browser\r
652 //\r
653 if (!HiiGetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData)) {\r
654 FreePool (IfrFormNvData);\r
655 return EFI_NOT_FOUND;\r
656 }\r
657\r
658 Status = EFI_SUCCESS;\r
659\r
660 switch (QuestionId) {\r
661\r
662 case KEY_DHCP_ENABLE:\r
663 if (IfrFormNvData->DhcpEnable == 0) {\r
664 Private->Current->SessionConfigData.Enabled = FALSE;\r
665 } else {\r
666 Private->Current->SessionConfigData.Enabled = TRUE;\r
667 }\r
668\r
669 break;\r
670\r
671 case KEY_LOCAL_IP:\r
672 UnicodeStrToAsciiStr (IfrFormNvData->StationAddress, Ip4String);\r
673 Status = Ip4AsciiStrToIp (Ip4String, &HostIp.v4);\r
674 if (EFI_ERROR (Status) || !Ip4IsUnicast (NTOHL (HostIp.Addr[0]), 0)) {\r
675 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid IP address!", NULL);\r
676 Status = EFI_INVALID_PARAMETER;\r
677 } else {\r
678 CopyMem (&Private->Current->SessionConfigData.LocalIp, &HostIp.v4, sizeof (HostIp.v4));\r
679 }\r
680\r
681 break;\r
682\r
683 case KEY_SUBNET_MASK:\r
684 UnicodeStrToAsciiStr (IfrFormNvData->SubnetMask, Ip4String);\r
685 Status = Ip4AsciiStrToIp (Ip4String, &SubnetMask.v4);\r
686 if (EFI_ERROR (Status) || ((SubnetMask.Addr[0] != 0) && (GetSubnetMaskPrefixLength (&SubnetMask.v4) == 0))) {\r
687 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid SubnetMask!", NULL);\r
688 Status = EFI_INVALID_PARAMETER;\r
689 } else {\r
690 CopyMem (&Private->Current->SessionConfigData.SubnetMask, &SubnetMask.v4, sizeof (SubnetMask.v4));\r
691 }\r
692\r
693 break;\r
694\r
695 case KEY_GATE_WAY:\r
696 UnicodeStrToAsciiStr (IfrFormNvData->GatewayAddress, Ip4String);\r
697 Status = Ip4AsciiStrToIp (Ip4String, &Gateway.v4);\r
698 if (EFI_ERROR (Status) || ((Gateway.Addr[0] != 0) && !Ip4IsUnicast (NTOHL (Gateway.Addr[0]), 0))) {\r
699 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Invalid Gateway!", NULL);\r
700 Status = EFI_INVALID_PARAMETER;\r
701 } else {\r
702 CopyMem (&Private->Current->SessionConfigData.Gateway, &Gateway.v4, sizeof (Gateway.v4));\r
703 }\r
704\r
705 break;\r
706\r
707 case KEY_SAVE_CHANGES:\r
708 Ip4ConfigInstance = Private->Current->Ip4ConfigInstance;\r
709 NicInfo = AllocateZeroPool (sizeof (NIC_IP4_CONFIG_INFO) + 2 * sizeof (EFI_IP4_ROUTE_TABLE));\r
710 NicInfo->Ip4Info.RouteTable = (EFI_IP4_ROUTE_TABLE *) (NicInfo + 1);\r
711\r
712 if (!Private->Current->SessionConfigData.Enabled) {\r
713 CopyMem (&HostIp.v4, &Private->Current->SessionConfigData.LocalIp, sizeof (HostIp.v4));\r
714 CopyMem (&SubnetMask.v4, &Private->Current->SessionConfigData.SubnetMask, sizeof (SubnetMask.v4));\r
715 CopyMem (&Gateway.v4, &Private->Current->SessionConfigData.Gateway, sizeof (Gateway.v4));\r
716\r
717 if ((Gateway.Addr[0] != 0)) {\r
718 if (SubnetMask.Addr[0] == 0) {\r
719 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Gateway address is set but subnet mask is zero.", NULL);\r
720 Status = EFI_INVALID_PARAMETER;\r
721 break;\r
722 } else if (!IP4_NET_EQUAL (HostIp.Addr[0], Gateway.Addr[0], SubnetMask.Addr[0])) {\r
723 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, L"Local IP and Gateway are not in the same subnet.", NULL);\r
724 Status = EFI_INVALID_PARAMETER;\r
725 break;\r
726 }\r
727 }\r
728\r
729 NicInfo->Source = IP4_CONFIG_SOURCE_STATIC;\r
730 NicInfo->Ip4Info.RouteTableSize = 2;\r
731\r
732 CopyMem (&NicInfo->Ip4Info.StationAddress, &HostIp.v4, sizeof (EFI_IPv4_ADDRESS));\r
733 CopyMem (&NicInfo->Ip4Info.SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
734\r
735 Ip.Addr[0] = HostIp.Addr[0] & SubnetMask.Addr[0];\r
736\r
737 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetAddress, &Ip.v4, sizeof (EFI_IPv4_ADDRESS));\r
738 CopyMem (&NicInfo->Ip4Info.RouteTable[0].SubnetMask, &SubnetMask.v4, sizeof (EFI_IPv4_ADDRESS));\r
739 CopyMem (&NicInfo->Ip4Info.RouteTable[1].GatewayAddress, &Gateway.v4, sizeof (EFI_IPv4_ADDRESS));\r
740 } else {\r
741 NicInfo->Source = IP4_CONFIG_SOURCE_DHCP;\r
742 }\r
743\r
744 NicInfo->Perment = TRUE;\r
745 CopyMem (&NicInfo->NicAddr, &Ip4ConfigInstance->NicAddr, sizeof (NIC_ADDR));\r
746\r
747 EfiNicIp4ConfigSetInfo (Ip4ConfigInstance, NicInfo, TRUE);\r
748\r
749 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
750 break;\r
751\r
752 default:\r
753 if ((QuestionId >= KEY_DEVICE_ENTRY_BASE) && (QuestionId < (mNumberOfIp4Devices + KEY_DEVICE_ENTRY_BASE))) {\r
754 //\r
755 // In case goto the device configuration form, update the device form title.\r
756 //\r
757 ConfigFormEntry = Ip4GetConfigFormEntryByIndex ((UINT32) (QuestionId - KEY_DEVICE_ENTRY_BASE));\r
758 ASSERT (ConfigFormEntry != NULL);\r
759\r
760 Ip4ConfigInstance = ConfigFormEntry->Ip4ConfigInstance;\r
761\r
762 UnicodeSPrint (PortString, (UINTN) 128, L"Port %s", ConfigFormEntry->MacString);\r
763 DeviceFormTitleToken = (EFI_STRING_ID) STR_IP4_DEVICE_FORM_TITLE;\r
764 HiiSetString (Private->RegisteredHandle, DeviceFormTitleToken, PortString, NULL);\r
765\r
766 Ip4ConfigConvertDeviceConfigDataToIfrNvData (Ip4ConfigInstance, IfrFormNvData);\r
767\r
768 Private->Current = ConfigFormEntry;\r
769 }\r
770\r
771 break;\r
772 }\r
773\r
774 if (!EFI_ERROR (Status)) {\r
775\r
776 //\r
777 // Pass changed uncommitted data back to Form Browser\r
778 //\r
779 HiiSetBrowserData (&gEfiNicIp4ConfigVariableGuid, EFI_NIC_IP4_CONFIG_VARIABLE, sizeof (IP4_CONFIG_IFR_NVDATA), (UINT8 *) IfrFormNvData, NULL);\r
780 }\r
781\r
782 FreePool (IfrFormNvData);\r
783 return Status;\r
784}\r
785\r
786/**\r
787 Install HII Config Access protocol for network device and allocate resource.\r
788\r
789 @param[in] Instance The IP4 Config instance.\r
790\r
791 @retval EFI_SUCCESS The HII Config Access protocol is installed.\r
792 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
793 @retval Others Other errors as indicated.\r
794**/\r
795EFI_STATUS\r
796Ip4ConfigDeviceInit (\r
797 IN IP4_CONFIG_INSTANCE *Instance\r
798 )\r
799{\r
800 EFI_STATUS Status;\r
801 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
802 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
803\r
804 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);\r
805 if (EFI_ERROR (Status)) {\r
806 return Status;\r
807 }\r
808\r
809 CallbackInfo = &Instance->Ip4FormCallbackInfo;\r
810\r
811 CallbackInfo->Signature = IP4CONFIG_FORM_CALLBACK_INFO_SIGNATURE;\r
812 CallbackInfo->HiiDatabase = HiiDatabase;\r
813\r
814 CallbackInfo->ConfigAccess.ExtractConfig = Ip4DeviceExtractConfig;\r
815 CallbackInfo->ConfigAccess.RouteConfig = Ip4DeviceRouteConfig;\r
816 CallbackInfo->ConfigAccess.Callback = NULL;\r
817\r
818 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&CallbackInfo->ConfigRouting);\r
819 if (EFI_ERROR (Status)) {\r
820 return Status;\r
821 }\r
822\r
823 CallbackInfo->DriverHandle = Instance->Controller;\r
824 //\r
825 // Install Device Path Protocol and Config Access protocol to driver handle\r
826 //\r
827 Status = gBS->InstallMultipleProtocolInterfaces (\r
828 &CallbackInfo->DriverHandle,\r
829 &gEfiHiiConfigAccessProtocolGuid,\r
830 &CallbackInfo->ConfigAccess,\r
831 NULL\r
832 );\r
833 ASSERT_EFI_ERROR (Status);\r
834\r
835 return Status;\r
836}\r
837\r
838/**\r
839 Uninstall HII Config Access protocol for network device and free resource.\r
840\r
841 @param[in] Instance The IP4 Config instance.\r
842\r
843 @retval EFI_SUCCESS The HII Config Access protocol is uninstalled.\r
844 @retval Others Other errors as indicated.\r
845**/\r
846EFI_STATUS\r
847Ip4ConfigDeviceUnload (\r
848 IN IP4_CONFIG_INSTANCE *Instance\r
849 )\r
850{\r
851 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
852\r
853 CallbackInfo = &Instance->Ip4FormCallbackInfo;\r
854\r
855 Ip4ConfigUpdateForm (Instance, FALSE);\r
856\r
857 //\r
858 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
859 //\r
860 gBS->UninstallMultipleProtocolInterfaces (\r
861 CallbackInfo->DriverHandle,\r
862 &gEfiHiiConfigAccessProtocolGuid,\r
863 &CallbackInfo->ConfigAccess,\r
864 NULL\r
865 );\r
866\r
867 return EFI_SUCCESS;\r
868}\r
869\r
870/**\r
871 Unload the network configuration form, this includes: delete all the network\r
872 device configuration entries, uninstall the form callback protocol and\r
873 free the resources used.\r
874\r
875 @retval EFI_SUCCESS The network configuration form is unloaded.\r
876**/\r
877EFI_STATUS\r
878Ip4ConfigFormUnload (\r
879 VOID\r
880 )\r
881{\r
882 IP4CONFIG_FORM_ENTRY *ConfigFormEntry;\r
883\r
884 while (!IsListEmpty (&mIp4ConfigFormList)) {\r
885 //\r
886 // Uninstall the device forms as the network driver instance may fail to\r
887 // control the controller but still install the device configuration form.\r
888 // In such case, upon driver unloading, the driver instance's driverbinding.\r
889 // stop () won't be called, so we have to take this chance here to uninstall\r
890 // the device form.\r
891 //\r
892 ConfigFormEntry = NET_LIST_USER_STRUCT (mIp4ConfigFormList.ForwardLink, IP4CONFIG_FORM_ENTRY, Link);\r
893 Ip4ConfigUpdateForm (ConfigFormEntry->Ip4ConfigInstance, FALSE);\r
894 }\r
895\r
896 //\r
897 // Remove HII package list\r
898 //\r
899 mCallbackInfo->HiiDatabase->RemovePackageList (\r
900 mCallbackInfo->HiiDatabase,\r
901 mCallbackInfo->RegisteredHandle\r
902 );\r
903\r
904 //\r
905 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
906 //\r
907 gBS->UninstallMultipleProtocolInterfaces (\r
908 mCallbackInfo->DriverHandle,\r
909 &gEfiDevicePathProtocolGuid,\r
910 &mIp4ConifgHiiVendorDevicePath,\r
911 &gEfiHiiConfigAccessProtocolGuid,\r
912 &mCallbackInfo->ConfigAccess,\r
913 NULL\r
914 );\r
915\r
916 FreePool (mCallbackInfo);\r
917\r
918 return EFI_SUCCESS;\r
919}\r
920\r
921/**\r
922 Updates the network configuration form to add/delete an entry for the network\r
923 device specified by the Instance.\r
924\r
925 @param[in] Instance The IP4 Config instance.\r
926 @param[in] AddForm Whether to add or delete a form entry.\r
927\r
928 @retval EFI_SUCCESS The network configuration form is updated.\r
929 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
930 @retval Others Other errors as indicated.\r
931**/\r
932EFI_STATUS\r
933Ip4ConfigUpdateForm (\r
934 IN IP4_CONFIG_INSTANCE *Instance,\r
935 IN BOOLEAN AddForm\r
936 )\r
937{\r
938 LIST_ENTRY *Entry;\r
939 IP4CONFIG_FORM_ENTRY *ConfigFormEntry;\r
940 BOOLEAN EntryExisted;\r
941 EFI_STATUS Status;\r
942 EFI_SIMPLE_NETWORK_PROTOCOL *Snp;\r
943 CHAR16 PortString[128];\r
944 UINT16 FormIndex;\r
945 VOID *StartOpCodeHandle;\r
946 VOID *EndOpCodeHandle;\r
947 EFI_IFR_GUID_LABEL *StartLabel;\r
948 EFI_IFR_GUID_LABEL *EndLabel;\r
949\r
950 ConfigFormEntry = NULL;\r
951 EntryExisted = FALSE;\r
952\r
953 NET_LIST_FOR_EACH (Entry, &mIp4ConfigFormList) {\r
954 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, IP4CONFIG_FORM_ENTRY, Link);\r
955\r
956 if (ConfigFormEntry->Controller == Instance->Controller) {\r
957 EntryExisted = TRUE;\r
958 break;\r
959 }\r
960 }\r
961\r
962 if (AddForm) {\r
963 if (EntryExisted) {\r
964 return EFI_SUCCESS;\r
965 } else {\r
966 //\r
967 // Add a new form.\r
968 //\r
969 ConfigFormEntry = (IP4CONFIG_FORM_ENTRY *) AllocateZeroPool (sizeof (IP4CONFIG_FORM_ENTRY));\r
970 if (ConfigFormEntry == NULL) {\r
971 return EFI_OUT_OF_RESOURCES;\r
972 }\r
973\r
974 ConfigFormEntry->Ip4ConfigInstance = Instance;\r
975 InitializeListHead (&ConfigFormEntry->Link);\r
976 ConfigFormEntry->Controller = Instance->Controller;\r
977\r
978 //\r
979 // Get the simple network protocol and convert the MAC address into\r
980 // the formatted string.\r
981 //\r
982 Status = gBS->HandleProtocol (\r
983 Instance->Controller,\r
984 &gEfiSimpleNetworkProtocolGuid,\r
985 (VOID **)&Snp\r
986 );\r
987 ASSERT (Status == EFI_SUCCESS);\r
988\r
989 Ip4MacAddrToStr (&Snp->Mode->PermanentAddress, Snp->Mode->HwAddressSize, ConfigFormEntry->MacString);\r
990\r
991 //\r
992 // Compose the Port string and create a new EFI_STRING_ID.\r
993 //\r
994 UnicodeSPrint (PortString, 128, L"%s %s", Instance->NicName, ConfigFormEntry->MacString);\r
995 ConfigFormEntry->PortTitleToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, PortString, NULL);\r
996\r
997 //\r
998 // Compose the help string of this port and create a new EFI_STRING_ID.\r
999 //\r
1000 UnicodeSPrint (PortString, 128, L"Set the network parameters on eth%d %s", 0, ConfigFormEntry->MacString);\r
1001 ConfigFormEntry->PortTitleHelpToken = HiiSetString (mCallbackInfo->RegisteredHandle, 0, PortString, NULL);\r
1002\r
1003 InsertTailList (&mIp4ConfigFormList, &ConfigFormEntry->Link);\r
1004 mNumberOfIp4Devices++;\r
1005 }\r
1006 } else {\r
1007 ASSERT (EntryExisted);\r
1008\r
1009 mNumberOfIp4Devices--;\r
1010 RemoveEntryList (&ConfigFormEntry->Link);\r
1011 gBS->FreePool (ConfigFormEntry);\r
1012 }\r
1013\r
1014 //\r
1015 // Init OpCode Handle\r
1016 //\r
1017 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1018 ASSERT (StartOpCodeHandle != NULL);\r
1019\r
1020 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1021 ASSERT (EndOpCodeHandle != NULL);\r
1022\r
1023 //\r
1024 // Create Hii Extend Label OpCode as the start opcode\r
1025 //\r
1026 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1027 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1028 StartLabel->Number = DEVICE_ENTRY_LABEL;\r
1029\r
1030 //\r
1031 // Create Hii Extend Label OpCode as the end opcode\r
1032 //\r
1033 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1034 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1035 EndLabel->Number = LABEL_END;\r
1036\r
1037 FormIndex = 0;\r
1038\r
1039 FormIndex = 0;\r
1040 NET_LIST_FOR_EACH (Entry, &mIp4ConfigFormList) {\r
1041 ConfigFormEntry = NET_LIST_USER_STRUCT (Entry, IP4CONFIG_FORM_ENTRY, Link);\r
1042\r
1043 HiiCreateGotoOpCode (\r
1044 StartOpCodeHandle, // Container for dynamic created opcodes\r
1045 FORMID_DEVICE_FORM, // Target Form ID\r
1046 ConfigFormEntry->PortTitleToken, // Prompt text\r
1047 ConfigFormEntry->PortTitleHelpToken, // Help text\r
1048 EFI_IFR_FLAG_CALLBACK, // Question flag\r
1049 (UINT16)(KEY_DEVICE_ENTRY_BASE + FormIndex) // Question ID\r
1050 );\r
1051\r
1052 FormIndex++;\r
1053 }\r
1054\r
1055 HiiUpdateForm (\r
1056 mCallbackInfo->RegisteredHandle,\r
1057 &gEfiNicIp4ConfigVariableGuid,\r
1058 FORMID_MAIN_FORM,\r
1059 StartOpCodeHandle, // Label DEVICE_ENTRY_LABEL\r
1060 EndOpCodeHandle // LABEL_END\r
1061 );\r
1062\r
1063 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
1064 HiiFreeOpCodeHandle (EndOpCodeHandle);\r
1065\r
1066 return EFI_SUCCESS;\r
1067}\r
1068\r
1069/**\r
1070 Initialize the network configuration form, this includes: delete all the network\r
1071 device configuration entries, install the form callback protocol and\r
1072 allocate the resources used.\r
1073\r
1074 @retval EFI_SUCCESS The network configuration form is unloaded.\r
1075 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
1076**/\r
1077EFI_STATUS\r
1078Ip4ConfigFormInit (\r
1079 VOID\r
1080 )\r
1081{\r
1082 EFI_STATUS Status;\r
1083 EFI_HII_DATABASE_PROTOCOL *HiiDatabase;\r
1084 IP4_FORM_CALLBACK_INFO *CallbackInfo;\r
1085\r
1086 Status = gBS->LocateProtocol (&gEfiHiiDatabaseProtocolGuid, NULL, (VOID **)&HiiDatabase);\r
1087 if (EFI_ERROR (Status)) {\r
1088 return Status;\r
1089 }\r
1090\r
1091 CallbackInfo = (IP4_FORM_CALLBACK_INFO *) AllocateZeroPool (sizeof (IP4_FORM_CALLBACK_INFO));\r
1092 if (CallbackInfo == NULL) {\r
1093 return EFI_OUT_OF_RESOURCES;\r
1094 }\r
1095\r
1096 CallbackInfo->Signature = IP4CONFIG_FORM_CALLBACK_INFO_SIGNATURE;\r
1097 CallbackInfo->HiiDatabase = HiiDatabase;\r
1098\r
1099 CallbackInfo->ConfigAccess.ExtractConfig = Ip4FormExtractConfig;\r
1100 CallbackInfo->ConfigAccess.RouteConfig = Ip4FormRouteConfig;\r
1101 CallbackInfo->ConfigAccess.Callback = Ip4FormCallback;\r
1102\r
1103 Status = gBS->LocateProtocol (&gEfiHiiConfigRoutingProtocolGuid, NULL, (VOID **)&CallbackInfo->ConfigRouting);\r
1104 if (EFI_ERROR (Status)) {\r
1105 return Status;\r
1106 }\r
1107\r
1108 CallbackInfo->DriverHandle = NULL;\r
1109 //\r
1110 // Install Device Path Protocol and Config Access protocol to driver handle\r
1111 //\r
1112 Status = gBS->InstallMultipleProtocolInterfaces (\r
1113 &CallbackInfo->DriverHandle,\r
1114 &gEfiDevicePathProtocolGuid,\r
1115 &mIp4ConifgHiiVendorDevicePath,\r
1116 &gEfiHiiConfigAccessProtocolGuid,\r
1117 &CallbackInfo->ConfigAccess,\r
1118 NULL\r
1119 );\r
1120 ASSERT_EFI_ERROR (Status);\r
1121\r
1122 //\r
1123 // Publish our HII data\r
1124 //\r
1125 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
1126 &gEfiNicIp4ConfigVariableGuid,\r
1127 CallbackInfo->DriverHandle,\r
1128 Ip4ConfigDxeStrings,\r
1129 Ip4ConfigDxeBin,\r
1130 NULL\r
1131 );\r
1132 if (CallbackInfo->RegisteredHandle == NULL) {\r
1133 return EFI_OUT_OF_RESOURCES;\r
1134 }\r
1135\r
1136 mCallbackInfo = CallbackInfo;\r
1137\r
1138 return Status;\r
1139}\r