]> 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 970b2af27b367d3b77b14af6a6c3ba9a5cd4f891..981c04f34ba8f1c7ab3e868ba3aa05cc72d350cc 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
 \r
-Copyright (c) 2004 - 2008, Intel Corporation                                                         \r
-All rights reserved. This program and the accompanying materials                          \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
 http://opensource.org/licenses/bsd-license.php                                            \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
@@ -472,7 +477,7 @@ Returns:
 \r
   printf (\r
     "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x\n",\r
-    Guid->Data1,\r
+    (unsigned) Guid->Data1,\r
     Guid->Data2,\r
     Guid->Data3,\r
     Guid->Data4[0],\r
@@ -529,7 +534,7 @@ Returns:
     sprintf (\r
       (CHAR8 *)Buffer,\r
       "%08X-%04X-%04X-%02X%02X-%02X%02X%02X%02X%02X%02X",\r
-      Guid->Data1,\r
+      (unsigned) Guid->Data1,\r
       Guid->Data2,\r
       Guid->Data3,\r
       Guid->Data4[0],\r
@@ -545,7 +550,7 @@ Returns:
     sprintf (\r
       (CHAR8 *)Buffer,\r
       "%08x-%04x-%04x-%02x%02x-%02x%02x%02x%02x%02x%02x",\r
-      Guid->Data1,\r
+      (unsigned) Guid->Data1,\r
       Guid->Data2,\r
       Guid->Data3,\r
       Guid->Data4[0],\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