]> git.proxmox.com Git - mirror_edk2.git/blame - MdeModulePkg/Library/BootMaintenanceManagerUiLib/BootMaintenanceManagerCustomizedUiSupport.c
MdeModulePkg/DisplayEngine: Fix memory leak issues in DisplayEngine
[mirror_edk2.git] / MdeModulePkg / Library / BootMaintenanceManagerUiLib / BootMaintenanceManagerCustomizedUiSupport.c
CommitLineData
a85be3ae
ED
1/** @file\r
2The functions for Boot Maintainence Main menu.\r
3\r
4Copyright (c) 2004 - 2016, Intel Corporation. All rights reserved.<BR>\r
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\r
16#include "BootMaintenanceManager.h"\r
17#include "BootMaintenanceManagerCustomizedUiSupport.h"\r
18\r
19#define UI_HII_DRIVER_LIST_SIZE 0x8\r
20\r
21typedef struct {\r
22 EFI_STRING_ID PromptId;\r
23 EFI_STRING_ID HelpId;\r
24 EFI_STRING_ID DevicePathId;\r
25 EFI_GUID FormSetGuid;\r
26 BOOLEAN EmptyLineAfter;\r
27} UI_HII_DRIVER_INSTANCE;\r
28\r
7b13510f 29STATIC UI_HII_DRIVER_INSTANCE *gHiiDriverList;\r
a85be3ae
ED
30\r
31\r
32/**\r
33 Create the dynamic item to allow user to set the "BootNext" vaule.\r
34\r
35 @param CallbackData The BMM context data.\r
36\r
37**/\r
38VOID\r
39BmmCreateBootNextMenu(\r
40 IN EFI_HII_HANDLE HiiHandle,\r
41 IN VOID *StartOpCodeHandle\r
42 )\r
43{\r
44 BM_MENU_ENTRY *NewMenuEntry;\r
720eea6a 45 BM_LOAD_CONTEXT *NewLoadContext;\r
a85be3ae
ED
46 UINT16 Index;\r
47 VOID *OptionsOpCodeHandle;\r
720eea6a 48 UINT32 BootNextIndex;\r
a85be3ae 49\r
720eea6a 50 if (BootOptionMenu.MenuNumber == 0) {\r
a85be3ae
ED
51 return;\r
52 }\r
53\r
720eea6a
ED
54 BootNextIndex = NONE_BOOTNEXT_VALUE;\r
55\r
a85be3ae
ED
56 OptionsOpCodeHandle = HiiAllocateOpCodeHandle ();\r
57 ASSERT (OptionsOpCodeHandle != NULL);\r
58\r
59 for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {\r
60 NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
720eea6a
ED
61 NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
62\r
63 if (NewLoadContext->IsBootNext) {\r
64 HiiCreateOneOfOptionOpCode (\r
65 OptionsOpCodeHandle,\r
66 NewMenuEntry->DisplayStringToken,\r
67 EFI_IFR_OPTION_DEFAULT,\r
68 EFI_IFR_TYPE_NUM_SIZE_32,\r
69 Index\r
70 );\r
71 BootNextIndex = Index;\r
72 } else {\r
73 HiiCreateOneOfOptionOpCode (\r
74 OptionsOpCodeHandle,\r
75 NewMenuEntry->DisplayStringToken,\r
76 0,\r
77 EFI_IFR_TYPE_NUM_SIZE_32,\r
78 Index\r
79 );\r
80 }\r
81 }\r
a85be3ae 82\r
720eea6a
ED
83 if (BootNextIndex == NONE_BOOTNEXT_VALUE) {\r
84 HiiCreateOneOfOptionOpCode (\r
85 OptionsOpCodeHandle,\r
86 STRING_TOKEN (STR_NONE),\r
87 EFI_IFR_OPTION_DEFAULT,\r
88 EFI_IFR_TYPE_NUM_SIZE_32,\r
89 NONE_BOOTNEXT_VALUE\r
90 );\r
91 } else {\r
a85be3ae
ED
92 HiiCreateOneOfOptionOpCode (\r
93 OptionsOpCodeHandle,\r
720eea6a 94 STRING_TOKEN (STR_NONE),\r
a85be3ae 95 0,\r
720eea6a
ED
96 EFI_IFR_TYPE_NUM_SIZE_32,\r
97 NONE_BOOTNEXT_VALUE\r
a85be3ae
ED
98 );\r
99 }\r
100\r
a85be3ae
ED
101 HiiCreateOneOfOpCode (\r
102 StartOpCodeHandle,\r
103 (EFI_QUESTION_ID) BOOT_NEXT_QUESTION_ID,\r
104 VARSTORE_ID_BOOT_MAINT,\r
105 BOOT_NEXT_VAR_OFFSET,\r
106 STRING_TOKEN (STR_BOOT_NEXT),\r
107 STRING_TOKEN (STR_BOOT_NEXT_HELP),\r
108 0,\r
720eea6a 109 EFI_IFR_NUMERIC_SIZE_4,\r
a85be3ae
ED
110 OptionsOpCodeHandle,\r
111 NULL\r
112 );\r
113\r
114 HiiFreeOpCodeHandle (OptionsOpCodeHandle);\r
115\r
116}\r
117\r
118/**\r
119 Create Time Out Menu in the page.\r
120\r
121 @param[in] HiiHandle The hii handle for the Uiapp driver.\r
122 @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
123 @param[in] PromptId The Prompt string id.\r
124 @param[in] HelpId The help string id.\r
125 @param[in] FormId The Form id for the dest form.\r
126 @param[in] QuestionId The question id for this goto question.\r
127\r
128**/\r
129VOID\r
130BmmCreateTimeOutMenu (\r
131 IN EFI_HII_HANDLE HiiHandle,\r
132 IN VOID *StartOpCodeHandle\r
133 )\r
134{\r
135 HiiCreateNumericOpCode (\r
136 StartOpCodeHandle,\r
137 (EFI_QUESTION_ID) FORM_TIME_OUT_ID,\r
138 VARSTORE_ID_BOOT_MAINT,\r
139 BOOT_TIME_OUT_VAR_OFFSET,\r
140 STRING_TOKEN(STR_NUM_AUTO_BOOT),\r
141 STRING_TOKEN(STR_HLP_AUTO_BOOT),\r
142 EFI_IFR_FLAG_CALLBACK,\r
143 EFI_IFR_NUMERIC_SIZE_2 | EFI_IFR_DISPLAY_UINT_DEC,\r
144 0,\r
145 65535,\r
146 0,\r
147 NULL\r
148 );\r
149}\r
150\r
151/**\r
152 Create Boot Option menu in the page.\r
153\r
154 @param[in] HiiHandle The hii handle for the Uiapp driver.\r
155 @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
156\r
157**/\r
158VOID\r
159BmmCreateBootOptionMenu (\r
160 IN EFI_HII_HANDLE HiiHandle,\r
161 IN VOID *StartOpCodeHandle\r
162 )\r
163{\r
164 HiiCreateGotoOpCode (\r
165 StartOpCodeHandle,\r
166 FORM_BOOT_SETUP_ID,\r
167 STRING_TOKEN (STR_FORM_BOOT_SETUP_TITLE),\r
168 STRING_TOKEN (STR_FORM_BOOT_SETUP_HELP),\r
169 EFI_IFR_FLAG_CALLBACK,\r
170 FORM_BOOT_SETUP_ID\r
171 );\r
172}\r
173\r
174/**\r
175 Create Driver Option menu in the page.\r
176\r
177 @param[in] HiiHandle The hii handle for the Uiapp driver.\r
178 @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
179\r
180**/\r
181VOID\r
182BmmCreateDriverOptionMenu (\r
183 IN EFI_HII_HANDLE HiiHandle,\r
184 IN VOID *StartOpCodeHandle\r
185 )\r
186{\r
187 HiiCreateGotoOpCode (\r
188 StartOpCodeHandle,\r
189 FORM_DRIVER_SETUP_ID,\r
190 STRING_TOKEN (STR_FORM_DRIVER_SETUP_TITLE),\r
191 STRING_TOKEN (STR_FORM_DRIVER_SETUP_HELP),\r
192 EFI_IFR_FLAG_CALLBACK,\r
193 FORM_DRIVER_SETUP_ID\r
194 );\r
195}\r
196\r
197/**\r
198 Create Com Option menu in the page.\r
199\r
200 @param[in] HiiHandle The hii handle for the Uiapp driver.\r
201 @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
202\r
203**/\r
204VOID\r
205BmmCreateComOptionMenu (\r
206 IN EFI_HII_HANDLE HiiHandle,\r
207 IN VOID *StartOpCodeHandle\r
208 )\r
209{\r
210 HiiCreateGotoOpCode (\r
211 StartOpCodeHandle,\r
212 FORM_CON_MAIN_ID,\r
213 STRING_TOKEN (STR_FORM_CON_MAIN_TITLE),\r
214 STRING_TOKEN (STR_FORM_CON_MAIN_HELP),\r
215 EFI_IFR_FLAG_CALLBACK,\r
216 FORM_CON_MAIN_ID\r
217 );\r
218}\r
219\r
220/**\r
221 Create Com Option menu in the page.\r
222\r
223 @param[in] HiiHandle The hii handle for the Uiapp driver.\r
224 @param[in] StartOpCodeHandle The opcode handle to save the new opcode.\r
225 @param[in] PromptId The Prompt string id.\r
226 @param[in] HelpId The help string id.\r
227 @param[in] FormId The Form id for the dest form.\r
228 @param[in] QuestionId The question id for this goto question.\r
229\r
230**/\r
231VOID\r
232BmmCreateBootFromFileMenu (\r
233 IN EFI_HII_HANDLE HiiHandle,\r
234 IN VOID *StartOpCodeHandle\r
235 )\r
236{\r
237 HiiCreateGotoOpCode (\r
238 StartOpCodeHandle,\r
239 FORM_MAIN_ID,\r
240 STRING_TOKEN (STR_BOOT_FROM_FILE),\r
241 STRING_TOKEN (STR_BOOT_FROM_FILE_HELP),\r
242 EFI_IFR_FLAG_CALLBACK,\r
243 KEY_VALUE_BOOT_FROM_FILE\r
244 );\r
245}\r
246\r
247/**\r
248 Create empty line menu in the front page.\r
249\r
250 @param HiiHandle The hii handle for the Uiapp driver.\r
251 @param StartOpCodeHandle The opcode handle to save the new opcode.\r
252\r
253**/\r
254VOID\r
255BmmCreateEmptyLine (\r
256 IN EFI_HII_HANDLE HiiHandle,\r
257 IN VOID *StartOpCodeHandle\r
258 )\r
259{\r
260 HiiCreateSubTitleOpCode (StartOpCodeHandle, STRING_TOKEN (STR_NULL_STRING), 0, 0, 0);\r
261}\r
262\r
263/**\r
264 Extract device path for given HII handle and class guid.\r
265\r
266 @param Handle The HII handle.\r
267\r
268 @retval NULL Fail to get the device path string.\r
269 @return PathString Get the device path string.\r
270\r
271**/\r
272CHAR16 *\r
273ExtractDevicePathFromHandle (\r
274 IN EFI_HII_HANDLE Handle\r
275 )\r
276{\r
277 EFI_STATUS Status;\r
278 EFI_HANDLE DriverHandle;\r
279\r
280 ASSERT (Handle != NULL);\r
281\r
282 if (Handle == NULL) {\r
283 return NULL;\r
284 }\r
285\r
286 Status = gHiiDatabase->GetPackageListHandle (gHiiDatabase, Handle, &DriverHandle);\r
287 if (EFI_ERROR (Status)) {\r
288 return NULL;\r
289 }\r
290\r
291 return ConvertDevicePathToText(DevicePathFromHandle (DriverHandle), FALSE, FALSE);\r
292}\r
293\r
294/**\r
295 Check whether this driver need to be shown in the front page.\r
296\r
297 @param HiiHandle The hii handle for the driver.\r
298 @param Guid The special guid for the driver which is the target.\r
299 @param PromptId Return the prompt string id.\r
300 @param HelpId Return the help string id.\r
301 @param FormsetGuid Return the formset guid info.\r
302\r
303 @retval EFI_SUCCESS Search the driver success\r
304\r
305**/\r
306BOOLEAN\r
307IsRequiredDriver (\r
308 IN EFI_HII_HANDLE HiiHandle,\r
309 IN EFI_GUID *Guid,\r
310 OUT EFI_STRING_ID *PromptId,\r
311 OUT EFI_STRING_ID *HelpId,\r
312 OUT VOID *FormsetGuid\r
313 )\r
314{\r
315 EFI_STATUS Status;\r
316 UINT8 ClassGuidNum;\r
317 EFI_GUID *ClassGuid;\r
318 EFI_IFR_FORM_SET *Buffer;\r
319 UINTN BufferSize;\r
320 UINT8 *Ptr;\r
321 UINTN TempSize;\r
322 BOOLEAN RetVal;\r
323\r
324 Status = HiiGetFormSetFromHiiHandle(HiiHandle, &Buffer,&BufferSize);\r
325 if (EFI_ERROR (Status)) {\r
326 return FALSE;\r
327 }\r
328\r
329 RetVal = FALSE;\r
330 TempSize = 0;\r
331 Ptr = (UINT8 *) Buffer;\r
332 while(TempSize < BufferSize) {\r
333 TempSize += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
334\r
335 if (((EFI_IFR_OP_HEADER *) Ptr)->Length <= OFFSET_OF (EFI_IFR_FORM_SET, Flags)){\r
336 Ptr += ((EFI_IFR_OP_HEADER *) Ptr)->Length;\r
337 continue;\r
338 }\r
339\r
340 ClassGuidNum = (UINT8) (((EFI_IFR_FORM_SET *)Ptr)->Flags & 0x3);\r
341 ClassGuid = (EFI_GUID *) (VOID *)(Ptr + sizeof (EFI_IFR_FORM_SET));\r
342 while (ClassGuidNum-- > 0) {\r
343 if (!CompareGuid (Guid, ClassGuid)){\r
344 ClassGuid ++;\r
345 continue;\r
346 }\r
347\r
348 *PromptId = ((EFI_IFR_FORM_SET *)Ptr)->FormSetTitle;\r
349 *HelpId = ((EFI_IFR_FORM_SET *)Ptr)->Help;\r
350 CopyMem (FormsetGuid, &((EFI_IFR_FORM_SET *) Ptr)->Guid, sizeof (EFI_GUID));\r
351 RetVal = TRUE;\r
352 }\r
353 }\r
354\r
355 FreePool (Buffer);\r
356\r
357 return RetVal;\r
358}\r
359\r
360/**\r
361 Search the drivers in the system which need to show in the front page\r
362 and insert the menu to the front page.\r
363\r
364 @param HiiHandle The hii handle for the Uiapp driver.\r
365 @param ClassGuid The class guid for the driver which is the target.\r
366 @param StartOpCodeHandle The opcode handle to save the new opcode.\r
367 @param SpecialHandler The pointer to the specail handler function, if any.\r
368\r
369 @retval EFI_SUCCESS Search the driver success\r
370\r
371**/\r
372EFI_STATUS\r
373BmmListThirdPartyDrivers (\r
374 IN EFI_HII_HANDLE HiiHandle,\r
375 IN EFI_GUID *ClassGuid,\r
376 IN DRIVER_SPECIAL_HANDLER SpecialHandlerFn,\r
377 IN VOID *StartOpCodeHandle\r
378 )\r
379{\r
380 UINTN Index;\r
381 EFI_STRING String;\r
382 EFI_STRING_ID Token;\r
383 EFI_STRING_ID TokenHelp;\r
384 EFI_HII_HANDLE *HiiHandles;\r
385 CHAR16 *DevicePathStr;\r
386 UINTN Count;\r
387 UINTN CurrentSize;\r
388 UI_HII_DRIVER_INSTANCE *DriverListPtr;\r
389 EFI_STRING NewName;\r
390 BOOLEAN EmptyLineAfter;\r
391\r
392 if (gHiiDriverList != NULL) {\r
393 FreePool (gHiiDriverList);\r
394 }\r
395\r
396 HiiHandles = HiiGetHiiHandles (NULL);\r
397 ASSERT (HiiHandles != NULL);\r
398\r
399 gHiiDriverList = AllocateZeroPool (UI_HII_DRIVER_LIST_SIZE * sizeof (UI_HII_DRIVER_INSTANCE));\r
400 ASSERT (gHiiDriverList != NULL);\r
401 DriverListPtr = gHiiDriverList;\r
402 CurrentSize = UI_HII_DRIVER_LIST_SIZE;\r
403\r
404 for (Index = 0, Count = 0; HiiHandles[Index] != NULL; Index++) {\r
405 if (!IsRequiredDriver (HiiHandles[Index], ClassGuid, &Token, &TokenHelp, &gHiiDriverList[Count].FormSetGuid)) {\r
406 continue;\r
407 }\r
408\r
409 String = HiiGetString (HiiHandles[Index], Token, NULL);\r
410 if (String == NULL) {\r
411 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
412 ASSERT (String != NULL);\r
413 } else if (SpecialHandlerFn != NULL) {\r
414 //\r
415 // Check whether need to rename the driver name.\r
416 //\r
417 EmptyLineAfter = FALSE;\r
418 if (SpecialHandlerFn (String, &NewName, &EmptyLineAfter)) {\r
419 FreePool (String);\r
420 String = NewName;\r
421 DriverListPtr[Count].EmptyLineAfter = EmptyLineAfter;\r
422 }\r
423 }\r
424 DriverListPtr[Count].PromptId = HiiSetString (HiiHandle, 0, String, NULL);\r
425 FreePool (String);\r
426\r
427 String = HiiGetString (HiiHandles[Index], TokenHelp, NULL);\r
428 if (String == NULL) {\r
429 String = HiiGetString (HiiHandle, STRING_TOKEN (STR_MISSING_STRING), NULL);\r
430 ASSERT (String != NULL);\r
431 }\r
432 DriverListPtr[Count].HelpId = HiiSetString (HiiHandle, 0, String, NULL);\r
433 FreePool (String);\r
434\r
435 DevicePathStr = ExtractDevicePathFromHandle(HiiHandles[Index]);\r
436 if (DevicePathStr != NULL){\r
437 DriverListPtr[Count].DevicePathId = HiiSetString (HiiHandle, 0, DevicePathStr, NULL);\r
438 FreePool (DevicePathStr);\r
439 } else {\r
440 DriverListPtr[Count].DevicePathId = 0;\r
441 }\r
442\r
443 Count++;\r
444 if (Count >= CurrentSize) {\r
445 DriverListPtr = AllocateCopyPool ((Count + UI_HII_DRIVER_LIST_SIZE) * sizeof (UI_HII_DRIVER_INSTANCE), gHiiDriverList);\r
446 ASSERT (DriverListPtr != NULL);\r
447 FreePool (gHiiDriverList);\r
448 gHiiDriverList = DriverListPtr;\r
449 CurrentSize += UI_HII_DRIVER_LIST_SIZE;\r
450 }\r
451 }\r
452\r
453 FreePool (HiiHandles);\r
454\r
455 Index = 0;\r
456 while (gHiiDriverList[Index].PromptId != 0) {\r
457 HiiCreateGotoExOpCode (\r
458 StartOpCodeHandle,\r
459 0,\r
460 gHiiDriverList[Index].PromptId,\r
461 gHiiDriverList[Index].HelpId,\r
462 0,\r
463 0,\r
464 0,\r
465 &gHiiDriverList[Index].FormSetGuid,\r
466 gHiiDriverList[Index].DevicePathId\r
467 );\r
468\r
469 if (gHiiDriverList[Index].EmptyLineAfter) {\r
470 BmmCreateEmptyLine (HiiHandle, StartOpCodeHandle);\r
471 }\r
472\r
473 Index ++;\r
474 }\r
475\r
476 return EFI_SUCCESS;\r
477}\r
478\r