]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c
IntelFrameworkModulePkg: Clean up source files
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / FileExplorer.c
CommitLineData
5c08e117 1/** @file\r
2 File explorer related functions.\r
3\r
0a6f4824 4Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
180a5a35 5This program and the accompanying materials\r
5c08e117 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 "BootMaint.h"\r
16\r
17/**\r
18 Update the File Explore page.\r
19\r
20 @param CallbackData The BMM context data.\r
21 @param MenuOption Pointer to menu options to display.\r
22\r
23**/\r
24VOID\r
25UpdateFileExplorePage (\r
26 IN BMM_CALLBACK_DATA *CallbackData,\r
27 BM_MENU_OPTION *MenuOption\r
28 )\r
29{\r
30 UINTN Index;\r
31 BM_MENU_ENTRY *NewMenuEntry;\r
32 BM_FILE_CONTEXT *NewFileContext;\r
33 EFI_FORM_ID FormId;\r
34\r
35 NewMenuEntry = NULL;\r
36 NewFileContext = NULL;\r
37 FormId = 0;\r
38\r
39 RefreshUpdateData ();\r
75bf9d0e 40 mStartLabel->Number = FORM_FILE_EXPLORER_ID;\r
5c08e117 41\r
42 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
43 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
44 NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
45\r
46 if (NewFileContext->IsBootLegacy) {\r
47 continue;\r
48 }\r
49\r
13078b3f 50 if ((NewFileContext->IsDir) || (FileExplorerStateBootFromFile == CallbackData->FeCurrentState)) {\r
5c08e117 51 //\r
13078b3f 52 // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.\r
5c08e117 53 //\r
75bf9d0e
LG
54 HiiCreateActionOpCode (\r
55 mStartOpCodeHandle,\r
5c08e117 56 (UINT16) (FILE_OPTION_OFFSET + Index),\r
57 NewMenuEntry->DisplayStringToken,\r
58 STRING_TOKEN (STR_NULL_STRING),\r
59 EFI_IFR_FLAG_CALLBACK,\r
75bf9d0e 60 0\r
5c08e117 61 );\r
62 } else {\r
63 //\r
13078b3f 64 // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.\r
5c08e117 65 //\r
13078b3f 66 if (FileExplorerStateAddBootOption == CallbackData->FeCurrentState) {\r
5c08e117 67 FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
13078b3f 68 } else if (FileExplorerStateAddDriverOptionState == CallbackData->FeCurrentState) {\r
5c08e117 69 FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
70 }\r
71\r
75bf9d0e
LG
72 HiiCreateGotoOpCode (\r
73 mStartOpCodeHandle,\r
5c08e117 74 FormId,\r
75 NewMenuEntry->DisplayStringToken,\r
76 STRING_TOKEN (STR_NULL_STRING),\r
77 EFI_IFR_FLAG_CALLBACK,\r
c93bcb7e 78 (UINT16) (FILE_OPTION_GOTO_OFFSET + Index)\r
5c08e117 79 );\r
80 }\r
81 }\r
82\r
75bf9d0e 83 HiiUpdateForm (\r
5c08e117 84 CallbackData->FeHiiHandle,\r
e24fc103 85 &gFileExploreFormSetGuid,\r
5c08e117 86 FORM_FILE_EXPLORER_ID,\r
75bf9d0e
LG
87 mStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID\r
88 mEndOpCodeHandle // LABEL_END\r
5c08e117 89 );\r
90}\r
91\r
92/**\r
93 Update the file explower page with the refershed file system.\r
94\r
95\r
96 @param CallbackData BMM context data\r
97 @param KeyValue Key value to identify the type of data to expect.\r
98\r
99 @retval TRUE Inform the caller to create a callback packet to exit file explorer.\r
100 @retval FALSE Indicate that there is no need to exit file explorer.\r
101\r
102**/\r
103BOOLEAN\r
104UpdateFileExplorer (\r
105 IN BMM_CALLBACK_DATA *CallbackData,\r
106 IN UINT16 KeyValue\r
107 )\r
108{\r
109 UINT16 FileOptionMask;\r
110 BM_MENU_ENTRY *NewMenuEntry;\r
111 BM_FILE_CONTEXT *NewFileContext;\r
112 EFI_FORM_ID FormId;\r
113 BOOLEAN ExitFileExplorer;\r
114 EFI_STATUS Status;\r
115\r
116 NewMenuEntry = NULL;\r
117 NewFileContext = NULL;\r
118 ExitFileExplorer = FALSE;\r
119\r
120 FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);\r
121\r
13078b3f 122 if (FileExplorerDisplayUnknown == CallbackData->FeDisplayContext) {\r
5c08e117 123 //\r
124 // First in, display file system.\r
125 //\r
126 BOpt_FreeMenu (&FsOptionMenu);\r
127 BOpt_FindFileSystem (CallbackData);\r
128 CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu);\r
129\r
130 UpdateFileExplorePage (CallbackData, &FsOptionMenu);\r
131\r
13078b3f 132 CallbackData->FeDisplayContext = FileExplorerDisplayFileSystem;\r
5c08e117 133 } else {\r
13078b3f 134 if (FileExplorerDisplayFileSystem == CallbackData->FeDisplayContext) {\r
5c08e117 135 NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);\r
13078b3f 136 } else if (FileExplorerDisplayDirectory == CallbackData->FeDisplayContext) {\r
5c08e117 137 NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);\r
138 }\r
139\r
a19ad64b 140 NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
5c08e117 141\r
5c08e117 142 if (NewFileContext->IsDir ) {\r
0b716fd7
ED
143 CallbackData->FeDisplayContext = FileExplorerDisplayDirectory;\r
144\r
145 RemoveEntryList (&NewMenuEntry->Link);\r
5c08e117 146 BOpt_FreeMenu (&DirectoryMenu);\r
147 Status = BOpt_FindFiles (CallbackData, NewMenuEntry);\r
148 if (EFI_ERROR (Status)) {\r
149 ExitFileExplorer = TRUE;\r
150 goto exit;\r
151 }\r
152 CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu);\r
0b716fd7 153 BOpt_DestroyMenuEntry (NewMenuEntry);\r
5c08e117 154\r
155 UpdateFileExplorePage (CallbackData, &DirectoryMenu);\r
156\r
157 } else {\r
158 switch (CallbackData->FeCurrentState) {\r
13078b3f 159 case FileExplorerStateBootFromFile:\r
2df686c6 160 //\r
161 // Restore to original mode before launching boot option.\r
162 //\r
163 BdsSetConsoleMode (FALSE);\r
164\r
5c08e117 165 //\r
166 // Here boot from file\r
167 //\r
168 BootThisFile (NewFileContext);\r
72861c22 169 //\r
170 // Set proper video resolution and text mode for setup.\r
171 //\r
2df686c6 172 BdsSetConsoleMode (TRUE);\r
5c08e117 173 ExitFileExplorer = TRUE;\r
174 break;\r
175\r
13078b3f 176 case FileExplorerStateAddBootOption:\r
177 case FileExplorerStateAddDriverOptionState:\r
178 if (FileExplorerStateAddBootOption == CallbackData->FeCurrentState) {\r
5c08e117 179 FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
8acb3f7b
ED
180 if (!CallbackData->FeFakeNvData.BootOptionChanged) {\r
181 ZeroMem (CallbackData->FeFakeNvData.BootOptionalData, sizeof (CallbackData->FeFakeNvData.BootOptionalData));\r
182 ZeroMem (CallbackData->FeFakeNvData.BootDescriptionData, sizeof (CallbackData->FeFakeNvData.BootDescriptionData));\r
183 }\r
5c08e117 184 } else {\r
185 FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
8acb3f7b
ED
186 if (!CallbackData->FeFakeNvData.DriverOptionChanged) {\r
187 ZeroMem (CallbackData->FeFakeNvData.DriverOptionalData, sizeof (CallbackData->FeFakeNvData.DriverOptionalData));\r
188 ZeroMem (CallbackData->FeFakeNvData.DriverDescriptionData, sizeof (CallbackData->FeFakeNvData.DriverDescriptionData));\r
189 }\r
5c08e117 190 }\r
191\r
192 CallbackData->MenuEntry = NewMenuEntry;\r
193 CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;\r
194\r
195 //\r
196 // Create Subtitle op-code for the display string of the option.\r
197 //\r
198 RefreshUpdateData ();\r
75bf9d0e 199 mStartLabel->Number = FormId;\r
5c08e117 200\r
75bf9d0e
LG
201 HiiCreateSubTitleOpCode (\r
202 mStartOpCodeHandle,\r
5c08e117 203 NewMenuEntry->DisplayStringToken,\r
204 0,\r
205 0,\r
75bf9d0e 206 0\r
5c08e117 207 );\r
208\r
75bf9d0e 209 HiiUpdateForm (\r
5c08e117 210 CallbackData->FeHiiHandle,\r
e24fc103 211 &gFileExploreFormSetGuid,\r
5c08e117 212 FormId,\r
75bf9d0e
LG
213 mStartOpCodeHandle, // Label FormId\r
214 mEndOpCodeHandle // LABEL_END\r
5c08e117 215 );\r
216 break;\r
217\r
218 default:\r
219 break;\r
220 }\r
221 }\r
222 }\r
223 exit:\r
224 return ExitFileExplorer;\r
225}\r
226\r
be9304f3
ED
227/**\r
228 This function applies changes in a driver's configuration.\r
229 Input is a Configuration, which has the routing data for this\r
230 driver followed by name / value configuration pairs. The driver\r
231 must apply those pairs to its configurable storage. If the\r
232 driver's configuration is stored in a linear block of data\r
233 and the driver's name / value pairs are in <BlockConfig>\r
234 format, it may use the ConfigToBlock helper function (above) to\r
235 simplify the job. Currently not implemented.\r
236\r
237 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
238 @param[in] Configuration A null-terminated Unicode string in\r
0a6f4824 239 <ConfigString> format.\r
be9304f3
ED
240 @param[out] Progress A pointer to a string filled in with the\r
241 offset of the most recent '&' before the\r
242 first failing name / value pair (or the\r
243 beginn ing of the string if the failure\r
244 is in the first name / value pair) or\r
245 the terminating NULL if all was\r
246 successful.\r
247\r
248 @retval EFI_SUCCESS The results have been distributed or are\r
0a6f4824 249 awaiting distribution.\r
be9304f3
ED
250 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
251 parts of the results that must be\r
252 stored awaiting possible future\r
253 protocols.\r
254 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
255 Results parameter would result\r
256 in this type of error.\r
257 @retval EFI_NOT_FOUND Target for the specified routing data\r
258 was not found.\r
259**/\r
260EFI_STATUS\r
261EFIAPI\r
262FileExplorerRouteConfig (\r
263 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
264 IN CONST EFI_STRING Configuration,\r
265 OUT EFI_STRING *Progress\r
266 )\r
267{\r
268 EFI_STATUS Status;\r
269 UINTN BufferSize;\r
270 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
271 FILE_EXPLORER_NV_DATA *FeData;\r
272 BMM_CALLBACK_DATA *Private;\r
273\r
274 if (Progress == NULL) {\r
275 return EFI_INVALID_PARAMETER;\r
276 }\r
277 *Progress = Configuration;\r
278\r
279 if (Configuration == NULL) {\r
280 return EFI_INVALID_PARAMETER;\r
281 }\r
282\r
283 //\r
284 // Check routing data in <ConfigHdr>.\r
285 // Note: there is no name for Name/Value storage, only GUID will be checked\r
286 //\r
287 if (!HiiIsConfigHdrMatch (Configuration, &gFileExploreFormSetGuid, mFileExplorerStorageName)) {\r
288 return EFI_NOT_FOUND;\r
289 }\r
290\r
291 Status = gBS->LocateProtocol (\r
0a6f4824
LG
292 &gEfiHiiConfigRoutingProtocolGuid,\r
293 NULL,\r
8819a096 294 (VOID**) &ConfigRouting\r
be9304f3
ED
295 );\r
296 if (EFI_ERROR (Status)) {\r
297 return Status;\r
298 }\r
299\r
300 Private = FE_CALLBACK_DATA_FROM_THIS (This);\r
301 //\r
302 // Get Buffer Storage data from EFI variable\r
303 //\r
304 BufferSize = sizeof (FILE_EXPLORER_NV_DATA );\r
305 FeData = &Private->FeFakeNvData;\r
306\r
307 //\r
308 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
309 //\r
310 Status = ConfigRouting->ConfigToBlock (\r
311 ConfigRouting,\r
312 Configuration,\r
313 (UINT8 *) FeData,\r
314 &BufferSize,\r
315 Progress\r
316 );\r
317 ASSERT_EFI_ERROR (Status);\r
318\r
319 if (FeData->BootDescriptionData[0] != 0x00 || FeData->BootOptionalData[0] != 0x00) {\r
320 Status = Var_UpdateBootOption (Private, FeData);\r
321 if (EFI_ERROR (Status)) {\r
322 return Status;\r
323 }\r
324\r
325 BOpt_GetBootOptions (Private);\r
326 CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);\r
327 }\r
328\r
329 if (FeData->DriverDescriptionData[0] != 0x00 || FeData->DriverOptionalData[0] != 0x00) {\r
330 Status = Var_UpdateDriverOption (\r
331 Private,\r
332 Private->FeHiiHandle,\r
333 FeData->DriverDescriptionData,\r
334 FeData->DriverOptionalData,\r
335 FeData->ForceReconnect\r
336 );\r
337 if (EFI_ERROR (Status)) {\r
338 return Status;\r
339 }\r
340\r
341 BOpt_GetDriverOptions (Private);\r
342 CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);\r
343 }\r
344\r
345 return EFI_SUCCESS;\r
346}\r
347\r
5c08e117 348/**\r
349 This function processes the results of changes in configuration.\r
350 When user select a interactive opcode, this callback will be triggered.\r
351 Based on the Question(QuestionId) that triggers the callback, the corresponding\r
352 actions is performed. It handles:\r
353\r
354 1) the addition of boot option.\r
355 2) the addition of driver option.\r
356 3) exit from file browser\r
357 4) update of file content if a dir is selected.\r
358 5) boot the file if a file is selected in "boot from file"\r
359\r
360\r
361 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
362 @param Action Specifies the type of action taken by the browser.\r
363 @param QuestionId A unique value which is sent to the original exporting driver\r
364 so that it can identify the type of data to expect.\r
365 @param Type The type of value for the question.\r
366 @param Value A pointer to the data being sent to the original exporting driver.\r
367 @param ActionRequest On return, points to the action requested by the callback function.\r
368\r
369 @retval EFI_SUCCESS The callback successfully handled the action.\r
370 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
371 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
372 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
70d3fe9d 373 @retval EFI_INVALID_PARAMETER If parameter Value or ActionRequest is NULL.\r
5c08e117 374**/\r
375EFI_STATUS\r
376EFIAPI\r
377FileExplorerCallback (\r
378 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
379 IN EFI_BROWSER_ACTION Action,\r
380 IN EFI_QUESTION_ID QuestionId,\r
381 IN UINT8 Type,\r
382 IN EFI_IFR_TYPE_VALUE *Value,\r
383 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
384 )\r
385{\r
386 BMM_CALLBACK_DATA *Private;\r
387 FILE_EXPLORER_NV_DATA *NvRamMap;\r
388 EFI_STATUS Status;\r
5c08e117 389\r
84724077 390 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
4548fc2a 391 //\r
84724077 392 // All other action return unsupported.\r
4548fc2a 393 //\r
84724077
ED
394 return EFI_UNSUPPORTED;\r
395 }\r
0a6f4824 396\r
84724077
ED
397 Status = EFI_SUCCESS;\r
398 Private = FE_CALLBACK_DATA_FROM_THIS (This);\r
4548fc2a 399\r
84724077
ED
400 //\r
401 // Retrieve uncommitted data from Form Browser\r
402 //\r
403 NvRamMap = &Private->FeFakeNvData;\r
404 HiiGetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap);\r
405\r
406 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
407 if ((Value == NULL) || (ActionRequest == NULL)) {\r
408 return EFI_INVALID_PARAMETER;\r
409 }\r
0a6f4824 410\r
8acb3f7b
ED
411 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {\r
412 NvRamMap->BootOptionChanged = FALSE;\r
413 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
414 } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
415 NvRamMap->DriverOptionChanged = FALSE;\r
416 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
be9304f3
ED
417 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
418 //\r
419 // Discard changes and exit formset\r
420 //\r
421 NvRamMap->DriverOptionalData[0] = 0x0000;\r
422 NvRamMap->DriverDescriptionData[0] = 0x0000;\r
8acb3f7b 423 NvRamMap->DriverOptionChanged = FALSE;\r
be9304f3
ED
424 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
425 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {\r
d88f86f1
ED
426 //\r
427 // Discard changes and exit formset\r
428 //\r
be9304f3
ED
429 NvRamMap->BootOptionalData[0] = 0x0000;\r
430 NvRamMap->BootDescriptionData[0] = 0x0000;\r
8acb3f7b 431 NvRamMap->BootOptionChanged = FALSE;\r
d88f86f1 432 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
8acb3f7b
ED
433 } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {\r
434 NvRamMap->BootOptionChanged = TRUE;\r
435 } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {\r
436 NvRamMap->DriverOptionChanged = TRUE;\r
437 } else if (QuestionId < FILE_OPTION_OFFSET) {\r
d88f86f1
ED
438 //\r
439 // Exit File Explorer formset\r
440 //\r
441 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
c93bcb7e
ED
442 } else if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) {\r
443 //\r
444 // Update forms may return TRUE or FALSE, need to check here.\r
445 //\r
446 if (UpdateFileExplorer (Private, QuestionId)) {\r
447 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
448 }\r
5c08e117 449 }\r
84724077
ED
450 } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
451 if (Value == NULL) {\r
452 return EFI_INVALID_PARAMETER;\r
453 }\r
0a6f4824 454\r
c93bcb7e
ED
455 if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {\r
456 //\r
457 // function will always return FALSE, no need to check here.\r
458 //\r
84724077
ED
459 UpdateFileExplorer (Private, QuestionId);\r
460 }\r
5c08e117 461 }\r
84724077 462\r
8acb3f7b
ED
463 //\r
464 // Pass changed uncommitted data back to Form Browser\r
465 //\r
466 HiiSetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap, NULL);\r
467\r
84724077 468 return Status;\r
5c08e117 469}\r