+++ /dev/null
-/** @file\r
- File explorer related functions.\r
-\r
-Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
-SPDX-License-Identifier: BSD-2-Clause-Patent\r
-\r
-**/\r
-\r
-#include "BootMaint.h"\r
-\r
-/**\r
- Update the File Explore page.\r
-\r
- @param CallbackData The BMM context data.\r
- @param MenuOption Pointer to menu options to display.\r
-\r
-**/\r
-VOID\r
-UpdateFileExplorePage (\r
- IN BMM_CALLBACK_DATA *CallbackData,\r
- BM_MENU_OPTION *MenuOption\r
- )\r
-{\r
- UINTN Index;\r
- BM_MENU_ENTRY *NewMenuEntry;\r
- BM_FILE_CONTEXT *NewFileContext;\r
- EFI_FORM_ID FormId;\r
-\r
- NewMenuEntry = NULL;\r
- NewFileContext = NULL;\r
- FormId = 0;\r
-\r
- RefreshUpdateData ();\r
- mStartLabel->Number = FORM_FILE_EXPLORER_ID;\r
-\r
- for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
- NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
- NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
-\r
- if (NewFileContext->IsBootLegacy) {\r
- continue;\r
- }\r
-\r
- if ((NewFileContext->IsDir) || (FileExplorerStateBootFromFile == CallbackData->FeCurrentState)) {\r
- //\r
- // Create Text opcode for directory, also create Text opcode for file in FileExplorerStateBootFromFile.\r
- //\r
- HiiCreateActionOpCode (\r
- mStartOpCodeHandle,\r
- (UINT16) (FILE_OPTION_OFFSET + Index),\r
- NewMenuEntry->DisplayStringToken,\r
- STRING_TOKEN (STR_NULL_STRING),\r
- EFI_IFR_FLAG_CALLBACK,\r
- 0\r
- );\r
- } else {\r
- //\r
- // Create Goto opcode for file in FileExplorerStateAddBootOption or FileExplorerStateAddDriverOptionState.\r
- //\r
- if (FileExplorerStateAddBootOption == CallbackData->FeCurrentState) {\r
- FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
- } else if (FileExplorerStateAddDriverOptionState == CallbackData->FeCurrentState) {\r
- FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
- }\r
-\r
- HiiCreateGotoOpCode (\r
- mStartOpCodeHandle,\r
- FormId,\r
- NewMenuEntry->DisplayStringToken,\r
- STRING_TOKEN (STR_NULL_STRING),\r
- EFI_IFR_FLAG_CALLBACK,\r
- (UINT16) (FILE_OPTION_GOTO_OFFSET + Index)\r
- );\r
- }\r
- }\r
-\r
- HiiUpdateForm (\r
- CallbackData->FeHiiHandle,\r
- &gFileExploreFormSetGuid,\r
- FORM_FILE_EXPLORER_ID,\r
- mStartOpCodeHandle, // Label FORM_FILE_EXPLORER_ID\r
- mEndOpCodeHandle // LABEL_END\r
- );\r
-}\r
-\r
-/**\r
- Update the file explower page with the refershed file system.\r
-\r
-\r
- @param CallbackData BMM context data\r
- @param KeyValue Key value to identify the type of data to expect.\r
-\r
- @retval TRUE Inform the caller to create a callback packet to exit file explorer.\r
- @retval FALSE Indicate that there is no need to exit file explorer.\r
-\r
-**/\r
-BOOLEAN\r
-UpdateFileExplorer (\r
- IN BMM_CALLBACK_DATA *CallbackData,\r
- IN UINT16 KeyValue\r
- )\r
-{\r
- UINT16 FileOptionMask;\r
- BM_MENU_ENTRY *NewMenuEntry;\r
- BM_FILE_CONTEXT *NewFileContext;\r
- EFI_FORM_ID FormId;\r
- BOOLEAN ExitFileExplorer;\r
- EFI_STATUS Status;\r
-\r
- NewMenuEntry = NULL;\r
- NewFileContext = NULL;\r
- ExitFileExplorer = FALSE;\r
-\r
- FileOptionMask = (UINT16) (FILE_OPTION_MASK & KeyValue);\r
-\r
- if (FileExplorerDisplayUnknown == CallbackData->FeDisplayContext) {\r
- //\r
- // First in, display file system.\r
- //\r
- BOpt_FreeMenu (&FsOptionMenu);\r
- BOpt_FindFileSystem (CallbackData);\r
- CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &FsOptionMenu);\r
-\r
- UpdateFileExplorePage (CallbackData, &FsOptionMenu);\r
-\r
- CallbackData->FeDisplayContext = FileExplorerDisplayFileSystem;\r
- } else {\r
- if (FileExplorerDisplayFileSystem == CallbackData->FeDisplayContext) {\r
- NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);\r
- } else if (FileExplorerDisplayDirectory == CallbackData->FeDisplayContext) {\r
- NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);\r
- }\r
-\r
- NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
-\r
- if (NewFileContext->IsDir ) {\r
- CallbackData->FeDisplayContext = FileExplorerDisplayDirectory;\r
-\r
- RemoveEntryList (&NewMenuEntry->Link);\r
- BOpt_FreeMenu (&DirectoryMenu);\r
- Status = BOpt_FindFiles (CallbackData, NewMenuEntry);\r
- if (EFI_ERROR (Status)) {\r
- ExitFileExplorer = TRUE;\r
- goto exit;\r
- }\r
- CreateMenuStringToken (CallbackData, CallbackData->FeHiiHandle, &DirectoryMenu);\r
- BOpt_DestroyMenuEntry (NewMenuEntry);\r
-\r
- UpdateFileExplorePage (CallbackData, &DirectoryMenu);\r
-\r
- } else {\r
- switch (CallbackData->FeCurrentState) {\r
- case FileExplorerStateBootFromFile:\r
- //\r
- // Restore to original mode before launching boot option.\r
- //\r
- BdsSetConsoleMode (FALSE);\r
-\r
- //\r
- // Here boot from file\r
- //\r
- BootThisFile (NewFileContext);\r
- //\r
- // Set proper video resolution and text mode for setup.\r
- //\r
- BdsSetConsoleMode (TRUE);\r
- ExitFileExplorer = TRUE;\r
- break;\r
-\r
- case FileExplorerStateAddBootOption:\r
- case FileExplorerStateAddDriverOptionState:\r
- if (FileExplorerStateAddBootOption == CallbackData->FeCurrentState) {\r
- FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
- if (!CallbackData->FeFakeNvData.BootOptionChanged) {\r
- ZeroMem (CallbackData->FeFakeNvData.BootOptionalData, sizeof (CallbackData->FeFakeNvData.BootOptionalData));\r
- ZeroMem (CallbackData->FeFakeNvData.BootDescriptionData, sizeof (CallbackData->FeFakeNvData.BootDescriptionData));\r
- }\r
- } else {\r
- FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
- if (!CallbackData->FeFakeNvData.DriverOptionChanged) {\r
- ZeroMem (CallbackData->FeFakeNvData.DriverOptionalData, sizeof (CallbackData->FeFakeNvData.DriverOptionalData));\r
- ZeroMem (CallbackData->FeFakeNvData.DriverDescriptionData, sizeof (CallbackData->FeFakeNvData.DriverDescriptionData));\r
- }\r
- }\r
-\r
- CallbackData->MenuEntry = NewMenuEntry;\r
- CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;\r
-\r
- //\r
- // Create Subtitle op-code for the display string of the option.\r
- //\r
- RefreshUpdateData ();\r
- mStartLabel->Number = FormId;\r
-\r
- HiiCreateSubTitleOpCode (\r
- mStartOpCodeHandle,\r
- NewMenuEntry->DisplayStringToken,\r
- 0,\r
- 0,\r
- 0\r
- );\r
-\r
- HiiUpdateForm (\r
- CallbackData->FeHiiHandle,\r
- &gFileExploreFormSetGuid,\r
- FormId,\r
- mStartOpCodeHandle, // Label FormId\r
- mEndOpCodeHandle // LABEL_END\r
- );\r
- break;\r
-\r
- default:\r
- break;\r
- }\r
- }\r
- }\r
- exit:\r
- return ExitFileExplorer;\r
-}\r
-\r
-/**\r
- This function applies changes in a driver's configuration.\r
- Input is a Configuration, which has the routing data for this\r
- driver followed by name / value configuration pairs. The driver\r
- must apply those pairs to its configurable storage. If the\r
- driver's configuration is stored in a linear block of data\r
- and the driver's name / value pairs are in <BlockConfig>\r
- format, it may use the ConfigToBlock helper function (above) to\r
- simplify the job. Currently not implemented.\r
-\r
- @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param[in] Configuration A null-terminated Unicode string in\r
- <ConfigString> format.\r
- @param[out] Progress A pointer to a string filled in with the\r
- offset of the most recent '&' before the\r
- first failing name / value pair (or the\r
- beginn ing of the string if the failure\r
- is in the first name / value pair) or\r
- the terminating NULL if all was\r
- successful.\r
-\r
- @retval EFI_SUCCESS The results have been distributed or are\r
- awaiting distribution.\r
- @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
- parts of the results that must be\r
- stored awaiting possible future\r
- protocols.\r
- @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
- Results parameter would result\r
- in this type of error.\r
- @retval EFI_NOT_FOUND Target for the specified routing data\r
- was not found.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileExplorerRouteConfig (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN CONST EFI_STRING Configuration,\r
- OUT EFI_STRING *Progress\r
- )\r
-{\r
- EFI_STATUS Status;\r
- UINTN BufferSize;\r
- EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
- FILE_EXPLORER_NV_DATA *FeData;\r
- BMM_CALLBACK_DATA *Private;\r
-\r
- if (Progress == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
- *Progress = Configuration;\r
-\r
- if (Configuration == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- //\r
- // Check routing data in <ConfigHdr>.\r
- // Note: there is no name for Name/Value storage, only GUID will be checked\r
- //\r
- if (!HiiIsConfigHdrMatch (Configuration, &gFileExploreFormSetGuid, mFileExplorerStorageName)) {\r
- return EFI_NOT_FOUND;\r
- }\r
-\r
- Status = gBS->LocateProtocol (\r
- &gEfiHiiConfigRoutingProtocolGuid,\r
- NULL,\r
- (VOID**) &ConfigRouting\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- Private = FE_CALLBACK_DATA_FROM_THIS (This);\r
- //\r
- // Get Buffer Storage data from EFI variable\r
- //\r
- BufferSize = sizeof (FILE_EXPLORER_NV_DATA );\r
- FeData = &Private->FeFakeNvData;\r
-\r
- //\r
- // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
- //\r
- Status = ConfigRouting->ConfigToBlock (\r
- ConfigRouting,\r
- Configuration,\r
- (UINT8 *) FeData,\r
- &BufferSize,\r
- Progress\r
- );\r
- ASSERT_EFI_ERROR (Status);\r
-\r
- if (FeData->BootDescriptionData[0] != 0x00 || FeData->BootOptionalData[0] != 0x00) {\r
- Status = Var_UpdateBootOption (Private, FeData);\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- BOpt_GetBootOptions (Private);\r
- CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);\r
- }\r
-\r
- if (FeData->DriverDescriptionData[0] != 0x00 || FeData->DriverOptionalData[0] != 0x00) {\r
- Status = Var_UpdateDriverOption (\r
- Private,\r
- Private->FeHiiHandle,\r
- FeData->DriverDescriptionData,\r
- FeData->DriverOptionalData,\r
- FeData->ForceReconnect\r
- );\r
- if (EFI_ERROR (Status)) {\r
- return Status;\r
- }\r
-\r
- BOpt_GetDriverOptions (Private);\r
- CreateMenuStringToken (Private, Private->FeHiiHandle, &DriverOptionMenu);\r
- }\r
-\r
- return EFI_SUCCESS;\r
-}\r
-\r
-/**\r
- This function processes the results of changes in configuration.\r
- When user select a interactive opcode, this callback will be triggered.\r
- Based on the Question(QuestionId) that triggers the callback, the corresponding\r
- actions is performed. It handles:\r
-\r
- 1) the addition of boot option.\r
- 2) the addition of driver option.\r
- 3) exit from file browser\r
- 4) update of file content if a dir is selected.\r
- 5) boot the file if a file is selected in "boot from file"\r
-\r
-\r
- @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
- @param Action Specifies the type of action taken by the browser.\r
- @param QuestionId A unique value which is sent to the original exporting driver\r
- so that it can identify the type of data to expect.\r
- @param Type The type of value for the question.\r
- @param Value A pointer to the data being sent to the original exporting driver.\r
- @param ActionRequest On return, points to the action requested by the callback function.\r
-\r
- @retval EFI_SUCCESS The callback successfully handled the action.\r
- @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
- @retval EFI_DEVICE_ERROR The variable could not be saved.\r
- @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
- @retval EFI_INVALID_PARAMETER If parameter Value or ActionRequest is NULL.\r
-**/\r
-EFI_STATUS\r
-EFIAPI\r
-FileExplorerCallback (\r
- IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
- IN EFI_BROWSER_ACTION Action,\r
- IN EFI_QUESTION_ID QuestionId,\r
- IN UINT8 Type,\r
- IN EFI_IFR_TYPE_VALUE *Value,\r
- OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
- )\r
-{\r
- BMM_CALLBACK_DATA *Private;\r
- FILE_EXPLORER_NV_DATA *NvRamMap;\r
- EFI_STATUS Status;\r
-\r
- if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
- //\r
- // All other action return unsupported.\r
- //\r
- return EFI_UNSUPPORTED;\r
- }\r
-\r
- Status = EFI_SUCCESS;\r
- Private = FE_CALLBACK_DATA_FROM_THIS (This);\r
-\r
- //\r
- // Retrieve uncommitted data from Form Browser\r
- //\r
- NvRamMap = &Private->FeFakeNvData;\r
- HiiGetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap);\r
-\r
- if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
- if ((Value == NULL) || (ActionRequest == NULL)) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {\r
- NvRamMap->BootOptionChanged = FALSE;\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
- } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {\r
- NvRamMap->DriverOptionChanged = FALSE;\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_SUBMIT;\r
- } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {\r
- //\r
- // Discard changes and exit formset\r
- //\r
- NvRamMap->DriverOptionalData[0] = 0x0000;\r
- NvRamMap->DriverDescriptionData[0] = 0x0000;\r
- NvRamMap->DriverOptionChanged = FALSE;\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
- } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {\r
- //\r
- // Discard changes and exit formset\r
- //\r
- NvRamMap->BootOptionalData[0] = 0x0000;\r
- NvRamMap->BootDescriptionData[0] = 0x0000;\r
- NvRamMap->BootOptionChanged = FALSE;\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
- } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {\r
- NvRamMap->BootOptionChanged = TRUE;\r
- } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {\r
- NvRamMap->DriverOptionChanged = TRUE;\r
- } else if (QuestionId < FILE_OPTION_OFFSET) {\r
- //\r
- // Exit File Explorer formset\r
- //\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
- } else if (QuestionId >= FILE_OPTION_OFFSET && QuestionId < FILE_OPTION_GOTO_OFFSET) {\r
- //\r
- // Update forms may return TRUE or FALSE, need to check here.\r
- //\r
- if (UpdateFileExplorer (Private, QuestionId)) {\r
- *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT;\r
- }\r
- }\r
- } else if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
- if (Value == NULL) {\r
- return EFI_INVALID_PARAMETER;\r
- }\r
-\r
- if (QuestionId >= FILE_OPTION_GOTO_OFFSET) {\r
- //\r
- // function will always return FALSE, no need to check here.\r
- //\r
- UpdateFileExplorer (Private, QuestionId);\r
- }\r
- }\r
-\r
- //\r
- // Pass changed uncommitted data back to Form Browser\r
- //\r
- HiiSetBrowserData (&gFileExploreFormSetGuid, mFileExplorerStorageName, sizeof (FILE_EXPLORER_NV_DATA), (UINT8 *) NvRamMap, NULL);\r
-\r
- return Status;\r
-}\r