2 File explorer related functions.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 SPDX-License-Identifier: BSD-2-Clause-Patent
12 Update the File Explore page.
14 @param CallbackData The BMM context data.
15 @param MenuOption Pointer to menu options to display.
19 UpdateFileExplorePage (
20 IN BMM_CALLBACK_DATA
*CallbackData
,
21 BM_MENU_OPTION
*MenuOption
25 BM_MENU_ENTRY
*NewMenuEntry
;
26 BM_FILE_CONTEXT
*NewFileContext
;
30 NewFileContext
= NULL
;
34 mStartLabel
->Number
= FORM_FILE_EXPLORER_ID
;
36 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
37 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
38 NewFileContext
= (BM_FILE_CONTEXT
*) NewMenuEntry
->VariableContext
;
40 if (NewFileContext
->IsBootLegacy
) {
44 if ((NewFileContext
->IsDir
) || (FileExplorerStateBootFromFile
== CallbackData
->FeCurrentState
)) {
46 // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
48 HiiCreateActionOpCode (
50 (UINT16
) (FILE_OPTION_OFFSET
+ Index
),
51 NewMenuEntry
->DisplayStringToken
,
52 STRING_TOKEN (STR_NULL_STRING
),
53 EFI_IFR_FLAG_CALLBACK
,
58 // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.
60 if (FileExplorerStateAddBootOption
== CallbackData
->FeCurrentState
) {
61 FormId
= FORM_BOOT_ADD_DESCRIPTION_ID
;
62 } else if (FileExplorerStateAddDriverOptionState
== CallbackData
->FeCurrentState
) {
63 FormId
= FORM_DRIVER_ADD_FILE_DESCRIPTION_ID
;
69 NewMenuEntry
->DisplayStringToken
,
70 STRING_TOKEN (STR_NULL_STRING
),
71 EFI_IFR_FLAG_CALLBACK
,
72 (UINT16
) (FILE_OPTION_GOTO_OFFSET
+ Index
)
78 CallbackData
->FeHiiHandle
,
79 &gFileExploreFormSetGuid
,
80 FORM_FILE_EXPLORER_ID
,
81 mStartOpCodeHandle
, // Label FORM_FILE_EXPLORER_ID
82 mEndOpCodeHandle
// LABEL_END
87 Update the file explower page with the refershed file system.
90 @param CallbackData BMM context data
91 @param KeyValue Key value to identify the type of data to expect.
93 @retval TRUE Inform the caller to create a callback packet to exit file explorer.
94 @retval FALSE Indicate that there is no need to exit file explorer.
99 IN BMM_CALLBACK_DATA
*CallbackData
,
103 UINT16 FileOptionMask
;
104 BM_MENU_ENTRY
*NewMenuEntry
;
105 BM_FILE_CONTEXT
*NewFileContext
;
107 BOOLEAN ExitFileExplorer
;
111 NewFileContext
= NULL
;
112 ExitFileExplorer
= FALSE
;
114 FileOptionMask
= (UINT16
) (FILE_OPTION_MASK
& KeyValue
);
116 if (FileExplorerDisplayUnknown
== CallbackData
->FeDisplayContext
) {
118 // First in, display file system.
120 BOpt_FreeMenu (&FsOptionMenu
);
121 BOpt_FindFileSystem (CallbackData
);
122 CreateMenuStringToken (CallbackData
, CallbackData
->FeHiiHandle
, &FsOptionMenu
);
124 UpdateFileExplorePage (CallbackData
, &FsOptionMenu
);
126 CallbackData
->FeDisplayContext
= FileExplorerDisplayFileSystem
;
128 if (FileExplorerDisplayFileSystem
== CallbackData
->FeDisplayContext
) {
129 NewMenuEntry
= BOpt_GetMenuEntry (&FsOptionMenu
, FileOptionMask
);
130 } else if (FileExplorerDisplayDirectory
== CallbackData
->FeDisplayContext
) {
131 NewMenuEntry
= BOpt_GetMenuEntry (&DirectoryMenu
, FileOptionMask
);
134 NewFileContext
= (BM_FILE_CONTEXT
*) NewMenuEntry
->VariableContext
;
136 if (NewFileContext
->IsDir
) {
137 CallbackData
->FeDisplayContext
= FileExplorerDisplayDirectory
;
139 RemoveEntryList (&NewMenuEntry
->Link
);
140 BOpt_FreeMenu (&DirectoryMenu
);
141 Status
= BOpt_FindFiles (CallbackData
, NewMenuEntry
);
142 if (EFI_ERROR (Status
)) {
143 ExitFileExplorer
= TRUE
;
146 CreateMenuStringToken (CallbackData
, CallbackData
->FeHiiHandle
, &DirectoryMenu
);
147 BOpt_DestroyMenuEntry (NewMenuEntry
);
149 UpdateFileExplorePage (CallbackData
, &DirectoryMenu
);
152 switch (CallbackData
->FeCurrentState
) {
153 case FileExplorerStateBootFromFile
:
155 // Restore to original mode before launching boot option.
157 BdsSetConsoleMode (FALSE
);
160 // Here boot from file
162 BootThisFile (NewFileContext
);
164 // Set proper video resolution and text mode for setup.
166 BdsSetConsoleMode (TRUE
);
167 ExitFileExplorer
= TRUE
;
170 case FileExplorerStateAddBootOption
:
171 case FileExplorerStateAddDriverOptionState
:
172 if (FileExplorerStateAddBootOption
== CallbackData
->FeCurrentState
) {
173 FormId
= FORM_BOOT_ADD_DESCRIPTION_ID
;
174 if (!CallbackData
->FeFakeNvData
.BootOptionChanged
) {
175 ZeroMem (CallbackData
->FeFakeNvData
.BootOptionalData
, sizeof (CallbackData
->FeFakeNvData
.BootOptionalData
));
176 ZeroMem (CallbackData
->FeFakeNvData
.BootDescriptionData
, sizeof (CallbackData
->FeFakeNvData
.BootDescriptionData
));
179 FormId
= FORM_DRIVER_ADD_FILE_DESCRIPTION_ID
;
180 if (!CallbackData
->FeFakeNvData
.DriverOptionChanged
) {
181 ZeroMem (CallbackData
->FeFakeNvData
.DriverOptionalData
, sizeof (CallbackData
->FeFakeNvData
.DriverOptionalData
));
182 ZeroMem (CallbackData
->FeFakeNvData
.DriverDescriptionData
, sizeof (CallbackData
->FeFakeNvData
.DriverDescriptionData
));
186 CallbackData
->MenuEntry
= NewMenuEntry
;
187 CallbackData
->LoadContext
->FilePathList
= ((BM_FILE_CONTEXT
*) (CallbackData
->MenuEntry
->VariableContext
))->DevicePath
;
190 // Create Subtitle op-code for the display string of the option.
192 RefreshUpdateData ();
193 mStartLabel
->Number
= FormId
;
195 HiiCreateSubTitleOpCode (
197 NewMenuEntry
->DisplayStringToken
,
204 CallbackData
->FeHiiHandle
,
205 &gFileExploreFormSetGuid
,
207 mStartOpCodeHandle
, // Label FormId
208 mEndOpCodeHandle
// LABEL_END
218 return ExitFileExplorer
;
222 This function applies changes in a driver's configuration.
223 Input is a Configuration, which has the routing data for this
224 driver followed by name / value configuration pairs. The driver
225 must apply those pairs to its configurable storage. If the
226 driver's configuration is stored in a linear block of data
227 and the driver's name / value pairs are in <BlockConfig>
228 format, it may use the ConfigToBlock helper function (above) to
229 simplify the job. Currently not implemented.
231 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
232 @param[in] Configuration A null-terminated Unicode string in
233 <ConfigString> format.
234 @param[out] Progress A pointer to a string filled in with the
235 offset of the most recent '&' before the
236 first failing name / value pair (or the
237 beginn ing of the string if the failure
238 is in the first name / value pair) or
239 the terminating NULL if all was
242 @retval EFI_SUCCESS The results have been distributed or are
243 awaiting distribution.
244 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
245 parts of the results that must be
246 stored awaiting possible future
248 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
249 Results parameter would result
250 in this type of error.
251 @retval EFI_NOT_FOUND Target for the specified routing data
256 FileExplorerRouteConfig (
257 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
258 IN CONST EFI_STRING Configuration
,
259 OUT EFI_STRING
*Progress
264 EFI_HII_CONFIG_ROUTING_PROTOCOL
*ConfigRouting
;
265 FILE_EXPLORER_NV_DATA
*FeData
;
266 BMM_CALLBACK_DATA
*Private
;
268 if (Progress
== NULL
) {
269 return EFI_INVALID_PARAMETER
;
271 *Progress
= Configuration
;
273 if (Configuration
== NULL
) {
274 return EFI_INVALID_PARAMETER
;
278 // Check routing data in <ConfigHdr>.
279 // Note: there is no name for Name/Value storage, only GUID will be checked
281 if (!HiiIsConfigHdrMatch (Configuration
, &gFileExploreFormSetGuid
, mFileExplorerStorageName
)) {
282 return EFI_NOT_FOUND
;
285 Status
= gBS
->LocateProtocol (
286 &gEfiHiiConfigRoutingProtocolGuid
,
288 (VOID
**) &ConfigRouting
290 if (EFI_ERROR (Status
)) {
294 Private
= FE_CALLBACK_DATA_FROM_THIS (This
);
296 // Get Buffer Storage data from EFI variable
298 BufferSize
= sizeof (FILE_EXPLORER_NV_DATA
);
299 FeData
= &Private
->FeFakeNvData
;
302 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
304 Status
= ConfigRouting
->ConfigToBlock (
311 ASSERT_EFI_ERROR (Status
);
313 if (FeData
->BootDescriptionData
[0] != 0x00 || FeData
->BootOptionalData
[0] != 0x00) {
314 Status
= Var_UpdateBootOption (Private
, FeData
);
315 if (EFI_ERROR (Status
)) {
319 BOpt_GetBootOptions (Private
);
320 CreateMenuStringToken (Private
, Private
->FeHiiHandle
, &BootOptionMenu
);
323 if (FeData
->DriverDescriptionData
[0] != 0x00 || FeData
->DriverOptionalData
[0] != 0x00) {
324 Status
= Var_UpdateDriverOption (
326 Private
->FeHiiHandle
,
327 FeData
->DriverDescriptionData
,
328 FeData
->DriverOptionalData
,
329 FeData
->ForceReconnect
331 if (EFI_ERROR (Status
)) {
335 BOpt_GetDriverOptions (Private
);
336 CreateMenuStringToken (Private
, Private
->FeHiiHandle
, &DriverOptionMenu
);
343 This function processes the results of changes in configuration.
344 When user select a interactive opcode, this callback will be triggered.
345 Based on the Question(QuestionId) that triggers the callback, the corresponding
346 actions is performed. It handles:
348 1) the addition of boot option.
349 2) the addition of driver option.
350 3) exit from file browser
351 4) update of file content if a dir is selected.
352 5) boot the file if a file is selected in "boot from file"
355 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
356 @param Action Specifies the type of action taken by the browser.
357 @param QuestionId A unique value which is sent to the original exporting driver
358 so that it can identify the type of data to expect.
359 @param Type The type of value for the question.
360 @param Value A pointer to the data being sent to the original exporting driver.
361 @param ActionRequest On return, points to the action requested by the callback function.
363 @retval EFI_SUCCESS The callback successfully handled the action.
364 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
365 @retval EFI_DEVICE_ERROR The variable could not be saved.
366 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
367 @retval EFI_INVALID_PARAMETER If parameter Value or ActionRequest is NULL.
371 FileExplorerCallback (
372 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
373 IN EFI_BROWSER_ACTION Action
,
374 IN EFI_QUESTION_ID QuestionId
,
376 IN EFI_IFR_TYPE_VALUE
*Value
,
377 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
380 BMM_CALLBACK_DATA
*Private
;
381 FILE_EXPLORER_NV_DATA
*NvRamMap
;
384 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
386 // All other action return unsupported.
388 return EFI_UNSUPPORTED
;
391 Status
= EFI_SUCCESS
;
392 Private
= FE_CALLBACK_DATA_FROM_THIS (This
);
395 // Retrieve uncommitted data from Form Browser
397 NvRamMap
= &Private
->FeFakeNvData
;
398 HiiGetBrowserData (&gFileExploreFormSetGuid
, mFileExplorerStorageName
, sizeof (FILE_EXPLORER_NV_DATA
), (UINT8
*) NvRamMap
);
400 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
401 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
402 return EFI_INVALID_PARAMETER
;
405 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_BOOT
) {
406 NvRamMap
->BootOptionChanged
= FALSE
;
407 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
408 } else if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_DRIVER
) {
409 NvRamMap
->DriverOptionChanged
= FALSE
;
410 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
411 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER
) {
413 // Discard changes and exit formset
415 NvRamMap
->DriverOptionalData
[0] = 0x0000;
416 NvRamMap
->DriverDescriptionData
[0] = 0x0000;
417 NvRamMap
->DriverOptionChanged
= FALSE
;
418 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
419 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_BOOT
) {
421 // Discard changes and exit formset
423 NvRamMap
->BootOptionalData
[0] = 0x0000;
424 NvRamMap
->BootDescriptionData
[0] = 0x0000;
425 NvRamMap
->BootOptionChanged
= FALSE
;
426 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
427 } else if (QuestionId
== KEY_VALUE_BOOT_DESCRIPTION
|| QuestionId
== KEY_VALUE_BOOT_OPTION
) {
428 NvRamMap
->BootOptionChanged
= TRUE
;
429 } else if (QuestionId
== KEY_VALUE_DRIVER_DESCRIPTION
|| QuestionId
== KEY_VALUE_DRIVER_OPTION
) {
430 NvRamMap
->DriverOptionChanged
= TRUE
;
431 } else if (QuestionId
< FILE_OPTION_OFFSET
) {
433 // Exit File Explorer formset
435 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
436 } else if (QuestionId
>= FILE_OPTION_OFFSET
&& QuestionId
< FILE_OPTION_GOTO_OFFSET
) {
438 // Update forms may return TRUE or FALSE, need to check here.
440 if (UpdateFileExplorer (Private
, QuestionId
)) {
441 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
444 } else if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
446 return EFI_INVALID_PARAMETER
;
449 if (QuestionId
>= FILE_OPTION_GOTO_OFFSET
) {
451 // function will always return FALSE, no need to check here.
453 UpdateFileExplorer (Private
, QuestionId
);
458 // Pass changed uncommitted data back to Form Browser
460 HiiSetBrowserData (&gFileExploreFormSetGuid
, mFileExplorerStorageName
, sizeof (FILE_EXPLORER_NV_DATA
), (UINT8
*) NvRamMap
, NULL
);