AllocateCopyPool(AllocationSize, *Buffer) will copy "AllocationSize" bytes of memory from old "Buffer" to new allocated one. If "AllocationSize" is bigger than size of "Buffer", heap memory overflow occurs during copy. One solution is to allocate pool first then copy the necessary bytes to new memory. Another is using ReallocatePool instead if old buffer will be freed on spot. Cc: Star Zeng <star.zeng@intel.com> Cc: Eric Dong <eric.dong@intel.com> Cc: Bi Dandan <dandan.bi@intel.com> Contributed-under: TianoCore Contribution Agreement 1.1 Signed-off-by: Jian J Wang <jian.j.wang@intel.com> Reviewed-by: Star Zeng <star.zeng@intel.com> Reviewed-by: Bi Dandan <dandan.bi@intel.com>
		
			
				
	
	
		
			476 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			476 lines
		
	
	
		
			13 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /** @file
 | |
| The functions for Boot Maintainence Main menu.
 | |
| 
 | |
| Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
 | |
| This program and the accompanying materials
 | |
| are licensed and made available under the terms and conditions of the BSD License
 | |
| which accompanies this distribution.  The full text of the license may be found at
 | |
| http://opensource.org/licenses/bsd-license.php
 | |
| 
 | |
| THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
 | |
| WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
 | |
| 
 | |
| **/
 | |
| 
 | |
| 
 | |
| #include "BootMaintenanceManager.h"
 | |
| #include "BootMaintenanceManagerCustomizedUiSupport.h"
 | |
| 
 | |
| #define UI_HII_DRIVER_LIST_SIZE               0x8
 | |
| 
 | |
| typedef struct {
 | |
|   EFI_STRING_ID   PromptId;
 | |
|   EFI_STRING_ID   HelpId;
 | |
|   EFI_STRING_ID   DevicePathId;
 | |
|   EFI_GUID        FormSetGuid;
 | |
|   BOOLEAN         EmptyLineAfter;
 | |
| } UI_HII_DRIVER_INSTANCE;
 | |
| 
 | |
| STATIC UI_HII_DRIVER_INSTANCE       *gHiiDriverList;
 | |
| 
 | |
| 
 | |
