git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2368 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1316 lines
		
	
	
		
			38 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1316 lines
		
	
	
		
			38 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:
 | 
						|
 | 
						|
  BootMaint.c
 | 
						|
    
 | 
						|
Abstract:
 | 
						|
 | 
						|
  Boot Maintainence Main File
 | 
						|
 | 
						|
--*/
 | 
						|
 | 
						|
#include "Bds.h"
 | 
						|
#include "BootMaint.h"
 | 
						|
#include "FormGuid.h"
 | 
						|
 | 
						|
//
 | 
						|
// Form binary for Boot Maintenance
 | 
						|
//
 | 
						|
extern UINT8    BmBin[];
 | 
						|
extern UINT8    FEBin[];
 | 
						|
extern EFI_GUID gBdsStringPackGuid;
 | 
						|
extern BOOLEAN  gConnectAllHappened;
 | 
						|
 | 
						|
EFI_GUID        EfiLegacyDevOrderGuid = EFI_LEGACY_DEV_ORDER_VARIABLE_GUID;
 | 
						|
 | 
						|
VOID
 | 
						|
InitAllMenu (
 | 
						|
  IN  BMM_CALLBACK_DATA    *CallbackData
 | 
						|
  );
 | 
						|
 | 
						|
VOID
 | 
						|
