Home | History | Annotate | Download | only in UiApp
      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