| /**
 | |
|   Create the dynamic item to allow user to set the "BootNext" vaule.
 | |
| 
 | |
|   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| BmmCreateBootNextMenu(
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   BM_MENU_ENTRY   *NewMenuEntry;
 | |
|   BM_LOAD_CONTEXT *NewLoadContext;
 | |
|   UINT16          Index;
 | |
|   VOID            *OptionsOpCodeHandle;
 | |
|   UINT32          BootNextIndex;
 | |
| 
 | |
|   if (BootOptionMenu.MenuNumber == 0) {
 | |
|     return;
 | |
|   }
 | |
| 
 | |
|   BootNextIndex = NONE_BOOTNEXT_VALUE;
 | |
| 
 | |
|   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
 | |
|   ASSERT (OptionsOpCodeHandle != NULL);
 | |
| 
 | |
|   for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
 | |
|     NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
 | |
|     NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
 | |
| 
 | |
|     if (NewLoadContext->IsBootNext) {
 | |
|       HiiCreateOneOfOptionOpCode (
 | |
|         OptionsOpCodeHandle,
 | |
|         NewMenuEntry->DisplayStringToken,
 | |
|         EFI_IFR_OPTION_DEFAULT,
 | |
|         EFI_IFR_TYPE_NUM_SIZE_32,
 | |
|         Index
 | |
|         );
 | |
|       BootNextIndex = Index;
 | |
|     } else {
 | |
|       HiiCreateOneOfOptionOpCode (
 | |
|         OptionsOpCodeHandle,
 | |
|         NewMenuEntry->DisplayStringToken,
 | |
|         0,
 | |
|         EFI_IFR_TYPE_NUM_SIZE_32,
 | |
|         Index
 | |
|         );
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   if (BootNextIndex == NONE_BOOTNEXT_VALUE) {
 | |
|     HiiCreateOneOfOptionOpCode (
 | |
|       OptionsOpCodeHandle,
 | |
|       STRING_TOKEN (STR_NONE),
 | |
|       EFI_IFR_OPTION_DEFAULT,
 | |
|       EFI_IFR_TYPE_NUM_SIZE_32,
 | |
|       NONE_BOOTNEXT_VALUE
 | |
|       );
 | |
|   } else {
 | |
|     HiiCreateOneOfOptionOpCode (
 | |
|       OptionsOpCodeHandle,
 | |
|       STRING_TOKEN (STR_NONE),
 | |
|       0,
 | |
|       EFI_IFR_TYPE_NUM_SIZE_32,
 | |
|       NONE_BOOTNEXT_VALUE
 | |
|       );
 | |
|   }
 | |
| 
 | |
|   HiiCreateOneOfOpCode (
 | |
|     StartOpCodeHandle,
 | |
|     (EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,
 | |
|     VARSTORE_ID_BOOT_MAINT,
 | |
|     BOOT_NEXT_VAR_OFFSET,
 | |
|     STRING_TOKEN (STR_BOOT_NEXT),
 | |
|     STRING_TOKEN (STR_BOOT_NEXT_HELP),
 | |
|     0,
 | |
|     EFI_IFR_NUMERIC_SIZE_4,
 | |
|     OptionsOpCodeHandle,
 | |
|     NULL
 | |
|     );
 | |
| 
 | |
|   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
 | |
| 
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Time Out Menu in the page.
 | |
| 
 | |
|   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| BmmCreateTimeOutMenu (
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   HiiCreateNumericOpCode (
 | |
|     StartOpCodeHandle,
 | |
|     (EFI_QUESTION_ID) FORM_TIME_OUT_ID,
 | |
|     VARSTORE_ID_BOOT_MAINT,
 | |
|     BOOT_TIME_OUT_VAR_OFFSET,
 | |
|     STRING_TOKEN(STR_NUM_AUTO_BOOT),
 | |
|     STRING_TOKEN(STR_HLP_AUTO_BOOT),
 | |
|     EFI_IFR_FLAG_CALLBACK,
 | |
|     EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,
 | |
|     0,
 | |
|     65535,
 | |
|     0,
 | |
|     NULL
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Boot Option menu in the page.
 | |
| 
 | |
|   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| BmmCreateBootOptionMenu (
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   HiiCreateGotoOpCode (
 | |
|     StartOpCodeHandle,
 | |
|     FORM_BOOT_SETUP_ID,
 | |
|     STRING_TOKEN (STR_FORM_BOOT_SETUP_TITLE),
 | |
|     STRING_TOKEN (STR_FORM_BOOT_SETUP_HELP),
 | |
|     EFI_IFR_FLAG_CALLBACK,
 | |
|     FORM_BOOT_SETUP_ID
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Driver Option menu in the page.
 | |
| 
 | |
|   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| BmmCreateDriverOptionMenu (
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   HiiCreateGotoOpCode (
 | |
|     StartOpCodeHandle,
 | |
|     FORM_DRIVER_SETUP_ID,
 | |
|     STRING_TOKEN (STR_FORM_DRIVER_SETUP_TITLE),
 | |
|     STRING_TOKEN (STR_FORM_DRIVER_SETUP_HELP),
 | |
|     EFI_IFR_FLAG_CALLBACK,
 | |
|     FORM_DRIVER_SETUP_ID
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Com Option menu in the page.
 | |
| 
 | |
|   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| BmmCreateComOptionMenu (
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   HiiCreateGotoOpCode (
 | |
|     StartOpCodeHandle,
 | |
|     FORM_CON_MAIN_ID,
 | |
|     STRING_TOKEN (STR_FORM_CON_MAIN_TITLE),
 | |
|     STRING_TOKEN (STR_FORM_CON_MAIN_HELP),
 | |
|     EFI_IFR_FLAG_CALLBACK,
 | |
|     FORM_CON_MAIN_ID
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create Com Option menu in the page.
 | |
| 
 | |
|   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| BmmCreateBootFromFileMenu (
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   HiiCreateGotoOpCode (
 | |
|     StartOpCodeHandle,
 | |
|     FORM_MAIN_ID,
 | |
|     STRING_TOKEN (STR_BOOT_FROM_FILE),
 | |
|     STRING_TOKEN (STR_BOOT_FROM_FILE_HELP),
 | |
|     EFI_IFR_FLAG_CALLBACK,
 | |
|     KEY_VALUE_BOOT_FROM_FILE
 | |
|     );
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Create empty line menu in the front page.
 | |
| 
 | |
|   @param    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
| **/
 | |
| VOID
 | |
