bool IsAltPathPrefix(CFSTR s) throw()
{ unsigned len = MyStringLen(s); if (len == 0) returnfalse; if (s[len - 1] != ':') returnfalse;
#ifdefined(_WIN32) && !defined(UNDER_CE) if (IsDevicePath(s)) returnfalse; if (IsSuperPath(s))
{
s += kSuperPathPrefixSize;
len -= kSuperPathPrefixSize;
} if (len == 2 && IsDrivePath2(s)) returnfalse; #endif
s = s; returnfalse; /* // actually we don't know the way to open device file in WinCE. unsigned len = MyStringLen(s); if (len < 5 || len > 5 || !IsString1PrefixedByString2(s, "DSK")) 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)) returnfalse; unsigned len = MyStringLen(s); if (len == 6 && s[5] == ':') returntrue; if (len < 18 || len > 22 || !IsString1PrefixedByString2(s + kDevicePathPrefixSize, "PhysicalDrive")) returnfalse; for (unsigned i = 17; i < len; i++) if (s[i] < '0' || s[i] > '9') returnfalse; returntrue;
#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])) returnfalse; if (IsSuperUncPath(s)) returntrue;
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) returnfalse;
s += prefixSize; int pos = FindSepar(s); if (pos < 0) returntrue; return s[(unsigned)pos + 1] == 0;
}
int FindAltStreamColon(CFSTR path) throw()
{ 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
staticunsigned 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;
}
for (unsigned i = 0;;)
{ constwchar_t c = s[i]; if (c == 0) returntrue; if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
{ constwchar_t c1 = s[i + 1]; if (c1 == '.')
{ constwchar_t c2 = s[i + 2]; if (IS_SEPAR(c2) || c2 == 0)
{ if (i == 0) returnfalse; int k = i - 2;
i += 2;
for (;; k--)
{ if (k < 0) returnfalse; if (!IS_SEPAR(s[(unsigned)k])) break;
}
do
k--; while (k >= 0 && !IS_SEPAR(s[(unsigned)k]));
unsigned num;
if (k >= 0)
{
num = i - k;
i = k;
} else
{
num = (c2 == 0 ? i : (i + 1));
i = 0;
}
s.Delete(i, num); continue;
}
} elseif (IS_SEPAR(c1) || c1 == 0)
{ unsigned num = 2; if (i != 0)
i--; elseif (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 staticbool AreThereDotsFolders(CFSTR s)
{ for (unsigned i = 0;; i++)
{
FChar c = s[i]; if (c == 0) returnfalse; 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])))) returntrue;
}
}
} #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.
*/
UString rem = &temp[fixedSize]; if (!ResolveDotsFolders(rem)) returntrue;
temp.DeleteFrom(fixedSize);
res += temp;
res += rem;
#endif
returntrue;
}
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)) returnfalse;
res += kSuperUncPrefix;
temp.DeleteFrom(fixedSize);
res += temp;
res += rem; returntrue;
}
} else
{ if (IsDrivePath2(s))
{
UString temp = fs2us(s); unsigned prefixSize = 2; if (IsDrivePath(s))
prefixSize = kDrivePrefixSize;
UString rem = temp.Ptr(prefixSize); if (!ResolveDotsFolders(rem)) returntrue;
res += kSuperPathPrefix;
temp.DeleteFrom(prefixSize);
res += temp;
res += rem; returntrue;
}
}
UString curDir; if (!GetCurDir(curDir)) returnfalse;
NormalizeDirPathPrefix(curDir);
UString temp; if (IS_SEPAR(c))
{
temp = fs2us(s + 1);
} else
{
temp += &curDir[fixedSizeStart + fixedSize];
temp += fs2us(s);
} if (!ResolveDotsFolders(temp)) returnfalse; if (superMarker)
res += superMarker;
res += curDir.Mid(fixedSizeStart, fixedSize);
res += temp; returntrue;
}
/* 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
bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
{ if (!GetSuperPathBase(s1, d1) ||
!GetSuperPathBase(s2, d2)) returnfalse; if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew) returnfalse; if (d1.IsEmpty()) d1 = fs2us(s1); if (d2.IsEmpty()) d2 = fs2us(s2); returntrue;
}
/* // 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
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.