]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Application/UiApp/BootMaint/BootMaint.c
MdeModulePkg:Create Boot Maintenance Manager Library
[mirror_edk2.git] / MdeModulePkg / Application / UiApp / BootMaint / BootMaint.c
CommitLineData
143f0b1d
ED
1/** @file\r
2 The functions for Boot Maintainence Main menu.\r
3\r
afc244a5 4Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>\r
143f0b1d
ED
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 "BootMaint.h"\r
16\r
17EFI_DEVICE_PATH_PROTOCOL EndDevicePath[] = {\r
18 {\r
19 END_DEVICE_PATH_TYPE,\r
20 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
21 {\r
22 END_DEVICE_PATH_LENGTH,\r
23 0\r
24 }\r
25 }\r
26};\r
27\r
28HII_VENDOR_DEVICE_PATH mBmmHiiVendorDevicePath = {\r
29 {\r
30 {\r
31 HARDWARE_DEVICE_PATH,\r
32 HW_VENDOR_DP,\r
33 {\r
34 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
35 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
36 }\r
37 },\r
38 //\r
39 // {165A028F-0BB2-4b5f-8747-77592E3F6499}\r
40 //\r
41 { 0x165a028f, 0xbb2, 0x4b5f, { 0x87, 0x47, 0x77, 0x59, 0x2e, 0x3f, 0x64, 0x99 } }\r
42 },\r
43 {\r
44 END_DEVICE_PATH_TYPE,\r
45 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
46 { \r
47 (UINT8) (END_DEVICE_PATH_LENGTH),\r
48 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
49 }\r
50 }\r
51};\r
52\r
53HII_VENDOR_DEVICE_PATH mFeHiiVendorDevicePath = {\r
54 {\r
55 {\r
56 HARDWARE_DEVICE_PATH,\r
57 HW_VENDOR_DP,\r
58 {\r
59 (UINT8) (sizeof (VENDOR_DEVICE_PATH)),\r
60 (UINT8) ((sizeof (VENDOR_DEVICE_PATH)) >> 8)\r
61 }\r
62 },\r
63 //\r
64 // {91DB4238-B0C8-472e-BBCF-F3A6541010F4}\r
65 //\r
66 { 0x91db4238, 0xb0c8, 0x472e, { 0xbb, 0xcf, 0xf3, 0xa6, 0x54, 0x10, 0x10, 0xf4 } }\r
67 },\r
68 {\r
69 END_DEVICE_PATH_TYPE,\r
70 END_ENTIRE_DEVICE_PATH_SUBTYPE,\r
71 { \r
72 (UINT8) (END_DEVICE_PATH_LENGTH),\r
73 (UINT8) ((END_DEVICE_PATH_LENGTH) >> 8)\r
74 }\r
75 }\r
76};\r
77\r
78EFI_GUID mBootMaintGuid = BOOT_MAINT_FORMSET_GUID;\r
79EFI_GUID mFileExplorerGuid = FILE_EXPLORE_FORMSET_GUID;\r
80\r
81CHAR16 mBootMaintStorageName[] = L"BmmData";\r
82CHAR16 mFileExplorerStorageName[] = L"FeData";\r
83BMM_CALLBACK_DATA *mBmmCallbackInfo = NULL;\r
84BOOLEAN mAllMenuInit = FALSE;\r
85BOOLEAN mEnterFileExplorer = FALSE;\r
86\r
87/**\r
88 Init all memu.\r
89\r
90 @param CallbackData The BMM context data.\r
91\r
92**/\r
93VOID\r
94InitAllMenu (\r
95 IN BMM_CALLBACK_DATA *CallbackData\r
96 );\r
97\r
98/**\r
99 Free up all Menu Option list.\r
100\r
101**/\r
102VOID\r
103FreeAllMenu (\r
104 VOID\r
105 );\r
106\r
107/**\r
108 Create string tokens for a menu from its help strings and display strings\r
109\r
110 @param CallbackData The BMM context data.\r
111 @param HiiHandle Hii Handle of the package to be updated.\r
112 @param MenuOption The Menu whose string tokens need to be created\r
113\r
114 @retval EFI_SUCCESS String tokens created successfully\r
115 @retval others contain some errors\r
116**/\r
117EFI_STATUS\r
118CreateMenuStringToken (\r
119 IN BMM_CALLBACK_DATA *CallbackData,\r
120 IN EFI_HII_HANDLE HiiHandle,\r
121 IN BM_MENU_OPTION *MenuOption\r
122 )\r
123{\r
124 BM_MENU_ENTRY *NewMenuEntry;\r
125 UINTN Index;\r
126\r
127 for (Index = 0; Index < MenuOption->MenuNumber; Index++) {\r
128 NewMenuEntry = BOpt_GetMenuEntry (MenuOption, Index);\r
129\r
130 NewMenuEntry->DisplayStringToken = HiiSetString (\r
131 HiiHandle,\r
132 0,\r
133 NewMenuEntry->DisplayString,\r
134 NULL\r
135 );\r
136\r
137 if (NULL == NewMenuEntry->HelpString) {\r
138 NewMenuEntry->HelpStringToken = NewMenuEntry->DisplayStringToken;\r
139 } else {\r
140 NewMenuEntry->HelpStringToken = HiiSetString (\r
141 HiiHandle,\r
142 0,\r
143 NewMenuEntry->HelpString,\r
144 NULL\r
145 );\r
146 }\r
147 }\r
148\r
149 return EFI_SUCCESS;\r
150}\r
151\r
152/**\r
153 This function allows a caller to extract the current configuration for one\r
154 or more named elements from the target driver.\r
155\r
156\r
157 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
158 @param Request A null-terminated Unicode string in <ConfigRequest> format.\r
159 @param Progress On return, points to a character in the Request string.\r
160 Points to the string's null terminator if request was successful.\r
161 Points to the most recent '&' before the first failing name/value\r
162 pair (or the beginning of the string if the failure is in the\r
163 first name/value pair) if the request was not successful.\r
164 @param Results A null-terminated Unicode string in <ConfigAltResp> format which\r
165 has all values filled in for the names in the Request string.\r
166 String to be allocated by the called function.\r
167\r
168 @retval EFI_SUCCESS The Results is filled with the requested values.\r
169 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the results.\r
170 @retval EFI_INVALID_PARAMETER Request is NULL, illegal syntax, or unknown name.\r
171 @retval EFI_NOT_FOUND Routing data doesn't match any storage in this driver.\r
172\r
173**/\r
174EFI_STATUS\r
175EFIAPI\r
176BootMaintExtractConfig (\r
177 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
178 IN CONST EFI_STRING Request,\r
179 OUT EFI_STRING *Progress,\r
180 OUT EFI_STRING *Results\r
181 )\r
182{\r
183 EFI_STATUS Status;\r
184 UINTN BufferSize;\r
185 BMM_CALLBACK_DATA *Private;\r
186 EFI_STRING ConfigRequestHdr;\r
187 EFI_STRING ConfigRequest;\r
188 BOOLEAN AllocatedRequest;\r
189 UINTN Size;\r
190\r
191 if (Progress == NULL || Results == NULL) {\r
192 return EFI_INVALID_PARAMETER;\r
193 }\r
194\r
195 *Progress = Request;\r
196 if ((Request != NULL) && !HiiIsConfigHdrMatch (Request, &mBootMaintGuid, mBootMaintStorageName)) {\r
197 return EFI_NOT_FOUND;\r
198 }\r
199\r
200 ConfigRequestHdr = NULL;\r
201 ConfigRequest = NULL;\r
202 AllocatedRequest = FALSE;\r
203 Size = 0;\r
204\r
205 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
206 //\r
207 // Convert buffer data to <ConfigResp> by helper function BlockToConfig()\r
208 //\r
209 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
210 ConfigRequest = Request;\r
211 if ((Request == NULL) || (StrStr (Request, L"OFFSET") == NULL)) {\r
212 //\r
213 // Request has no request element, construct full request string.\r
214 // Allocate and fill a buffer large enough to hold the <ConfigHdr> template\r
215 // followed by "&OFFSET=0&WIDTH=WWWWWWWWWWWWWWWW" followed by a Null-terminator\r
216 //\r
217 ConfigRequestHdr = HiiConstructConfigHdr (&mBootMaintGuid, mBootMaintStorageName, Private->BmmDriverHandle);\r
218 Size = (StrLen (ConfigRequestHdr) + 32 + 1) * sizeof (CHAR16);\r
219 ConfigRequest = AllocateZeroPool (Size);\r
220 ASSERT (ConfigRequest != NULL);\r
221 AllocatedRequest = TRUE;\r
222 UnicodeSPrint (ConfigRequest, Size, L"%s&OFFSET=0&WIDTH=%016LX", ConfigRequestHdr, (UINT64)BufferSize);\r
223 FreePool (ConfigRequestHdr);\r
224 }\r
225\r
226 Status = gHiiConfigRouting->BlockToConfig (\r
227 gHiiConfigRouting,\r
228 ConfigRequest,\r
229 (UINT8 *) &Private->BmmFakeNvData,\r
230 BufferSize,\r
231 Results,\r
232 Progress\r
233 );\r
234 //\r
235 // Free the allocated config request string.\r
236 //\r
237 if (AllocatedRequest) {\r
238 FreePool (ConfigRequest);\r
239 ConfigRequest = NULL;\r
240 }\r
241 //\r
242 // Set Progress string to the original request string.\r
243 //\r
244 if (Request == NULL) {\r
245 *Progress = NULL;\r
246 } else if (StrStr (Request, L"OFFSET") == NULL) {\r
247 *Progress = Request + StrLen (Request);\r
248 }\r
249\r
250 return Status;\r
251}\r
252\r
253/**\r
254 This function applies changes in a driver's configuration.\r
255 Input is a Configuration, which has the routing data for this\r
256 driver followed by name / value configuration pairs. The driver\r
257 must apply those pairs to its configurable storage. If the\r
258 driver's configuration is stored in a linear block of data\r
259 and the driver's name / value pairs are in <BlockConfig>\r
260 format, it may use the ConfigToBlock helper function (above) to\r
261 simplify the job. Currently not implemented.\r
262\r
263 @param[in] This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
264 @param[in] Configuration A null-terminated Unicode string in\r
265 <ConfigString> format. \r
266 @param[out] Progress A pointer to a string filled in with the\r
267 offset of the most recent '&' before the\r
268 first failing name / value pair (or the\r
269 beginn ing of the string if the failure\r
270 is in the first name / value pair) or\r
271 the terminating NULL if all was\r
272 successful.\r
273\r
274 @retval EFI_SUCCESS The results have been distributed or are\r
275 awaiting distribution. \r
276 @retval EFI_OUT_OF_RESOURCES Not enough memory to store the\r
277 parts of the results that must be\r
278 stored awaiting possible future\r
279 protocols.\r
280 @retval EFI_INVALID_PARAMETERS Passing in a NULL for the\r
281 Results parameter would result\r
282 in this type of error.\r
283 @retval EFI_NOT_FOUND Target for the specified routing data\r
284 was not found.\r
285**/\r
286EFI_STATUS\r
287EFIAPI\r
288BootMaintRouteConfig (\r
289 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
290 IN CONST EFI_STRING Configuration,\r
291 OUT EFI_STRING *Progress\r
292 )\r
293{\r
294 EFI_STATUS Status;\r
295 UINTN BufferSize;\r
296 EFI_HII_CONFIG_ROUTING_PROTOCOL *ConfigRouting;\r
297 BMM_FAKE_NV_DATA *NewBmmData;\r
298 BMM_FAKE_NV_DATA *OldBmmData;\r
a22a50fa
DB
299 BM_CONSOLE_CONTEXT *NewConsoleContext;\r
300 BM_TERMINAL_CONTEXT *NewTerminalContext;\r
143f0b1d
ED
301 BM_MENU_ENTRY *NewMenuEntry;\r
302 BM_LOAD_CONTEXT *NewLoadContext;\r
a22a50fa
DB
303 UINT16 Index;\r
304 BOOLEAN TerminalAttChange;\r
143f0b1d
ED
305 BMM_CALLBACK_DATA *Private; \r
306\r
307 if (Progress == NULL) {\r
308 return EFI_INVALID_PARAMETER;\r
309 }\r
310 *Progress = Configuration;\r
311\r
312 if (Configuration == NULL) {\r
313 return EFI_INVALID_PARAMETER;\r
314 }\r
315\r
316 //\r
317 // Check routing data in <ConfigHdr>.\r
318 // Note: there is no name for Name/Value storage, only GUID will be checked\r
319 //\r
320 if (!HiiIsConfigHdrMatch (Configuration, &mBootMaintGuid, mBootMaintStorageName)) {\r
321 return EFI_NOT_FOUND;\r
322 }\r
323\r
324 Status = gBS->LocateProtocol (\r
325 &gEfiHiiConfigRoutingProtocolGuid, \r
326 NULL, \r
327 (VOID **)&ConfigRouting\r
328 );\r
329 if (EFI_ERROR (Status)) {\r
330 return Status;\r
331 }\r
332 \r
333 Private = BMM_CALLBACK_DATA_FROM_THIS (This); \r
334 //\r
335 // Get Buffer Storage data from EFI variable\r
336 //\r
337 BufferSize = sizeof (BMM_FAKE_NV_DATA);\r
338 OldBmmData = &Private->BmmOldFakeNVData;\r
339 NewBmmData = &Private->BmmFakeNvData;\r
340 //\r
341 // Convert <ConfigResp> to buffer data by helper function ConfigToBlock()\r
342 //\r
343 Status = ConfigRouting->ConfigToBlock (\r
344 ConfigRouting,\r
345 Configuration,\r
346 (UINT8 *) NewBmmData,\r
347 &BufferSize,\r
348 Progress\r
349 );\r
350 ASSERT_EFI_ERROR (Status); \r
351 //\r
352 // Compare new and old BMM configuration data and only do action for modified item to \r
353 // avoid setting unnecessary non-volatile variable\r
354 //\r
355 \r
356 //\r
357 // Check data which located in BMM main page and save the settings if need\r
358 // \r
359 if (CompareMem (&NewBmmData->BootNext, &OldBmmData->BootNext, sizeof (NewBmmData->BootNext)) != 0) {\r
360 Status = Var_UpdateBootNext (Private);\r
361 }\r
362 \r
363 //\r
364 // Check data which located in Boot Options Menu and save the settings if need\r
365 // \r
366 if (CompareMem (NewBmmData->BootOptionDel, OldBmmData->BootOptionDel, sizeof (NewBmmData->BootOptionDel)) != 0) { \r
367 for (Index = 0; \r
368 ((Index < BootOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->BootOptionDel) / sizeof (NewBmmData->BootOptionDel[0])))); \r
369 Index ++) {\r
370 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
371 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
372 NewLoadContext->Deleted = NewBmmData->BootOptionDel[Index];\r
373 NewBmmData->BootOptionDel[Index] = FALSE;\r
a22a50fa 374 NewBmmData->BootOptionDelMark[Index] = FALSE;\r
143f0b1d
ED
375 }\r
376 \r
377 Var_DelBootOption ();\r
378 }\r
379 \r
380 if (CompareMem (NewBmmData->BootOptionOrder, OldBmmData->BootOptionOrder, sizeof (NewBmmData->BootOptionOrder)) != 0) { \r
381 Status = Var_UpdateBootOrder (Private);\r
a22a50fa
DB
382 }\r
383\r
384 if (CompareMem (&NewBmmData->BootTimeOut, &OldBmmData->BootTimeOut, sizeof (NewBmmData->BootTimeOut)) != 0){\r
385 Status = gRT->SetVariable(\r
386 L"Timeout",\r
387 &gEfiGlobalVariableGuid,\r
388 EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
389 sizeof(UINT16),\r
390 &(NewBmmData->BootTimeOut)\r
391 );\r
392 ASSERT_EFI_ERROR(Status);\r
393\r
394 Private->BmmOldFakeNVData.BootTimeOut = NewBmmData->BootTimeOut;\r
395 }\r
143f0b1d
ED
396\r
397 //\r
398 // Check data which located in Driver Options Menu and save the settings if need\r
399 // \r
400 if (CompareMem (NewBmmData->DriverOptionDel, OldBmmData->DriverOptionDel, sizeof (NewBmmData->DriverOptionDel)) != 0) { \r
401 for (Index = 0; \r
402 ((Index < DriverOptionMenu.MenuNumber) && (Index < (sizeof (NewBmmData->DriverOptionDel) / sizeof (NewBmmData->DriverOptionDel[0])))); \r
403 Index++) {\r
404 NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
405 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
406 NewLoadContext->Deleted = NewBmmData->DriverOptionDel[Index];\r
407 NewBmmData->DriverOptionDel[Index] = FALSE;\r
a22a50fa 408 NewBmmData->DriverOptionDelMark[Index] = FALSE;\r
143f0b1d
ED
409 }\r
410 Var_DelDriverOption (); \r
411 }\r
412 \r
413 if (CompareMem (NewBmmData->DriverOptionOrder, OldBmmData->DriverOptionOrder, sizeof (NewBmmData->DriverOptionOrder)) != 0) { \r
414 Status = Var_UpdateDriverOrder (Private);\r
a22a50fa
DB
415 }\r
416\r
417 if (CompareMem (&NewBmmData->ConsoleOutMode, &OldBmmData->ConsoleOutMode, sizeof (NewBmmData->ConsoleOutMode)) != 0){\r
418 Var_UpdateConMode(Private);\r
419 }\r
420\r
421 TerminalAttChange = FALSE;\r
422 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
423\r
424 //\r
425 // only need update modified items\r
426 //\r
427 if (CompareMem (&NewBmmData->COMBaudRate[Index], &OldBmmData->COMBaudRate[Index], sizeof (NewBmmData->COMBaudRate[Index])) == 0 &&\r
428 CompareMem (&NewBmmData->COMDataRate[Index], &OldBmmData->COMDataRate[Index], sizeof (NewBmmData->COMDataRate[Index])) == 0 &&\r
429 CompareMem (&NewBmmData->COMStopBits[Index], &OldBmmData->COMStopBits[Index], sizeof (NewBmmData->COMStopBits[Index])) == 0 &&\r
430 CompareMem (&NewBmmData->COMParity[Index], &OldBmmData->COMParity[Index], sizeof (NewBmmData->COMParity[Index])) == 0 &&\r
431 CompareMem (&NewBmmData->COMTerminalType[Index], &OldBmmData->COMTerminalType[Index], sizeof (NewBmmData->COMTerminalType[Index])) == 0 &&\r
432 CompareMem (&NewBmmData->COMFlowControl[Index], &OldBmmData->COMFlowControl[Index], sizeof (NewBmmData->COMFlowControl[Index])) == 0) {\r
433 continue;\r
434 }\r
435\r
436 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
437 ASSERT (NewMenuEntry != NULL);\r
438 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
439 NewTerminalContext->BaudRateIndex = NewBmmData->COMBaudRate[Index];\r
440 ASSERT (NewBmmData->COMBaudRate[Index] < (sizeof (BaudRateList) / sizeof (BaudRateList[0])));\r
441 NewTerminalContext->BaudRate = BaudRateList[NewBmmData->COMBaudRate[Index]].Value;\r
442 NewTerminalContext->DataBitsIndex = NewBmmData->COMDataRate[Index];\r
443 ASSERT (NewBmmData->COMDataRate[Index] < (sizeof (DataBitsList) / sizeof (DataBitsList[0])));\r
444 NewTerminalContext->DataBits = (UINT8) DataBitsList[NewBmmData->COMDataRate[Index]].Value;\r
445 NewTerminalContext->StopBitsIndex = NewBmmData->COMStopBits[Index];\r
446 ASSERT (NewBmmData->COMStopBits[Index] < (sizeof (StopBitsList) / sizeof (StopBitsList[0])));\r
447 NewTerminalContext->StopBits = (UINT8) StopBitsList[NewBmmData->COMStopBits[Index]].Value;\r
448 NewTerminalContext->ParityIndex = NewBmmData->COMParity[Index];\r
449 ASSERT (NewBmmData->COMParity[Index] < (sizeof (ParityList) / sizeof (ParityList[0])));\r
450 NewTerminalContext->Parity = (UINT8) ParityList[NewBmmData->COMParity[Index]].Value;\r
451 NewTerminalContext->TerminalType = NewBmmData->COMTerminalType[Index];\r
452 NewTerminalContext->FlowControl = NewBmmData->COMFlowControl[Index];\r
453 ChangeTerminalDevicePath (\r
454 NewTerminalContext->DevicePath,\r
455 FALSE\r
456 );\r
457 TerminalAttChange = TRUE;\r
458 }\r
459 if (TerminalAttChange) {\r
460 Var_UpdateConsoleInpOption ();\r
461 Var_UpdateConsoleOutOption ();\r
462 Var_UpdateErrorOutOption ();\r
463 }\r
464 //\r
465 // Check data which located in Console Options Menu and save the settings if need\r
466 //\r
467 if (CompareMem (NewBmmData->ConsoleInCheck, OldBmmData->ConsoleInCheck, sizeof (NewBmmData->ConsoleInCheck)) != 0){\r
468 for (Index = 0; Index < ConsoleInpMenu.MenuNumber; Index++){\r
469 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleInpMenu, Index);\r
470 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
471 ASSERT (Index < MAX_MENU_NUMBER);\r
472 NewConsoleContext->IsActive = NewBmmData->ConsoleInCheck[Index];\r
473 }\r
474 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
475 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
476 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
477 ASSERT (Index + ConsoleInpMenu.MenuNumber < MAX_MENU_NUMBER);\r
478 NewTerminalContext->IsConIn = NewBmmData->ConsoleInCheck[Index + ConsoleInpMenu.MenuNumber];\r
479 }\r
480 Var_UpdateConsoleInpOption();\r
481 }\r
482\r
483 if (CompareMem (NewBmmData->ConsoleOutCheck, OldBmmData->ConsoleOutCheck, sizeof (NewBmmData->ConsoleOutCheck)) != 0){\r
484 for (Index = 0; Index < ConsoleOutMenu.MenuNumber; Index++){\r
485 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleOutMenu, Index);\r
486 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
487 ASSERT (Index < MAX_MENU_NUMBER);\r
488 NewConsoleContext->IsActive = NewBmmData->ConsoleOutCheck[Index];\r
489 }\r
490 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
491 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
492 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
493 ASSERT (Index + ConsoleOutMenu.MenuNumber < MAX_MENU_NUMBER);\r
494 NewTerminalContext->IsConOut = NewBmmData->ConsoleOutCheck[Index + ConsoleOutMenu.MenuNumber];\r
495 }\r
496 Var_UpdateConsoleOutOption();\r
497 }\r
498\r
499 if (CompareMem (NewBmmData->ConsoleErrCheck, OldBmmData->ConsoleErrCheck, sizeof (NewBmmData->ConsoleErrCheck)) != 0){\r
500 for (Index = 0; Index < ConsoleErrMenu.MenuNumber; Index++){\r
501 NewMenuEntry = BOpt_GetMenuEntry(&ConsoleErrMenu, Index);\r
502 NewConsoleContext = (BM_CONSOLE_CONTEXT *)NewMenuEntry->VariableContext;\r
503 ASSERT (Index < MAX_MENU_NUMBER);\r
504 NewConsoleContext->IsActive = NewBmmData->ConsoleErrCheck[Index];\r
505 }\r
506 for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {\r
507 NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);\r
508 NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;\r
509 ASSERT (Index + ConsoleErrMenu.MenuNumber < MAX_MENU_NUMBER);\r
510 NewTerminalContext->IsStdErr = NewBmmData->ConsoleErrCheck[Index + ConsoleErrMenu.MenuNumber];\r
511 }\r
512 Var_UpdateErrorOutOption();\r
513 }\r
143f0b1d
ED
514\r
515 //\r
516 // After user do the save action, need to update OldBmmData.\r
517 //\r
518 CopyMem (OldBmmData, NewBmmData, sizeof (BMM_FAKE_NV_DATA));\r
519\r
520 return EFI_SUCCESS;\r
521}\r
522\r
523/**\r
524 This function processes the results of changes in configuration.\r
525\r
526\r
527 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.\r
528 @param Action Specifies the type of action taken by the browser.\r
529 @param QuestionId A unique value which is sent to the original exporting driver\r
530 so that it can identify the type of data to expect.\r
531 @param Type The type of value for the question.\r
532 @param Value A pointer to the data being sent to the original exporting driver.\r
533 @param ActionRequest On return, points to the action requested by the callback function.\r
534\r
535 @retval EFI_SUCCESS The callback successfully handled the action.\r
536 @retval EFI_OUT_OF_RESOURCES Not enough storage is available to hold the variable and its data.\r
537 @retval EFI_DEVICE_ERROR The variable could not be saved.\r
538 @retval EFI_UNSUPPORTED The specified Action is not supported by the callback.\r
539 @retval EFI_INVALID_PARAMETER The parameter of Value or ActionRequest is invalid.\r
540**/\r
541EFI_STATUS\r
542EFIAPI\r
543BootMaintCallback (\r
544 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL *This,\r
545 IN EFI_BROWSER_ACTION Action,\r
546 IN EFI_QUESTION_ID QuestionId,\r
547 IN UINT8 Type,\r
548 IN EFI_IFR_TYPE_VALUE *Value,\r
549 OUT EFI_BROWSER_ACTION_REQUEST *ActionRequest\r
550 )\r
551{\r
552 BMM_CALLBACK_DATA *Private;\r
553 BM_MENU_ENTRY *NewMenuEntry;\r
554 BMM_FAKE_NV_DATA *CurrentFakeNVMap;\r
143f0b1d
ED
555 UINTN OldValue;\r
556 UINTN NewValue;\r
557 UINTN Number;\r
558 UINTN Index;\r
559\r
560 //\r
561 //Chech whether exit from FileExplorer and reenter BM,if yes,reclaim string depositories\r
562 //\r
563 if (Action == EFI_BROWSER_ACTION_FORM_OPEN){\r
564 if(mEnterFileExplorer ){\r
565 ReclaimStringDepository();\r
566 mEnterFileExplorer = FALSE;\r
567 }\r
568 }\r
569\r
570 if (Action != EFI_BROWSER_ACTION_CHANGING && Action != EFI_BROWSER_ACTION_CHANGED) {\r
571 //\r
572 // Do nothing for other UEFI Action. Only do call back when data is changed.\r
573 //\r
574 return EFI_UNSUPPORTED;\r
575 }\r
576\r
577 OldValue = 0;\r
578 NewValue = 0;\r
579 Number = 0;\r
580\r
581 Private = BMM_CALLBACK_DATA_FROM_THIS (This);\r
582\r
583 //\r
584 // Retrive uncommitted data from Form Browser\r
585 //\r
586 CurrentFakeNVMap = &Private->BmmFakeNvData;\r
587 HiiGetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap);\r
588\r
589 if (Action == EFI_BROWSER_ACTION_CHANGING) {\r
590 if (Value == NULL) {\r
591 return EFI_INVALID_PARAMETER;\r
592 }\r
593 \r
594 UpdatePageId (Private, QuestionId);\r
595\r
596 if (QuestionId < FILE_OPTION_OFFSET) {\r
597 if (QuestionId < CONFIG_OPTION_OFFSET) {\r
598 switch (QuestionId) {\r
599 case FORM_BOOT_ADD_ID:\r
600 // Leave Bm and enter FileExplorer.\r
601 Private->FeCurrentState = FileExplorerStateAddBootOption;\r
602 Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
603 ReclaimStringDepository (); \r
604 UpdateFileExplorer(Private, 0);\r
605 mEnterFileExplorer = TRUE;\r
606 break;\r
607\r
608 case FORM_DRV_ADD_FILE_ID:\r
609 // Leave Bm and enter FileExplorer.\r
610 Private->FeCurrentState = FileExplorerStateAddDriverOptionState;\r
611 Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
612 ReclaimStringDepository ();\r
613 UpdateFileExplorer(Private, 0);\r
614 mEnterFileExplorer = TRUE;\r
615 break;\r
616\r
617 case FORM_DRV_ADD_HANDLE_ID:\r
618 CleanUpPage (FORM_DRV_ADD_HANDLE_ID, Private);\r
619 UpdateDrvAddHandlePage (Private);\r
620 break;\r
621\r
622 case FORM_BOOT_DEL_ID:\r
623 CleanUpPage (FORM_BOOT_DEL_ID, Private);\r
624 UpdateBootDelPage (Private);\r
625 break;\r
626\r
627 case FORM_BOOT_CHG_ID:\r
628 case FORM_DRV_CHG_ID:\r
629 UpdatePageBody (QuestionId, Private);\r
630 break;\r
631\r
632 case FORM_DRV_DEL_ID:\r
633 CleanUpPage (FORM_DRV_DEL_ID, Private);\r
634 UpdateDrvDelPage (Private);\r
635 break;\r
636\r
637 case FORM_BOOT_NEXT_ID:\r
638 CleanUpPage (FORM_BOOT_NEXT_ID, Private);\r
639 UpdateBootNextPage (Private);\r
640 break;\r
641\r
642 case FORM_TIME_OUT_ID:\r
643 CleanUpPage (FORM_TIME_OUT_ID, Private);\r
644 UpdateTimeOutPage (Private);\r
645 break;\r
646\r
647 case FORM_CON_IN_ID:\r
648 case FORM_CON_OUT_ID:\r
649 case FORM_CON_ERR_ID:\r
650 UpdatePageBody (QuestionId, Private);\r
651 break;\r
652\r
653 case FORM_CON_MODE_ID:\r
654 CleanUpPage (FORM_CON_MODE_ID, Private);\r
655 UpdateConModePage (Private);\r
656 break;\r
657\r
658 case FORM_CON_COM_ID:\r
659 CleanUpPage (FORM_CON_COM_ID, Private);\r
660 UpdateConCOMPage (Private);\r
661 break;\r
662\r
663 default:\r
664 break;\r
665 }\r
666 } else if ((QuestionId >= TERMINAL_OPTION_OFFSET) && (QuestionId < CONSOLE_OPTION_OFFSET)) {\r
667 Index = (UINT16) (QuestionId - TERMINAL_OPTION_OFFSET);\r
668 Private->CurrentTerminal = Index;\r
669\r
670 CleanUpPage (FORM_CON_COM_SETUP_ID, Private);\r
671 UpdateTerminalPage (Private);\r
672\r
673 } else if (QuestionId >= HANDLE_OPTION_OFFSET) {\r
674 Index = (UINT16) (QuestionId - HANDLE_OPTION_OFFSET);\r
675\r
676 NewMenuEntry = BOpt_GetMenuEntry (&DriverMenu, Index);\r
677 ASSERT (NewMenuEntry != NULL);\r
678 Private->HandleContext = (BM_HANDLE_CONTEXT *) NewMenuEntry->VariableContext;\r
679\r
680 CleanUpPage (FORM_DRV_ADD_HANDLE_DESC_ID, Private);\r
681\r
682 Private->MenuEntry = NewMenuEntry;\r
683 Private->LoadContext->FilePathList = Private->HandleContext->DevicePath;\r
684\r
685 UpdateDriverAddHandleDescPage (Private);\r
686 }\r
687 }\r
688 if (QuestionId == KEY_VALUE_BOOT_FROM_FILE){\r
689 // Leave Bm and enter FileExplorer.\r
690 Private->FeCurrentState = FileExplorerStateBootFromFile;\r
691 Private->FeDisplayContext = FileExplorerDisplayUnknown;\r
692 ReclaimStringDepository ();\r
693 UpdateFileExplorer(Private, 0);\r
694 mEnterFileExplorer = TRUE;\r
695 }\r
696 } else if (Action == EFI_BROWSER_ACTION_CHANGED) {\r
697 if ((Value == NULL) || (ActionRequest == NULL)) {\r
698 return EFI_INVALID_PARAMETER;\r
699 }\r
700\r
a22a50fa
DB
701 if ((QuestionId >= BOOT_OPTION_DEL_QUESTION_ID) && (QuestionId < BOOT_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
702 if (Value->b){\r
703 //\r
704 // Means user try to delete this boot option but not press F10 or "Commit Changes and Exit" menu.\r
705 //\r
706 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = TRUE;\r
707 } else {\r
708 //\r
709 // Means user remove the old check status.\r
710 //\r
711 CurrentFakeNVMap->BootOptionDelMark[QuestionId - BOOT_OPTION_DEL_QUESTION_ID] = FALSE;\r
143f0b1d 712 }\r
a22a50fa
DB
713 } else if ((QuestionId >= DRIVER_OPTION_DEL_QUESTION_ID) && (QuestionId < DRIVER_OPTION_DEL_QUESTION_ID + MAX_MENU_NUMBER)) {\r
714 if (Value->b){\r
715 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = TRUE;\r
716 } else {\r
717 CurrentFakeNVMap->DriverOptionDelMark[QuestionId - DRIVER_OPTION_DEL_QUESTION_ID] = FALSE;\r
718 }\r
719 } else {\r
720 switch (QuestionId) {\r
721 case KEY_VALUE_SAVE_AND_EXIT:\r
722 case KEY_VALUE_NO_SAVE_AND_EXIT:\r
723 if (QuestionId == KEY_VALUE_SAVE_AND_EXIT) {\r
724 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_SUBMIT_EXIT;\r
725 } else if (QuestionId == KEY_VALUE_NO_SAVE_AND_EXIT) {\r
726 DiscardChangeHandler (Private, CurrentFakeNVMap);\r
727 *ActionRequest = EFI_BROWSER_ACTION_REQUEST_FORM_DISCARD_EXIT;\r
728 }\r
143f0b1d 729\r
a22a50fa 730 break;\r
00db1dfc 731 \r
a22a50fa
DB
732 case FORM_RESET:\r
733 gRT->ResetSystem (EfiResetCold, EFI_SUCCESS, 0, NULL);\r
734 return EFI_UNSUPPORTED;\r
143f0b1d 735\r
a22a50fa
DB
736 default:\r
737 break;\r
738 }\r
143f0b1d
ED
739 }\r
740 }\r
741\r
742 //\r
743 // Pass changed uncommitted data back to Form Browser\r
744 //\r
745 HiiSetBrowserData (&mBootMaintGuid, mBootMaintStorageName, sizeof (BMM_FAKE_NV_DATA), (UINT8 *) CurrentFakeNVMap, NULL);\r
746\r
747 return EFI_SUCCESS;\r
748}\r
749\r
143f0b1d
ED
750/**\r
751 Discard all changes done to the BMM pages such as Boot Order change,\r
752 Driver order change.\r
753\r
754 @param Private The BMM context data.\r
755 @param CurrentFakeNVMap The current Fack NV Map.\r
756\r
757**/\r
758VOID\r
759DiscardChangeHandler (\r
760 IN BMM_CALLBACK_DATA *Private,\r
761 IN BMM_FAKE_NV_DATA *CurrentFakeNVMap\r
762 )\r
763{\r
764 UINT16 Index;\r
765\r
766 switch (Private->BmmPreviousPageId) {\r
767 case FORM_BOOT_CHG_ID:\r
768 CopyMem (CurrentFakeNVMap->BootOptionOrder, Private->BmmOldFakeNVData.BootOptionOrder, sizeof (CurrentFakeNVMap->BootOptionOrder));\r
769 break;\r
770 \r
771 case FORM_DRV_CHG_ID:\r
772 CopyMem (CurrentFakeNVMap->DriverOptionOrder, Private->BmmOldFakeNVData.DriverOptionOrder, sizeof (CurrentFakeNVMap->DriverOptionOrder));\r
773 break;\r
774\r
775 case FORM_BOOT_DEL_ID:\r
776 ASSERT (BootOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->BootOptionDel) / sizeof (CurrentFakeNVMap->BootOptionDel[0])));\r
777 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
778 CurrentFakeNVMap->BootOptionDel[Index] = FALSE;\r
779 }\r
780 break;\r
781\r
782 case FORM_DRV_DEL_ID:\r
783 ASSERT (DriverOptionMenu.MenuNumber <= (sizeof (CurrentFakeNVMap->DriverOptionDel) / sizeof (CurrentFakeNVMap->DriverOptionDel[0])));\r
784 for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {\r
785 CurrentFakeNVMap->DriverOptionDel[Index] = FALSE;\r
786 }\r
787 break;\r
788\r
789 case FORM_BOOT_NEXT_ID:\r
790 CurrentFakeNVMap->BootNext = Private->BmmOldFakeNVData.BootNext;\r
791 break;\r
792\r
793 case FORM_TIME_OUT_ID:\r
794 CurrentFakeNVMap->BootTimeOut = Private->BmmOldFakeNVData.BootTimeOut;\r
795 break;\r
796\r
797 case FORM_DRV_ADD_HANDLE_DESC_ID:\r
798 case FORM_DRV_ADD_FILE_ID:\r
799 case FORM_DRV_ADD_HANDLE_ID:\r
800 CurrentFakeNVMap->DriverAddHandleDesc[0] = 0x0000;\r
801 CurrentFakeNVMap->DriverAddHandleOptionalData[0] = 0x0000;\r
802 break;\r
803\r
804 default:\r
805 break;\r
806 }\r
807}\r
808\r
809\r
810/**\r
811 Create dynamic code for BMM.\r
812\r
813 @param BmmCallbackInfo The BMM context data.\r
814\r
815**/\r
816VOID\r
817InitializeDrivers(\r
818 IN BMM_CALLBACK_DATA *BmmCallbackInfo\r
819 )\r
820{\r
821 EFI_HII_HANDLE HiiHandle;\r
822 VOID *StartOpCodeHandle;\r
823 VOID *EndOpCodeHandle;\r
824 EFI_IFR_GUID_LABEL *StartLabel;\r
825 EFI_IFR_GUID_LABEL *EndLabel;\r
826 UINTN Index; \r
827 EFI_STRING_ID FormSetTitle;\r
828 EFI_STRING_ID FormSetHelp; \r
829 EFI_STRING String;\r
830 EFI_STRING_ID Token;\r
831 EFI_STRING_ID TokenHelp; \r
832 EFI_HII_HANDLE *HiiHandles;\r
833 UINTN SkipCount;\r
834 EFI_GUID FormSetGuid;\r
835 CHAR16 *DevicePathStr;\r
836 EFI_STRING_ID DevicePathId;\r
837\r
838 HiiHandle = BmmCallbackInfo->BmmHiiHandle;\r
839 //\r
840 // Allocate space for creation of UpdateData Buffer\r
841 //\r
842 StartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
843 ASSERT (StartOpCodeHandle != NULL);\r
844\r
845 EndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
846 ASSERT (EndOpCodeHandle != NULL);\r
847\r
848 //\r
849 // Create Hii Extend Label OpCode as the start opcode\r
850 //\r
851 StartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (StartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
852 StartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
853 StartLabel->Number = LABEL_BMM_PLATFORM_INFORMATION;\r
854\r
855 //\r
856 // Create Hii Extend Label OpCode as the end opcode\r
857 //\r
858 EndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (EndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
859 EndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
860 EndLabel->Number = LABEL_END;\r
861\r
862 //\r
863 // Get all the Hii handles\r
864 //\r
865 HiiHandles = HiiGetHiiHandles (NULL);\r
866 ASSERT (HiiHandles != NULL);\r
867\r
868 //\r
869 // Search for formset of each class type\r
870 //\r
871 SkipCount = 0;\r
872 for (Index = 0; HiiHandles[Index] != NULL; Index++) {\r
873 if (!ExtractDisplayedHiiFormFromHiiHandle (HiiHandles[Index], &gEfiIfrBootMaintenanceGuid, SkipCount, &FormSetTitle, &FormSetHelp, &FormSetGuid)) {\r
874 SkipCount = 0;\r
875 continue;\r
876 }\r
877 String = HiiGetString (HiiHandles[Index], FormSetTitle, NULL);\r
878 if (String == NULL) {\r
879 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);\r
880 ASSERT (String != NULL);\r
881 }\r
882 Token = HiiSetString (HiiHandle, 0, String, NULL);\r
883 FreePool (String);\r
884\r
885 String = HiiGetString (HiiHandles[Index], FormSetHelp, NULL);\r
886 if (String == NULL) {\r
887 String = HiiGetString (HiiHandle, STR_MISSING_STRING, NULL);\r
888 ASSERT (String != NULL);\r
889 }\r
890 TokenHelp = HiiSetString (HiiHandle, 0, String, NULL);\r
891 FreePool (String);\r
892\r
893 DevicePathStr = ExtractDevicePathFromHiiHandle(HiiHandles[Index]);\r
894 DevicePathId = 0;\r
895 if (DevicePathStr != NULL){\r
896 DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);\r
897 FreePool (DevicePathStr);\r
898 }\r
899\r
900 HiiCreateGotoExOpCode (\r
901 StartOpCodeHandle,\r
902 0,\r
903 Token,\r
904 TokenHelp,\r
905 0,\r
906 (EFI_QUESTION_ID) (Index + FRONT_PAGE_KEY_OFFSET),\r
907 0,\r
908 &FormSetGuid,\r
909 DevicePathId\r
910 );\r
911 //\r
912 //One packagelist may has more than one form package,\r
913 //Index-- means keep current HiiHandle and still extract from the packagelist, \r
914 //SkipCount++ means skip the formset which was found before in the same form package. \r
915 //\r
916 SkipCount++;\r
917 Index--;\r
918 }\r
919\r
920 HiiUpdateForm (\r
921 HiiHandle,\r
922 &mBootMaintGuid,\r
923 FORM_MAIN_ID,\r
924 StartOpCodeHandle,\r
925 EndOpCodeHandle\r
926 );\r
927\r
928 HiiFreeOpCodeHandle (StartOpCodeHandle);\r
929 HiiFreeOpCodeHandle (EndOpCodeHandle); \r
930 FreePool (HiiHandles);\r
931}\r
932\r
143f0b1d 933/**\r
a22a50fa
DB
934 Create dynamic code for BMM and initialize all of BMM configuration data in BmmFakeNvData and\r
935 BmmOldFakeNVData member in BMM context data.\r
143f0b1d 936\r
a22a50fa 937 @param CallbackData The BMM context data.\r
143f0b1d
ED
938\r
939**/\r
940VOID\r
a22a50fa
DB
941InitializeBmmConfig (\r
942 IN BMM_CALLBACK_DATA *CallbackData\r
143f0b1d
ED
943 )\r
944{\r
a22a50fa
DB
945 BM_MENU_ENTRY *NewMenuEntry;\r
946 BM_LOAD_CONTEXT *NewLoadContext;\r
947 UINT16 Index;\r
143f0b1d 948\r
a22a50fa
DB
949 ASSERT (CallbackData != NULL);\r
950\r
951 InitializeDrivers (CallbackData);\r
952\r
953 //\r
954 // Initialize data which located in BMM main page\r
955 //\r
956 CallbackData->BmmFakeNvData.BootNext = (UINT16) (BootOptionMenu.MenuNumber);\r
957 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
958 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
959 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
960\r
961 if (NewLoadContext->IsBootNext) {\r
962 CallbackData->BmmFakeNvData.BootNext = Index;\r
963 break;\r
964 }\r
143f0b1d
ED
965 }\r
966\r
a22a50fa
DB
967 CallbackData->BmmFakeNvData.BootTimeOut = PcdGet16 (PcdPlatformBootTimeOut);\r
968\r
969 //\r
970 // Initialize data which located in Boot Options Menu\r
971 //\r
972 GetBootOrder (CallbackData);\r
973\r
974 //\r
975 // Initialize data which located in Driver Options Menu\r
976 //\r
977 GetDriverOrder (CallbackData);\r
978\r
979 //\r
980 // Initialize data which located in Console Options Menu\r
981 // \r
982 GetConsoleOutMode (CallbackData);\r
983 GetConsoleInCheck (CallbackData);\r
984 GetConsoleOutCheck (CallbackData);\r
985 GetConsoleErrCheck (CallbackData);\r
986 GetTerminalAttribute (CallbackData);\r
987\r
988 //\r
989 // Backup Initialize BMM configuartion data to BmmOldFakeNVData\r
990 //\r
991 CopyMem (&CallbackData->BmmOldFakeNVData, &CallbackData->BmmFakeNvData, sizeof (BMM_FAKE_NV_DATA));\r
143f0b1d
ED
992}\r
993\r
994/**\r
995 Initialize the Boot Maintenance Utitliy.\r
996\r
997**/\r
998VOID\r
999InitializeBM (\r
1000 VOID\r
1001 )\r
1002{\r
1003 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1004\r
1005 BmmCallbackInfo = mBmmCallbackInfo;\r
1006 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1007 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1008 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;\r
1009 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;\r
1010\r
1011 InitAllMenu (BmmCallbackInfo);\r
1012\r
1013 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleInpMenu);\r
1014 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleOutMenu);\r
1015 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &ConsoleErrMenu);\r
1016 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &BootOptionMenu);\r
1017 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverOptionMenu);\r
1018 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &TerminalMenu);\r
1019 CreateMenuStringToken (BmmCallbackInfo, BmmCallbackInfo->BmmHiiHandle, &DriverMenu);\r
1020\r
1021 InitializeBmmConfig(BmmCallbackInfo);\r
1022}\r
1023\r
1024/**\r
1025 Initialized all Menu Option List.\r
1026\r
1027 @param CallbackData The BMM context data.\r
1028\r
1029**/\r
1030VOID\r
1031InitAllMenu (\r
1032 IN BMM_CALLBACK_DATA *CallbackData\r
1033 )\r
1034{\r
1035 InitializeListHead (&BootOptionMenu.Head);\r
1036 InitializeListHead (&DriverOptionMenu.Head);\r
1037 BOpt_GetBootOptions (CallbackData);\r
1038 BOpt_GetDriverOptions (CallbackData);\r
1039 InitializeListHead (&FsOptionMenu.Head);\r
1040 BOpt_FindDrivers ();\r
1041 InitializeListHead (&DirectoryMenu.Head);\r
1042 InitializeListHead (&ConsoleInpMenu.Head);\r
1043 InitializeListHead (&ConsoleOutMenu.Head);\r
1044 InitializeListHead (&ConsoleErrMenu.Head);\r
1045 InitializeListHead (&TerminalMenu.Head);\r
1046 LocateSerialIo ();\r
1047 GetAllConsoles ();\r
1048 mAllMenuInit = TRUE;\r
1049}\r
1050\r
1051/**\r
1052 Free up all Menu Option list.\r
1053\r
1054**/\r
1055VOID\r
1056FreeAllMenu (\r
1057 VOID\r
1058 )\r
1059{\r
1060 if (!mAllMenuInit){\r
1061 return;\r
1062 }\r
1063 BOpt_FreeMenu (&DirectoryMenu);\r
1064 BOpt_FreeMenu (&FsOptionMenu);\r
1065 BOpt_FreeMenu (&BootOptionMenu);\r
1066 BOpt_FreeMenu (&DriverOptionMenu);\r
1067 BOpt_FreeMenu (&DriverMenu);\r
1068 FreeAllConsoles ();\r
1069 mAllMenuInit = FALSE;\r
1070}\r
1071\r
1072/**\r
1073 Initialize all the string depositories.\r
1074\r
1075**/\r
1076VOID\r
1077InitializeStringDepository (\r
1078 VOID\r
1079 )\r
1080{\r
1081 STRING_DEPOSITORY *StringDepository;\r
1082 StringDepository = AllocateZeroPool (sizeof (STRING_DEPOSITORY) * STRING_DEPOSITORY_NUMBER);\r
1083 FileOptionStrDepository = StringDepository++;\r
1084 ConsoleOptionStrDepository = StringDepository++;\r
1085 BootOptionStrDepository = StringDepository++;\r
1086 BootOptionHelpStrDepository = StringDepository++;\r
1087 DriverOptionStrDepository = StringDepository++;\r
1088 DriverOptionHelpStrDepository = StringDepository++;\r
1089 TerminalStrDepository = StringDepository;\r
1090}\r
1091\r
1092/**\r
1093 Fetch a usable string node from the string depository and return the string token.\r
1094\r
1095 @param CallbackData The BMM context data.\r
1096 @param StringDepository The string repository.\r
1097\r
1098 @retval EFI_STRING_ID String token.\r
1099\r
1100**/\r
1101EFI_STRING_ID\r
1102GetStringTokenFromDepository (\r
1103 IN BMM_CALLBACK_DATA *CallbackData,\r
1104 IN STRING_DEPOSITORY *StringDepository\r
1105 )\r
1106{\r
1107 STRING_LIST_NODE *CurrentListNode;\r
1108 STRING_LIST_NODE *NextListNode;\r
1109\r
1110 CurrentListNode = StringDepository->CurrentNode;\r
1111\r
1112 if ((NULL != CurrentListNode) && (NULL != CurrentListNode->Next)) {\r
1113 //\r
1114 // Fetch one reclaimed node from the list.\r
1115 //\r
1116 NextListNode = StringDepository->CurrentNode->Next;\r
1117 } else {\r
1118 //\r
1119 // If there is no usable node in the list, update the list.\r
1120 //\r
1121 NextListNode = AllocateZeroPool (sizeof (STRING_LIST_NODE));\r
1122 ASSERT (NextListNode != NULL);\r
1123 NextListNode->StringToken = HiiSetString (CallbackData->BmmHiiHandle, 0, L" ", NULL);\r
1124 ASSERT (NextListNode->StringToken != 0);\r
1125\r
1126 StringDepository->TotalNodeNumber++;\r
1127\r
1128 if (NULL == CurrentListNode) {\r
1129 StringDepository->ListHead = NextListNode;\r
1130 } else {\r
1131 CurrentListNode->Next = NextListNode;\r
1132 }\r
1133 }\r
1134\r
1135 StringDepository->CurrentNode = NextListNode;\r
1136\r
1137 return StringDepository->CurrentNode->StringToken;\r
1138}\r
1139\r
1140/**\r
1141 Reclaim string depositories by moving the current node pointer to list head..\r
1142\r
1143**/\r
1144VOID\r
1145ReclaimStringDepository (\r
1146 VOID\r
1147 )\r
1148{\r
1149 UINTN DepositoryIndex;\r
1150 STRING_DEPOSITORY *StringDepository;\r
1151\r
1152 StringDepository = FileOptionStrDepository;\r
1153 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1154 StringDepository->CurrentNode = StringDepository->ListHead;\r
1155 StringDepository++;\r
1156 }\r
1157}\r
1158\r
1159/**\r
1160 Release resource for all the string depositories.\r
1161\r
1162**/\r
1163VOID\r
1164CleanUpStringDepository (\r
1165 VOID\r
1166 )\r
1167{\r
1168 UINTN NodeIndex;\r
1169 UINTN DepositoryIndex;\r
1170 STRING_LIST_NODE *CurrentListNode;\r
1171 STRING_LIST_NODE *NextListNode;\r
1172 STRING_DEPOSITORY *StringDepository;\r
1173\r
1174 //\r
1175 // Release string list nodes.\r
1176 //\r
1177 StringDepository = FileOptionStrDepository;\r
1178 for (DepositoryIndex = 0; DepositoryIndex < STRING_DEPOSITORY_NUMBER; DepositoryIndex++) {\r
1179 CurrentListNode = StringDepository->ListHead;\r
1180 for (NodeIndex = 0; NodeIndex < StringDepository->TotalNodeNumber; NodeIndex++) {\r
1181 NextListNode = CurrentListNode->Next;\r
1182 FreePool (CurrentListNode);\r
1183 CurrentListNode = NextListNode;\r
1184 }\r
1185\r
1186 StringDepository++;\r
1187 }\r
1188 //\r
1189 // Release string depository.\r
1190 //\r
1191 FreePool (FileOptionStrDepository);\r
1192}\r
1193\r
1194/**\r
1195 Install BootMaint and FileExplorer HiiPackages.\r
1196\r
1197**/\r
1198VOID\r
1199InitBootMaintenance(\r
1200 VOID\r
1201 )\r
1202{\r
1203 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1204 EFI_STATUS Status;\r
1205 UINT8 *Ptr;\r
1206\r
1207 Status = EFI_SUCCESS;\r
1208\r
1209 if (!gConnectAllHappened){\r
1210 EfiBootManagerConnectAll();\r
1211 gConnectAllHappened = TRUE;\r
1212 }\r
1213\r
1214 EfiBootManagerRefreshAllBootOption ();\r
1215\r
1216 //\r
1217 // Create CallbackData structures for Driver Callback\r
1218 //\r
1219 BmmCallbackInfo = AllocateZeroPool (sizeof (BMM_CALLBACK_DATA));\r
1220 ASSERT (BmmCallbackInfo != NULL);\r
1221\r
1222 //\r
1223 // Create LoadOption in BmmCallbackInfo for Driver Callback\r
1224 //\r
1225 Ptr = AllocateZeroPool (sizeof (BM_LOAD_CONTEXT) + sizeof (BM_FILE_CONTEXT) + sizeof (BM_HANDLE_CONTEXT) + sizeof (BM_MENU_ENTRY));\r
1226 ASSERT (Ptr != NULL);\r
1227\r
1228 //\r
1229 // Initialize Bmm callback data.\r
1230 //\r
1231 BmmCallbackInfo->LoadContext = (BM_LOAD_CONTEXT *) Ptr;\r
1232 Ptr += sizeof (BM_LOAD_CONTEXT);\r
1233\r
1234 BmmCallbackInfo->FileContext = (BM_FILE_CONTEXT *) Ptr;\r
1235 Ptr += sizeof (BM_FILE_CONTEXT);\r
1236\r
1237 BmmCallbackInfo->HandleContext = (BM_HANDLE_CONTEXT *) Ptr;\r
1238 Ptr += sizeof (BM_HANDLE_CONTEXT);\r
1239\r
1240 BmmCallbackInfo->MenuEntry = (BM_MENU_ENTRY *) Ptr;\r
1241\r
1242 BmmCallbackInfo->Signature = BMM_CALLBACK_DATA_SIGNATURE;\r
1243 BmmCallbackInfo->BmmConfigAccess.ExtractConfig = BootMaintExtractConfig;\r
1244 BmmCallbackInfo->BmmConfigAccess.RouteConfig = BootMaintRouteConfig;\r
1245 BmmCallbackInfo->BmmConfigAccess.Callback = BootMaintCallback;\r
1246 BmmCallbackInfo->BmmPreviousPageId = FORM_MAIN_ID;\r
1247 BmmCallbackInfo->BmmCurrentPageId = FORM_MAIN_ID;\r
1248 BmmCallbackInfo->FeConfigAccess.ExtractConfig = FakeExtractConfig;\r
a22a50fa 1249 BmmCallbackInfo->FeConfigAccess.RouteConfig = FileExplorerRouteConfig;\r
143f0b1d
ED
1250 BmmCallbackInfo->FeConfigAccess.Callback = FileExplorerCallback;\r
1251 BmmCallbackInfo->FeCurrentState = FileExplorerStateInActive;\r
1252 BmmCallbackInfo->FeDisplayContext = FileExplorerDisplayUnknown;\r
1253\r
1254 //\r
1255 // Install Device Path Protocol and Config Access protocol to driver handle\r
1256 //\r
1257 Status = gBS->InstallMultipleProtocolInterfaces (\r
1258 &BmmCallbackInfo->BmmDriverHandle,\r
1259 &gEfiDevicePathProtocolGuid,\r
1260 &mBmmHiiVendorDevicePath,\r
1261 &gEfiHiiConfigAccessProtocolGuid,\r
1262 &BmmCallbackInfo->BmmConfigAccess,\r
1263 NULL\r
1264 );\r
1265 ASSERT_EFI_ERROR (Status);\r
1266\r
1267 //\r
1268 // Install Device Path Protocol and Config Access protocol to driver handle\r
1269 //\r
1270 Status = gBS->InstallMultipleProtocolInterfaces (\r
1271 &BmmCallbackInfo->FeDriverHandle,\r
1272 &gEfiDevicePathProtocolGuid,\r
1273 &mFeHiiVendorDevicePath,\r
1274 &gEfiHiiConfigAccessProtocolGuid,\r
1275 &BmmCallbackInfo->FeConfigAccess,\r
1276 NULL\r
1277 );\r
1278 ASSERT_EFI_ERROR (Status);\r
1279\r
1280 //\r
1281 // Post our Boot Maint VFR binary to the HII database.\r
1282 //\r
1283 BmmCallbackInfo->BmmHiiHandle = HiiAddPackages (\r
1284 &mBootMaintGuid,\r
1285 BmmCallbackInfo->BmmDriverHandle,\r
1286 BmBin,\r
1287 UiAppStrings,\r
1288 NULL\r
1289 );\r
1290 ASSERT (BmmCallbackInfo->BmmHiiHandle != NULL);\r
1291\r
1292 //\r
1293 // Post our File Explorer VFR binary to the HII database.\r
1294 //\r
1295 BmmCallbackInfo->FeHiiHandle = HiiAddPackages (\r
1296 &mFileExplorerGuid,\r
1297 BmmCallbackInfo->FeDriverHandle,\r
1298 FEBin,\r
1299 UiAppStrings,\r
1300 NULL\r
1301 );\r
1302 ASSERT (BmmCallbackInfo->FeHiiHandle != NULL);\r
1303\r
1304 //\r
1305 // Init OpCode Handle and Allocate space for creation of Buffer\r
1306 //\r
1307 mStartOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1308 ASSERT (mStartOpCodeHandle != NULL);\r
1309\r
1310 mEndOpCodeHandle = HiiAllocateOpCodeHandle ();\r
1311 ASSERT (mEndOpCodeHandle != NULL);\r
1312\r
1313 //\r
1314 // Create Hii Extend Label OpCode as the start opcode\r
1315 //\r
1316 mStartLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mStartOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1317 mStartLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1318\r
1319 //\r
1320 // Create Hii Extend Label OpCode as the end opcode\r
1321 //\r
1322 mEndLabel = (EFI_IFR_GUID_LABEL *) HiiCreateGuidOpCode (mEndOpCodeHandle, &gEfiIfrTianoGuid, NULL, sizeof (EFI_IFR_GUID_LABEL));\r
1323 mEndLabel->ExtendOpCode = EFI_IFR_EXTEND_OP_LABEL;\r
1324 mEndLabel->Number = LABEL_END;\r
1325\r
1326 mBmmCallbackInfo = BmmCallbackInfo;\r
1327\r
1328 InitializeStringDepository ();\r
1329\r
1330}\r
1331\r
1332/**\r
1333 Remove the installed BootMaint and FileExplorer HiiPackages.\r
1334\r
1335**/\r
143f0b1d
ED
1336VOID\r
1337FreeBMPackage(\r
1338 VOID\r
1339 )\r
1340{\r
1341 BMM_CALLBACK_DATA *BmmCallbackInfo;\r
1342\r
1343 if (mStartOpCodeHandle != NULL) {\r
1344 HiiFreeOpCodeHandle (mStartOpCodeHandle);\r
1345 }\r
1346\r
1347 if (mEndOpCodeHandle != NULL) {\r
1348 HiiFreeOpCodeHandle (mEndOpCodeHandle);\r
1349 }\r
1350\r
1351 FreeAllMenu ();\r
1352 CleanUpStringDepository ();\r
1353\r
1354 BmmCallbackInfo = mBmmCallbackInfo;\r
1355\r
1356 //\r
1357 // Remove our IFR data from HII database\r
1358 //\r
1359 HiiRemovePackages (BmmCallbackInfo->BmmHiiHandle);\r
1360 HiiRemovePackages (BmmCallbackInfo->FeHiiHandle);\r
1361\r
1362 gBS->UninstallMultipleProtocolInterfaces (\r
1363 BmmCallbackInfo->FeDriverHandle,\r
1364 &gEfiDevicePathProtocolGuid,\r
1365 &mFeHiiVendorDevicePath,\r
1366 &gEfiHiiConfigAccessProtocolGuid,\r
1367 &BmmCallbackInfo->FeConfigAccess,\r
1368 NULL\r
1369 );\r
1370\r
1371 gBS->UninstallMultipleProtocolInterfaces (\r
1372 BmmCallbackInfo->BmmDriverHandle,\r
1373 &gEfiDevicePathProtocolGuid,\r
1374 &mBmmHiiVendorDevicePath,\r
1375 &gEfiHiiConfigAccessProtocolGuid,\r
1376 &BmmCallbackInfo->BmmConfigAccess,\r
1377 NULL\r
1378 );\r
1379\r
1380 FreePool (BmmCallbackInfo->LoadContext);\r
1381 FreePool (BmmCallbackInfo);\r
1382}\r
1383\r