Update video card preference policy, together with some memory leaks in Generic BDS Library.

git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@2234 6f19259b-4bc3-4df7-8a09-765794883524
This commit is contained in:
xli24 2007-01-12 05:34:49 +00:00
parent 74c56167df
commit d02ea95873
6 changed files with 374 additions and 140 deletions

View File

@ -246,6 +246,17 @@ BdsLibUnpackDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevPath
);
VOID
BdsLibSafeFreePool (
IN VOID *Buffer
);
EFI_DEVICE_PATH_PROTOCOL *
BdsLibDelPartMatchInstance (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
);
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,

View File

@ -19,6 +19,30 @@ Abstract:
--*/
BOOLEAN
IsNvNeed (
IN CHAR16 *ConVarName
)
{
CHAR16 *Ptr;
Ptr = ConVarName;
//
// If the variable includes "Dev" at last, we consider
// it does not support NV attribute.
//
while (*Ptr) {
Ptr++;
}
if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
return FALSE;
} else {
return TRUE;
}
}
EFI_STATUS
BdsLibUpdateConsoleVariable (
IN CHAR16 *ConVarName,
@ -56,12 +80,12 @@ Returns:
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VarConsole;
UINTN DevicePathSize;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
UINT32 Attributes;
VarConsole = NULL;
DevicePathSize = 0;
NewDevicePath = NULL;
Status = EFI_UNSUPPORTED;
//
@ -79,73 +103,70 @@ Returns:
&gEfiGlobalVariableGuid,
&DevicePathSize
);
//
// Initialize NewDevicePath
//
NewDevicePath = VarConsole;
//
// If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
// In the end, NewDevicePath is the final device path.
//
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {
Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
while (VarConsole != NULL) {
if (CompareMem (
Instance,
ExclusiveDevicePath,
DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)
) == 0) {
//
// Remove the match part
//
NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);
break;
} else {
//
// Continue the next instance
//
NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
}
Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
}
//
// Reset the console variable with new device path
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
GetDevicePathSize (NewDevicePath),
NewDevicePath
);
}
NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
}
//
// Try to append customized device path
// Try to append customized device path to NewDevicePath.
//
VarConsole = BdsLibGetVariableAndSize (
ConVarName,
&gEfiGlobalVariableGuid,
&DevicePathSize
);
if (CustomizedConDevicePath != NULL) {
if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {
if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
//
// Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
//
NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
//
// In the first check, the default console variable will be null,
// just append current customized device path
//
VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);
//
// Update the variable of the default console
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
GetDevicePathSize (VarConsole),
VarConsole
);
TempNewDevicePath = NewDevicePath;
NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
BdsLibSafeFreePool(TempNewDevicePath);
}
}
//
// The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
//
if (IsNvNeed(ConVarName)) {
//
// ConVarName has NV attribute.
//
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
} else {
//
// ConVarName does not have NV attribute.
//
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
}
//
// Finally, Update the variable of the default console by NewDevicePath
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
Attributes,
GetDevicePathSize (NewDevicePath),
NewDevicePath
);
if (VarConsole == NewDevicePath) {
BdsLibSafeFreePool(VarConsole);
} else {
BdsLibSafeFreePool(VarConsole);
BdsLibSafeFreePool(NewDevicePath);
}
return EFI_SUCCESS;
@ -201,7 +222,7 @@ Returns:
return EFI_UNSUPPORTED;
}
CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);
CopyOfDevicePath = StartDevicePath;
do {
//
// Check every instance of the console variable
@ -226,7 +247,7 @@ Returns:
} else {
DeviceExist = TRUE;
}
BdsLibSafeFreePool(Instance);
} while (CopyOfDevicePath != NULL);
gBS->FreePool (StartDevicePath);
@ -289,6 +310,8 @@ Returns:
BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
}
BdsLibSafeFreePool(HandleBuffer);
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleTextOutProtocolGuid,
@ -305,6 +328,9 @@ Returns:
BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
}
BdsLibSafeFreePool(HandleBuffer);
//
// Connect all console variables
//
@ -337,8 +363,6 @@ Returns:
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VarErrout;
UINTN DevicePathSize;
//
// Connect all default console variables
@ -356,14 +380,7 @@ Returns:
// Special treat the err out device, becaues the null
// err out var is legal.
//
VarErrout = BdsLibGetVariableAndSize (
L"ErrOut",
&gEfiGlobalVariableGuid,
&DevicePathSize
);
if (VarErrout != NULL) {
BdsLibConnectConsoleVariable (L"ErrOut");
}
BdsLibConnectConsoleVariable (L"ErrOut");
return EFI_SUCCESS;

