]> git.proxmox.com Git - mirror_edk2.git/blobdiff - BaseTools/Source/C/Common/CommonLib.c
BaseTools: Convert ".\\" to "" in FilePath
[mirror_edk2.git] / BaseTools / Source / C / Common / CommonLib.c
index cb72e2723f3a65dc745930bda6f0776a1e0dabfc..2d07dfc667b19b3c9fc3c7cef7af1b713ff6b6c4 100644 (file)
@@ -1,6 +1,7 @@
 /** @file\r
+Common basic Library Functions\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
@@ -9,20 +10,17 @@ http://opensource.org/licenses/bsd-license.php
 THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS,                     \r
 WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED.             \r
 \r
-Module Name:\r
-\r
-  CommonLib.c\r
-\r
-Abstract:\r
-\r
-  Common basic Library Functions\r
\r
 **/\r
 \r
 #include <stdio.h>\r
 #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 +194,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 +295,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 +580,140 @@ 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
+    if ((PathPointer = strstr (mCommonLibFullPath, ":\\\\")) != NULL) {\r
+      *(PathPointer + 2) = '\0';\r
+      strcat (mCommonLibFullPath, PathPointer + 3);\r
+    }\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 "\\", 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