]> git.proxmox.com Git - mirror_edk2.git/blob - MdeModulePkg/Application/UiApp/FrontPage.c
MdeModulePkg: Refine the UI code
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / FrontPage.c
1 /** @file
2 FrontPage routines to handle the callbacks and browser calls
3
4 Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
9
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13 **/
14
15 #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 if (EFI_ERROR (Status)) {
424 FreePool (Lang);
425 return EFI_DEVICE_ERROR;
426 }
427 } else {
428 ASSERT (FALSE);
429 }
430 FreePool (Lang);
431 //
432 //Current language of platform is changed,recreate oneof options for language.
433 //
434 InitializeLanguage();
435 break;
436
437 default:
438 break;
439 }
440 }
441
442 return EFI_SUCCESS;
443 }
444
445 /**
446 Update front page form base on the ClassGuid in the formset in other modules.
447
448 **/
449 VOID
450 UpdateFrontPageForm (
451 VOID
452 )
453 {
454 EFI_STATUS Status;
455 EFI_HII_HANDLE HiiHandle;
456 VOID *StartOpCodeHandle;
457 VOID *EndOpCodeHandle;
458 EFI_IFR_GUID_LABEL *StartLabel;
459 EFI_IFR_GUID_LABEL *EndLabel;
460 UINTN Index;
461 EFI_STRING String;
462 EFI_STRING_ID Token;
463 EFI_STRING_ID TokenHelp;
464 EFI_HII_HANDLE *HiiHandles;
465 EFI_GUID FormSetGuid;
466 CHAR16 *DevicePathStr;
467 EFI_STRING_ID DevicePathId;
468 EFI_IFR_FORM_SET *Buffer;
469 UINTN BufferSize;
470 UINT8 ClassGuidNum;
471 EFI_GUID *ClassGuid;
472 UINTN TempSize;
473 UINT8 *Ptr;
474
475 TempSize =0;
476 BufferSize = 0;
477 Buffer = NULL;
478
479 HiiHandle = gFrontPagePrivate.HiiHandle;
480
481 //
482 // Allocate space for creation of UpdateData Buffer
483 //
484 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
485 ASSERT (StartOpCodeHandle != NULL);
486
487 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
488 ASSERT (EndOpCodeHandle != NULL);
489 //
490 // Create Hii Extend Label OpCode as the start opcode
491 //
492 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
493 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
494 StartLabel->Number = LABEL_PLATFORM_INFORMATION;
495 //
496 // Create Hii Extend Label OpCode as the end opcode
497 //
498 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
499 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
500 EndLabel->Number = LABEL_END;
501
502 //
503 // Get all the Hii handles
504 //
505 HiiHandles = HiiGetHiiHandles (NULL);
506 ASSERT (HiiHandles != NULL);
507 //
508 // Search for formset of each class type
509 //
510 for (Index = 0; HiiHandles[Index] != NULL; Index++) {
511 Status = HiiGetFormSetFromHiiHandle(HiiHandles[Index], &Buffer,&BufferSize);
512 if (EFI_ERROR (Status)) {
513 continue;
514 }
515
516 Ptr = (UINT8 *)Buffer;
517 while(TempSize < BufferSize) {
518 TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
519
520 if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){
521 Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
522 continue;
523 }
524
525 //
526 // Find Class Guid
527 //
528 ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);
529 ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));
530 while (ClassGuidNum-- > 0) {
531 if (CompareGuid (&gEfiIfrFrontPageGuid, ClassGuid) == 0){
532 ClassGuid ++;
533 continue;
534 }
535
536 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle, NULL);
537 if (String == NULL) {
538 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
539 ASSERT (String != NULL);
540 }
541 Token = HiiSetString (HiiHandle, 0, String, NULL);
542 FreePool (String);
543
544 String = HiiGetString (HiiHandles[Index], ((EFI_IFR_FORM_SET *)Ptr)->Help, NULL);
545
546 if (String == NULL) {
547 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);
548 ASSERT (String != NULL);
549 }
550 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);
551 FreePool (String);
552
553 FormSetGuid = ((EFI_IFR_FORM_SET *)Ptr)->Guid;
554
555 DevicePathStr = ExtractDevicePathFromHiiHandle(HiiHandles[Index]);
556 DevicePathId = 0;
557 if (DevicePathStr != NULL){
558 DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);
559 FreePool (DevicePathStr);
560 }
561 HiiCreateGotoExOpCode (
562 StartOpCodeHandle,
563 0,
564 Token,
565 TokenHelp,
566 0,
567 (EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_OFFSET),
568 0,
569 &FormSetGuid,
570 DevicePathId
571 );
572 break;
573 }
574 Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;
575 }
576
577 FreePool(Buffer);
578 Buffer = NULL;
579 TempSize = 0;
580 BufferSize = 0;
581 }
582
583 HiiUpdateForm (
584 HiiHandle,
585 &mFrontPageGuid,
586 FRONT_PAGE_FORM_ID,
587 StartOpCodeHandle,
588 EndOpCodeHandle
589 );
590
591 HiiFreeOpCodeHandle (StartOpCodeHandle);
592 HiiFreeOpCodeHandle (EndOpCodeHandle);
593 FreePool (HiiHandles);
594 }
595
596 /**
597 Initialize HII information for the FrontPage
598
599
600 @retval EFI_SUCCESS The operation is successful.
601 @retval EFI_DEVICE_ERROR If the dynamic opcode creation failed.
602
603 **/
604 EFI_STATUS
605 InitializeFrontPage (
606 VOID
607 )
608 {
609 EFI_STATUS Status;
610 //
611 // Locate Hii relative protocols
612 //
613 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &gFormBrowser2);
614 if (EFI_ERROR (Status)) {
615 return Status;
616 }
617
618 //
619 // Install Device Path Protocol and Config Access protocol to driver handle
620 //
621 gFrontPagePrivate.DriverHandle = NULL;
622 Status = gBS->InstallMultipleProtocolInterfaces (
623 &gFrontPagePrivate.DriverHandle,
624 &gEfiDevicePathProtocolGuid,
625 &mFrontPageHiiVendorDevicePath,
626 &gEfiHiiConfigAccessProtocolGuid,
627 &gFrontPagePrivate.ConfigAccess,
628 NULL
629 );
630 ASSERT_EFI_ERROR (Status);
631
632 //
633 // Publish our HII data
634 //
635 gFrontPagePrivate.HiiHandle = HiiAddPackages (
636 &mFrontPageGuid,
637 gFrontPagePrivate.DriverHandle,
638 FrontPageVfrBin,
639 UiAppStrings,
640 NULL
641 );
642 ASSERT (gFrontPagePrivate.HiiHandle != NULL);
643
644 //
645 //Updata Front Page strings
646 //
647 UpdateFrontPageStrings ();
648
649 //
650 // Initialize laguage options
651 //
652 InitializeLanguage ();
653
654 //
655 //Updata Front Page form
656 //
657 UpdateFrontPageForm();
658
659 return Status;
660 }
661
662 /**
663 Call the browser and display the front page
664
665 @return Status code that will be returned by
666 EFI_FORM_BROWSER2_PROTOCOL.SendForm ().
667
668 **/
669 EFI_STATUS
670 CallFrontPage (
671 VOID
672 )
673 {
674 EFI_STATUS Status;
675 EFI_BROWSER_ACTION_REQUEST ActionRequest;
676
677 //
678 // Begin waiting for USER INPUT
679 //
680 REPORT_STATUS_CODE (
681 EFI_PROGRESS_CODE,
682 (EFI_SOFTWARE_DXE_BS_DRIVER | EFI_SW_PC_INPUT_WAIT)
683 );
684
685 ActionRequest = EFI_BROWSER_ACTION_REQUEST_NONE;
686 Status = gFormBrowser2->SendForm (
687 gFormBrowser2,
688 &gFrontPagePrivate.HiiHandle,
689 1,
690 &mFrontPageGuid,
691 0,
692 NULL,
693 &ActionRequest
694 );
695 //
696 // Check whether user change any option setting which needs a reset to be effective
697 //
698 if (ActionRequest == EFI_BROWSER_ACTION_REQUEST_RESET) {
699 EnableResetRequired ();
700 }
701
702 return Status;
703 }
704
705 /**
706 Remove the installed packages from the HiiDatabase.
707
708 **/
709 VOID
710 FreeFrontPage(
711 VOID
712 )
713 {
714 EFI_STATUS Status;
715 Status = gBS->UninstallMultipleProtocolInterfaces (
716 gFrontPagePrivate.DriverHandle,
717 &gEfiDevicePathProtocolGuid,
718 &mFrontPageHiiVendorDevicePath,
719 &gEfiHiiConfigAccessProtocolGuid,
720 &gFrontPagePrivate.ConfigAccess,
721 NULL
722 );
723 ASSERT_EFI_ERROR (Status);
724
725 //
726 // Publish our HII data
727 //
728 HiiRemovePackages (gFrontPagePrivate.HiiHandle);
729 if (gFrontPagePrivate.LanguageToken != NULL) {
730 FreePool (gFrontPagePrivate.LanguageToken);
731 gFrontPagePrivate.LanguageToken = NULL;
732 }
733 }
734
735 /**
736 Convert Processor Frequency Data to a string.
737
738 @param ProcessorFrequency The frequency data to process
739 @param Base10Exponent The exponent based on 10
740 @param String The string that is created
741
742 **/
743 VOID
744 ConvertProcessorToString (
745 IN UINT16 ProcessorFrequency,
746 IN UINT16 Base10Exponent,
747 OUT CHAR16 **String
748 )
749 {
750 CHAR16 *StringBuffer;
751 UINTN Index;
752 UINTN DestMax;
753 UINT32 FreqMhz;
754
755 if (Base10Exponent >= 6) {
756 FreqMhz = ProcessorFrequency;
757 for (Index = 0; Index < (UINTN) (Base10Exponent - 6); Index++) {
758 FreqMhz *= 10;
759 }
760 } else {
761 FreqMhz = 0;
762 }
763 DestMax = 0x20 / sizeof (CHAR16);
764 StringBuffer = AllocateZeroPool (0x20);
765 ASSERT (StringBuffer != NULL);
766 Index = UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, FreqMhz / 1000, 3);
767 StrCatS (StringBuffer, DestMax, L".");
768 UnicodeValueToString (StringBuffer + Index + 1, PREFIX_ZERO, (FreqMhz % 1000) / 10, 2);
769 StrCatS (StringBuffer, DestMax, L" GHz");
770 *String = (CHAR16 *) StringBuffer;
771 return ;
772 }
773
774
775 /**
776 Convert Memory Size to a string.
777
778 @param MemorySize The size of the memory to process
779 @param String The string that is created
780
781 **/
782 VOID
783 ConvertMemorySizeToString (
784 IN UINT32 MemorySize,
785 OUT CHAR16 **String
786 )
787 {
788 CHAR16 *StringBuffer;
789
790 StringBuffer = AllocateZeroPool (0x24);
791 ASSERT (StringBuffer != NULL);
792 UnicodeValueToString (StringBuffer, LEFT_JUSTIFY, MemorySize, 10);
793 StrCatS (StringBuffer, 0x24 / sizeof (CHAR16), L" MB RAM");
794
795 *String = (CHAR16 *) StringBuffer;
796
797 return ;
798 }
799
800 /**
801
802 Acquire the string associated with the Index from smbios structure and return it.
803 The caller is responsible for free the string buffer.
804
805 @param OptionalStrStart The start position to search the string
806 @param Index The index of the string to extract
807 @param String The string that is extracted
808
809 @retval EFI_SUCCESS The function returns EFI_SUCCESS always.
810
811 **/
812 EFI_STATUS
813 GetOptionalStringByIndex (
814 IN CHAR8 *OptionalStrStart,
815 IN UINT8 Index,
816 OUT CHAR16 **String
817 )
818 {
819 UINTN StrSize;
820
821 if (Index == 0) {
822 *String = AllocateZeroPool (sizeof (CHAR16));
823 return EFI_SUCCESS;
824 }
825
826 StrSize = 0;
827 do {
828 Index--;
829 OptionalStrStart += StrSize;
830 StrSize = AsciiStrSize (OptionalStrStart);
831 } while (OptionalStrStart[StrSize] != 0 && Index != 0);
832
833 if ((Index != 0) || (StrSize == 1)) {
834 //
835 // Meet the end of strings set but Index is non-zero, or
836 // Find an empty string
837 //
838 *String = GetStringById (STRING_TOKEN (STR_MISSING_STRING));
839 } else {
840 *String = AllocatePool (StrSize * sizeof (CHAR16));
841 AsciiStrToUnicodeStr (OptionalStrStart, *String);
842 }
843
844 return EFI_SUCCESS;
845 }
846
847
848 /**
849 Update the banner information for the Front Page based on Smbios information.
850 **/
851 VOID
852 UpdateFrontPageStrings (
853 VOID
854 )
855 {
856 UINT8 StrIndex;
857 CHAR16 *NewString;
858 CHAR16 *FirmwareVersionString;
859 BOOLEAN Find[5];
860 EFI_STATUS Status;
861 EFI_STRING_ID TokenToUpdate;
862 EFI_SMBIOS_HANDLE SmbiosHandle;
863 EFI_SMBIOS_PROTOCOL *Smbios;
864 SMBIOS_TABLE_TYPE0 *Type0Record;
865 SMBIOS_TABLE_TYPE1 *Type1Record;
866 SMBIOS_TABLE_TYPE4 *Type4Record;
867 SMBIOS_TABLE_TYPE19 *Type19Record;
868 EFI_SMBIOS_TABLE_HEADER *Record;
869
870 ZeroMem (Find, sizeof (Find));
871
872 //
873 // Update Front Page strings
874 //
875 Status = gBS->LocateProtocol (
876 &gEfiSmbiosProtocolGuid,
877 NULL,
878 (VOID **) &Smbios
879 );
880 if (EFI_ERROR (Status)) {
881 return ;
882 }
883
884 SmbiosHandle = SMBIOS_HANDLE_PI_RESERVED;
885 do {
886 Status = Smbios->GetNext (Smbios, &SmbiosHandle, NULL, &Record, NULL);
887 if (EFI_ERROR(Status)) {
888 break;
889 }
890
891 if (Record->Type == EFI_SMBIOS_TYPE_BIOS_INFORMATION) {
892 Type0Record = (SMBIOS_TABLE_TYPE0 *) Record;
893 StrIndex = Type0Record->BiosVersion;
894 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type0Record + Type0Record->Hdr.Length), StrIndex, &NewString);
895 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_BIOS_VERSION);
896 FirmwareVersionString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
897 if (*FirmwareVersionString != 0x0000 ) {
898 FreePool (NewString);
899 NewString = (CHAR16 *) PcdGetPtr (PcdFirmwareVersionString);
900 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);
901 } else {
902 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);
903 FreePool (NewString);
904 }
905 Find[0] = TRUE;
906 }
907
908 if (Record->Type == EFI_SMBIOS_TYPE_SYSTEM_INFORMATION) {
909 Type1Record = (SMBIOS_TABLE_TYPE1 *) Record;
910 StrIndex = Type1Record->ProductName;
911 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type1Record + Type1Record->Hdr.Length), StrIndex, &NewString);
912 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_COMPUTER_MODEL);
913 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);
914 FreePool (NewString);
915 Find[1] = TRUE;
916 }
917
918 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[2]) {
919 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;
920 //
921 // The information in the record should be only valid when the CPU Socket is populated.
922 //
923 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {
924 StrIndex = Type4Record->ProcessorVersion;
925 GetOptionalStringByIndex ((CHAR8*)((UINT8*)Type4Record + Type4Record->Hdr.Length), StrIndex, &NewString);
926 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_MODEL);
927 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);
928 FreePool (NewString);
929 Find[2] = TRUE;
930 }
931 }
932
933 if ((Record->Type == EFI_SMBIOS_TYPE_PROCESSOR_INFORMATION) && !Find[3]) {
934 Type4Record = (SMBIOS_TABLE_TYPE4 *) Record;
935 //
936 // The information in the record should be only valid when the CPU Socket is populated.
937 //
938 if ((Type4Record->Status & SMBIOS_TYPE4_CPU_SOCKET_POPULATED) == SMBIOS_TYPE4_CPU_SOCKET_POPULATED) {
939 ConvertProcessorToString(Type4Record->CurrentSpeed, 6, &NewString);
940 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_CPU_SPEED);
941 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);
942 FreePool (NewString);
943 Find[3] = TRUE;
944 }
945 }
946
947 if ( Record->Type == EFI_SMBIOS_TYPE_MEMORY_ARRAY_MAPPED_ADDRESS ) {
948 Type19Record = (SMBIOS_TABLE_TYPE19 *) Record;
949 ConvertMemorySizeToString (
950 (UINT32)(RShiftU64((Type19Record->EndingAddress - Type19Record->StartingAddress + 1), 10)),
951 &NewString
952 );
953 TokenToUpdate = STRING_TOKEN (STR_FRONT_PAGE_MEMORY_SIZE);
954 HiiSetString (gFrontPagePrivate.HiiHandle, TokenToUpdate, NewString, NULL);
955 FreePool (NewString);
956 Find[4] = TRUE;
957 }
958 } while ( !(Find[0] && Find[1] && Find[2] && Find[3] && Find[4]));
959 return ;
960 }
961
962 /**
963 This function will change video resolution and text mode
964 according to defined setup mode or defined boot mode
965
966 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
967
968 @retval EFI_SUCCESS Mode is changed successfully.
969 @retval Others Mode failed to be changed.
970
971 **/
972 EFI_STATUS
973 EFIAPI
974 BdsSetConsoleMode (
975 BOOLEAN IsSetupMode
976 )
977 {
978 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
979 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
980 UINTN SizeOfInfo;
981 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
982 UINT32 MaxGopMode;
983 UINT32 MaxTextMode;
984 UINT32 ModeNumber;
985 UINT32 NewHorizontalResolution;
986 UINT32 NewVerticalResolution;
987 UINT32 NewColumns;
988 UINT32 NewRows;
989 UINTN HandleCount;
990 EFI_HANDLE *HandleBuffer;
991 EFI_STATUS Status;
992 UINTN Index;
993 UINTN CurrentColumn;
994 UINTN CurrentRow;
995
996 MaxGopMode = 0;
997 MaxTextMode = 0;
998
999 //
1000 // Get current video resolution and text mode
1001 //
1002 Status = gBS->HandleProtocol (
1003 gST->ConsoleOutHandle,
1004 &gEfiGraphicsOutputProtocolGuid,
1005 (VOID**)&GraphicsOutput
1006 );
1007 if (EFI_ERROR (Status)) {
1008 GraphicsOutput = NULL;
1009 }
1010
1011 Status = gBS->HandleProtocol (
1012 gST->ConsoleOutHandle,
1013 &gEfiSimpleTextOutProtocolGuid,
1014 (VOID**)&SimpleTextOut
1015 );
1016 if (EFI_ERROR (Status)) {
1017 SimpleTextOut = NULL;
1018 }
1019
1020 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
1021 return EFI_UNSUPPORTED;
1022 }
1023
1024 if (IsSetupMode) {
1025 //
1026 // The requried resolution and text mode is setup mode.
1027 //
1028 NewHorizontalResolution = mSetupHorizontalResolution;
1029 NewVerticalResolution = mSetupVerticalResolution;
1030 NewColumns = mSetupTextModeColumn;
1031 NewRows = mSetupTextModeRow;
1032 } else {
1033 //
1034 // The required resolution and text mode is boot mode.
1035 //
1036 NewHorizontalResolution = mBootHorizontalResolution;
1037 NewVerticalResolution = mBootVerticalResolution;
1038 NewColumns = mBootTextModeColumn;
1039 NewRows = mBootTextModeRow;
1040 }
1041
1042 if (GraphicsOutput != NULL) {
1043 MaxGopMode = GraphicsOutput->Mode->MaxMode;
1044 }
1045
1046 if (SimpleTextOut != NULL) {
1047 MaxTextMode = SimpleTextOut->Mode->MaxMode;
1048 }
1049
1050 //
1051 // 1. If current video resolution is same with required video resolution,
1052 // video resolution need not be changed.
1053 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
1054 // 1.2. If current text mode is different from required text mode, text mode need be changed.
1055 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
1056 //
1057 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
1058 Status = GraphicsOutput->QueryMode (
1059 GraphicsOutput,
1060 ModeNumber,
1061 &SizeOfInfo,
1062 &Info
1063 );
1064 if (!EFI_ERROR (Status)) {
1065 if ((Info->HorizontalResolution == NewHorizontalResolution) &&
1066 (Info->VerticalResolution == NewVerticalResolution)) {
1067 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
1068 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {
1069 //
1070 // Current resolution is same with required resolution, check if text mode need be set
1071 //
1072 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
1073 ASSERT_EFI_ERROR (Status);
1074 if (CurrentColumn == NewColumns && CurrentRow == NewRows) {
1075 //
1076 // If current text mode is same with required text mode. Do nothing
1077 //
1078 FreePool (Info);
1079 return EFI_SUCCESS;
1080 } else {
1081 //
1082 // If current text mode is different from requried text mode. Set new video mode
1083 //
1084 for (Index = 0; Index < MaxTextMode; Index++) {
1085 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
1086 if (!EFI_ERROR(Status)) {
1087 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
1088 //
1089 // Required text mode is supported, set it.
1090 //
1091 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
1092 ASSERT_EFI_ERROR (Status);
1093 //
1094 // Update text mode PCD.
1095 //
1096 Status = PcdSet32S (PcdConOutColumn, mSetupTextModeColumn);
1097 ASSERT_EFI_ERROR (Status);
1098 Status = PcdSet32S (PcdConOutRow, mSetupTextModeRow);
1099 ASSERT_EFI_ERROR (Status);
1100 FreePool (Info);
1101 return EFI_SUCCESS;
1102 }
1103 }
1104 }
1105 if (Index == MaxTextMode) {
1106 //
1107 // If requried text mode is not supported, return error.
1108 //
1109 FreePool (Info);
1110 return EFI_UNSUPPORTED;
1111 }
1112 }
1113 } else {
1114 //
1115 // If current video resolution is not same with the new one, set new video resolution.
1116 // In this case, the driver which produces simple text out need be restarted.
1117 //
1118 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
1119 if (!EFI_ERROR (Status)) {
1120 FreePool (Info);
1121 break;
1122 }
1123 }
1124 }
1125 FreePool (Info);
1126 }
1127 }
1128
1129 if (ModeNumber == MaxGopMode) {
1130 //
1131 // If the resolution is not supported, return error.
1132 //
1133 return EFI_UNSUPPORTED;
1134 }
1135
1136 //
1137 // Set PCD to Inform GraphicsConsole to change video resolution.
1138 // Set PCD to Inform Consplitter to change text mode.
1139 //
1140 Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
1141 ASSERT_EFI_ERROR (Status);
1142 Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
1143 ASSERT_EFI_ERROR (Status);
1144 Status = PcdSet32S (PcdConOutColumn, NewColumns);
1145 ASSERT_EFI_ERROR (Status);
1146 Status = PcdSet32S (PcdConOutRow, NewRows);
1147 ASSERT_EFI_ERROR (Status);
1148
1149
1150 //
1151 // Video mode is changed, so restart graphics console driver and higher level driver.
1152 // Reconnect graphics console driver and higher level driver.
1153 // Locate all the handles with GOP protocol and reconnect it.
1154 //
1155 Status = gBS->LocateHandleBuffer (
1156 ByProtocol,
1157 &gEfiSimpleTextOutProtocolGuid,
1158 NULL,
1159 &HandleCount,
1160 &HandleBuffer
1161 );
1162 if (!EFI_ERROR (Status)) {
1163 for (Index = 0; Index < HandleCount; Index++) {
1164 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
1165 }
1166 for (Index = 0; Index < HandleCount; Index++) {
1167 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
1168 }
1169 if (HandleBuffer != NULL) {
1170 FreePool (HandleBuffer);
1171 }
1172 }
1173
1174 return EFI_SUCCESS;
1175 }
1176
1177 /**
1178 The user Entry Point for Application. The user code starts with this function
1179 as the real entry point for the image goes into a library that calls this
1180 function.
1181
1182 @param[in] ImageHandle The firmware allocated handle for the EFI image.
1183 @param[in] SystemTable A pointer to the EFI System Table.
1184
1185 @retval EFI_SUCCESS The entry point is executed successfully.
1186 @retval other Some error occurs when executing this entry point.
1187
1188 **/
1189 EFI_STATUS
1190 EFIAPI
1191 InitializeUserInterface (
1192 IN EFI_HANDLE ImageHandle,
1193 IN EFI_SYSTEM_TABLE *SystemTable
1194 )
1195 {
1196 EFI_HII_HANDLE HiiHandle;
1197 EFI_STATUS Status;
1198 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1199 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
1200 UINTN BootTextColumn;
1201 UINTN BootTextRow;
1202
1203 if (!mModeInitialized) {
1204 //
1205 // After the console is ready, get current video resolution
1206 // and text mode before launching setup at first time.
1207 //
1208 Status = gBS->HandleProtocol (
1209 gST->ConsoleOutHandle,
1210 &gEfiGraphicsOutputProtocolGuid,
1211 (VOID**)&GraphicsOutput
1212 );
1213 if (EFI_ERROR (Status)) {
1214 GraphicsOutput = NULL;
1215 }
1216
1217 Status = gBS->HandleProtocol (
1218 gST->ConsoleOutHandle,
1219 &gEfiSimpleTextOutProtocolGuid,
1220 (VOID**)&SimpleTextOut
1221 );
1222 if (EFI_ERROR (Status)) {
1223 SimpleTextOut = NULL;
1224 }
1225
1226 if (GraphicsOutput != NULL) {
1227 //
1228 // Get current video resolution and text mode.
1229 //
1230 mBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
1231 mBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
1232 }
1233
1234 if (SimpleTextOut != NULL) {
1235 Status = SimpleTextOut->QueryMode (
1236 SimpleTextOut,
1237 SimpleTextOut->Mode->Mode,
1238 &BootTextColumn,
1239 &BootTextRow
1240 );
1241 mBootTextModeColumn = (UINT32)BootTextColumn;
1242 mBootTextModeRow = (UINT32)BootTextRow;
1243 }
1244
1245 //
1246 // Get user defined text mode for setup.
1247 //
1248 mSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
1249 mSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
1250 mSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
1251 mSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
1252
1253 mModeInitialized = TRUE;
1254 }
1255
1256 gBS->SetWatchdogTimer (0x0000, 0x0000, 0x0000, NULL);
1257 gST->ConOut->ClearScreen (gST->ConOut);
1258
1259 //
1260 // Install customized fonts needed by Front Page
1261 //
1262
1263 HiiHandle = ExportFonts ();
1264 ASSERT (HiiHandle != NULL);
1265
1266 InitializeStringSupport ();
1267
1268 BdsSetConsoleMode (TRUE);
1269 UiEntry (FALSE);
1270 BdsSetConsoleMode (FALSE);
1271
1272 UninitializeStringSupport ();
1273 HiiRemovePackages (HiiHandle);
1274
1275 return EFI_SUCCESS;
1276 }
1277
1278 /**
1279 This function is the main entry of the UI entry.
1280 The function will present the main menu of the system UI.
1281
1282 @param ConnectAllHappened Caller passes the value to UI to avoid unnecessary connect-all.
1283
1284 **/
1285 VOID
1286 EFIAPI
1287 UiEntry (
1288 IN BOOLEAN ConnectAllHappened
1289 )
1290 {
1291 EFI_STATUS Status;
1292 EFI_BOOT_LOGO_PROTOCOL *BootLogo;
1293
1294 //
1295 // Indicate if the connect all has been performed before.
1296 //
1297 if (ConnectAllHappened) {
1298 gConnectAllHappened = TRUE;
1299 }
1300
1301 //
1302 // The boot option enumeration time is acceptable in Ui driver
1303 //
1304 EfiBootManagerRefreshAllBootOption ();
1305
1306 //
1307 // Boot Logo is corrupted, report it using Boot Logo protocol.
1308 //
1309 Status = gBS->LocateProtocol (&gEfiBootLogoProtocolGuid, NULL, (VOID **) &BootLogo);
1310 if (!EFI_ERROR (Status) && (BootLogo != NULL)) {
1311 BootLogo->SetBootLogo (BootLogo, NULL, 0, 0, 0, 0);
1312 }
1313
1314 InitializeFrontPage ();
1315
1316 CallFrontPage ();
1317
1318 FreeFrontPage ();
1319
1320 if (mLanguageString != NULL) {
1321 FreePool (mLanguageString);
1322 mLanguageString = NULL;
1323 }
1324
1325 //
1326 //Will leave browser, check any reset required change is applied? if yes, reset system
1327 //
1328 SetupResetReminder ();
1329 }
1330
1331 /**
1332 Extract device path for given HII handle and class guid.
1333
1334 @param Handle The HII handle.
1335
1336 @retval NULL Fail to get the device path string.
1337 @return PathString Get the device path string.
1338
1339 **/
1340 CHAR16 *
1341 ExtractDevicePathFromHiiHandle (
1342 IN EFI_HII_HANDLE Handle
1343 )
1344 {
1345 EFI_STATUS Status;
1346 EFI_HANDLE DriverHandle;
1347
1348 ASSERT (Handle != NULL);
1349
1350 if (Handle == NULL) {
1351 return NULL;
1352 }
1353
1354 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
1355 if (EFI_ERROR (Status)) {
1356 return NULL;
1357 }
1358
1359 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);
1360
1361 }
1362
1363 //
1364 // Following are BDS Lib functions which contain all the code about setup browser reset reminder feature.
1365 // Setup Browser reset reminder feature is that an reset reminder will be given before user leaves the setup browser if
1366 // user change any option setting which needs a reset to be effective, and the reset will be applied according to the user selection.
1367 //
1368
1369
1370 /**
1371 Enable the setup browser reset reminder feature.
1372 This routine is used in platform tip. If the platform policy need the feature, use the routine to enable it.
1373
1374 **/
1375 VOID
1376 EFIAPI
1377 EnableResetReminderFeature (
1378 VOID
1379 )
1380 {
1381 mFeaturerSwitch = TRUE;
1382 }
1383
1384
1385 /**
1386 Disable the setup browser reset reminder feature.
1387 This routine is used in platform tip. If the platform policy do not want the feature, use the routine to disable it.
1388
1389 **/
1390 VOID
1391 EFIAPI
1392 DisableResetReminderFeature (
1393 VOID
1394 )
1395 {
1396 mFeaturerSwitch = FALSE;
1397 }
1398
1399
1400 /**
1401 Record the info that a reset is required.
1402 A module boolean variable is used to record whether a reset is required.
1403
1404 **/
1405 VOID
1406 EFIAPI
1407 EnableResetRequired (
1408 VOID
1409 )
1410 {
1411 mResetRequired = TRUE;
1412 }
1413
1414
1415 /**
1416 Record the info that no reset is required.
1417 A module boolean variable is used to record whether a reset is required.
1418
1419 **/
1420 VOID
1421 EFIAPI
1422 DisableResetRequired (
1423 VOID
1424 )
1425 {
1426 mResetRequired = FALSE;
1427 }
1428
1429
1430 /**
1431 Check whether platform policy enable the reset reminder feature. The default is enabled.
1432
1433 **/
1434 BOOLEAN
1435 EFIAPI
1436 IsResetReminderFeatureEnable (
1437 VOID
1438 )
1439 {
1440 return mFeaturerSwitch;
1441 }
1442
1443
1444 /**
1445 Check if user changed any option setting which needs a system reset to be effective.
1446
1447 **/
1448 BOOLEAN
1449 EFIAPI
1450 IsResetRequired (
1451 VOID
1452 )
1453 {
1454 return mResetRequired;
1455 }
1456
1457
1458 /**
1459 Check whether a reset is needed, and finish the reset reminder feature.
1460 If a reset is needed, Popup a menu to notice user, and finish the feature
1461 according to the user selection.
1462
1463 **/
1464 VOID
1465 EFIAPI
1466 SetupResetReminder (
1467 VOID
1468 )
1469 {
1470 EFI_INPUT_KEY Key;
1471 CHAR16 *StringBuffer1;
1472 CHAR16 *StringBuffer2;
1473
1474
1475 //
1476 //check any reset required change is applied? if yes, reset system
1477 //
1478 if (IsResetReminderFeatureEnable ()) {
1479 if (IsResetRequired ()) {
1480
1481 StringBuffer1 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
1482 ASSERT (StringBuffer1 != NULL);
1483 StringBuffer2 = AllocateZeroPool (MAX_STRING_LEN * sizeof (CHAR16));
1484 ASSERT (StringBuffer2 != NULL);
1485 StrCpyS (StringBuffer1, MAX_STRING_LEN, L"Configuration changed. Reset to apply it Now.");
1486 StrCpyS (StringBuffer2, MAX_STRING_LEN, L"Press ENTER to reset");
1487 //
1488 // Popup a menu to notice user
1489 //
1490 do {
1491 CreatePopUp (EFI_LIGHTGRAY | EFI_BACKGROUND_BLUE, &Key, StringBuffer1, StringBuffer2, NULL);
1492 } while (Key.UnicodeChar != CHAR_CARRIAGE_RETURN);
1493
1494 FreePool (StringBuffer1);
1495 FreePool (StringBuffer2);
1496
1497 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1498 }
1499 }
1500 }
1501