\r
Boot option manipulation\r
\r
-Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2018, Intel Corporation. All rights reserved.<BR>\r
This program and the accompanying materials\r
are licensed and made available under the terms and conditions of the BSD License\r
which accompanies this distribution. The full text of the license may be found at\r
if (FileContext->Info == NULL) {\r
VolumeLabel = L"NO FILE SYSTEM INFO";\r
} else {\r
- if (FileContext->Info->VolumeLabel == NULL) {\r
- VolumeLabel = L"NULL VOLUME LABEL";\r
- } else {\r
- VolumeLabel = FileContext->Info->VolumeLabel;\r
- if (*VolumeLabel == 0x0000) {\r
- VolumeLabel = L"NO VOLUME LABEL";\r
- }\r
+ VolumeLabel = FileContext->Info->VolumeLabel;\r
+ if (*VolumeLabel == 0x0000) {\r
+ VolumeLabel = L"NO VOLUME LABEL";\r
}\r
}\r
\r
RemoveEntryList (&MenuEntry->Link);\r
BOpt_DestroyMenuEntry (MenuEntry);\r
}\r
+ FreeMenu->MenuNumber = 0;\r
}\r
\r
/**\r
HDD_INFO *HddInfo;\r
UINT16 BbsCount;\r
BBS_TABLE *BbsTable;\r
- UINTN Index;\r
+ UINT16 Index;\r
CHAR16 DescString[100];\r
UINTN FDNum;\r
UINTN HDNum;\r
}\r
\r
NewLegacyDevContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;\r
- NewLegacyDevContext->BbsTable = &BbsTable[Index];\r
- NewLegacyDevContext->Index = Index;\r
+ NewLegacyDevContext->BbsEntry = &BbsTable[Index];\r
+ NewLegacyDevContext->BbsIndex = Index;\r
NewLegacyDevContext->BbsCount = BbsCount;\r
BdsBuildLegacyDevNameString (\r
&BbsTable[Index],\r
sizeof (DescString),\r
DescString\r
);\r
- NewLegacyDevContext->Description = AllocateZeroPool (StrSize (DescString));\r
+ NewLegacyDevContext->Description = AllocateCopyPool (StrSize (DescString), DescString);\r
if (NULL == NewLegacyDevContext->Description) {\r
break;\r
}\r
\r
- CopyMem (NewLegacyDevContext->Description, DescString, StrSize (DescString));\r
NewMenuEntry->DisplayString = NewLegacyDevContext->Description;\r
NewMenuEntry->HelpString = NULL;\r
\r
EFI_DEVICE_PATH_PROTOCOL *DevicePath;\r
UINTN MenuCount;\r
UINT8 *Ptr;\r
- \r
+\r
MenuCount = 0;\r
BootOrderListSize = 0;\r
BootNextSize = 0;\r
if (BootOrderList == NULL) {\r
return EFI_NOT_FOUND;\r
}\r
- \r
+\r
//\r
// Get the BootNext from the Var\r
//\r
\r
NewLoadContext->FilePathListLength = *(UINT16 *) LoadOptionPtr;\r
LoadOptionPtr += sizeof (UINT16);\r
- \r
+\r
StringSize = StrSize((UINT16*)LoadOptionPtr);\r
\r
- NewLoadContext->Description = AllocateZeroPool (StrSize((UINT16*)LoadOptionPtr));\r
- ASSERT (NewLoadContext->Description != NULL);\r
- StrCpy (NewLoadContext->Description, (UINT16*)LoadOptionPtr);\r
- \r
+ NewLoadContext->Description = AllocateCopyPool (StrSize((UINT16*)LoadOptionPtr), LoadOptionPtr);\r
ASSERT (NewLoadContext->Description != NULL);\r
+\r
NewMenuEntry->DisplayString = NewLoadContext->Description;\r
\r
LoadOptionPtr += StringSize;\r
{\r
UINTN Size1;\r
UINTN Size2;\r
+ UINTN MaxLen;\r
CHAR16 *Str;\r
CHAR16 *TmpStr;\r
CHAR16 *Ptr;\r
\r
Size1 = StrSize (Str1);\r
Size2 = StrSize (Str2);\r
- Str = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16));\r
+ MaxLen = (Size1 + Size2 + sizeof (CHAR16)) / sizeof (CHAR16);\r
+ Str = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
ASSERT (Str != NULL);\r
\r
- TmpStr = AllocateZeroPool (Size1 + Size2 + sizeof (CHAR16)); \r
+ TmpStr = AllocateZeroPool (MaxLen * sizeof (CHAR16));\r
ASSERT (TmpStr != NULL);\r
\r
- StrCat (Str, Str1);\r
+ StrCatS (Str, MaxLen, Str1);\r
if (!((*Str == '\\') && (*(Str + 1) == 0))) {\r
- StrCat (Str, L"\\");\r
+ StrCatS (Str, MaxLen, L"\\");\r
}\r
\r
- StrCat (Str, Str2);\r
+ StrCatS (Str, MaxLen, Str2);\r
\r
Ptr = Str;\r
LastSlash = Str;\r
//\r
\r
//\r
- // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings \r
+ // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
// that overlap.\r
//\r
- StrCpy (TmpStr, Ptr + 3);\r
- StrCpy (LastSlash, TmpStr);\r
+ StrCpyS (TmpStr, MaxLen, Ptr + 3);\r
+ StrCpyS (LastSlash, MaxLen - ((UINTN) LastSlash - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
Ptr = LastSlash;\r
} else if (*Ptr == '\\' && *(Ptr + 1) == '.' && *(Ptr + 2) == '\\') {\r
//\r
//\r
\r
//\r
- // Use TmpStr as a backup, as StrCpy in BaseLib does not handle copy of two strings \r
+ // Use TmpStr as a backup, as StrCpyS in BaseLib does not handle copy of two strings\r
// that overlap.\r
//\r
- StrCpy (TmpStr, Ptr + 2);\r
- StrCpy (Ptr, TmpStr);\r
+ StrCpyS (TmpStr, MaxLen, Ptr + 2);\r
+ StrCpyS (Ptr, MaxLen - ((UINTN) Ptr - (UINTN) Str) / sizeof (CHAR16), TmpStr);\r
Ptr = LastSlash;\r
} else if (*Ptr == '\\') {\r
LastSlash = Ptr;\r
}\r
\r
FreePool (TmpStr);\r
- \r
+\r
return Str;\r
}\r
\r
return FALSE;\r
}\r
\r
-/**\r
-\r
- Check whether current FileName point to a valid Efi Application\r
-\r
- @param Dir Pointer to current Directory\r
- @param FileName Pointer to current File name.\r
-\r
- @retval TRUE Is a valid Efi Application\r
- @retval FALSE not a valid Efi Application\r
-\r
-**/\r
-BOOLEAN\r
-BOpt_IsEfiApp (\r
- IN EFI_FILE_HANDLE Dir,\r
- IN UINT16 *FileName\r
- )\r
-{\r
- UINTN BufferSize;\r
- EFI_IMAGE_DOS_HEADER DosHdr;\r
- UINT16 Subsystem;\r
- EFI_FILE_HANDLE File;\r
- EFI_STATUS Status;\r
- EFI_IMAGE_OPTIONAL_HEADER_UNION PeHdr;\r
-\r
- Status = Dir->Open (Dir, &File, FileName, EFI_FILE_MODE_READ, 0);\r
-\r
- if (EFI_ERROR (Status)) {\r
- return FALSE;\r
- }\r
-\r
- BufferSize = sizeof (EFI_IMAGE_DOS_HEADER);\r
- File->Read (File, &BufferSize, &DosHdr);\r
- if (DosHdr.e_magic != EFI_IMAGE_DOS_SIGNATURE) {\r
- File->Close (File);\r
- return FALSE;\r
- }\r
-\r
- File->SetPosition (File, DosHdr.e_lfanew);\r
- BufferSize = sizeof (EFI_IMAGE_OPTIONAL_HEADER_UNION);\r
- File->Read (File, &BufferSize, &PeHdr);\r
- if (PeHdr.Pe32.Signature != EFI_IMAGE_NT_SIGNATURE) {\r
- File->Close (File);\r
- return FALSE;\r
- }\r
- //\r
- // Determine PE type and read subsytem\r
- //\r
- if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR32_MAGIC) {\r
- Subsystem = PeHdr.Pe32.OptionalHeader.Subsystem;\r
- } else if (PeHdr.Pe32.OptionalHeader.Magic == EFI_IMAGE_NT_OPTIONAL_HDR64_MAGIC) {\r
- Subsystem = PeHdr.Pe32Plus.OptionalHeader.Subsystem;\r
- } else {\r
- return FALSE;\r
- }\r
\r
- if (Subsystem == EFI_IMAGE_SUBSYSTEM_EFI_APPLICATION) {\r
- File->Close (File);\r
- return TRUE;\r
- } else {\r
- File->Close (File);\r
- return FALSE;\r
- }\r
-}\r
\r
/**\r
\r
OrderListSize = 0;\r
OrderList = NULL;\r
OptionNumber = 0;\r
+ Index = 0;\r
\r
UnicodeSPrint (StrTemp, sizeof (StrTemp), L"%sOrder", Type);\r
\r
&gEfiGlobalVariableGuid,\r
&OrderListSize\r
);\r
- ASSERT (OrderList != NULL);\r
\r
for (OptionNumber = 0; ; OptionNumber++) {\r
- for (Index = 0; Index < OrderListSize / sizeof (UINT16); Index++) {\r
- if (OptionNumber == OrderList[Index]) {\r
- break;\r
+ if (OrderList != NULL) {\r
+ for (Index = 0; Index < OrderListSize / sizeof (UINT16); Index++) {\r
+ if (OptionNumber == OrderList[Index]) {\r
+ break;\r
+ }\r
}\r
}\r
\r
if (DriverOrderList == NULL) {\r
return EFI_NOT_FOUND;\r
}\r
- \r
+\r
for (Index = 0; Index < DriverOrderListSize / sizeof (UINT16); Index++) {\r
UnicodeSPrint (\r
DriverString,\r
\r
}\r
\r
+/**\r
+ Get option number according to Boot#### and BootOrder variable.\r
+ The value is saved as #### + 1.\r
+\r
+ @param CallbackData The BMM context data.\r
+**/\r
+VOID\r
+GetBootOrder (\r
+ IN BMM_CALLBACK_DATA *CallbackData\r
+ )\r
+{\r
+ BMM_FAKE_NV_DATA *BmmConfig;\r
+ UINT16 Index;\r
+ UINT16 OptionOrderIndex;\r
+ UINTN DeviceType;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ BM_LOAD_CONTEXT *NewLoadContext;\r
+\r
+ ASSERT (CallbackData != NULL);\r
+\r
+ DeviceType = (UINTN) -1;\r
+ BmmConfig = &CallbackData->BmmFakeNvData;\r
+ ZeroMem (BmmConfig->BootOptionOrder, sizeof (BmmConfig->BootOptionOrder));\r
+\r
+ for (Index = 0, OptionOrderIndex = 0; ((Index < BootOptionMenu.MenuNumber) &&\r
+ (OptionOrderIndex < (sizeof (BmmConfig->BootOptionOrder) / sizeof (BmmConfig->BootOptionOrder[0]))));\r
+ Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);\r
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+ if (NewLoadContext->IsLegacy) {\r
+ if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {\r
+ DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;\r
+ } else {\r
+ //\r
+ // Only show one legacy boot option for the same device type\r
+ // assuming the boot options are grouped by the device type\r
+ //\r
+ continue;\r
+ }\r
+ }\r
+ BmmConfig->BootOptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
+ }\r
+}\r
+\r
+/**\r
+ According to LegacyDevOrder variable to get legacy FD\HD\CD\NET\BEV\r
+ devices list .\r
+\r
+ @param CallbackData The BMM context data.\r
+**/\r
+VOID\r
+GetLegacyDeviceOrder (\r
+ IN BMM_CALLBACK_DATA *CallbackData\r
+ )\r
+{\r
+ UINTN Index;\r
+ UINTN OptionIndex;\r
+ UINT16 PageIdList[5];\r
+ UINTN PageNum;\r
+ UINTN VarSize;\r
+ UINT8 *VarData;\r
+ UINT8 *WorkingVarData;\r
+ LEGACY_DEV_ORDER_ENTRY *DevOrder;\r
+ UINT16 VarDevOrder;\r
+ UINT8 *DisMap;\r
+ BM_MENU_OPTION *OptionMenu;\r
+ BBS_TYPE BbsType;\r
+ UINT8 *LegacyOrder;\r
+ UINT8 *OldData;\r
+ UINTN Pos;\r
+ UINTN Bit;\r
+\r
+ ASSERT (CallbackData != NULL);\r
+\r
+ PageIdList[0] = FORM_SET_FD_ORDER_ID;\r
+ PageIdList[1] = FORM_SET_HD_ORDER_ID;\r
+ PageIdList[2] = FORM_SET_CD_ORDER_ID;\r
+ PageIdList[3] = FORM_SET_NET_ORDER_ID;\r
+ PageIdList[4] = FORM_SET_BEV_ORDER_ID;\r
+ OptionMenu = NULL;\r
+ BbsType = 0;\r
+ LegacyOrder = NULL;\r
+ OldData = NULL;\r
+ DisMap = ZeroMem (CallbackData->BmmFakeNvData.DisableMap, sizeof (CallbackData->BmmFakeNvData.DisableMap));\r
+ PageNum = ARRAY_SIZE (PageIdList);\r
+ VarData = BdsLibGetVariableAndSize (\r
+ VAR_LEGACY_DEV_ORDER,\r
+ &gEfiLegacyDevOrderVariableGuid,\r
+ &VarSize\r
+ );\r
+\r
+ for (Index = 0; Index < PageNum; Index++) {\r
+ switch (PageIdList[Index]) {\r
+\r
+ case FORM_SET_FD_ORDER_ID:\r
+ OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;\r
+ BbsType = BBS_FLOPPY;\r
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyFD;\r
+ OldData = CallbackData->BmmOldFakeNVData.LegacyFD;\r
+ break;\r
+\r
+ case FORM_SET_HD_ORDER_ID:\r
+ OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;\r
+ BbsType = BBS_HARDDISK;\r
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyHD;\r
+ OldData = CallbackData->BmmOldFakeNVData.LegacyHD;\r
+ break;\r
+\r
+ case FORM_SET_CD_ORDER_ID:\r
+ OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;\r
+ BbsType = BBS_CDROM;\r
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyCD;\r
+ OldData = CallbackData->BmmOldFakeNVData.LegacyCD;\r
+ break;\r
+\r
+ case FORM_SET_NET_ORDER_ID:\r
+ OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;\r
+ BbsType = BBS_EMBED_NETWORK;\r
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyNET;\r
+ OldData = CallbackData->BmmOldFakeNVData.LegacyNET;\r
+ break;\r
+\r
+ default:\r
+ ASSERT (PageIdList[Index] == FORM_SET_BEV_ORDER_ID);\r
+ OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;\r
+ BbsType = BBS_BEV_DEVICE;\r
+ LegacyOrder = CallbackData->BmmFakeNvData.LegacyBEV;\r
+ OldData = CallbackData->BmmOldFakeNVData.LegacyBEV;\r
+ break;\r
+ }\r
+\r
+ if (NULL != VarData) {\r
+ WorkingVarData = VarData;\r
+ DevOrder = (LEGACY_DEV_ORDER_ENTRY *) WorkingVarData;\r
+ while (WorkingVarData < VarData + VarSize) {\r
+ if (DevOrder->BbsType == BbsType) {\r
+ break;\r
+ }\r
+\r
+ WorkingVarData = (UINT8 *)((UINTN)WorkingVarData + sizeof (BBS_TYPE));\r
+ WorkingVarData += *(UINT16 *) WorkingVarData;\r
+ DevOrder = (LEGACY_DEV_ORDER_ENTRY *) WorkingVarData;\r
+ }\r
+ for (OptionIndex = 0; OptionIndex < OptionMenu->MenuNumber; OptionIndex++) {\r
+ VarDevOrder = *(UINT16 *) ((UINTN) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + OptionIndex * sizeof (UINT16));\r
+ if (0xFF00 == (VarDevOrder & 0xFF00)) {\r
+ LegacyOrder[OptionIndex] = 0xFF;\r
+ Pos = (VarDevOrder & 0xFF) / 8;\r
+ Bit = 7 - ((VarDevOrder & 0xFF) % 8);\r
+ DisMap[Pos] = (UINT8) (DisMap[Pos] | (UINT8) (1 << Bit));\r
+ } else {\r
+ LegacyOrder[OptionIndex] = (UINT8) (VarDevOrder & 0xFF);\r
+ }\r
+ }\r
+ CopyMem (OldData, LegacyOrder, 100);\r
+ }\r
+ }\r
+}\r
+\r
+/**\r
+ Get driver option order from globalc DriverOptionMenu.\r
+\r
+ @param CallbackData The BMM context data.\r
+\r
+**/\r
+VOID\r
+GetDriverOrder (\r
+ IN BMM_CALLBACK_DATA *CallbackData\r
+ )\r
+{\r
+ BMM_FAKE_NV_DATA *BmmConfig;\r
+ UINT16 Index;\r
+ UINT16 OptionOrderIndex;\r
+ UINTN DeviceType;\r
+ BM_MENU_ENTRY *NewMenuEntry;\r
+ BM_LOAD_CONTEXT *NewLoadContext;\r
+\r
+ ASSERT (CallbackData != NULL);\r
+\r
+ DeviceType = (UINTN) -1;\r
+ BmmConfig = &CallbackData->BmmFakeNvData;\r
+ ZeroMem (BmmConfig->DriverOptionOrder, sizeof (BmmConfig->DriverOptionOrder));\r
+\r
+ for (Index = 0, OptionOrderIndex = 0; ((Index < DriverOptionMenu.MenuNumber) &&\r
+ (OptionOrderIndex < (sizeof (BmmConfig->DriverOptionOrder) / sizeof (BmmConfig->DriverOptionOrder[0]))));\r
+ Index++) {\r
+ NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);\r
+ NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;\r
+\r
+ if (NewLoadContext->IsLegacy) {\r
+ if (((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType != DeviceType) {\r
+ DeviceType = ((BBS_BBS_DEVICE_PATH *) NewLoadContext->FilePathList)->DeviceType;\r
+ } else {\r
+ //\r
+ // Only show one legacy boot option for the same device type\r
+ // assuming the boot options are grouped by the device type\r
+ //\r
+ continue;\r
+ }\r
+ }\r
+ BmmConfig->DriverOptionOrder[OptionOrderIndex++] = (UINT32) (NewMenuEntry->OptionNumber + 1);\r
+ }\r
+}\r