]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/Common/CommonLib.c
There is a limitation on WINDOWS OS for the length of entire file path can’t be large...
[mirror_edk2.git] / BaseTools / Source / C / Common / CommonLib.c
index cb72e2723f3a65dc745930bda6f0776a1e0dabfc..981c04f34ba8f1c7ab3e868ba3aa05cc72d350cc 100644 (file)
@@ -1,6 +1,6 @@
 /** @file\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.<BR>\r
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.<BR>\r
 This program and the accompanying materials                          \r
 are licensed and made available under the terms and conditions of the BSD License         \r
 which accompanies this distribution.  The full text of the license may be found at        \r
@@ -23,6 +23,11 @@ Abstract:
 #include <string.h>\r
 #include <stdlib.h>\r
 #include <ctype.h>\r
+#ifdef __GNUC__\r
+#include <unistd.h>\r
+#else\r
+#include <direct.h>\r
+#endif\r
 #include "CommonLib.h"\r
 #include "EfiUtilityMsgs.h"\r
 \r
@@ -196,7 +201,7 @@ Returns:
   //\r
   // Open the file\r
   //\r
-  InputFile = fopen (InputFileName, "rb");\r
+  InputFile = fopen (LongFilePath (InputFileName), "rb");\r
   if (InputFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening the input file", InputFileName);\r
     return EFI_ABORTED;\r
@@ -297,7 +302,7 @@ Returns:
   //\r
   // Open the file\r
   //\r
-  OutputFile = fopen (OutputFileName, "wb");\r
+  OutputFile = fopen (LongFilePath (OutputFileName), "wb");\r
   if (OutputFile == NULL) {\r
     Error (NULL, 0, 0001, "Error opening the output file", OutputFileName);\r
     return EFI_ABORTED;\r
@@ -582,3 +587,124 @@ char *strlwr(char *s)
 }\r
 #endif\r
 #endif\r
+\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