| BmmCreateEmptyLine (
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Extract device path for given HII handle and class guid.
 | |
| 
 | |
|   @param Handle          The HII handle.
 | |
| 
 | |
|   @retval  NULL          Fail to get the device path string.
 | |
|   @return  PathString    Get the device path string.
 | |
| 
 | |
| **/
 | |
| CHAR16 *
 | |
| ExtractDevicePathFromHandle (
 | |
|   IN      EFI_HII_HANDLE      Handle
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                       Status;
 | |
|   EFI_HANDLE                       DriverHandle;
 | |
| 
 | |
|   ASSERT (Handle != NULL);
 | |
| 
 | |
|   if (Handle == NULL) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return NULL;
 | |
|   }
 | |
| 
 | |
|   return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Check whether this driver need to be shown in the front page.
 | |
| 
 | |
|   @param    HiiHandle           The hii handle for the driver.
 | |
|   @param    Guid                The special guid for the driver which is the target.
 | |
|   @param    PromptId            Return the prompt string id.
 | |
|   @param    HelpId              Return the help string id.
 | |
|   @param    FormsetGuid         Return the formset guid info.
 | |
| 
 | |
|   @retval   EFI_SUCCESS         Search the driver success
 | |
| 
 | |
| **/
 | |
| BOOLEAN
 | |
| IsRequiredDriver (
 | |
|   IN  EFI_HII_HANDLE              HiiHandle,
 | |
|   IN  EFI_GUID                    *Guid,
 | |
|   OUT EFI_STRING_ID               *PromptId,
 | |
|   OUT EFI_STRING_ID               *HelpId,
 | |
|   OUT VOID                        *FormsetGuid
 | |
|   )
 | |
| {
 | |
|   EFI_STATUS                  Status;
 | |
|   UINT8                       ClassGuidNum;
 | |
|   EFI_GUID                    *ClassGuid;
 | |
|   EFI_IFR_FORM_SET            *Buffer;
 | |
|   UINTN                       BufferSize;
 | |
|   UINT8                       *Ptr;
 | |
|   UINTN                       TempSize;
 | |
|   BOOLEAN                     RetVal;
 | |
| 
 | |
|   Status = HiiGetFormSetFromHiiHandle(HiiHandle, &Buffer,&BufferSize);
 | |
|   if (EFI_ERROR (Status)) {
 | |
|     return FALSE;
 | |
|   }
 | |
| 
 | |
|   RetVal = FALSE;
 | |
|   TempSize = 0;
 | |
|   Ptr = (UINT8 *) Buffer;
 | |
|   while(TempSize < BufferSize)  {
 | |
|     TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
 | |
| 
 | |
|     if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){
 | |
|       Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
 | |
|     ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
 | |
|     while (ClassGuidNum-- > 0) {
 | |
|       if (!CompareGuid (Guid, ClassGuid)){
 | |
|         ClassGuid ++;
 | |
|         continue;
 | |
|       }
 | |
| 
 | |
|       *PromptId = ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle;
 | |
|       *HelpId = ((EFI_IFR_FORM_SET *)Ptr)->Help;
 | |
|       CopyMem (FormsetGuid, &((EFI_IFR_FORM_SET *) Ptr)->Guid, sizeof (EFI_GUID));
 | |
|       RetVal = TRUE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   FreePool (Buffer);
 | |
| 
 | |
|   return RetVal;
 | |
| }
 | |
| 
 | |
| /**
 | |
|   Search the drivers in the system which need to show in the front page
 | |
|   and insert the menu to the front page.
 | |
| 
 | |
|   @param    HiiHandle           The hii handle for the Uiapp driver.
 | |
|   @param    ClassGuid           The class guid for the driver which is the target.
 | |
|   @param    SpecialHandlerFn    The pointer to the specail handler function, if any.
 | |
|   @param    StartOpCodeHandle   The opcode handle to save the new opcode.
 | |
| 
 | |
|   @retval   EFI_SUCCESS         Search the driver success
 | |
| 
 | |
| **/
 | |
| EFI_STATUS
 | |
| BmmListThirdPartyDrivers (
 | |
|   IN EFI_HII_HANDLE              HiiHandle,
 | |
|   IN EFI_GUID                    *ClassGuid,
 | |
|   IN DRIVER_SPECIAL_HANDLER      SpecialHandlerFn,
 | |
|   IN VOID                        *StartOpCodeHandle
 | |
|   )
 | |
| {
 | |
|   UINTN                       Index;
 | |
|   EFI_STRING                  String;
 | |
|   EFI_STRING_ID               Token;
 | |
|   EFI_STRING_ID               TokenHelp;
 | |
|   EFI_HII_HANDLE              *HiiHandles;
 | |
|   CHAR16                      *DevicePathStr;
 | |
|   UINTN                       Count;
 | |
|   UINTN                       CurrentSize;
 | |
|   UI_HII_DRIVER_INSTANCE      *DriverListPtr;
 | |
|   EFI_STRING                  NewName;
 | |
|   BOOLEAN                     EmptyLineAfter;
 | |
| 
 | |
|   if (gHiiDriverList != NULL) {
 | |
|     FreePool (gHiiDriverList);
 | |
|   }
 | |
| 
 | |
|   HiiHandles = HiiGetHiiHandles (NULL);
 | |
|   ASSERT (HiiHandles != NULL);
 | |
| 
 | |
|   gHiiDriverList = AllocateZeroPool (UI_HII_DRIVER_LIST_SIZE * sizeof (UI_HII_DRIVER_INSTANCE));
 | |
|   ASSERT (gHiiDriverList != NULL);
 | |
|   DriverListPtr = gHiiDriverList;
 | |
|   CurrentSize = UI_HII_DRIVER_LIST_SIZE;
 | |
| 
 | |
|   for (Index = 0, Count = 0; HiiHandles[Index] != NULL; Index++) {
 | |
|     if (!IsRequiredDriver (HiiHandles[Index], ClassGuid, &Token, &TokenHelp, &gHiiDriverList[Count].FormSetGuid)) {
 | |
|       continue;
 | |
|     }
 | |
| 
 | |
|     String = HiiGetString (HiiHandles[Index], Token, NULL);
 | |
|     if (String == NULL) {
 | |
|       String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
 | |
|       ASSERT (String != NULL);
 | |
|     } else if (SpecialHandlerFn != NULL) {
 | |
|       //
 | |
|       // Check whether need to rename the driver name.
 | |
|       //
 | |
|       EmptyLineAfter = FALSE;
 | |
|       if (SpecialHandlerFn (String, &NewName, &EmptyLineAfter)) {
 | |
|         FreePool (String);
 | |
|         String = NewName;
 | |
|         DriverListPtr[Count].EmptyLineAfter = EmptyLineAfter;
 | |
|       }
 | |
|     }
 | |
|     DriverListPtr[Count].PromptId = HiiSetString (HiiHandle, 0, String, NULL);
 | |
|     FreePool (String);
 | |
| 
 | |
|     String = HiiGetString (HiiHandles[Index], TokenHelp, NULL);
 | |
|     if (String == NULL) {
 | |
|       String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
 | |
|       ASSERT (String != NULL);
 | |
|     }
 | |
|     DriverListPtr[Count].HelpId = HiiSetString (HiiHandle, 0, String, NULL);
 | |
|     FreePool (String);
 | |
| 
 | |
|     DevicePathStr = ExtractDevicePathFromHandle(HiiHandles[Index]);
 | |
|     if (DevicePathStr != NULL){
 | |
|       DriverListPtr[Count].DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
 | |
|       FreePool (DevicePathStr);
 | |
|     } else {
 | |
|       DriverListPtr[Count].DevicePathId = 0;
 | |
|     }
 | |
| 
 | |
|     Count++;
 | |
|     if (Count >= CurrentSize) {
 | |
|       DriverListPtr = ReallocatePool (
 | |
|                         CurrentSize * sizeof (UI_HII_DRIVER_INSTANCE),
 | |
|                         (Count + UI_HII_DRIVER_LIST_SIZE)
 | |
|                         * sizeof (UI_HII_DRIVER_INSTANCE),
 | |
|                         gHiiDriverList
 | |
|                         );
 | |
|       ASSERT (DriverListPtr != NULL);
 | |
|       gHiiDriverList = DriverListPtr;
 | |
|       CurrentSize += UI_HII_DRIVER_LIST_SIZE;
 | |
|     }
 | |
|   }
 | |
| 
 | |
|   FreePool (HiiHandles);
 | |
| 
 | |
|   Index = 0;
 | |
|   while (gHiiDriverList[Index].PromptId != 0) {
 | |
|     HiiCreateGotoExOpCode (
 | |
|       StartOpCodeHandle,
 | |
|       0,
 | |
|       gHiiDriverList[Index].PromptId,
 | |
|       gHiiDriverList[Index].HelpId,
 | |
|       0,
 | |
|       0,
 | |
|       0,
 | |
|       &gHiiDriverList[Index].FormSetGuid,
 | |
|       gHiiDriverList[Index].DevicePathId
 | |
|     );
 | |
| 
 | |
|     if (gHiiDriverList[Index].EmptyLineAfter) {
 | |
|       BmmCreateEmptyLine (HiiHandle, StartOpCodeHandle);
 | |
|     }
 | |
| 
 | |
|     Index ++;
 | |
|   }
 | |
| 
 | |
|   return EFI_SUCCESS;
 | |
| }
 | |
| 
 |