MdeModulePkg/TerminalDxe: Avoid always append device path to *Dev
authorRuiyu Ni <ruiyu.ni@intel.com>
Wed, 19 Apr 2017 02:42:01 +0000 (10:42 +0800)
committerRuiyu Ni <ruiyu.ni@intel.com>
Thu, 20 Apr 2017 02:24:10 +0000 (10:24 +0800)
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 <ruiyu.ni@intel.com>
Reviewed-by: Star Zeng <star.zeng@intel.com>
MdeModulePkg/Universal/Console/TerminalDxe/Terminal.c

index 5d55969c96915d4dffb23898fd2de4fd6217eb0c..60de2d4d6db2b09f8937226465ca98e9c2660d21 100644 (file)
@@ -993,6 +993,49 @@ TerminalDriverBindingStop (
   return EFI_SUCCESS;\r
 }\r
 \r
+/**\r
+  Compare a device path data structure to that of all the nodes of a\r
+  second device path instance.\r
+\r
+  @param  Multi          A pointer to a multi-instance device path data structure.\r
+  @param  Single         A pointer to a single-instance device path data structure.\r
+\r
+  @retval TRUE           If the Single is contained within Multi.\r
+  @retval FALSE          The Single is not match within Multi.\r
+\r
+**/\r
+BOOLEAN\r
+MatchDevicePaths (\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Multi,\r
+  IN  EFI_DEVICE_PATH_PROTOCOL  *Single\r
+  )\r
+{\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePath;\r
+  EFI_DEVICE_PATH_PROTOCOL  *DevicePathInst;\r
+  UINTN                     Size;\r
+\r
+  DevicePath      = Multi;\r
+  DevicePathInst  = GetNextDevicePathInstance (&DevicePath, &Size);\r
+  //\r
+  // Search for the match of 'Single' in 'Multi'\r
+  //\r
+  while (DevicePathInst != NULL) {\r
+    //\r
+    // If the single device path is found in multiple device paths,\r
+    // return success\r
+    //\r
+    if (CompareMem (Single, DevicePathInst, Size) == 0) {\r
+      FreePool (DevicePathInst);\r
+      return TRUE;\r
+    }\r
+\r
+    FreePool (DevicePathInst);\r
+    DevicePathInst = GetNextDevicePathInstance (&DevicePath, &Size);\r
+  }\r
+\r
+  return FALSE;\r
+}\r
+\r
 /**\r
   Update terminal device path in Console Device Environment Variables.\r
 \r
@@ -1018,8 +1061,12 @@ TerminalUpdateConsoleDevVariable (
   //\r
   // Get global variable and its size according to the name given.\r
   //\r
-  GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);\r
-  if (Variable == NULL) {\r
+  Status = GetEfiGlobalVariable2 (VariableName, (VOID**)&Variable, NULL);\r
+  if (Status == EFI_NOT_FOUND) {\r
+    Status   = EFI_SUCCESS;\r
+    Variable = NULL;\r
+  }\r
+  if (EFI_ERROR (Status)) {\r
     return;\r
   }\r
 \r
@@ -1028,17 +1075,21 @@ TerminalUpdateConsoleDevVariable (
   //\r
   for (TerminalType = 0; TerminalType < ARRAY_SIZE (mTerminalType); TerminalType++) {\r
     SetTerminalDevicePath (TerminalType, ParentDevicePath, &TempDevicePath);\r
-    NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);\r
-    ASSERT (NewVariable != NULL);\r
-    if (Variable != NULL) {\r
-      FreePool (Variable);\r
-    }\r
 \r
     if (TempDevicePath != NULL) {\r
+      if (!MatchDevicePaths (Variable, TempDevicePath)) {\r
+        NewVariable = AppendDevicePathInstance (Variable, TempDevicePath);\r
+        if (NewVariable != NULL) {\r
+          if (Variable != NULL) {\r
+            FreePool (Variable);\r
+          }\r
+          Variable = NewVariable;\r
+        }\r
+      }\r
+\r
       FreePool (TempDevicePath);\r
     }\r
 \r
-    Variable = NewVariable;\r
   }\r
 \r
   VariableSize = GetDevicePathSize (Variable);\r