mirror of
				https://git.proxmox.com/git/mirror_edk2
				synced 2025-10-31 20:43:59 +00:00 
			
		
		
		
	 52657feb15
			
		
	
	
		52657feb15
		
	
	
	
	
		
			
			git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2368 6f19259b-4bc3-4df7-8a09-765794883524
		
			
				
	
	
		
			1279 lines
		
	
	
		
			37 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			1279 lines
		
	
	
		
			37 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:
 | |
| 
 | |
|   Variable.c
 | |
| 
 | |
| Abstract:
 | |
| 
 | |
|   Variable operation that will be used by BootMaint
 | |
| 
 | |
| --*/
 | |
| 
 | |
| #include "Bds.h"
 | |
| #include "BootMaint.h"
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_DelBootOption (
 | |
|   VOID
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   Delete Boot Option that represent a Deleted state in BootOptionMenu.
 | |
|   After deleting this boot option, call Var_ChangeBootOrder to
 | |
|   make sure BootOrder is in valid state.
 | |
|   
 | |
| Arguments:
 | |
|   LoadOption -- Pointer to the boot option that to be deleted
 | |
| 
 | |
| Returns:
 | |
|   EFI_SUCCESS
 | |
|   Others
 | |
|   
 | |
| --*/
 | |
| {
 | |
|   BM_MENU_ENTRY   *NewMenuEntry;
 | |
|   BM_LOAD_CONTEXT *NewLoadContext;
 | |
| 
 | |
|   UINT16          BootString[10];
 | |
|   EFI_STATUS      Status;
 | |
|   UINTN           Index;
 | |
|   UINTN           Index2;
 | |
| 
 | |
|   Status  = EFI_SUCCESS;
 | |
|   Index2  = 0;
 | |
|   for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
 | |
|     NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));
 | |
|     if (NULL == NewMenuEntry) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
| 
 | |
|     NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|     if (!NewLoadContext->Deleted) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     UnicodeSPrint (
 | |
|       BootString,
 | |
|       sizeof (BootString),
 | |
|       L"Boot%04x",
 | |
|       NewMenuEntry->OptionNumber
 | |
|       );
 | |
| 
 | |
|     EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid);
 | |
|     Index2++;
 | |
|     //
 | |
|     // If current Load Option is the same as BootNext,
 | |
|     // must delete BootNext in order to make sure
 | |
|     // there will be no panic on next boot
 | |
|     //
 | |
|     if (NewLoadContext->IsBootNext) {
 | |
|       EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
 | |
|     }
 | |
| 
 | |
|     RemoveEntryList (&NewMenuEntry->Link);
 | |
|     BOpt_DestroyMenuEntry (NewMenuEntry);
 | |
|     NewMenuEntry = NULL;
 | |
|   }
 | |
| 
 | |
|   BootOptionMenu.MenuNumber -= Index2;
 | |
| 
 | |
