summaryrefslogtreecommitdiffstats
path: root/src/libs/7zip/win/CPP/Windows/FileName.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/libs/7zip/win/CPP/Windows/FileName.cpp')
-rw-r--r--src/libs/7zip/win/CPP/Windows/FileName.cpp687
1 files changed, 0 insertions, 687 deletions
diff --git a/src/libs/7zip/win/CPP/Windows/FileName.cpp b/src/libs/7zip/win/CPP/Windows/FileName.cpp
deleted file mode 100644
index 0a6aee100..000000000
--- a/src/libs/7zip/win/CPP/Windows/FileName.cpp
+++ /dev/null
@@ -1,687 +0,0 @@
-// Windows/FileName.cpp
-
-#include "StdAfx.h"
-
-#include "FileName.h"
-
-#ifndef _UNICODE
-extern bool g_IsNT;
-#endif
-
-namespace NWindows {
-namespace NFile {
-namespace NName {
-
-#ifndef USE_UNICODE_FSTRING
-void NormalizeDirPathPrefix(FString &dirPath)
-{
- if (dirPath.IsEmpty())
- return;
- if (dirPath.Back() != FCHAR_PATH_SEPARATOR)
- dirPath += FCHAR_PATH_SEPARATOR;
-}
-#endif
-
-void NormalizeDirPathPrefix(UString &dirPath)
-{
- if (dirPath.IsEmpty())
- return;
- if (dirPath.Back() != WCHAR_PATH_SEPARATOR)
- dirPath += WCHAR_PATH_SEPARATOR;
-}
-
-
-#ifdef _WIN32
-
-const wchar_t *kSuperPathPrefix = L"\\\\?\\";
-static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
-
-#define IS_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '.' && (s)[3] == '\\')
-#define IS_SUPER_PREFIX(s) ((s)[0] == '\\' && (s)[1] == '\\' && (s)[2] == '?' && (s)[3] == '\\')
-#define IS_SUPER_OR_DEVICE_PATH(s) ((s)[0] == '\\' && (s)[1] == '\\' && ((s)[2] == '?' || (s)[2] == '.') && (s)[3] == '\\')
-#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
-
-#define IS_UNC_WITH_SLASH(s) ( \
- ((s)[0] == 'U' || (s)[0] == 'u') && \
- ((s)[1] == 'N' || (s)[1] == 'n') && \
- ((s)[2] == 'C' || (s)[2] == 'c') && \
- (s)[3] == '\\')
-
-bool IsDevicePath(CFSTR s) throw()
-{
- #ifdef UNDER_CE
-
- s = s;
- return false;
- /*
- // 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)
- return false;
- if (s[4] != ':')
- return false;
- // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
- */
-
- #else
-
- if (!IS_DEVICE_PATH(s))
- return false;
- 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)
- return false;
- for (unsigned i = 17; i < len; i++)
- if (s[i] < '0' || s[i] > '9')
- return false;
- return true;
-
- #endif
-}
-
-bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
-
-bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
-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) { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
-
-#ifndef USE_UNICODE_FSTRING
-bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == '\\'; }
-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 IsAbsolutePath(const wchar_t *s) throw()
-{
- return s[0] == WCHAR_PATH_SEPARATOR || IsDrivePath(s);
-}
-
-static const unsigned kDrivePrefixSize = 3; /* c:\ */
-
-#ifndef USE_UNICODE_FSTRING
-
-static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s) throw()
-{
- // Network path: we look "server\path\" as root prefix
- int pos = FindCharPosInString(s, '\\');
- if (pos < 0)
- return 0;
- int pos2 = FindCharPosInString(s + pos + 1, '\\');
- if (pos2 < 0)
- return 0;
- return pos + pos2 + 2;
-}
-
-static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s) throw()
-{
- if (IsDrivePath(s))
- return kDrivePrefixSize;
- if (s[0] != '\\' || s[1] != '\\')
- return 0;
- unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
- return (size == 0) ? 0 : 2 + size;
-}
-
-static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s) throw()
-{
- if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
- {
- 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 = FindCharPosInString(s + kSuperPathPrefixSize, FCHAR_PATH_SEPARATOR);
- if (pos < 0)
- return 0;
- return kSuperPathPrefixSize + pos + 1;
-}
-
-unsigned GetRootPrefixSize(CFSTR s) throw()
-{
- if (IS_DEVICE_PATH(s))
- return kDevicePathPrefixSize;
- if (IsSuperPath(s))
- return GetRootPrefixSize_Of_SuperPath(s);
- return GetRootPrefixSize_Of_SimplePath(s);
-}
-
-#endif // USE_UNICODE_FSTRING
-
-static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw()
-{
- // Network path: we look "server\path\" as root prefix
- int pos = FindCharPosInString(s, L'\\');
- if (pos < 0)
- return 0;
- int pos2 = FindCharPosInString(s + pos + 1, L'\\');
- if (pos2 < 0)
- return 0;
- return pos + pos2 + 2;
-}
-
-static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw()
-{
- if (IsDrivePath(s))
- return kDrivePrefixSize;
- if (s[0] != '\\' || s[1] != '\\')
- return 0;
- unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
- return (size == 0) ? 0 : 2 + size;
-}
-
-static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
-{
- if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
- {
- 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 = FindCharPosInString(s + kSuperPathPrefixSize, L'\\');
- if (pos < 0)
- return 0;
- return kSuperPathPrefixSize + pos + 1;
-}
-
-unsigned GetRootPrefixSize(const wchar_t *s) throw()
-{
- if (IS_DEVICE_PATH(s))
- return kDevicePathPrefixSize;
- if (IsSuperPath(s))
- return GetRootPrefixSize_Of_SuperPath(s);
- return GetRootPrefixSize_Of_SimplePath(s);
-}
-
-#else // _WIN32
-
-bool IsAbsolutePath(const wchar_t *s) throw() { return s[0] == WCHAR_PATH_SEPARATOR }
-
-#ifndef USE_UNICODE_FSTRING
-unsigned GetRootPrefixSize(CFSTR s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
-#endif
-unsigned GetRootPrefixSize(const wchar_t *s) throw() { return s[0] == CHAR_PATH_SEPRATOR ? 1 : 0; }
-
-#endif // _WIN32
-
-
-#ifndef UNDER_CE
-
-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);
-}
-
-static bool ResolveDotsFolders(UString &s)
-{
- #ifdef _WIN32
- s.Replace(L'/', WCHAR_PATH_SEPARATOR);
- #endif
- for (int i = 0;;)
- {
- wchar_t c = s[i];
- if (c == 0)
- return true;
- if (c == '.' && (i == 0 || s[i - 1] == WCHAR_PATH_SEPARATOR))
- {
- wchar_t c1 = s[i + 1];
- if (c1 == '.')
- {
- wchar_t c2 = s[i + 2];
- if (c2 == WCHAR_PATH_SEPARATOR || c2 == 0)
- {
- if (i == 0)
- return false;
- int k = i - 2;
- for (; k >= 0; k--)
- if (s[k] == WCHAR_PATH_SEPARATOR)
- break;
- unsigned num;
- if (k >= 0)
- {
- num = i + 2 - k;
- i = k;
- }
- else
- {
- num = (c2 == 0 ? (i + 2) : (i + 3));
- i = 0;
- }
- s.Delete(i, num);
- continue;
- }
- }
- else
- {
- if (c1 == WCHAR_PATH_SEPARATOR || c1 == 0)
- {
- unsigned num = 2;
- if (i != 0)
- i--;
- else if (c1 == 0)
- num = 1;
- s.Delete(i, num);
- continue;
- }
- }
- }
- i++;
- }
-}
-
-#endif // UNDER_CE
-
-#define LONG_PATH_DOTS_FOLDERS_PARSING
-
-
-/*
-Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\
-To solve that problem we check such path:
- - super path contains "." or ".." - we use kSuperPathType_UseOnlySuper
- - super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain
-*/
-#ifdef LONG_PATH_DOTS_FOLDERS_PARSING
-#ifndef UNDER_CE
-static bool AreThereDotsFolders(CFSTR s)
-{
- for (unsigned i = 0;; i++)
- {
- FChar c = s[i];
- if (c == 0)
- return false;
- if (c == '.' && (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR))
- {
- FChar c1 = s[i + 1];
- if (c1 == 0 || c1 == CHAR_PATH_SEPARATOR ||
- (c1 == '.' && (s[i + 2] == 0 || s[i + 2] == CHAR_PATH_SEPARATOR)))
- return true;
- }
- }
-}
-#endif
-#endif // LONG_PATH_DOTS_FOLDERS_PARSING
-
-#ifdef WIN_LONG_PATH
-
-/*
-Most of Windows versions have problems, if some file or dir name
-contains '.' or ' ' at the end of name (Bad Path).
-To solve that problem, we always use Super Path ("\\?\" prefix and full path)
-in such cases. Note that "." and ".." are not bad names.
-
-There are 3 cases:
- 1) If the path is already Super Path, we use that path
- 2) If the path is not Super Path :
- 2.1) Bad Path; we use only Super Path.
- 2.2) Good Path; we use Main Path. If it fails, we use Super Path.
-
- NeedToUseOriginalPath returns:
- kSuperPathType_UseOnlyMain : Super already
- kSuperPathType_UseOnlySuper : not Super, Bad Path
- kSuperPathType_UseMainAndSuper : not Super, Good Path
-*/
-
-int GetUseSuperPathType(CFSTR s) throw()
-{
- if (IsSuperOrDevicePath(s))
- {
- #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
- if ((s)[2] != '.')
- if (AreThereDotsFolders(s + kSuperPathPrefixSize))
- return kSuperPathType_UseOnlySuper;
- #endif
- return kSuperPathType_UseOnlyMain;
- }
-
- for (unsigned i = 0;; i++)
- {
- FChar c = s[i];
- if (c == 0)
- return kSuperPathType_UseMainAndSuper;
- if (c == '.' || c == ' ')
- {
- FChar c2 = s[i + 1];
- if (c2 == 0 || c2 == CHAR_PATH_SEPARATOR)
- {
- // if it's "." or "..", it's not bad name.
- if (c == '.')
- {
- if (i == 0 || s[i - 1] == CHAR_PATH_SEPARATOR)
- continue;
- if (s[i - 1] == '.')
- {
- if (i - 1 == 0 || s[i - 2] == CHAR_PATH_SEPARATOR)
- continue;
- }
- }
- return kSuperPathType_UseOnlySuper;
- }
- }
- }
-}
-
-
-/*
- returns false in two cases:
- - if GetCurDir was used, and GetCurDir returned error.
- - if we can't resolve ".." name.
- if path is ".", "..", res is empty.
- if it's Super Path already, res is empty.
- for \**** , and if GetCurDir is not drive (c:\), res is empty
- for absolute paths, returns true, res is Super path.
-*/
-
-
-static bool GetSuperPathBase(CFSTR s, UString &res)
-{
- res.Empty();
-
- FChar c = s[0];
- if (c == 0)
- return true;
- if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
- return true;
-
- if (IsSuperOrDevicePath(s))
- {
- #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
-
- if ((s)[2] == '.')
- return true;
-
- // we will return true here, so we will try to use these problem paths.
-
- if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
- return true;
-
- UString temp = fs2us(s);
- unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
- if (fixedSize == 0)
- return true;
-
- UString rem = &temp[fixedSize];
- if (!ResolveDotsFolders(rem))
- return true;
-
- temp.DeleteFrom(fixedSize);
- res += temp;
- res += rem;
-
- #endif
-
- return true;
- }
-
- if (c == CHAR_PATH_SEPARATOR)
- {
- if (s[1] == CHAR_PATH_SEPARATOR)
- {
- UString temp = fs2us(s + 2);
- unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
- if (fixedSize == 0) // maybe we must ignore that error to allow short network paths?
- return false;
- UString rem = &temp[fixedSize];
- if (!ResolveDotsFolders(rem))
- return false;
- res += kSuperUncPrefix;
- temp.DeleteFrom(fixedSize);
- res += temp;
- res += rem;
- return true;
- }
- }
- else
- {
- if (IsDrivePath(s))
- {
- UString temp = fs2us(s);
- UString rem = &temp[kDrivePrefixSize];
- if (!ResolveDotsFolders(rem))
- return true;
- res += kSuperPathPrefix;
- temp.DeleteFrom(kDrivePrefixSize);
- res += temp;
- res += rem;
- return true;
- }
- }
-
- UString curDir;
- if (!GetCurDir(curDir))
- return false;
- if (curDir.Back() != WCHAR_PATH_SEPARATOR)
- curDir += WCHAR_PATH_SEPARATOR;
-
- unsigned fixedSizeStart = 0;
- unsigned fixedSize = 0;
- const wchar_t *superMarker = NULL;
- if (IsSuperPath(curDir))
- {
- fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
- if (fixedSize == 0)
- return false;
- }
- else
- {
- if (IsDrivePath(curDir))
- {
- superMarker = kSuperPathPrefix;
- fixedSize = kDrivePrefixSize;
- }
- else
- {
- if (curDir[0] != CHAR_PATH_SEPARATOR || curDir[1] != CHAR_PATH_SEPARATOR)
- return false;
- fixedSizeStart = 2;
- fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
- if (fixedSize == 0)
- return false;
- superMarker = kSuperUncPrefix;
- }
- }
-
- UString temp;
- if (c == CHAR_PATH_SEPARATOR)
- {
- temp = fs2us(s + 1);
- }
- else
- {
- temp += &curDir[fixedSizeStart + fixedSize];
- temp += fs2us(s);
- }
- if (!ResolveDotsFolders(temp))
- return false;
- if (superMarker)
- res += superMarker;
- res += curDir.Mid(fixedSizeStart, fixedSize);
- res += temp;
- return true;
-}
-
-
-/*
- In that case if GetSuperPathBase doesn't return new path, we don't need
- to use same path that was used as main path
-
- GetSuperPathBase superPath.IsEmpty() onlyIfNew
- false * * GetCurDir Error
- 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
- type of path (not drive and not network)
-
- We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
- and we didn't try mainPath still.
- If we want to work that way, we don't need to use GetSuperPathBase return code.
-*/
-
-bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew)
-{
- if (GetSuperPathBase(path, superPath))
- {
- if (superPath.IsEmpty())
- {
- // actually the only possible when onlyIfNew == true and superPath is empty
- // is case when
-
- if (onlyIfNew)
- return false;
- superPath = fs2us(path);
- }
- return true;
- }
- return false;
-}
-
-bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
-{
- if (!GetSuperPathBase(s1, d1) ||
- !GetSuperPathBase(s2, d2))
- return false;
- if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew)
- return false;
- if (d1.IsEmpty()) d1 = fs2us(s1);
- if (d2.IsEmpty()) d2 = fs2us(s2);
- return true;
-}
-
-
-/*
-// returns true, if we need additional use with New Super path.
-bool GetSuperPath(CFSTR path, UString &superPath)
-{
- if (GetSuperPathBase(path, superPath))
- return !superPath.IsEmpty();
- return false;
-}
-*/
-#endif // WIN_LONG_PATH
-
-bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
-{
- res = s;
-
- #ifdef UNDER_CE
-
- if (s[0] != CHAR_PATH_SEPARATOR)
- {
- if (!dirPrefix)
- return false;
- res = dirPrefix;
- res += s;
- }
-
- #else
-
- unsigned prefixSize = GetRootPrefixSize(s);
- if (prefixSize != 0)
- {
- if (!AreThereDotsFolders(s + prefixSize))
- return true;
-
- UString rem = fs2us(s + prefixSize);
- if (!ResolveDotsFolders(rem))
- return true; // maybe false;
- res.DeleteFrom(prefixSize);
- res += us2fs(rem);
- return true;
- }
-
- /*
- FChar c = s[0];
- if (c == 0)
- return true;
- if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
- return true;
- if (c == CHAR_PATH_SEPARATOR && s[1] == CHAR_PATH_SEPARATOR)
- return true;
- if (IsDrivePath(s))
- return true;
- */
-
- UString curDir;
- if (dirPrefix)
- curDir = fs2us(dirPrefix);
- else
- {
- if (!GetCurDir(curDir))
- return false;
- }
- if (!curDir.IsEmpty() && curDir.Back() != WCHAR_PATH_SEPARATOR)
- curDir += WCHAR_PATH_SEPARATOR;
-
- unsigned fixedSize = 0;
-
- #ifdef _WIN32
-
- if (IsSuperPath(curDir))
- {
- fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
- if (fixedSize == 0)
- return false;
- }
- else
- {
- if (IsDrivePath(curDir))
- fixedSize = kDrivePrefixSize;
- else
- {
- if (curDir[0] != WCHAR_PATH_SEPARATOR || curDir[1] != WCHAR_PATH_SEPARATOR)
- return false;
- fixedSize = GetRootPrefixSize_Of_NetworkPath(&curDir[2]);
- if (fixedSize == 0)
- return false;
- fixedSize += 2;
- }
- }
-
- #endif // _WIN32
-
- UString temp;
- if (s[0] == CHAR_PATH_SEPARATOR)
- {
- temp = fs2us(s + 1);
- }
- else
- {
- temp += curDir.Ptr(fixedSize);
- temp += fs2us(s);
- }
- if (!ResolveDotsFolders(temp))
- return false;
- curDir.DeleteFrom(fixedSize);
- res = us2fs(curDir);
- res += us2fs(temp);
-
- #endif // UNDER_CE
-
- return true;
-}
-
-bool GetFullPath(CFSTR path, FString &fullPath)
-{
- return GetFullPath(NULL, path, fullPath);
-}
-
-}}}