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