summaryrefslogtreecommitdiffstatshomepage
path: root/3rdparty/lzma/CPP/Windows/FileName.cpp
diff options
context:
space:
mode:
Diffstat (limited to '3rdparty/lzma/CPP/Windows/FileName.cpp')
-rw-r--r--3rdparty/lzma/CPP/Windows/FileName.cpp251
1 files changed, 152 insertions, 99 deletions
diff --git a/3rdparty/lzma/CPP/Windows/FileName.cpp b/3rdparty/lzma/CPP/Windows/FileName.cpp
index 908ed53f4d0..c9c4f8b6ce9 100644
--- a/3rdparty/lzma/CPP/Windows/FileName.cpp
+++ b/3rdparty/lzma/CPP/Windows/FileName.cpp
@@ -2,6 +2,13 @@
#include "StdAfx.h"
+#ifndef _WIN32
+#include <limits.h>
+#include <unistd.h>
+#include "../Common/StringConvert.h"
+#endif
+
+#include "FileDir.h"
#include "FileName.h"
#ifndef _UNICODE
@@ -58,7 +65,32 @@ void NormalizeDirPathPrefix(UString &dirPath)
dirPath.Add_PathSepar();
}
-#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
+#ifdef _WIN32
+
+#ifndef USE_UNICODE_FSTRING
+#ifdef Z7_LONG_PATH
+static void NormalizeDirSeparators(UString &s)
+{
+ const unsigned len = s.Len();
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] == '/')
+ s.ReplaceOneCharAtPos(i, WCHAR_PATH_SEPARATOR);
+}
+#endif
+#endif
+
+void NormalizeDirSeparators(FString &s)
+{
+ const unsigned len = s.Len();
+ for (unsigned i = 0; i < len; i++)
+ if (s[i] == '/')
+ s.ReplaceOneCharAtPos(i, FCHAR_PATH_SEPARATOR);
+}
+
+#endif
+
+
+#define IS_LETTER_CHAR(c) ((((unsigned)(int)(c) | 0x20) - (unsigned)'a' <= (unsigned)('z' - 'a')))
bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
@@ -87,8 +119,10 @@ bool IsAltPathPrefix(CFSTR s) throw()
#if defined(_WIN32) && !defined(UNDER_CE)
-const wchar_t *kSuperPathPrefix = L"\\\\?\\";
-static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
+const char * const kSuperPathPrefix = "\\\\?\\";
+#ifdef Z7_LONG_PATH
+static const char * const kSuperUncPrefix = "\\\\?\\UNC\\";
+#endif
#define IS_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '.' && IS_SEPAR((s)[3]))
#define IS_SUPER_PREFIX(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '?' && IS_SEPAR((s)[3]))
@@ -109,7 +143,7 @@ bool IsDevicePath(CFSTR s) throw()
/*
// actually we don't know the way to open device file in WinCE.
unsigned len = MyStringLen(s);
- if (len < 5 || len > 5 || memcmp(s, FTEXT("DSK"), 3 * sizeof(FChar)) != 0)
+ if (len < 5 || len > 5 || !IsString1PrefixedByString2(s, "DSK"))
return false;
if (s[4] != ':')
return false;
@@ -123,7 +157,7 @@ bool IsDevicePath(CFSTR s) throw()
unsigned len = MyStringLen(s);
if (len == 6 && s[5] == ':')
return true;
- if (len < 18 || len > 22 || memcmp(s + kDevicePathPrefixSize, FTEXT("PhysicalDrive"), 13 * sizeof(FChar)) != 0)
+ if (len < 18 || len > 22 || !IsString1PrefixedByString2(s + kDevicePathPrefixSize, "PhysicalDrive"))
return false;
for (unsigned i = 17; i < len; i++)
if (s[i] < '0' || s[i] > '9')
@@ -157,19 +191,19 @@ unsigned GetNetworkServerPrefixSize(CFSTR s) throw()
if (c == '.' || c == '?')
return 0;
}
- int pos = FindSepar(s + prefixSize);
+ const int pos = FindSepar(s + prefixSize);
if (pos < 0)
return 0;
- return prefixSize + pos + 1;
+ return prefixSize + (unsigned)(pos + 1);
}
bool IsNetworkShareRootPath(CFSTR s) throw()
{
- unsigned prefixSize = GetNetworkServerPrefixSize(s);
+ const unsigned prefixSize = GetNetworkServerPrefixSize(s);
if (prefixSize == 0)
return false;
s += prefixSize;
- int pos = FindSepar(s);
+ const int pos = FindSepar(s);
if (pos < 0)
return true;
return s[(unsigned)pos + 1] == 0;
@@ -183,6 +217,37 @@ bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); }
bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
// bool IsSuperUncPath(const wchar_t *s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
+bool IsAltStreamPrefixWithColon(const UString &s) throw()
+{
+ if (s.IsEmpty())
+ return false;
+ if (s.Back() != ':')
+ return false;
+ unsigned pos = 0;
+ if (IsSuperPath(s))
+ pos = kSuperPathPrefixSize;
+ if (s.Len() - pos == 2 && IsDrivePath2(s.Ptr(pos)))
+ return false;
+ return true;
+}
+
+bool If_IsSuperPath_RemoveSuperPrefix(UString &s)
+{
+ if (!IsSuperPath(s))
+ return false;
+ unsigned start = 0;
+ unsigned count = kSuperPathPrefixSize;
+ const wchar_t *s2 = s.Ptr(kSuperPathPrefixSize);
+ if (IS_UNC_WITH_SLASH(s2))
+ {
+ start = 2;
+ count = kSuperUncPathPrefixSize - 2;
+ }
+ s.Delete(start, count);
+ return true;
+}
+
+
#ifndef USE_UNICODE_FSTRING
bool IsDrivePath2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
// bool IsDriveName2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
@@ -191,14 +256,12 @@ bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); }
bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
#endif // USE_UNICODE_FSTRING
-/*
-bool IsDrivePath_SuperAllowed(CFSTR s)
+bool IsDrivePath_SuperAllowed(CFSTR s) throw()
{
if (IsSuperPath(s))
s += kSuperPathPrefixSize;
return IsDrivePath(s);
}
-*/
bool IsDriveRootPath_SuperAllowed(CFSTR s) throw()
{
@@ -212,7 +275,7 @@ bool IsAbsolutePath(const wchar_t *s) throw()
return IS_SEPAR(s[0]) || IsDrivePath2(s);
}
-int FindAltStreamColon(CFSTR path)
+int FindAltStreamColon(CFSTR path) throw()
{
unsigned i = 0;
if (IsDrivePath2(path))
@@ -226,7 +289,7 @@ int FindAltStreamColon(CFSTR path)
if (c == ':')
{
if (colonPos < 0)
- colonPos = i;
+ colonPos = (int)i;
continue;
}
if (IS_SEPAR(c))
@@ -256,7 +319,7 @@ static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s)
return 0;
if (s[1] == 0 || !IS_SEPAR(s[1]))
return 1;
- unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
+ const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
return (size == 0) ? 0 : 2 + size;
}
@@ -264,17 +327,17 @@ static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
{
if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
{
- unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
+ const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
}
// we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
- int pos = FindSepar(s + kSuperPathPrefixSize);
+ const int pos = FindSepar(s + kSuperPathPrefixSize);
if (pos < 0)
return 0;
return kSuperPathPrefixSize + pos + 1;
}
-unsigned GetRootPrefixSize(CFSTR s)
+unsigned GetRootPrefixSize(CFSTR s) throw()
{
if (IS_DEVICE_PATH(s))
return kDevicePathPrefixSize;
@@ -285,7 +348,7 @@ unsigned GetRootPrefixSize(CFSTR s)
#endif // USE_UNICODE_FSTRING
-static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s)
+static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw()
{
// Network path: we look "server\path\" as root prefix
int pos = FindSepar(s);
@@ -294,10 +357,10 @@ static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s)
int pos2 = FindSepar(s + (unsigned)pos + 1);
if (pos2 < 0)
return 0;
- return pos + pos2 + 2;
+ return (unsigned)(pos + pos2 + 2);
}
-static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
+static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw()
{
if (IsDrivePath(s))
return kDrivePrefixSize;
@@ -309,7 +372,7 @@ static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
return (size == 0) ? 0 : 2 + size;
}
-static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s)
+static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
{
if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
{
@@ -320,7 +383,7 @@ static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s)
int pos = FindSepar(s + kSuperPathPrefixSize);
if (pos < 0)
return 0;
- return kSuperPathPrefixSize + pos + 1;
+ return kSuperPathPrefixSize + (unsigned)(pos + 1);
}
unsigned GetRootPrefixSize(const wchar_t *s) throw()
@@ -334,41 +397,39 @@ unsigned GetRootPrefixSize(const wchar_t *s) throw()
#else // _WIN32
-bool IsAbsolutePath(const wchar_t *s) { return IS_SEPAR(s[0]); }
+bool IsAbsolutePath(const wchar_t *s) throw() { return IS_SEPAR(s[0]); }
#ifndef USE_UNICODE_FSTRING
-unsigned GetRootPrefixSize(CFSTR s) { return IS_SEPAR(s[0]) ? 1 : 0; }
+unsigned GetRootPrefixSize(CFSTR s) throw();
+unsigned GetRootPrefixSize(CFSTR s) throw() { return IS_SEPAR(s[0]) ? 1 : 0; }
#endif
-unsigned GetRootPrefixSize(const wchar_t *s) { return IS_SEPAR(s[0]) ? 1 : 0; }
+unsigned GetRootPrefixSize(const wchar_t *s) throw() { return IS_SEPAR(s[0]) ? 1 : 0; }
#endif // _WIN32
#ifndef UNDER_CE
+
+#ifdef USE_UNICODE_FSTRING
+
+#define GetCurDir NDir::GetCurrentDir
+
+#else
+
static bool GetCurDir(UString &path)
{
path.Empty();
- DWORD needLength;
- #ifndef _UNICODE
- if (!g_IsNT)
- {
- TCHAR s[MAX_PATH + 2];
- s[0] = 0;
- needLength = ::GetCurrentDirectory(MAX_PATH + 1, s);
- path = fs2us(fas2fs(s));
- }
- else
- #endif
- {
- WCHAR s[MAX_PATH + 2];
- s[0] = 0;
- needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s);
- path = s;
- }
- return (needLength > 0 && needLength <= MAX_PATH);
+ FString s;
+ if (!NDir::GetCurrentDir(s))
+ return false;
+ path = fs2us(s);
+ return true;
}
+#endif
+
+
static bool ResolveDotsFolders(UString &s)
{
#ifdef _WIN32
@@ -390,7 +451,7 @@ static bool ResolveDotsFolders(UString &s)
{
if (i == 0)
return false;
- int k = i - 2;
+ int k = (int)i - 2;
i += 2;
for (;; k--)
@@ -409,8 +470,8 @@ static bool ResolveDotsFolders(UString &s)
if (k >= 0)
{
- num = i - k;
- i = k;
+ num = i - (unsigned)k;
+ i = (unsigned)k;
}
else
{
@@ -470,7 +531,7 @@ static bool AreThereDotsFolders(CFSTR s)
#endif
#endif // LONG_PATH_DOTS_FOLDERS_PARSING
-#ifdef WIN_LONG_PATH
+#ifdef Z7_LONG_PATH
/*
Most of Windows versions have problems, if some file or dir name
@@ -530,6 +591,7 @@ int GetUseSuperPathType(CFSTR s) throw()
}
+
/*
returns false in two cases:
- if GetCurDir was used, and GetCurDir returned error.
@@ -540,7 +602,6 @@ int GetUseSuperPathType(CFSTR s) throw()
for absolute paths, returns true, res is Super path.
*/
-
static bool GetSuperPathBase(CFSTR s, UString &res)
{
res.Empty();
@@ -564,11 +625,11 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
return true;
UString temp = fs2us(s);
- unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
+ const unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
if (fixedSize == 0)
return true;
- UString rem = &temp[fixedSize];
+ UString rem = temp.Ptr(fixedSize);
if (!ResolveDotsFolders(rem))
return true;
@@ -586,13 +647,13 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
if (IS_SEPAR(s[1]))
{
UString temp = fs2us(s + 2);
- unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
+ const unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
// we ignore that error to allow short network paths server\share?
/*
if (fixedSize == 0)
return false;
*/
- UString rem = &temp[fixedSize];
+ UString rem = temp.Ptr(fixedSize);
if (!ResolveDotsFolders(rem))
return false;
res += kSuperUncPrefix;
@@ -628,7 +689,7 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
unsigned fixedSizeStart = 0;
unsigned fixedSize = 0;
- const wchar_t *superMarker = NULL;
+ const char *superMarker = NULL;
if (IsSuperPath(curDir))
{
fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
@@ -683,7 +744,7 @@ static bool GetSuperPathBase(CFSTR s, UString &res)
true false * use Super path
true true true don't use any path, we already used mainPath
true true false use main path as Super Path, we don't try mainMath
- That case is possible now if GetCurDir returns unknow
+ That case is possible now if GetCurDir returns unknown
type of path (not drive and not network)
We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
@@ -704,6 +765,8 @@ bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew)
return false;
superPath = fs2us(path);
}
+
+ NormalizeDirSeparators(superPath);
return true;
}
return false;
@@ -714,6 +777,10 @@ bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
if (!GetSuperPathBase(s1, d1) ||
!GetSuperPathBase(s2, d2))
return false;
+
+ NormalizeDirSeparators(d1);
+ NormalizeDirSeparators(d2);
+
if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew)
return false;
if (d1.IsEmpty()) d1 = fs2us(s1);
@@ -731,7 +798,7 @@ bool GetSuperPath(CFSTR path, UString &superPath)
return false;
}
*/
-#endif // WIN_LONG_PATH
+#endif // Z7_LONG_PATH
bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
{
@@ -749,8 +816,11 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
#else
- unsigned prefixSize = GetRootPrefixSize(s);
+ const unsigned prefixSize = GetRootPrefixSize(s);
if (prefixSize != 0)
+#ifdef _WIN32
+ if (prefixSize != 1)
+#endif
{
if (!AreThereDotsFolders(s + prefixSize))
return true;
@@ -763,21 +833,9 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
return true;
}
- /*
- FChar c = s[0];
- if (c == 0)
- return true;
- if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
- return true;
- if (IS_SEPAR(c) && IS_SEPAR(s[1]))
- return true;
- if (IsDrivePath(s))
- return true;
- */
-
UString curDir;
- if (dirPrefix)
- curDir = fs2us(dirPrefix);
+ if (dirPrefix && prefixSize == 0)
+ curDir = fs2us(dirPrefix); // we use (dirPrefix), only if (s) path is relative
else
{
if (!GetCurDir(curDir))
@@ -785,46 +843,40 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
}
NormalizeDirPathPrefix(curDir);
- unsigned fixedSize = 0;
-
- #ifdef _WIN32
+ unsigned fixedSize = GetRootPrefixSize(curDir);
- if (IsSuperPath(curDir))
+ UString temp;
+#ifdef _WIN32
+ if (prefixSize != 0)
{
- fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
+ /* (s) is absolute path, but only (prefixSize == 1) is possible here.
+ So for full resolving we need root of current folder and
+ relative part of (s). */
+ s += prefixSize;
+ // (s) is relative part now
if (fixedSize == 0)
- return false;
- }
- else
- {
- if (IsDrivePath(curDir))
- fixedSize = kDrivePrefixSize;
- else
{
- if (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
- return false;
- fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
- if (fixedSize == 0)
- return false;
- fixedSize += 2;
+ // (curDir) is not absolute.
+ // That case is unexpected, but we support it too.
+ curDir.Empty();
+ curDir.Add_PathSepar();
+ fixedSize = 1;
+ // (curDir) now is just Separ character.
+ // So final (res) path later also will have Separ prefix.
}
}
-
- #endif // _WIN32
-
- UString temp;
- if (IS_SEPAR(s[0]))
- {
- temp = fs2us(s + 1);
- }
else
+#endif // _WIN32
{
- temp += curDir.Ptr(fixedSize);
- temp += fs2us(s);
+ // (s) is relative path
+ temp = curDir.Ptr(fixedSize);
+ // (temp) is relative_part_of(curDir)
}
+ temp += fs2us(s);
if (!ResolveDotsFolders(temp))
return false;
curDir.DeleteFrom(fixedSize);
+ // (curDir) now contains only absolute prefix part
res = us2fs(curDir);
res += us2fs(temp);
@@ -833,6 +885,7 @@ bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
return true;
}
+
bool GetFullPath(CFSTR path, FString &fullPath)
{
return GetFullPath(NULL, path, fullPath);