diff options
Diffstat (limited to 'EdkNt32Pkg')
-rw-r--r-- | EdkNt32Pkg/Include/Library/EdkGenericBdsLib.h | 11 | ||||
-rw-r--r-- | EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c | 157 | ||||
-rw-r--r-- | EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c | 89 |
3 files changed, 187 insertions, 70 deletions
diff --git a/EdkNt32Pkg/Include/Library/EdkGenericBdsLib.h b/EdkNt32Pkg/Include/Library/EdkGenericBdsLib.h index ed52085a17..7ec0222620 100644 --- a/EdkNt32Pkg/Include/Library/EdkGenericBdsLib.h +++ b/EdkNt32Pkg/Include/Library/EdkGenericBdsLib.h @@ -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,
diff --git a/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c b/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c index 721d74363a..6c9097f142 100644 --- a/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c +++ b/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c @@ -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)) {
//
- // In the first check, the default console variable will be null,
- // just append current customized device path
+ // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.
//
- VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);
-
+ NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);
//
- // Update the variable of the default console
+ // In the first check, the default console variable will be null,
+ // just append current customized device path
//
- 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;
diff --git a/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c b/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c index 908bc3059b..e7add072e1 100644 --- a/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c +++ b/EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c @@ -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,
|