View File

@ -651,6 +651,95 @@ Returns:
return Buffer;
}
VOID
BdsLibSafeFreePool (
IN VOID *Buffer
)
/*++
Routine Description:
Free pool safely.
Arguments:
Buffer - The allocated pool entry to free
Returns:
Pointer of the buffer allocated.
--*/
{
if (Buffer != NULL) {
gBS->FreePool (Buffer);
Buffer = NULL;
}
}
EFI_DEVICE_PATH_PROTOCOL *
BdsLibDelPartMatchInstance (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
)
/*++
Routine Description:
Delete the instance in Multi which matches partly with Single instance
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
Returns:
This function will remove the device path instances in Multi which partly
match with the Single, and return the result device path. If there is no
remaining device path as a result, this function will return NULL.
--*/
{
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
UINTN InstanceSize;
UINTN SingleDpSize;
UINTN Size;
NewDevicePath = NULL;
TempNewDevicePath = NULL;
if (Multi == NULL || Single == NULL) {
return Multi;
}
Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
InstanceSize -= END_DEVICE_PATH_LENGTH;
while (Instance != NULL) {
Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
if ((CompareMem (Instance, Single, Size) != 0)) {
//
// Append the device path instance which does not match with Single
//
TempNewDevicePath = NewDevicePath;
NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
BdsLibSafeFreePool(TempNewDevicePath);
}
BdsLibSafeFreePool(Instance);
Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
InstanceSize -= END_DEVICE_PATH_LENGTH;
}
return NewDevicePath;
}
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,

View File

@ -246,6 +246,17 @@ BdsLibUnpackDevicePath (
IN EFI_DEVICE_PATH_PROTOCOL *DevPath
);
VOID
BdsLibSafeFreePool (
IN VOID *Buffer
);
EFI_DEVICE_PATH_PROTOCOL *
BdsLibDelPartMatchInstance (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
);
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,

View File

