]> git.proxmox.com Git - mirror_edk2.git/blame - IntelFrameworkModulePkg/Universal/BdsDxe/BootMaint/FileExplorer.c
Support RouteConfig function for BdsDxe driver.
[mirror_edk2.git] / IntelFrameworkModulePkg / Universal / BdsDxe / BootMaint / FileExplorer.c
CommitLineData
5c08e117 1/** @file\r
2 File explorer related functions.\r
3\r
c93bcb7e 4Copyright (c) 2004 - 2014, 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
180 } else {\r
181 FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
182 }\r
183\r
184 CallbackData->MenuEntry = NewMenuEntry;\r
185 CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;\r
186\r
187 //\r
188 // Create Subtitle op-code for the display string of the option.\r
189 //\r
190 RefreshUpdateData ();\r
75bf9d0e 191 mStartLabel->Number = FormId;\r
5c08e117 192\r
75bf9d0e
LG
193 HiiCreateSubTitleOpCode (\r
194 mStartOpCodeHandle,\r
5c08e117 195 NewMenuEntry->DisplayStringToken,\r
196 0,\r
197 0,\r
75bf9d0e 198 0\r
5c08e117 199 );\r
200\r
75bf9d0e 201 HiiUpdateForm (\r
5c08e117 202 CallbackData->FeHiiHandle,\r
e24fc103 203 &gFileExploreFormSetGuid,\r
5c08e117 204 FormId,\r
75bf9d0e
LG
205 mStartOpCodeHandle, // Label FormId\r
206 mEndOpCodeHandle // LABEL_END\r
5c08e117 207 );\r
208 break;\r
209\r
210 default:\r
211 break;\r
212 }\r
213 }\r
214 }\r
215 exit:\r
216 return ExitFileExplorer;\r
217}\r
218\r
be9304f3
ED
219/**\r
220 This function applies changes in a driver's configuration.\r
221 Input is a Configuration, which has the routing data for this\r
222 driver followed by name / value configuration pairs. The driver\r
223 must apply those pairs to its configurable storage. If the\r
224 driver's configuration is stored in a linear block of data\r
225 and the driver's name / value pairs are in <BlockConfig>\r
226 format, it may use the ConfigToBlock helper function (above) to\r
227 simplify the job. Currently not implemented.\r
228\r
229 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
230 @param[in] Configuration A null-terminated Unicode string in\r
231 <ConfigString> format. \r
232 @param[out] Progress A pointer to a string filled in with the\r
233 offset of the most recent '&' before the\r
234 first failing name / value pair (or the\r
235 beginn ing of the string if the failure\r
236 is in the first name / value pair) or\r
237 the terminating NULL if all was\r
238 successful.\r
239\r
240 @retval EFI_SUCCESS The results have been distributed or are\r
241 awaiting distribution. \r
242 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
243 parts of the results that must be\r
244 stored awaiting possible future\r
245 protocols.\r
246 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
247 Results parameter would result\r
248 in this type of error.\r
249 @retval EFI_NOT_FOUND Target for the specified routing data\r
250 was not found.\r
251**/\r
252EFI_STATUS\r
253EFIAPI\r
254FileExplorerRouteConfig (\r
255 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
256 IN CONST EFI_STRING Configuration,\r
257 OUT EFI_STRING *Progress\r
258 )\r
259{\r
260 EFI_STATUS Status;\r
261 UINTN BufferSize;\r
262 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
263 FILE_EXPLORER_NV_DATA *FeData;\r
264 BMM_CALLBACK_DATA *Private;\r
265\r
266 if (Progress == NULL) {\r
267 return EFI_INVALID_PARAMETER;\r
268 }\r
269 *Progress = Configuration;\r
270\r
271 if (Configuration == NULL) {\r
272 return EFI_INVALID_PARAMETER;\r
273 }\r
274\r
275 //\r
276 // Check routing data in <ConfigHdr>.\r
277 // Note: there is no name for Name/Value storage, only GUID will be checked\r
278 //\r
279 if (!HiiIsConfigHdrMatch (Configuration, &gFileExploreFormSetGuid, mFileExplorerStorageName)) {\r
280 return EFI_NOT_FOUND;\r
281 }\r
282\r
283 Status = gBS->LocateProtocol (\r
284 &gEfiHiiConfigRoutingProtocolGuid, \r
285 NULL, \r
286 &ConfigRouting\r
287 );\r
288 if (EFI_ERROR (Status)) {\r
289 return Status;\r
290 }\r
291\r
292 Private = FE_CALLBACK_DATA_FROM_THIS (This);\r
293 //\r
294 // Get Buffer Storage data from EFI variable\r
295 //\r
296 BufferSize = sizeof (FILE_EXPLORER_NV_DATA );\r
297 FeData = &Private->FeFakeNvData;\r
298\r
299 //\r
300 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
301 //\r
302 Status = ConfigRouting->ConfigToBlock (\r
303 ConfigRouting,\r
304 Configuration,\r
305 (UINT8 *) FeData,\r
306 &BufferSize,\r
307 Progress\r
308 );\r
309 ASSERT_EFI_ERROR (Status);\r
310\r
311 if (FeData->BootDescriptionData[0] != 0x00 || FeData->BootOptionalData[0] != 0x00) {\r
312 Status = Var_UpdateBootOption (Private, FeData);\r
313 if (EFI_ERROR (Status)) {\r
314 return Status;\r
315 }\r
316\r
317 BOpt_GetBootOptions (Private);\r
318 CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);\r
319 }\r
320\r
321 if (FeData->DriverDescriptionData[0] != 0x00 || FeData->DriverOptionalData[0] != 0x00) {\r
322 Status = Var_UpdateDriverOption (\r
323 Private,\r
324 Private->FeHiiHandle,\r
325 FeData->DriverDescriptionData,\r
326 FeData->DriverOptionalData,\r
327 FeData->ForceReconnect\r
328 );\r
329 if (EFI_ERROR (Status)) {\r
330 return Status;\r
331 }\r
332\r
333 BOpt_GetDriverOptions (Private);\r
334 CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);\r
335 }\r
336\r
337 return EFI_SUCCESS;\r
338}\r
339\r
5c08e117 340/**\r
341 This function processes the results of changes in configuration.\r
342 When user select a interactive opcode, this callback will be triggered.\r
343 Based on the Question(QuestionId) that triggers the callback, the corresponding\r
344 actions is performed. It handles:\r
345\r
346 1) the addition of boot option.\r
347 2) the addition of driver option.\r
348 3) exit from file browser\r
349 4) update of file content if a dir is selected.\r
350 5) boot the file if a file is selected in "boot from file"\r
351\r
352\r
353 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
354 @param Action Specifies the type of action taken by the browser.\r
355 @param QuestionId A unique value which is sent to the original exporting driver\r
356 so that it can identify the type of data to expect.\r
357 @param Type The type of value for the question.\r
358 @param Value A pointer to the data being sent to the original exporting driver.\r
359 @param ActionRequest On return, points to the action requested by the callback function.\r
360\r
361 @retval EFI_SUCCESS The callback successfully handled the action.\r
362 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
363 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
364 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
365 @retval EFI_INVALID_PARAMETER If paramter Value or ActionRequest is NULL.\r
366**/\r
367EFI_STATUS\r
368EFIAPI\r
369FileExplorerCallback (\r
370 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
371 IN EFI_BROWSER_ACTION Action,\r
372 IN EFI_QUESTION_ID QuestionId,\r
373 IN UINT8 Type,\r
374 IN EFI_IFR_TYPE_VALUE *Value,\r
375 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
376 )\r
377{\r
378 BMM_CALLBACK_DATA *Private;\r
379 FILE_EXPLORER_NV_DATA *NvRamMap;\r
380 EFI_STATUS Status;\r
5c08e117 381\r
84724077 382 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
4548fc2a 383 //\r
84724077 384 // All other action return unsupported.\r
4548fc2a 385 //\r
84724077
ED
386 return EFI_UNSUPPORTED;\r
387 }\r
388 \r
389 Status = EFI_SUCCESS;\r
390 Private = FE_CALLBACK_DATA_FROM_THIS (This);\r
4548fc2a 391\r
84724077
ED
392 //\r
393 // Retrieve uncommitted data from Form Browser\r
394 //\r
395 NvRamMap = &Private->FeFakeNvData;\r
396 HiiGetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap);\r
397\r
398 if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
399 if ((Value == NULL) || (ActionRequest == NULL)) {\r
400 return EFI_INVALID_PARAMETER;\r
401 }\r
402 \r
d88f86f1
ED
403 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT || QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
404 //\r
405 // Apply changes and exit formset\r
406 //\r
407 if (FileExplorerStateAddBootOption == Private->FeCurrentState) {\r
408 Status = Var_UpdateBootOption (Private, NvRamMap);\r
409 if (EFI_ERROR (Status)) {\r
410 return Status;\r
411 }\r
5c08e117 412\r
d88f86f1
ED
413 BOpt_GetBootOptions (Private);\r
414 CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);\r
415 } else if (FileExplorerStateAddDriverOptionState == Private->FeCurrentState) {\r
416 Status = Var_UpdateDriverOption (\r
417 Private,\r
418 Private->FeHiiHandle,\r
be9304f3
ED
419 NvRamMap->DriverDescriptionData,\r
420 NvRamMap->DriverOptionalData,\r
d88f86f1
ED
421 NvRamMap->ForceReconnect\r
422 );\r
423 if (EFI_ERROR (Status)) {\r
424 return Status;\r
425 }\r
5c08e117 426\r
d88f86f1
ED
427 BOpt_GetDriverOptions (Private);\r
428 CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);\r
5c08e117 429 }\r
430\r
d88f86f1 431 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
be9304f3
ED
432 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
433 //\r
434 // Discard changes and exit formset\r
435 //\r
436 NvRamMap->DriverOptionalData[0] = 0x0000;\r
437 NvRamMap->DriverDescriptionData[0] = 0x0000;\r
438 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
439 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {\r
d88f86f1
ED
440 //\r
441 // Discard changes and exit formset\r
442 //\r
be9304f3
ED
443 NvRamMap->BootOptionalData[0] = 0x0000;\r
444 NvRamMap->BootDescriptionData[0] = 0x0000;\r
d88f86f1 445 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
be9304f3 446 }else if (QuestionId < FILE_OPTION_OFFSET) {\r
d88f86f1
ED
447 //\r
448 // Exit File Explorer formset\r
449 //\r
450 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
c93bcb7e
ED
451 } else if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) {\r
452 //\r
453 // Update forms may return TRUE or FALSE, need to check here.\r
454 //\r
455 if (UpdateFileExplorer (Private, QuestionId)) {\r
456 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
457 }\r
5c08e117 458 }\r
84724077
ED
459 } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
460 if (Value == NULL) {\r
461 return EFI_INVALID_PARAMETER;\r
462 }\r
463 \r
c93bcb7e
ED
464 if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {\r
465 //\r
466 // function will always return FALSE, no need to check here.\r
467 //\r
84724077
ED
468 UpdateFileExplorer (Private, QuestionId);\r
469 }\r
5c08e117 470 }\r
84724077
ED
471\r
472 return Status;\r
5c08e117 473}\r