mirror of
https://github.com/Xevion/easy7zip.git
synced 2025-12-08 18:07:15 -06:00
Initialer Commit
This commit is contained in:
829
CPP/Windows/FileName.cpp
Normal file
829
CPP/Windows/FileName.cpp
Normal file
@@ -0,0 +1,829 @@
|
||||
// Windows/FileName.cpp
|
||||
|
||||
#include "StdAfx.h"
|
||||
|
||||
#include "FileName.h"
|
||||
|
||||
#ifndef _UNICODE
|
||||
extern bool g_IsNT;
|
||||
#endif
|
||||
|
||||
namespace NWindows {
|
||||
namespace NFile {
|
||||
namespace NName {
|
||||
|
||||
#define IS_SEPAR(c) IS_PATH_SEPAR(c)
|
||||
|
||||
int FindSepar(const wchar_t *s) throw()
|
||||
{
|
||||
for (const wchar_t *p = s;; p++)
|
||||
{
|
||||
const wchar_t c = *p;
|
||||
if (c == 0)
|
||||
return -1;
|
||||
if (IS_SEPAR(c))
|
||||
return (int)(p - s);
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_UNICODE_FSTRING
|
||||
int FindSepar(const FChar *s) throw()
|
||||
{
|
||||
for (const FChar *p = s;; p++)
|
||||
{
|
||||
const FChar c = *p;
|
||||
if (c == 0)
|
||||
return -1;
|
||||
if (IS_SEPAR(c))
|
||||
return (int)(p - s);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef USE_UNICODE_FSTRING
|
||||
void NormalizeDirPathPrefix(FString &dirPath)
|
||||
{
|
||||
if (dirPath.IsEmpty())
|
||||
return;
|
||||
if (!IsPathSepar(dirPath.Back()))
|
||||
dirPath.Add_PathSepar();
|
||||
}
|
||||
#endif
|
||||
|
||||
void NormalizeDirPathPrefix(UString &dirPath)
|
||||
{
|
||||
if (dirPath.IsEmpty())
|
||||
return;
|
||||
if (!IsPathSepar(dirPath.Back()))
|
||||
dirPath.Add_PathSepar();
|
||||
}
|
||||
|
||||
#define IS_LETTER_CHAR(c) ((c) >= 'a' && (c) <= 'z' || (c) >= 'A' && (c) <= 'Z')
|
||||
|
||||
bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
|
||||
|
||||
bool IsAltPathPrefix(CFSTR s) throw()
|
||||
{
|
||||
unsigned len = MyStringLen(s);
|
||||
if (len == 0)
|
||||
return false;
|
||||
if (s[len - 1] != ':')
|
||||
return false;
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
if (IsDevicePath(s))
|
||||
return false;
|
||||
if (IsSuperPath(s))
|
||||
{
|
||||
s += kSuperPathPrefixSize;
|
||||
len -= kSuperPathPrefixSize;
|
||||
}
|
||||
if (len == 2 && IsDrivePath2(s))
|
||||
return false;
|
||||
#endif
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#if defined(_WIN32) && !defined(UNDER_CE)
|
||||
|
||||
const wchar_t *kSuperPathPrefix = L"\\\\?\\";
|
||||
static const wchar_t *kSuperUncPrefix = L"\\\\?\\UNC\\";
|
||||
|
||||
#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]))
|
||||
#define IS_SUPER_OR_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && ((s)[2] == '?' || (s)[2] == '.') && IS_SEPAR((s)[3]))
|
||||
|
||||
#define IS_UNC_WITH_SLASH(s) ( \
|
||||
((s)[0] == 'U' || (s)[0] == 'u') \
|
||||
&& ((s)[1] == 'N' || (s)[1] == 'n') \
|
||||
&& ((s)[2] == 'C' || (s)[2] == 'c') \
|
||||
&& IS_SEPAR((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 IsNetworkPath(CFSTR s) throw()
|
||||
{
|
||||
if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
|
||||
return false;
|
||||
if (IsSuperUncPath(s))
|
||||
return true;
|
||||
FChar c = s[2];
|
||||
return (c != '.' && c != '?');
|
||||
}
|
||||
|
||||
unsigned GetNetworkServerPrefixSize(CFSTR s) throw()
|
||||
{
|
||||
if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
|
||||
return 0;
|
||||
unsigned prefixSize = 2;
|
||||
if (IsSuperUncPath(s))
|
||||
prefixSize = kSuperUncPathPrefixSize;
|
||||
else
|
||||
{
|
||||
FChar c = s[2];
|
||||
if (c == '.' || c == '?')
|
||||
return 0;
|
||||
}
|
||||
int pos = FindSepar(s + prefixSize);
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
return prefixSize + pos + 1;
|
||||
}
|
||||
|
||||
bool IsNetworkShareRootPath(CFSTR s) throw()
|
||||
{
|
||||
unsigned prefixSize = GetNetworkServerPrefixSize(s);
|
||||
if (prefixSize == 0)
|
||||
return false;
|
||||
s += prefixSize;
|
||||
int pos = FindSepar(s);
|
||||
if (pos < 0)
|
||||
return true;
|
||||
return s[(unsigned)pos + 1] == 0;
|
||||
}
|
||||
|
||||
static const unsigned kDrivePrefixSize = 3; /* c:\ */
|
||||
|
||||
bool IsDrivePath2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
|
||||
// bool IsDriveName2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
|
||||
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)); }
|
||||
|
||||
#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; }
|
||||
bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(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 IsDrivePath_SuperAllowed(CFSTR s)
|
||||
{
|
||||
if (IsSuperPath(s))
|
||||
s += kSuperPathPrefixSize;
|
||||
return IsDrivePath(s);
|
||||
}
|
||||
*/
|
||||
|
||||
bool IsDriveRootPath_SuperAllowed(CFSTR s) throw()
|
||||
{
|
||||
if (IsSuperPath(s))
|
||||
s += kSuperPathPrefixSize;
|
||||
return IsDrivePath(s) && s[kDrivePrefixSize] == 0;
|
||||
}
|
||||
|
||||
bool IsAbsolutePath(const wchar_t *s) throw()
|
||||
{
|
||||
return IS_SEPAR(s[0]) || IsDrivePath2(s);
|
||||
}
|
||||
|
||||
int FindAltStreamColon(CFSTR path)
|
||||
{
|
||||
unsigned i = 0;
|
||||
if (IsDrivePath2(path))
|
||||
i = 2;
|
||||
int colonPos = -1;
|
||||
for (;; i++)
|
||||
{
|
||||
FChar c = path[i];
|
||||
if (c == 0)
|
||||
return colonPos;
|
||||
if (c == ':')
|
||||
{
|
||||
if (colonPos < 0)
|
||||
colonPos = i;
|
||||
continue;
|
||||
}
|
||||
if (IS_SEPAR(c))
|
||||
colonPos = -1;
|
||||
}
|
||||
}
|
||||
|
||||
#ifndef USE_UNICODE_FSTRING
|
||||
|
||||
static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s)
|
||||
{
|
||||
// Network path: we look "server\path\" as root prefix
|
||||
int pos = FindSepar(s);
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
int pos2 = FindSepar(s + (unsigned)pos + 1);
|
||||
if (pos2 < 0)
|
||||
return 0;
|
||||
return pos + pos2 + 2;
|
||||
}
|
||||
|
||||
static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s)
|
||||
{
|
||||
if (IsDrivePath(s))
|
||||
return kDrivePrefixSize;
|
||||
if (!IS_SEPAR(s[0]))
|
||||
return 0;
|
||||
if (s[1] == 0 || !IS_SEPAR(s[1]))
|
||||
return 1;
|
||||
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
|
||||
return (size == 0) ? 0 : 2 + size;
|
||||
}
|
||||
|
||||
static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
|
||||
{
|
||||
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 = FindSepar(s + kSuperPathPrefixSize);
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
return kSuperPathPrefixSize + pos + 1;
|
||||
}
|
||||
|
||||
unsigned GetRootPrefixSize(CFSTR s)
|
||||
{
|
||||
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)
|
||||
{
|
||||
// Network path: we look "server\path\" as root prefix
|
||||
int pos = FindSepar(s);
|
||||
if (pos < 0)
|
||||
return 0;
|
||||
int pos2 = FindSepar(s + (unsigned)pos + 1);
|
||||
if (pos2 < 0)
|
||||
return 0;
|
||||
return pos + pos2 + 2;
|
||||
}
|
||||
|
||||
static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s)
|
||||
{
|
||||
if (IsDrivePath(s))
|
||||
return kDrivePrefixSize;
|
||||
if (!IS_SEPAR(s[0]))
|
||||
return 0;
|
||||
if (s[1] == 0 || !IS_SEPAR(s[1]))
|
||||
return 1;
|
||||
unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
|
||||
return (size == 0) ? 0 : 2 + size;
|
||||
}
|
||||
|
||||
static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s)
|
||||
{
|
||||
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 = FindSepar(s + kSuperPathPrefixSize);
|
||||
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) { return IS_SEPAR(s[0]); }
|
||||
|
||||
#ifndef USE_UNICODE_FSTRING
|
||||
unsigned GetRootPrefixSize(CFSTR s) { return IS_SEPAR(s[0]) ? 1 : 0; }
|
||||
#endif
|
||||
unsigned GetRootPrefixSize(const wchar_t *s) { return IS_SEPAR(s[0]) ? 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 (unsigned i = 0;;)
|
||||
{
|
||||
wchar_t c = s[i];
|
||||
if (c == 0)
|
||||
return true;
|
||||
if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
|
||||
{
|
||||
wchar_t c1 = s[i + 1];
|
||||
if (c1 == '.')
|
||||
{
|
||||
wchar_t c2 = s[i + 2];
|
||||
if (IS_SEPAR(c2) || c2 == 0)
|
||||
{
|
||||
if (i == 0)
|
||||
return false;
|
||||
int k = i - 2;
|
||||
for (; k >= 0; k--)
|
||||
if (IS_SEPAR(s[(unsigned)k]))
|
||||
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 (IS_SEPAR(c1) || 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 || IS_SEPAR(s[i - 1])))
|
||||
{
|
||||
FChar c1 = s[i + 1];
|
||||
if (c1 == 0 || IS_SEPAR(c1) ||
|
||||
(c1 == '.' && (s[i + 2] == 0 || IS_SEPAR(s[i + 2]))))
|
||||
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 || IS_SEPAR(c2))
|
||||
{
|
||||
// if it's "." or "..", it's not bad name.
|
||||
if (c == '.')
|
||||
{
|
||||
if (i == 0 || IS_SEPAR(s[i - 1]))
|
||||
continue;
|
||||
if (s[i - 1] == '.')
|
||||
{
|
||||
if (i - 1 == 0 || IS_SEPAR(s[i - 2]))
|
||||
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 (IS_SEPAR(c))
|
||||
{
|
||||
if (IS_SEPAR(s[1]))
|
||||
{
|
||||
UString temp = fs2us(s + 2);
|
||||
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];
|
||||
if (!ResolveDotsFolders(rem))
|
||||
return false;
|
||||
res += kSuperUncPrefix;
|
||||
temp.DeleteFrom(fixedSize);
|
||||
res += temp;
|
||||
res += rem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (IsDrivePath2(s))
|
||||
{
|
||||
UString temp = fs2us(s);
|
||||
unsigned prefixSize = 2;
|
||||
if (IsDrivePath(s))
|
||||
prefixSize = kDrivePrefixSize;
|
||||
UString rem = temp.Ptr(prefixSize);
|
||||
if (!ResolveDotsFolders(rem))
|
||||
return true;
|
||||
res += kSuperPathPrefix;
|
||||
temp.DeleteFrom(prefixSize);
|
||||
res += temp;
|
||||
res += rem;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
UString curDir;
|
||||
if (!GetCurDir(curDir))
|
||||
return false;
|
||||
NormalizeDirPathPrefix(curDir);
|
||||
|
||||
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 (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
|
||||
return false;
|
||||
fixedSizeStart = 2;
|
||||
fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
|
||||
if (fixedSize == 0)
|
||||
return false;
|
||||
superMarker = kSuperUncPrefix;
|
||||
}
|
||||
}
|
||||
|
||||
UString temp;
|
||||
if (IS_SEPAR(c))
|
||||
{
|
||||
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 (!IS_SEPAR(s[0]))
|
||||
{
|
||||
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 (IS_SEPAR(c) && IS_SEPAR(s[1]))
|
||||
return true;
|
||||
if (IsDrivePath(s))
|
||||
return true;
|
||||
*/
|
||||
|
||||
UString curDir;
|
||||
if (dirPrefix)
|
||||
curDir = fs2us(dirPrefix);
|
||||
else
|
||||
{
|
||||
if (!GetCurDir(curDir))
|
||||
return false;
|
||||
}
|
||||
NormalizeDirPathPrefix(curDir);
|
||||
|
||||
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 (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
|
||||
return false;
|
||||
fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
|
||||
if (fixedSize == 0)
|
||||
return false;
|
||||
fixedSize += 2;
|
||||
}
|
||||
}
|
||||
|
||||
#endif // _WIN32
|
||||
|
||||
UString temp;
|
||||
if (IS_SEPAR(s[0]))
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
}}}
|
||||
Reference in New Issue
Block a user