+\r
+#define WINDOWS_EXTENSION_PATH "\\\\?\\"\r
+#define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC"\r
+\r
+//\r
+// Global data to store full file path. It is not required to be free. \r
+//\r
+CHAR8 mCommonLibFullPath[MAX_LONG_FILE_PATH];\r
+\r
+CHAR8 *\r
+LongFilePath (\r
+ IN CHAR8 *FileName\r
+ )\r
+/*++\r
+\r
+Routine Description:\r
+ Convert FileName to the long file path, which can support larger than 260 length. \r
+\r
+Arguments:\r
+ FileName - FileName. \r
+\r
+Returns:\r
+ LongFilePath A pointer to the converted long file path.\r
+ \r
+--*/\r
+{\r
+#ifdef __GNUC__\r
+ //\r
+ // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here. \r
+ // unix has no limitation on file path. Just return FileName. \r
+ //\r
+ return FileName;\r
+#else\r
+ CHAR8 *RootPath;\r
+ CHAR8 *PathPointer;\r
+ CHAR8 *NextPointer;\r
+ \r
+ PathPointer = (CHAR8 *) FileName;\r
+ \r
+ if (FileName != NULL) {\r
+ //\r
+ // Add the extension string first to support long file path. \r
+ //\r
+ mCommonLibFullPath[0] = 0;\r
+ strcpy (mCommonLibFullPath, WINDOWS_EXTENSION_PATH);\r
+\r
+ if (strlen (FileName) > 1 && FileName[0] == '\\' && FileName[1] == '\\') {\r
+ //\r
+ // network path like \\server\share to \\?\UNC\server\share\r
+ //\r
+ strcpy (mCommonLibFullPath, WINDOWS_UNC_EXTENSION_PATH);\r
+ FileName ++;\r
+ } else if (strlen (FileName) < 3 || FileName[1] != ':' || (FileName[2] != '\\' && FileName[2] != '/')) {\r
+ //\r
+ // Relative file path. Convert it to absolute path. \r
+ //\r
+ RootPath = getcwd (NULL, 0);\r
+ if (RootPath != NULL) {\r
+ strcat (mCommonLibFullPath, RootPath);\r
+ if (FileName[0] != '\\' && FileName[0] != '/') {\r
+ //\r
+ // Attach directory separator\r
+ //\r
+ strcat (mCommonLibFullPath, "\\");\r
+ }\r
+ free (RootPath);\r
+ }\r
+ }\r
+\r
+ //\r
+ // Construct the full file path\r
+ //\r
+ strcat (mCommonLibFullPath, FileName);\r
+ \r
+ //\r
+ // Convert directory separator '/' to '\\'\r
+ //\r
+ PathPointer = (CHAR8 *) mCommonLibFullPath;\r
+ do {\r
+ if (*PathPointer == '/') {\r
+ *PathPointer = '\\';\r
+ }\r
+ } while (*PathPointer ++ != '\0');\r
+ \r
+ //\r
+ // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH.\r
+ //\r
+ while ((PathPointer = strstr (mCommonLibFullPath, "\\.\\")) != NULL) {\r
+ *PathPointer = '\0';\r
+ strcat (mCommonLibFullPath, PathPointer + 2);\r
+ }\r
+ \r
+ //\r
+ // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH.\r
+ //\r
+ while ((PathPointer = strstr (mCommonLibFullPath, "\\..\\")) != NULL) {\r
+ NextPointer = PathPointer + 3;\r
+ do {\r
+ PathPointer --;\r
+ } while (PathPointer > mCommonLibFullPath && *PathPointer != ':' && *PathPointer != '\\');\r
+\r
+ if (*PathPointer == '\\') {\r
+ //\r
+ // Skip one directory\r
+ //\r
+ *PathPointer = '\0';\r
+ strcat (mCommonLibFullPath, NextPointer);\r
+ } else {\r
+ //\r
+ // No directory is found. Just break.\r
+ //\r
+ break;\r
+ }\r
+ }\r
+ \r
+ PathPointer = mCommonLibFullPath;\r
+ }\r
+ \r
+ return PathPointer;\r
+#endif\r
+}\r