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