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