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