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