FreeAllMenu (
 | 
						|
  VOID
 | 
						|
  );
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
CreateMenuStringToken (
 | 
						|
  IN BMM_CALLBACK_DATA                *CallbackData,
 | 
						|
  IN EFI_HII_HANDLE                   HiiHandle,
 | 
						|
  IN BM_MENU_OPTION                   *MenuOption
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Create string tokens for a menu from its help strings and display strings
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  HiiHandle       - Hii Handle of the package to be updated.
 | 
						|
  
 | 
						|
  MenuOption      - The Menu whose string tokens need to be created
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS     - string tokens created successfully
 | 
						|
  
 | 
						|
  others          - contain some errors
 | 
						|
  
 | 
						|
--*/
 | 
						|
{
 | 
						|
  BM_MENU_ENTRY *NewMenuEntry;
 | 
						|
  UINTN         Index;
 | 
						|
 | 
						|
  for (Index = 0; Index < MenuOption->MenuNumber; Index++) {
 | 
						|
    NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);
 | 
						|
    CallbackData->Hii->NewString (
 | 
						|
                        CallbackData->Hii,
 | 
						|
                        NULL,
 | 
						|
                        HiiHandle,
 | 
						|
                        &NewMenuEntry->DisplayStringToken,
 | 
						|
                        NewMenuEntry->DisplayString
 | 
						|
                        );
 | 
						|
 | 
						|
    if (NULL == NewMenuEntry->HelpString) {
 | 
						|
      NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;
 | 
						|
    } else {
 | 
						|
      CallbackData->Hii->NewString (
 | 
						|
                          CallbackData->Hii,
 | 
						|
                          NULL,
 | 
						|
                          HiiHandle,
 | 
						|
                          &NewMenuEntry->HelpStringToken,
 | 
						|
                          NewMenuEntry->HelpString
 | 
						|
                          );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
DriverCallback (
 | 
						|
  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 boot maintenance utility user interface 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;
 | 
						|
  BM_MENU_ENTRY     *NewMenuEntry;
 | 
						|
  BMM_FAKE_NV_DATA  *CurrentFakeNVMap;
 | 
						|
  EFI_STATUS        Status;
 | 
						|
  UINTN             OldValue;
 | 
						|
  UINTN             NewValue;
 | 
						|
  UINTN             Number;
 | 
						|
  UINTN             Pos;
 | 
						|
  UINTN             Bit;
 | 
						|
  UINT16            NewValuePos;
 | 
						|
  UINT16            Index2;
 | 
						|
  UINT16            Index;
 | 
						|
  UINT8             *OldLegacyDev;
 | 
						|
  UINT8             *NewLegacyDev;
 | 
						|
  UINT8             *Location;
 | 
						|
  UINT8             *DisMap;
 | 
						|
  FORM_ID           FormId;
 | 
						|
 | 
						|
  OldValue                        = 0;
 | 
						|
  NewValue                        = 0;
 | 
						|
  Number                          = 0;
 | 
						|
  OldLegacyDev                    = NULL;
 | 
						|
  NewLegacyDev                    = NULL;
 | 
						|
  NewValuePos                     = 0;
 | 
						|
  DisMap                          = NULL;
 | 
						|
 | 
						|
  Private                         = BMM_CALLBACK_DATA_FROM_THIS (This);
 | 
						|
  UpdateData->FormCallbackHandle  = (EFI_PHYSICAL_ADDRESS) (UINTN) Private->BmmCallbackHandle;
 | 
						|
  CurrentFakeNVMap                = (BMM_FAKE_NV_DATA *) Data->NvRamMap;
 | 
						|
  Private->BmmFakeNvData          = CurrentFakeNVMap;
 | 
						|
  Location                        = (UINT8 *) &UpdateData->Data;
 | 
						|
 | 
						|
  UpdatePageId (Private, KeyValue);
 | 
						|
 | 
						|
  //
 | 
						|
  // need to be subtituded.
 | 
						|
  //
 | 
						|
  // Update Select FD/HD/CD/NET/BEV Order Form
 | 
						|
  //
 | 
						|
  if (FORM_SET_FD_ORDER_ID == Private->BmmPreviousPageId ||
 | 
						|
      FORM_SET_HD_ORDER_ID == Private->BmmPreviousPageId ||
 | 
						|
      FORM_SET_CD_ORDER_ID == Private->BmmPreviousPageId ||
 | 
						|
      FORM_SET_NET_ORDER_ID == Private->BmmPreviousPageId ||
 | 
						|
      FORM_SET_BEV_ORDER_ID == Private->BmmPreviousPageId ||
 | 
						|
      ((FORM_BOOT_SETUP_ID == Private->BmmPreviousPageId) &&
 | 
						|
      (KeyValue >= LEGACY_FD_QUESTION_ID) &&
 | 
						|
       (KeyValue < (LEGACY_BEV_QUESTION_ID + 100)) )
 | 
						|
      ) {
 | 
						|
 | 
						|
    DisMap  = Private->BmmOldFakeNVData.DisableMap;
 | 
						|
 | 
						|
    FormId  = Private->BmmPreviousPageId;
 | 
						|
    if (FormId == FORM_BOOT_SETUP_ID) {
 | 
						|
      FormId = Private->BmmCurrentPageId;
 | 
						|
    }
 | 
						|
 | 
						|
    switch (FormId) {
 | 
						|
    case FORM_SET_FD_ORDER_ID:
 | 
						|
      Number        = (UINT16) LegacyFDMenu.MenuNumber;
 | 
						|
      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyFD;
 | 
						|
      NewLegacyDev  = CurrentFakeNVMap->LegacyFD;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FORM_SET_HD_ORDER_ID:
 | 
						|
      Number        = (UINT16) LegacyHDMenu.MenuNumber;
 | 
						|
      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyHD;
 | 
						|
      NewLegacyDev  = CurrentFakeNVMap->LegacyHD;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FORM_SET_CD_ORDER_ID:
 | 
						|
      Number        = (UINT16) LegacyCDMenu.MenuNumber;
 | 
						|
      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyCD;
 | 
						|
      NewLegacyDev  = CurrentFakeNVMap->LegacyCD;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FORM_SET_NET_ORDER_ID:
 | 
						|
      Number        = (UINT16) LegacyNETMenu.MenuNumber;
 | 
						|
      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyNET;
 | 
						|
      NewLegacyDev  = CurrentFakeNVMap->LegacyNET;
 | 
						|
      break;
 | 
						|
 | 
						|
    case FORM_SET_BEV_ORDER_ID:
 | 
						|
      Number        = (UINT16) LegacyBEVMenu.MenuNumber;
 | 
						|
      OldLegacyDev  = Private->BmmOldFakeNVData.LegacyBEV;
 | 
						|
      NewLegacyDev  = CurrentFakeNVMap->LegacyBEV;
 | 
						|
      break;
 | 
						|
 | 
						|
    default:
 | 
						|
      break;
 | 
						|
    }
 | 
						|
    //
 | 
						|
    //  First, find the different position
 | 
						|
    //  if there is change, it should be only one
 | 
						|
    //
 | 
						|
    for (Index = 0; Index < Number; Index++) {
 | 
						|
      if (OldLegacyDev[Index] != NewLegacyDev[Index]) {
 | 
						|
        OldValue  = OldLegacyDev[Index];
 | 
						|
        NewValue  = NewLegacyDev[Index];
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    }
 | 
						|
 | 
						|
    if (Index != Number) {
 | 
						|
      //
 | 
						|
      // there is change, now process
 | 
						|
      //
 | 
						|
      if (0xFF == NewValue) {
 | 
						|
        //
 | 
						|
        // This item will be disable
 | 
						|
        // Just move the items behind this forward to overlap it
 | 
						|
        //
 | 
						|
        Pos = OldValue / 8;
 | 
						|
        Bit = 7 - (OldValue % 8);
 | 
						|
        DisMap[Pos] |= (UINT8) (1 << Bit);
 | 
						|
        for (Index2 = Index; Index2 < Number - 1; Index2++) {
 | 
						|
          NewLegacyDev[Index2] = NewLegacyDev[Index2 + 1];
 | 
						|
        }
 | 
						|
 | 
						|
        NewLegacyDev[Index2] = 0xFF;
 | 
						|
      } else {
 | 
						|
        for (Index2 = 0; Index2 < Number; Index2++) {
 | 
						|
          if (Index2 == Index) {
 | 
						|
            continue;
 | 
						|
          }
 | 
						|
 | 
						|
          if (OldLegacyDev[Index2] == NewValue) {
 | 
						|
            //
 | 
						|
            // If NewValue is in OldLegacyDev array
 | 
						|
            // remember its old position
 | 
						|
            //
 | 
						|
            NewValuePos = Index2;
 | 
						|
            break;
 | 
						|
          }
 | 
						|
        }
 | 
						|
 | 
						|
        if (Index2 != Number) {
 | 
						|
          //
 | 
						|
          // We will change current item to an existing item
 | 
						|
          // (It's hard to describe here, please read code, it's like a cycle-moving)
 | 
						|
          //
 | 
						|
          for (Index2 = NewValuePos; Index2 != Index;) {
 | 
						|
            if (NewValuePos < Index) {
 | 
						|
              NewLegacyDev[Index2] = OldLegacyDev[Index2 + 1];
 | 
						|
              Index2++;
 | 
						|
            } else {
 | 
						|
              NewLegacyDev[Index2] = OldLegacyDev[Index2 - 1];
 | 
						|
              Index2--;
 | 
						|
            }
 | 
						|
          }
 | 
						|
        } else {
 | 
						|
          //
 | 
						|
          // If NewValue is not in OldlegacyDev array, we are changing to a disabled item
 | 
						|
          // so we should modify DisMap to reflect the change
 | 
						|
          //
 | 
						|
          Pos = NewValue / 8;
 | 
						|
          Bit = 7 - (NewValue % 8);
 | 
						|
          DisMap[Pos] &= ~ (UINT8) (1 << Bit);
 | 
						|
          if (0xFF != OldValue) {
 | 
						|
            //
 | 
						|
            // Because NewValue is a item that was disabled before
 | 
						|
            // so after changing the OldValue should be disabled
 | 
						|
            // actually we are doing a swap of enable-disable states of two items
 | 
						|
            //
 | 
						|
            Pos = OldValue / 8;
 | 
						|
            Bit = 7 - (OldValue % 8);
 | 
						|
            DisMap[Pos] |= (UINT8) (1 << Bit);
 | 
						|
          }
 | 
						|
        }
 | 
						|
      }
 | 
						|
      //
 | 
						|
      // To prevent DISABLE appears in the middle of the list
 | 
						|
      // we should perform a re-ordering
 | 
						|
      //
 | 
						|
      Index = 0;
 | 
						|
      while (Index < Number) {
 | 
						|
        if (0xFF != NewLegacyDev[Index]) {
 | 
						|
          Index++;
 | 
						|
          continue;
 | 
						|
        }
 | 
						|
 | 
						|
        Index2 = Index;
 | 
						|
        Index2++;
 | 
						|
        while (Index2 < Number) {
 | 
						|
          if (0xFF != NewLegacyDev[Index2]) {
 | 
						|
            break;
 | 
						|
          }
 | 
						|
 | 
						|
          Index2++;
 | 
						|
        }
 | 
						|
 | 
						|
        if (Index2 < Number) {
 | 
						|
          NewLegacyDev[Index]   = NewLegacyDev[Index2];
 | 
						|
          NewLegacyDev[Index2]  = 0xFF;
 | 
						|
        }
 | 
						|
 | 
						|
        Index++;
 | 
						|
      }
 | 
						|
 | 
						|
      CopyMem (
 | 
						|
        OldLegacyDev,
 | 
						|
        NewLegacyDev,
 | 
						|
        Number
 | 
						|
        );
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  if (KeyValue < FILE_OPTION_OFFSET) {
 | 
						|
    if (KeyValue < NORMAL_GOTO_OFFSET) {
 | 
						|
      switch (KeyValue) {
 | 
						|
      case KEY_VALUE_BOOT_FROM_FILE:
 | 
						|
        Private->FeCurrentState = BOOT_FROM_FILE_STATE;
 | 
						|
 | 
						|
        //
 | 
						|
        // Exit Bmm main formset to send File Explorer formset.
 | 
						|
        //
 | 
						|
        CreateCallbackPacket (Packet, EXIT_REQUIRED);
 | 
						|
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_BOOT_ADD_ID:
 | 
						|
        Private->FeCurrentState = ADD_BOOT_OPTION_STATE;
 | 
						|
 | 
						|
        //
 | 
						|
        // Exit Bmm main formset to send File Explorer formset.
 | 
						|
        //
 | 
						|
        CreateCallbackPacket (Packet, EXIT_REQUIRED);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_DRV_ADD_FILE_ID:
 | 
						|
        Private->FeCurrentState = ADD_DRIVER_OPTION_STATE;
 | 
						|
 | 
						|
        //
 | 
						|
        // Exit Bmm main formset to send File Explorer formset.
 | 
						|
        //
 | 
						|
        CreateCallbackPacket (Packet, EXIT_REQUIRED);
 | 
						|
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_DRV_ADD_HANDLE_ID:
 | 
						|
        CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
 | 
						|
        UpdateDrvAddHandlePage (Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_BOOT_DEL_ID:
 | 
						|
        CleanUpPage (FORM_BOOT_DEL_ID, Private);
 | 
						|
        UpdateBootDelPage (Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_BOOT_CHG_ID:
 | 
						|
      case FORM_DRV_CHG_ID:
 | 
						|
        UpdatePageBody (KeyValue, Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_DRV_DEL_ID:
 | 
						|
        CleanUpPage (FORM_DRV_DEL_ID, Private);
 | 
						|
        UpdateDrvDelPage (Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_BOOT_NEXT_ID:
 | 
						|
        CleanUpPage (FORM_BOOT_NEXT_ID, Private);
 | 
						|
        UpdateBootNextPage (Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_TIME_OUT_ID:
 | 
						|
        CleanUpPage (FORM_TIME_OUT_ID, Private);
 | 
						|
        UpdateTimeOutPage (Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_RESET:
 | 
						|
        gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
 | 
						|
        return EFI_UNSUPPORTED;
 | 
						|
 | 
						|
      case FORM_CON_IN_ID:
 | 
						|
      case FORM_CON_OUT_ID:
 | 
						|
      case FORM_CON_ERR_ID:
 | 
						|
        UpdatePageBody (KeyValue, Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_CON_COM_ID:
 | 
						|
        CleanUpPage (FORM_CON_COM_ID, Private);
 | 
						|
        UpdateConCOMPage (Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case FORM_SET_FD_ORDER_ID:
 | 
						|
      case FORM_SET_HD_ORDER_ID:
 | 
						|
      case FORM_SET_CD_ORDER_ID:
 | 
						|
      case FORM_SET_NET_ORDER_ID:
 | 
						|
      case FORM_SET_BEV_ORDER_ID:
 | 
						|
        CleanUpPage (KeyValue, Private);
 | 
						|
        UpdateSetLegacyDeviceOrderPage (KeyValue, Private);
 | 
						|
        break;
 | 
						|
 | 
						|
      case KEY_VALUE_SAVE_AND_EXIT:
 | 
						|
      case KEY_VALUE_NO_SAVE_AND_EXIT:
 | 
						|
 | 
						|
        if (KeyValue == KEY_VALUE_SAVE_AND_EXIT) {
 | 
						|
          Status = ApplyChangeHandler (Private, CurrentFakeNVMap, Private->BmmPreviousPageId);
 | 
						|
          if (EFI_ERROR (Status)) {
 | 
						|
            return Status;
 | 
						|
          }
 | 
						|
        } else if (KeyValue == KEY_VALUE_NO_SAVE_AND_EXIT) {
 | 
						|
          DiscardChangeHandler (Private, CurrentFakeNVMap);
 | 
						|
        }
 | 
						|
        //
 | 
						|
        // Tell browser not to ask for confirmation of changes,
 | 
						|
        // since we have already applied or discarded.
 | 
						|
        //
 | 
						|
        CreateCallbackPacket (Packet, NV_NOT_CHANGED);
 | 
						|
        break;
 | 
						|
 | 
						|
      default:
 | 
						|
        break;
 | 
						|
      }
 | 
						|
    } else if ((KeyValue >= TERMINAL_OPTION_OFFSET) && (KeyValue < CONSOLE_OPTION_OFFSET)) {
 | 
						|
      Index2                    = (UINT16) (KeyValue - TERMINAL_OPTION_OFFSET);
 | 
						|
      Private->CurrentTerminal  = Index2;
 | 
						|
 | 
						|
      CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
 | 
						|
      UpdateTerminalPage (Private);
 | 
						|
 | 
						|
    } else if (KeyValue >= HANDLE_OPTION_OFFSET) {
 | 
						|
      Index2                  = (UINT16) (KeyValue - HANDLE_OPTION_OFFSET);
 | 
						|
 | 
						|
      NewMenuEntry            = BOpt_GetMenuEntry (&DriverMenu, Index2);
 | 
						|
      Private->HandleContext  = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
 | 
						|
      CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
 | 
						|
 | 
						|
      Private->MenuEntry                  = NewMenuEntry;
 | 
						|
      Private->LoadContext->FilePathList  = Private->HandleContext->DevicePath;
 | 
						|
 | 
						|
      UpdateDriverAddHandleDescPage (Private);
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
ApplyChangeHandler (
 | 
						|
  IN  BMM_CALLBACK_DATA               *Private,
 | 
						|
  IN  BMM_FAKE_NV_DATA                *CurrentFakeNVMap,
 | 
						|
  IN  FORM_ID                         FormId
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Function handling request to apply changes for BMM pages.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  Private          - Pointer to callback data buffer.
 | 
						|
  CurrentFakeNVMap - Pointer to buffer holding data of various values used by BMM
 | 
						|
  FormId           - ID of the form which has sent the request to apply change.
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS      - Change successfully applied.
 | 
						|
  Other            - Error occurs while trying to apply changes.
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  BM_CONSOLE_CONTEXT  *NewConsoleContext;
 | 
						|
  BM_TERMINAL_CONTEXT *NewTerminalContext;
 | 
						|
  BM_LOAD_CONTEXT     *NewLoadContext;
 | 
						|
  BM_MENU_ENTRY       *NewMenuEntry;
 | 
						|
  EFI_STATUS          Status;
 | 
						|
  UINT16              Index;
 | 
						|
 | 
						|
  Status = EFI_SUCCESS;
 | 
						|
 | 
						|
  switch (FormId) {
 | 
						|
  case FORM_SET_FD_ORDER_ID:
 | 
						|
  case FORM_SET_HD_ORDER_ID:
 | 
						|
  case FORM_SET_CD_ORDER_ID:
 | 
						|
  case FORM_SET_NET_ORDER_ID:
 | 
						|
  case FORM_SET_BEV_ORDER_ID:
 | 
						|
    Var_UpdateBBSOption (Private);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_BOOT_DEL_ID:
 | 
						|
    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry            = BOpt_GetMenuEntry (&BootOptionMenu, Index);
 | 
						|
      NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewLoadContext->Deleted = CurrentFakeNVMap->BootOptionDel[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    Var_DelBootOption ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_DRV_DEL_ID:
 | 
						|
    for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry            = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
 | 
						|
      NewLoadContext          = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewLoadContext->Deleted = CurrentFakeNVMap->DriverOptionDel[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    Var_DelDriverOption ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_BOOT_CHG_ID:
 | 
						|
    Status = Var_UpdateBootOrder (Private);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_DRV_CHG_ID:
 | 
						|
    Status = Var_UpdateDriverOrder (Private);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_TIME_OUT_ID:
 | 
						|
    Status = gRT->SetVariable (
 | 
						|
                    L"Timeout",
 | 
						|
                    &gEfiGlobalVariableGuid,
 | 
						|
                    VAR_FLAG,
 | 
						|
                    sizeof (UINT16),
 | 
						|
                    &(CurrentFakeNVMap->BootTimeOut)
 | 
						|
                    );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      goto Error;
 | 
						|
    }
 | 
						|
 | 
						|
    Private->BmmOldFakeNVData.BootTimeOut = CurrentFakeNVMap->BootTimeOut;
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_BOOT_NEXT_ID:
 | 
						|
    Status = Var_UpdateBootNext (Private);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_CON_COM_ID:
 | 
						|
    NewMenuEntry                      = BOpt_GetMenuEntry (&TerminalMenu, Private->CurrentTerminal);
 | 
						|
 | 
						|
    NewTerminalContext                = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
 | 
						|
    NewTerminalContext->BaudRateIndex = CurrentFakeNVMap->COMBaudRate;
 | 
						|
    NewTerminalContext->BaudRate      = BaudRateList[CurrentFakeNVMap->COMBaudRate].Value;
 | 
						|
    NewTerminalContext->DataBitsIndex = CurrentFakeNVMap->COMDataRate;
 | 
						|
    NewTerminalContext->DataBits      = (UINT8) DataBitsList[CurrentFakeNVMap->COMDataRate].Value;
 | 
						|
    NewTerminalContext->StopBitsIndex = CurrentFakeNVMap->COMStopBits;
 | 
						|
    NewTerminalContext->StopBits      = (UINT8) StopBitsList[CurrentFakeNVMap->COMStopBits].Value;
 | 
						|
    NewTerminalContext->ParityIndex   = CurrentFakeNVMap->COMParity;
 | 
						|
    NewTerminalContext->Parity        = (UINT8) ParityList[CurrentFakeNVMap->COMParity].Value;
 | 
						|
    NewTerminalContext->TerminalType  = CurrentFakeNVMap->COMTerminalType;
 | 
						|
 | 
						|
    ChangeTerminalDevicePath (
 | 
						|
      NewTerminalContext->DevicePath,
 | 
						|
      FALSE
 | 
						|
      );
 | 
						|
 | 
						|
    Var_UpdateConsoleInpOption ();
 | 
						|
    Var_UpdateConsoleOutOption ();
 | 
						|
    Var_UpdateErrorOutOption ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_CON_IN_ID:
 | 
						|
    for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleInpMenu, Index);
 | 
						|
      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry                = BOpt_GetMenuEntry (&TerminalMenu, Index);
 | 
						|
      NewTerminalContext          = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewTerminalContext->IsConIn = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleInpMenu.MenuNumber];
 | 
						|
    }
 | 
						|
 | 
						|
    Var_UpdateConsoleInpOption ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_CON_OUT_ID:
 | 
						|
    for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleOutMenu, Index);
 | 
						|
      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry                  = BOpt_GetMenuEntry (&TerminalMenu, Index);
 | 
						|
      NewTerminalContext            = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewTerminalContext->IsConOut  = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleOutMenu.MenuNumber];
 | 
						|
    }
 | 
						|
 | 
						|
    Var_UpdateConsoleOutOption ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_CON_ERR_ID:
 | 
						|
    for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry                = BOpt_GetMenuEntry (&ConsoleErrMenu, Index);
 | 
						|
      NewConsoleContext           = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewConsoleContext->IsActive = CurrentFakeNVMap->ConsoleCheck[Index];
 | 
						|
    }
 | 
						|
 | 
						|
    for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
 | 
						|
      NewMenuEntry                  = BOpt_GetMenuEntry (&TerminalMenu, Index);
 | 
						|
      NewTerminalContext            = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
 | 
						|
      NewTerminalContext->IsStdErr  = CurrentFakeNVMap->ConsoleCheck[Index + ConsoleErrMenu.MenuNumber];
 | 
						|
    }
 | 
						|
 | 
						|
    Var_UpdateErrorOutOption ();
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_DRV_ADD_HANDLE_DESC_ID:
 | 
						|
    Status = Var_UpdateDriverOption (
 | 
						|
               Private,
 | 
						|
               Private->BmmHiiHandle,
 | 
						|
               CurrentFakeNVMap->DriverAddHandleDesc,
 | 
						|
               CurrentFakeNVMap->DriverAddHandleOptionalData,
 | 
						|
               CurrentFakeNVMap->DriverAddForceReconnect
 | 
						|
               );
 | 
						|
    if (EFI_ERROR (Status)) {
 | 
						|
      goto Error;
 | 
						|
    }
 | 
						|
 | 
						|
    BOpt_GetDriverOptions (Private);
 | 
						|
    CreateMenuStringToken (Private, Private->BmmHiiHandle, &DriverOptionMenu);
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
 | 
						|
Error:
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
DiscardChangeHandler (
 | 
						|
  IN  BMM_CALLBACK_DATA               *Private,
 | 
						|
  IN  BMM_FAKE_NV_DATA                *CurrentFakeNVMap
 | 
						|
  )
 | 
						|
{
 | 
						|
  UINT16  Index;
 | 
						|
 | 
						|
  switch (Private->BmmPreviousPageId) {
 | 
						|
  case FORM_BOOT_CHG_ID:
 | 
						|
  case FORM_DRV_CHG_ID:
 | 
						|
    CopyMem (CurrentFakeNVMap->OptionOrder, Private->BmmOldFakeNVData.OptionOrder, 100);
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_BOOT_DEL_ID:
 | 
						|
    for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
 | 
						|
      CurrentFakeNVMap->BootOptionDel[Index] = 0x00;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_DRV_DEL_ID:
 | 
						|
    for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
 | 
						|
      CurrentFakeNVMap->DriverOptionDel[Index] = 0x00;
 | 
						|
    }
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_BOOT_NEXT_ID:
 | 
						|
    CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_TIME_OUT_ID:
 | 
						|
    CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
 | 
						|
    break;
 | 
						|
 | 
						|
  case FORM_DRV_ADD_HANDLE_DESC_ID:
 | 
						|
  case FORM_DRV_ADD_FILE_ID:
 | 
						|
  case FORM_DRV_ADD_HANDLE_ID:
 | 
						|
    CurrentFakeNVMap->DriverAddHandleDesc[0]          = 0x0000;
 | 
						|
    CurrentFakeNVMap->DriverAddHandleOptionalData[0]  = 0x0000;
 | 
						|
    break;
 | 
						|
 | 
						|
  default:
 | 
						|
    break;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
EFIAPI
 | 
						|
NvWrite (
 | 
						|
  IN     EFI_FORM_CALLBACK_PROTOCOL              *This,
 | 
						|
  IN     CHAR16                                  *VariableName,
 | 
						|
  IN     EFI_GUID                                *VendorGuid,
 | 
						|
  OUT    UINT32                                  Attributes OPTIONAL,
 | 
						|
  IN OUT UINTN                                   DataSize,
 | 
						|
  OUT    VOID                                    *Buffer,
 | 
						|
  OUT    BOOLEAN                                 *ResetRequired
 | 
						|
  )
 | 
						|
{
 | 
						|
  //
 | 
						|
  // Do nothing here. Just to catch the F10, we use "Apply Changes" tag to save.
 | 
						|
  //
 | 
						|
  return EFI_SUCCESS;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
InitializeBM (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
 | 
						|
  Initialize the Boot Maintenance Utitliy
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
  ImageHandle     - caller provided handle
 | 
						|
  
 | 
						|
  SystemTable     - caller provided system tables
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
  EFI_SUCCESS     - utility ended successfully
 | 
						|
  
 | 
						|
  others          - contain some errors
 | 
						|
  
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_LEGACY_BIOS_PROTOCOL  *LegacyBios;
 | 
						|
  EFI_HII_PACKAGES          *PackageList;
 | 
						|
  BMM_CALLBACK_DATA         *BmmCallbackInfo;
 | 
						|
  EFI_HII_PROTOCOL          *Hii;
 | 
						|
  EFI_HII_HANDLE            HiiHandle;
 | 
						|
  EFI_STATUS                Status;
 | 
						|
  EFI_HANDLE                Handle;
 | 
						|
  UINT8                     *Ptr;
 | 
						|
  UINT8                     *Location;
 | 
						|
 | 
						|
  Status      = EFI_SUCCESS;
 | 
						|
  UpdateData  = NULL;
 | 
						|
  //
 | 
						|
  // Initialize EfiUtilityLib and EfiDriverLib
 | 
						|
  // Since many functions in UtilityLib must be used and
 | 
						|
  // SetupBrowser use DriverLib
 | 
						|
  //
 | 
						|
  //
 | 
						|
  // There should be only one EFI_HII_PROTOCOL Image
 | 
						|
  //
 | 
						|
  Status = EfiLibLocateProtocol (&gEfiHiiProtocolGuid, (VOID**)&Hii);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Create CallbackData structures for Driver Callback
 | 
						|
  //
 | 
						|
  BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));
 | 
						|
  if (!BmmCallbackInfo) {
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Create LoadOption in BmmCallbackInfo for Driver Callback
 | 
						|
  //
 | 
						|
  Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
 | 
						|
  if (!Ptr) {
 | 
						|
    SafeFreePool (BmmCallbackInfo);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Initialize Bmm callback data.
 | 
						|
  //
 | 
						|
  BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
 | 
						|
  Ptr += sizeof (BM_LOAD_CONTEXT);
 | 
						|
 | 
						|
  BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
 | 
						|
  Ptr += sizeof (BM_FILE_CONTEXT);
 | 
						|
 | 
						|
  BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
 | 
						|
  Ptr += sizeof (BM_HANDLE_CONTEXT);
 | 
						|
 | 
						|
  BmmCallbackInfo->MenuEntry      = (BM_MENU_ENTRY *) Ptr;
 | 
						|
 | 
						|
  BmmCallbackInfo->BmmFakeNvData  = &BmmCallbackInfo->BmmOldFakeNVData;
 | 
						|
 | 
						|
  ZeroMem (BmmCallbackInfo->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));
 | 
						|
 | 
						|
  BmmCallbackInfo->Signature                  = BMM_CALLBACK_DATA_SIGNATURE;
 | 
						|
  BmmCallbackInfo->Hii                        = Hii;
 | 
						|
  BmmCallbackInfo->BmmDriverCallback.NvRead   = NULL;
 | 
						|
  BmmCallbackInfo->BmmDriverCallback.NvWrite  = NvWrite;
 | 
						|
  BmmCallbackInfo->BmmDriverCallback.Callback = DriverCallback;
 | 
						|
  BmmCallbackInfo->BmmPreviousPageId          = FORM_MAIN_ID;
 | 
						|
  BmmCallbackInfo->BmmCurrentPageId           = FORM_MAIN_ID;
 | 
						|
  BmmCallbackInfo->FeDriverCallback.NvRead    = NULL;
 | 
						|
  BmmCallbackInfo->FeDriverCallback.NvWrite   = NvWrite;
 | 
						|
  BmmCallbackInfo->FeDriverCallback.Callback  = FileExplorerCallback;
 | 
						|
  BmmCallbackInfo->FeCurrentState             = INACTIVE_STATE;
 | 
						|
  BmmCallbackInfo->FeDisplayContext           = UNKNOWN_CONTEXT;
 | 
						|
 | 
						|
  //
 | 
						|
  // Install bmm callback protocol interface
 | 
						|
  //
 | 
						|
  Handle = NULL;
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &Handle,
 | 
						|
                  &gEfiFormCallbackProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &BmmCallbackInfo->BmmDriverCallback
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  BmmCallbackInfo->BmmCallbackHandle = Handle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Install file explorer callback protocol interface
 | 
						|
  //
 | 
						|
  Handle = NULL;
 | 
						|
  Status = gBS->InstallProtocolInterface (
 | 
						|
                  &Handle,
 | 
						|
                  &gEfiFormCallbackProtocolGuid,
 | 
						|
                  EFI_NATIVE_INTERFACE,
 | 
						|
                  &BmmCallbackInfo->FeDriverCallback
 | 
						|
                  );
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  BmmCallbackInfo->FeCallbackHandle = Handle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Post our VFR to the HII database.
 | 
						|
  //
 | 
						|
  PackageList = PreparePackages (1, &gBdsStringPackGuid, BmBin);
 | 
						|
  Status      = Hii->NewPack (Hii, PackageList, &HiiHandle);
 | 
						|
  gBS->FreePool (PackageList);
 | 
						|
 | 
						|
  BmmCallbackInfo->BmmHiiHandle = HiiHandle;
 | 
						|
 | 
						|
  PackageList                   = PreparePackages (1, &gBdsStringPackGuid, FEBin);
 | 
						|
  Status                        = Hii->NewPack (Hii, PackageList, &HiiHandle);
 | 
						|
  gBS->FreePool (PackageList);
 | 
						|
 | 
						|
  BmmCallbackInfo->FeHiiHandle = HiiHandle;
 | 
						|
 | 
						|
  //
 | 
						|
  // Allocate space for creation of Buffer
 | 
						|
  //
 | 
						|
  UpdateData = AllocateZeroPool (UPDATE_DATA_SIZE);
 | 
						|
  if (!UpdateData) {
 | 
						|
    SafeFreePool (BmmCallbackInfo->LoadContext);
 | 
						|
    SafeFreePool (BmmCallbackInfo);
 | 
						|
    return EFI_OUT_OF_RESOURCES;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Initialize UpdateData structure
 | 
						|
  //
 | 
						|
  RefreshUpdateData (TRUE, (EFI_PHYSICAL_ADDRESS) (UINTN) BmmCallbackInfo->BmmCallbackHandle, FALSE, 0, 0);
 | 
						|
 | 
						|
  Location = (UINT8 *) &UpdateData->Data;
 | 
						|
 | 
						|
  InitializeStringDepository ();
 | 
						|
 | 
						|
  InitAllMenu (BmmCallbackInfo);
 | 
						|
 | 
						|
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);
 | 
						|
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);
 | 
						|
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);
 | 
						|
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);
 | 
						|
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);
 | 
						|
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);
 | 
						|
  CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);
 | 
						|
 | 
						|
  UpdateBootDelPage (BmmCallbackInfo);
 | 
						|
  UpdateDrvDelPage (BmmCallbackInfo);
 | 
						|
 | 
						|
  if (TerminalMenu.MenuNumber > 0) {
 | 
						|
    BmmCallbackInfo->CurrentTerminal = 0;
 | 
						|
    UpdateTerminalPage (BmmCallbackInfo);
 | 
						|
  }
 | 
						|
 | 
						|
  Location  = (UINT8 *) &UpdateData->Data;
 | 
						|
  Status    = EfiLibLocateProtocol (&gEfiLegacyBiosProtocolGuid, (VOID**) &LegacyBios);
 | 
						|
  if (!EFI_ERROR (Status)) {
 | 
						|
    //
 | 
						|
    // If LegacyBios Protocol is installed, add 3 tags about legacy boot option
 | 
						|
    // in BootOption form: legacy FD/HD/CD/NET/BEV
 | 
						|
    //
 | 
						|
    UpdateData->DataCount = 5;
 | 
						|
    CreateGotoOpCode (
 | 
						|
      FORM_SET_FD_ORDER_ID,
 | 
						|
      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
 | 
						|
      STRING_TOKEN (STR_FORM_SET_FD_ORDER_TITLE),
 | 
						|
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
 | 
						|
      FORM_SET_FD_ORDER_ID,
 | 
						|
      Location
 | 
						|
      );
 | 
						|
 | 
						|
    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
 | 
						|
 | 
						|
    CreateGotoOpCode (
 | 
						|
      FORM_SET_HD_ORDER_ID,
 | 
						|
      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
 | 
						|
      STRING_TOKEN (STR_FORM_SET_HD_ORDER_TITLE),
 | 
						|
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
 | 
						|
      FORM_SET_HD_ORDER_ID,
 | 
						|
      Location
 | 
						|
      );
 | 
						|
 | 
						|
    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
 | 
						|
 | 
						|
    CreateGotoOpCode (
 | 
						|
      FORM_SET_CD_ORDER_ID,
 | 
						|
      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
 | 
						|
      STRING_TOKEN (STR_FORM_SET_CD_ORDER_TITLE),
 | 
						|
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
 | 
						|
      FORM_SET_CD_ORDER_ID,
 | 
						|
      Location
 | 
						|
      );
 | 
						|
 | 
						|
    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
 | 
						|
 | 
						|
    CreateGotoOpCode (
 | 
						|
      FORM_SET_NET_ORDER_ID,
 | 
						|
      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
 | 
						|
      STRING_TOKEN (STR_FORM_SET_NET_ORDER_TITLE),
 | 
						|
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
 | 
						|
      FORM_SET_NET_ORDER_ID,
 | 
						|
      Location
 | 
						|
      );
 | 
						|
 | 
						|
    Location = Location + ((EFI_IFR_OP_HEADER *) Location)->Length;
 | 
						|
 | 
						|
    CreateGotoOpCode (
 | 
						|
      FORM_SET_BEV_ORDER_ID,
 | 
						|
      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
 | 
						|
      STRING_TOKEN (STR_FORM_SET_BEV_ORDER_TITLE),
 | 
						|
      EFI_IFR_FLAG_INTERACTIVE | EFI_IFR_FLAG_NV_ACCESS,
 | 
						|
      FORM_SET_BEV_ORDER_ID,
 | 
						|
      Location
 | 
						|
      );
 | 
						|
 | 
						|
    Hii->UpdateForm (
 | 
						|
          Hii,
 | 
						|
          BmmCallbackInfo->BmmHiiHandle,
 | 
						|
          (EFI_FORM_LABEL) FORM_BOOT_LEGACY_DEVICE_ID,
 | 
						|
          TRUE,
 | 
						|
          UpdateData
 | 
						|
          );
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Dispatch BMM main formset and File Explorer formset.
 | 
						|
  //
 | 
						|
  FormSetDispatcher (BmmCallbackInfo);
 | 
						|
 | 
						|
  Hii->ResetStrings (Hii, HiiHandle);
 | 
						|
 | 
						|
  CleanUpStringDepository ();
 | 
						|
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  FreeAllMenu ();
 | 
						|
 | 
						|
  SafeFreePool (BmmCallbackInfo->LoadContext);
 | 
						|
  BmmCallbackInfo->LoadContext = NULL;
 | 
						|
  SafeFreePool (BmmCallbackInfo);
 | 
						|
  BmmCallbackInfo = NULL;
 | 
						|
  SafeFreePool (UpdateData);
 | 
						|
  UpdateData = NULL;
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
InitAllMenu (
 | 
						|
  IN  BMM_CALLBACK_DATA    *CallbackData
 | 
						|
  )
 | 
						|
{
 | 
						|
  InitializeListHead (&BootOptionMenu.Head);
 | 
						|
  InitializeListHead (&DriverOptionMenu.Head);
 | 
						|
  BOpt_GetBootOptions (CallbackData);
 | 
						|
  BOpt_GetDriverOptions (CallbackData);
 | 
						|
  BOpt_GetLegacyOptions ();
 | 
						|
  InitializeListHead (&FsOptionMenu.Head);
 | 
						|
  BOpt_FindDrivers ();
 | 
						|
  InitializeListHead (&DirectoryMenu.Head);
 | 
						|
  InitializeListHead (&ConsoleInpMenu.Head);
 | 
						|
  InitializeListHead (&ConsoleOutMenu.Head);
 | 
						|
  InitializeListHead (&ConsoleErrMenu.Head);
 | 
						|
  InitializeListHead (&TerminalMenu.Head);
 | 
						|
  LocateSerialIo ();
 | 
						|
  GetAllConsoles ();
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
FreeAllMenu (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
{
 | 
						|
  BOpt_FreeMenu (&DirectoryMenu);
 | 
						|
  BOpt_FreeMenu (&FsOptionMenu);
 | 
						|
  BOpt_FreeMenu (&BootOptionMenu);
 | 
						|
  BOpt_FreeMenu (&DriverOptionMenu);
 | 
						|
  BOpt_FreeMenu (&DriverMenu);
 | 
						|
  BOpt_FreeLegacyOptions ();
 | 
						|
  FreeAllConsoles ();
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
InitializeStringDepository (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
  Intialize all the string depositories.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  None.
 | 
						|
 | 
						|
Returns:
 | 
						|
  None.  
 | 
						|
--*/
 | 
						|
{
 | 
						|
  STRING_DEPOSITORY *StringDepository;
 | 
						|
  StringDepository              = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);
 | 
						|
  FileOptionStrDepository       = StringDepository++;
 | 
						|
  ConsoleOptionStrDepository    = StringDepository++;
 | 
						|
  BootOptionStrDepository       = StringDepository++;
 | 
						|
  BootOptionHelpStrDepository   = StringDepository++;
 | 
						|
  DriverOptionStrDepository     = StringDepository++;
 | 
						|
  DriverOptionHelpStrDepository = StringDepository++;
 | 
						|
  TerminalStrDepository         = StringDepository;
 | 
						|
}
 | 
						|
 | 
						|
STRING_REF
 | 
						|
GetStringTokenFromDepository (
 | 
						|
  IN   BMM_CALLBACK_DATA     *CallbackData,
 | 
						|
  IN   STRING_DEPOSITORY     *StringDepository
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
  Fetch a usable string node from the string depository and return the string token.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  StringDepository       - Pointer of the string depository.
 | 
						|
 | 
						|
Returns:
 | 
						|
  STRING_REF             - String token.
 | 
						|
--*/
 | 
						|
{
 | 
						|
  STRING_LIST_NODE  *CurrentListNode;
 | 
						|
  STRING_LIST_NODE  *NextListNode;
 | 
						|
 | 
						|
  CurrentListNode = StringDepository->CurrentNode;
 | 
						|
 | 
						|
  if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {
 | 
						|
    //
 | 
						|
    // Fetch one reclaimed node from the list.
 | 
						|
    //
 | 
						|
    NextListNode = StringDepository->CurrentNode->Next;
 | 
						|
  } else {
 | 
						|
    //
 | 
						|
    // If there is no usable node in the list, update the list.
 | 
						|
    //
 | 
						|
    NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));
 | 
						|
 | 
						|
    CallbackData->Hii->NewString (
 | 
						|
                        CallbackData->Hii,
 | 
						|
                        NULL,
 | 
						|
                        CallbackData->BmmHiiHandle,
 | 
						|
                        &(NextListNode->StringToken),
 | 
						|
                        L" "
 | 
						|
                        );
 | 
						|
 | 
						|
    ASSERT (NextListNode->StringToken != 0);
 | 
						|
 | 
						|
    StringDepository->TotalNodeNumber++;
 | 
						|
 | 
						|
    if (NULL == CurrentListNode) {
 | 
						|
      StringDepository->ListHead = NextListNode;
 | 
						|
    } else {
 | 
						|
      CurrentListNode->Next = NextListNode;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  StringDepository->CurrentNode = NextListNode;
 | 
						|
 | 
						|
  return StringDepository->CurrentNode->StringToken;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
ReclaimStringDepository (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
  Reclaim string depositories by moving the current node pointer to list head..
 | 
						|
 | 
						|
Arguments:
 | 
						|
  None.
 | 
						|
 | 
						|
Returns:
 | 
						|
  None.
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINTN             DepositoryIndex;
 | 
						|
  STRING_DEPOSITORY *StringDepository;
 | 
						|
 | 
						|
  StringDepository = FileOptionStrDepository;
 | 
						|
  for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
 | 
						|
    StringDepository->CurrentNode = StringDepository->ListHead;
 | 
						|
    StringDepository++;
 | 
						|
  }
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CleanUpStringDepository (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
Routine Description:
 | 
						|
  Release resource for all the string depositories.
 | 
						|
 | 
						|
Arguments:
 | 
						|
  None.
 | 
						|
 | 
						|
Returns:
 | 
						|
  None.
 | 
						|
--*/
 | 
						|
{
 | 
						|
  UINTN             NodeIndex;
 | 
						|
  UINTN             DepositoryIndex;
 | 
						|
  STRING_LIST_NODE  *CurrentListNode;
 | 
						|
  STRING_LIST_NODE  *NextListNode;
 | 
						|
  STRING_DEPOSITORY *StringDepository;
 | 
						|
 | 
						|
  //
 | 
						|
  // Release string list nodes.
 | 
						|
  //
 | 
						|
  StringDepository = FileOptionStrDepository;
 | 
						|
  for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {
 | 
						|
    CurrentListNode = StringDepository->ListHead;
 | 
						|
    for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {
 | 
						|
      NextListNode = CurrentListNode->Next;
 | 
						|
      SafeFreePool (CurrentListNode);
 | 
						|
      CurrentListNode = NextListNode;
 | 
						|
    }
 | 
						|
 | 
						|
    StringDepository++;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Release string depository.
 | 
						|
  //
 | 
						|
  SafeFreePool (FileOptionStrDepository);
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
BdsStartBootMaint (
 | 
						|
  VOID
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Start boot maintenance manager
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_STATUS  Status;
 | 
						|
  LIST_ENTRY  BdsBootOptionList;
 | 
						|
 | 
						|
  InitializeListHead (&BdsBootOptionList);
 | 
						|
 | 
						|
  //
 | 
						|
  // Connect all prior to entering the platform setup menu.
 | 
						|
  //
 | 
						|
  if (!gConnectAllHappened) {
 | 
						|
    BdsLibConnectAllDriversToAllControllers ();
 | 
						|
    gConnectAllHappened = TRUE;
 | 
						|
  }
 | 
						|
  //
 | 
						|
  // Have chance to enumerate boot device
 | 
						|
  //
 | 
						|
  BdsLibEnumerateAllBootOption (&BdsBootOptionList);
 | 
						|
 | 
						|
  //
 | 
						|
  // Init the BMM
 | 
						|
  //
 | 
						|
  Status = InitializeBM ();
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
EFI_STATUS
 | 
						|
FormSetDispatcher (
 | 
						|
  IN  BMM_CALLBACK_DATA    *CallbackData
 | 
						|
  )
 | 
						|
/*++
 | 
						|
 | 
						|
Routine Description:
 | 
						|
  Dispatch BMM formset and FileExplorer formset.
 | 
						|
 | 
						|
Arguments:
 | 
						|
 | 
						|
Returns:
 | 
						|
 | 
						|
--*/
 | 
						|
{
 | 
						|
  EFI_FORM_BROWSER_PROTOCOL *FormConfig;
 | 
						|
  UINT8                     *Location;
 | 
						|
  EFI_STATUS                Status;
 | 
						|
  UINTN                     Index;
 | 
						|
  BM_MENU_ENTRY             *NewMenuEntry;
 | 
						|
  BM_FILE_CONTEXT           *NewFileContext;
 | 
						|
  BOOLEAN	                 BootMaintMenuResetRequired;
 | 
						|
 | 
						|
  Location        = NULL;
 | 
						|
  Index           = 0;
 | 
						|
  NewMenuEntry    = NULL;
 | 
						|
  NewFileContext  = NULL;
 | 
						|
 | 
						|
  //
 | 
						|
  // There should only be one Form Configuration protocol
 | 
						|
  //
 | 
						|
  Status = EfiLibLocateProtocol (&gEfiFormBrowserProtocolGuid, (VOID**) &FormConfig);
 | 
						|
  if (EFI_ERROR (Status)) {
 | 
						|
    return Status;
 | 
						|
  }
 | 
						|
 | 
						|
  while (1) {
 | 
						|
    UpdatePageId (CallbackData, FORM_MAIN_ID);
 | 
						|
 | 
						|
    BootMaintMenuResetRequired = FALSE;
 | 
						|
    Status = FormConfig->SendForm (
 | 
						|
                          FormConfig,
 | 
						|
                          TRUE,
 | 
						|
                          &(CallbackData->BmmHiiHandle),
 | 
						|
                          1,
 | 
						|
                          NULL,
 | 
						|
                          NULL,
 | 
						|
                          (UINT8 *) CallbackData->BmmFakeNvData,
 | 
						|
                          NULL,
 | 
						|
                          &BootMaintMenuResetRequired
 | 
						|
                          );
 | 
						|
 | 
						|
    if (BootMaintMenuResetRequired) {
 | 
						|
      EnableResetRequired ();
 | 
						|
    }
 | 
						|
 | 
						|
    ReclaimStringDepository ();
 | 
						|
 | 
						|
    //
 | 
						|
    // When this Formset returns, check if we are going to explore files.
 | 
						|
    //
 | 
						|
    if (INACTIVE_STATE != CallbackData->FeCurrentState) {
 | 
						|
      UpdateFileExplorer (CallbackData, 0);
 | 
						|
 | 
						|
      BootMaintMenuResetRequired = FALSE;
 | 
						|
      Status = FormConfig->SendForm (
 | 
						|
                            FormConfig,
 | 
						|
                            TRUE,
 | 
						|
                            &(CallbackData->FeHiiHandle),
 | 
						|
                            1,
 | 
						|
                            NULL,
 | 
						|
                            NULL,
 | 
						|
                            NULL,
 | 
						|
                            NULL,
 | 
						|
                            &BootMaintMenuResetRequired
 | 
						|
                            );
 | 
						|
 | 
						|
      if (BootMaintMenuResetRequired) {
 | 
						|
        EnableResetRequired ();
 | 
						|
      }
 | 
						|
 | 
						|
      CallbackData->FeCurrentState    = INACTIVE_STATE;
 | 
						|
      CallbackData->FeDisplayContext  = UNKNOWN_CONTEXT;
 | 
						|
      ReclaimStringDepository ();
 | 
						|
    } else {
 | 
						|
      break;
 | 
						|
    }
 | 
						|
  }
 | 
						|
 | 
						|
  return Status;
 | 
						|
}
 | 
						|
 | 
						|
VOID
 | 
						|
CreateCallbackPacket (
 | 
						|
  OUT EFI_HII_CALLBACK_PACKET         **Packet,
 | 
						|
  IN  UINT16                          Flags
 | 
						|
  )
 | 
						|
{
 | 
						|
  *Packet = (EFI_HII_CALLBACK_PACKET *) AllocateZeroPool (sizeof (EFI_HII_CALLBACK_PACKET) + 2);
 | 
						|
  ASSERT (*Packet != NULL);
 | 
						|
 | 
						|
  (*Packet)->DataArray.EntryCount   = 1;
 | 
						|
  (*Packet)->DataArray.NvRamMap     = NULL;
 | 
						|
  ((EFI_IFR_DATA_ENTRY *) (&((*Packet)->DataArray) + 1))->Flags  = Flags;
 | 
						|
}
 |