+/**\r
+ Build the terminal device path for the child device according to the\r
+ terminal type.\r
+\r
+ @param ParentDevicePath Parent device path.\r
+ @param RemainingDevicePath A specific child device.\r
+\r
+ @return The child device path built.\r
+\r
+**/\r
+EFI_DEVICE_PATH_PROTOCOL*\r
+EFIAPI\r
+BuildTerminalDevpath (\r
+ IN EFI_DEVICE_PATH_PROTOCOL *ParentDevicePath,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *RemainingDevicePath\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath;\r
+ UINT8 TerminalType;\r
+ VENDOR_DEVICE_PATH *Node;\r
+ EFI_STATUS Status;\r
+\r
+ TerminalDevicePath = NULL;\r
+ TerminalType = PCANSITYPE;\r
+\r
+ //\r
+ // Use the RemainingDevicePath to determine the terminal type\r
+ //\r
+ Node = (VENDOR_DEVICE_PATH *) RemainingDevicePath;\r
+ if (Node == NULL) {\r
+ TerminalType = PCANSITYPE;\r
+\r
+ } else if (CompareGuid (&Node->Guid, &gEfiPcAnsiGuid)) {\r
+\r
+ TerminalType = PCANSITYPE;\r
+\r
+ } else if (CompareGuid (&Node->Guid, &gEfiVT100Guid)) {\r
+\r
+ TerminalType = VT100TYPE;\r
+\r
+ } else if (CompareGuid (&Node->Guid, &gEfiVT100PlusGuid)) {\r
+\r
+ TerminalType = VT100PLUSTYPE;\r
+\r
+ } else if (CompareGuid (&Node->Guid, &gEfiVTUTF8Guid)) {\r
+\r
+ TerminalType = VTUTF8TYPE;\r
+\r
+ } else {\r
+ return NULL;\r
+ }\r
+\r
+ //\r
+ // Build the device path for the child device\r
+ //\r
+ Status = SetTerminalDevicePath (\r
+ TerminalType,\r
+ ParentDevicePath,\r
+ &TerminalDevicePath\r
+ );\r
+ if (EFI_ERROR (Status)) {\r
+ return NULL;\r
+ }\r
+ return TerminalDevicePath;\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
+ Check whether the terminal device path is in the global variable.\r
+\r
+ @param VariableName Pointer to one global variable.\r
+ @param TerminalDevicePath Pointer to the terminal device's device path.\r
+\r
+ @retval TRUE The devcie is in the global variable.\r
+ @retval FALSE The devcie is not in the global variable.\r
+\r
+**/\r
+BOOLEAN\r
+IsTerminalInConsoleVariable (\r
+ IN CHAR16 *VariableName,\r
+ IN EFI_DEVICE_PATH_PROTOCOL *TerminalDevicePath\r
+ )\r
+{\r
+ EFI_DEVICE_PATH_PROTOCOL *Variable;\r
+ BOOLEAN ReturnFlag;\r
+\r
+ //\r
+ // Get global variable and its size according to the name given.\r
+ //\r
+ Variable = GetEfiGlobalVariable (VariableName);\r
+ if (Variable == NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Check whether the terminal device path is one of the variable instances.\r
+ //\r
+ ReturnFlag = MatchDevicePaths (Variable, TerminalDevicePath);\r
+\r
+ FreePool (Variable);\r
+\r
+ return ReturnFlag;\r
+}\r
+\r
+/**\r
+ Free notify functions list.\r
+\r
+ @param ListHead The list head\r
+\r
+ @retval EFI_SUCCESS Free the notify list successfully.\r
+ @retval EFI_INVALID_PARAMETER ListHead is NULL.\r
+\r
+**/\r
+EFI_STATUS\r
+TerminalFreeNotifyList (\r
+ IN OUT LIST_ENTRY *ListHead\r
+ )\r
+{\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY *NotifyNode;\r
+\r
+ if (ListHead == NULL) {\r
+ return EFI_INVALID_PARAMETER;\r
+ }\r
+ while (!IsListEmpty (ListHead)) {\r
+ NotifyNode = CR (\r
+ ListHead->ForwardLink,\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY,\r
+ NotifyEntry,\r
+ TERMINAL_CONSOLE_IN_EX_NOTIFY_SIGNATURE\r
+ );\r
+ RemoveEntryList (ListHead->ForwardLink);\r
+ FreePool (NotifyNode);\r
+ }\r
+\r
+ return EFI_SUCCESS;\r
+}\r
+\r
+\r