2 File explorer related functions.
4 Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BootMaint.h"
18 Update the File Explore page.
20 @param CallbackData The BMM context data.
21 @param MenuOption Pointer to menu options to display.
25 UpdateFileExplorePage (
26 IN BMM_CALLBACK_DATA
*CallbackData
,
27 BM_MENU_OPTION
*MenuOption
31 BM_MENU_ENTRY
*NewMenuEntry
;
32 BM_FILE_CONTEXT
*NewFileContext
;
36 NewFileContext
= NULL
;
40 mStartLabel
->Number
= FORM_FILE_EXPLORER_ID
;
42 for (Index
= 0; Index
< MenuOption
->MenuNumber
; Index
++) {
43 NewMenuEntry
= BOpt_GetMenuEntry (MenuOption
, Index
);
44 NewFileContext
= (BM_FILE_CONTEXT
*) NewMenuEntry
->VariableContext
;
46 if (NewFileContext
->IsBootLegacy
) {
50 if ((NewFileContext
->IsDir
) || (FileExplorerStateBootFromFile
== CallbackData
->FeCurrentState
)) {
52 // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.
54 HiiCreateActionOpCode (
56 (UINT16
) (FILE_OPTION_OFFSET
+ Index
),
57 NewMenuEntry
->DisplayStringToken
,
58 STRING_TOKEN (STR_NULL_STRING
),
59 EFI_IFR_FLAG_CALLBACK
,
64 // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.
66 if (FileExplorerStateAddBootOption
== CallbackData
->FeCurrentState
) {
67 FormId
= FORM_BOOT_ADD_DESCRIPTION_ID
;
68 } else if (FileExplorerStateAddDriverOptionState
== CallbackData
->FeCurrentState
) {
69 FormId
= FORM_DRIVER_ADD_FILE_DESCRIPTION_ID
;
75 NewMenuEntry
->DisplayStringToken
,
76 STRING_TOKEN (STR_NULL_STRING
),
77 EFI_IFR_FLAG_CALLBACK
,
78 (UINT16
) (FILE_OPTION_GOTO_OFFSET
+ Index
)
84 CallbackData
->FeHiiHandle
,
85 &gFileExploreFormSetGuid
,
86 FORM_FILE_EXPLORER_ID
,
87 mStartOpCodeHandle
, // Label FORM_FILE_EXPLORER_ID
88 mEndOpCodeHandle
// LABEL_END
93 Update the file explower page with the refershed file system.
96 @param CallbackData BMM context data
97 @param KeyValue Key value to identify the type of data to expect.
99 @retval TRUE Inform the caller to create a callback packet to exit file explorer.
100 @retval FALSE Indicate that there is no need to exit file explorer.
105 IN BMM_CALLBACK_DATA
*CallbackData
,
109 UINT16 FileOptionMask
;
110 BM_MENU_ENTRY
*NewMenuEntry
;
111 BM_FILE_CONTEXT
*NewFileContext
;
113 BOOLEAN ExitFileExplorer
;
117 NewFileContext
= NULL
;
118 ExitFileExplorer
= FALSE
;
120 FileOptionMask
= (UINT16
) (FILE_OPTION_MASK
& KeyValue
);
122 if (FileExplorerDisplayUnknown
== CallbackData
->FeDisplayContext
) {
124 // First in, display file system.
126 BOpt_FreeMenu (&FsOptionMenu
);
127 BOpt_FindFileSystem (CallbackData
);
128 CreateMenuStringToken (CallbackData
, CallbackData
->FeHiiHandle
, &FsOptionMenu
);
130 UpdateFileExplorePage (CallbackData
, &FsOptionMenu
);
132 CallbackData
->FeDisplayContext
= FileExplorerDisplayFileSystem
;
134 if (FileExplorerDisplayFileSystem
== CallbackData
->FeDisplayContext
) {
135 NewMenuEntry
= BOpt_GetMenuEntry (&FsOptionMenu
, FileOptionMask
);
136 } else if (FileExplorerDisplayDirectory
== CallbackData
->FeDisplayContext
) {
137 NewMenuEntry
= BOpt_GetMenuEntry (&DirectoryMenu
, FileOptionMask
);
140 NewFileContext
= (BM_FILE_CONTEXT
*) NewMenuEntry
->VariableContext
;
142 if (NewFileContext
->IsDir
) {
143 CallbackData
->FeDisplayContext
= FileExplorerDisplayDirectory
;
145 RemoveEntryList (&NewMenuEntry
->Link
);
146 BOpt_FreeMenu (&DirectoryMenu
);
147 Status
= BOpt_FindFiles (CallbackData
, NewMenuEntry
);
148 if (EFI_ERROR (Status
)) {
149 ExitFileExplorer
= TRUE
;
152 CreateMenuStringToken (CallbackData
, CallbackData
->FeHiiHandle
, &DirectoryMenu
);
153 BOpt_DestroyMenuEntry (NewMenuEntry
);
155 UpdateFileExplorePage (CallbackData
, &DirectoryMenu
);
158 switch (CallbackData
->FeCurrentState
) {
159 case FileExplorerStateBootFromFile
:
161 // Restore to original mode before launching boot option.
163 BdsSetConsoleMode (FALSE
);
166 // Here boot from file
168 BootThisFile (NewFileContext
);
170 // Set proper video resolution and text mode for setup.
172 BdsSetConsoleMode (TRUE
);
173 ExitFileExplorer
= TRUE
;
176 case FileExplorerStateAddBootOption
:
177 case FileExplorerStateAddDriverOptionState
:
178 if (FileExplorerStateAddBootOption
== CallbackData
->FeCurrentState
) {
179 FormId
= FORM_BOOT_ADD_DESCRIPTION_ID
;
180 if (!CallbackData
->FeFakeNvData
.BootOptionChanged
) {
181 ZeroMem (CallbackData
->FeFakeNvData
.BootOptionalData
, sizeof (CallbackData
->FeFakeNvData
.BootOptionalData
));
182 ZeroMem (CallbackData
->FeFakeNvData
.BootDescriptionData
, sizeof (CallbackData
->FeFakeNvData
.BootDescriptionData
));
185 FormId
= FORM_DRIVER_ADD_FILE_DESCRIPTION_ID
;
186 if (!CallbackData
->FeFakeNvData
.DriverOptionChanged
) {
187 ZeroMem (CallbackData
->FeFakeNvData
.DriverOptionalData
, sizeof (CallbackData
->FeFakeNvData
.DriverOptionalData
));
188 ZeroMem (CallbackData
->FeFakeNvData
.DriverDescriptionData
, sizeof (CallbackData
->FeFakeNvData
.DriverDescriptionData
));
192 CallbackData
->MenuEntry
= NewMenuEntry
;
193 CallbackData
->LoadContext
->FilePathList
= ((BM_FILE_CONTEXT
*) (CallbackData
->MenuEntry
->VariableContext
))->DevicePath
;
196 // Create Subtitle op-code for the display string of the option.
198 RefreshUpdateData ();
199 mStartLabel
->Number
= FormId
;
201 HiiCreateSubTitleOpCode (
203 NewMenuEntry
->DisplayStringToken
,
210 CallbackData
->FeHiiHandle
,
211 &gFileExploreFormSetGuid
,
213 mStartOpCodeHandle
, // Label FormId
214 mEndOpCodeHandle
// LABEL_END
224 return ExitFileExplorer
;
228 This function applies changes in a driver's configuration.
229 Input is a Configuration, which has the routing data for this
230 driver followed by name / value configuration pairs. The driver
231 must apply those pairs to its configurable storage. If the
232 driver's configuration is stored in a linear block of data
233 and the driver's name / value pairs are in <BlockConfig>
234 format, it may use the ConfigToBlock helper function (above) to
235 simplify the job. Currently not implemented.
237 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
238 @param[in] Configuration A null-terminated Unicode string in
239 <ConfigString> format.
240 @param[out] Progress A pointer to a string filled in with the
241 offset of the most recent '&' before the
242 first failing name / value pair (or the
243 beginn ing of the string if the failure
244 is in the first name / value pair) or
245 the terminating NULL if all was
248 @retval EFI_SUCCESS The results have been distributed or are
249 awaiting distribution.
250 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
251 parts of the results that must be
252 stored awaiting possible future
254 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
255 Results parameter would result
256 in this type of error.
257 @retval EFI_NOT_FOUND Target for the specified routing data
262 FileExplorerRouteConfig (
263 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
264 IN CONST EFI_STRING Configuration
,
265 OUT EFI_STRING
*Progress
270 EFI_HII_CONFIG_ROUTING_PROTOCOL
*ConfigRouting
;
271 FILE_EXPLORER_NV_DATA
*FeData
;
272 BMM_CALLBACK_DATA
*Private
;
274 if (Progress
== NULL
) {
275 return EFI_INVALID_PARAMETER
;
277 *Progress
= Configuration
;
279 if (Configuration
== NULL
) {
280 return EFI_INVALID_PARAMETER
;
284 // Check routing data in <ConfigHdr>.
285 // Note: there is no name for Name/Value storage, only GUID will be checked
287 if (!HiiIsConfigHdrMatch (Configuration
, &gFileExploreFormSetGuid
, mFileExplorerStorageName
)) {
288 return EFI_NOT_FOUND
;
291 Status
= gBS
->LocateProtocol (
292 &gEfiHiiConfigRoutingProtocolGuid
,
294 (VOID
**) &ConfigRouting
296 if (EFI_ERROR (Status
)) {
300 Private
= FE_CALLBACK_DATA_FROM_THIS (This
);
302 // Get Buffer Storage data from EFI variable
304 BufferSize
= sizeof (FILE_EXPLORER_NV_DATA
);
305 FeData
= &Private
->FeFakeNvData
;
308 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
310 Status
= ConfigRouting
->ConfigToBlock (
317 ASSERT_EFI_ERROR (Status
);
319 if (FeData
->BootDescriptionData
[0] != 0x00 || FeData
->BootOptionalData
[0] != 0x00) {
320 Status
= Var_UpdateBootOption (Private
, FeData
);
321 if (EFI_ERROR (Status
)) {
325 BOpt_GetBootOptions (Private
);
326 CreateMenuStringToken (Private
, Private
->FeHiiHandle
, &BootOptionMenu
);
329 if (FeData
->DriverDescriptionData
[0] != 0x00 || FeData
->DriverOptionalData
[0] != 0x00) {
330 Status
= Var_UpdateDriverOption (
332 Private
->FeHiiHandle
,
333 FeData
->DriverDescriptionData
,
334 FeData
->DriverOptionalData
,
335 FeData
->ForceReconnect
337 if (EFI_ERROR (Status
)) {
341 BOpt_GetDriverOptions (Private
);
342 CreateMenuStringToken (Private
, Private
->FeHiiHandle
, &DriverOptionMenu
);
349 This function processes the results of changes in configuration.
350 When user select a interactive opcode, this callback will be triggered.
351 Based on the Question(QuestionId) that triggers the callback, the corresponding
352 actions is performed. It handles:
354 1) the addition of boot option.
355 2) the addition of driver option.
356 3) exit from file browser
357 4) update of file content if a dir is selected.
358 5) boot the file if a file is selected in "boot from file"
361 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
362 @param Action Specifies the type of action taken by the browser.
363 @param QuestionId A unique value which is sent to the original exporting driver
364 so that it can identify the type of data to expect.
365 @param Type The type of value for the question.
366 @param Value A pointer to the data being sent to the original exporting driver.
367 @param ActionRequest On return, points to the action requested by the callback function.
369 @retval EFI_SUCCESS The callback successfully handled the action.
370 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
371 @retval EFI_DEVICE_ERROR The variable could not be saved.
372 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
373 @retval EFI_INVALID_PARAMETER If parameter Value or ActionRequest is NULL.
377 FileExplorerCallback (
378 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
379 IN EFI_BROWSER_ACTION Action
,
380 IN EFI_QUESTION_ID QuestionId
,
382 IN EFI_IFR_TYPE_VALUE
*Value
,
383 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
386 BMM_CALLBACK_DATA
*Private
;
387 FILE_EXPLORER_NV_DATA
*NvRamMap
;
390 if (Action
!= EFI_BROWSER_ACTION_CHANGING
&& Action
!= EFI_BROWSER_ACTION_CHANGED
) {
392 // All other action return unsupported.
394 return EFI_UNSUPPORTED
;
397 Status
= EFI_SUCCESS
;
398 Private
= FE_CALLBACK_DATA_FROM_THIS (This
);
401 // Retrieve uncommitted data from Form Browser
403 NvRamMap
= &Private
->FeFakeNvData
;
404 HiiGetBrowserData (&gFileExploreFormSetGuid
, mFileExplorerStorageName
, sizeof (FILE_EXPLORER_NV_DATA
), (UINT8
*) NvRamMap
);
406 if (Action
== EFI_BROWSER_ACTION_CHANGED
) {
407 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
408 return EFI_INVALID_PARAMETER
;
411 if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_BOOT
) {
412 NvRamMap
->BootOptionChanged
= FALSE
;
413 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
414 } else if (QuestionId
== KEY_VALUE_SAVE_AND_EXIT_DRIVER
) {
415 NvRamMap
->DriverOptionChanged
= FALSE
;
416 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_SUBMIT
;
417 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER
) {
419 // Discard changes and exit formset
421 NvRamMap
->DriverOptionalData
[0] = 0x0000;
422 NvRamMap
->DriverDescriptionData
[0] = 0x0000;
423 NvRamMap
->DriverOptionChanged
= FALSE
;
424 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
425 } else if (QuestionId
== KEY_VALUE_NO_SAVE_AND_EXIT_BOOT
) {
427 // Discard changes and exit formset
429 NvRamMap
->BootOptionalData
[0] = 0x0000;
430 NvRamMap
->BootDescriptionData
[0] = 0x0000;
431 NvRamMap
->BootOptionChanged
= FALSE
;
432 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
433 } else if (QuestionId
== KEY_VALUE_BOOT_DESCRIPTION
|| QuestionId
== KEY_VALUE_BOOT_OPTION
) {
434 NvRamMap
->BootOptionChanged
= TRUE
;
435 } else if (QuestionId
== KEY_VALUE_DRIVER_DESCRIPTION
|| QuestionId
== KEY_VALUE_DRIVER_OPTION
) {
436 NvRamMap
->DriverOptionChanged
= TRUE
;
437 } else if (QuestionId
< FILE_OPTION_OFFSET
) {
439 // Exit File Explorer formset
441 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
442 } else if (QuestionId
>= FILE_OPTION_OFFSET
&& QuestionId
< FILE_OPTION_GOTO_OFFSET
) {
444 // Update forms may return TRUE or FALSE, need to check here.
446 if (UpdateFileExplorer (Private
, QuestionId
)) {
447 *ActionRequest
= EFI_BROWSER_ACTION_REQUEST_EXIT
;
450 } else if (Action
== EFI_BROWSER_ACTION_CHANGING
) {
452 return EFI_INVALID_PARAMETER
;
455 if (QuestionId
>= FILE_OPTION_GOTO_OFFSET
) {
457 // function will always return FALSE, no need to check here.
459 UpdateFileExplorer (Private
, QuestionId
);
464 // Pass changed uncommitted data back to Form Browser
466 HiiSetBrowserData (&gFileExploreFormSetGuid
, mFileExplorerStorageName
, sizeof (FILE_EXPLORER_NV_DATA
), (UINT8
*) NvRamMap
, NULL
);