1 /** @file 2 FrontPage routines to handle the callbacks and browser calls 3 4 Copyright (c) 2004 - 2015, 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 #include "FrontPage.h" 16 #include "Language.h" 17 #define MAX_STRING_LEN 200 18 19 EFI_GUID mFrontPageGuid = FRONT_PAGE_FORMSET_GUID; 20 21 BOOLEAN gConnectAllHappened = FALSE; 22 BOOLEAN mFeaturerSwitch = TRUE; 23 BOOLEAN mResetRequired = FALSE; 24 25 EFI_FORM_BROWSER2_PROTOCOL *gFormBrowser2; 26 CHAR8 *mLanguageString; 27 BOOLEAN mModeInitialized = FALSE; 28 // 29 // Boot video resolution and text mode. 30 // 31 UINT32 mBootHorizontalResolution = 0; 32 UINT32 mBootVerticalResolution = 0; 33 UINT32 mBootTextModeColumn = 0; 34 UINT32 mBootTextModeRow = 0; 35 // 36 // BIOS setup video resolution and text mode. 37 // 38 UINT32 mSetupTextModeColumn = 0; 39 UINT32 mSetupTextModeRow = 0; 40 UINT32 mSetupHorizontalResolution = 0; 41 UINT32 mSetupVerticalResolution = 0; 42 43 FRONT_PAGE_CALLBACK_DATA gFrontPagePrivate = { 44 FRONT_PAGE_CALLBACK_DATA_SIGNATURE, 45 NULL, 46 NULL, 47 NULL, 48 { 49 FakeExtractConfig, 50 FakeRouteConfig, 51 FrontPageCallback 52 } 53 }; 54 55 HII_VENDOR_DEVICE_PATH mFrontPageHiiVendorDevicePath = { 56 { 57 { 58 HARDWARE_DEVICE_PATH, 59 HW_VENDOR_DP, 60 { 61 (UINT8) (sizeof (VENDOR_DEVICE_PATH)), 62 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8) 63 } 64 }, 65 // 66 // {8E6D99EE-7531-48f8-8745-7F6144468FF2} 67 // 68 { 0x8e6d99ee, 0x7531, 0x48f8, { 0x87, 0x45, 0x7f, 0x61, 0x44, 0x46, 0x8f, 0xf2 } } 69 }, 70 { 71 END_DEVICE_PATH_TYPE, 72 END_ENTIRE_DEVICE_PATH_SUBTYPE, 73 { 74 (UINT8) (END_DEVICE_PATH_LENGTH), 75 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8) 76 } 77 } 78 }; 79 80 /** 81 Update the banner information for the Front Page based on Smbios information. 82 83 **/ 84 VOID 85 UpdateFrontPageStrings ( 86 VOID 87 ); 88 89 /** 90 This function allows a caller to extract the current configuration for one 91 or more named elements from the target driver. 92 93 94 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 95 @param Request A null-terminated Unicode string in <ConfigRequest> format. 96 @param Progress On return, points to a character in the Request string. 97 Points to the string's null terminator if request was successful. 98 Points to the most recent '&' before the first failing name/value 99 pair (or the beginning of the string if the failure is in the 100 first name/value pair) if the request was not successful. 101 @param Results A null-terminated Unicode string in <ConfigAltResp> format which 102 has all values filled in for the names in the Request string. 103 String to be allocated by the called function. 104 105 @retval EFI_SUCCESS The Results is filled with the requested values. 106 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results. 107 @retval EFI_INVALID_PARAMETER Request is illegal syntax, or unknown name. 108 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. 109 110 **/ 111 EFI_STATUS 112 EFIAPI 113 FakeExtractConfig ( 114 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 115 IN CONST EFI_STRING Request, 116 OUT EFI_STRING *Progress, 117 OUT EFI_STRING *Results 118 ) 119 { 120 if (Progress == NULL || Results == NULL) { 121 return EFI_INVALID_PARAMETER; 122 } 123 *Progress = Request; 124 return EFI_NOT_FOUND; 125 } 126 127 /** 128 This function processes the results of changes in configuration. 129 130 131 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 132 @param Configuration A null-terminated Unicode string in <ConfigResp> format. 133 @param Progress A pointer to a string filled in with the offset of the most 134 recent '&' before the first failing name/value pair (or the 135 beginning of the string if the failure is in the first 136 name/value pair) or the terminating NULL if all was successful. 137 138 @retval EFI_SUCCESS The Results is processed successfully. 139 @retval EFI_INVALID_PARAMETER Configuration is NULL. 140 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver. 141 142 **/ 143 EFI_STATUS 144 EFIAPI 145 FakeRouteConfig ( 146 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 147 IN CONST EFI_STRING Configuration, 148 OUT EFI_STRING *Progress 149 ) 150 { 151 if (Configuration == NULL || Progress == NULL) { 152 return EFI_INVALID_PARAMETER; 153 } 154 155 return EFI_NOT_FOUND; 156 } 157 158 /** 159 Create oneof options for language. 160 161 **/ 162 VOID 163 InitializeLanguage ( 164 VOID 165 ) 166 { 167 EFI_STATUS Status; 168 CHAR8 *LangCode; 169 CHAR8 *Lang; 170 CHAR8 *CurrentLang; 171 UINTN OptionCount; 172 CHAR16 *StringBuffer; 173 EFI_HII_HANDLE HiiHandle; 174 VOID *OptionsOpCodeHandle; 175 VOID *StartOpCodeHandle; 176 VOID *EndOpCodeHandle; 177 EFI_IFR_GUID_LABEL *StartLabel; 178 EFI_IFR_GUID_LABEL *EndLabel; 179 EFI_HII_STRING_PROTOCOL *HiiString; 180 UINTN StringSize; 181 182 Lang = NULL; 183 StringBuffer = NULL; 184 185 // 186 // Init OpCode Handle and Allocate space for creation of UpdateData Buffer 187 // 188 StartOpCodeHandle = HiiAllocateOpCodeHandle (); 189 ASSERT (StartOpCodeHandle != NULL); 190 191 EndOpCodeHandle = HiiAllocateOpCodeHandle (); 192 ASSERT (EndOpCodeHandle != NULL); 193 194 OptionsOpCodeHandle = HiiAllocateOpCodeHandle (); 195 ASSERT (OptionsOpCodeHandle != NULL); 196 // 197 // Create Hii Extend Label OpCode as the start opcode 198 // 199 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 200 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 201 StartLabel->Number = LABEL_SELECT_LANGUAGE; 202 203 // 204 // Create Hii Extend Label OpCode as the end opcode 205 // 206 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 207 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 208 EndLabel->Number = LABEL_END; 209 // 210 // Collect the languages from what our current Language support is based on our VFR 211 // 212 HiiHandle = gFrontPagePrivate.HiiHandle; 213 214 GetEfiGlobalVariable2 (L"PlatformLang", (VOID**)&CurrentLang, NULL); 215 216 if (mLanguageString == NULL) { 217 // 218 // Get Support language list from variable. 219 // 220 GetEfiGlobalVariable2 (L"PlatformLangCodes", (VOID**)&mLanguageString, NULL); 221 if (mLanguageString == NULL) { 222 mLanguageString = AllocateCopyPool ( 223 AsciiStrSize ((CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes)), 224 (CHAR8 *) PcdGetPtr (PcdUefiVariableDefaultPlatformLangCodes) 225 ); 226 ASSERT (mLanguageString != NULL); 227 } 228 } 229 230 if (gFrontPagePrivate.LanguageToken == NULL) { 231 // 232 // Count the language list number. 233 // 234 LangCode = mLanguageString; 235 Lang = AllocatePool (AsciiStrSize (mLanguageString)); 236 ASSERT (Lang != NULL); 237 OptionCount = 0; 238 while (*LangCode != 0) { 239 GetNextLanguage (&LangCode, Lang); 240 OptionCount ++; 241 } 242 243 // 244 // Allocate extra 1 as the end tag. 245 // 246 gFrontPagePrivate.LanguageToken = AllocateZeroPool ((OptionCount + 1) * sizeof (EFI_STRING_ID)); 247 ASSERT (gFrontPagePrivate.LanguageToken != NULL); 248 249 Status = gBS->LocateProtocol (&gEfiHiiStringProtocolGuid, NULL, (VOID **) &HiiString); 250 ASSERT_EFI_ERROR (Status); 251 252 LangCode = mLanguageString; 253 OptionCount = 0; 254 while (*LangCode != 0) { 255 GetNextLanguage (&LangCode, Lang); 256 257 StringSize = 0; 258 Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL); 259 if (Status == EFI_BUFFER_TOO_SMALL) { 260 StringBuffer = AllocateZeroPool (StringSize); 261 ASSERT (StringBuffer != NULL); 262 Status = HiiString->GetString (HiiString, Lang, HiiHandle, PRINTABLE_LANGUAGE_NAME_STRING_ID, StringBuffer, &StringSize, NULL); 263 ASSERT_EFI_ERROR (Status); 264 } 265 266 if (EFI_ERROR (Status)) { 267 StringBuffer = AllocatePool (AsciiStrSize (Lang) * sizeof (CHAR16)); 268 ASSERT (StringBuffer != NULL); 269 AsciiStrToUnicodeStr (Lang, StringBuffer); 270 } 271 272 ASSERT (StringBuffer != NULL); 273 gFrontPagePrivate.LanguageToken[OptionCount] = HiiSetString (HiiHandle, 0, StringBuffer, NULL); 274 FreePool (StringBuffer); 275 276 OptionCount++; 277 } 278 } 279 280 ASSERT (gFrontPagePrivate.LanguageToken != NULL); 281 LangCode = mLanguageString; 282 OptionCount = 0; 283 if (Lang == NULL) { 284 Lang = AllocatePool (AsciiStrSize (mLanguageString)); 285 ASSERT (Lang != NULL); 286 } 287 while (*LangCode != 0) { 288 GetNextLanguage (&LangCode, Lang); 289 290 if (CurrentLang != NULL && AsciiStrCmp (Lang, CurrentLang) == 0) { 291 HiiCreateOneOfOptionOpCode ( 292 OptionsOpCodeHandle, 293 gFrontPagePrivate.LanguageToken[OptionCount], 294 EFI_IFR_OPTION_DEFAULT, 295 EFI_IFR_NUMERIC_SIZE_1, 296 (UINT8) OptionCount 297 ); 298 } else { 299 HiiCreateOneOfOptionOpCode ( 300 OptionsOpCodeHandle, 301 gFrontPagePrivate.LanguageToken[OptionCount], 302 0, 303 EFI_IFR_NUMERIC_SIZE_1, 304 (UINT8) OptionCount 305 ); 306 } 307 308 OptionCount++; 309 } 310 311 if (CurrentLang != NULL) { 312 FreePool (CurrentLang); 313 } 314 FreePool (Lang); 315 316 HiiCreateOneOfOpCode ( 317 StartOpCodeHandle, 318 FRONT_PAGE_KEY_LANGUAGE, 319 0, 320 0, 321 STRING_TOKEN (STR_LANGUAGE_SELECT), 322 STRING_TOKEN (STR_LANGUAGE_SELECT_HELP), 323 EFI_IFR_FLAG_CALLBACK, 324 EFI_IFR_NUMERIC_SIZE_1, 325 OptionsOpCodeHandle, 326 NULL 327 ); 328 329 Status = HiiUpdateForm ( 330 HiiHandle, 331 &mFrontPageGuid, 332 FRONT_PAGE_FORM_ID, 333 StartOpCodeHandle, // LABEL_SELECT_LANGUAGE 334 EndOpCodeHandle // LABEL_END 335 ); 336 337 HiiFreeOpCodeHandle (StartOpCodeHandle); 338 HiiFreeOpCodeHandle (EndOpCodeHandle); 339 HiiFreeOpCodeHandle (OptionsOpCodeHandle); 340 } 341 342 /** 343 This function processes the results of changes in configuration. 344 345 346 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL. 347 @param Action Specifies the type of action taken by the browser. 348 @param QuestionId A unique value which is sent to the original exporting driver 349 so that it can identify the type of data to expect. 350 @param Type The type of value for the question. 351 @param Value A pointer to the data being sent to the original exporting driver. 352 @param ActionRequest On return, points to the action requested by the callback function. 353 354 @retval EFI_SUCCESS The callback successfully handled the action. 355 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data. 356 @retval EFI_DEVICE_ERROR The variable could not be saved. 357 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback. 358 359 **/ 360 EFI_STATUS 361 EFIAPI 362 FrontPageCallback ( 363 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This, 364 IN EFI_BROWSER_ACTION Action, 365 IN EFI_QUESTION_ID QuestionId, 366 IN UINT8 Type, 367 IN EFI_IFR_TYPE_VALUE *Value, 368 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest 369 ) 370 { 371 CHAR8 *LangCode; 372 CHAR8 *Lang; 373 UINTN Index; 374 EFI_STATUS Status; 375 376 if (Action != EFI_BROWSER_ACTION_CHANGED) { 377 // 378 // Do nothing for other UEFI Action. Only do call back when data is changed. 379 // 380 return EFI_UNSUPPORTED; 381 } 382 383 if (Action == EFI_BROWSER_ACTION_CHANGED) { 384 if ((Value == NULL) || (ActionRequest == NULL)) { 385 return EFI_INVALID_PARAMETER; 386 } 387 388 switch (QuestionId) { 389 case FRONT_PAGE_KEY_CONTINUE: 390 // 391 // This is the continue - clear the screen and return an error to get out of FrontPage loop 392 // 393 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_EXIT; 394 break; 395 396 case FRONT_PAGE_KEY_LANGUAGE: 397 // 398 // Allocate working buffer for RFC 4646 language in supported LanguageString. 399 // 400 Lang = AllocatePool (AsciiStrSize (mLanguageString)); 401 ASSERT (Lang != NULL); 402 403 Index = 0; 404 LangCode = mLanguageString; 405 while (*LangCode != 0) { 406 GetNextLanguage (&LangCode, Lang); 407 408 if (Index == Value->u8) { 409 break; 410 } 411 412 Index++; 413 } 414 415 if (Index == Value->u8) { 416 Status = gRT->SetVariable ( 417 L"PlatformLang", 418 &gEfiGlobalVariableGuid, 419 EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, 420 AsciiStrSize (Lang), 421 Lang 422 ); 423 ASSERT_EFI_ERROR(Status); 424 } else { 425 ASSERT (FALSE); 426 } 427 FreePool (Lang); 428 // 429 //Current language of platform is changed,recreate oneof options for language. 430 // 431 InitializeLanguage(); 432 break; 433 434 default: 435 break; 436 } 437 } 438 439 return EFI_SUCCESS; 440 } 441 442 /** 443 Update front page form base on the ClassGuid in the formset in other modules. 444 445 **/ 446 VOID 447 UpdateFrontPageForm ( 448 VOID 449 ) 450 { 451 EFI_STATUS Status; 452 EFI_HII_HANDLE HiiHandle; 453 VOID *StartOpCodeHandle; 454 VOID *EndOpCodeHandle; 455 EFI_IFR_GUID_LABEL *StartLabel; 456 EFI_IFR_GUID_LABEL *EndLabel; 457 UINTN Index; 458 EFI_STRING String; 459 EFI_STRING_ID Token; 460 EFI_STRING_ID TokenHelp; 461 EFI_HII_HANDLE *HiiHandles; 462 EFI_GUID FormSetGuid; 463 CHAR16 *DevicePathStr; 464 EFI_STRING_ID DevicePathId; 465 EFI_IFR_FORM_SET *Buffer; 466 UINTN BufferSize; 467 UINT8 ClassGuidNum; 468 EFI_GUID *ClassGuid; 469 UINTN TempSize; 470 UINT8 *Ptr; 471 472 TempSize =0; 473 BufferSize = 0; 474 Buffer = NULL; 475 476 HiiHandle = gFrontPagePrivate.HiiHandle; 477 478 // 479 // Allocate space for creation of UpdateData Buffer 480 // 481 StartOpCodeHandle = HiiAllocateOpCodeHandle (); 482 ASSERT (StartOpCodeHandle != NULL); 483 484 EndOpCodeHandle = HiiAllocateOpCodeHandle (); 485 ASSERT (EndOpCodeHandle != NULL); 486 // 487 // Create Hii Extend Label OpCode as the start opcode 488 // 489 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 490 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 491 StartLabel->Number = LABEL_PLATFORM_INFORMATION; 492 // 493 // Create Hii Extend Label OpCode as the end opcode 494 // 495 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL)); 496 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL; 497 EndLabel->Number = LABEL_END; 498 499 // 500 // Get all the Hii handles 501 // 502 HiiHandles = HiiGetHiiHandles (NULL); 503 ASSERT (HiiHandles != NULL); 504 // 505 // Search for formset of each class type 506 // 507 for (Index = 0; HiiHandles[Index] != NULL; Index++) { 508 Status = HiiGetFormSetFromHiiHandle(HiiHandles[Index], &Buffer,&BufferSize); 509 if (EFI_ERROR (Status)) { 510 continue; 511 } 512 513 Ptr = (UINT8 *)Buffer; 514 while(TempSize < BufferSize) { 515 TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length; 516 517 if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){ 518 Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length; 519 continue; 520 } 521 522 // 523 // Find Class Guid 524 // 525 ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3); 526 ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET)); 527 while (ClassGuidNum-- > 0) { 528 if (CompareGuid (&gEfiIfrFrontPageGuid, ClassGuid) == 0){ 529 ClassGuid ++; 530 continue; 531 } 532 533 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL); 534 if (String == NULL) { 535 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL); 536 ASSERT (String != NULL); 537 } 538 Token = HiiSetString (HiiHandle, 0, String, NULL); 539 FreePool (String); 540 541 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL); 542 543 if (String == NULL) { 544 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL); 545 ASSERT (String != NULL); 546 } 547 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL); 548 FreePool (String); 549 550 FormSetGuid = ((EFI_IFR_FORM_SET *)Ptr)->Guid; 551 552 DevicePathStr = ExtractDevicePathFromHiiHandle(HiiHandles[Index]); 553 DevicePathId = 0; 554 if (DevicePathStr != NULL){ 555 DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL); 556 FreePool (DevicePathStr); 557 } 558 HiiCreateGotoExOpCode ( 559 StartOpCodeHandle, 560 0, 561 Token, 562 TokenHelp, 563 0, 564 (EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_OFFSET), 565 0, 566 &FormSetGuid, 567 DevicePathId 568 ); 569 break; 570 } 571 Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length; 572 } 573 574 FreePool(Buffer); 575 Buffer = NULL; 576 TempSize = 0; 577 BufferSize = 0; 578 } 579 580 HiiUpdateForm ( 581 HiiHandle, 582 &mFrontPageGuid, 583 FRONT_PAGE_FORM_ID, 584 StartOpCodeHandle, 585 EndOpCodeHandle 586 ); 587 588 HiiFreeOpCodeHandle (StartOpCodeHandle); 589 HiiFreeOpCodeHandle (EndOpCodeHandle); 590 FreePool (HiiHandles); 591 } 592 593 /** 594 Initialize HII information for the FrontPage 595 596 597 @retval EFI_SUCCESS The operation is successful. 598 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed. 599 600 **/ 601 EFI_STATUS 602 InitializeFrontPage ( 603 VOID 604 ) 605 { 606 EFI_STATUS Status; 607 // 608 // Locate Hii relative protocols 609 // 610 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2); 611 if (EFI_ERROR (Status)) { 612 return Status; 613 } 614 615 // 616 // Install Device Path Protocol and Config Access protocol to driver handle 617 // 618 gFrontPagePrivate.DriverHandle = NULL; 619 Status = gBS->InstallMultipleProtocolInterfaces ( 620 &gFrontPagePrivate.DriverHandle, 621 &gEfiDevicePathProtocolGuid, 622 &mFrontPageHiiVendorDevicePath, 623 &gEfiHiiConfigAccessProtocolGuid, 624 &gFrontPagePrivate.ConfigAccess, 625 NULL 626 ); 627 ASSERT_EFI_ERROR (Status); 628 629 // 630 // Publish our HII data 631 // 632 gFrontPagePrivate.HiiHandle = HiiAddPackages ( 633 &mFrontPageGuid, 634 gFrontPagePrivate.DriverHandle, 635 FrontPageVfrBin, 636 UiAppStrings, 637 NULL 638 ); 639 ASSERT (gFrontPagePrivate.HiiHandle != NULL); 640 641 // 642 //Updata Front Page strings 643 // 644 UpdateFrontPageStrings (); 645 646 // 647 // Initialize laguage options 648 // 649 InitializeLanguage (); 650 651 // 652 //Updata Front Page form 653 // 654 UpdateFrontPageForm(); 655 656 return Status; 657 } 658 659 /** 660 Call the browser and display the front page 661 662 @return Status code that will be returned by 663 EFI_FORM_BROWSER2_PROTOCOL.SendForm (). 664 665 **/ 666 EFI_STATUS 667 CallFrontPage ( 668 VOID 669 ) 670 { 671 EFI_STATUS Status; 672 EFI_BROWSER_ACTION_REQUEST ActionRequest; 673 674 // 675 // Begin waiting for USER INPUT 676 // 677 REPORT_STATUS_CODE ( 678 EFI_PROGRESS_CODE, 679 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT) 680 ); 681 682 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE; 683 Status = gFormBrowser2->SendForm ( 684 gFormBrowser2, 685 &gFrontPagePrivate.HiiHandle, 686 1, 687 &mFrontPageGuid, 688 0, 689 NULL, 690 &ActionRequest 691 ); 692 // 693 // Check whether user change any option setting which needs a reset to be effective 694 // 695 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) { 696 EnableResetRequired (); 697 } 698 699 return Status; 700 } 701 702 /** 703 Remove the installed packages from the HiiDatabase. 704 705 **/ 706 VOID 707 FreeFrontPage( 708 VOID 709 ) 710 { 711 EFI_STATUS Status; 712 Status = gBS->UninstallMultipleProtocolInterfaces ( 713 gFrontPagePrivate.DriverHandle, 714 &gEfiDevicePathProtocolGuid, 715 &mFrontPageHiiVendorDevicePath, 716 &gEfiHiiConfigAccessProtocolGuid, 717 &gFrontPagePrivate.ConfigAccess, 718 NULL 719 ); 720 ASSERT_EFI_ERROR (Status); 721 722 // 723 // Publish our HII data 724 // 725 HiiRemovePackages (gFrontPagePrivate.HiiHandle); 726 if (gFrontPagePrivate.LanguageToken != NULL) { 727 FreePool (gFrontPagePrivate.LanguageToken); 728 gFrontPagePrivate.LanguageToken = NULL; 729 } 730 } 731 732 /** 733 Convert Processor Frequency Data to a string. 734 735 @param ProcessorFrequency The frequency data to process 736 @param Base10Exponent The exponent based on 10 737 @param String The string that is created 738 739 **/ 740 VOID 741 ConvertProcessorToString ( 742 IN UINT16 ProcessorFrequency, 743 IN UINT16 Base10Exponent, 744 OUT CHAR16 **String 745 ) 746 { 747 CHAR16 *StringBuffer; 748 UINTN Index; 749 UINTN DestMax; 750 UINT32 FreqMhz; 751 752 if (Base10Exponent >= 6) { 753 FreqMhz = ProcessorFrequency; 754 for (Index = 0; Index < (UINTN) (Base10Exponent - 6); Index++) { 755 FreqMhz *= 10; 756 } 757 } else { 758 FreqMhz = 0; 759 } 760 DestMax = 0x20 / sizeof (CHAR16); 761 StringBuffer = AllocateZeroPool (0x20); 762 ASSERT (StringBuffer != NULL); 763 Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3); 764 StrCatS (StringBuffer, DestMax, L"."); 765 UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2); 766 StrCatS (StringBuffer, DestMax, L" GHz"); 767 *String = (CHAR16 *) StringBuffer; 768 return ; 769 } 770 771 772 /** 773 Convert Memory Size to a string. 774 775 @param MemorySize The size of the memory to process 776 @param String The string that is created 777 778 **/ 779 VOID 780 ConvertMemorySizeToString ( 781 IN UINT32 MemorySize, 782 OUT CHAR16 **String 783 ) 784 { 785 CHAR16 *StringBuffer; 786 787 StringBuffer = AllocateZeroPool (0x24); 788 ASSERT (StringBuffer != NULL); 789 UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 10); 790 StrCatS (StringBuffer, 0x24 / sizeof (CHAR16), L" MB RAM"); 791 792 *String = (CHAR16 *) StringBuffer; 793 794 return ; 795 } 796 797 /** 798 799 Acquire the string associated with the Index from smbios structure and return it. 800 The caller is responsible for free the string buffer. 801 802 @param OptionalStrStart The start position to search the string 803 @param Index The index of the string to extract 804 @param String The string that is extracted 805 806 @retval EFI_SUCCESS The function returns EFI_SUCCESS always. 807 808 **/ 809 EFI_STATUS 810 GetOptionalStringByIndex ( 811 IN CHAR8 *OptionalStrStart, 812 IN UINT8 Index, 813 OUT CHAR16 **String 814 ) 815 { 816 UINTN StrSize; 817 818 if (Index == 0) { 819 *String = AllocateZeroPool (sizeof (CHAR16)); 820 return EFI_SUCCESS; 821 } 822 823 StrSize = 0; 824 do { 825 Index--; 826 OptionalStrStart += StrSize; 827 StrSize = AsciiStrSize (OptionalStrStart); 828 } while (OptionalStrStart[StrSize] != 0 && Index != 0); 829 830 if ((Index != 0) || (StrSize == 1)) { 831 // 832 // Meet the end of strings set but Index is non-zero, or 833 // Find an empty string 834 // 835 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING)); 836 } else { 837 *String = AllocatePool (StrSize * sizeof (CHAR16)); 838 AsciiStrToUnicodeStr (OptionalStrStart, *String); 839 } 840 841 return EFI_SUCCESS; 842 } 843 844 845 /** 846 Update the banner information for the Front Page based on Smbios information. 847 **/ 848 VOID 849 UpdateFrontPageStrings ( 850 VOID 851 ) 852 { 853 UINT8 StrIndex; 854 CHAR16 *NewString; 855 CHAR16 *FirmwareVersionString; 856 BOOLEAN Find[5]; 857 EFI_STATUS Status; 858 EFI_STRING_ID TokenToUpdate; 859 EFI_SMBIOS_HANDLE SmbiosHandle; 860 EFI_SMBIOS_PROTOCOL *Smbios; 861 SMBIOS_TABLE_TYPE0 *Type0Record; 862 SMBIOS_TABLE_TYPE1 *Type1Record; 863 SMBIOS_TABLE_TYPE4 *Type4Record; 864 SMBIOS_TABLE_TYPE19 *Type19Record; 865 EFI_SMBIOS_TABLE_HEADER *Record; 866 867 ZeroMem (Find, sizeof (Find)); 868 869 // 870 // Update Front Page strings 871 // 872 Status = gBS->LocateProtocol ( 873 &gEfiSmbiosProtocolGuid, 874 NULL, 875 (VOID **) &Smbios 876 ); 877 if (EFI_ERROR (Status)) { 878 return ; 879 } 880 881 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED; 882 do { 883 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL); 884 if (EFI_ERROR(Status)) { 885 break; 886 } 887 888 if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) { 889 Type0Record = (SMBIOS_TABLE_TYPE0 *) Record; 890 StrIndex = Type0Record->BiosVersion; 891 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString); 892 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION); 893 FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString); 894 if (*FirmwareVersionString != 0x0000 ) { 895 FreePool (NewString); 896 NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString); 897 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); 898 } else { 899 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); 900 FreePool (NewString); 901 } 902 Find[0] = TRUE; 903 } 904 905 if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) { 906 Type1Record = (SMBIOS_TABLE_TYPE1 *) Record; 907 StrIndex = Type1Record->ProductName; 908 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString); 909 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL); 910 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); 911 FreePool (NewString); 912 Find[1] = TRUE; 913 } 914 915 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[2]) { 916 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record; 917 // 918 // The information in the record should be only valid when the CPU Socket is populated. 919 // 920 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) { 921 StrIndex = Type4Record->ProcessorVersion; 922 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString); 923 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL); 924 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); 925 FreePool (NewString); 926 Find[2] = TRUE; 927 } 928 } 929 930 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[3]) { 931 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record; 932 // 933 // The information in the record should be only valid when the CPU Socket is populated. 934 // 935 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) { 936 ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString); 937 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED); 938 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); 939 FreePool (NewString); 940 Find[3] = TRUE; 941 } 942 } 943 944 if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) { 945 Type19Record = (SMBIOS_TABLE_TYPE19 *) Record; 946 ConvertMemorySizeToString ( 947 (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)), 948 &NewString 949 ); 950 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE); 951 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL); 952 FreePool (NewString); 953 Find[4] = TRUE; 954 } 955 } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4])); 956 return ; 957 } 958 959 /** 960 This function will change video resolution and text mode 961 according to defined setup mode or defined boot mode 962 963 @param IsSetupMode Indicate mode is changed to setup mode or boot mode. 964 965 @retval EFI_SUCCESS Mode is changed successfully. 966 @retval Others Mode failed to be changed. 967 968 **/ 969 EFI_STATUS 970 EFIAPI 971 BdsSetConsoleMode ( 972 BOOLEAN IsSetupMode 973 ) 974 { 975 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; 976 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; 977 UINTN SizeOfInfo; 978 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info; 979 UINT32 MaxGopMode; 980 UINT32 MaxTextMode; 981 UINT32 ModeNumber; 982 UINT32 NewHorizontalResolution; 983 UINT32 NewVerticalResolution; 984 UINT32 NewColumns; 985 UINT32 NewRows; 986 UINTN HandleCount; 987 EFI_HANDLE *HandleBuffer; 988 EFI_STATUS Status; 989 UINTN Index; 990 UINTN CurrentColumn; 991 UINTN CurrentRow; 992 993 MaxGopMode = 0; 994 MaxTextMode = 0; 995 996 // 997 // Get current video resolution and text mode 998 // 999 Status = gBS->HandleProtocol ( 1000 gST->ConsoleOutHandle, 1001 &gEfiGraphicsOutputProtocolGuid, 1002 (VOID**)&GraphicsOutput 1003 ); 1004 if (EFI_ERROR (Status)) { 1005 GraphicsOutput = NULL; 1006 } 1007 1008 Status = gBS->HandleProtocol ( 1009 gST->ConsoleOutHandle, 1010 &gEfiSimpleTextOutProtocolGuid, 1011 (VOID**)&SimpleTextOut 1012 ); 1013 if (EFI_ERROR (Status)) { 1014 SimpleTextOut = NULL; 1015 } 1016 1017 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) { 1018 return EFI_UNSUPPORTED; 1019 } 1020 1021 if (IsSetupMode) { 1022 // 1023 // The requried resolution and text mode is setup mode. 1024 // 1025 NewHorizontalResolution = mSetupHorizontalResolution; 1026 NewVerticalResolution = mSetupVerticalResolution; 1027 NewColumns = mSetupTextModeColumn; 1028 NewRows = mSetupTextModeRow; 1029 } else { 1030 // 1031 // The required resolution and text mode is boot mode. 1032 // 1033 NewHorizontalResolution = mBootHorizontalResolution; 1034 NewVerticalResolution = mBootVerticalResolution; 1035 NewColumns = mBootTextModeColumn; 1036 NewRows = mBootTextModeRow; 1037 } 1038 1039 if (GraphicsOutput != NULL) { 1040 MaxGopMode = GraphicsOutput->Mode->MaxMode; 1041 } 1042 1043 if (SimpleTextOut != NULL) { 1044 MaxTextMode = SimpleTextOut->Mode->MaxMode; 1045 } 1046 1047 // 1048 // 1. If current video resolution is same with required video resolution, 1049 // video resolution need not be changed. 1050 // 1.1. If current text mode is same with required text mode, text mode need not be changed. 1051 // 1.2. If current text mode is different from required text mode, text mode need be changed. 1052 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers. 1053 // 1054 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) { 1055 Status = GraphicsOutput->QueryMode ( 1056 GraphicsOutput, 1057 ModeNumber, 1058 &SizeOfInfo, 1059 &Info 1060 ); 1061 if (!EFI_ERROR (Status)) { 1062 if ((Info->HorizontalResolution == NewHorizontalResolution) && 1063 (Info->VerticalResolution == NewVerticalResolution)) { 1064 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) && 1065 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) { 1066 // 1067 // Current resolution is same with required resolution, check if text mode need be set 1068 // 1069 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow); 1070 ASSERT_EFI_ERROR (Status); 1071 if (CurrentColumn == NewColumns && CurrentRow == NewRows) { 1072 // 1073 // If current text mode is same with required text mode. Do nothing 1074 // 1075 FreePool (Info); 1076 return EFI_SUCCESS; 1077 } else { 1078 // 1079 // If current text mode is different from requried text mode. Set new video mode 1080 // 1081 for (Index = 0; Index < MaxTextMode; Index++) { 1082 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow); 1083 if (!EFI_ERROR(Status)) { 1084 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) { 1085 // 1086 // Required text mode is supported, set it. 1087 // 1088 Status = SimpleTextOut->SetMode (SimpleTextOut, Index); 1089 ASSERT_EFI_ERROR (Status); 1090 // 1091 // Update text mode PCD. 1092 // 1093 Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn); 1094 ASSERT_EFI_ERROR (Status); 1095 Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow); 1096 ASSERT_EFI_ERROR (Status); 1097 FreePool (Info); 1098 return EFI_SUCCESS; 1099 } 1100 } 1101 } 1102 if (Index == MaxTextMode) { 1103 // 1104 // If requried text mode is not supported, return error. 1105 // 1106 FreePool (Info); 1107 return EFI_UNSUPPORTED; 1108 } 1109 } 1110 } else { 1111 // 1112 // If current video resolution is not same with the new one, set new video resolution. 1113 // In this case, the driver which produces simple text out need be restarted. 1114 // 1115 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber); 1116 if (!EFI_ERROR (Status)) { 1117 FreePool (Info); 1118 break; 1119 } 1120 } 1121 } 1122 FreePool (Info); 1123 } 1124 } 1125 1126 if (ModeNumber == MaxGopMode) { 1127 // 1128 // If the resolution is not supported, return error. 1129 // 1130 return EFI_UNSUPPORTED; 1131 } 1132 1133 // 1134 // Set PCD to Inform GraphicsConsole to change video resolution. 1135 // Set PCD to Inform Consplitter to change text mode. 1136 // 1137 Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution); 1138 ASSERT_EFI_ERROR (Status); 1139 Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution); 1140 ASSERT_EFI_ERROR (Status); 1141 Status = PcdSet32S (PcdConOutColumn, NewColumns); 1142 ASSERT_EFI_ERROR (Status); 1143 Status = PcdSet32S (PcdConOutRow, NewRows); 1144 ASSERT_EFI_ERROR (Status); 1145 1146 1147 // 1148 // Video mode is changed, so restart graphics console driver and higher level driver. 1149 // Reconnect graphics console driver and higher level driver. 1150 // Locate all the handles with GOP protocol and reconnect it. 1151 // 1152 Status = gBS->LocateHandleBuffer ( 1153 ByProtocol, 1154 &gEfiSimpleTextOutProtocolGuid, 1155 NULL, 1156 &HandleCount, 1157 &HandleBuffer 1158 ); 1159 if (!EFI_ERROR (Status)) { 1160 for (Index = 0; Index < HandleCount; Index++) { 1161 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL); 1162 } 1163 for (Index = 0; Index < HandleCount; Index++) { 1164 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE); 1165 } 1166 if (HandleBuffer != NULL) { 1167 FreePool (HandleBuffer); 1168 } 1169 } 1170 1171 return EFI_SUCCESS; 1172 } 1173 1174 /** 1175 The user Entry Point for Application. The user code starts with this function 1176 as the real entry point for the image goes into a library that calls this 1177 function. 1178 1179 @param[in] ImageHandle The firmware allocated handle for the EFI image. 1180 @param[in] SystemTable A pointer to the EFI System Table. 1181 1182 @retval EFI_SUCCESS The entry point is executed successfully. 1183 @retval other Some error occurs when executing this entry point. 1184 1185 **/ 1186 EFI_STATUS 1187 EFIAPI 1188 InitializeUserInterface ( 1189 IN EFI_HANDLE ImageHandle, 1190 IN EFI_SYSTEM_TABLE *SystemTable 1191 ) 1192 { 1193 EFI_HII_HANDLE HiiHandle; 1194 EFI_STATUS Status; 1195 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput; 1196 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut; 1197 UINTN BootTextColumn; 1198 UINTN BootTextRow; 1199 1200 if (!mModeInitialized) { 1201 // 1202 // After the console is ready, get current video resolution 1203 // and text mode before launching setup at first time. 1204 // 1205 Status = gBS->HandleProtocol ( 1206 gST->ConsoleOutHandle, 1207 &gEfiGraphicsOutputProtocolGuid, 1208 (VOID**)&GraphicsOutput 1209 ); 1210 if (EFI_ERROR (Status)) { 1211 GraphicsOutput = NULL; 1212 } 1213 1214 Status = gBS->HandleProtocol ( 1215 gST->ConsoleOutHandle, 1216 &gEfiSimpleTextOutProtocolGuid, 1217 (VOID**)&SimpleTextOut 1218 ); 1219 if (EFI_ERROR (Status)) { 1220 SimpleTextOut = NULL; 1221 } 1222 1223 if (GraphicsOutput != NULL) { 1224 // 1225 // Get current video resolution and text mode. 1226 // 1227 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution; 1228 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution; 1229 } 1230 1231 if (SimpleTextOut != NULL) { 1232 Status = SimpleTextOut->QueryMode ( 1233 SimpleTextOut, 1234 SimpleTextOut->Mode->Mode, 1235 &BootTextColumn, 1236 &BootTextRow 1237 ); 1238 mBootTextModeColumn = (UINT32)BootTextColumn; 1239 mBootTextModeRow = (UINT32)BootTextRow; 1240 } 1241 1242 // 1243 // Get user defined text mode for setup. 1244 // 1245 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution); 1246 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution); 1247 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn); 1248 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow); 1249 1250 mModeInitialized = TRUE; 1251 } 1252 1253 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL); 1254 gST->ConOut->ClearScreen (gST->ConOut); 1255 1256 // 1257 // Install customized fonts needed by Front Page 1258 // 1259 1260 HiiHandle = ExportFonts (); 1261 ASSERT (HiiHandle != NULL); 1262 1263 InitializeStringSupport (); 1264 1265 BdsSetConsoleMode (TRUE); 1266 UiEntry (FALSE); 1267 BdsSetConsoleMode (FALSE); 1268 1269 UninitializeStringSupport (); 1270 HiiRemovePackages (HiiHandle); 1271 1272 return EFI_SUCCESS; 1273 } 1274 1275 /** 1276 This function is the main entry of the UI entry. 1277 The function will present the main menu of the system UI. 1278 1279 @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all. 1280 1281 **/ 1282 VOID 1283 EFIAPI 1284 UiEntry ( 1285 IN BOOLEAN ConnectAllHappened 1286 ) 1287 { 1288 EFI_STATUS Status; 1289 EFI_BOOT_LOGO_PROTOCOL *BootLogo; 1290 1291 // 1292 // Indicate if the connect all has been performed before. 1293 // 1294 if (ConnectAllHappened) { 1295 gConnectAllHappened = TRUE; 1296 } 1297 1298 // 1299 // The boot option enumeration time is acceptable in Ui driver 1300 // 1301 EfiBootManagerRefreshAllBootOption (); 1302 1303 // 1304 // Boot Logo is corrupted, report it using Boot Logo protocol. 1305 // 1306 Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo); 1307 if (!EFI_ERROR (Status) && (BootLogo != NULL)) { 1308 BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0); 1309 } 1310 1311 InitializeFrontPage (); 1312 1313 CallFrontPage (); 1314 1315 FreeFrontPage (); 1316 1317 if (mLanguageString != NULL) { 1318 FreePool (mLanguageString); 1319 mLanguageString = NULL; 1320 } 1321 1322 // 1323 //Will leave browser, check any reset required change is applied? if yes, reset system 1324 // 1325 SetupResetReminder (); 1326 } 1327 1328 /** 1329 Extract device path for given HII handle and class guid. 1330 1331 @param Handle The HII handle. 1332 1333 @retval NULL Fail to get the device path string. 1334 @return PathString Get the device path string. 1335 1336 **/ 1337 CHAR16 * 1338 ExtractDevicePathFromHiiHandle ( 1339 IN EFI_HII_HANDLE Handle 1340 ) 1341 { 1342 EFI_STATUS Status; 1343 EFI_HANDLE DriverHandle; 1344 1345 ASSERT (Handle != NULL); 1346 1347 if (Handle == NULL) { 1348 return NULL; 1349 } 1350 1351 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle); 1352 if (EFI_ERROR (Status)) { 1353 return NULL; 1354 } 1355 1356 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE); 1357 1358 } 1359 1360 // 1361 // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature. 1362 // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if 1363 // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection. 1364 // 1365 1366 1367 /** 1368 Enable the setup browser reset reminder feature. 1369 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it. 1370 1371 **/ 1372 VOID 1373 EFIAPI 1374 EnableResetReminderFeature ( 1375 VOID 1376 ) 1377 { 1378 mFeaturerSwitch = TRUE; 1379 } 1380 1381 1382 /** 1383 Disable the setup browser reset reminder feature. 1384 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it. 1385 1386 **/ 1387 VOID 1388 EFIAPI 1389 DisableResetReminderFeature ( 1390 VOID 1391 ) 1392 { 1393 mFeaturerSwitch = FALSE; 1394 } 1395 1396 1397 /** 1398 Record the info that a reset is required. 1399 A module boolean variable is used to record whether a reset is required. 1400 1401 **/ 1402 VOID 1403 EFIAPI 1404 EnableResetRequired ( 1405 VOID 1406 ) 1407 { 1408 mResetRequired = TRUE; 1409 } 1410 1411 1412 /** 1413 Record the info that no reset is required. 1414 A module boolean variable is used to record whether a reset is required. 1415 1416 **/ 1417 VOID 1418 EFIAPI 1419 DisableResetRequired ( 1420 VOID 1421 ) 1422 { 1423 mResetRequired = FALSE; 1424 } 1425 1426 1427 /** 1428 Check whether platform policy enable the reset reminder feature. The default is enabled. 1429 1430 **/ 1431 BOOLEAN 1432 EFIAPI 1433 IsResetReminderFeatureEnable ( 1434 VOID 1435 ) 1436 { 1437 return mFeaturerSwitch; 1438 } 1439 1440 1441 /** 1442 Check if user changed any option setting which needs a system reset to be effective. 1443 1444 **/ 1445 BOOLEAN 1446 EFIAPI 1447 IsResetRequired ( 1448 VOID 1449 ) 1450 { 1451 return mResetRequired; 1452 } 1453 1454 1455 /** 1456 Check whether a reset is needed, and finish the reset reminder feature. 1457 If a reset is needed, Popup a menu to notice user, and finish the feature 1458 according to the user selection. 1459 1460 **/ 1461 VOID 1462 EFIAPI 1463 SetupResetReminder ( 1464 VOID 1465 ) 1466 { 1467 EFI_INPUT_KEY Key; 1468 CHAR16 *StringBuffer1; 1469 CHAR16 *StringBuffer2; 1470 1471 1472 // 1473 //check any reset required change is applied? if yes, reset system 1474 // 1475 if (IsResetReminderFeatureEnable ()) { 1476 if (IsResetRequired ()) { 1477 1478 StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); 1479 ASSERT (StringBuffer1 != NULL); 1480 StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16)); 1481 ASSERT (StringBuffer2 != NULL); 1482 StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now."); 1483 StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset"); 1484 // 1485 // Popup a menu to notice user 1486 // 1487 do { 1488 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL); 1489 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN); 1490 1491 FreePool (StringBuffer1); 1492 FreePool (StringBuffer2); 1493 1494 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL); 1495 } 1496 } 1497 } 1498 1499