VirtualBox

source: vbox/trunk/src/VBox/Devices/EFI/FirmwareNew/MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenance.c@ 77662

Last change on this file since 77662 was 77662, checked in by vboxsync, 6 years ago

EFI: First step in UDK2018 merge. Does not build yet.

  • Property svn:eol-style set to native
File size: 58.7 KB
Line 
1/** @file
2The functions for Boot Maintainence Main menu.
3
4Copyright (c) 2004 - 2017, Intel Corporation. All rights reserved.<BR>
5This program and the accompanying materials
6are licensed and made available under the terms and conditions of the BSD License
7which accompanies this distribution. The full text of the license may be found at
8http://opensource.org/licenses/bsd-license.php
9
10THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
12
13**/
14
15#include "BootMaintenanceManager.h"
16
17#define FRONT_PAGE_KEY_OFFSET 0x4000
18//
19// Boot video resolution and text mode.
20//
21UINT32 mBmmBootHorizontalResolution = 0;
22UINT32 mBmmBootVerticalResolution = 0;
23UINT32 mBmmBootTextModeColumn = 0;
24UINT32 mBmmBootTextModeRow = 0;
25//
26// BIOS setup video resolution and text mode.
27//
28UINT32 mBmmSetupTextModeColumn = 0;
29UINT32 mBmmSetupTextModeRow = 0;
30UINT32 mBmmSetupHorizontalResolution = 0;
31UINT32 mBmmSetupVerticalResolution = 0;
32
33BOOLEAN mBmmModeInitialized = FALSE;
34
35EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {
36 {
37 END_DEVICE_PATH_TYPE,
38 END_ENTIRE_DEVICE_PATH_SUBTYPE,
39 {
40 END_DEVICE_PATH_LENGTH,
41 0
42 }
43 }
44};
45
46HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {
47 {
48 {
49 HARDWARE_DEVICE_PATH,
50 HW_VENDOR_DP,
51 {
52 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),
53 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)
54 }
55 },
56 //
57 // {165A028F-0BB2-4b5f-8747-77592E3F6499}
58 //
59 { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 } }
60 },
61 {
62 END_DEVICE_PATH_TYPE,
63 END_ENTIRE_DEVICE_PATH_SUBTYPE,
64 {
65 (UINT8) (END_DEVICE_PATH_LENGTH),
66 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)
67 }
68 }
69};
70
71EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;
72
73CHAR16 mBootMaintStorageName[] = L"BmmData";
74BMM_CALLBACK_DATA gBootMaintenancePrivate = {
75 BMM_CALLBACK_DATA_SIGNATURE,
76 NULL,
77 NULL,
78 {
79 BootMaintExtractConfig,
80 BootMaintRouteConfig,
81 BootMaintCallback
82 }
83};
84
85BMM_CALLBACK_DATA *mBmmCallbackInfo = &gBootMaintenancePrivate;
86BOOLEAN mAllMenuInit = FALSE;
87BOOLEAN mFirstEnterBMMForm = FALSE;
88
89/**
90 Init all memu.
91
92 @param CallbackData The BMM context data.
93
94**/
95VOID
96InitAllMenu (
97 IN BMM_CALLBACK_DATA *CallbackData
98 );
99
100/**
101 Free up all Menu Option list.
102
103**/
104VOID
105FreeAllMenu (
106 VOID
107 );
108
109/**
110
111 Update the menus in the BMM page.
112
113**/
114VOID
115CustomizeMenus (
116 VOID
117 );
118
119/**
120 This function will change video resolution and text mode
121 according to defined setup mode or defined boot mode
122
123 @param IsSetupMode Indicate mode is changed to setup mode or boot mode.
124
125 @retval EFI_SUCCESS Mode is changed successfully.
126 @retval Others Mode failed to be changed.
127
128**/
129EFI_STATUS
130BmmSetConsoleMode (
131 BOOLEAN IsSetupMode
132 )
133{
134 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
135 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
136 UINTN SizeOfInfo;
137 EFI_GRAPHICS_OUTPUT_MODE_INFORMATION *Info;
138 UINT32 MaxGopMode;
139 UINT32 MaxTextMode;
140 UINT32 ModeNumber;
141 UINT32 NewHorizontalResolution;
142 UINT32 NewVerticalResolution;
143 UINT32 NewColumns;
144 UINT32 NewRows;
145 UINTN HandleCount;
146 EFI_HANDLE *HandleBuffer;
147 EFI_STATUS Status;
148 UINTN Index;
149 UINTN CurrentColumn;
150 UINTN CurrentRow;
151
152 MaxGopMode = 0;
153 MaxTextMode = 0;
154
155 //
156 // Get current video resolution and text mode
157 //
158 Status = gBS->HandleProtocol (
159 gST->ConsoleOutHandle,
160 &gEfiGraphicsOutputProtocolGuid,
161 (VOID**)&GraphicsOutput
162 );
163 if (EFI_ERROR (Status)) {
164 GraphicsOutput = NULL;
165 }
166
167 Status = gBS->HandleProtocol (
168 gST->ConsoleOutHandle,
169 &gEfiSimpleTextOutProtocolGuid,
170 (VOID**)&SimpleTextOut
171 );
172 if (EFI_ERROR (Status)) {
173 SimpleTextOut = NULL;
174 }
175
176 if ((GraphicsOutput == NULL) || (SimpleTextOut == NULL)) {
177 return EFI_UNSUPPORTED;
178 }
179
180 if (IsSetupMode) {
181 //
182 // The required resolution and text mode is setup mode.
183 //
184 NewHorizontalResolution = mBmmSetupHorizontalResolution;
185 NewVerticalResolution = mBmmSetupVerticalResolution;
186 NewColumns = mBmmSetupTextModeColumn;
187 NewRows = mBmmSetupTextModeRow;
188 } else {
189 //
190 // The required resolution and text mode is boot mode.
191 //
192 NewHorizontalResolution = mBmmBootHorizontalResolution;
193 NewVerticalResolution = mBmmBootVerticalResolution;
194 NewColumns = mBmmBootTextModeColumn;
195 NewRows = mBmmBootTextModeRow;
196 }
197
198 if (GraphicsOutput != NULL) {
199 MaxGopMode = GraphicsOutput->Mode->MaxMode;
200 }
201
202 if (SimpleTextOut != NULL) {
203 MaxTextMode = SimpleTextOut->Mode->MaxMode;
204 }
205
206 //
207 // 1. If current video resolution is same with required video resolution,
208 // video resolution need not be changed.
209 // 1.1. If current text mode is same with required text mode, text mode need not be changed.
210 // 1.2. If current text mode is different from required text mode, text mode need be changed.
211 // 2. If current video resolution is different from required video resolution, we need restart whole console drivers.
212 //
213 for (ModeNumber = 0; ModeNumber < MaxGopMode; ModeNumber++) {
214 Status = GraphicsOutput->QueryMode (
215 GraphicsOutput,
216 ModeNumber,
217 &SizeOfInfo,
218 &Info
219 );
220 if (!EFI_ERROR (Status)) {
221 if ((Info->HorizontalResolution == NewHorizontalResolution) &&
222 (Info->VerticalResolution == NewVerticalResolution)) {
223 if ((GraphicsOutput->Mode->Info->HorizontalResolution == NewHorizontalResolution) &&
224 (GraphicsOutput->Mode->Info->VerticalResolution == NewVerticalResolution)) {
225 //
226 // Current resolution is same with required resolution, check if text mode need be set
227 //
228 Status = SimpleTextOut->QueryMode (SimpleTextOut, SimpleTextOut->Mode->Mode, &CurrentColumn, &CurrentRow);
229 ASSERT_EFI_ERROR (Status);
230 if (CurrentColumn == NewColumns && CurrentRow == NewRows) {
231 //
232 // If current text mode is same with required text mode. Do nothing
233 //
234 FreePool (Info);
235 return EFI_SUCCESS;
236 } else {
237 //
238 // If current text mode is different from required text mode. Set new video mode
239 //
240 for (Index = 0; Index < MaxTextMode; Index++) {
241 Status = SimpleTextOut->QueryMode (SimpleTextOut, Index, &CurrentColumn, &CurrentRow);
242 if (!EFI_ERROR(Status)) {
243 if ((CurrentColumn == NewColumns) && (CurrentRow == NewRows)) {
244 //
245 // Required text mode is supported, set it.
246 //
247 Status = SimpleTextOut->SetMode (SimpleTextOut, Index);
248 ASSERT_EFI_ERROR (Status);
249 //
250 // Update text mode PCD.
251 //
252 Status = PcdSet32S (PcdConOutColumn, mBmmSetupTextModeColumn);
253 ASSERT_EFI_ERROR (Status);
254 Status = PcdSet32S (PcdConOutRow, mBmmSetupTextModeRow);
255 ASSERT_EFI_ERROR (Status);
256 FreePool (Info);
257 return EFI_SUCCESS;
258 }
259 }
260 }
261 if (Index == MaxTextMode) {
262 //
263 // If required text mode is not supported, return error.
264 //
265 FreePool (Info);
266 return EFI_UNSUPPORTED;
267 }
268 }
269 } else {
270 //
271 // If current video resolution is not same with the new one, set new video resolution.
272 // In this case, the driver which produces simple text out need be restarted.
273 //
274 Status = GraphicsOutput->SetMode (GraphicsOutput, ModeNumber);
275 if (!EFI_ERROR (Status)) {
276 FreePool (Info);
277 break;
278 }
279 }
280 }
281 FreePool (Info);
282 }
283 }
284
285 if (ModeNumber == MaxGopMode) {
286 //
287 // If the resolution is not supported, return error.
288 //
289 return EFI_UNSUPPORTED;
290 }
291
292 //
293 // Set PCD to Inform GraphicsConsole to change video resolution.
294 // Set PCD to Inform Consplitter to change text mode.
295 //
296 Status = PcdSet32S (PcdVideoHorizontalResolution, NewHorizontalResolution);
297 ASSERT_EFI_ERROR (Status);
298 Status = PcdSet32S (PcdVideoVerticalResolution, NewVerticalResolution);
299 ASSERT_EFI_ERROR (Status);
300 Status = PcdSet32S (PcdConOutColumn, NewColumns);
301 ASSERT_EFI_ERROR (Status);
302 Status = PcdSet32S (PcdConOutRow, NewRows);
303 ASSERT_EFI_ERROR (Status);
304
305 //
306 // Video mode is changed, so restart graphics console driver and higher level driver.
307 // Reconnect graphics console driver and higher level driver.
308 // Locate all the handles with GOP protocol and reconnect it.
309 //
310 Status = gBS->LocateHandleBuffer (
311 ByProtocol,
312 &gEfiSimpleTextOutProtocolGuid,
313 NULL,
314 &HandleCount,
315 &HandleBuffer
316 );
317 if (!EFI_ERROR (Status)) {
318 for (Index = 0; Index < HandleCount; Index++) {
319 gBS->DisconnectController (HandleBuffer[Index], NULL, NULL);
320 }
321 for (Index = 0; Index < HandleCount; Index++) {
322 gBS->ConnectController (HandleBuffer[Index], NULL, NULL, TRUE);
323 }
324 if (HandleBuffer != NULL) {
325 FreePool (HandleBuffer);
326 }
327 }
328
329 return EFI_SUCCESS;
330}
331
332/**
333 This function converts an input device structure to a Unicode string.
334
335 @param DevPath A pointer to the device path structure.
336
337 @return A new allocated Unicode string that represents the device path.
338
339**/
340CHAR16 *
341UiDevicePathToStr (
342 IN EFI_DEVICE_PATH_PROTOCOL *DevPath
343 )
344{
345 EFI_STATUS Status;
346 CHAR16 *ToText;
347 EFI_DEVICE_PATH_TO_TEXT_PROTOCOL *DevPathToText;
348
349 if (DevPath == NULL) {
350 return NULL;
351 }
352
353 Status = gBS->LocateProtocol (
354 &gEfiDevicePathToTextProtocolGuid,
355 NULL,
356 (VOID **) &DevPathToText
357 );
358 ASSERT_EFI_ERROR (Status);
359 ToText = DevPathToText->ConvertDevicePathToText (
360 DevPath,
361 FALSE,
362 TRUE
363 );
364 ASSERT (ToText != NULL);
365 return ToText;
366}
367
368/**
369 Extract filename from device path. The returned buffer is allocated using AllocateCopyPool.
370 The caller is responsible for freeing the allocated buffer using FreePool().
371
372 @param DevicePath Device path.
373
374 @return A new allocated string that represents the file name.
375
376**/
377CHAR16 *
378ExtractFileNameFromDevicePath (
379 IN EFI_DEVICE_PATH_PROTOCOL *DevicePath
380 )
381{
382 CHAR16 *String;
383 CHAR16 *MatchString;
384 CHAR16 *LastMatch;
385 CHAR16 *FileName;
386 UINTN Length;
387
388 ASSERT(DevicePath != NULL);
389
390 String = UiDevicePathToStr(DevicePath);
391 MatchString = String;
392 LastMatch = String;
393 FileName = NULL;
394
395 while(MatchString != NULL){
396 LastMatch = MatchString + 1;
397 MatchString = StrStr(LastMatch,L"\\");
398 }
399
400 Length = StrLen(LastMatch);
401 FileName = AllocateCopyPool ((Length + 1) * sizeof(CHAR16), LastMatch);
402 if (FileName != NULL) {
403 *(FileName + Length) = 0;
404 }
405
406 FreePool(String);
407
408 return FileName;
409}
410
411/**
412 Extract device path for given HII handle and class guid.
413
414 @param Handle The HII handle.
415
416 @retval NULL Fail to get the device path string.
417 @return PathString Get the device path string.
418
419**/
420CHAR16 *
421BmmExtractDevicePathFromHiiHandle (
422 IN EFI_HII_HANDLE Handle
423 )
424{
425 EFI_STATUS Status;
426 EFI_HANDLE DriverHandle;
427
428 ASSERT (Handle != NULL);
429
430 if (Handle == NULL) {
431 return NULL;
432 }
433
434 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);
435 if (EFI_ERROR (Status)) {
436 return NULL;
437 }
438
439 //
440 // Get device path string.
441 //
442 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);
443
444}
445
446/**
447 Converts the unicode character of the string from uppercase to lowercase.
448 This is a internal function.
449
450 @param ConfigString String to be converted
451
452**/
453VOID
454HiiToLower (
455 IN EFI_STRING ConfigString
456 )
457{
458 EFI_STRING String;
459 BOOLEAN Lower;
460
461 ASSERT (ConfigString != NULL);
462
463 //
464 // Convert all hex digits in range [A-F] in the configuration header to [a-f]
465 //
466 for (String = ConfigString, Lower = FALSE; *String != L'\0'; String++) {
467 if (*String == L'=') {
468 Lower = TRUE;
469 } else if (*String == L'&') {
470 Lower = FALSE;
471 } else if (Lower && *String >= L'A' && *String <= L'F') {
472 *String = (CHAR16) (*String - L'A' + L'a');
473 }
474 }
475}
476
477/**
478 Update the progress string through the offset value.
479
480 @param Offset The offset value
481 @param Configuration Point to the configuration string.
482
483**/
484EFI_STRING
485UpdateProgress(
486 IN UINTN Offset,
487 IN EFI_STRING Configuration
488)
489{
490 UINTN Length;
491 EFI_STRING StringPtr;
492 EFI_STRING ReturnString;
493
494 StringPtr = NULL;
495 ReturnString = NULL;
496
497 //
498 // &OFFSET=XXXX followed by a Null-terminator.
499 // Length = StrLen (L"&OFFSET=") + 4 + 1
500 //
501 Length = StrLen (L"&OFFSET=") + 4 + 1;
502
503 StringPtr = AllocateZeroPool (Length * sizeof (CHAR16));
504
505 if (StringPtr == NULL) {
506 return NULL;
507 }
508
509 UnicodeSPrint (
510 StringPtr,
511 (8 + 4 + 1) * sizeof (CHAR16),
512 L"&OFFSET=%04x",
513 Offset
514 );
515
516 ReturnString = StrStr (Configuration, StringPtr);
517
518 if (ReturnString == NULL) {
519 //
520 // If doesn't find the string in Configuration, convert the string to lower case then search again.
521 //
522 HiiToLower (StringPtr);
523 ReturnString = StrStr (Configuration, StringPtr);
524 }
525
526 FreePool (StringPtr);
527
528 return ReturnString;
529}
530
531/**
532 Update the terminal content in TerminalMenu.
533
534 @param BmmData The BMM fake NV data.
535
536**/
537VOID
538UpdateTerminalContent (
539 IN BMM_FAKE_NV_DATA *BmmData
540 )
541{
542 UINT16 Index;
543 BM_TERMINAL_CONTEXT *NewTerminalContext;
544 BM_MENU_ENTRY *NewMenuEntry;
545
546 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
547 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
548 ASSERT (NewMenuEntry != NULL);
549 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
550 NewTerminalContext->BaudRateIndex = BmmData->COMBaudRate[Index];
551 ASSERT (BmmData->COMBaudRate[Index] < (ARRAY_SIZE (BaudRateList)));
552 NewTerminalContext->BaudRate = BaudRateList[BmmData->COMBaudRate[Index]].Value;
553 NewTerminalContext->DataBitsIndex = BmmData->COMDataRate[Index];
554 ASSERT (BmmData->COMDataRate[Index] < (ARRAY_SIZE (DataBitsList)));
555 NewTerminalContext->DataBits = (UINT8) DataBitsList[BmmData->COMDataRate[Index]].Value;
556 NewTerminalContext->StopBitsIndex = BmmData->COMStopBits[Index];
557 ASSERT (BmmData->COMStopBits[Index] < (ARRAY_SIZE (StopBitsList)));
558 NewTerminalContext->StopBits = (UINT8) StopBitsList[BmmData->COMStopBits[Index]].Value;
559 NewTerminalContext->ParityIndex = BmmData->COMParity[Index];
560 ASSERT (BmmData->COMParity[Index] < (ARRAY_SIZE (ParityList)));
561 NewTerminalContext->Parity = (UINT8) ParityList[BmmData->COMParity[Index]].Value;
562 NewTerminalContext->TerminalType = BmmData->COMTerminalType[Index];
563 NewTerminalContext->FlowControl = BmmData->COMFlowControl[Index];
564 ChangeTerminalDevicePath (
565 NewTerminalContext->DevicePath,
566 FALSE
567 );
568 }
569}
570
571/**
572 Update the console content in ConsoleMenu.
573
574 @param ConsoleName The name for the console device type.
575 @param BmmData The BMM fake NV data.
576
577**/
578VOID
579UpdateConsoleContent(
580 IN CHAR16 *ConsoleName,
581 IN BMM_FAKE_NV_DATA *BmmData
582 )
583{
584 UINT16 Index;
585 BM_CONSOLE_CONTEXT *NewConsoleContext;
586 BM_TERMINAL_CONTEXT *NewTerminalContext;
587 BM_MENU_ENTRY *NewMenuEntry;
588
589 if (StrCmp (ConsoleName, L"ConIn") == 0) {
590 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++){
591 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleInpMenu, Index);
592 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
593 ASSERT (Index < MAX_MENU_NUMBER);
594 NewConsoleContext->IsActive = BmmData->ConsoleInCheck[Index];
595 }
596 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
597 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
598 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
599 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);
600 NewTerminalContext->IsConIn = BmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];
601 }
602 }
603
604 if (StrCmp (ConsoleName, L"ConOut") == 0) {
605 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++){
606 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleOutMenu, Index);
607 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
608 ASSERT (Index < MAX_MENU_NUMBER);
609 NewConsoleContext->IsActive = BmmData->ConsoleOutCheck[Index];
610 }
611 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
612 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
613 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
614 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);
615 NewTerminalContext->IsConOut = BmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];
616 }
617 }
618 if (StrCmp (ConsoleName, L"ErrOut") == 0) {
619 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++){
620 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleErrMenu, Index);
621 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;
622 ASSERT (Index < MAX_MENU_NUMBER);
623 NewConsoleContext->IsActive = BmmData->ConsoleErrCheck[Index];
624 }
625 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
626 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
627 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
628 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);
629 NewTerminalContext->IsStdErr = BmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];
630 }
631 }
632}
633
634/**
635 This function allows a caller to extract the current configuration for one
636 or more named elements from the target driver.
637
638 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
639 @param Request A null-terminated Unicode string in <ConfigRequest> format.
640 @param Progress On return, points to a character in the Request string.
641 Points to the string's null terminator if request was successful.
642 Points to the most recent '&' before the first failing name/value
643 pair (or the beginning of the string if the failure is in the
644 first name/value pair) if the request was not successful.
645 @param Results A null-terminated Unicode string in <ConfigAltResp> format which
646 has all values filled in for the names in the Request string.
647 String to be allocated by the called function.
648
649 @retval EFI_SUCCESS The Results is filled with the requested values.
650 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.
651 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.
652 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.
653
654**/
655EFI_STATUS
656EFIAPI
657BootMaintExtractConfig (
658 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
659 IN CONST EFI_STRING Request,
660 OUT EFI_STRING *Progress,
661 OUT EFI_STRING *Results
662 )
663{
664 EFI_STATUS Status;
665 UINTN BufferSize;
666 BMM_CALLBACK_DATA *Private;
667 EFI_STRING ConfigRequestHdr;
668 EFI_STRING ConfigRequest;
669 BOOLEAN AllocatedRequest;
670 UINTN Size;
671
672 if (Progress == NULL || Results == NULL) {
673 return EFI_INVALID_PARAMETER;
674 }
675
676 *Progress = Request;
677 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {
678 return EFI_NOT_FOUND;
679 }
680
681 ConfigRequestHdr = NULL;
682 ConfigRequest = NULL;
683 AllocatedRequest = FALSE;
684 Size = 0;
685
686 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
687 //
688 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()
689 //
690 BufferSize = sizeof (BMM_FAKE_NV_DATA);
691 ConfigRequest = Request;
692 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {
693 //
694 // Request has no request element, construct full request string.
695 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template
696 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator
697 //
698 ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);
699 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);
700 ConfigRequest = AllocateZeroPool (Size);
701 ASSERT (ConfigRequest != NULL);
702 AllocatedRequest = TRUE;
703 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);
704 FreePool (ConfigRequestHdr);
705 }
706
707 Status = gHiiConfigRouting->BlockToConfig (
708 gHiiConfigRouting,
709 ConfigRequest,
710 (UINT8 *) &Private->BmmFakeNvData,
711 BufferSize,
712 Results,
713 Progress
714 );
715 //
716 // Free the allocated config request string.
717 //
718 if (AllocatedRequest) {
719 FreePool (ConfigRequest);
720 ConfigRequest = NULL;
721 }
722 //
723 // Set Progress string to the original request string.
724 //
725 if (Request == NULL) {
726 *Progress = NULL;
727 } else if (StrStr (Request, L"OFFSET") == NULL) {
728 *Progress = Request + StrLen (Request);
729 }
730
731 return Status;
732}
733
734/**
735 This function applies changes in a driver's configuration.
736 Input is a Configuration, which has the routing data for this
737 driver followed by name / value configuration pairs. The driver
738 must apply those pairs to its configurable storage. If the
739 driver's configuration is stored in a linear block of data
740 and the driver's name / value pairs are in <BlockConfig>
741 format, it may use the ConfigToBlock helper function (above) to
742 simplify the job. Currently not implemented.
743
744 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
745 @param[in] Configuration A null-terminated Unicode string in
746 <ConfigString> format.
747 @param[out] Progress A pointer to a string filled in with the
748 offset of the most recent '&' before the
749 first failing name / value pair (or the
750 beginn ing of the string if the failure
751 is in the first name / value pair) or
752 the terminating NULL if all was
753 successful.
754
755 @retval EFI_SUCCESS The results have been distributed or are
756 awaiting distribution.
757 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the
758 parts of the results that must be
759 stored awaiting possible future
760 protocols.
761 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the
762 Results parameter would result
763 in this type of error.
764 @retval EFI_NOT_FOUND Target for the specified routing data
765 was not found.
766**/
767EFI_STATUS
768EFIAPI
769BootMaintRouteConfig (
770 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
771 IN CONST EFI_STRING Configuration,
772 OUT EFI_STRING *Progress
773 )
774{
775 EFI_STATUS Status;
776 UINTN BufferSize;
777 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;
778 BMM_FAKE_NV_DATA *NewBmmData;
779 BMM_FAKE_NV_DATA *OldBmmData;
780 BM_MENU_ENTRY *NewMenuEntry;
781 BM_LOAD_CONTEXT *NewLoadContext;
782 UINT16 Index;
783 BOOLEAN TerminalAttChange;
784 BMM_CALLBACK_DATA *Private;
785 UINTN Offset;
786
787 if (Progress == NULL) {
788 return EFI_INVALID_PARAMETER;
789 }
790 *Progress = Configuration;
791
792 if (Configuration == NULL) {
793 return EFI_INVALID_PARAMETER;
794 }
795
796 //
797 // Check routing data in <ConfigHdr>.
798 // Note: there is no name for Name/Value storage, only GUID will be checked
799 //
800 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {
801 return EFI_NOT_FOUND;
802 }
803
804 Status = gBS->LocateProtocol (
805 &gEfiHiiConfigRoutingProtocolGuid,
806 NULL,
807 (VOID **)&ConfigRouting
808 );
809 if (EFI_ERROR (Status)) {
810 return Status;
811 }
812
813 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
814 //
815 // Get Buffer Storage data from EFI variable
816 //
817 BufferSize = sizeof (BMM_FAKE_NV_DATA);
818 OldBmmData = &Private->BmmOldFakeNVData;
819 NewBmmData = &Private->BmmFakeNvData;
820 Offset = 0;
821 //
822 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()
823 //
824 Status = ConfigRouting->ConfigToBlock (
825 ConfigRouting,
826 Configuration,
827 (UINT8 *) NewBmmData,
828 &BufferSize,
829 Progress
830 );
831 ASSERT_EFI_ERROR (Status);
832 //
833 // Compare new and old BMM configuration data and only do action for modified item to
834 // avoid setting unnecessary non-volatile variable
835 //
836
837 //
838 // Check data which located in BMM main page and save the settings if need
839 //
840 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {
841 Status = Var_UpdateBootNext (Private);
842 if (EFI_ERROR (Status)) {
843 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootNext);
844 goto Exit;
845 }
846 }
847
848 //
849 // Check data which located in Boot Options Menu and save the settings if need
850 //
851 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) {
852 for (Index = 0;
853 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0]))));
854 Index ++) {
855 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
856 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
857 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];
858 NewBmmData->BootOptionDel[Index] = FALSE;
859 NewBmmData->BootOptionDelMark[Index] = FALSE;
860 }
861
862 Status = Var_DelBootOption ();
863 if (EFI_ERROR (Status)) {
864 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionDel);
865 goto Exit;
866 }
867 }
868
869 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) {
870 Status = Var_UpdateBootOrder (Private);
871 if (EFI_ERROR (Status)) {
872 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionOrder);
873 goto Exit;
874 }
875 }
876
877 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0){
878 Status = gRT->SetVariable(
879 L"Timeout",
880 &gEfiGlobalVariableGuid,
881 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
882 sizeof(UINT16),
883 &(NewBmmData->BootTimeOut)
884 );
885 if (EFI_ERROR (Status)) {
886 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootTimeOut);
887 goto Exit;
888 }
889 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;
890 }
891
892 //
893 // Check data which located in Driver Options Menu and save the settings if need
894 //
895 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) {
896 for (Index = 0;
897 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0]))));
898 Index++) {
899 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
900 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
901 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];
902 NewBmmData->DriverOptionDel[Index] = FALSE;
903 NewBmmData->DriverOptionDelMark[Index] = FALSE;
904 }
905 Status = Var_DelDriverOption ();
906 if (EFI_ERROR (Status)) {
907 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionDel);
908 goto Exit;
909 }
910 }
911
912 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) {
913 Status = Var_UpdateDriverOrder (Private);
914 if (EFI_ERROR (Status)) {
915 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionOrder);
916 goto Exit;
917 }
918 }
919
920 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0){
921 Status = Var_UpdateConMode(Private);
922 if (EFI_ERROR (Status)) {
923 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutMode);
924 goto Exit;
925 }
926 }
927
928 TerminalAttChange = FALSE;
929 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
930
931 //
932 // only need update modified items
933 //
934 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&
935 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&
936 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&
937 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&
938 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&
939 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {
940 continue;
941 }
942
943 TerminalAttChange = TRUE;
944 }
945 if (TerminalAttChange) {
946 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) != 0) {
947 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMBaudRate);
948 } else if (CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) != 0) {
949 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMDataRate);
950 } else if (CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) != 0) {
951 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMStopBits);
952 } else if (CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) != 0) {
953 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMParity);
954 } else if (CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) != 0) {
955 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMTerminalType);
956 } else if (CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) != 0) {
957 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, COMFlowControl);
958 }
959 Status = Var_UpdateConsoleInpOption ();
960 if (EFI_ERROR (Status)) {
961 goto Exit;
962 }
963 Status = Var_UpdateConsoleOutOption ();
964 if (EFI_ERROR (Status)) {
965 goto Exit;
966 }
967 Status = Var_UpdateErrorOutOption ();
968 if (EFI_ERROR (Status)) {
969 goto Exit;
970 }
971 }
972 //
973 // Check data which located in Console Options Menu and save the settings if need
974 //
975 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0){
976 Status = Var_UpdateConsoleInpOption();
977 if (EFI_ERROR (Status)) {
978 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleInCheck);
979 goto Exit;
980 }
981 }
982
983 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0){
984 Status = Var_UpdateConsoleOutOption();
985 if (EFI_ERROR (Status)) {
986 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleOutCheck);
987 goto Exit;
988 }
989 }
990
991 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0){
992 Status = Var_UpdateErrorOutOption();
993 if (EFI_ERROR (Status)) {
994 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, ConsoleErrCheck);
995 goto Exit;
996 }
997 }
998
999 if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0 ||
1000 CompareMem (NewBmmData->BootOptionalData, OldBmmData->BootOptionalData, sizeof (NewBmmData->BootOptionalData)) != 0) {
1001 Status = Var_UpdateBootOption (Private);
1002 NewBmmData->BootOptionChanged = FALSE;
1003 if (EFI_ERROR (Status)) {
1004 if (CompareMem (NewBmmData->BootDescriptionData, OldBmmData->BootDescriptionData, sizeof (NewBmmData->BootDescriptionData)) != 0) {
1005 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootDescriptionData);
1006 } else {
1007 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, BootOptionalData);
1008 }
1009 goto Exit;
1010 }
1011 BOpt_GetBootOptions (Private);
1012 }
1013
1014 if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0 ||
1015 CompareMem (NewBmmData->DriverOptionalData, OldBmmData->DriverOptionalData, sizeof (NewBmmData->DriverOptionalData)) != 0) {
1016 Status = Var_UpdateDriverOption (
1017 Private,
1018 Private->BmmHiiHandle,
1019 NewBmmData->DriverDescriptionData,
1020 NewBmmData->DriverOptionalData,
1021 NewBmmData->ForceReconnect
1022 );
1023 NewBmmData->DriverOptionChanged = FALSE;
1024 NewBmmData->ForceReconnect = TRUE;
1025 if (EFI_ERROR (Status)) {
1026 if (CompareMem (NewBmmData->DriverDescriptionData, OldBmmData->DriverDescriptionData, sizeof (NewBmmData->DriverDescriptionData)) != 0) {
1027 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverDescriptionData);
1028 } else {
1029 Offset = OFFSET_OF (BMM_FAKE_NV_DATA, DriverOptionalData);
1030 }
1031 goto Exit;
1032 }
1033
1034 BOpt_GetDriverOptions (Private);
1035 }
1036
1037 //
1038 // After user do the save action, need to update OldBmmData.
1039 //
1040 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));
1041
1042 return EFI_SUCCESS;
1043
1044Exit:
1045 //
1046 // Fail to save the data, update the progress string.
1047 //
1048 *Progress = UpdateProgress (Offset, Configuration);
1049 if (Status == EFI_OUT_OF_RESOURCES) {
1050 return Status;
1051 } else {
1052 return EFI_NOT_FOUND;
1053 }
1054}
1055
1056/**
1057 This function processes the results of changes in configuration.
1058
1059
1060 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
1061 @param Action Specifies the type of action taken by the browser.
1062 @param QuestionId A unique value which is sent to the original exporting driver
1063 so that it can identify the type of data to expect.
1064 @param Type The type of value for the question.
1065 @param Value A pointer to the data being sent to the original exporting driver.
1066 @param ActionRequest On return, points to the action requested by the callback function.
1067
1068 @retval EFI_SUCCESS The callback successfully handled the action.
1069 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.
1070 @retval EFI_DEVICE_ERROR The variable could not be saved.
1071 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.
1072 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.
1073**/
1074EFI_STATUS
1075EFIAPI
1076BootMaintCallback (
1077 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,
1078 IN EFI_BROWSER_ACTION Action,
1079 IN EFI_QUESTION_ID QuestionId,
1080 IN UINT8 Type,
1081 IN EFI_IFR_TYPE_VALUE *Value,
1082 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest
1083 )
1084{
1085 BMM_CALLBACK_DATA *Private;
1086 BM_MENU_ENTRY *NewMenuEntry;
1087 BMM_FAKE_NV_DATA *CurrentFakeNVMap;
1088 BMM_FAKE_NV_DATA *OldFakeNVMap;
1089 UINTN Index;
1090 EFI_DEVICE_PATH_PROTOCOL * File;
1091
1092 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED && Action != EFI_BROWSER_ACTION_FORM_OPEN) {
1093 //
1094 // Do nothing for other UEFI Action. Only do call back when data is changed or the form is open.
1095 //
1096 return EFI_UNSUPPORTED;
1097 }
1098
1099 Private = BMM_CALLBACK_DATA_FROM_THIS (This);
1100
1101 if (Action == EFI_BROWSER_ACTION_FORM_OPEN) {
1102 if (QuestionId == KEY_VALUE_TRIGGER_FORM_OPEN_ACTION) {
1103 if (!mFirstEnterBMMForm) {
1104 //
1105 // BMMUiLib depends on LegacyUi library to show legacy menus.
1106 // If we want to show Legacy menus correctly in BMM page,
1107 // we must do it after the LegacyUi library has already been initialized.
1108 // Opening the BMM form is the appropriate time that the LegacyUi library has already been initialized.
1109 // So we do the tasks which are related to legacy menus here.
1110 // 1. Update the menus (including legacy munu) show in BootMiantenanceManager page.
1111 // 2. Re-scan the BootOption menus (including the legacy boot option).
1112 //
1113 CustomizeMenus ();
1114 BOpt_GetBootOptions (Private);
1115 mFirstEnterBMMForm = TRUE;
1116 }
1117 }
1118 }
1119 //
1120 // Retrieve uncommitted data from Form Browser
1121 //
1122 CurrentFakeNVMap = &Private->BmmFakeNvData;
1123 OldFakeNVMap = &Private->BmmOldFakeNVData;
1124 HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);
1125
1126 if (Action == EFI_BROWSER_ACTION_CHANGING) {
1127 if (Value == NULL) {
1128 return EFI_INVALID_PARAMETER;
1129 }
1130
1131 UpdatePageId (Private, QuestionId);
1132
1133 if (QuestionId < FILE_OPTION_OFFSET) {
1134 if (QuestionId < CONFIG_OPTION_OFFSET) {
1135 switch (QuestionId) {
1136 case FORM_BOOT_ADD_ID:
1137 // Leave BMM and enter FileExplorer.
1138 ChooseFile (NULL, L".efi", CreateBootOptionFromFile, &File);
1139 break;
1140
1141 case FORM_DRV_ADD_FILE_ID:
1142 // Leave BMM and enter FileExplorer.
1143 ChooseFile (NULL, L".efi", CreateDriverOptionFromFile, &File);
1144 break;
1145
1146 case FORM_DRV_ADD_HANDLE_ID:
1147 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);
1148 UpdateDrvAddHandlePage (Private);
1149 break;
1150
1151 case FORM_BOOT_DEL_ID:
1152 CleanUpPage (FORM_BOOT_DEL_ID, Private);
1153 UpdateBootDelPage (Private);
1154 break;
1155
1156 case FORM_BOOT_CHG_ID:
1157 case FORM_DRV_CHG_ID:
1158 UpdatePageBody (QuestionId, Private);
1159 break;
1160
1161 case FORM_DRV_DEL_ID:
1162 CleanUpPage (FORM_DRV_DEL_ID, Private);
1163 UpdateDrvDelPage (Private);
1164 break;
1165
1166 case FORM_CON_IN_ID:
1167 case FORM_CON_OUT_ID:
1168 case FORM_CON_ERR_ID:
1169 UpdatePageBody (QuestionId, Private);
1170 break;
1171
1172 case FORM_CON_MODE_ID:
1173 CleanUpPage (FORM_CON_MODE_ID, Private);
1174 UpdateConModePage (Private);
1175 break;
1176
1177 case FORM_CON_COM_ID:
1178 CleanUpPage (FORM_CON_COM_ID, Private);
1179 UpdateConCOMPage (Private);
1180 break;
1181
1182 default:
1183 break;
1184 }
1185 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {
1186 Index = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);
1187 Private->CurrentTerminal = Index;
1188
1189 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);
1190 UpdateTerminalPage (Private);
1191
1192 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {
1193 Index = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);
1194
1195 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);
1196 ASSERT (NewMenuEntry != NULL);
1197 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;
1198
1199 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);
1200
1201 Private->MenuEntry = NewMenuEntry;
1202 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;
1203
1204 UpdateDriverAddHandleDescPage (Private);
1205 }
1206 }
1207 if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){
1208 // Leave BMM and enter FileExplorer.
1209 ChooseFile (NULL, L".efi", BootFromFile, &File);
1210 }
1211 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {
1212 if ((Value == NULL) || (ActionRequest == NULL)) {
1213 return EFI_INVALID_PARAMETER;
1214 }
1215
1216 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_BOOT) {
1217 CleanUselessBeforeSubmit (Private);
1218 CurrentFakeNVMap->BootOptionChanged = FALSE;
1219 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1220 } else if (QuestionId == KEY_VALUE_SAVE_AND_EXIT_DRIVER) {
1221 CleanUselessBeforeSubmit (Private);
1222 CurrentFakeNVMap->DriverOptionChanged = FALSE;
1223 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1224 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_DRIVER) {
1225 //
1226 // Discard changes and exit formset
1227 //
1228 ZeroMem (CurrentFakeNVMap->DriverOptionalData, sizeof (CurrentFakeNVMap->DriverOptionalData));
1229 ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
1230 ZeroMem (OldFakeNVMap->DriverOptionalData, sizeof (OldFakeNVMap->DriverOptionalData));
1231 ZeroMem (OldFakeNVMap->DriverDescriptionData, sizeof (OldFakeNVMap->DriverDescriptionData));
1232 CurrentFakeNVMap->DriverOptionChanged = FALSE;
1233 CurrentFakeNVMap->ForceReconnect = TRUE;
1234 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1235 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT_BOOT) {
1236 //
1237 // Discard changes and exit formset
1238 //
1239 ZeroMem (CurrentFakeNVMap->BootOptionalData, sizeof (CurrentFakeNVMap->BootOptionalData));
1240 ZeroMem (CurrentFakeNVMap->BootDescriptionData, sizeof (CurrentFakeNVMap->BootDescriptionData));
1241 ZeroMem (OldFakeNVMap->BootOptionalData, sizeof (OldFakeNVMap->BootOptionalData));
1242 ZeroMem (OldFakeNVMap->BootDescriptionData, sizeof (OldFakeNVMap->BootDescriptionData));
1243 CurrentFakeNVMap->BootOptionChanged = FALSE;
1244 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1245 } else if (QuestionId == KEY_VALUE_BOOT_DESCRIPTION || QuestionId == KEY_VALUE_BOOT_OPTION) {
1246 CurrentFakeNVMap->BootOptionChanged = TRUE;
1247 } else if (QuestionId == KEY_VALUE_DRIVER_DESCRIPTION || QuestionId == KEY_VALUE_DRIVER_OPTION) {
1248 CurrentFakeNVMap->DriverOptionChanged = TRUE;
1249 }
1250
1251 if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
1252 if (Value->b){
1253 //
1254 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.
1255 //
1256 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;
1257 } else {
1258 //
1259 // Means user remove the old check status.
1260 //
1261 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;
1262 }
1263 } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {
1264 if (Value->b){
1265 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;
1266 } else {
1267 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;
1268 }
1269 } else {
1270 switch (QuestionId) {
1271 case KEY_VALUE_SAVE_AND_EXIT:
1272 case KEY_VALUE_NO_SAVE_AND_EXIT:
1273 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {
1274 CleanUselessBeforeSubmit (Private);
1275 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;
1276 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {
1277 DiscardChangeHandler (Private, CurrentFakeNVMap);
1278 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;
1279 }
1280
1281 break;
1282
1283 case FORM_RESET:
1284 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);
1285 return EFI_UNSUPPORTED;
1286
1287 default:
1288 break;
1289 }
1290 }
1291 //
1292 // Update the content in Terminal menu and Console menu here.
1293 //
1294 if (QuestionId == COM_BAUD_RATE_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_DATA_RATE_QUESTION_ID + Private->CurrentTerminal ||
1295 QuestionId == COM_PARITY_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_STOP_BITS_QUESTION_ID + Private->CurrentTerminal ||
1296 QuestionId == COM_TERMINAL_QUESTION_ID + Private->CurrentTerminal || QuestionId == COM_FLOWCONTROL_QUESTION_ID + Private->CurrentTerminal
1297 ) {
1298 UpdateTerminalContent(CurrentFakeNVMap);
1299 }
1300 if ((QuestionId >= CON_IN_DEVICE_QUESTION_ID) && (QuestionId < CON_IN_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
1301 UpdateConsoleContent (L"ConIn",CurrentFakeNVMap);
1302 } else if ((QuestionId >= CON_OUT_DEVICE_QUESTION_ID) && (QuestionId < CON_OUT_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
1303 UpdateConsoleContent (L"ConOut", CurrentFakeNVMap);
1304 } else if ((QuestionId >= CON_ERR_DEVICE_QUESTION_ID) && (QuestionId < CON_ERR_DEVICE_QUESTION_ID + MAX_MENU_NUMBER)) {
1305 UpdateConsoleContent (L"ErrOut", CurrentFakeNVMap);
1306 }
1307 }
1308
1309 //
1310 // Pass changed uncommitted data back to Form Browser
1311 //
1312 HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);
1313
1314 return EFI_SUCCESS;
1315}
1316
1317/**
1318 Discard all changes done to the BMM pages such as Boot Order change,
1319 Driver order change.
1320
1321 @param Private The BMM context data.
1322 @param CurrentFakeNVMap The current Fack NV Map.
1323
1324**/
1325VOID
1326DiscardChangeHandler (
1327 IN BMM_CALLBACK_DATA *Private,
1328 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap
1329 )
1330{
1331 UINT16 Index;
1332
1333 switch (Private->BmmPreviousPageId) {
1334 case FORM_BOOT_CHG_ID:
1335 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));
1336 break;
1337
1338 case FORM_DRV_CHG_ID:
1339 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));
1340 break;
1341
1342 case FORM_BOOT_DEL_ID:
1343 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));
1344 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
1345 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;
1346 }
1347 break;
1348
1349 case FORM_DRV_DEL_ID:
1350 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));
1351 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
1352 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;
1353 }
1354 break;
1355
1356 case FORM_BOOT_NEXT_ID:
1357 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;
1358 break;
1359
1360 case FORM_TIME_OUT_ID:
1361 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;
1362 break;
1363
1364 case FORM_DRV_ADD_HANDLE_DESC_ID:
1365 case FORM_DRV_ADD_FILE_ID:
1366 case FORM_DRV_ADD_HANDLE_ID:
1367 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;
1368 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;
1369 break;
1370
1371 default:
1372 break;
1373 }
1374}
1375
1376/**
1377 This function is to clean some useless data before submit changes.
1378
1379 @param Private The BMM context data.
1380
1381**/
1382VOID
1383CleanUselessBeforeSubmit (
1384 IN BMM_CALLBACK_DATA *Private
1385 )
1386{
1387 UINT16 Index;
1388 if (Private->BmmPreviousPageId != FORM_BOOT_DEL_ID) {
1389 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
1390 if (Private->BmmFakeNvData.BootOptionDel[Index] && !Private->BmmFakeNvData.BootOptionDelMark[Index]) {
1391 Private->BmmFakeNvData.BootOptionDel[Index] = FALSE;
1392 Private->BmmOldFakeNVData.BootOptionDel[Index] = FALSE;
1393 }
1394 }
1395 }
1396 if (Private->BmmPreviousPageId != FORM_DRV_DEL_ID) {
1397 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
1398 if (Private->BmmFakeNvData.DriverOptionDel[Index] && !Private->BmmFakeNvData.DriverOptionDelMark[Index]) {
1399 Private->BmmFakeNvData.DriverOptionDel[Index] = FALSE;
1400 Private->BmmOldFakeNVData.DriverOptionDel[Index] = FALSE;
1401 }
1402 }
1403 }
1404}
1405
1406/**
1407
1408 Update the menus in the BMM page.
1409
1410**/
1411VOID
1412CustomizeMenus (
1413 VOID
1414 )
1415{
1416 VOID *StartOpCodeHandle;
1417 VOID *EndOpCodeHandle;
1418 EFI_IFR_GUID_LABEL *StartGuidLabel;
1419 EFI_IFR_GUID_LABEL *EndGuidLabel;
1420
1421 //
1422 // Allocate space for creation of UpdateData Buffer
1423 //
1424 StartOpCodeHandle = HiiAllocateOpCodeHandle ();
1425 ASSERT (StartOpCodeHandle != NULL);
1426
1427 EndOpCodeHandle = HiiAllocateOpCodeHandle ();
1428 ASSERT (EndOpCodeHandle != NULL);
1429 //
1430 // Create Hii Extend Label OpCode as the start opcode
1431 //
1432 StartGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1433 StartGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1434 StartGuidLabel->Number = LABEL_FORM_MAIN_START;
1435 //
1436 // Create Hii Extend Label OpCode as the end opcode
1437 //
1438 EndGuidLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));
1439 EndGuidLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;
1440 EndGuidLabel->Number = LABEL_FORM_MAIN_END;
1441
1442 //
1443 //Updata Front Page form
1444 //
1445 UiCustomizeBMMPage (
1446 mBmmCallbackInfo->BmmHiiHandle,
1447 StartOpCodeHandle
1448 );
1449
1450 HiiUpdateForm (
1451 mBmmCallbackInfo->BmmHiiHandle,
1452 &mBootMaintGuid,
1453 FORM_MAIN_ID,
1454 StartOpCodeHandle,
1455 EndOpCodeHandle
1456 );
1457
1458 HiiFreeOpCodeHandle (StartOpCodeHandle);
1459 HiiFreeOpCodeHandle (EndOpCodeHandle);
1460}
1461
1462/**
1463 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and
1464 BmmOldFakeNVData member in BMM context data.
1465
1466 @param CallbackData The BMM context data.
1467
1468**/
1469VOID
1470InitializeBmmConfig (
1471 IN BMM_CALLBACK_DATA *CallbackData
1472 )
1473{
1474 BM_MENU_ENTRY *NewMenuEntry;
1475 BM_LOAD_CONTEXT *NewLoadContext;
1476 UINT16 Index;
1477
1478 ASSERT (CallbackData != NULL);
1479
1480 //
1481 // Initialize data which located in BMM main page
1482 //
1483 CallbackData->BmmFakeNvData.BootNext = NONE_BOOTNEXT_VALUE;
1484 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
1485 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
1486 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
1487
1488 if (NewLoadContext->IsBootNext) {
1489 CallbackData->BmmFakeNvData.BootNext = Index;
1490 break;
1491 }
1492 }
1493
1494 CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);
1495
1496 //
1497 // Initialize data which located in Boot Options Menu
1498 //
1499 GetBootOrder (CallbackData);
1500
1501 //
1502 // Initialize data which located in Driver Options Menu
1503 //
1504 GetDriverOrder (CallbackData);
1505
1506 //
1507 // Initialize data which located in Console Options Menu
1508 //
1509 GetConsoleOutMode (CallbackData);
1510 GetConsoleInCheck (CallbackData);
1511 GetConsoleOutCheck (CallbackData);
1512 GetConsoleErrCheck (CallbackData);
1513 GetTerminalAttribute (CallbackData);
1514
1515 CallbackData->BmmFakeNvData.ForceReconnect = TRUE;
1516
1517 //
1518 // Backup Initialize BMM configuartion data to BmmOldFakeNVData
1519 //
1520 CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));
1521}
1522
1523/**
1524 Initialized all Menu Option List.
1525
1526 @param CallbackData The BMM context data.
1527
1528**/
1529VOID
1530InitAllMenu (
1531 IN BMM_CALLBACK_DATA *CallbackData
1532 )
1533{
1534 InitializeListHead (&BootOptionMenu.Head);
1535 InitializeListHead (&DriverOptionMenu.Head);
1536 BOpt_GetBootOptions (CallbackData);
1537 BOpt_GetDriverOptions (CallbackData);
1538 BOpt_FindDrivers ();
1539 InitializeListHead (&ConsoleInpMenu.Head);
1540 InitializeListHead (&ConsoleOutMenu.Head);
1541 InitializeListHead (&ConsoleErrMenu.Head);
1542 InitializeListHead (&TerminalMenu.Head);
1543 LocateSerialIo ();
1544 GetAllConsoles ();
1545 mAllMenuInit = TRUE;
1546}
1547
1548/**
1549 Free up all Menu Option list.
1550
1551**/
1552VOID
1553FreeAllMenu (
1554 VOID
1555 )
1556{
1557 if (!mAllMenuInit){
1558 return;
1559 }
1560 BOpt_FreeMenu (&BootOptionMenu);
1561 BOpt_FreeMenu (&DriverOptionMenu);
1562 BOpt_FreeMenu (&DriverMenu);
1563 FreeAllConsoles ();
1564 mAllMenuInit = FALSE;
1565}
1566
1567/**
1568 Initial the boot mode related parameters.
1569
1570**/
1571VOID
1572BmmInitialBootModeInfo (
1573 VOID
1574 )
1575{
1576 EFI_STATUS Status;
1577 EFI_GRAPHICS_OUTPUT_PROTOCOL *GraphicsOutput;
1578 EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL *SimpleTextOut;
1579 UINTN BootTextColumn;
1580 UINTN BootTextRow;
1581
1582 if (mBmmModeInitialized) {
1583 return;
1584 }
1585
1586 //
1587 // After the console is ready, get current video resolution
1588 // and text mode before launching setup at first time.
1589 //
1590 Status = gBS->HandleProtocol (
1591 gST->ConsoleOutHandle,
1592 &gEfiGraphicsOutputProtocolGuid,
1593 (VOID**)&GraphicsOutput
1594 );
1595 if (EFI_ERROR (Status)) {
1596 GraphicsOutput = NULL;
1597 }
1598
1599 Status = gBS->HandleProtocol (
1600 gST->ConsoleOutHandle,
1601 &gEfiSimpleTextOutProtocolGuid,
1602 (VOID**)&SimpleTextOut
1603 );
1604 if (EFI_ERROR (Status)) {
1605 SimpleTextOut = NULL;
1606 }
1607
1608 if (GraphicsOutput != NULL) {
1609 //
1610 // Get current video resolution and text mode.
1611 //
1612 mBmmBootHorizontalResolution = GraphicsOutput->Mode->Info->HorizontalResolution;
1613 mBmmBootVerticalResolution = GraphicsOutput->Mode->Info->VerticalResolution;
1614 }
1615
1616 if (SimpleTextOut != NULL) {
1617 Status = SimpleTextOut->QueryMode (
1618 SimpleTextOut,
1619 SimpleTextOut->Mode->Mode,
1620 &BootTextColumn,
1621 &BootTextRow
1622 );
1623 mBmmBootTextModeColumn = (UINT32)BootTextColumn;
1624 mBmmBootTextModeRow = (UINT32)BootTextRow;
1625 }
1626
1627 //
1628 // Get user defined text mode for setup.
1629 //
1630 mBmmSetupHorizontalResolution = PcdGet32 (PcdSetupVideoHorizontalResolution);
1631 mBmmSetupVerticalResolution = PcdGet32 (PcdSetupVideoVerticalResolution);
1632 mBmmSetupTextModeColumn = PcdGet32 (PcdSetupConOutColumn);
1633 mBmmSetupTextModeRow = PcdGet32 (PcdSetupConOutRow);
1634
1635 mBmmModeInitialized = TRUE;
1636}
1637
1638/**
1639
1640 Install Boot Maintenance Manager Menu driver.
1641
1642 @param ImageHandle The image handle.
1643 @param SystemTable The system table.
1644
1645 @retval EFI_SUCEESS Install Boot manager menu success.
1646 @retval Other Return error status.
1647
1648**/
1649EFI_STATUS
1650EFIAPI
1651BootMaintenanceManagerUiLibConstructor (
1652 IN EFI_HANDLE ImageHandle,
1653 IN EFI_SYSTEM_TABLE *SystemTable
1654 )
1655
1656{
1657 EFI_STATUS Status;
1658 UINT8 *Ptr;
1659
1660 Status = EFI_SUCCESS;
1661
1662 //
1663 // Install Device Path Protocol and Config Access protocol to driver handle
1664 //
1665 Status = gBS->InstallMultipleProtocolInterfaces (
1666 &mBmmCallbackInfo->BmmDriverHandle,
1667 &gEfiDevicePathProtocolGuid,
1668 &mBmmHiiVendorDevicePath,
1669 &gEfiHiiConfigAccessProtocolGuid,
1670 &mBmmCallbackInfo->BmmConfigAccess,
1671 NULL
1672 );
1673 ASSERT_EFI_ERROR (Status);
1674
1675 //
1676 // Post our Boot Maint VFR binary to the HII database.
1677 //
1678 mBmmCallbackInfo->BmmHiiHandle = HiiAddPackages (
1679 &mBootMaintGuid,
1680 mBmmCallbackInfo->BmmDriverHandle,
1681 BootMaintenanceManagerBin,
1682 BootMaintenanceManagerUiLibStrings,
1683 NULL
1684 );
1685 ASSERT (mBmmCallbackInfo->BmmHiiHandle != NULL);
1686
1687 //
1688 // Locate Formbrowser2 protocol
1689 //
1690 Status = gBS->LocateProtocol (&gEfiFormBrowser2ProtocolGuid, NULL, (VOID **) &mBmmCallbackInfo->FormBrowser2);
1691 ASSERT_EFI_ERROR (Status);
1692
1693 EfiBootManagerRefreshAllBootOption ();
1694
1695 //
1696 // Create LoadOption in BmmCallbackInfo for Driver Callback
1697 //
1698 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));
1699 ASSERT (Ptr != NULL);
1700
1701 //
1702 // Initialize Bmm callback data.
1703 //
1704 mBmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;
1705 Ptr += sizeof (BM_LOAD_CONTEXT);
1706
1707 mBmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;
1708 Ptr += sizeof (BM_FILE_CONTEXT);
1709
1710 mBmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;
1711 Ptr += sizeof (BM_HANDLE_CONTEXT);
1712
1713 mBmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;
1714
1715 mBmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;
1716 mBmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;
1717
1718 InitAllMenu (mBmmCallbackInfo);
1719
1720 CreateUpdateData();
1721 //
1722 // Update boot maintenance manager page
1723 //
1724 InitializeBmmConfig(mBmmCallbackInfo);
1725
1726 BmmInitialBootModeInfo();
1727
1728 return EFI_SUCCESS;
1729}
1730
1731/**
1732 Unloads the application and its installed protocol.
1733
1734 @param ImageHandle Handle that identifies the image to be unloaded.
1735 @param SystemTable The system table.
1736
1737 @retval EFI_SUCCESS The image has been unloaded.
1738
1739**/
1740EFI_STATUS
1741EFIAPI
1742BootMaintenanceManagerUiLibDestructor (
1743 IN EFI_HANDLE ImageHandle,
1744 IN EFI_SYSTEM_TABLE *SystemTable
1745 )
1746
1747{
1748 if (mStartOpCodeHandle != NULL) {
1749 HiiFreeOpCodeHandle (mStartOpCodeHandle);
1750 }
1751
1752 if (mEndOpCodeHandle != NULL) {
1753 HiiFreeOpCodeHandle (mEndOpCodeHandle);
1754 }
1755
1756 FreeAllMenu ();
1757
1758 //
1759 // Remove our IFR data from HII database
1760 //
1761 HiiRemovePackages (mBmmCallbackInfo->BmmHiiHandle);
1762
1763 gBS->UninstallMultipleProtocolInterfaces (
1764 mBmmCallbackInfo->BmmDriverHandle,
1765 &gEfiDevicePathProtocolGuid,
1766 &mBmmHiiVendorDevicePath,
1767 &gEfiHiiConfigAccessProtocolGuid,
1768 &mBmmCallbackInfo->BmmConfigAccess,
1769 NULL
1770 );
1771
1772 FreePool (mBmmCallbackInfo->LoadContext);
1773
1774 return EFI_SUCCESS;
1775}
1776
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette