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