IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
);\r
\r
+VOID\r
+BdsLibSafeFreePool (\r
+ IN VOID *Buffer\r
+ );\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsLibDelPartMatchInstance (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Single\r
+ );\r
+\r
BOOLEAN\r
BdsLibMatchDevicePaths (\r
IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
\r
--*/\r
\r
+BOOLEAN\r
+IsNvNeed (\r
+ IN CHAR16 *ConVarName\r
+ )\r
+{\r
+ CHAR16 *Ptr;\r
+ \r
+ Ptr = ConVarName;\r
+ \r
+ //\r
+ // If the variable includes "Dev" at last, we consider\r
+ // it does not support NV attribute.\r
+ //\r
+ while (*Ptr) {\r
+ Ptr++;\r
+ }\r
+ \r
+ if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {\r
+ return FALSE;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+}\r
+\r
EFI_STATUS\r
BdsLibUpdateConsoleVariable (\r
IN CHAR16 *ConVarName,\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
UINTN DevicePathSize;\r
- EFI_DEVICE_PATH_PROTOCOL *Instance;\r
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
+ UINT32 Attributes;\r
\r
VarConsole = NULL;\r
DevicePathSize = 0;\r
- NewDevicePath = NULL;\r
Status = EFI_UNSUPPORTED;\r
\r
//\r
&gEfiGlobalVariableGuid,\r
&DevicePathSize\r
);\r
-\r
+ \r
+ //\r
+ // Initialize NewDevicePath\r
+ //\r
+ NewDevicePath = VarConsole;\r
+ \r
+ //\r
+ // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.\r
+ // In the end, NewDevicePath is the final device path.\r
+ //\r
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {\r
- if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {\r
-\r
- Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
-\r
- while (VarConsole != NULL) {\r
- if (CompareMem (\r
- Instance,\r
- ExclusiveDevicePath,\r
- DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)\r
- ) == 0) {\r
- //\r
- // Remove the match part\r
- //\r
- NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);\r
- break;\r
- } else {\r
- //\r
- // Continue the next instance\r
- //\r
- NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);\r
- }\r
-\r
- Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
- }\r
- //\r
- // Reset the console variable with new device path\r
- //\r
- gRT->SetVariable (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- GetDevicePathSize (NewDevicePath),\r
- NewDevicePath\r
- );\r
- }\r
+ NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
}\r
//\r
- // Try to append customized device path\r
+ // Try to append customized device path to NewDevicePath.\r
//\r
- VarConsole = BdsLibGetVariableAndSize (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- &DevicePathSize\r
- );\r
-\r
if (CustomizedConDevicePath != NULL) {\r
- if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {\r
+ if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
//\r
- // In the first check, the default console variable will be null,\r
- // just append current customized device path\r
+ // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
//\r
- VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);\r
-\r
+ NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);\r
//\r
- // Update the variable of the default console\r
+ // In the first check, the default console variable will be null,\r
+ // just append current customized device path\r
//\r
- gRT->SetVariable (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- GetDevicePathSize (VarConsole),\r
- VarConsole\r
- );\r
+ TempNewDevicePath = NewDevicePath;\r
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);\r
+ BdsLibSafeFreePool(TempNewDevicePath);\r
}\r
}\r
+ \r
+ //\r
+ // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.\r
+ //\r
+ if (IsNvNeed(ConVarName)) {\r
+ //\r
+ // ConVarName has NV attribute.\r
+ //\r
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
+ } else {\r
+ //\r
+ // ConVarName does not have NV attribute.\r
+ //\r
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
+ }\r
+ \r
+ //\r
+ // Finally, Update the variable of the default console by NewDevicePath\r
+ //\r
+ gRT->SetVariable (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ Attributes,\r
+ GetDevicePathSize (NewDevicePath),\r
+ NewDevicePath\r
+ );\r
+\r
+ if (VarConsole == NewDevicePath) {\r
+ BdsLibSafeFreePool(VarConsole);\r
+ } else {\r
+ BdsLibSafeFreePool(VarConsole);\r
+ BdsLibSafeFreePool(NewDevicePath);\r
+ }\r
\r
return EFI_SUCCESS;\r
\r
return EFI_UNSUPPORTED;\r
}\r
\r
- CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);\r
+ CopyOfDevicePath = StartDevicePath;\r
do {\r
//\r
// Check every instance of the console variable\r
} else {\r
DeviceExist = TRUE;\r
}\r
-\r
+ BdsLibSafeFreePool(Instance);\r
} while (CopyOfDevicePath != NULL);\r
\r
gBS->FreePool (StartDevicePath);\r
BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);\r
}\r
\r
+ BdsLibSafeFreePool(HandleBuffer);\r
+\r
Status = gBS->LocateHandleBuffer (\r
ByProtocol,\r
&gEfiSimpleTextOutProtocolGuid,\r
BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);\r
BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);\r
}\r
+\r
+ BdsLibSafeFreePool(HandleBuffer);\r
+\r
//\r
// Connect all console variables\r
//\r
--*/\r
{\r
EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *VarErrout;\r
- UINTN DevicePathSize;\r
\r
//\r
// Connect all default console variables\r
// Special treat the err out device, becaues the null\r
// err out var is legal.\r
//\r
- VarErrout = BdsLibGetVariableAndSize (\r
- L"ErrOut",\r
- &gEfiGlobalVariableGuid,\r
- &DevicePathSize\r
- );\r
- if (VarErrout != NULL) {\r
- BdsLibConnectConsoleVariable (L"ErrOut");\r
- }\r
+ BdsLibConnectConsoleVariable (L"ErrOut");\r
\r
return EFI_SUCCESS;\r
\r
return Buffer;\r
}\r
\r
+VOID\r
+BdsLibSafeFreePool (\r
+ IN VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free pool safely.\r
+\r
+Arguments:\r
+ \r
+ Buffer - The allocated pool entry to free\r
+\r
+Returns:\r
+\r
+ Pointer of the buffer allocated.\r
+\r
+--*/\r
+{\r
+ if (Buffer != NULL) {\r
+ gBS->FreePool (Buffer);\r
+ Buffer = NULL;\r
+ }\r
+}\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsLibDelPartMatchInstance (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Single\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delete the instance in Multi which matches partly with Single instance\r
+\r
+Arguments:\r
+\r
+ Multi - A pointer to a multi-instance device path data structure.\r
+\r
+ Single - A pointer to a single-instance device path data structure.\r
+\r
+Returns:\r
+\r
+ This function will remove the device path instances in Multi which partly \r
+ match with the Single, and return the result device path. If there is no\r
+ remaining device path as a result, this function will return NULL.\r
+\r
+--*/\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *Instance;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
+ UINTN InstanceSize;\r
+ UINTN SingleDpSize; \r
+ UINTN Size; \r
+ \r
+ NewDevicePath = NULL;\r
+ TempNewDevicePath = NULL;\r
+\r
+ if (Multi == NULL || Single == NULL) {\r
+ return Multi;\r
+ }\r
+ \r
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+ SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;\r
+ InstanceSize -= END_DEVICE_PATH_LENGTH;\r
+\r
+ while (Instance != NULL) {\r
+\r
+ Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize; \r
+ \r
+ if ((CompareMem (Instance, Single, Size) != 0)) {\r
+ //\r
+ // Append the device path instance which does not match with Single\r
+ //\r
+ TempNewDevicePath = NewDevicePath;\r
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);\r
+ BdsLibSafeFreePool(TempNewDevicePath);\r
+ }\r
+ BdsLibSafeFreePool(Instance);\r
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+ InstanceSize -= END_DEVICE_PATH_LENGTH;\r
+ }\r
+ \r
+ return NewDevicePath;\r
+}\r
+\r
BOOLEAN\r
BdsLibMatchDevicePaths (\r
IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
IN EFI_DEVICE_PATH_PROTOCOL *DevPath\r
);\r
\r
+VOID\r
+BdsLibSafeFreePool (\r
+ IN VOID *Buffer\r
+ );\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsLibDelPartMatchInstance (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Single\r
+ );\r
+\r
BOOLEAN\r
BdsLibMatchDevicePaths (\r
IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
\r
--*/\r
\r
+BOOLEAN\r
+IsNvNeed (\r
+ IN CHAR16 *ConVarName\r
+ )\r
+{\r
+ CHAR16 *Ptr;\r
+ \r
+ Ptr = ConVarName;\r
+ \r
+ //\r
+ // If the variable includes "Dev" at last, we consider\r
+ // it does not support NV attribute.\r
+ //\r
+ while (*Ptr) {\r
+ Ptr++;\r
+ }\r
+ \r
+ if ((*(Ptr - 3) == 'D') && (*(Ptr - 2) == 'e') && (*(Ptr - 1) == 'v')) {\r
+ return FALSE;\r
+ } else {\r
+ return TRUE;\r
+ }\r
+}\r
+\r
EFI_STATUS\r
BdsLibUpdateConsoleVariable (\r
IN CHAR16 *ConVarName,\r
EFI_STATUS Status;\r
EFI_DEVICE_PATH_PROTOCOL *VarConsole;\r
UINTN DevicePathSize;\r
- EFI_DEVICE_PATH_PROTOCOL *Instance;\r
EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
+ UINT32 Attributes;\r
\r
VarConsole = NULL;\r
DevicePathSize = 0;\r
- NewDevicePath = NULL;\r
Status = EFI_UNSUPPORTED;\r
\r
//\r
&gEfiGlobalVariableGuid,\r
&DevicePathSize\r
);\r
-\r
+ \r
+ //\r
+ // Initialize NewDevicePath\r
+ //\r
+ NewDevicePath = VarConsole;\r
+ \r
+ //\r
+ // If ExclusiveDevicePath is even the part of the instance in VarConsole, delete it.\r
+ // In the end, NewDevicePath is the final device path.\r
+ //\r
if (ExclusiveDevicePath != NULL && VarConsole != NULL) {\r
- if (BdsLibMatchDevicePaths (VarConsole, ExclusiveDevicePath)) {\r
-\r
- Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
-\r
- while (VarConsole != NULL) {\r
- if (CompareMem (\r
- Instance,\r
- ExclusiveDevicePath,\r
- DevicePathSize - sizeof (EFI_DEVICE_PATH_PROTOCOL)\r
- ) == 0) {\r
- //\r
- // Remove the match part\r
- //\r
- NewDevicePath = AppendDevicePathInstance (NewDevicePath, VarConsole);\r
- break;\r
- } else {\r
- //\r
- // Continue the next instance\r
- //\r
- NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);\r
- }\r
-\r
- Instance = GetNextDevicePathInstance (&VarConsole, &DevicePathSize);\r
- }\r
- //\r
- // Reset the console variable with new device path\r
- //\r
- gRT->SetVariable (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- GetDevicePathSize (NewDevicePath),\r
- NewDevicePath\r
- );\r
- }\r
+ NewDevicePath = BdsLibDelPartMatchInstance (VarConsole, ExclusiveDevicePath);\r
}\r
//\r
- // Try to append customized device path\r
+ // Try to append customized device path to NewDevicePath.\r
//\r
- VarConsole = BdsLibGetVariableAndSize (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- &DevicePathSize\r
- );\r
-\r
if (CustomizedConDevicePath != NULL) {\r
- if (!BdsLibMatchDevicePaths (VarConsole, CustomizedConDevicePath)) {\r
+ if (!BdsLibMatchDevicePaths (NewDevicePath, CustomizedConDevicePath)) {\r
//\r
- // In the first check, the default console variable will be null,\r
- // just append current customized device path\r
+ // Check if there is part of CustomizedConDevicePath in NewDevicePath, delete it.\r
//\r
- VarConsole = AppendDevicePathInstance (VarConsole, CustomizedConDevicePath);\r
-\r
+ NewDevicePath = BdsLibDelPartMatchInstance (NewDevicePath, CustomizedConDevicePath);\r
//\r
- // Update the variable of the default console\r
+ // In the first check, the default console variable will be null,\r
+ // just append current customized device path\r
//\r
- gRT->SetVariable (\r
- ConVarName,\r
- &gEfiGlobalVariableGuid,\r
- EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE,\r
- GetDevicePathSize (VarConsole),\r
- VarConsole\r
- );\r
+ TempNewDevicePath = NewDevicePath;\r
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, CustomizedConDevicePath);\r
+ BdsLibSafeFreePool(TempNewDevicePath);\r
}\r
}\r
+ \r
+ //\r
+ // The attribute for ConInDev, ConOutDev and ErrOutDev does not include NV.\r
+ //\r
+ if (IsNvNeed(ConVarName)) {\r
+ //\r
+ // ConVarName has NV attribute.\r
+ //\r
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS | EFI_VARIABLE_NON_VOLATILE;\r
+ } else {\r
+ //\r
+ // ConVarName does not have NV attribute.\r
+ //\r
+ Attributes = EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS;\r
+ }\r
+ \r
+ //\r
+ // Finally, Update the variable of the default console by NewDevicePath\r
+ //\r
+ gRT->SetVariable (\r
+ ConVarName,\r
+ &gEfiGlobalVariableGuid,\r
+ Attributes,\r
+ GetDevicePathSize (NewDevicePath),\r
+ NewDevicePath\r
+ );\r
+\r
+ if (VarConsole == NewDevicePath) {\r
+ BdsLibSafeFreePool(VarConsole);\r
+ } else {\r
+ BdsLibSafeFreePool(VarConsole);\r
+ BdsLibSafeFreePool(NewDevicePath);\r
+ }\r
\r
return EFI_SUCCESS;\r
\r
return EFI_UNSUPPORTED;\r
}\r
\r
- CopyOfDevicePath = DuplicateDevicePath (StartDevicePath);\r
+ CopyOfDevicePath = StartDevicePath;\r
do {\r
//\r
// Check every instance of the console variable\r
} else {\r
DeviceExist = TRUE;\r
}\r
-\r
+ BdsLibSafeFreePool(Instance);\r
} while (CopyOfDevicePath != NULL);\r
\r
gBS->FreePool (StartDevicePath);\r
BdsLibUpdateConsoleVariable (L"ConIn", ConDevicePath, NULL);\r
}\r
\r
+ BdsLibSafeFreePool(HandleBuffer);\r
+\r
Status = gBS->LocateHandleBuffer (\r
ByProtocol,\r
&gEfiSimpleTextOutProtocolGuid,\r
BdsLibUpdateConsoleVariable (L"ConOut", ConDevicePath, NULL);\r
BdsLibUpdateConsoleVariable (L"ErrOut", ConDevicePath, NULL);\r
}\r
+\r
+ BdsLibSafeFreePool(HandleBuffer);\r
+\r
//\r
// Connect all console variables\r
//\r
--*/\r
{\r
EFI_STATUS Status;\r
- EFI_DEVICE_PATH_PROTOCOL *VarErrout;\r
- UINTN DevicePathSize;\r
\r
//\r
// Connect all default console variables\r
// Special treat the err out device, becaues the null\r
// err out var is legal.\r
//\r
- VarErrout = BdsLibGetVariableAndSize (\r
- L"ErrOut",\r
- &gEfiGlobalVariableGuid,\r
- &DevicePathSize\r
- );\r
- if (VarErrout != NULL) {\r
- BdsLibConnectConsoleVariable (L"ErrOut");\r
- }\r
+ BdsLibConnectConsoleVariable (L"ErrOut");\r
\r
return EFI_SUCCESS;\r
\r
return Buffer;\r
}\r
\r
+VOID\r
+BdsLibSafeFreePool (\r
+ IN VOID *Buffer\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Free pool safely.\r
+\r
+Arguments:\r
+ \r
+ Buffer - The allocated pool entry to free\r
+\r
+Returns:\r
+\r
+ Pointer of the buffer allocated.\r
+\r
+--*/\r
+{\r
+ if (Buffer != NULL) {\r
+ gBS->FreePool (Buffer);\r
+ Buffer = NULL;\r
+ }\r
+}\r
+\r
+EFI_DEVICE_PATH_PROTOCOL *\r
+BdsLibDelPartMatchInstance (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *Single\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+\r
+ Delete the instance in Multi which matches partly with Single instance\r
+\r
+Arguments:\r
+\r
+ Multi - A pointer to a multi-instance device path data structure.\r
+\r
+ Single - A pointer to a single-instance device path data structure.\r
+\r
+Returns:\r
+\r
+ This function will remove the device path instances in Multi which partly \r
+ match with the Single, and return the result device path. If there is no\r
+ remaining device path as a result, this function will return NULL.\r
+\r
+--*/\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *Instance;\r
+ EFI_DEVICE_PATH_PROTOCOL *NewDevicePath;\r
+ EFI_DEVICE_PATH_PROTOCOL *TempNewDevicePath;\r
+ UINTN InstanceSize;\r
+ UINTN SingleDpSize; \r
+ UINTN Size; \r
+ \r
+ NewDevicePath = NULL;\r
+ TempNewDevicePath = NULL;\r
+\r
+ if (Multi == NULL || Single == NULL) {\r
+ return Multi;\r
+ }\r
+ \r
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+ SingleDpSize = GetDevicePathSize (Single) - END_DEVICE_PATH_LENGTH;\r
+ InstanceSize -= END_DEVICE_PATH_LENGTH;\r
+\r
+ while (Instance != NULL) {\r
+\r
+ Size = (SingleDpSize < InstanceSize) ? SingleDpSize : InstanceSize; \r
+ \r
+ if ((CompareMem (Instance, Single, Size) != 0)) {\r
+ //\r
+ // Append the device path instance which does not match with Single\r
+ //\r
+ TempNewDevicePath = NewDevicePath;\r
+ NewDevicePath = AppendDevicePathInstance (NewDevicePath, Instance);\r
+ BdsLibSafeFreePool(TempNewDevicePath);\r
+ }\r
+ BdsLibSafeFreePool(Instance);\r
+ Instance = GetNextDevicePathInstance (&Multi, &InstanceSize);\r
+ InstanceSize -= END_DEVICE_PATH_LENGTH;\r
+ }\r
+ \r
+ return NewDevicePath;\r
+}\r
+\r
BOOLEAN\r
BdsLibMatchDevicePaths (\r
IN EFI_DEVICE_PATH_PROTOCOL *Multi,\r