--- /dev/null
+/*++\r
+\r
+Copyright (c) 2006, Intel Corporation \r
+All rights reserved. This program and the accompanying materials \r
+are licensed and made available under the terms and conditions of the BSD License \r
+which accompanies this distribution. The full text of the license may be found at \r
+http://opensource.org/licenses/bsd-license.php \r
+ \r
+THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r
+WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r
+\r
+Module Name:\r
+\r
+ FileExplorer.c\r
+ \r
+AgBStract:\r
+\r
+ File explorer related functions.\r
+\r
+--*/\r
+\r
+#include "Generic/Bds.h"\r
+#include "BootMaint.h"\r
+#include "BdsPlatform.h"\r
+\r
+VOID\r
+UpdateFileExplorePage (\r
+ IN BMM_CALLBACK_DATA *CallbackData,\r
+ BM_MENU_OPTION *MenuOption\r
+ )\r
+/*++\r
+Routine Description:\r
+ Update the File Explore page.\r
+\r
+Arguments:\r
+ MenuOption - Pointer to menu options to display.\r
+\r
+Returns:\r
+ None.\r
+\r
+--*/\r
+{\r
+ UINT8 *Location;\r
+ UINTN Index;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ BM_FILE_CONTEXT *NewFileContext;\r
+ FORM_ID FormId;\r
+\r
+ NewMenuEntry = NULL;\r
+ NewFileContext = NULL;\r
+ FormId = 0;\r
+\r
+ //\r
+ // Clean up file explore page.\r
+ //\r
+ RefreshUpdateData (FALSE, 0, FALSE, 0, 0xff);\r
+\r
+ //\r
+ // Remove all op-codes from dynamic page\r
+ //\r
+ CallbackData->Hii->UpdateForm (\r
+ CallbackData->Hii,\r
+ CallbackData->FeHiiHandle,\r
+ FORM_FILE_EXPLORER_ID,\r
+ FALSE,\r
+ UpdateData\r
+ );\r
+\r
+ RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 0);\r
+\r
+ Location = (UINT8 *) &UpdateData->Data;\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) || (BOOT_FROM_FILE_STATE == CallbackData->FeCurrentState)) {\r
+ //\r
+ // Create Text opcode for directory, also create Text opcode for file in BOOT_FROM_FILE_STATE.\r
+ //\r
+ CreateTextOpCode (\r
+ NewMenuEntry->DisplayStringToken,\r
+ STR_NULL_STRING,\r
+ STR_NULL_STRING,\r
+ EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+ (UINT16) (FILE_OPTION_OFFSET + Index),\r
+ Location\r
+ );\r
+ } else {\r
+ //\r
+ // Create Goto opcode for file in ADD_BOOT_OPTION_STATE or ADD_DRIVER_OPTION_STATE.\r
+ //\r
+ if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {\r
+ FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
+ } else if (ADD_DRIVER_OPTION_STATE == CallbackData->FeCurrentState) {\r
+ FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
+ }\r
+\r
+ CreateGotoOpCode (\r
+ FormId,\r
+ NewMenuEntry->DisplayStringToken,\r
+ STRING_TOKEN (STR_NULL_STRING),\r
+ EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,\r
+ (UINT16) (FILE_OPTION_OFFSET + Index),\r
+ Location\r
+ );\r
+ }\r
+\r
+ UpdateData->DataCount++;\r
+ Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;\r
+ }\r
+\r
+ CallbackData->Hii->UpdateForm (\r
+ CallbackData->Hii,\r
+ CallbackData->FeHiiHandle,\r
+ FORM_FILE_EXPLORER_ID,\r
+ TRUE,\r
+ UpdateData\r
+ );\r
+}\r
+\r
+BOOLEAN\r
+UpdateFileExplorer (\r
+ IN BMM_CALLBACK_DATA *CallbackData,\r
+ IN UINT16 KeyValue\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Update the file explower page with the refershed file system.\r
+\r
+Arguments:\r
+ CallbackData - BMM context data\r
+ KeyValue - Key value to identify the type of data to expect.\r
+\r
+Returns:\r
+ TRUE - Inform the caller to create a callback packet to exit file explorer.\r
+ FALSE - Indicate that there is no need to exit file explorer.\r
+\r
+--*/\r
+{\r
+ UINT16 FileOptionMask;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ BM_FILE_CONTEXT *NewFileContext;\r
+ 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 (UNKNOWN_CONTEXT == 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 = FILE_SYSTEM;\r
+ } else {\r
+ if (FILE_SYSTEM == CallbackData->FeDisplayContext) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&FsOptionMenu, FileOptionMask);\r
+ } else if (DIRECTORY == CallbackData->FeDisplayContext) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&DirectoryMenu, FileOptionMask);\r
+ }\r
+\r
+ CallbackData->FeDisplayContext = DIRECTORY;\r
+\r
+ NewFileContext = (BM_FILE_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+ if (NewFileContext->IsDir ) {\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 BOOT_FROM_FILE_STATE:\r
+ //\r
+ // Here boot from file\r
+ //\r
+ BootThisFile (NewFileContext);\r
+ ExitFileExplorer = TRUE;\r
+ break;\r
+\r
+ case ADD_BOOT_OPTION_STATE:\r
+ case ADD_DRIVER_OPTION_STATE:\r
+ if (ADD_BOOT_OPTION_STATE == CallbackData->FeCurrentState) {\r
+ FormId = FORM_BOOT_ADD_DESCRIPTION_ID;\r
+ } else {\r
+ FormId = FORM_DRIVER_ADD_FILE_DESCRIPTION_ID;\r
+ }\r
+\r
+ CallbackData->MenuEntry = NewMenuEntry;\r
+ CallbackData->LoadContext->FilePathList = ((BM_FILE_CONTEXT *) (CallbackData->MenuEntry->VariableContext))->DevicePath;\r
+\r
+ //\r
+ // Clean up file explore page.\r
+ //\r
+ RefreshUpdateData (FALSE, 0, FALSE, 0, 1);\r
+\r
+ //\r
+ // Remove the Subtitle op-code.\r
+ //\r
+ CallbackData->Hii->UpdateForm (\r
+ CallbackData->Hii,\r
+ CallbackData->FeHiiHandle,\r
+ FormId,\r
+ FALSE,\r
+ UpdateData\r
+ );\r
+\r
+ //\r
+ // Create Subtitle op-code for the display string of the option.\r
+ //\r
+ RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) CallbackData->FeCallbackHandle, FALSE, 0, 1);\r
+\r
+ CreateSubTitleOpCode (\r
+ NewMenuEntry->DisplayStringToken,\r
+ &UpdateData->Data\r
+ );\r
+\r
+ CallbackData->Hii->UpdateForm (\r
+ CallbackData->Hii,\r
+ CallbackData->FeHiiHandle,\r
+ FormId,\r
+ TRUE,\r
+ UpdateData\r
+ );\r
+ break;\r
+\r
+ default:\r
+ break;\r
+ }\r
+ }\r
+ }\r
+exit:\r
+ return ExitFileExplorer;\r
+}\r
+\r
+EFI_STATUS\r
+EFIAPI\r
+FileExplorerCallback (\r
+ IN EFI_FORM_CALLBACK_PROTOCOL *This,\r
+ IN UINT16 KeyValue,\r
+ IN EFI_IFR_DATA_ARRAY *Data,\r
+ OUT EFI_HII_CALLBACK_PACKET **Packet\r
+ )\r
+/*++\r
+Routine Description:\r
+ Callback Function for file exploration and file interaction.\r
+\r
+Arguments:\r
+ This - File explorer callback protocol pointer. \r
+ KeyValue - Key value to identify the type of data to expect.\r
+ Data - A pointer to the data being sent to the original exporting driver.\r
+ Packet - A pointer to a packet of information which a driver passes back to the browser.\r
+\r
+Returns:\r
+ EFI_SUCCESS - Callback ended successfully.\r
+ Others - Contain some errors.\r
+ \r
+--*/\r
+{\r
+ BMM_CALLBACK_DATA *Private;\r
+ FILE_EXPLORER_NV_DATA *NvRamMap;\r
+ EFI_STATUS Status;\r
+\r
+ Status = EFI_SUCCESS;\r
+ Private = FE_CALLBACK_DATA_FROM_THIS (This);\r
+ UpdateData->FormCallbackHandle = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->FeCallbackHandle;\r
+ NvRamMap = (FILE_EXPLORER_NV_DATA *) Data->NvRamMap;\r
+\r
+ if (KEY_VALUE_SAVE_AND_EXIT == KeyValue) {\r
+ //\r
+ // Apply changes and exit formset.\r
+ //\r
+ if (ADD_BOOT_OPTION_STATE == Private->FeCurrentState) {\r
+ Status = Var_UpdateBootOption (Private, NvRamMap);\r
+ if (EFI_ERROR (Status)) {\r
+ return Status;\r
+ }\r
+\r
+ BOpt_GetBootOptions (Private);\r
+ CreateMenuStringToken (Private, Private->FeHiiHandle, &BootOptionMenu);\r
+ } else if (ADD_DRIVER_OPTION_STATE == Private->FeCurrentState) {\r
+ Status = Var_UpdateDriverOption (\r
+ Private,\r
+ Private->FeHiiHandle,\r
+ NvRamMap->DescriptionData,\r
+ NvRamMap->OptionalData,\r
+ NvRamMap->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
+ CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);\r
+ } else if (KEY_VALUE_NO_SAVE_AND_EXIT == KeyValue) {\r
+ //\r
+ // Discard changes and exit formset.\r
+ //\r
+ NvRamMap->OptionalData[0] = 0x0000;\r
+ NvRamMap->DescriptionData[0] = 0x0000;\r
+ CreateCallbackPacket (Packet, EXIT_REQUIRED | NV_NOT_CHANGED);\r
+ } else if (KeyValue < FILE_OPTION_OFFSET) {\r
+ //\r
+ // Exit File Explorer formset.\r
+ //\r
+ CreateCallbackPacket (Packet, EXIT_REQUIRED);\r
+ } else {\r
+ if (UpdateFileExplorer (Private, KeyValue)) {\r
+ CreateCallbackPacket (Packet, EXIT_REQUIRED);\r
+ }\r
+ }\r
+\r
+ return Status;\r
+}\r