|   Status = Var_ChangeBootOrder ();
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_ChangeBootOrder (
 | |
|   VOID
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   After any operation on Boot####, there will be a discrepancy in BootOrder.
 | |
|   Since some are missing but in BootOrder, while some are present but are 
 | |
|   not reflected by BootOrder. Then a function rebuild BootOrder from 
 | |
|   scratch by content from BootOptionMenu is needed.
 | |
|   
 | |
| Arguments:
 | |
| 
 | |
| Returns:
 | |
|   EFI_SUCCESS
 | |
|   Others
 | |
|   
 | |
| --*/
 | |
| {
 | |
| 
 | |
|   EFI_STATUS    Status;
 | |
|   BM_MENU_ENTRY *NewMenuEntry;
 | |
|   UINT16        *BootOrderList;
 | |
|   UINT16        *BootOrderListPtr;
 | |
|   UINTN         BootOrderListSize;
 | |
|   UINTN         Index;
 | |
| 
 | |
|   BootOrderList     = NULL;
 | |
|   BootOrderListSize = 0;
 | |
| 
 | |
|   //
 | |
|   // First check whether BootOrder is present in current configuration
 | |
|   //
 | |
|   BootOrderList = BdsLibGetVariableAndSize (
 | |
|                     L"BootOrder",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     &BootOrderListSize
 | |
|                     );
 | |
| 
 | |
|   //
 | |
|   // If exists, delete it to hold new BootOrder
 | |
|   //
 | |
|   if (BootOrderList) {
 | |
|     EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
 | |
|     SafeFreePool (BootOrderList);
 | |
|     BootOrderList = NULL;
 | |
|   }
 | |
|   //
 | |
|   // Maybe here should be some check method to ensure that
 | |
|   // no new added boot options will be added
 | |
|   // but the setup engine now will give only one callback
 | |
|   // that is to say, user are granted only one chance to
 | |
|   // decide whether the boot option will be added or not
 | |
|   // there should be no indictor to show whether this
 | |
|   // is a "new" boot option
 | |
|   //
 | |
|   BootOrderListSize = BootOptionMenu.MenuNumber;
 | |
| 
 | |
|   if (BootOrderListSize > 0) {
 | |
|     BootOrderList = AllocateZeroPool (BootOrderListSize * sizeof (UINT16));
 | |
|     ASSERT (BootOrderList != NULL);
 | |
|     BootOrderListPtr = BootOrderList;
 | |
| 
 | |
|     //
 | |
|     // Get all current used Boot#### from BootOptionMenu.
 | |
|     // OptionNumber in each BM_LOAD_OPTION is really its
 | |
|     // #### value.
 | |
|     //
 | |
|     for (Index = 0; Index < BootOrderListSize; Index++) {
 | |
|       NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
 | |
|       *BootOrderList  = (UINT16) NewMenuEntry->OptionNumber;
 | |
|       BootOrderList++;
 | |
|     }
 | |
| 
 | |
|     BootOrderList = BootOrderListPtr;
 | |
| 
 | |
|     //
 | |
|     // After building the BootOrderList, write it back
 | |
|     //
 | |
|     Status = gRT->SetVariable (
 | |
|                     L"BootOrder",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     VAR_FLAG,
 | |
|                     BootOrderListSize * sizeof (UINT16),
 | |
|                     BootOrderList
 | |
|                     );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_DelDriverOption (
 | |
|   VOID
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   Delete Load Option that represent a Deleted state in BootOptionMenu.
 | |
|   After deleting this Driver option, call Var_ChangeDriverOrder to
 | |
|   make sure DriverOrder is in valid state.
 | |
|   
 | |
| Arguments:
 | |
|   LoadOption -- Pointer to the Driver option that to be deleted
 | |
| 
 | |
| Returns:
 | |
|   EFI_SUCCESS
 | |
|   Others
 | |
|   
 | |
| --*/
 | |
| {
 | |
|   BM_MENU_ENTRY   *NewMenuEntry;
 | |
|   BM_LOAD_CONTEXT *NewLoadContext;
 | |
| 
 | |
|   UINT16          DriverString[12];
 | |
|   EFI_STATUS      Status;
 | |
|   UINTN           Index;
 | |
|   UINTN           Index2;
 | |
| 
 | |
|   Status  = EFI_SUCCESS;
 | |
|   Index2  = 0;
 | |
|   for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
 | |
|     NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));
 | |
|     if (NULL == NewMenuEntry) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
| 
 | |
|     NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|     if (!NewLoadContext->Deleted) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     UnicodeSPrint (
 | |
|       DriverString,
 | |
|       sizeof (DriverString),
 | |
|       L"Driver%04x",
 | |
|       NewMenuEntry->OptionNumber
 | |
|       );
 | |
| 
 | |
|     EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid);
 | |
|     Index2++;
 | |
| 
 | |
|     RemoveEntryList (&NewMenuEntry->Link);
 | |
|     BOpt_DestroyMenuEntry (NewMenuEntry);
 | |
|     NewMenuEntry = NULL;
 | |
|   }
 | |
| 
 | |
|   DriverOptionMenu.MenuNumber -= Index2;
 | |
| 
 | |
|   Status = Var_ChangeDriverOrder ();
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_ChangeDriverOrder (
 | |
|   VOID
 | |
|   )
 | |
| /*++
 | |
| 
 | |
| Routine Description:
 | |
|   After any operation on Driver####, there will be a discrepancy in 
 | |
|   DriverOrder. Since some are missing but in DriverOrder, while some 
 | |
|   are present but are not reflected by DriverOrder. Then a function 
 | |
|   rebuild DriverOrder from scratch by content from DriverOptionMenu is 
 | |
|   needed.
 | |
|   
 | |
| Arguments:
 | |
| 
 | |
| Returns:
 | |
|   EFI_SUCCESS
 | |
|   Others
 | |
|   
 | |
| --*/
 | |
| {
 | |
|   EFI_STATUS    Status;
 | |
|   BM_MENU_ENTRY *NewMenuEntry;
 | |
|   UINT16        *DriverOrderList;
 | |
|   UINT16        *DriverOrderListPtr;
 | |
|   UINTN         DriverOrderListSize;
 | |
|   UINTN         Index;
 | |
| 
 | |
|   DriverOrderList     = NULL;
 | |
|   DriverOrderListSize = 0;
 | |
| 
 | |
|   //
 | |
|   // First check whether DriverOrder is present in current configuration
 | |
|   //
 | |
|   DriverOrderList = BdsLibGetVariableAndSize (
 | |
|                       L"DriverOrder",
 | |
|                       &gEfiGlobalVariableGuid,
 | |
|                       &DriverOrderListSize
 | |
|                       );
 | |
| 
 | |
|   //
 | |
|   // If exists, delete it to hold new DriverOrder
 | |
|   //
 | |
|   if (DriverOrderList) {
 | |
|     EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
 | |
|     SafeFreePool (DriverOrderList);
 | |
|     DriverOrderList = NULL;
 | |
|   }
 | |
| 
 | |
|   DriverOrderListSize = DriverOptionMenu.MenuNumber;
 | |
| 
 | |
|   if (DriverOrderListSize > 0) {
 | |
|     DriverOrderList = AllocateZeroPool (DriverOrderListSize * sizeof (UINT16));
 | |
|     ASSERT (DriverOrderList != NULL);
 | |
|     DriverOrderListPtr = DriverOrderList;
 | |
| 
 | |
|     //
 | |
|     // Get all current used Driver#### from DriverOptionMenu.
 | |
|     // OptionNumber in each BM_LOAD_OPTION is really its
 | |
|     // #### value.
 | |
|     //
 | |
|     for (Index = 0; Index < DriverOrderListSize; Index++) {
 | |
|       NewMenuEntry      = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
 | |
|       *DriverOrderList  = (UINT16) NewMenuEntry->OptionNumber;
 | |
|       DriverOrderList++;
 | |
|     }
 | |
| 
 | |
|     DriverOrderList = DriverOrderListPtr;
 | |
| 
 | |
|     //
 | |
|     // After building the DriverOrderList, write it back
 | |
|     //
 | |
|     Status = gRT->SetVariable (
 | |
|                     L"DriverOrder",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     VAR_FLAG,
 | |
|                     DriverOrderListSize * sizeof (UINT16),
 | |
|                     DriverOrderList
 | |
|                     );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| VOID
 | |
| Var_UpdateAllConsoleOption (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *OutDevicePath;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *InpDevicePath;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *ErrDevicePath;
 | |
|   EFI_STATUS                Status;
 | |
| 
 | |
|   OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
 | |
|   InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
 | |
|   ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
 | |
|   if (OutDevicePath) {
 | |
|     ChangeVariableDevicePath (OutDevicePath);
 | |
|     Status = gRT->SetVariable (
 | |
|                     L"ConOut",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     VAR_FLAG,
 | |
|                     GetDevicePathSize (OutDevicePath),
 | |
|                     OutDevicePath
 | |
|                     );
 | |
|     ASSERT (!EFI_ERROR (Status));
 | |
|   }
 | |
| 
 | |
|   if (InpDevicePath) {
 | |
|     ChangeVariableDevicePath (InpDevicePath);
 | |
|     Status = gRT->SetVariable (
 | |
|                     L"ConIn",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     VAR_FLAG,
 | |
|                     GetDevicePathSize (InpDevicePath),
 | |
|                     InpDevicePath
 | |
|                     );
 | |
|     ASSERT (!EFI_ERROR (Status));
 | |
|   }
 | |
| 
 | |
|   if (ErrDevicePath) {
 | |
|     ChangeVariableDevicePath (ErrDevicePath);
 | |
|     Status = gRT->SetVariable (
 | |
|                     L"ErrOut",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     VAR_FLAG,
 | |
|                     GetDevicePathSize (ErrDevicePath),
 | |
|                     ErrDevicePath
 | |
|                     );
 | |
|     ASSERT (!EFI_ERROR (Status));
 | |
|   }
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateConsoleOption (
 | |
|   IN UINT16                     *ConsoleName,
 | |
|   IN BM_MENU_OPTION             *ConsoleMenu,
 | |
|   IN UINT16                     UpdatePageId
 | |
|   )
 | |
| {
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *ConDevicePath;
 | |
|   BM_MENU_ENTRY             *NewMenuEntry;
 | |
|   BM_CONSOLE_CONTEXT        *NewConsoleContext;
 | |
|   BM_TERMINAL_CONTEXT       *NewTerminalContext;
 | |
|   EFI_STATUS                Status;
 | |
|   VENDOR_DEVICE_PATH        Vendor;
 | |
|   EFI_DEVICE_PATH_PROTOCOL  *TerminalDevicePath;
 | |
|   UINTN                     Index;
 | |
|   UINT16                    *Temp;
 | |
| 
 | |
|   ConDevicePath = EfiLibGetVariable (ConsoleName, &gEfiGlobalVariableGuid);
 | |
|   if (ConDevicePath != NULL) {
 | |
|     EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);
 | |
|     SafeFreePool (ConDevicePath);
 | |
|     ConDevicePath = NULL;
 | |
|   };
 | |
| 
 | |
|   //
 | |
|   // First add all console input device to it from console input menu
 | |
|   //
 | |
|   for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
 | |
|     NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
 | |
|     if (NULL == NewMenuEntry) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
| 
 | |
|     NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|     if (NewConsoleContext->IsActive) {
 | |
|       ConDevicePath = AppendDevicePathInstance (
 | |
|                         ConDevicePath,
 | |
|                         NewConsoleContext->DevicePath
 | |
|                         );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
 | |
|     NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
 | |
|     if (NULL == NewMenuEntry) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
| 
 | |
|     NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|     if ((NewTerminalContext->IsConIn && (UpdatePageId == FORM_CON_IN_ID)) ||
 | |
|         (NewTerminalContext->IsConOut && (UpdatePageId == FORM_CON_OUT_ID)) ||
 | |
|         (NewTerminalContext->IsStdErr && (UpdatePageId == FORM_CON_ERR_ID))
 | |
|         ) {
 | |
|       Vendor.Header.Type    = MESSAGING_DEVICE_PATH;
 | |
|       Vendor.Header.SubType = MSG_VENDOR_DP;
 | |
|       CopyMem (
 | |
|         &Vendor.Guid,
 | |
|         &Guid[NewTerminalContext->TerminalType],
 | |
|         sizeof (EFI_GUID)
 | |
|         );
 | |
|       SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
 | |
|       TerminalDevicePath = AppendDevicePathNode (
 | |
|                             NewTerminalContext->DevicePath,
 | |
|                             (EFI_DEVICE_PATH_PROTOCOL *) &Vendor
 | |
|                             );
 | |
|       ChangeTerminalDevicePath (TerminalDevicePath, TRUE);
 | |
|       Temp = DevicePathToStr (TerminalDevicePath);
 | |
|       ConDevicePath = AppendDevicePathInstance (
 | |
|                         ConDevicePath,
 | |
|                         TerminalDevicePath
 | |
|                         );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (ConDevicePath) {
 | |
|     Status = gRT->SetVariable (
 | |
|                     ConsoleName,
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     VAR_FLAG,
 | |
|                     GetDevicePathSize (ConDevicePath),
 | |
|                     ConDevicePath
 | |
|                     );
 | |
|     if (EFI_ERROR (Status)) {
 | |
|       return Status;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateConsoleInpOption (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateConsoleOutOption (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateErrorOutOption (
 | |
|   VOID
 | |
|   )
 | |
| {
 | |
|   return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateDriverOption (
 | |
|   IN  BMM_CALLBACK_DATA         *CallbackData,
 | |
|   IN  EFI_HII_HANDLE            HiiHandle,
 | |
|   IN  UINT16                    *DescriptionData,
 | |
|   IN  UINT16                    *OptionalData,
 | |
|   IN  UINT8                     ForceReconnect
 | |
|   )
 | |
| {
 | |
|   UINT16          Index;
 | |
|   UINT16          *DriverOrderList;
 | |
|   UINT16          *NewDriverOrderList;
 | |
|   UINT16          DriverString[12];
 | |
|   UINTN           DriverOrderListSize;
 | |
|   VOID            *Buffer;
 | |
|   UINTN           BufferSize;
 | |
|   UINT8           *Ptr;
 | |
|   BM_MENU_ENTRY   *NewMenuEntry;
 | |
|   BM_LOAD_CONTEXT *NewLoadContext;
 | |
|   BOOLEAN         OptionalDataExist;
 | |
|   EFI_STATUS      Status;
 | |
| 
 | |
|   OptionalDataExist = FALSE;
 | |
| 
 | |
|   Index             = BOpt_GetDriverOptionNumber ();
 | |
|   UnicodeSPrint (
 | |
|     DriverString,
 | |
|     sizeof (DriverString),
 | |
|     L"Driver%04x",
 | |
|     Index
 | |
|     );
 | |
| 
 | |
|   if (*DescriptionData == 0x0000) {
 | |
|     StrCpy (DescriptionData, DriverString);
 | |
|   }
 | |
| 
 | |
|   BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);
 | |
| 
 | |
|   if (*OptionalData != 0x0000) {
 | |
|     OptionalDataExist = TRUE;
 | |
|     BufferSize += StrSize (OptionalData);
 | |
|   }
 | |
| 
 | |
|   Buffer = AllocateZeroPool (BufferSize);
 | |
|   if (NULL == Buffer) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
 | |
|   if (NULL == NewMenuEntry) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   NewLoadContext                  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|   NewLoadContext->Deleted         = FALSE;
 | |
|   NewLoadContext->LoadOptionSize  = BufferSize;
 | |
|   Ptr = (UINT8 *) Buffer;
 | |
|   NewLoadContext->LoadOption = Ptr;
 | |
|   *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);
 | |
|   NewLoadContext->Attributes = *((UINT32 *) Ptr);
 | |
|   NewLoadContext->IsActive = TRUE;
 | |
|   NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
 | |
| 
 | |
|   Ptr += sizeof (UINT32);
 | |
|   *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
 | |
|   NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
 | |
| 
 | |
|   Ptr += sizeof (UINT16);
 | |
|   CopyMem (
 | |
|     Ptr,
 | |
|     DescriptionData,
 | |
|     StrSize (DescriptionData)
 | |
|     );
 | |
| 
 | |
|   NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));
 | |
|   ASSERT (NewLoadContext->Description != NULL);
 | |
|   NewMenuEntry->DisplayString = NewLoadContext->Description;
 | |
|   CopyMem (
 | |
|     NewLoadContext->Description,
 | |
|     (VOID *) Ptr,
 | |
|     StrSize (DescriptionData)
 | |
|     );
 | |
| 
 | |
|   Ptr += StrSize (DescriptionData);
 | |
|   CopyMem (
 | |
|     Ptr,
 | |
|     CallbackData->LoadContext->FilePathList,
 | |
|     GetDevicePathSize (CallbackData->LoadContext->FilePathList)
 | |
|     );
 | |
| 
 | |
|   NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
 | |
|   ASSERT (NewLoadContext->FilePathList != NULL);
 | |
| 
 | |
|   CopyMem (
 | |
|     NewLoadContext->FilePathList,
 | |
|     (VOID *) Ptr,
 | |
|     GetDevicePathSize (CallbackData->LoadContext->FilePathList)
 | |
|     );
 | |
| 
 | |
|   NewMenuEntry->HelpString    = DevicePathToStr (NewLoadContext->FilePathList);
 | |
|   NewMenuEntry->OptionNumber  = Index;
 | |
|   NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
 | |
|                                       CallbackData,
 | |
|                                       DriverOptionStrDepository
 | |
|                                       );
 | |
|   CallbackData->Hii->NewString (
 | |
|                       CallbackData->Hii,
 | |
|                       NULL,
 | |
|                       HiiHandle,
 | |
|                       &NewMenuEntry->DisplayStringToken,
 | |
|                       NewMenuEntry->DisplayString
 | |
|                       );
 | |
| 
 | |
|   NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
 | |
|                                     CallbackData,
 | |
|                                     DriverOptionHelpStrDepository
 | |
|                                     );
 | |
|   CallbackData->Hii->NewString (
 | |
|                       CallbackData->Hii,
 | |
|                       NULL,
 | |
|                       HiiHandle,
 | |
|                       &NewMenuEntry->HelpStringToken,
 | |
|                       NewMenuEntry->HelpString
 | |
|                       );
 | |
| 
 | |
|   if (OptionalDataExist) {
 | |
|     Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
 | |
| 
 | |
|     CopyMem (
 | |
|       Ptr,
 | |
|       OptionalData,
 | |
|       StrSize (OptionalData)
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   DriverString,
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   VAR_FLAG,
 | |
|                   BufferSize,
 | |
|                   Buffer
 | |
|                   );
 | |
|   DriverOrderList = BdsLibGetVariableAndSize (
 | |
|                       L"DriverOrder",
 | |
|                       &gEfiGlobalVariableGuid,
 | |
|                       &DriverOrderListSize
 | |
|                       );
 | |
|   NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
 | |
|   ASSERT (NewDriverOrderList != NULL);
 | |
|   CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
 | |
|   NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
 | |
|   if (DriverOrderList != NULL) {
 | |
|     EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
 | |
|   }
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   L"DriverOrder",
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   VAR_FLAG,
 | |
|                   DriverOrderListSize + sizeof (UINT16),
 | |
|                   NewDriverOrderList
 | |
|                   );
 | |
|   SafeFreePool (DriverOrderList);
 | |
|   DriverOrderList = NULL;
 | |
|   SafeFreePool (NewDriverOrderList);
 | |
|   NewDriverOrderList = NULL;
 | |
|   InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
 | |
|   DriverOptionMenu.MenuNumber++;
 | |
| 
 | |
|   *DescriptionData  = 0x0000;
 | |
|   *OptionalData     = 0x0000;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateBootOption (
 | |
|   IN  BMM_CALLBACK_DATA                   *CallbackData,
 | |
|   IN  FILE_EXPLORER_NV_DATA               *NvRamMap
 | |
|   )
 | |
| {
 | |
|   UINT16          *BootOrderList;
 | |
|   UINT16          *NewBootOrderList;
 | |
|   UINTN           BootOrderListSize;
 | |
|   UINT16          BootString[10];
 | |
|   VOID            *Buffer;
 | |
|   UINTN           BufferSize;
 | |
|   UINT8           *Ptr;
 | |
|   UINT16          Index;
 | |
|   BM_MENU_ENTRY   *NewMenuEntry;
 | |
|   BM_LOAD_CONTEXT *NewLoadContext;
 | |
|   BOOLEAN         OptionalDataExist;
 | |
|   EFI_STATUS      Status;
 | |
| 
 | |
|   OptionalDataExist = FALSE;
 | |
| 
 | |
|   Index             = BOpt_GetBootOptionNumber ();
 | |
|   UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);
 | |
| 
 | |
|   if (NvRamMap->DescriptionData[0] == 0x0000) {
 | |
|     StrCpy (NvRamMap->DescriptionData, BootString);
 | |
|   }
 | |
| 
 | |
|   BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);
 | |
| 
 | |
|   if (NvRamMap->OptionalData[0] != 0x0000) {
 | |
|     OptionalDataExist = TRUE;
 | |
|     BufferSize += StrSize (NvRamMap->OptionalData);
 | |
|   }
 | |
| 
 | |
|   Buffer = AllocateZeroPool (BufferSize);
 | |
|   if (NULL == Buffer) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
 | |
|   if (NULL == NewMenuEntry) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   NewLoadContext                  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|   NewLoadContext->Deleted         = FALSE;
 | |
|   NewLoadContext->LoadOptionSize  = BufferSize;
 | |
|   Ptr = (UINT8 *) Buffer;
 | |
|   NewLoadContext->LoadOption = Ptr;
 | |
|   *((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
 | |
|   NewLoadContext->Attributes = *((UINT32 *) Ptr);
 | |
|   NewLoadContext->IsActive = TRUE;
 | |
|   NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
 | |
| 
 | |
|   Ptr += sizeof (UINT32);
 | |
|   *((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
 | |
|   NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
 | |
|   Ptr += sizeof (UINT16);
 | |
| 
 | |
|   CopyMem (
 | |
|     Ptr,
 | |
|     NvRamMap->DescriptionData,
 | |
|     StrSize (NvRamMap->DescriptionData)
 | |
|     );
 | |
| 
 | |
|   NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->DescriptionData));
 | |
|   ASSERT (NewLoadContext->Description != NULL);
 | |
| 
 | |
|   NewMenuEntry->DisplayString = NewLoadContext->Description;
 | |
|   CopyMem (
 | |
|     NewLoadContext->Description,
 | |
|     (VOID *) Ptr,
 | |
|     StrSize (NvRamMap->DescriptionData)
 | |
|     );
 | |
| 
 | |
|   Ptr += StrSize (NvRamMap->DescriptionData);
 | |
|   CopyMem (
 | |
|     Ptr,
 | |
|     CallbackData->LoadContext->FilePathList,
 | |
|     GetDevicePathSize (CallbackData->LoadContext->FilePathList)
 | |
|     );
 | |
| 
 | |
|   NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
 | |
|   ASSERT (NewLoadContext->FilePathList != NULL);
 | |
| 
 | |
|   CopyMem (
 | |
|     NewLoadContext->FilePathList,
 | |
|     (VOID *) Ptr,
 | |
|     GetDevicePathSize (CallbackData->LoadContext->FilePathList)
 | |
|     );
 | |
| 
 | |
|   NewMenuEntry->HelpString    = DevicePathToStr (NewLoadContext->FilePathList);
 | |
|   NewMenuEntry->OptionNumber  = Index;
 | |
|   NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
 | |
|                                       CallbackData,
 | |
|                                       BootOptionStrDepository
 | |
|                                       );
 | |
|   CallbackData->Hii->NewString (
 | |
|                       CallbackData->Hii,
 | |
|                       NULL,
 | |
|                       CallbackData->FeHiiHandle,
 | |
|                       &NewMenuEntry->DisplayStringToken,
 | |
|                       NewMenuEntry->DisplayString
 | |
|                       );
 | |
| 
 | |
|   NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
 | |
|                                     CallbackData,
 | |
|                                     BootOptionHelpStrDepository
 | |
|                                     );
 | |
| 
 | |
|   CallbackData->Hii->NewString (
 | |
|                       CallbackData->Hii,
 | |
|                       NULL,
 | |
|                       CallbackData->FeHiiHandle,
 | |
|                       &NewMenuEntry->HelpStringToken,
 | |
|                       NewMenuEntry->HelpString
 | |
|                       );
 | |
| 
 | |
|   if (OptionalDataExist) {
 | |
|     Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
 | |
| 
 | |
|     CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));
 | |
|   }
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   BootString,
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   VAR_FLAG,
 | |
|                   BufferSize,
 | |
|                   Buffer
 | |
|                   );
 | |
| 
 | |
|   BootOrderList = BdsLibGetVariableAndSize (
 | |
|                     L"BootOrder",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     &BootOrderListSize
 | |
|                     );
 | |
| 
 | |
|   NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
 | |
|   ASSERT (NewBootOrderList != NULL);
 | |
|   CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
 | |
|   NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
 | |
| 
 | |
|   if (BootOrderList != NULL) {
 | |
|     EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
 | |
|   }
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   L"BootOrder",
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   VAR_FLAG,
 | |
|                   BootOrderListSize + sizeof (UINT16),
 | |
|                   NewBootOrderList
 | |
|                   );
 | |
| 
 | |
|   SafeFreePool (BootOrderList);
 | |
|   BootOrderList = NULL;
 | |
|   SafeFreePool (NewBootOrderList);
 | |
|   NewBootOrderList = NULL;
 | |
|   InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
 | |
|   BootOptionMenu.MenuNumber++;
 | |
| 
 | |
|   NvRamMap->DescriptionData[0]  = 0x0000;
 | |
|   NvRamMap->OptionalData[0]     = 0x0000;
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateBootNext (
 | |
|   IN BMM_CALLBACK_DATA            *CallbackData
 | |
|   )
 | |
| {
 | |
|   BM_MENU_ENTRY     *NewMenuEntry;
 | |
|   BM_LOAD_CONTEXT   *NewLoadContext;
 | |
|   BMM_FAKE_NV_DATA  *CurrentFakeNVMap;
 | |
|   UINT16            Index;
 | |
|   EFI_STATUS        Status;
 | |
| 
 | |
|   Status            = EFI_SUCCESS;
 | |
|   CurrentFakeNVMap  = CallbackData->BmmFakeNvData;
 | |
|   for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
 | |
|     NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
 | |
|     if (NULL == NewMenuEntry) {
 | |
|       return EFI_NOT_FOUND;
 | |
|     }
 | |
| 
 | |
|     NewLoadContext              = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|     NewLoadContext->IsBootNext  = FALSE;
 | |
|   }
 | |
| 
 | |
|   if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {
 | |
|     EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
 | |
|     return EFI_SUCCESS;
 | |
|   }
 | |
| 
 | |
|   NewMenuEntry = BOpt_GetMenuEntry (
 | |
|                   &BootOptionMenu,
 | |
|                   CurrentFakeNVMap->BootNext
 | |
|                   );
 | |
|   if (NULL == NewMenuEntry) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|   Status = gRT->SetVariable (
 | |
|                   L"BootNext",
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   VAR_FLAG,
 | |
|                   sizeof (UINT16),
 | |
|                   &NewMenuEntry->OptionNumber
 | |
|                   );
 | |
|   NewLoadContext->IsBootNext              = TRUE;
 | |
|   CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
 | |
|   return Status;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateBootOrder (
 | |
|   IN BMM_CALLBACK_DATA            *CallbackData
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINT16      Index;
 | |
|   UINT16      *BootOrderList;
 | |
|   UINT16      *NewBootOrderList;
 | |
|   UINTN       BootOrderListSize;
 | |
|   UINT8       *Map;
 | |
| 
 | |
|   BootOrderList     = NULL;
 | |
|   BootOrderListSize = 0;
 | |
| 
 | |
|   //
 | |
|   // First check whether BootOrder is present in current configuration
 | |
|   //
 | |
|   BootOrderList = BdsLibGetVariableAndSize (
 | |
|                     L"BootOrder",
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     &BootOrderListSize
 | |
|                     );
 | |
| 
 | |
|   NewBootOrderList = AllocateZeroPool (BootOrderListSize);
 | |
|   if (!NewBootOrderList) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   Map = AllocateZeroPool (BootOrderListSize / sizeof (UINT16));
 | |
|   if (!Map) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
|   //
 | |
|   // If exists, delete it to hold new BootOrder
 | |
|   //
 | |
|   if (BootOrderList) {
 | |
|     EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
 | |
|     NewBootOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;
 | |
|   }
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   L"BootOrder",
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   VAR_FLAG,
 | |
|                   BootOrderListSize,
 | |
|                   NewBootOrderList
 | |
|                   );
 | |
|   SafeFreePool (BootOrderList);
 | |
|   SafeFreePool (NewBootOrderList);
 | |
|   SafeFreePool (Map);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   BOpt_FreeMenu (&BootOptionMenu);
 | |
|   BOpt_GetBootOptions (CallbackData);
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| 
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateDriverOrder (
 | |
|   IN BMM_CALLBACK_DATA            *CallbackData
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS  Status;
 | |
|   UINT16      Index;
 | |
|   UINT16      *DriverOrderList;
 | |
|   UINT16      *NewDriverOrderList;
 | |
|   UINTN       DriverOrderListSize;
 | |
| 
 | |
|   DriverOrderList     = NULL;
 | |
|   DriverOrderListSize = 0;
 | |
| 
 | |
|   //
 | |
|   // First check whether DriverOrder is present in current configuration
 | |
|   //
 | |
|   DriverOrderList = BdsLibGetVariableAndSize (
 | |
|                       L"DriverOrder",
 | |
|                       &gEfiGlobalVariableGuid,
 | |
|                       &DriverOrderListSize
 | |
|                       );
 | |
| 
 | |
|   NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);
 | |
| 
 | |
|   if (!NewDriverOrderList) {
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
|   //
 | |
|   // If exists, delete it to hold new DriverOrder
 | |
|   //
 | |
|   if (DriverOrderList) {
 | |
|     EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < DriverOrderListSize; Index++) {
 | |
|     NewDriverOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;
 | |
|   }
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   L"DriverOrder",
 | |
|                   &gEfiGlobalVariableGuid,
 | |
|                   VAR_FLAG,
 | |
|                   DriverOrderListSize,
 | |
|                   NewDriverOrderList
 | |
|                   );
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return Status;
 | |
|   }
 | |
