2 The platform boot manager reference implementation
4 Copyright (c) 2004 - 2015, Intel Corporation. All rights reserved.<BR>
5 This program and the accompanying materials
6 are licensed and made available under the terms and conditions of the BSD License
7 which accompanies this distribution. The full text of the license may be found at
8 http://opensource.org/licenses/bsd-license.php
10 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
11 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
15 #include "BootManager.h"
17 EFI_GUID mBootManagerGuid
= BOOT_MANAGER_FORMSET_GUID
;
18 CHAR16
*mDeviceTypeStr
[] = {
25 L
"Legacy Embedded Network",
26 L
"Legacy Unknown Device"
30 HII_VENDOR_DEVICE_PATH mBootManagerHiiVendorDevicePath
= {
36 (UINT8
) (sizeof (VENDOR_DEVICE_PATH
)),
37 (UINT8
) ((sizeof (VENDOR_DEVICE_PATH
)) >> 8)
41 // {1DDDBE15-481D-4d2b-8277-B191EAF66525}
43 { 0x1dddbe15, 0x481d, 0x4d2b, { 0x82, 0x77, 0xb1, 0x91, 0xea, 0xf6, 0x65, 0x25 } }
47 END_ENTIRE_DEVICE_PATH_SUBTYPE
,
49 (UINT8
) (END_DEVICE_PATH_LENGTH
),
50 (UINT8
) ((END_DEVICE_PATH_LENGTH
) >> 8)
55 BOOT_MANAGER_CALLBACK_DATA gBootManagerPrivate
= {
56 BOOT_MANAGER_CALLBACK_DATA_SIGNATURE
,
67 This call back function is registered with Boot Manager formset.
68 When user selects a boot option, this call back function will
69 be triggered. The boot option is saved for later processing.
72 @param This Points to the EFI_HII_CONFIG_ACCESS_PROTOCOL.
73 @param Action Specifies the type of action taken by the browser.
74 @param QuestionId A unique value which is sent to the original exporting driver
75 so that it can identify the type of data to expect.
76 @param Type The type of value for the question.
77 @param Value A pointer to the data being sent to the original exporting driver.
78 @param ActionRequest On return, points to the action requested by the callback function.
80 @retval EFI_SUCCESS The callback successfully handled the action.
81 @retval EFI_INVALID_PARAMETER The setup browser call this function with invalid parameters.
87 IN CONST EFI_HII_CONFIG_ACCESS_PROTOCOL
*This
,
88 IN EFI_BROWSER_ACTION Action
,
89 IN EFI_QUESTION_ID QuestionId
,
91 IN EFI_IFR_TYPE_VALUE
*Value
,
92 OUT EFI_BROWSER_ACTION_REQUEST
*ActionRequest
96 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOption
;
97 UINTN BootOptionCount
;
100 EFI_BOOT_MANAGER_LOAD_OPTION Option
;
102 if (Action
!= EFI_BROWSER_ACTION_CHANGED
) {
104 // Do nothing for other UEFI Action. Only do call back when data is changed.
106 return EFI_UNSUPPORTED
;
109 if ((Value
== NULL
) || (ActionRequest
== NULL
)) {
110 return EFI_INVALID_PARAMETER
;
114 // Initialize the key count
117 Option
.Attributes
= 0;
118 BootOption
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
120 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
123 EfiBootManagerInitializeLoadOption (
125 BootOption
[Index
].OptionNumber
,
126 BootOption
[Index
].OptionType
,
127 BootOption
[Index
].Attributes
,
128 BootOption
[Index
].Description
,
129 BootOption
[Index
].FilePath
,
130 BootOption
[Index
].OptionalData
,
131 BootOption
[Index
].OptionalDataSize
135 // Is this device the one chosen?
137 if (KeyCount
== QuestionId
) {
139 // Clear the screen before.
141 gST
->ConOut
->SetAttribute (gST
->ConOut
, EFI_TEXT_ATTR (EFI_LIGHTGRAY
, EFI_BLACK
));
142 gST
->ConOut
->ClearScreen (gST
->ConOut
);
144 // Check any reset required change is applied? if yes, reset system
146 SetupResetReminder();
148 // Parse the selected option.
150 BdsSetConsoleMode(FALSE
);
151 EfiBootManagerBoot (&Option
);
152 BdsSetConsoleMode(TRUE
);
154 if (EFI_ERROR (Option
.Status
)) {
155 gST
->ConOut
->OutputString (
157 GetStringById (STRING_TOKEN (STR_ANY_KEY_CONTINUE
))
159 gST
->ConIn
->ReadKeyStroke (gST
->ConIn
, &Key
);
164 EfiBootManagerFreeLoadOptions (BootOption
, BootOptionCount
);
170 Register HII packages to HII database.
174 InitializeBootManager (
180 if (!gConnectAllHappened
){
181 EfiBootManagerConnectAll();
182 gConnectAllHappened
= TRUE
;
186 // Install Device Path Protocol and Config Access protocol to driver handle
188 gBootManagerPrivate
.DriverHandle
= NULL
;
189 Status
= gBS
->InstallMultipleProtocolInterfaces (
190 &gBootManagerPrivate
.DriverHandle
,
191 &gEfiDevicePathProtocolGuid
,
192 &mBootManagerHiiVendorDevicePath
,
193 &gEfiHiiConfigAccessProtocolGuid
,
194 &gBootManagerPrivate
.ConfigAccess
,
197 ASSERT_EFI_ERROR (Status
);
200 // Publish our HII data
202 gBootManagerPrivate
.HiiHandle
= HiiAddPackages (
204 gBootManagerPrivate
.DriverHandle
,
209 ASSERT(gBootManagerPrivate
.HiiHandle
!= NULL
);
214 Enumerate possible boot options.
218 EnumerateBootOptions (
223 EFI_BOOT_MANAGER_LOAD_OPTION
*BootOption
;
224 UINTN BootOptionCount
;
227 EFI_STRING_ID HelpToken
;
229 EFI_HII_HANDLE HiiHandle
;
231 VOID
*StartOpCodeHandle
;
232 VOID
*EndOpCodeHandle
;
233 EFI_IFR_GUID_LABEL
*StartLabel
;
234 EFI_IFR_GUID_LABEL
*EndLabel
;
236 BOOLEAN IsLegacyOption
;
241 DeviceType
= (UINT16
) -1;
244 // for better user experience
245 // 1. User changes HD configuration (e.g.: unplug HDD), here we have a chance to remove the HDD boot option
246 // 2. User enables/disables UEFI PXE, here we have a chance to add/remove EFI Network boot option
248 EfiBootManagerRefreshAllBootOption ();
250 BootOption
= EfiBootManagerGetLoadOptions (&BootOptionCount
, LoadOptionTypeBoot
);
252 HiiHandle
= gBootManagerPrivate
.HiiHandle
;
255 // Allocate space for creation of UpdateData Buffer
257 StartOpCodeHandle
= HiiAllocateOpCodeHandle ();
258 ASSERT (StartOpCodeHandle
!= NULL
);
260 EndOpCodeHandle
= HiiAllocateOpCodeHandle ();
261 ASSERT (EndOpCodeHandle
!= NULL
);
264 // Create Hii Extend Label OpCode as the start opcode
266 StartLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (StartOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
267 StartLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
268 StartLabel
->Number
= LABEL_BOOT_OPTION
;
271 // Create Hii Extend Label OpCode as the end opcode
273 EndLabel
= (EFI_IFR_GUID_LABEL
*) HiiCreateGuidOpCode (EndOpCodeHandle
, &gEfiIfrTianoGuid
, NULL
, sizeof (EFI_IFR_GUID_LABEL
));
274 EndLabel
->ExtendOpCode
= EFI_IFR_EXTEND_OP_LABEL
;
275 EndLabel
->Number
= LABEL_BOOT_OPTION_END
;
279 for (Index
= 0; Index
< BootOptionCount
; Index
++) {
281 // At this stage we are creating a menu entry, thus the Keys are reproduceable
286 // Don't display the hidden/inactive boot option
288 if (((BootOption
[Index
].Attributes
& LOAD_OPTION_HIDDEN
) != 0) || ((BootOption
[Index
].Attributes
& LOAD_OPTION_ACTIVE
) == 0)) {
293 // Group the legacy boot option in the sub title created dynamically
295 IsLegacyOption
= (BOOLEAN
) (
296 (DevicePathType (BootOption
[Index
].FilePath
) == BBS_DEVICE_PATH
) &&
297 (DevicePathSubType (BootOption
[Index
].FilePath
) == BBS_BBS_DP
)
300 if (!IsLegacyOption
&& NeedEndOp
) {
302 HiiCreateEndOpCode (StartOpCodeHandle
);
305 if (IsLegacyOption
&& DeviceType
!= ((BBS_BBS_DEVICE_PATH
*) BootOption
[Index
].FilePath
)->DeviceType
) {
307 HiiCreateEndOpCode (StartOpCodeHandle
);
310 DeviceType
= ((BBS_BBS_DEVICE_PATH
*) BootOption
[Index
].FilePath
)->DeviceType
;
311 Token
= HiiSetString (
315 MIN (DeviceType
& 0xF, sizeof (mDeviceTypeStr
) / sizeof (mDeviceTypeStr
[0]) - 1)
319 HiiCreateSubTitleOpCode (StartOpCodeHandle
, Token
, 0, 0, 1);
323 ASSERT (BootOption
[Index
].Description
!= NULL
);
325 Token
= HiiSetString (HiiHandle
, 0, BootOption
[Index
].Description
, NULL
);
327 TempStr
= UiDevicePathToStr (BootOption
[Index
].FilePath
);
328 TempSize
= StrSize (TempStr
);
329 DestMax
= (TempSize
+ StrSize (L
"Device Path : ")) / sizeof(CHAR16
);
330 HelpString
= AllocateZeroPool (TempSize
+ StrSize (L
"Device Path : "));
331 ASSERT (HelpString
!= NULL
);
332 StrCatS (HelpString
, DestMax
, L
"Device Path : ");
333 StrCatS (HelpString
, DestMax
, TempStr
);
335 HelpToken
= HiiSetString (HiiHandle
, 0, HelpString
, NULL
);
337 HiiCreateActionOpCode (
342 EFI_IFR_FLAG_CALLBACK
,
348 HiiCreateEndOpCode (StartOpCodeHandle
);
354 BOOT_MANAGER_FORM_ID
,
359 HiiFreeOpCodeHandle (StartOpCodeHandle
);
360 HiiFreeOpCodeHandle (EndOpCodeHandle
);
362 EfiBootManagerFreeLoadOptions (BootOption
, BootOptionCount
);
367 Remove the installed packages from the HII Database.
376 Status
= gBS
->UninstallMultipleProtocolInterfaces (
377 gBootManagerPrivate
.DriverHandle
,
378 &gEfiDevicePathProtocolGuid
,
379 &mBootManagerHiiVendorDevicePath
,
380 &gEfiHiiConfigAccessProtocolGuid
,
381 &gBootManagerPrivate
.ConfigAccess
,
384 ASSERT_EFI_ERROR (Status
);
386 HiiRemovePackages (gBootManagerPrivate
.HiiHandle
);