From 7a2b42e850cd0f5cd6fd3fb5de08abe9bd187a04 Mon Sep 17 00:00:00 2001 From: Ruiyu Ni Date: Wed, 19 Apr 2017 10:42:01 +0800 Subject: MdeModulePkg/TerminalDxe: Avoid always append device path to *Dev When TerminalDxe Start() is called multiple times, the old logic unconditionally appended the terminal device path candidates to *Dev (ConInDev/ConOutDev/ErrOutDev), resulting the volatile storage is full. Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Ruiyu Ni Reviewed-by: Star Zeng (cherry picked from commit b9c04b88a148d6a4d618e176c9a35d9b15ce9954) --- .../Universal/Console/TerminalDxe/Terminal.c | 67 +++++++++++++++++++--- 1 file changed, 59 insertions(+), 8 deletions(-) (limited to 'Core') diff --git a/Core/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c b/Core/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c index 5d55969c96..60de2d4d6d 100644 --- a/Core/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c +++ b/Core/MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c @@ -993,6 +993,49 @@ TerminalDriverBindingStop ( return EFI_SUCCESS; } +/** + Compare a device path data structure to that of all the nodes of a + second device path instance. + + @param Multi A pointer to a multi-instance device path data structure. + @param Single A pointer to a single-instance device path data structure. + + @retval TRUE If the Single is contained within Multi. + @retval FALSE The Single is not match within Multi. + +**/ +BOOLEAN +MatchDevicePaths ( + IN EFI_DEVICE_PATH_PROTOCOL *Multi, + IN EFI_DEVICE_PATH_PROTOCOL *Single + ) +{ + EFI_DEVICE_PATH_PROTOCOL *DevicePath; + EFI_DEVICE_PATH_PROTOCOL *DevicePathInst; + UINTN Size; + + DevicePath = Multi; + DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); + // + // Search for the match of 'Single' in 'Multi' + // + while (DevicePathInst != NULL) { + // + // If the single device path is found in multiple device paths, + // return success + // + if (CompareMem (Single, DevicePathInst, Size) == 0) { + FreePool (DevicePathInst); + return TRUE; + } + + FreePool (DevicePathInst); + DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size); + } + + return FALSE; +} + /** Update terminal device path in Console Device Environment Variables. @@ -1018,8 +1061,12 @@ TerminalUpdateConsoleDevVariable ( // // Get global variable and its size according to the name given. // - GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL); - if (Variable == NULL) { + Status = GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL); + if (Status == EFI_NOT_FOUND) { + Status = EFI_SUCCESS; + Variable = NULL; + } + if (EFI_ERROR (Status)) { return; } @@ -1028,17 +1075,21 @@ TerminalUpdateConsoleDevVariable ( // for (TerminalType = 0; TerminalType < ARRAY_SIZE (mTerminalType); TerminalType++) { SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath); - NewVariable = AppendDevicePathInstance (Variable, TempDevicePath); - ASSERT (NewVariable != NULL); - if (Variable != NULL) { - FreePool (Variable); - } if (TempDevicePath != NULL) { + if (!MatchDevicePaths (Variable, TempDevicePath)) { + NewVariable = AppendDevicePathInstance (Variable, TempDevicePath); + if (NewVariable != NULL) { + if (Variable != NULL) { + FreePool (Variable); + } + Variable = NewVariable; + } + } + FreePool (TempDevicePath); } - Variable = NewVariable; } VariableSize = GetDevicePathSize (Variable); -- cgit v1.2.3