+/**\r
+ Count the number of Leading Dot in FileNameToken.\r
+\r
+ @param FileNameToken A string representing a token in the path name.\r
+\r
+ @return UINTN The number of leading dot in the name.\r
+\r
+**/\r
+UINTN\r
+CountLeadingDots (\r
+ IN CONST CHAR16 * FileNameToken\r
+ )\r
+{\r
+ UINTN Num;\r
+\r
+ Num = 0;\r
+ while (*FileNameToken == L'.') {\r
+ Num++;\r
+ FileNameToken++;\r
+ }\r
+ \r
+ return Num;\r
+}\r
+\r
+BOOLEAN \r
+IsFileNameTokenValid (\r
+ IN CONST CHAR16 * FileNameToken\r
+ )\r
+{\r
+ UINTN Num;\r
+ if (StrStr (FileNameToken, L"/") != NULL) {\r
+ //\r
+ // No L'/' in file name.\r
+ //\r
+ return FALSE;\r
+ } else {\r
+ //\r
+ // If Token has all dot, the number should not exceed 2\r
+ //\r
+ Num = CountLeadingDots (FileNameToken);\r
+\r
+ if (Num == StrLen (FileNameToken)) {\r
+ //\r
+ // If the FileNameToken only contains a number of L'.'.\r
+ //\r
+ if (Num > 2) {\r
+ return FALSE;\r
+ }\r
+ }\r
+ }\r
+\r
+ return TRUE;\r
+}\r
+\r
+/**\r
+ Return the first string token found in the indirect pointer a String named by FileName.\r
+\r
+ On input, FileName is a indirect pointer pointing to a String.\r
+ On output, FileName is a updated to point to the next character after the first\r
+ found L"\" or NULL if there is no L"\" found.\r
+\r
+ @param FileName A indirect pointer pointing to a FileName.\r
+\r
+ @return Token The first string token found before a L"\".\r
+\r
+**/\r
+CHAR16 *\r
+GetNextFileNameToken (\r
+ IN OUT CONST CHAR16 ** FileName \r
+ )\r
+{\r
+ CHAR16 *SlashPos;\r
+ CHAR16 *Token;\r
+ UINTN Offset;\r
+ ASSERT (**FileName != L'\\');\r
+ ASSERT (**FileName != L'\0');\r
+\r
+ SlashPos = StrStr (*FileName, L"\\");\r
+ if (SlashPos == NULL) {\r
+ Token = AllocateCopyPool (StrSize(*FileName), *FileName);\r
+ *FileName = NULL;\r
+ } else {\r
+ Offset = SlashPos - *FileName;\r
+ Token = AllocateZeroPool ((Offset + 1) * sizeof (CHAR16));\r
+ StrnCpy (Token, *FileName, Offset);\r
+ //\r
+ // Point *FileName to the next character after L'\'.\r
+ //\r
+ *FileName = *FileName + Offset + 1;\r
+ //\r
+ // If *FileName is an empty string, then set *FileName to NULL\r
+ //\r
+ if (**FileName == L'\0') {\r
+ *FileName = NULL;\r
+ }\r
+ }\r
+\r
+ return Token;\r
+}\r
+\r
+/**\r
+ Check if a FileName contains only Valid Characters.\r
+\r
+ If FileName contains only a single L'\', return TRUE.\r
+ If FileName contains two adjacent L'\', return FALSE.\r
+ If FileName conatins L'/' , return FALSE.\r
+ If FielName contains more than two dots seperated with other FileName characters\r
+ by L'\', return FALSE. For example, L'.\...\filename.txt' is invalid path name. But L'..TwoDots\filename.txt' is valid path name.\r
+\r
+ @param FileName The File Name String to check.\r
+\r
+ @return TRUE FileName only contains valid characters.\r
+ @return FALSE FileName contains at least one invalid character.\r
+\r
+**/\r
+\r
+BOOLEAN\r
+IsFileNameValid (\r
+ IN CONST CHAR16 *FileName \r
+ )\r
+{\r
+ CHAR16 *Token;\r
+ BOOLEAN Valid;\r
+\r
+ //\r
+ // If FileName is just L'\', then it is a valid pathname. \r
+ //\r
+ if (StrCmp (FileName, L"\\") == 0) {\r
+ return TRUE;\r
+ }\r
+ //\r
+ // We don't support two or more adjacent L'\'.\r
+ //\r
+ if (StrStr (FileName, L"\\\\") != NULL) {\r
+ return FALSE;\r
+ }\r
+\r
+ //\r
+ // Is FileName has a leading L"\", skip to next character.\r
+ //\r
+ if (FileName [0] == L'\\') {\r
+ FileName++;\r
+ }\r
+\r
+ do {\r
+ Token = GetNextFileNameToken (&FileName);\r
+ Valid = IsFileNameTokenValid (Token);\r
+ FreePool (Token);\r
+ \r
+ if (!Valid)\r
+ return FALSE;\r
+ } while (FileName != NULL);\r
+\r
+ return TRUE;\r
+}\r
+\r