2006-04-22 00:54:32 +02:00
|
|
|
/*++
|
|
|
|
|
|
|
|
Copyright (c) 2006, Intel Corporation
|
|
|
|
All rights reserved. This program and the accompanying materials
|
|
|
|
are licensed and made available under the terms and conditions of the BSD License
|
|
|
|
which accompanies this distribution. The full text of the license may be found at
|
|
|
|
http://opensource.org/licenses/bsd-license.php
|
|
|
|
|
|
|
|
THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,
|
|
|
|
WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.
|
|
|
|
|
|
|
|
Module Name:
|
|
|
|
|
|
|
|
Variable.c
|
|
|
|
|
|
|
|
Abstract:
|
|
|
|
|
2006-10-31 16:58:02 +01:00
|
|
|
Variable operation that will be used by BootMaint
|
2006-04-22 00:54:32 +02:00
|
|
|
|
|
|
|
--*/
|
|
|
|
|
|
|
|
#include "Generic/Bds.h"
|
2006-10-31 16:58:02 +01:00
|
|
|
#include "BootMaint.h"
|
2006-04-22 00:54:32 +02:00
|
|
|
#include "bdsplatform.h"
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_DelBootOption (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
/*++
|
|
|
|
|
|
|
|
Routine Description:
|
|
|
|
Delete Boot Option that represent a Deleted state in BootOptionMenu.
|
|
|
|
After deleting this boot option, call Var_ChangeBootOrder to
|
|
|
|
make sure BootOrder is in valid state.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
LoadOption -- Pointer to the boot option that to be deleted
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS
|
|
|
|
Others
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
|
|
|
|
|
|
UINT16 BootString[10];
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINTN Index;
|
|
|
|
UINTN Index2;
|
|
|
|
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
Index2 = 0;
|
|
|
|
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, (Index - Index2));
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
if (!NewLoadContext->Deleted) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
UnicodeSPrint (
|
|
|
|
BootString,
|
|
|
|
sizeof (BootString),
|
|
|
|
L"Boot%04x",
|
|
|
|
NewMenuEntry->OptionNumber
|
|
|
|
);
|
|
|
|
|
|
|
|
EfiLibDeleteVariable (BootString, &gEfiGlobalVariableGuid);
|
|
|
|
Index2++;
|
|
|
|
//
|
|
|
|
// If current Load Option is the same as BootNext,
|
|
|
|
// must delete BootNext in order to make sure
|
|
|
|
// there will be no panic on next boot
|
|
|
|
//
|
|
|
|
if (NewLoadContext->IsBootNext) {
|
|
|
|
EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
RemoveEntryList (&NewMenuEntry->Link);
|
|
|
|
BOpt_DestroyMenuEntry (NewMenuEntry);
|
|
|
|
NewMenuEntry = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
BootOptionMenu.MenuNumber -= Index2;
|
|
|
|
|
|
|
|
Status = Var_ChangeBootOrder ();
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_ChangeBootOrder (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
/*++
|
|
|
|
|
|
|
|
Routine Description:
|
|
|
|
After any operation on Boot####, there will be a discrepancy in BootOrder.
|
|
|
|
Since some are missing but in BootOrder, while some are present but are
|
|
|
|
not reflected by BootOrder. Then a function rebuild BootOrder from
|
|
|
|
scratch by content from BootOptionMenu is needed.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS
|
|
|
|
Others
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
|
|
|
|
EFI_STATUS Status;
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
UINT16 *BootOrderList;
|
|
|
|
UINT16 *BootOrderListPtr;
|
|
|
|
UINTN BootOrderListSize;
|
|
|
|
UINTN Index;
|
|
|
|
|
|
|
|
BootOrderList = NULL;
|
|
|
|
BootOrderListSize = 0;
|
|
|
|
|
|
|
|
//
|
|
|
|
// First check whether BootOrder is present in current configuration
|
|
|
|
//
|
|
|
|
BootOrderList = BdsLibGetVariableAndSize (
|
|
|
|
L"BootOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
&BootOrderListSize
|
|
|
|
);
|
|
|
|
|
|
|
|
//
|
|
|
|
// If exists, delete it to hold new BootOrder
|
|
|
|
//
|
|
|
|
if (BootOrderList) {
|
|
|
|
EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
|
|
|
|
SafeFreePool (BootOrderList);
|
|
|
|
BootOrderList = NULL;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// Maybe here should be some check method to ensure that
|
|
|
|
// no new added boot options will be added
|
|
|
|
// but the setup engine now will give only one callback
|
|
|
|
// that is to say, user are granted only one chance to
|
|
|
|
// decide whether the boot option will be added or not
|
|
|
|
// there should be no indictor to show whether this
|
|
|
|
// is a "new" boot option
|
|
|
|
//
|
|
|
|
BootOrderListSize = BootOptionMenu.MenuNumber;
|
|
|
|
|
|
|
|
if (BootOrderListSize > 0) {
|
|
|
|
BootOrderList = AllocateZeroPool (BootOrderListSize * sizeof (UINT16));
|
|
|
|
ASSERT (BootOrderList != NULL);
|
|
|
|
BootOrderListPtr = BootOrderList;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get all current used Boot#### from BootOptionMenu.
|
|
|
|
// OptionNumber in each BM_LOAD_OPTION is really its
|
|
|
|
// #### value.
|
|
|
|
//
|
|
|
|
for (Index = 0; Index < BootOrderListSize; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
|
|
|
|
*BootOrderList = (UINT16) NewMenuEntry->OptionNumber;
|
|
|
|
BootOrderList++;
|
|
|
|
}
|
|
|
|
|
|
|
|
BootOrderList = BootOrderListPtr;
|
|
|
|
|
|
|
|
//
|
|
|
|
// After building the BootOrderList, write it back
|
|
|
|
//
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"BootOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
BootOrderListSize * sizeof (UINT16),
|
|
|
|
BootOrderList
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_DelDriverOption (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
/*++
|
|
|
|
|
|
|
|
Routine Description:
|
|
|
|
Delete Load Option that represent a Deleted state in BootOptionMenu.
|
|
|
|
After deleting this Driver option, call Var_ChangeDriverOrder to
|
|
|
|
make sure DriverOrder is in valid state.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
LoadOption -- Pointer to the Driver option that to be deleted
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS
|
|
|
|
Others
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
|
|
|
|
|
|
UINT16 DriverString[12];
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINTN Index;
|
|
|
|
UINTN Index2;
|
|
|
|
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
Index2 = 0;
|
|
|
|
for (Index = 0; Index < DriverOptionMenu.MenuNumber; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, (Index - Index2));
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
if (!NewLoadContext->Deleted) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
UnicodeSPrint (
|
|
|
|
DriverString,
|
|
|
|
sizeof (DriverString),
|
|
|
|
L"Driver%04x",
|
|
|
|
NewMenuEntry->OptionNumber
|
|
|
|
);
|
|
|
|
|
|
|
|
EfiLibDeleteVariable (DriverString, &gEfiGlobalVariableGuid);
|
|
|
|
Index2++;
|
|
|
|
|
|
|
|
RemoveEntryList (&NewMenuEntry->Link);
|
|
|
|
BOpt_DestroyMenuEntry (NewMenuEntry);
|
|
|
|
NewMenuEntry = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DriverOptionMenu.MenuNumber -= Index2;
|
|
|
|
|
|
|
|
Status = Var_ChangeDriverOrder ();
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_ChangeDriverOrder (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
/*++
|
|
|
|
|
|
|
|
Routine Description:
|
|
|
|
After any operation on Driver####, there will be a discrepancy in
|
|
|
|
DriverOrder. Since some are missing but in DriverOrder, while some
|
|
|
|
are present but are not reflected by DriverOrder. Then a function
|
|
|
|
rebuild DriverOrder from scratch by content from DriverOptionMenu is
|
|
|
|
needed.
|
|
|
|
|
|
|
|
Arguments:
|
|
|
|
|
|
|
|
Returns:
|
|
|
|
EFI_SUCCESS
|
|
|
|
Others
|
|
|
|
|
|
|
|
--*/
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
UINT16 *DriverOrderList;
|
|
|
|
UINT16 *DriverOrderListPtr;
|
|
|
|
UINTN DriverOrderListSize;
|
|
|
|
UINTN Index;
|
|
|
|
|
|
|
|
DriverOrderList = NULL;
|
|
|
|
DriverOrderListSize = 0;
|
|
|
|
|
|
|
|
//
|
|
|
|
// First check whether DriverOrder is present in current configuration
|
|
|
|
//
|
|
|
|
DriverOrderList = BdsLibGetVariableAndSize (
|
|
|
|
L"DriverOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
&DriverOrderListSize
|
|
|
|
);
|
|
|
|
|
|
|
|
//
|
|
|
|
// If exists, delete it to hold new DriverOrder
|
|
|
|
//
|
|
|
|
if (DriverOrderList) {
|
|
|
|
EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
|
|
|
|
SafeFreePool (DriverOrderList);
|
|
|
|
DriverOrderList = NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
DriverOrderListSize = DriverOptionMenu.MenuNumber;
|
|
|
|
|
|
|
|
if (DriverOrderListSize > 0) {
|
|
|
|
DriverOrderList = AllocateZeroPool (DriverOrderListSize * sizeof (UINT16));
|
|
|
|
ASSERT (DriverOrderList != NULL);
|
|
|
|
DriverOrderListPtr = DriverOrderList;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Get all current used Driver#### from DriverOptionMenu.
|
|
|
|
// OptionNumber in each BM_LOAD_OPTION is really its
|
|
|
|
// #### value.
|
|
|
|
//
|
|
|
|
for (Index = 0; Index < DriverOrderListSize; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (&DriverOptionMenu, Index);
|
|
|
|
*DriverOrderList = (UINT16) NewMenuEntry->OptionNumber;
|
|
|
|
DriverOrderList++;
|
|
|
|
}
|
|
|
|
|
|
|
|
DriverOrderList = DriverOrderListPtr;
|
|
|
|
|
|
|
|
//
|
|
|
|
// After building the DriverOrderList, write it back
|
|
|
|
//
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"DriverOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
DriverOrderListSize * sizeof (UINT16),
|
|
|
|
DriverOrderList
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
VOID
|
|
|
|
Var_UpdateAllConsoleOption (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *OutDevicePath;
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *InpDevicePath;
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *ErrDevicePath;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
OutDevicePath = EfiLibGetVariable (L"ConOut", &gEfiGlobalVariableGuid);
|
|
|
|
InpDevicePath = EfiLibGetVariable (L"ConIn", &gEfiGlobalVariableGuid);
|
|
|
|
ErrDevicePath = EfiLibGetVariable (L"ErrOut", &gEfiGlobalVariableGuid);
|
|
|
|
if (OutDevicePath) {
|
|
|
|
ChangeVariableDevicePath (OutDevicePath);
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"ConOut",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
GetDevicePathSize (OutDevicePath),
|
|
|
|
OutDevicePath
|
|
|
|
);
|
|
|
|
ASSERT (!EFI_ERROR (Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (InpDevicePath) {
|
|
|
|
ChangeVariableDevicePath (InpDevicePath);
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"ConIn",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
GetDevicePathSize (InpDevicePath),
|
|
|
|
InpDevicePath
|
|
|
|
);
|
|
|
|
ASSERT (!EFI_ERROR (Status));
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ErrDevicePath) {
|
|
|
|
ChangeVariableDevicePath (ErrDevicePath);
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"ErrOut",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
GetDevicePathSize (ErrDevicePath),
|
|
|
|
ErrDevicePath
|
|
|
|
);
|
|
|
|
ASSERT (!EFI_ERROR (Status));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateConsoleOption (
|
|
|
|
IN UINT16 *ConsoleName,
|
|
|
|
IN BM_MENU_OPTION *ConsoleMenu,
|
|
|
|
IN UINT16 UpdatePageId
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *ConDevicePath;
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
BM_CONSOLE_CONTEXT *NewConsoleContext;
|
|
|
|
BM_TERMINAL_CONTEXT *NewTerminalContext;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
VENDOR_DEVICE_PATH Vendor;
|
|
|
|
EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;
|
|
|
|
UINTN Index;
|
|
|
|
UINT16 *Temp;
|
|
|
|
|
|
|
|
ConDevicePath = EfiLibGetVariable (ConsoleName, &gEfiGlobalVariableGuid);
|
|
|
|
if (ConDevicePath != NULL) {
|
|
|
|
EfiLibDeleteVariable (ConsoleName, &gEfiGlobalVariableGuid);
|
|
|
|
SafeFreePool (ConDevicePath);
|
|
|
|
ConDevicePath = NULL;
|
|
|
|
};
|
|
|
|
|
|
|
|
//
|
|
|
|
// First add all console input device to it from console input menu
|
|
|
|
//
|
|
|
|
for (Index = 0; Index < ConsoleMenu->MenuNumber; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (ConsoleMenu, Index);
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewConsoleContext = (BM_CONSOLE_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
if (NewConsoleContext->IsActive) {
|
|
|
|
ConDevicePath = AppendDevicePathInstance (
|
|
|
|
ConDevicePath,
|
|
|
|
NewConsoleContext->DevicePath
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Index = 0; Index < TerminalMenu.MenuNumber; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (&TerminalMenu, Index);
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewTerminalContext = (BM_TERMINAL_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
if ((NewTerminalContext->IsConIn && (UpdatePageId == FORM_CON_IN_ID)) ||
|
|
|
|
(NewTerminalContext->IsConOut && (UpdatePageId == FORM_CON_OUT_ID)) ||
|
|
|
|
(NewTerminalContext->IsStdErr && (UpdatePageId == FORM_CON_ERR_ID))
|
|
|
|
) {
|
|
|
|
Vendor.Header.Type = MESSAGING_DEVICE_PATH;
|
|
|
|
Vendor.Header.SubType = MSG_VENDOR_DP;
|
|
|
|
CopyMem (
|
|
|
|
&Vendor.Guid,
|
|
|
|
&Guid[NewTerminalContext->TerminalType],
|
|
|
|
sizeof (EFI_GUID)
|
|
|
|
);
|
|
|
|
SetDevicePathNodeLength (&Vendor.Header, sizeof (VENDOR_DEVICE_PATH));
|
|
|
|
TerminalDevicePath = AppendDevicePathNode (
|
|
|
|
NewTerminalContext->DevicePath,
|
|
|
|
(EFI_DEVICE_PATH_PROTOCOL *) &Vendor
|
|
|
|
);
|
2007-01-16 03:57:57 +01:00
|
|
|
ASSERT (TerminalDevicePath != NULL);
|
2006-04-22 00:54:32 +02:00
|
|
|
ChangeTerminalDevicePath (TerminalDevicePath, TRUE);
|
|
|
|
Temp = DevicePathToStr (TerminalDevicePath);
|
|
|
|
ConDevicePath = AppendDevicePathInstance (
|
|
|
|
ConDevicePath,
|
|
|
|
TerminalDevicePath
|
|
|
|
);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if (ConDevicePath) {
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
ConsoleName,
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
GetDevicePathSize (ConDevicePath),
|
|
|
|
ConDevicePath
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateConsoleInpOption (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return Var_UpdateConsoleOption (L"ConIn", &ConsoleInpMenu, FORM_CON_IN_ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateConsoleOutOption (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return Var_UpdateConsoleOption (L"ConOut", &ConsoleOutMenu, FORM_CON_OUT_ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateErrorOutOption (
|
|
|
|
VOID
|
|
|
|
)
|
|
|
|
{
|
|
|
|
return Var_UpdateConsoleOption (L"ErrOut", &ConsoleErrMenu, FORM_CON_ERR_ID);
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateDriverOption (
|
|
|
|
IN BMM_CALLBACK_DATA *CallbackData,
|
|
|
|
IN EFI_HII_HANDLE HiiHandle,
|
|
|
|
IN UINT16 *DescriptionData,
|
|
|
|
IN UINT16 *OptionalData,
|
|
|
|
IN UINT8 ForceReconnect
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT16 Index;
|
|
|
|
UINT16 *DriverOrderList;
|
|
|
|
UINT16 *NewDriverOrderList;
|
|
|
|
UINT16 DriverString[12];
|
|
|
|
UINTN DriverOrderListSize;
|
|
|
|
VOID *Buffer;
|
|
|
|
UINTN BufferSize;
|
|
|
|
UINT8 *Ptr;
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
|
|
BOOLEAN OptionalDataExist;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
OptionalDataExist = FALSE;
|
|
|
|
|
|
|
|
Index = BOpt_GetDriverOptionNumber ();
|
|
|
|
UnicodeSPrint (
|
|
|
|
DriverString,
|
|
|
|
sizeof (DriverString),
|
|
|
|
L"Driver%04x",
|
|
|
|
Index
|
|
|
|
);
|
|
|
|
|
|
|
|
if (*DescriptionData == 0x0000) {
|
|
|
|
StrCpy (DescriptionData, DriverString);
|
|
|
|
}
|
|
|
|
|
|
|
|
BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);
|
|
|
|
|
|
|
|
if (*OptionalData != 0x0000) {
|
|
|
|
OptionalDataExist = TRUE;
|
|
|
|
BufferSize += StrSize (OptionalData);
|
|
|
|
}
|
|
|
|
|
|
|
|
Buffer = AllocateZeroPool (BufferSize);
|
|
|
|
if (NULL == Buffer) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
NewLoadContext->Deleted = FALSE;
|
|
|
|
NewLoadContext->LoadOptionSize = BufferSize;
|
|
|
|
Ptr = (UINT8 *) Buffer;
|
|
|
|
NewLoadContext->LoadOption = Ptr;
|
|
|
|
*((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE | (ForceReconnect << 1);
|
|
|
|
NewLoadContext->Attributes = *((UINT32 *) Ptr);
|
|
|
|
NewLoadContext->IsActive = TRUE;
|
|
|
|
NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
|
|
|
|
|
|
|
|
Ptr += sizeof (UINT32);
|
|
|
|
*((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
|
|
|
|
NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
|
|
|
|
|
|
|
|
Ptr += sizeof (UINT16);
|
|
|
|
CopyMem (
|
|
|
|
Ptr,
|
|
|
|
DescriptionData,
|
|
|
|
StrSize (DescriptionData)
|
|
|
|
);
|
|
|
|
|
|
|
|
NewLoadContext->Description = AllocateZeroPool (StrSize (DescriptionData));
|
|
|
|
ASSERT (NewLoadContext->Description != NULL);
|
|
|
|
NewMenuEntry->DisplayString = NewLoadContext->Description;
|
|
|
|
CopyMem (
|
|
|
|
NewLoadContext->Description,
|
|
|
|
(VOID *) Ptr,
|
|
|
|
StrSize (DescriptionData)
|
|
|
|
);
|
|
|
|
|
|
|
|
Ptr += StrSize (DescriptionData);
|
|
|
|
CopyMem (
|
|
|
|
Ptr,
|
|
|
|
CallbackData->LoadContext->FilePathList,
|
|
|
|
GetDevicePathSize (CallbackData->LoadContext->FilePathList)
|
|
|
|
);
|
|
|
|
|
|
|
|
NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
|
|
|
|
ASSERT (NewLoadContext->FilePathList != NULL);
|
|
|
|
|
|
|
|
CopyMem (
|
|
|
|
NewLoadContext->FilePathList,
|
|
|
|
(VOID *) Ptr,
|
|
|
|
GetDevicePathSize (CallbackData->LoadContext->FilePathList)
|
|
|
|
);
|
|
|
|
|
|
|
|
NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
|
|
|
|
NewMenuEntry->OptionNumber = Index;
|
|
|
|
NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
|
|
|
|
CallbackData,
|
|
|
|
DriverOptionStrDepository
|
|
|
|
);
|
|
|
|
CallbackData->Hii->NewString (
|
|
|
|
CallbackData->Hii,
|
|
|
|
NULL,
|
|
|
|
HiiHandle,
|
|
|
|
&NewMenuEntry->DisplayStringToken,
|
|
|
|
NewMenuEntry->DisplayString
|
|
|
|
);
|
|
|
|
|
|
|
|
NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
|
|
|
|
CallbackData,
|
|
|
|
DriverOptionHelpStrDepository
|
|
|
|
);
|
|
|
|
CallbackData->Hii->NewString (
|
|
|
|
CallbackData->Hii,
|
|
|
|
NULL,
|
|
|
|
HiiHandle,
|
|
|
|
&NewMenuEntry->HelpStringToken,
|
|
|
|
NewMenuEntry->HelpString
|
|
|
|
);
|
|
|
|
|
|
|
|
if (OptionalDataExist) {
|
|
|
|
Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
|
|
|
|
|
|
|
|
CopyMem (
|
|
|
|
Ptr,
|
|
|
|
OptionalData,
|
|
|
|
StrSize (OptionalData)
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
DriverString,
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
BufferSize,
|
|
|
|
Buffer
|
|
|
|
);
|
|
|
|
DriverOrderList = BdsLibGetVariableAndSize (
|
|
|
|
L"DriverOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
&DriverOrderListSize
|
|
|
|
);
|
|
|
|
NewDriverOrderList = AllocateZeroPool (DriverOrderListSize + sizeof (UINT16));
|
|
|
|
ASSERT (NewDriverOrderList != NULL);
|
|
|
|
CopyMem (NewDriverOrderList, DriverOrderList, DriverOrderListSize);
|
|
|
|
NewDriverOrderList[DriverOrderListSize / sizeof (UINT16)] = Index;
|
|
|
|
if (DriverOrderList != NULL) {
|
|
|
|
EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"DriverOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
DriverOrderListSize + sizeof (UINT16),
|
|
|
|
NewDriverOrderList
|
|
|
|
);
|
|
|
|
SafeFreePool (DriverOrderList);
|
|
|
|
DriverOrderList = NULL;
|
|
|
|
SafeFreePool (NewDriverOrderList);
|
|
|
|
NewDriverOrderList = NULL;
|
|
|
|
InsertTailList (&DriverOptionMenu.Head, &NewMenuEntry->Link);
|
|
|
|
DriverOptionMenu.MenuNumber++;
|
|
|
|
|
|
|
|
*DescriptionData = 0x0000;
|
|
|
|
*OptionalData = 0x0000;
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateBootOption (
|
|
|
|
IN BMM_CALLBACK_DATA *CallbackData,
|
|
|
|
IN FILE_EXPLORER_NV_DATA *NvRamMap
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINT16 *BootOrderList;
|
|
|
|
UINT16 *NewBootOrderList;
|
|
|
|
UINTN BootOrderListSize;
|
|
|
|
UINT16 BootString[10];
|
|
|
|
VOID *Buffer;
|
|
|
|
UINTN BufferSize;
|
|
|
|
UINT8 *Ptr;
|
|
|
|
UINT16 Index;
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
|
|
BOOLEAN OptionalDataExist;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
OptionalDataExist = FALSE;
|
|
|
|
|
|
|
|
Index = BOpt_GetBootOptionNumber ();
|
|
|
|
UnicodeSPrint (BootString, sizeof (BootString), L"Boot%04x", Index);
|
|
|
|
|
|
|
|
if (NvRamMap->DescriptionData[0] == 0x0000) {
|
|
|
|
StrCpy (NvRamMap->DescriptionData, BootString);
|
|
|
|
}
|
|
|
|
|
|
|
|
BufferSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (NvRamMap->DescriptionData) + GetDevicePathSize (CallbackData->LoadContext->FilePathList);
|
|
|
|
|
|
|
|
if (NvRamMap->OptionalData[0] != 0x0000) {
|
|
|
|
OptionalDataExist = TRUE;
|
|
|
|
BufferSize += StrSize (NvRamMap->OptionalData);
|
|
|
|
}
|
|
|
|
|
|
|
|
Buffer = AllocateZeroPool (BufferSize);
|
|
|
|
if (NULL == Buffer) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewMenuEntry = BOpt_CreateMenuEntry (BM_LOAD_CONTEXT_SELECT);
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
NewLoadContext->Deleted = FALSE;
|
|
|
|
NewLoadContext->LoadOptionSize = BufferSize;
|
|
|
|
Ptr = (UINT8 *) Buffer;
|
|
|
|
NewLoadContext->LoadOption = Ptr;
|
|
|
|
*((UINT32 *) Ptr) = LOAD_OPTION_ACTIVE;
|
|
|
|
NewLoadContext->Attributes = *((UINT32 *) Ptr);
|
|
|
|
NewLoadContext->IsActive = TRUE;
|
|
|
|
NewLoadContext->ForceReconnect = (BOOLEAN) (NewLoadContext->Attributes & LOAD_OPTION_FORCE_RECONNECT);
|
|
|
|
|
|
|
|
Ptr += sizeof (UINT32);
|
|
|
|
*((UINT16 *) Ptr) = (UINT16) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
|
|
|
|
NewLoadContext->FilePathListLength = *((UINT16 *) Ptr);
|
|
|
|
Ptr += sizeof (UINT16);
|
|
|
|
|
|
|
|
CopyMem (
|
|
|
|
Ptr,
|
|
|
|
NvRamMap->DescriptionData,
|
|
|
|
StrSize (NvRamMap->DescriptionData)
|
|
|
|
);
|
|
|
|
|
|
|
|
NewLoadContext->Description = AllocateZeroPool (StrSize (NvRamMap->DescriptionData));
|
|
|
|
ASSERT (NewLoadContext->Description != NULL);
|
|
|
|
|
|
|
|
NewMenuEntry->DisplayString = NewLoadContext->Description;
|
|
|
|
CopyMem (
|
|
|
|
NewLoadContext->Description,
|
|
|
|
(VOID *) Ptr,
|
|
|
|
StrSize (NvRamMap->DescriptionData)
|
|
|
|
);
|
|
|
|
|
|
|
|
Ptr += StrSize (NvRamMap->DescriptionData);
|
|
|
|
CopyMem (
|
|
|
|
Ptr,
|
|
|
|
CallbackData->LoadContext->FilePathList,
|
|
|
|
GetDevicePathSize (CallbackData->LoadContext->FilePathList)
|
|
|
|
);
|
|
|
|
|
|
|
|
NewLoadContext->FilePathList = AllocateZeroPool (GetDevicePathSize (CallbackData->LoadContext->FilePathList));
|
|
|
|
ASSERT (NewLoadContext->FilePathList != NULL);
|
|
|
|
|
|
|
|
CopyMem (
|
|
|
|
NewLoadContext->FilePathList,
|
|
|
|
(VOID *) Ptr,
|
|
|
|
GetDevicePathSize (CallbackData->LoadContext->FilePathList)
|
|
|
|
);
|
|
|
|
|
|
|
|
NewMenuEntry->HelpString = DevicePathToStr (NewLoadContext->FilePathList);
|
|
|
|
NewMenuEntry->OptionNumber = Index;
|
|
|
|
NewMenuEntry->DisplayStringToken = GetStringTokenFromDepository (
|
|
|
|
CallbackData,
|
|
|
|
BootOptionStrDepository
|
|
|
|
);
|
|
|
|
CallbackData->Hii->NewString (
|
|
|
|
CallbackData->Hii,
|
|
|
|
NULL,
|
|
|
|
CallbackData->FeHiiHandle,
|
|
|
|
&NewMenuEntry->DisplayStringToken,
|
|
|
|
NewMenuEntry->DisplayString
|
|
|
|
);
|
|
|
|
|
|
|
|
NewMenuEntry->HelpStringToken = GetStringTokenFromDepository (
|
|
|
|
CallbackData,
|
|
|
|
BootOptionHelpStrDepository
|
|
|
|
);
|
|
|
|
|
|
|
|
CallbackData->Hii->NewString (
|
|
|
|
CallbackData->Hii,
|
|
|
|
NULL,
|
|
|
|
CallbackData->FeHiiHandle,
|
|
|
|
&NewMenuEntry->HelpStringToken,
|
|
|
|
NewMenuEntry->HelpString
|
|
|
|
);
|
|
|
|
|
|
|
|
if (OptionalDataExist) {
|
|
|
|
Ptr += (UINT8) GetDevicePathSize (CallbackData->LoadContext->FilePathList);
|
|
|
|
|
|
|
|
CopyMem (Ptr, NvRamMap->OptionalData, StrSize (NvRamMap->OptionalData));
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
BootString,
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
BufferSize,
|
|
|
|
Buffer
|
|
|
|
);
|
|
|
|
|
|
|
|
BootOrderList = BdsLibGetVariableAndSize (
|
|
|
|
L"BootOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
&BootOrderListSize
|
|
|
|
);
|
|
|
|
|
|
|
|
NewBootOrderList = AllocateZeroPool (BootOrderListSize + sizeof (UINT16));
|
|
|
|
ASSERT (NewBootOrderList != NULL);
|
|
|
|
CopyMem (NewBootOrderList, BootOrderList, BootOrderListSize);
|
|
|
|
NewBootOrderList[BootOrderListSize / sizeof (UINT16)] = Index;
|
|
|
|
|
|
|
|
if (BootOrderList != NULL) {
|
|
|
|
EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"BootOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
BootOrderListSize + sizeof (UINT16),
|
|
|
|
NewBootOrderList
|
|
|
|
);
|
|
|
|
|
|
|
|
SafeFreePool (BootOrderList);
|
|
|
|
BootOrderList = NULL;
|
|
|
|
SafeFreePool (NewBootOrderList);
|
|
|
|
NewBootOrderList = NULL;
|
|
|
|
InsertTailList (&BootOptionMenu.Head, &NewMenuEntry->Link);
|
|
|
|
BootOptionMenu.MenuNumber++;
|
|
|
|
|
|
|
|
NvRamMap->DescriptionData[0] = 0x0000;
|
|
|
|
NvRamMap->OptionalData[0] = 0x0000;
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateBootNext (
|
|
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
|
|
)
|
|
|
|
{
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
BM_LOAD_CONTEXT *NewLoadContext;
|
|
|
|
BMM_FAKE_NV_DATA *CurrentFakeNVMap;
|
|
|
|
UINT16 Index;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
CurrentFakeNVMap = CallbackData->BmmFakeNvData;
|
|
|
|
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (&BootOptionMenu, Index);
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
NewLoadContext->IsBootNext = FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (CurrentFakeNVMap->BootNext == BootOptionMenu.MenuNumber) {
|
|
|
|
EfiLibDeleteVariable (L"BootNext", &gEfiGlobalVariableGuid);
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (
|
|
|
|
&BootOptionMenu,
|
|
|
|
CurrentFakeNVMap->BootNext
|
|
|
|
);
|
|
|
|
if (NULL == NewMenuEntry) {
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewLoadContext = (BM_LOAD_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"BootNext",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
sizeof (UINT16),
|
|
|
|
&NewMenuEntry->OptionNumber
|
|
|
|
);
|
|
|
|
NewLoadContext->IsBootNext = TRUE;
|
|
|
|
CallbackData->BmmOldFakeNVData.BootNext = CurrentFakeNVMap->BootNext;
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateBootOrder (
|
|
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINT16 Index;
|
|
|
|
UINT16 *BootOrderList;
|
|
|
|
UINT16 *NewBootOrderList;
|
|
|
|
UINTN BootOrderListSize;
|
|
|
|
UINT8 *Map;
|
|
|
|
|
|
|
|
BootOrderList = NULL;
|
|
|
|
BootOrderListSize = 0;
|
|
|
|
|
|
|
|
//
|
|
|
|
// First check whether BootOrder is present in current configuration
|
|
|
|
//
|
|
|
|
BootOrderList = BdsLibGetVariableAndSize (
|
|
|
|
L"BootOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
&BootOrderListSize
|
|
|
|
);
|
|
|
|
|
|
|
|
NewBootOrderList = AllocateZeroPool (BootOrderListSize);
|
|
|
|
if (!NewBootOrderList) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
Map = AllocateZeroPool (BootOrderListSize / sizeof (UINT16));
|
|
|
|
if (!Map) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// If exists, delete it to hold new BootOrder
|
|
|
|
//
|
|
|
|
if (BootOrderList) {
|
|
|
|
EfiLibDeleteVariable (L"BootOrder", &gEfiGlobalVariableGuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Index = 0; Index < BootOptionMenu.MenuNumber; Index++) {
|
|
|
|
NewBootOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"BootOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
BootOrderListSize,
|
|
|
|
NewBootOrderList
|
|
|
|
);
|
|
|
|
SafeFreePool (BootOrderList);
|
|
|
|
SafeFreePool (NewBootOrderList);
|
|
|
|
SafeFreePool (Map);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
BOpt_FreeMenu (&BootOptionMenu);
|
|
|
|
BOpt_GetBootOptions (CallbackData);
|
|
|
|
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateDriverOrder (
|
|
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
|
|
)
|
|
|
|
{
|
|
|
|
EFI_STATUS Status;
|
|
|
|
UINT16 Index;
|
|
|
|
UINT16 *DriverOrderList;
|
|
|
|
UINT16 *NewDriverOrderList;
|
|
|
|
UINTN DriverOrderListSize;
|
|
|
|
|
|
|
|
DriverOrderList = NULL;
|
|
|
|
DriverOrderListSize = 0;
|
|
|
|
|
|
|
|
//
|
|
|
|
// First check whether DriverOrder is present in current configuration
|
|
|
|
//
|
|
|
|
DriverOrderList = BdsLibGetVariableAndSize (
|
|
|
|
L"DriverOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
&DriverOrderListSize
|
|
|
|
);
|
|
|
|
|
|
|
|
NewDriverOrderList = AllocateZeroPool (DriverOrderListSize);
|
|
|
|
|
|
|
|
if (!NewDriverOrderList) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// If exists, delete it to hold new DriverOrder
|
|
|
|
//
|
|
|
|
if (DriverOrderList) {
|
|
|
|
EfiLibDeleteVariable (L"DriverOrder", &gEfiGlobalVariableGuid);
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Index = 0; Index < DriverOrderListSize; Index++) {
|
|
|
|
NewDriverOrderList[Index] = CallbackData->BmmFakeNvData->OptionOrder[Index] - 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
L"DriverOrder",
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
DriverOrderListSize,
|
|
|
|
NewDriverOrderList
|
|
|
|
);
|
|
|
|
if (EFI_ERROR (Status)) {
|
|
|
|
return Status;
|
|
|
|
}
|
|
|
|
|
|
|
|
SafeFreePool (DriverOrderList);
|
|
|
|
|
|
|
|
BOpt_FreeMenu (&DriverOptionMenu);
|
|
|
|
BOpt_GetDriverOptions (CallbackData);
|
|
|
|
return EFI_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
EFI_STATUS
|
|
|
|
Var_UpdateBBSOption (
|
|
|
|
IN BMM_CALLBACK_DATA *CallbackData
|
|
|
|
)
|
|
|
|
{
|
|
|
|
UINTN Index;
|
|
|
|
UINTN Index2;
|
|
|
|
VOID *BootOptionVar;
|
|
|
|
CHAR16 VarName[100];
|
|
|
|
UINTN OptionSize;
|
|
|
|
UINT16 FilePathSize;
|
|
|
|
UINT8 *Ptr;
|
|
|
|
EFI_STATUS Status;
|
|
|
|
CHAR16 DescString[100];
|
|
|
|
UINTN NewOptionSize;
|
|
|
|
UINT8 *NewOptionPtr;
|
|
|
|
UINT8 *TempPtr;
|
|
|
|
UINT32 *Attribute;
|
|
|
|
|
|
|
|
BM_MENU_OPTION *OptionMenu;
|
|
|
|
BM_LEGACY_DEVICE_CONTEXT *LegacyDeviceContext;
|
|
|
|
UINT8 *LegacyDev;
|
|
|
|
UINT8 *VarData;
|
|
|
|
UINTN VarSize;
|
|
|
|
BM_MENU_ENTRY *NewMenuEntry;
|
|
|
|
BM_LEGACY_DEV_ORDER_CONTEXT *DevOrder;
|
|
|
|
UINT8 *OriginalPtr;
|
|
|
|
UINT8 *DisMap;
|
|
|
|
UINTN Pos;
|
|
|
|
UINTN Bit;
|
|
|
|
UINT16 *NewOrder;
|
|
|
|
UINT16 Tmp;
|
|
|
|
|
|
|
|
LegacyDeviceContext = NULL;
|
|
|
|
DisMap = NULL;
|
|
|
|
NewOrder = NULL;
|
|
|
|
|
|
|
|
if (FORM_SET_FD_ORDER_ID == CallbackData->BmmPreviousPageId) {
|
|
|
|
OptionMenu = (BM_MENU_OPTION *) &LegacyFDMenu;
|
|
|
|
LegacyDev = CallbackData->BmmFakeNvData->LegacyFD;
|
|
|
|
CallbackData->BbsType = BBS_FLOPPY;
|
|
|
|
} else {
|
|
|
|
if (FORM_SET_HD_ORDER_ID == CallbackData->BmmPreviousPageId) {
|
|
|
|
OptionMenu = (BM_MENU_OPTION *) &LegacyHDMenu;
|
|
|
|
LegacyDev = CallbackData->BmmFakeNvData->LegacyHD;
|
|
|
|
CallbackData->BbsType = BBS_HARDDISK;
|
|
|
|
} else {
|
|
|
|
if (FORM_SET_CD_ORDER_ID == CallbackData->BmmPreviousPageId) {
|
|
|
|
OptionMenu = (BM_MENU_OPTION *) &LegacyCDMenu;
|
|
|
|
LegacyDev = CallbackData->BmmFakeNvData->LegacyCD;
|
|
|
|
CallbackData->BbsType = BBS_CDROM;
|
|
|
|
} else {
|
|
|
|
if (FORM_SET_NET_ORDER_ID == CallbackData->BmmPreviousPageId) {
|
|
|
|
OptionMenu = (BM_MENU_OPTION *) &LegacyNETMenu;
|
|
|
|
LegacyDev = CallbackData->BmmFakeNvData->LegacyNET;
|
|
|
|
CallbackData->BbsType = BBS_EMBED_NETWORK;
|
|
|
|
} else {
|
|
|
|
OptionMenu = (BM_MENU_OPTION *) &LegacyBEVMenu;
|
|
|
|
LegacyDev = CallbackData->BmmFakeNvData->LegacyBEV;
|
|
|
|
CallbackData->BbsType = BBS_BEV_DEVICE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
DisMap = CallbackData->BmmOldFakeNVData.DisableMap;
|
|
|
|
Status = EFI_SUCCESS;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Find the first device's context
|
|
|
|
// If all devices are disabled( 0xFF == LegacyDev[0]), LegacyDeviceContext can be set to any VariableContext
|
|
|
|
// because we just use it to fill the desc string, and user can not see the string in UI
|
|
|
|
//
|
|
|
|
for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
|
|
|
|
NewMenuEntry = BOpt_GetMenuEntry (OptionMenu, Index);
|
|
|
|
LegacyDeviceContext = (BM_LEGACY_DEVICE_CONTEXT *) NewMenuEntry->VariableContext;
|
|
|
|
if (0xFF != LegacyDev[0] && LegacyDev[0] == LegacyDeviceContext->Index) {
|
|
|
|
DEBUG ((EFI_D_ERROR, "DescStr: %s\n", LegacyDeviceContext->Description));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// Update the Variable "LegacyDevOrder"
|
|
|
|
//
|
|
|
|
VarData = (UINT8 *) BdsLibGetVariableAndSize (
|
|
|
|
VarLegacyDevOrder,
|
|
|
|
&EfiLegacyDevOrderGuid,
|
|
|
|
&VarSize
|
|
|
|
);
|
|
|
|
|
|
|
|
if (NULL == VarData) {
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
OriginalPtr = VarData;
|
|
|
|
DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
|
|
|
|
|
|
|
|
while (VarData < VarData + VarSize) {
|
|
|
|
if (DevOrder->BbsType == CallbackData->BbsType) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
VarData += sizeof (BBS_TYPE);
|
|
|
|
VarData += *(UINT16 *) VarData;
|
|
|
|
DevOrder = (BM_LEGACY_DEV_ORDER_CONTEXT *) VarData;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (VarData >= VarData + VarSize) {
|
|
|
|
SafeFreePool (OriginalPtr);
|
|
|
|
return EFI_NOT_FOUND;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewOrder = (UINT16 *) AllocateZeroPool (DevOrder->Length - sizeof (UINT16));
|
|
|
|
if (NULL == NewOrder) {
|
|
|
|
SafeFreePool (VarData);
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (Index = 0; Index < OptionMenu->MenuNumber; Index++) {
|
|
|
|
if (0xFF == LegacyDev[Index]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
NewOrder[Index] = LegacyDev[Index];
|
|
|
|
}
|
|
|
|
//
|
|
|
|
// Only the enable/disable state of each boot device with same device type can be changed,
|
|
|
|
// so we can count on the index information in DevOrder.
|
|
|
|
// DisMap bit array is the only reliable source to check a device's en/dis state,
|
|
|
|
// so we use DisMap to set en/dis state of each item in NewOrder array
|
|
|
|
//
|
|
|
|
for (Index2 = 0; Index2 < OptionMenu->MenuNumber; Index2++) {
|
|
|
|
Tmp = *(UINT16 *) ((UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16) + Index2 * sizeof (UINT16));
|
|
|
|
Tmp &= 0xFF;
|
|
|
|
Pos = Tmp / 8;
|
|
|
|
Bit = 7 - (Tmp % 8);
|
|
|
|
if (DisMap[Pos] & (1 << Bit)) {
|
|
|
|
NewOrder[Index] = (UINT16) (0xFF00 | Tmp);
|
|
|
|
Index++;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
CopyMem (
|
|
|
|
(UINT8 *) DevOrder + sizeof (BBS_TYPE) + sizeof (UINT16),
|
|
|
|
NewOrder,
|
|
|
|
DevOrder->Length - sizeof (UINT16)
|
|
|
|
);
|
|
|
|
SafeFreePool (NewOrder);
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
VarLegacyDevOrder,
|
|
|
|
&EfiLegacyDevOrderGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
VarSize,
|
|
|
|
OriginalPtr
|
|
|
|
);
|
|
|
|
|
|
|
|
SafeFreePool (OriginalPtr);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Update Optional Data of Boot####
|
|
|
|
//
|
|
|
|
BootOptionVar = GetLegacyBootOptionVar (CallbackData->BbsType, &Index, &OptionSize);
|
|
|
|
|
|
|
|
if (NULL != BootOptionVar) {
|
|
|
|
CopyMem (
|
|
|
|
DescString,
|
|
|
|
LegacyDeviceContext->Description,
|
|
|
|
StrSize (LegacyDeviceContext->Description)
|
|
|
|
);
|
|
|
|
|
|
|
|
NewOptionSize = sizeof (UINT32) + sizeof (UINT16) + StrSize (DescString) + sizeof (BBS_TABLE) + sizeof (UINT16);
|
|
|
|
|
|
|
|
UnicodeSPrint (VarName, 100, L"Boot%04x", Index);
|
|
|
|
|
|
|
|
Ptr = BootOptionVar;
|
|
|
|
|
|
|
|
Attribute = (UINT32 *) Ptr;
|
|
|
|
*Attribute |= LOAD_OPTION_ACTIVE;
|
|
|
|
if (0xFF == LegacyDev[0]) {
|
|
|
|
//
|
|
|
|
// Disable this legacy boot option
|
|
|
|
//
|
|
|
|
*Attribute &= ~LOAD_OPTION_ACTIVE;
|
|
|
|
}
|
|
|
|
|
|
|
|
Ptr += sizeof (UINT32);
|
|
|
|
|
|
|
|
FilePathSize = *(UINT16 *) Ptr;
|
|
|
|
Ptr += sizeof (UINT16);
|
|
|
|
|
|
|
|
NewOptionSize += FilePathSize;
|
|
|
|
|
|
|
|
NewOptionPtr = AllocateZeroPool (NewOptionSize);
|
|
|
|
if (NULL == NewOptionPtr) {
|
|
|
|
return EFI_OUT_OF_RESOURCES;
|
|
|
|
}
|
|
|
|
|
|
|
|
TempPtr = NewOptionPtr;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Copy previous option data to new option except the description string
|
|
|
|
//
|
|
|
|
CopyMem (
|
|
|
|
TempPtr,
|
|
|
|
BootOptionVar,
|
|
|
|
sizeof (UINT32) + sizeof (UINT16)
|
|
|
|
);
|
|
|
|
|
|
|
|
TempPtr += (sizeof (UINT32) + sizeof (UINT16));
|
|
|
|
|
|
|
|
CopyMem (
|
|
|
|
TempPtr,
|
|
|
|
DescString,
|
|
|
|
StrSize (DescString)
|
|
|
|
);
|
|
|
|
|
|
|
|
TempPtr += StrSize (DescString);
|
|
|
|
|
|
|
|
//
|
|
|
|
// Description = (CHAR16 *)Ptr;
|
|
|
|
//
|
|
|
|
Ptr += StrSize ((CHAR16 *) Ptr);
|
|
|
|
|
|
|
|
CopyMem (
|
|
|
|
TempPtr,
|
|
|
|
Ptr,
|
|
|
|
FilePathSize
|
|
|
|
);
|
|
|
|
|
|
|
|
TempPtr += FilePathSize;
|
|
|
|
|
|
|
|
//
|
|
|
|
// DevicePath = (EFI_DEVICE_PATH_PROTOCOL *)Ptr;
|
|
|
|
//
|
|
|
|
Ptr += FilePathSize;
|
|
|
|
|
|
|
|
//
|
|
|
|
// Now Ptr point to optional data, i.e. Bbs Table
|
|
|
|
//
|
|
|
|
CopyMem (
|
|
|
|
TempPtr,
|
|
|
|
LegacyDeviceContext->BbsTable,
|
|
|
|
sizeof (BBS_TABLE)
|
|
|
|
);
|
|
|
|
|
|
|
|
TempPtr += sizeof (BBS_TABLE);
|
|
|
|
*((UINT16 *) TempPtr) = (UINT16) LegacyDeviceContext->Index;
|
|
|
|
|
|
|
|
Status = gRT->SetVariable (
|
|
|
|
VarName,
|
|
|
|
&gEfiGlobalVariableGuid,
|
|
|
|
VAR_FLAG,
|
|
|
|
NewOptionSize,
|
|
|
|
NewOptionPtr
|
|
|
|
);
|
|
|
|
|
|
|
|
SafeFreePool (NewOptionPtr);
|
|
|
|
SafeFreePool (BootOptionVar);
|
|
|
|
}
|
|
|
|
|
|
|
|
BOpt_GetBootOptions (CallbackData);
|
|
|
|
return Status;
|
|
|
|
}
|