git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2368 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			340 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			340 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /*++
 | |
| 
 | |
| 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;
 | |
| }
 |