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