| 
 | |
|   SafeFreePool (DriverOrderList);
 | |
| 
 | |
|   BOpt_FreeMenu (&DriverOptionMenu);
 | |
|   BOpt_GetDriverOptions (CallbackData);
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 | |
| EFI_STATUS
 | |
| Var_UpdateBBSOption (
 | |
|   IN BMM_CALLBACK_DATA            *CallbackData
 | |
|   )
 | |
| {
 | |
|   UINTN                       Index;
 | |
|   UINTN                       Index2;
 | |
|   VOID                        *BootOptionVar;
 | |
|   CHAR16                      VarName[100];
 | |
|   UINTN                       OptionSize;
 | |
|   UINT16                      FilePathSize;
 | |
|   UINT8                       *Ptr;
 | |
|   EFI_STATUS                  Status;
 | |
|   CHAR16                      DescString[100];
 | |
|   UINTN                       NewOptionSize;
 | |
|   UINT8                       *NewOptionPtr;
 | |
|   UINT8                       *TempPtr;
 | |
|   UINT32                      *Attribute;
 | |
| 
 | |
|   BM_MENU_OPTION              *OptionMenu;
 | |
|   BM_LEGACY_DEVICE_CONTEXT    *LegacyDeviceContext;
 | |
|   UINT8                       *LegacyDev;
 | |
|   UINT8                       *VarData;
 | |
|   UINTN                       VarSize;
 | |
|   BM_MENU_ENTRY               *NewMenuEntry;
 | |
|   BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;
 | |
|   UINT8                       *OriginalPtr;
 | |
|   UINT8                       *DisMap;
 | |
|   UINTN                       Pos;
 | |
|   UINTN                       Bit;
 | |
|   UINT16                      *NewOrder;
 | |
|   UINT16                      Tmp;
 | |
| 
 | |
|   LegacyDeviceContext = NULL;
 | |
|   DisMap              = NULL;
 | |
|   NewOrder            = NULL;
 | |
| 
 | |
|   if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {
 | |
|     OptionMenu            = (BM_MENU_OPTION *) &LegacyFDMenu;
 | |
|     LegacyDev             = CallbackData->BmmFakeNvData->LegacyFD;
 | |
|     CallbackData->BbsType = BBS_FLOPPY;
 | |
|   } else {
 | |
|     if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {
 | |
|       OptionMenu            = (BM_MENU_OPTION *) &LegacyHDMenu;
 | |
|       LegacyDev             = CallbackData->BmmFakeNvData->LegacyHD;
 | |
|       CallbackData->BbsType = BBS_HARDDISK;
 | |
|     } else {
 | |
|       if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {
 | |
|         OptionMenu            = (BM_MENU_OPTION *) &LegacyCDMenu;
 | |
|         LegacyDev             = CallbackData->BmmFakeNvData->LegacyCD;
 | |
|         CallbackData->BbsType = BBS_CDROM;
 | |
|       } else {
 | |
|         if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {
 | |
|           OptionMenu            = (BM_MENU_OPTION *) &LegacyNETMenu;
 | |
|           LegacyDev             = CallbackData->BmmFakeNvData->LegacyNET;
 | |
|           CallbackData->BbsType = BBS_EMBED_NETWORK;
 | |
|         } else {
 | |
|           OptionMenu            = (BM_MENU_OPTION *) &LegacyBEVMenu;
 | |
|           LegacyDev             = CallbackData->BmmFakeNvData->LegacyBEV;
 | |
|           CallbackData->BbsType = BBS_BEV_DEVICE;
 | |
|         }
 | |
|       }
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   DisMap  = CallbackData->BmmOldFakeNVData.DisableMap;
 | |
|   Status  = EFI_SUCCESS;
 | |
| 
 | |
|   //
 | |
|   // Find the first device's context
 | |
|   // If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
 | |
|   // because we just use it to fill the desc string, and user can not see the string in UI
 | |
|   //
 | |
|   for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
 | |
|     NewMenuEntry        = BOpt_GetMenuEntry (OptionMenu, Index);
 | |
|     LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
 | |
|     if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {
 | |
|       DEBUG ((EFI_D_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));
 | |
|       break;
 | |
|     }
 | |
|   }
 | |
|   //
 | |
|   // Update the Variable "LegacyDevOrder"
 | |
|   //
 | |
|   VarData = (UINT8 *) BdsLibGetVariableAndSize (
 | |
|                         VarLegacyDevOrder,
 | |
|                         &EfiLegacyDevOrderGuid,
 | |
|                         &VarSize
 | |
|                         );
 | |
| 
 | |
|   if (NULL == VarData) {
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   OriginalPtr = VarData;
 | |
|   DevOrder    = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
 | |
| 
 | |
|   while (VarData < VarData + VarSize) {
 | |
|     if (DevOrder->BbsType == CallbackData->BbsType) {
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     VarData += sizeof (BBS_TYPE);
 | |
|     VarData += *(UINT16 *) VarData;
 | |
|     DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
 | |
|   }
 | |
| 
 | |
|   if (VarData >= VarData + VarSize) {
 | |
|     SafeFreePool (OriginalPtr);
 | |
|     return EFI_NOT_FOUND;
 | |
|   }
 | |
| 
 | |
|   NewOrder = (UINT16 *) AllocateZeroPool (DevOrder->Length - sizeof (UINT16));
 | |
|   if (NULL == NewOrder) {
 | |
|     SafeFreePool (VarData);
 | |
|     return EFI_OUT_OF_RESOURCES;
 | |
|   }
 | |
| 
 | |
|   for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
 | |
|     if (0xFF == LegacyDev[Index]) {
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|     NewOrder[Index] = LegacyDev[Index];
 | |
|   }
 | |
|   //
 | |
|   // Only the enable/disable state of each boot device with same device type can be changed,
 | |
|   // so we can count on the index information in DevOrder.
 | |
|   // DisMap bit array is the only reliable source to check a device's en/dis state,
 | |
|   // so we use DisMap to set en/dis state of each item in NewOrder array
 | |
|   //
 | |
|   for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
 | |
|     Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));
 | |
|     Tmp &= 0xFF;
 | |
|     Pos = Tmp / 8;
 | |
|     Bit = 7 - (Tmp % 8);
 | |
|     if (DisMap[Pos] & (1 << Bit)) {
 | |
|       NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
 | |
|       Index++;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   CopyMem (
 | |
|     (UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),
 | |
|     NewOrder,
 | |
|     DevOrder->Length - sizeof (UINT16)
 | |
|     );
 | |
|   SafeFreePool (NewOrder);
 | |
| 
 | |
|   Status = gRT->SetVariable (
 | |
|                   VarLegacyDevOrder,
 | |
|                   &EfiLegacyDevOrderGuid,
 | |
|                   VAR_FLAG,
 | |
|                   VarSize,
 | |
|                   OriginalPtr
 | |
|                   );
 | |
| 
 | |
|   SafeFreePool (OriginalPtr);
 | |
| 
 | |
|   //
 | |
|   // Update Optional Data of Boot####
 | |
|   //
 | |
|   BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);
 | |
| 
 | |
|   if (NULL != BootOptionVar) {
 | |
|     CopyMem (
 | |
|       DescString,
 | |
|       LegacyDeviceContext->Description,
 | |
|       StrSize (LegacyDeviceContext->Description)
 | |
|       );
 | |
| 
 | |
|     NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescString) + sizeof (BBS_TABLE) + sizeof (UINT16);
 | |
| 
 | |
|     UnicodeSPrint (VarName, 100, L"Boot%04x", Index);
 | |
| 
 | |
|     Ptr       = BootOptionVar;
 | |
| 
 | |
|     Attribute = (UINT32 *) Ptr;
 | |
|     *Attribute |= LOAD_OPTION_ACTIVE;
 | |
|     if (0xFF == LegacyDev[0]) {
 | |
|       //
 | |
|       // Disable this legacy boot option
 | |
|       //
 | |
|       *Attribute &= ~LOAD_OPTION_ACTIVE;
 | |
|     }
 | |
| 
 | |
|     Ptr += sizeof (UINT32);
 | |
| 
 | |
|     FilePathSize = *(UINT16 *) Ptr;
 | |
|     Ptr += sizeof (UINT16);
 | |
| 
 | |
|     NewOptionSize += FilePathSize;
 | |
| 
 | |
|     NewOptionPtr = AllocateZeroPool (NewOptionSize);
 | |
|     if (NULL == NewOptionPtr) {
 | |
|       return EFI_OUT_OF_RESOURCES;
 | |
|     }
 | |
| 
 | |
|     TempPtr = NewOptionPtr;
 | |
| 
 | |
|     //
 | |
|     // Copy previous option data to new option except the description string
 | |
|     //
 | |
|     CopyMem (
 | |
|       TempPtr,
 | |
|       BootOptionVar,
 | |
|       sizeof (UINT32) + sizeof (UINT16)
 | |
|       );
 | |
| 
 | |
|     TempPtr += (sizeof (UINT32) + sizeof (UINT16));
 | |
| 
 | |
|     CopyMem (
 | |
|       TempPtr,
 | |
|       DescString,
 | |
|       StrSize (DescString)
 | |
|       );
 | |
| 
 | |
|     TempPtr += StrSize (DescString);
 | |
| 
 | |
|     //
 | |
|     // Description = (CHAR16 *)Ptr;
 | |
|     //
 | |
|     Ptr += StrSize ((CHAR16 *) Ptr);
 | |
| 
 | |
|     CopyMem (
 | |
|       TempPtr,
 | |
|       Ptr,
 | |
|       FilePathSize
 | |
|       );
 | |
| 
 | |
|     TempPtr += FilePathSize;
 | |
| 
 | |
|     //
 | |
|     // DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
 | |
|     //
 | |
|     Ptr += FilePathSize;
 | |
| 
 | |
|     //
 | |
|     // Now Ptr point to optional data, i.e. Bbs Table
 | |
|     //
 | |
|     CopyMem (
 | |
|       TempPtr,
 | |
|       LegacyDeviceContext->BbsTable,
 | |
|       sizeof (BBS_TABLE)
 | |
|       );
 | |
| 
 | |
|     TempPtr += sizeof (BBS_TABLE);
 | |
|     *((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;
 | |
| 
 | |
|     Status = gRT->SetVariable (
 | |
|                     VarName,
 | |
|                     &gEfiGlobalVariableGuid,
 | |
|                     VAR_FLAG,
 | |
|                     NewOptionSize,
 | |
|                     NewOptionPtr
 | |
|                     );
 | |
| 
 | |
|     SafeFreePool (NewOptionPtr);
 | |
|     SafeFreePool (BootOptionVar);
 | |
|   }
 | |
| 
 | |
|   BOpt_GetBootOptions (CallbackData);
 | |
|   return Status;
 | |
| }
 |