From d02ea958732846b91381c9050a5f43d503953974 Mon Sep 17 00:00:00 2001 From: xli24 Date: Fri, 12 Jan 2007 05:34:49 +0000 Subject: 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 --- EdkNt32Pkg/Library/EdkGenericBdsLib/BdsConsole.c | 157 +++++++++++++---------- EdkNt32Pkg/Library/EdkGenericBdsLib/BdsMisc.c | 89 +++++++++++++ 2 files changed, 176 insertions(+), 70 deletions(-) (limited to 'EdkNt32Pkg/Library') 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, -- cgit v1.2.3