]> git.proxmox.com Git - mirror_edk2.git/blame - NetworkPkg/HttpBootDxe/HttpBootConfig.c
UefiCpuPkg: Move AsmRelocateApLoopStart from Mpfuncs.nasm to AmdSev.nasm
[mirror_edk2.git] / NetworkPkg / HttpBootDxe / HttpBootConfig.c
CommitLineData
fa848a40
FS
1/** @file\r
2 Helper functions for configuring or getting the parameters relating to HTTP Boot.\r
3\r
f75a7f56 4Copyright (c) 2016 - 2018, Intel Corporation. All rights reserved.<BR>\r
ecf98fbc 5SPDX-License-Identifier: BSD-2-Clause-Patent\r
fa848a40
FS
6\r
7**/\r
8\r
9#include "HttpBootDxe.h"\r
50a65824 10#include <Library/UefiBootManagerLib.h>\r
fa848a40 11\r
d1050b9d 12CHAR16 mHttpBootConfigStorageName[] = L"HTTP_BOOT_CONFIG_IFR_NVDATA";\r
fa848a40
FS
13\r
14/**\r
15 Add new boot option for HTTP boot.\r
16\r
17 @param[in] Private Pointer to the driver private data.\r
18 @param[in] UsingIpv6 Set to TRUE if creating boot option for IPv6.\r
19 @param[in] Description The description text of the boot option.\r
20 @param[in] Uri The URI string of the boot file.\r
f75a7f56 21\r
fa848a40
FS
22 @retval EFI_SUCCESS The boot option is created successfully.\r
23 @retval Others Failed to create new boot option.\r
24\r
25**/\r
26EFI_STATUS\r
27HttpBootAddBootOption (\r
d1050b9d
MK
28 IN HTTP_BOOT_PRIVATE_DATA *Private,\r
29 IN BOOLEAN UsingIpv6,\r
30 IN CHAR16 *Description,\r
31 IN CHAR16 *Uri\r
fa848a40
FS
32 )\r
33{\r
d1050b9d
MK
34 EFI_DEV_PATH *Node;\r
35 EFI_DEVICE_PATH_PROTOCOL *TmpDevicePath;\r
36 EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
37 UINTN Length;\r
38 CHAR8 AsciiUri[URI_STR_MAX_SIZE];\r
39 EFI_STATUS Status;\r
40 UINTN Index;\r
41 EFI_BOOT_MANAGER_LOAD_OPTION NewOption;\r
50a65824 42\r
fa848a40 43 NewDevicePath = NULL;\r
fa848a40
FS
44 Node = NULL;\r
45 TmpDevicePath = NULL;\r
fa848a40
FS
46\r
47 if (StrLen (Description) == 0) {\r
48 return EFI_INVALID_PARAMETER;\r
49 }\r
50\r
51 //\r
52 // Convert the scheme to all lower case.\r
53 //\r
54 for (Index = 0; Index < StrLen (Uri); Index++) {\r
55 if (Uri[Index] == L':') {\r
56 break;\r
57 }\r
d1050b9d
MK
58\r
59 if ((Uri[Index] >= L'A') && (Uri[Index] <= L'Z')) {\r
fa848a40
FS
60 Uri[Index] -= (CHAR16)(L'A' - L'a');\r
61 }\r
62 }\r
63\r
64 //\r
0aa0beca 65 // Only accept empty URI, or http and https URI.\r
fa848a40 66 //\r
0aa0beca 67 if ((StrLen (Uri) != 0) && (StrnCmp (Uri, L"http://", 7) != 0) && (StrnCmp (Uri, L"https://", 8) != 0)) {\r
fa848a40
FS
68 return EFI_INVALID_PARAMETER;\r
69 }\r
f75a7f56 70\r
fa848a40
FS
71 //\r
72 // Create a new device path by appending the IP node and URI node to\r
73 // the driver's parent device path\r
74 //\r
75 if (!UsingIpv6) {\r
76 Node = AllocateZeroPool (sizeof (IPv4_DEVICE_PATH));\r
77 if (Node == NULL) {\r
78 Status = EFI_OUT_OF_RESOURCES;\r
79 goto ON_EXIT;\r
80 }\r
d1050b9d 81\r
fa848a40
FS
82 Node->Ipv4.Header.Type = MESSAGING_DEVICE_PATH;\r
83 Node->Ipv4.Header.SubType = MSG_IPv4_DP;\r
84 SetDevicePathNodeLength (Node, sizeof (IPv4_DEVICE_PATH));\r
85 } else {\r
86 Node = AllocateZeroPool (sizeof (IPv6_DEVICE_PATH));\r
87 if (Node == NULL) {\r
88 Status = EFI_OUT_OF_RESOURCES;\r
89 goto ON_EXIT;\r
90 }\r
d1050b9d
MK
91\r
92 Node->Ipv6.Header.Type = MESSAGING_DEVICE_PATH;\r
93 Node->Ipv6.Header.SubType = MSG_IPv6_DP;\r
fa848a40
FS
94 SetDevicePathNodeLength (Node, sizeof (IPv6_DEVICE_PATH));\r
95 }\r
d1050b9d
MK
96\r
97 TmpDevicePath = AppendDevicePathNode (Private->ParentDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);\r
fa848a40
FS
98 FreePool (Node);\r
99 if (TmpDevicePath == NULL) {\r
100 return EFI_OUT_OF_RESOURCES;\r
101 }\r
d1050b9d 102\r
fa848a40
FS
103 //\r
104 // Update the URI node with the input boot file URI.\r
105 //\r
b9679cd7 106 UnicodeStrToAsciiStrS (Uri, AsciiUri, sizeof (AsciiUri));\r
fa848a40 107 Length = sizeof (EFI_DEVICE_PATH_PROTOCOL) + AsciiStrSize (AsciiUri);\r
d1050b9d 108 Node = AllocatePool (Length);\r
fa848a40
FS
109 if (Node == NULL) {\r
110 Status = EFI_OUT_OF_RESOURCES;\r
111 FreePool (TmpDevicePath);\r
112 goto ON_EXIT;\r
113 }\r
d1050b9d 114\r
fa848a40
FS
115 Node->DevPath.Type = MESSAGING_DEVICE_PATH;\r
116 Node->DevPath.SubType = MSG_URI_DP;\r
117 SetDevicePathNodeLength (Node, Length);\r
d1050b9d
MK
118 CopyMem ((UINT8 *)Node + sizeof (EFI_DEVICE_PATH_PROTOCOL), AsciiUri, AsciiStrSize (AsciiUri));\r
119 NewDevicePath = AppendDevicePathNode (TmpDevicePath, (EFI_DEVICE_PATH_PROTOCOL *)Node);\r
fa848a40
FS
120 FreePool (Node);\r
121 FreePool (TmpDevicePath);\r
122 if (NewDevicePath == NULL) {\r
123 Status = EFI_OUT_OF_RESOURCES;\r
124 goto ON_EXIT;\r
125 }\r
126\r
127 //\r
50a65824 128 // Add a new load option.\r
fa848a40 129 //\r
50a65824 130 Status = EfiBootManagerInitializeLoadOption (\r
d1050b9d
MK
131 &NewOption,\r
132 LoadOptionNumberUnassigned,\r
133 LoadOptionTypeBoot,\r
134 LOAD_OPTION_ACTIVE,\r
135 Description,\r
136 NewDevicePath,\r
137 NULL,\r
138 0\r
139 );\r
fa848a40
FS
140 if (EFI_ERROR (Status)) {\r
141 goto ON_EXIT;\r
142 }\r
143\r
d1050b9d 144 Status = EfiBootManagerAddLoadOptionVariable (&NewOption, (UINTN)-1);\r
a1522257 145 EfiBootManagerFreeLoadOption (&NewOption);\r
fa848a40
FS
146\r
147ON_EXIT:\r
148\r
fa848a40
FS
149 if (NewDevicePath != NULL) {\r
150 FreePool (NewDevicePath);\r
151 }\r
152\r
153 return Status;\r
154}\r
155\r
156/**\r
f75a7f56 157\r
fa848a40
FS
158 This function allows the caller to request the current\r
159 configuration for one or more named elements. The resulting\r
160 string is in <ConfigAltResp> format. Also, any and all alternative\r
161 configuration strings shall be appended to the end of the\r
162 current configuration string. If they are, they must appear\r
163 after the current configuration. They must contain the same\r
164 routing (GUID, NAME, PATH) as the current configuration string.\r
165 They must have an additional description indicating the type of\r
166 alternative configuration the string represents,\r
167 "ALTCFG=<StringToken>". That <StringToken> (when\r
168 converted from Hex UNICODE to binary) is a reference to a\r
169 string in the associated string pack.\r
170\r
171 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
172\r
173 @param[in] Request A null-terminated Unicode string in\r
174 <ConfigRequest> format. Note that this\r
175 includes the routing information as well as\r
176 the configurable name / value pairs. It is\r
177 invalid for this string to be in\r
178 <MultiConfigRequest> format.\r
179\r
180 @param[out] Progress On return, points to a character in the\r
181 Request string. Points to the string's null\r
182 terminator if request was successful. Points\r
183 to the most recent "&" before the first\r
184 failing name / value pair (or the beginning\r
185 of the string if the failure is in the first\r
f75a7f56 186 name / value pair) if the request was not successful.\r
fa848a40
FS
187\r
188 @param[out] Results A null-terminated Unicode string in\r
189 <ConfigAltResp> format which has all values\r
190 filled in for the names in the Request string.\r
191 String to be allocated by the called function.\r
192\r
193 @retval EFI_SUCCESS The Results string is filled with the\r
194 values corresponding to all requested\r
195 names.\r
196\r
197 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
198 parts of the results that must be\r
199 stored awaiting possible future\r
200 protocols.\r
201\r
202 @retval EFI_INVALID_PARAMETER For example, passing in a NULL\r
203 for the Request parameter\r
204 would result in this type of\r
205 error. In this case, the\r
206 Progress parameter would be\r
f75a7f56 207 set to NULL.\r
fa848a40
FS
208\r
209 @retval EFI_NOT_FOUND Routing data doesn't match any\r
210 known driver. Progress set to the\r
211 first character in the routing header.\r
212 Note: There is no requirement that the\r
213 driver validate the routing data. It\r
214 must skip the <ConfigHdr> in order to\r
215 process the names.\r
216\r
217 @retval EFI_INVALID_PARAMETER Illegal syntax. Progress set\r
218 to most recent "&" before the\r
219 error or the beginning of the\r
220 string.\r
221\r
222 @retval EFI_INVALID_PARAMETER Unknown name. Progress points\r
223 to the & before the name in\r
224 question.\r
225\r
226**/\r
227EFI_STATUS\r
228EFIAPI\r
229HttpBootFormExtractConfig (\r
d1050b9d
MK
230 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
231 IN CONST EFI_STRING Request,\r
232 OUT EFI_STRING *Progress,\r
233 OUT EFI_STRING *Results\r
fa848a40
FS
234 )\r
235{\r
d1050b9d
MK
236 EFI_STATUS Status;\r
237 UINTN BufferSize;\r
238 HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;\r
239 EFI_STRING ConfigRequestHdr;\r
240 EFI_STRING ConfigRequest;\r
241 BOOLEAN AllocatedRequest;\r
242 UINTN Size;\r
243\r
244 if ((Progress == NULL) || (Results == NULL)) {\r
fa848a40
FS
245 return EFI_INVALID_PARAMETER;\r
246 }\r
247\r
248 *Progress = Request;\r
249 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {\r
250 return EFI_NOT_FOUND;\r
251 }\r
f75a7f56 252\r
fa848a40
FS
253 ConfigRequestHdr = NULL;\r
254 ConfigRequest = NULL;\r
255 AllocatedRequest = FALSE;\r
256 Size = 0;\r
257\r
258 CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
259 //\r
260 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
261 //\r
262 BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);\r
263 ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);\r
a5acc842 264 StrCpyS (CallbackInfo->HttpBootNvData.Description, DESCRIPTION_STR_MAX_SIZE / sizeof (CHAR16), HTTP_BOOT_DEFAULT_DESCRIPTION_STR);\r
fa848a40
FS
265\r
266 ConfigRequest = Request;\r
267 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
268 //\r
269 // Request has no request element, construct full request string.\r
270 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
271 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
272 //\r
273 ConfigRequestHdr = HiiConstructConfigHdr (&gHttpBootConfigGuid, mHttpBootConfigStorageName, CallbackInfo->ChildHandle);\r
d1050b9d
MK
274 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
275 ConfigRequest = AllocateZeroPool (Size);\r
7c275b3c
ZL
276 if (ConfigRequest == NULL) {\r
277 return EFI_OUT_OF_RESOURCES;\r
278 }\r
d1050b9d 279\r
fa848a40
FS
280 AllocatedRequest = TRUE;\r
281 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
282 FreePool (ConfigRequestHdr);\r
283 }\r
284\r
285 Status = gHiiConfigRouting->BlockToConfig (\r
286 gHiiConfigRouting,\r
287 ConfigRequest,\r
d1050b9d 288 (UINT8 *)&CallbackInfo->HttpBootNvData,\r
fa848a40
FS
289 BufferSize,\r
290 Results,\r
291 Progress\r
292 );\r
f75a7f56 293\r
fa848a40
FS
294 //\r
295 // Free the allocated config request string.\r
296 //\r
297 if (AllocatedRequest) {\r
298 FreePool (ConfigRequest);\r
299 ConfigRequest = NULL;\r
300 }\r
d1050b9d 301\r
fa848a40
FS
302 //\r
303 // Set Progress string to the original request string.\r
304 //\r
305 if (Request == NULL) {\r
306 *Progress = NULL;\r
307 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
308 *Progress = Request + StrLen (Request);\r
309 }\r
310\r
311 return Status;\r
312}\r
313\r
314/**\r
f75a7f56 315\r
fa848a40
FS
316 This function applies changes in a driver's configuration.\r
317 Input is a Configuration, which has the routing data for this\r
318 driver followed by name / value configuration pairs. The driver\r
319 must apply those pairs to its configurable storage. If the\r
320 driver's configuration is stored in a linear block of data\r
321 and the driver's name / value pairs are in <BlockConfig>\r
322 format, it may use the ConfigToBlock helper function (above) to\r
323 simplify the job.\r
324\r
325 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
326\r
327 @param[in] Configuration A null-terminated Unicode string in\r
f75a7f56
LG
328 <ConfigString> format.\r
329\r
fa848a40
FS
330 @param[out] Progress A pointer to a string filled in with the\r
331 offset of the most recent '&' before the\r
332 first failing name / value pair (or the\r
333 beginning of the string if the failure\r
334 is in the first name / value pair) or\r
335 the terminating NULL if all was\r
336 successful.\r
337\r
338 @retval EFI_SUCCESS The results have been distributed or are\r
339 awaiting distribution.\r
f75a7f56 340\r
fa848a40
FS
341 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
342 parts of the results that must be\r
343 stored awaiting possible future\r
344 protocols.\r
f75a7f56 345\r
fa848a40
FS
346 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
347 Results parameter would result\r
348 in this type of error.\r
f75a7f56 349\r
fa848a40
FS
350 @retval EFI_NOT_FOUND Target for the specified routing data\r
351 was not found.\r
352\r
353**/\r
354EFI_STATUS\r
355EFIAPI\r
356HttpBootFormRouteConfig (\r
d1050b9d
MK
357 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
358 IN CONST EFI_STRING Configuration,\r
359 OUT EFI_STRING *Progress\r
fa848a40
FS
360 )\r
361{\r
d1050b9d
MK
362 EFI_STATUS Status;\r
363 UINTN BufferSize;\r
364 HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;\r
365 HTTP_BOOT_PRIVATE_DATA *Private;\r
fa848a40
FS
366\r
367 if (Progress == NULL) {\r
368 return EFI_INVALID_PARAMETER;\r
369 }\r
d1050b9d 370\r
fa848a40
FS
371 *Progress = Configuration;\r
372\r
373 if (Configuration == NULL) {\r
374 return EFI_INVALID_PARAMETER;\r
375 }\r
376\r
377 //\r
378 // Check routing data in <ConfigHdr>.\r
379 // Note: there is no name for Name/Value storage, only GUID will be checked\r
380 //\r
381 if (!HiiIsConfigHdrMatch (Configuration, &gHttpBootConfigGuid, mHttpBootConfigStorageName)) {\r
382 return EFI_NOT_FOUND;\r
383 }\r
384\r
385 CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
386 Private = HTTP_BOOT_PRIVATE_DATA_FROM_CALLBACK_INFO (CallbackInfo);\r
f75a7f56 387\r
fa848a40
FS
388 BufferSize = sizeof (HTTP_BOOT_CONFIG_IFR_NVDATA);\r
389 ZeroMem (&CallbackInfo->HttpBootNvData, BufferSize);\r
390\r
391 Status = gHiiConfigRouting->ConfigToBlock (\r
d1050b9d
MK
392 gHiiConfigRouting,\r
393 Configuration,\r
394 (UINT8 *)&CallbackInfo->HttpBootNvData,\r
395 &BufferSize,\r
396 Progress\r
397 );\r
fa848a40
FS
398 if (EFI_ERROR (Status)) {\r
399 return Status;\r
400 }\r
401\r
402 //\r
403 // Create a new boot option according to the configuration data.\r
404 //\r
a5acc842
FS
405 HttpBootAddBootOption (\r
406 Private,\r
407 (CallbackInfo->HttpBootNvData.IpVersion == HTTP_BOOT_IP_VERSION_6) ? TRUE : FALSE,\r
408 CallbackInfo->HttpBootNvData.Description,\r
409 CallbackInfo->HttpBootNvData.Uri\r
410 );\r
f75a7f56 411\r
a5acc842 412 return EFI_SUCCESS;\r
fa848a40
FS
413}\r
414\r
415/**\r
f75a7f56 416\r
fa848a40
FS
417 This function is called to provide results data to the driver.\r
418 This data consists of a unique key that is used to identify\r
419 which data is either being passed back or being asked for.\r
420\r
421 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
422 @param[in] Action Specifies the type of action taken by the browser.\r
423 @param[in] QuestionId A unique value which is sent to the original\r
424 exporting driver so that it can identify the type\r
f75a7f56 425 of data to expect. The format of the data tends to\r
fa848a40
FS
426 vary based on the opcode that generated the callback.\r
427 @param[in] Type The type of value for the question.\r
428 @param[in, out] Value A pointer to the data being sent to the original\r
429 exporting driver.\r
430 @param[out] ActionRequest On return, points to the action requested by the\r
431 callback function.\r
432\r
433 @retval EFI_SUCCESS The callback successfully handled the action.\r
434 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the\r
435 variable and its data.\r
436 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
437 @retval EFI_UNSUPPORTED The specified Action is not supported by the\r
438 callback.\r
439**/\r
440EFI_STATUS\r
441EFIAPI\r
442HttpBootFormCallback (\r
d1050b9d
MK
443 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
444 IN EFI_BROWSER_ACTION Action,\r
445 IN EFI_QUESTION_ID QuestionId,\r
446 IN UINT8 Type,\r
447 IN OUT EFI_IFR_TYPE_VALUE *Value,\r
448 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
fa848a40
FS
449 )\r
450{\r
d1050b9d
MK
451 EFI_INPUT_KEY Key;\r
452 CHAR16 *Uri;\r
453 UINTN UriLen;\r
454 CHAR8 *AsciiUri;\r
455 HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;\r
456 EFI_STATUS Status;\r
221463c2
JW
457\r
458 Uri = NULL;\r
459 UriLen = 0;\r
460 AsciiUri = NULL;\r
461 Status = EFI_SUCCESS;\r
f75a7f56 462\r
d1050b9d 463 if ((This == NULL) || (Value == NULL)) {\r
a5acc842
FS
464 return EFI_INVALID_PARAMETER;\r
465 }\r
466\r
467 CallbackInfo = HTTP_BOOT_FORM_CALLBACK_INFO_FROM_CONFIG_ACCESS (This);\r
f75a7f56 468\r
a5acc842
FS
469 if (Action != EFI_BROWSER_ACTION_CHANGING) {\r
470 return EFI_UNSUPPORTED;\r
471 }\r
f75a7f56 472\r
a5acc842 473 switch (QuestionId) {\r
d1050b9d
MK
474 case KEY_INITIATOR_URI:\r
475 //\r
476 // Get user input URI string\r
477 //\r
478 Uri = HiiGetString (CallbackInfo->RegisteredHandle, Value->string, NULL);\r
479 if (Uri == NULL) {\r
480 return EFI_INVALID_PARAMETER;\r
a5acc842 481 }\r
221463c2 482\r
d1050b9d
MK
483 //\r
484 // The URI should be either an empty string (for corporate environment) ,or http(s) for home environment.\r
485 // Pop up a message box for the unsupported URI.\r
486 //\r
487 if (StrLen (Uri) != 0) {\r
488 UriLen = StrLen (Uri) + 1;\r
489 AsciiUri = AllocateZeroPool (UriLen);\r
490 if (AsciiUri == NULL) {\r
491 FreePool (Uri);\r
492 return EFI_OUT_OF_RESOURCES;\r
493 }\r
494\r
495 UnicodeStrToAsciiStrS (Uri, AsciiUri, UriLen);\r
496\r
497 Status = HttpBootCheckUriScheme (AsciiUri);\r
498\r
499 if (Status == EFI_INVALID_PARAMETER) {\r
500 DEBUG ((DEBUG_ERROR, "HttpBootFormCallback: %r.\n", Status));\r
501\r
502 CreatePopUp (\r
503 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
504 &Key,\r
505 L"ERROR: Unsupported URI!",\r
506 L"Only supports HTTP and HTTPS",\r
507 NULL\r
508 );\r
509 } else if (Status == EFI_ACCESS_DENIED) {\r
510 DEBUG ((DEBUG_ERROR, "HttpBootFormCallback: %r.\n", Status));\r
511\r
512 CreatePopUp (\r
513 EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE,\r
514 &Key,\r
515 L"ERROR: Unsupported URI!",\r
516 L"HTTP is disabled",\r
517 NULL\r
518 );\r
519 }\r
a5acc842 520 }\r
a5acc842 521\r
d1050b9d
MK
522 if (Uri != NULL) {\r
523 FreePool (Uri);\r
524 }\r
a5acc842 525\r
d1050b9d
MK
526 if (AsciiUri != NULL) {\r
527 FreePool (AsciiUri);\r
528 }\r
f75a7f56 529\r
d1050b9d 530 break;\r
a5acc842 531\r
d1050b9d
MK
532 default:\r
533 break;\r
a5acc842
FS
534 }\r
535\r
221463c2 536 return Status;\r
fa848a40
FS
537}\r
538\r
539/**\r
540 Initialize the configuration form.\r
541\r
542 @param[in] Private Pointer to the driver private data.\r
543\r
544 @retval EFI_SUCCESS The configuration form is initialized.\r
545 @retval EFI_OUT_OF_RESOURCES Failed to allocate memory.\r
546\r
547**/\r
548EFI_STATUS\r
549HttpBootConfigFormInit (\r
d1050b9d 550 IN HTTP_BOOT_PRIVATE_DATA *Private\r
fa848a40
FS
551 )\r
552{\r
d1050b9d
MK
553 EFI_STATUS Status;\r
554 HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;\r
555 VENDOR_DEVICE_PATH VendorDeviceNode;\r
556 CHAR16 *MacString;\r
557 CHAR16 *OldMenuString;\r
558 CHAR16 MenuString[128];\r
fa848a40
FS
559\r
560 CallbackInfo = &Private->CallbackInfo;\r
561\r
cd72b6cf 562 if (CallbackInfo->Initialized) {\r
fa848a40
FS
563 return EFI_SUCCESS;\r
564 }\r
f75a7f56 565\r
fa848a40
FS
566 CallbackInfo->Signature = HTTP_BOOT_FORM_CALLBACK_INFO_SIGNATURE;\r
567\r
568 //\r
569 // Construct device path node for EFI HII Config Access protocol,\r
570 // which consists of controller physical device path and one hardware\r
571 // vendor guid node.\r
572 //\r
573 ZeroMem (&VendorDeviceNode, sizeof (VENDOR_DEVICE_PATH));\r
574 VendorDeviceNode.Header.Type = HARDWARE_DEVICE_PATH;\r
575 VendorDeviceNode.Header.SubType = HW_VENDOR_DP;\r
576 CopyGuid (&VendorDeviceNode.Guid, &gEfiCallerIdGuid);\r
577 SetDevicePathNodeLength (&VendorDeviceNode.Header, sizeof (VENDOR_DEVICE_PATH));\r
578 CallbackInfo->HiiVendorDevicePath = AppendDevicePathNode (\r
579 Private->ParentDevicePath,\r
d1050b9d 580 (EFI_DEVICE_PATH_PROTOCOL *)&VendorDeviceNode\r
fa848a40
FS
581 );\r
582 if (CallbackInfo->HiiVendorDevicePath == NULL) {\r
583 Status = EFI_OUT_OF_RESOURCES;\r
584 goto Error;\r
585 }\r
586\r
587 CallbackInfo->ConfigAccess.ExtractConfig = HttpBootFormExtractConfig;\r
588 CallbackInfo->ConfigAccess.RouteConfig = HttpBootFormRouteConfig;\r
589 CallbackInfo->ConfigAccess.Callback = HttpBootFormCallback;\r
f75a7f56 590\r
fa848a40
FS
591 //\r
592 // Install Device Path Protocol and Config Access protocol to driver handle.\r
593 //\r
594 Status = gBS->InstallMultipleProtocolInterfaces (\r
595 &CallbackInfo->ChildHandle,\r
596 &gEfiDevicePathProtocolGuid,\r
597 CallbackInfo->HiiVendorDevicePath,\r
598 &gEfiHiiConfigAccessProtocolGuid,\r
599 &CallbackInfo->ConfigAccess,\r
600 NULL\r
601 );\r
fa848a40
FS
602 if (EFI_ERROR (Status)) {\r
603 goto Error;\r
604 }\r
605\r
606 //\r
607 // Publish our HII data.\r
608 //\r
609 CallbackInfo->RegisteredHandle = HiiAddPackages (\r
610 &gHttpBootConfigGuid,\r
611 CallbackInfo->ChildHandle,\r
612 HttpBootDxeStrings,\r
613 HttpBootConfigVfrBin,\r
614 NULL\r
615 );\r
616 if (CallbackInfo->RegisteredHandle == NULL) {\r
617 Status = EFI_OUT_OF_RESOURCES;\r
618 goto Error;\r
619 }\r
620\r
621 //\r
622 // Append MAC string in the menu help string\r
623 //\r
75372581 624 Status = NetLibGetMacString (Private->Controller, NULL, &MacString);\r
fa848a40
FS
625 if (!EFI_ERROR (Status)) {\r
626 OldMenuString = HiiGetString (\r
f75a7f56
LG
627 CallbackInfo->RegisteredHandle,\r
628 STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),\r
fa848a40
FS
629 NULL\r
630 );\r
631 UnicodeSPrint (MenuString, 128, L"%s (MAC:%s)", OldMenuString, MacString);\r
632 HiiSetString (\r
f75a7f56
LG
633 CallbackInfo->RegisteredHandle,\r
634 STRING_TOKEN (STR_HTTP_BOOT_CONFIG_FORM_HELP),\r
635 MenuString,\r
fa848a40
FS
636 NULL\r
637 );\r
f75a7f56 638\r
fa848a40
FS
639 FreePool (MacString);\r
640 FreePool (OldMenuString);\r
641\r
cd72b6cf 642 CallbackInfo->Initialized = TRUE;\r
fa848a40
FS
643 return EFI_SUCCESS;\r
644 }\r
f75a7f56 645\r
fa848a40
FS
646Error:\r
647\r
648 HttpBootConfigFormUnload (Private);\r
649 return Status;\r
650}\r
651\r
652/**\r
653 Unload the configuration form, this includes: delete all the configuration\r
654 entries, uninstall the form callback protocol, and free the resources used.\r
75372581 655 The form will only be unload completely when both IP4 and IP6 stack are stopped.\r
fa848a40
FS
656\r
657 @param[in] Private Pointer to the driver private data.\r
658\r
659 @retval EFI_SUCCESS The configuration form is unloaded.\r
660 @retval Others Failed to unload the form.\r
661\r
662**/\r
663EFI_STATUS\r
664HttpBootConfigFormUnload (\r
d1050b9d 665 IN HTTP_BOOT_PRIVATE_DATA *Private\r
fa848a40
FS
666 )\r
667{\r
d1050b9d 668 HTTP_BOOT_FORM_CALLBACK_INFO *CallbackInfo;\r
fa848a40 669\r
d1050b9d 670 if ((Private->Ip4Nic != NULL) || (Private->Ip6Nic != NULL)) {\r
fa848a40 671 //\r
75372581 672 // Only unload the configuration form when both IP4 and IP6 stack are stopped.\r
fa848a40 673 //\r
75372581
FS
674 return EFI_SUCCESS;\r
675 }\r
676\r
677 CallbackInfo = &Private->CallbackInfo;\r
678 if (CallbackInfo->ChildHandle != NULL) {\r
fa848a40
FS
679 //\r
680 // Uninstall EFI_HII_CONFIG_ACCESS_PROTOCOL\r
681 //\r
682 gBS->UninstallMultipleProtocolInterfaces (\r
683 CallbackInfo->ChildHandle,\r
684 &gEfiDevicePathProtocolGuid,\r
685 CallbackInfo->HiiVendorDevicePath,\r
686 &gEfiHiiConfigAccessProtocolGuid,\r
687 &CallbackInfo->ConfigAccess,\r
688 NULL\r
689 );\r
690 CallbackInfo->ChildHandle = NULL;\r
691 }\r
692\r
693 if (CallbackInfo->HiiVendorDevicePath != NULL) {\r
694 FreePool (CallbackInfo->HiiVendorDevicePath);\r
695 CallbackInfo->HiiVendorDevicePath = NULL;\r
696 }\r
697\r
698 if (CallbackInfo->RegisteredHandle != NULL) {\r
699 //\r
700 // Remove HII package list\r
701 //\r
702 HiiRemovePackages (CallbackInfo->RegisteredHandle);\r
703 CallbackInfo->RegisteredHandle = NULL;\r
704 }\r
705\r
706 return EFI_SUCCESS;\r
707}\r