@ -19,6 +19,30 @@ Abstract:
--*/
BOOLEAN
IsNvNeed (
IN CHAR16 *ConVarName
)
{
CHAR16 *Ptr;
Ptr = ConVarName;
//
// If the variable includes "Dev" at last, we consider
// it does not support NV attribute.
//
while (*Ptr) {
Ptr++;
}
if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {
return FALSE;
} else {
return TRUE;
}
}
EFI_STATUS
BdsLibUpdateConsoleVariable (
IN CHAR16 *ConVarName,
@ -56,12 +80,12 @@ Returns:
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VarConsole;
UINTN DevicePathSize;
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
UINT32 Attributes;
VarConsole = NULL;
DevicePathSize = 0;
NewDevicePath = NULL;
Status = EFI_UNSUPPORTED;
//
@ -79,73 +103,70 @@ Returns:
&gEfiGlobalVariableGuid,
&DevicePathSize
);
//
// Initialize NewDevicePath
//
NewDevicePath = VarConsole;
//
// If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.
// In the end, NewDevicePath is the final device path.
//
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {
if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {
Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
while (VarConsole != NULL) {
if (CompareMem (
Instance,
ExclusiveDevicePath,
DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)
) == 0) {
//
// Remove the match part
//
NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);
break;
} else {
//
// Continue the next instance
//
NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
}
Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);
}
//
// Reset the console variable with new device path
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
GetDevicePathSize (NewDevicePath),
NewDevicePath
);
}
NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);
}
//
// Try to append customized device path
// Try to append customized device path to NewDevicePath.
//
VarConsole = BdsLibGetVariableAndSize (
ConVarName,
&gEfiGlobalVariableGuid,
&DevicePathSize
);
if (CustomizedConDevicePath != NULL) {
if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {
if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {
//
// Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
//
NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
//
// In the first check, the default console variable will be null,
// just append current customized device path
//
VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);
//
// Update the variable of the default console
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,
GetDevicePathSize (VarConsole),
VarConsole
);
TempNewDevicePath = NewDevicePath;
NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);
BdsLibSafeFreePool(TempNewDevicePath);
}
}
//
// The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.
//
if (IsNvNeed(ConVarName)) {
//
// ConVarName has NV attribute.
//
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;
} else {
//
// ConVarName does not have NV attribute.
//
Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;
}
//
// Finally, Update the variable of the default console by NewDevicePath
//
gRT->SetVariable (
ConVarName,
&gEfiGlobalVariableGuid,
Attributes,
GetDevicePathSize (NewDevicePath),
NewDevicePath
);
if (VarConsole == NewDevicePath) {
BdsLibSafeFreePool(VarConsole);
} else {
BdsLibSafeFreePool(VarConsole);
BdsLibSafeFreePool(NewDevicePath);
}
return EFI_SUCCESS;
@ -201,7 +222,7 @@ Returns:
return EFI_UNSUPPORTED;
}
CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);
CopyOfDevicePath = StartDevicePath;
do {
//
// Check every instance of the console variable
@ -226,7 +247,7 @@ Returns:
} else {
DeviceExist = TRUE;
}
BdsLibSafeFreePool(Instance);
} while (CopyOfDevicePath != NULL);
gBS->FreePool (StartDevicePath);
@ -289,6 +310,8 @@ Returns:
BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);
}
BdsLibSafeFreePool(HandleBuffer);
Status = gBS->LocateHandleBuffer (
ByProtocol,
&gEfiSimpleTextOutProtocolGuid,
@ -305,6 +328,9 @@ Returns:
BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);
BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);
}
BdsLibSafeFreePool(HandleBuffer);
//
// Connect all console variables
//
@ -337,8 +363,6 @@ Returns:
--*/
{
EFI_STATUS Status;
EFI_DEVICE_PATH_PROTOCOL *VarErrout;
UINTN DevicePathSize;
//
// Connect all default console variables
@ -356,14 +380,7 @@ Returns:
// Special treat the err out device, becaues the null
// err out var is legal.
//
VarErrout = BdsLibGetVariableAndSize (
L"ErrOut",
&gEfiGlobalVariableGuid,
&DevicePathSize
);
if (VarErrout != NULL) {
BdsLibConnectConsoleVariable (L"ErrOut");
}
BdsLibConnectConsoleVariable (L"ErrOut");
return EFI_SUCCESS;

View File

@ -652,6 +652,95 @@ Returns:
return Buffer;
}
VOID
BdsLibSafeFreePool (
IN VOID *Buffer
)
/*++
Routine Description:
Free pool safely.
Arguments:
Buffer - The allocated pool entry to free
Returns:
Pointer of the buffer allocated.
--*/
{
if (Buffer != NULL) {
gBS->FreePool (Buffer);
Buffer = NULL;
}
}
EFI_DEVICE_PATH_PROTOCOL *
BdsLibDelPartMatchInstance (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,
IN EFI_DEVICE_PATH_PROTOCOL *Single
)
/*++
Routine Description:
Delete the instance in Multi which matches partly with Single instance
Arguments:
Multi - A pointer to a multi-instance device path data structure.
Single - A pointer to a single-instance device path data structure.
Returns:
This function will remove the device path instances in Multi which partly
match with the Single, and return the result device path. If there is no
remaining device path as a result, this function will return NULL.
--*/
{
EFI_DEVICE_PATH_PROTOCOL *Instance;
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;
EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;
UINTN InstanceSize;
UINTN SingleDpSize;
UINTN Size;
NewDevicePath = NULL;
TempNewDevicePath = NULL;
if (Multi == NULL || Single == NULL) {
return Multi;
}
Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;
InstanceSize -= END_DEVICE_PATH_LENGTH;
while (Instance != NULL) {
Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize;
if ((CompareMem (Instance, Single, Size) != 0)) {
//
// Append the device path instance which does not match with Single
//
TempNewDevicePath = NewDevicePath;
NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);
BdsLibSafeFreePool(TempNewDevicePath);
}
BdsLibSafeFreePool(Instance);
Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);
InstanceSize -= END_DEVICE_PATH_LENGTH;
}
return NewDevicePath;
}
BOOLEAN
BdsLibMatchDevicePaths (
IN EFI_DEVICE_PATH_PROTOCOL *Multi,