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