Home | History | Annotate | Download | only in BootMaintenanceManagerUiLib
      1 /** @file
      2 The functions for Boot Maintainence Main menu.
      3 
      4 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
      5 This program and the accompanying materials
      6 are licensed and made available under the terms and conditions of the BSD License
      7 which accompanies this distribution.  The full text of the license may be found at
      8 http://opensource.org/licenses/bsd-license.php
      9 
     10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
     11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
     12 
     13 **/
     14 
     15 
     16 #include "BootMaintenanceManager.h"
     17 #include "BootMaintenanceManagerCustomizedUiSupport.h"
     18 
     19 #define UI_HII_DRIVER_LIST_SIZE               0x8
     20 
     21 typedef struct {
     22   EFI_STRING_ID   PromptId;
     23   EFI_STRING_ID   HelpId;
     24   EFI_STRING_ID   DevicePathId;
     25   EFI_GUID        FormSetGuid;
     26   BOOLEAN         EmptyLineAfter;
     27 } UI_HII_DRIVER_INSTANCE;
     28 
     29 STATIC UI_HII_DRIVER_INSTANCE       *gHiiDriverList;
     30 
     31 
     32 /**
     33   Create the dynamic item to allow user to set the "BootNext" vaule.
     34 
     35   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
     36   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
     37 
     38 **/
     39 VOID
     40 BmmCreateBootNextMenu(
     41   IN EFI_HII_HANDLE              HiiHandle,
     42   IN VOID                        *StartOpCodeHandle
     43   )
     44 {
     45   BM_MENU_ENTRY   *NewMenuEntry;
     46   BM_LOAD_CONTEXT *NewLoadContext;
     47   UINT16          Index;
     48   VOID            *OptionsOpCodeHandle;
     49   UINT32          BootNextIndex;
     50 
     51   if (BootOptionMenu.MenuNumber == 0) {
     52     return;
     53   }
     54 
     55   BootNextIndex = NONE_BOOTNEXT_VALUE;
     56 
     57   OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();
     58   ASSERT (OptionsOpCodeHandle != NULL);
     59 
     60   for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
     61     NewMenuEntry    = BOpt_GetMenuEntry (&BootOptionMenu, Index);
     62     NewLoadContext  = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
     63 
     64     if (NewLoadContext->IsBootNext) {
     65       HiiCreateOneOfOptionOpCode (
     66         OptionsOpCodeHandle,
     67         NewMenuEntry->DisplayStringToken,
     68         EFI_IFR_OPTION_DEFAULT,
     69         EFI_IFR_TYPE_NUM_SIZE_32,
     70         Index
     71         );
     72       BootNextIndex = Index;
     73     } else {
     74       HiiCreateOneOfOptionOpCode (
     75         OptionsOpCodeHandle,
     76         NewMenuEntry->DisplayStringToken,
     77         0,
     78         EFI_IFR_TYPE_NUM_SIZE_32,
     79         Index
     80         );
     81     }
     82   }
     83 
     84   if (BootNextIndex == NONE_BOOTNEXT_VALUE) {
     85     HiiCreateOneOfOptionOpCode (
     86       OptionsOpCodeHandle,
     87       STRING_TOKEN (STR_NONE),
     88       EFI_IFR_OPTION_DEFAULT,
     89       EFI_IFR_TYPE_NUM_SIZE_32,
     90       NONE_BOOTNEXT_VALUE
     91       );
     92   } else {
     93     HiiCreateOneOfOptionOpCode (
     94       OptionsOpCodeHandle,
     95       STRING_TOKEN (STR_NONE),
     96       0,
     97       EFI_IFR_TYPE_NUM_SIZE_32,
     98       NONE_BOOTNEXT_VALUE
     99       );
    100   }
    101 
    102   HiiCreateOneOfOpCode (
    103     StartOpCodeHandle,
    104     (EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,
    105     VARSTORE_ID_BOOT_MAINT,
    106     BOOT_NEXT_VAR_OFFSET,
    107     STRING_TOKEN (STR_BOOT_NEXT),
    108     STRING_TOKEN (STR_BOOT_NEXT_HELP),
    109     0,
    110     EFI_IFR_NUMERIC_SIZE_4,
    111     OptionsOpCodeHandle,
    112     NULL
    113     );
    114 
    115   HiiFreeOpCodeHandle (OptionsOpCodeHandle);
    116 
    117 }
    118 
    119 /**
    120   Create Time Out Menu in the page.
    121 
    122   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
    123   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
    124 
    125 **/
    126 VOID
    127 BmmCreateTimeOutMenu (
    128   IN EFI_HII_HANDLE              HiiHandle,
    129   IN VOID                        *StartOpCodeHandle
    130   )
    131 {
    132   HiiCreateNumericOpCode (
    133     StartOpCodeHandle,
    134     (EFI_QUESTION_ID) FORM_TIME_OUT_ID,
    135     VARSTORE_ID_BOOT_MAINT,
    136     BOOT_TIME_OUT_VAR_OFFSET,
    137     STRING_TOKEN(STR_NUM_AUTO_BOOT),
    138     STRING_TOKEN(STR_HLP_AUTO_BOOT),
    139     EFI_IFR_FLAG_CALLBACK,
    140     EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,
    141     0,
    142     65535,
    143     0,
    144     NULL
    145     );
    146 }
    147 
    148 /**
    149   Create Boot Option menu in the page.
    150 
    151   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
    152   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
    153 
    154 **/
    155 VOID
    156 BmmCreateBootOptionMenu (
    157   IN EFI_HII_HANDLE              HiiHandle,
    158   IN VOID                        *StartOpCodeHandle
    159   )
    160 {
    161   HiiCreateGotoOpCode (
    162     StartOpCodeHandle,
    163     FORM_BOOT_SETUP_ID,
    164     STRING_TOKEN (STR_FORM_BOOT_SETUP_TITLE),
    165     STRING_TOKEN (STR_FORM_BOOT_SETUP_HELP),
    166     EFI_IFR_FLAG_CALLBACK,
    167     FORM_BOOT_SETUP_ID
    168     );
    169 }
    170 
    171 /**
    172   Create Driver Option menu in the page.
    173 
    174   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
    175   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
    176 
    177 **/
    178 VOID
    179 BmmCreateDriverOptionMenu (
    180   IN EFI_HII_HANDLE              HiiHandle,
    181   IN VOID                        *StartOpCodeHandle
    182   )
    183 {
    184   HiiCreateGotoOpCode (
    185     StartOpCodeHandle,
    186     FORM_DRIVER_SETUP_ID,
    187     STRING_TOKEN (STR_FORM_DRIVER_SETUP_TITLE),
    188     STRING_TOKEN (STR_FORM_DRIVER_SETUP_HELP),
    189     EFI_IFR_FLAG_CALLBACK,
    190     FORM_DRIVER_SETUP_ID
    191     );
    192 }
    193 
    194 /**
    195   Create Com Option menu in the page.
    196 
    197   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
    198   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
    199 
    200 **/
    201 VOID
    202 BmmCreateComOptionMenu (
    203   IN EFI_HII_HANDLE              HiiHandle,
    204   IN VOID                        *StartOpCodeHandle
    205   )
    206 {
    207   HiiCreateGotoOpCode (
    208     StartOpCodeHandle,
    209     FORM_CON_MAIN_ID,
    210     STRING_TOKEN (STR_FORM_CON_MAIN_TITLE),
    211     STRING_TOKEN (STR_FORM_CON_MAIN_HELP),
    212     EFI_IFR_FLAG_CALLBACK,
    213     FORM_CON_MAIN_ID
    214     );
    215 }
    216 
    217 /**
    218   Create Com Option menu in the page.
    219 
    220   @param[in]    HiiHandle           The hii handle for the Uiapp driver.
    221   @param[in]    StartOpCodeHandle   The opcode handle to save the new opcode.
    222 
    223 **/
    224 VOID
    225 BmmCreateBootFromFileMenu (
    226   IN EFI_HII_HANDLE              HiiHandle,
    227   IN VOID                        *StartOpCodeHandle
    228   )
    229 {
    230   HiiCreateGotoOpCode (
    231     StartOpCodeHandle,
    232     FORM_MAIN_ID,
    233     STRING_TOKEN (STR_BOOT_FROM_FILE),
    234     STRING_TOKEN (STR_BOOT_FROM_FILE_HELP),
    235     EFI_IFR_FLAG_CALLBACK,
    236     KEY_VALUE_BOOT_FROM_FILE
    237     );
    238 }
    239 
    240 /**
    241   Create empty line menu in the front page.
    242 
    243   @param    HiiHandle           The hii handle for the Uiapp driver.
    244   @param    StartOpCodeHandle   The opcode handle to save the new opcode.
    245 
    246 **/
    247 VOID
    248 BmmCreateEmptyLine (
    249   IN EFI_HII_HANDLE              HiiHandle,
    250   IN VOID                        *StartOpCodeHandle
    251   )
    252 {
    253   HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);
    254 }
    255 
    256 /**
    257   Extract device path for given HII handle and class guid.
    258 
    259   @param Handle          The HII handle.
    260 
    261   @retval  NULL          Fail to get the device path string.
    262   @return  PathString    Get the device path string.
    263 
    264 **/
    265 CHAR16 *
    266 ExtractDevicePathFromHandle (
    267   IN      EFI_HII_HANDLE      Handle
    268   )
    269 {
    270   EFI_STATUS                       Status;
    271   EFI_HANDLE                       DriverHandle;
    272 
    273   ASSERT (Handle != NULL);
    274 
    275   if (Handle == NULL) {
    276     return NULL;
    277   }
    278 
    279   Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
    280   if (EFI_ERROR (Status)) {
    281     return NULL;
    282   }
    283 
    284   return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);
    285 }
    286 
    287 /**
    288   Check whether this driver need to be shown in the front page.
    289 
    290   @param    HiiHandle           The hii handle for the driver.
    291   @param    Guid                The special guid for the driver which is the target.
    292   @param    PromptId            Return the prompt string id.
    293   @param    HelpId              Return the help string id.
    294   @param    FormsetGuid         Return the formset guid info.
    295 
    296   @retval   EFI_SUCCESS         Search the driver success
    297 
    298 **/
    299 BOOLEAN
    300 IsRequiredDriver (
    301   IN  EFI_HII_HANDLE              HiiHandle,
    302   IN  EFI_GUID                    *Guid,
    303   OUT EFI_STRING_ID               *PromptId,
    304   OUT EFI_STRING_ID               *HelpId,
    305   OUT VOID                        *FormsetGuid
    306   )
    307 {
    308   EFI_STATUS                  Status;
    309   UINT8                       ClassGuidNum;
    310   EFI_GUID                    *ClassGuid;
    311   EFI_IFR_FORM_SET            *Buffer;
    312   UINTN                       BufferSize;
    313   UINT8                       *Ptr;
    314   UINTN                       TempSize;
    315   BOOLEAN                     RetVal;
    316 
    317   Status = HiiGetFormSetFromHiiHandle(HiiHandle, &Buffer,&BufferSize);
    318   if (EFI_ERROR (Status)) {
    319     return FALSE;
    320   }
    321 
    322   RetVal = FALSE;
    323   TempSize = 0;
    324   Ptr = (UINT8 *) Buffer;
    325   while(TempSize < BufferSize)  {
    326     TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
    327 
    328     if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){
    329       Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
    330       continue;
    331     }
    332 
    333     ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
    334     ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
    335     while (ClassGuidNum-- > 0) {
    336       if (!CompareGuid (Guid, ClassGuid)){
    337         ClassGuid ++;
    338         continue;
    339       }
    340 
    341       *PromptId = ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle;
    342       *HelpId = ((EFI_IFR_FORM_SET *)Ptr)->Help;
    343       CopyMem (FormsetGuid, &((EFI_IFR_FORM_SET *) Ptr)->Guid, sizeof (EFI_GUID));
    344       RetVal = TRUE;
    345     }
    346   }
    347 
    348   FreePool (Buffer);
    349 
    350   return RetVal;
    351 }
    352 
    353 /**
    354   Search the drivers in the system which need to show in the front page
    355   and insert the menu to the front page.
    356 
    357   @param    HiiHandle           The hii handle for the Uiapp driver.
    358   @param    ClassGuid           The class guid for the driver which is the target.
    359   @param    SpecialHandlerFn    The pointer to the specail handler function, if any.
    360   @param    StartOpCodeHandle   The opcode handle to save the new opcode.
    361 
    362   @retval   EFI_SUCCESS         Search the driver success
    363 
    364 **/
    365 EFI_STATUS
    366 BmmListThirdPartyDrivers (
    367   IN EFI_HII_HANDLE              HiiHandle,
    368   IN EFI_GUID                    *ClassGuid,
    369   IN DRIVER_SPECIAL_HANDLER      SpecialHandlerFn,
    370   IN VOID                        *StartOpCodeHandle
    371   )
    372 {
    373   UINTN                       Index;
    374   EFI_STRING                  String;
    375   EFI_STRING_ID               Token;
    376   EFI_STRING_ID               TokenHelp;
    377   EFI_HII_HANDLE              *HiiHandles;
    378   CHAR16                      *DevicePathStr;
    379   UINTN                       Count;
    380   UINTN                       CurrentSize;
    381   UI_HII_DRIVER_INSTANCE      *DriverListPtr;
    382   EFI_STRING                  NewName;
    383   BOOLEAN                     EmptyLineAfter;
    384 
    385   if (gHiiDriverList != NULL) {
    386     FreePool (gHiiDriverList);
    387   }
    388 
    389   HiiHandles = HiiGetHiiHandles (NULL);
    390   ASSERT (HiiHandles != NULL);
    391 
    392   gHiiDriverList = AllocateZeroPool (UI_HII_DRIVER_LIST_SIZE * sizeof (UI_HII_DRIVER_INSTANCE));
    393   ASSERT (gHiiDriverList != NULL);
    394   DriverListPtr = gHiiDriverList;
    395   CurrentSize = UI_HII_DRIVER_LIST_SIZE;
    396 
    397   for (Index = 0, Count = 0; HiiHandles[Index] != NULL; Index++) {
    398     if (!IsRequiredDriver (HiiHandles[Index], ClassGuid, &Token, &TokenHelp, &gHiiDriverList[Count].FormSetGuid)) {
    399       continue;
    400     }
    401 
    402     String = HiiGetString (HiiHandles[Index], Token, NULL);
    403     if (String == NULL) {
    404       String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
    405       ASSERT (String != NULL);
    406     } else if (SpecialHandlerFn != NULL) {
    407       //
    408       // Check whether need to rename the driver name.
    409       //
    410       EmptyLineAfter = FALSE;
    411       if (SpecialHandlerFn (String, &NewName, &EmptyLineAfter)) {
    412         FreePool (String);
    413         String = NewName;
    414         DriverListPtr[Count].EmptyLineAfter = EmptyLineAfter;
    415       }
    416     }
    417     DriverListPtr[Count].PromptId = HiiSetString (HiiHandle, 0, String, NULL);
    418     FreePool (String);
    419 
    420     String = HiiGetString (HiiHandles[Index], TokenHelp, NULL);
    421     if (String == NULL) {
    422       String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
    423       ASSERT (String != NULL);
    424     }
    425     DriverListPtr[Count].HelpId = HiiSetString (HiiHandle, 0, String, NULL);
    426     FreePool (String);
    427 
    428     DevicePathStr = ExtractDevicePathFromHandle(HiiHandles[Index]);
    429     if (DevicePathStr != NULL){
    430       DriverListPtr[Count].DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
    431       FreePool (DevicePathStr);
    432     } else {
    433       DriverListPtr[Count].DevicePathId = 0;
    434     }
    435 
    436     Count++;
    437     if (Count >= CurrentSize) {
    438       DriverListPtr = AllocateCopyPool ((Count + UI_HII_DRIVER_LIST_SIZE) * sizeof (UI_HII_DRIVER_INSTANCE), gHiiDriverList);
    439       ASSERT (DriverListPtr != NULL);
    440       FreePool (gHiiDriverList);
    441       gHiiDriverList = DriverListPtr;
    442       CurrentSize += UI_HII_DRIVER_LIST_SIZE;
    443     }
    444   }
    445 
    446   FreePool (HiiHandles);
    447 
    448   Index = 0;
    449   while (gHiiDriverList[Index].PromptId != 0) {
    450     HiiCreateGotoExOpCode (
    451       StartOpCodeHandle,
    452       0,
    453       gHiiDriverList[Index].PromptId,
    454       gHiiDriverList[Index].HelpId,
    455       0,
    456       0,
    457       0,
    458       &gHiiDriverList[Index].FormSetGuid,
    459       gHiiDriverList[Index].DevicePathId
    460     );
    461 
    462     if (gHiiDriverList[Index].EmptyLineAfter) {
    463       BmmCreateEmptyLine (HiiHandle, StartOpCodeHandle);
    464     }
    465 
    466     Index ++;
    467   }
    468 
    469   return EFI_SUCCESS;
    470 }
    471 
    472