From 1be2ed90a20618d71ddf34b8a07d038da0b36854 Mon Sep 17 00:00:00 2001 From: Hess Chen Date: Fri, 15 Aug 2014 03:06:48 +0000 Subject: =?UTF-8?q?There=20is=20a=20limitation=20on=20WINDOWS=20OS=20for?= =?UTF-8?q?=20the=20length=20of=20entire=20file=20path=20can=E2=80=99t=20b?= =?UTF-8?q?e=20larger=20than=20255.=20There=20is=20an=20OS=20API=20provide?= =?UTF-8?q?d=20by=20Microsoft=20to=20add=20=E2=80=9C\\=3F\=E2=80=9D=20befo?= =?UTF-8?q?re=20the=20path=20header=20to=20support=20the=20long=20file=20p?= =?UTF-8?q?ath.=20Enable=20this=20feature=20on=20basetools.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Contributed-under: TianoCore Contribution Agreement 1.0 Signed-off-by: Hess Chen Reviewed-by: Yingke Liu git-svn-id: https://svn.code.sf.net/p/edk2/code/trunk/edk2@15809 6f19259b-4bc3-4df7-8a09-765794883524 --- BaseTools/Source/C/Common/CommonLib.c | 132 +++++++++++++++++++++++++- BaseTools/Source/C/Common/CommonLib.h | 29 +++++- BaseTools/Source/C/Common/MemoryFile.h | 6 +- BaseTools/Source/C/Common/OsPath.c | 5 +- BaseTools/Source/C/Common/ParseInf.c | 21 ++-- BaseTools/Source/C/Common/ParseInf.h | 12 +-- BaseTools/Source/C/Common/SimpleFileParsing.c | 5 +- 7 files changed, 179 insertions(+), 31 deletions(-) (limited to 'BaseTools/Source/C/Common') diff --git a/BaseTools/Source/C/Common/CommonLib.c b/BaseTools/Source/C/Common/CommonLib.c index cb72e2723f..981c04f34b 100644 --- a/BaseTools/Source/C/Common/CommonLib.c +++ b/BaseTools/Source/C/Common/CommonLib.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -23,6 +23,11 @@ Abstract: #include #include #include +#ifdef __GNUC__ +#include +#else +#include +#endif #include "CommonLib.h" #include "EfiUtilityMsgs.h" @@ -196,7 +201,7 @@ Returns: // // Open the file // - InputFile = fopen (InputFileName, "rb"); + InputFile = fopen (LongFilePath (InputFileName), "rb"); if (InputFile == NULL) { Error (NULL, 0, 0001, "Error opening the input file", InputFileName); return EFI_ABORTED; @@ -297,7 +302,7 @@ Returns: // // Open the file // - OutputFile = fopen (OutputFileName, "wb"); + OutputFile = fopen (LongFilePath (OutputFileName), "wb"); if (OutputFile == NULL) { Error (NULL, 0, 0001, "Error opening the output file", OutputFileName); return EFI_ABORTED; @@ -582,3 +587,124 @@ char *strlwr(char *s) } #endif #endif + +#define WINDOWS_EXTENSION_PATH "\\\\?\\" +#define WINDOWS_UNC_EXTENSION_PATH "\\\\?\\UNC" + +// +// Global data to store full file path. It is not required to be free. +// +CHAR8 mCommonLibFullPath[MAX_LONG_FILE_PATH]; + +CHAR8 * +LongFilePath ( + IN CHAR8 *FileName + ) +/*++ + +Routine Description: + Convert FileName to the long file path, which can support larger than 260 length. + +Arguments: + FileName - FileName. + +Returns: + LongFilePath A pointer to the converted long file path. + +--*/ +{ +#ifdef __GNUC__ + // + // __GNUC__ may not be good way to differentiate unix and windows. Need more investigation here. + // unix has no limitation on file path. Just return FileName. + // + return FileName; +#else + CHAR8 *RootPath; + CHAR8 *PathPointer; + CHAR8 *NextPointer; + + PathPointer = (CHAR8 *) FileName; + + if (FileName != NULL) { + // + // Add the extension string first to support long file path. + // + mCommonLibFullPath[0] = 0; + strcpy (mCommonLibFullPath, WINDOWS_EXTENSION_PATH); + + if (strlen (FileName) > 1 && FileName[0] == '\\' && FileName[1] == '\\') { + // + // network path like \\server\share to \\?\UNC\server\share + // + strcpy (mCommonLibFullPath, WINDOWS_UNC_EXTENSION_PATH); + FileName ++; + } else if (strlen (FileName) < 3 || FileName[1] != ':' || (FileName[2] != '\\' && FileName[2] != '/')) { + // + // Relative file path. Convert it to absolute path. + // + RootPath = getcwd (NULL, 0); + if (RootPath != NULL) { + strcat (mCommonLibFullPath, RootPath); + if (FileName[0] != '\\' && FileName[0] != '/') { + // + // Attach directory separator + // + strcat (mCommonLibFullPath, "\\"); + } + free (RootPath); + } + } + + // + // Construct the full file path + // + strcat (mCommonLibFullPath, FileName); + + // + // Convert directory separator '/' to '\\' + // + PathPointer = (CHAR8 *) mCommonLibFullPath; + do { + if (*PathPointer == '/') { + *PathPointer = '\\'; + } + } while (*PathPointer ++ != '\0'); + + // + // Convert "\\.\\" to "\\", because it doesn't work with WINDOWS_EXTENSION_PATH. + // + while ((PathPointer = strstr (mCommonLibFullPath, "\\.\\")) != NULL) { + *PathPointer = '\0'; + strcat (mCommonLibFullPath, PathPointer + 2); + } + + // + // Convert "\\..\\" to last directory, because it doesn't work with WINDOWS_EXTENSION_PATH. + // + while ((PathPointer = strstr (mCommonLibFullPath, "\\..\\")) != NULL) { + NextPointer = PathPointer + 3; + do { + PathPointer --; + } while (PathPointer > mCommonLibFullPath && *PathPointer != ':' && *PathPointer != '\\'); + + if (*PathPointer == '\\') { + // + // Skip one directory + // + *PathPointer = '\0'; + strcat (mCommonLibFullPath, NextPointer); + } else { + // + // No directory is found. Just break. + // + break; + } + } + + PathPointer = mCommonLibFullPath; + } + + return PathPointer; +#endif +} diff --git a/BaseTools/Source/C/Common/CommonLib.h b/BaseTools/Source/C/Common/CommonLib.h index 0610b21ed0..2c1db759b0 100644 --- a/BaseTools/Source/C/Common/CommonLib.h +++ b/BaseTools/Source/C/Common/CommonLib.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -25,6 +25,12 @@ Abstract: #include #include #define PRINTED_GUID_BUFFER_SIZE 37 // including null-termination + +#define MAX_LONG_FILE_PATH 500 + +#ifdef __cplusplus +extern "C" { +#endif // // Function declarations // @@ -145,6 +151,27 @@ PrintGuidToBuffer ( ) ; +CHAR8 * +LongFilePath ( + IN CHAR8 *FileName +); +/*++ + +Routine Description: + Convert FileName to the long file path, which can support larger than 260 length. + +Arguments: + FileName - FileName. + +Returns: + LongFilePath A pointer to the converted long file path. + +--*/ + +#ifdef __cplusplus +} +#endif + #define ASSERT(x) assert(x) #ifdef __GNUC__ diff --git a/BaseTools/Source/C/Common/MemoryFile.h b/BaseTools/Source/C/Common/MemoryFile.h index baab40baa2..0568fed5f2 100644 --- a/BaseTools/Source/C/Common/MemoryFile.h +++ b/BaseTools/Source/C/Common/MemoryFile.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -26,10 +26,6 @@ Abstract: #include #include -#ifndef _MAX_PATH -#define _MAX_PATH 500 -#endif - // // Common data structures // diff --git a/BaseTools/Source/C/Common/OsPath.c b/BaseTools/Source/C/Common/OsPath.c index 419c8f8b8c..07b47f09b4 100644 --- a/BaseTools/Source/C/Common/OsPath.c +++ b/BaseTools/Source/C/Common/OsPath.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2007 - 2008, Intel Corporation. All rights reserved.
+Copyright (c) 2007 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -22,6 +22,7 @@ Abstract: #include #include #include +#include "CommonLib.h" #include "OsPath.h" // @@ -294,7 +295,7 @@ Returns: --*/ { FILE *InputFile; - InputFile = fopen (InputFileName, "rb"); + InputFile = fopen (LongFilePath (InputFileName), "rb"); if (InputFile == NULL) { return FALSE; } else { diff --git a/BaseTools/Source/C/Common/ParseInf.c b/BaseTools/Source/C/Common/ParseInf.c index 385758f836..00ae0e65a1 100644 --- a/BaseTools/Source/C/Common/ParseInf.c +++ b/BaseTools/Source/C/Common/ParseInf.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2004 - 2010, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -25,6 +25,7 @@ Abstract: #include #include "EfiUtilityMsgs.h" #include "ParseInf.h" +#include "CommonLib.h" CHAR8 * ReadLine ( @@ -46,7 +47,7 @@ Routine Description: Arguments: InputFile Memory file image. - InputBuffer Buffer to read into, must be _MAX_PATH size. + InputBuffer Buffer to read into, must be MaxLength size. MaxLength The maximum size of the input buffer. Returns: @@ -165,7 +166,7 @@ Returns: --*/ { - CHAR8 InputBuffer[_MAX_PATH]; + CHAR8 InputBuffer[MAX_LONG_FILE_PATH]; CHAR8 *CurrentToken; // @@ -188,7 +189,7 @@ Returns: // // Read a line // - ReadLine (InputFile, InputBuffer, _MAX_PATH); + ReadLine (InputFile, InputBuffer, MAX_LONG_FILE_PATH); // // Check if the section is found @@ -222,7 +223,7 @@ Arguments: Section The section to search for, a string within []. Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file. Instance The instance of the token to search for. Zero is the first instance. - Value The string that holds the value following the =. Must be _MAX_PATH in size. + Value The string that holds the value following the =. Must be MAX_LONG_FILE_PATH in size. Returns: @@ -234,7 +235,7 @@ Returns: --*/ { - CHAR8 InputBuffer[_MAX_PATH]; + CHAR8 InputBuffer[MAX_LONG_FILE_PATH]; CHAR8 *CurrentToken; CHAR8 *Delimiter; BOOLEAN ParseError; @@ -274,7 +275,7 @@ Returns: // // Read a line from the file // - if (ReadLine (InputFile, InputBuffer, _MAX_PATH) == NULL) { + if (ReadLine (InputFile, InputBuffer, MAX_LONG_FILE_PATH) == NULL) { // // Error reading from input file // @@ -604,7 +605,7 @@ Routine Description: Arguments: InputFile Stream pointer. - InputBuffer Buffer to read into, must be _MAX_PATH size. + InputBuffer Buffer to read into, must be MAX_LONG_FILE_PATH size. Returns: @@ -624,7 +625,7 @@ Returns: // // Read a line // - if (fgets (InputBuffer, _MAX_PATH, InputFile) == NULL) { + if (fgets (InputBuffer, MAX_LONG_FILE_PATH, InputFile) == NULL) { return NULL; } // @@ -670,7 +671,7 @@ Returns: --*/ { - CHAR8 InputBuffer[_MAX_PATH]; + CHAR8 InputBuffer[MAX_LONG_FILE_PATH]; CHAR8 *CurrentToken; // diff --git a/BaseTools/Source/C/Common/ParseInf.h b/BaseTools/Source/C/Common/ParseInf.h index dfd180db74..6215ea2e78 100644 --- a/BaseTools/Source/C/Common/ParseInf.h +++ b/BaseTools/Source/C/Common/ParseInf.h @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -27,10 +27,6 @@ Abstract: #include #include -#ifndef _MAX_PATH -#define _MAX_PATH 500 -#endif - #ifdef __cplusplus extern "C" { #endif @@ -59,7 +55,7 @@ Routine Description: Arguments: InputFile Memory file image. - InputBuffer Buffer to read into, must be _MAX_PATH size. + InputBuffer Buffer to read into, must be MaxLength size. MaxLength The maximum size of the input buffer. Returns: @@ -115,7 +111,7 @@ Arguments: Section The section to search for, a string within []. Token The token to search for, e.g. EFI_PEIM_RECOVERY, followed by an = in the INF file. Instance The instance of the token to search for. Zero is the first instance. - Value The string that holds the value following the =. Must be _MAX_PATH in size. + Value The string that holds the value following the =. Must be MAX_LONG_FILE_PATH in size. Returns: @@ -196,7 +192,7 @@ Routine Description: Arguments: InputFile Stream pointer. - InputBuffer Buffer to read into, must be _MAX_PATH size. + InputBuffer Buffer to read into, must be MAX_LONG_FILE_PATH size. Returns: diff --git a/BaseTools/Source/C/Common/SimpleFileParsing.c b/BaseTools/Source/C/Common/SimpleFileParsing.c index 0f6151819c..3978e6ed3c 100644 --- a/BaseTools/Source/C/Common/SimpleFileParsing.c +++ b/BaseTools/Source/C/Common/SimpleFileParsing.c @@ -1,6 +1,6 @@ /** @file -Copyright (c) 2004 - 2008, Intel Corporation. All rights reserved.
+Copyright (c) 2004 - 2014, Intel Corporation. All rights reserved.
This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -24,6 +24,7 @@ Abstract: #include #include +#include "CommonLib.h" #include "EfiUtilityMsgs.h" #include "SimpleFileParsing.h" @@ -650,7 +651,7 @@ Returns: // Try to open the file locally, and if that fails try along our include paths. // strcpy (FoundFileName, SourceFile->FileName); - if ((SourceFile->Fptr = fopen (FoundFileName, "rb")) == NULL) { + if ((SourceFile->Fptr = fopen (LongFilePath (FoundFileName), "rb")) == NULL) { return STATUS_ERROR; } // -- cgit v1.2.3