xref: /aosp_15_r20/external/lzma/CPP/Windows/FileName.cpp (revision f6dc9357d832569d4d1f5d24eacdb3935a1ae8e6)
1*f6dc9357SAndroid Build Coastguard Worker // Windows/FileName.cpp
2*f6dc9357SAndroid Build Coastguard Worker 
3*f6dc9357SAndroid Build Coastguard Worker #include "StdAfx.h"
4*f6dc9357SAndroid Build Coastguard Worker 
5*f6dc9357SAndroid Build Coastguard Worker #ifndef _WIN32
6*f6dc9357SAndroid Build Coastguard Worker #include <limits.h>
7*f6dc9357SAndroid Build Coastguard Worker #include <unistd.h>
8*f6dc9357SAndroid Build Coastguard Worker #include "../Common/StringConvert.h"
9*f6dc9357SAndroid Build Coastguard Worker #endif
10*f6dc9357SAndroid Build Coastguard Worker 
11*f6dc9357SAndroid Build Coastguard Worker #include "FileDir.h"
12*f6dc9357SAndroid Build Coastguard Worker #include "FileName.h"
13*f6dc9357SAndroid Build Coastguard Worker 
14*f6dc9357SAndroid Build Coastguard Worker #ifndef _UNICODE
15*f6dc9357SAndroid Build Coastguard Worker extern bool g_IsNT;
16*f6dc9357SAndroid Build Coastguard Worker #endif
17*f6dc9357SAndroid Build Coastguard Worker 
18*f6dc9357SAndroid Build Coastguard Worker namespace NWindows {
19*f6dc9357SAndroid Build Coastguard Worker namespace NFile {
20*f6dc9357SAndroid Build Coastguard Worker namespace NName {
21*f6dc9357SAndroid Build Coastguard Worker 
22*f6dc9357SAndroid Build Coastguard Worker #define IS_SEPAR(c) IS_PATH_SEPAR(c)
23*f6dc9357SAndroid Build Coastguard Worker 
FindSepar(const wchar_t * s)24*f6dc9357SAndroid Build Coastguard Worker int FindSepar(const wchar_t *s) throw()
25*f6dc9357SAndroid Build Coastguard Worker {
26*f6dc9357SAndroid Build Coastguard Worker   for (const wchar_t *p = s;; p++)
27*f6dc9357SAndroid Build Coastguard Worker   {
28*f6dc9357SAndroid Build Coastguard Worker     const wchar_t c = *p;
29*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
30*f6dc9357SAndroid Build Coastguard Worker       return -1;
31*f6dc9357SAndroid Build Coastguard Worker     if (IS_SEPAR(c))
32*f6dc9357SAndroid Build Coastguard Worker       return (int)(p - s);
33*f6dc9357SAndroid Build Coastguard Worker   }
34*f6dc9357SAndroid Build Coastguard Worker }
35*f6dc9357SAndroid Build Coastguard Worker 
36*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
FindSepar(const FChar * s)37*f6dc9357SAndroid Build Coastguard Worker int FindSepar(const FChar *s) throw()
38*f6dc9357SAndroid Build Coastguard Worker {
39*f6dc9357SAndroid Build Coastguard Worker   for (const FChar *p = s;; p++)
40*f6dc9357SAndroid Build Coastguard Worker   {
41*f6dc9357SAndroid Build Coastguard Worker     const FChar c = *p;
42*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
43*f6dc9357SAndroid Build Coastguard Worker       return -1;
44*f6dc9357SAndroid Build Coastguard Worker     if (IS_SEPAR(c))
45*f6dc9357SAndroid Build Coastguard Worker       return (int)(p - s);
46*f6dc9357SAndroid Build Coastguard Worker   }
47*f6dc9357SAndroid Build Coastguard Worker }
48*f6dc9357SAndroid Build Coastguard Worker #endif
49*f6dc9357SAndroid Build Coastguard Worker 
50*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
NormalizeDirPathPrefix(FString & dirPath)51*f6dc9357SAndroid Build Coastguard Worker void NormalizeDirPathPrefix(FString &dirPath)
52*f6dc9357SAndroid Build Coastguard Worker {
53*f6dc9357SAndroid Build Coastguard Worker   if (dirPath.IsEmpty())
54*f6dc9357SAndroid Build Coastguard Worker     return;
55*f6dc9357SAndroid Build Coastguard Worker   if (!IsPathSepar(dirPath.Back()))
56*f6dc9357SAndroid Build Coastguard Worker     dirPath.Add_PathSepar();
57*f6dc9357SAndroid Build Coastguard Worker }
58*f6dc9357SAndroid Build Coastguard Worker #endif
59*f6dc9357SAndroid Build Coastguard Worker 
NormalizeDirPathPrefix(UString & dirPath)60*f6dc9357SAndroid Build Coastguard Worker void NormalizeDirPathPrefix(UString &dirPath)
61*f6dc9357SAndroid Build Coastguard Worker {
62*f6dc9357SAndroid Build Coastguard Worker   if (dirPath.IsEmpty())
63*f6dc9357SAndroid Build Coastguard Worker     return;
64*f6dc9357SAndroid Build Coastguard Worker   if (!IsPathSepar(dirPath.Back()))
65*f6dc9357SAndroid Build Coastguard Worker     dirPath.Add_PathSepar();
66*f6dc9357SAndroid Build Coastguard Worker }
67*f6dc9357SAndroid Build Coastguard Worker 
68*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
69*f6dc9357SAndroid Build Coastguard Worker 
70*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
71*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
NormalizeDirSeparators(UString & s)72*f6dc9357SAndroid Build Coastguard Worker static void NormalizeDirSeparators(UString &s)
73*f6dc9357SAndroid Build Coastguard Worker {
74*f6dc9357SAndroid Build Coastguard Worker   const unsigned len = s.Len();
75*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < len; i++)
76*f6dc9357SAndroid Build Coastguard Worker     if (s[i] == '/')
77*f6dc9357SAndroid Build Coastguard Worker       s.ReplaceOneCharAtPos(i, WCHAR_PATH_SEPARATOR);
78*f6dc9357SAndroid Build Coastguard Worker }
79*f6dc9357SAndroid Build Coastguard Worker #endif
80*f6dc9357SAndroid Build Coastguard Worker #endif
81*f6dc9357SAndroid Build Coastguard Worker 
NormalizeDirSeparators(FString & s)82*f6dc9357SAndroid Build Coastguard Worker void NormalizeDirSeparators(FString &s)
83*f6dc9357SAndroid Build Coastguard Worker {
84*f6dc9357SAndroid Build Coastguard Worker   const unsigned len = s.Len();
85*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0; i < len; i++)
86*f6dc9357SAndroid Build Coastguard Worker     if (s[i] == '/')
87*f6dc9357SAndroid Build Coastguard Worker       s.ReplaceOneCharAtPos(i, FCHAR_PATH_SEPARATOR);
88*f6dc9357SAndroid Build Coastguard Worker }
89*f6dc9357SAndroid Build Coastguard Worker 
90*f6dc9357SAndroid Build Coastguard Worker #endif
91*f6dc9357SAndroid Build Coastguard Worker 
92*f6dc9357SAndroid Build Coastguard Worker 
93*f6dc9357SAndroid Build Coastguard Worker #define IS_LETTER_CHAR(c) ((((unsigned)(int)(c) | 0x20) - (unsigned)'a' <= (unsigned)('z' - 'a')))
94*f6dc9357SAndroid Build Coastguard Worker 
IsDrivePath(const wchar_t * s)95*f6dc9357SAndroid Build Coastguard Worker bool IsDrivePath(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
96*f6dc9357SAndroid Build Coastguard Worker 
IsAltPathPrefix(CFSTR s)97*f6dc9357SAndroid Build Coastguard Worker bool IsAltPathPrefix(CFSTR s) throw()
98*f6dc9357SAndroid Build Coastguard Worker {
99*f6dc9357SAndroid Build Coastguard Worker   unsigned len = MyStringLen(s);
100*f6dc9357SAndroid Build Coastguard Worker   if (len == 0)
101*f6dc9357SAndroid Build Coastguard Worker     return false;
102*f6dc9357SAndroid Build Coastguard Worker   if (s[len - 1] != ':')
103*f6dc9357SAndroid Build Coastguard Worker     return false;
104*f6dc9357SAndroid Build Coastguard Worker 
105*f6dc9357SAndroid Build Coastguard Worker   #if defined(_WIN32) && !defined(UNDER_CE)
106*f6dc9357SAndroid Build Coastguard Worker   if (IsDevicePath(s))
107*f6dc9357SAndroid Build Coastguard Worker     return false;
108*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(s))
109*f6dc9357SAndroid Build Coastguard Worker   {
110*f6dc9357SAndroid Build Coastguard Worker     s += kSuperPathPrefixSize;
111*f6dc9357SAndroid Build Coastguard Worker     len -= kSuperPathPrefixSize;
112*f6dc9357SAndroid Build Coastguard Worker   }
113*f6dc9357SAndroid Build Coastguard Worker   if (len == 2 && IsDrivePath2(s))
114*f6dc9357SAndroid Build Coastguard Worker     return false;
115*f6dc9357SAndroid Build Coastguard Worker   #endif
116*f6dc9357SAndroid Build Coastguard Worker 
117*f6dc9357SAndroid Build Coastguard Worker   return true;
118*f6dc9357SAndroid Build Coastguard Worker }
119*f6dc9357SAndroid Build Coastguard Worker 
120*f6dc9357SAndroid Build Coastguard Worker #if defined(_WIN32) && !defined(UNDER_CE)
121*f6dc9357SAndroid Build Coastguard Worker 
122*f6dc9357SAndroid Build Coastguard Worker const char * const kSuperPathPrefix = "\\\\?\\";
123*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
124*f6dc9357SAndroid Build Coastguard Worker static const char * const kSuperUncPrefix = "\\\\?\\UNC\\";
125*f6dc9357SAndroid Build Coastguard Worker #endif
126*f6dc9357SAndroid Build Coastguard Worker 
127*f6dc9357SAndroid Build Coastguard Worker #define IS_DEVICE_PATH(s)          (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '.' && IS_SEPAR((s)[3]))
128*f6dc9357SAndroid Build Coastguard Worker #define IS_SUPER_PREFIX(s)         (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && (s)[2] == '?' && IS_SEPAR((s)[3]))
129*f6dc9357SAndroid Build Coastguard Worker #define IS_SUPER_OR_DEVICE_PATH(s) (IS_SEPAR((s)[0]) && IS_SEPAR((s)[1]) && ((s)[2] == '?' || (s)[2] == '.') && IS_SEPAR((s)[3]))
130*f6dc9357SAndroid Build Coastguard Worker 
131*f6dc9357SAndroid Build Coastguard Worker #define IS_UNC_WITH_SLASH(s) ( \
132*f6dc9357SAndroid Build Coastguard Worker      ((s)[0] == 'U' || (s)[0] == 'u') \
133*f6dc9357SAndroid Build Coastguard Worker   && ((s)[1] == 'N' || (s)[1] == 'n') \
134*f6dc9357SAndroid Build Coastguard Worker   && ((s)[2] == 'C' || (s)[2] == 'c') \
135*f6dc9357SAndroid Build Coastguard Worker   && IS_SEPAR((s)[3]))
136*f6dc9357SAndroid Build Coastguard Worker 
IsDevicePath(CFSTR s)137*f6dc9357SAndroid Build Coastguard Worker bool IsDevicePath(CFSTR s) throw()
138*f6dc9357SAndroid Build Coastguard Worker {
139*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
140*f6dc9357SAndroid Build Coastguard Worker 
141*f6dc9357SAndroid Build Coastguard Worker   s = s;
142*f6dc9357SAndroid Build Coastguard Worker   return false;
143*f6dc9357SAndroid Build Coastguard Worker   /*
144*f6dc9357SAndroid Build Coastguard Worker   // actually we don't know the way to open device file in WinCE.
145*f6dc9357SAndroid Build Coastguard Worker   unsigned len = MyStringLen(s);
146*f6dc9357SAndroid Build Coastguard Worker   if (len < 5 || len > 5 || !IsString1PrefixedByString2(s, "DSK"))
147*f6dc9357SAndroid Build Coastguard Worker     return false;
148*f6dc9357SAndroid Build Coastguard Worker   if (s[4] != ':')
149*f6dc9357SAndroid Build Coastguard Worker     return false;
150*f6dc9357SAndroid Build Coastguard Worker   // for reading use SG_REQ sg; if (DeviceIoControl(dsk, IOCTL_DISK_READ));
151*f6dc9357SAndroid Build Coastguard Worker   */
152*f6dc9357SAndroid Build Coastguard Worker 
153*f6dc9357SAndroid Build Coastguard Worker   #else
154*f6dc9357SAndroid Build Coastguard Worker 
155*f6dc9357SAndroid Build Coastguard Worker   if (!IS_DEVICE_PATH(s))
156*f6dc9357SAndroid Build Coastguard Worker     return false;
157*f6dc9357SAndroid Build Coastguard Worker   unsigned len = MyStringLen(s);
158*f6dc9357SAndroid Build Coastguard Worker   if (len == 6 && s[5] == ':')
159*f6dc9357SAndroid Build Coastguard Worker     return true;
160*f6dc9357SAndroid Build Coastguard Worker   if (len < 18 || len > 22 || !IsString1PrefixedByString2(s + kDevicePathPrefixSize, "PhysicalDrive"))
161*f6dc9357SAndroid Build Coastguard Worker     return false;
162*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 17; i < len; i++)
163*f6dc9357SAndroid Build Coastguard Worker     if (s[i] < '0' || s[i] > '9')
164*f6dc9357SAndroid Build Coastguard Worker       return false;
165*f6dc9357SAndroid Build Coastguard Worker   return true;
166*f6dc9357SAndroid Build Coastguard Worker 
167*f6dc9357SAndroid Build Coastguard Worker   #endif
168*f6dc9357SAndroid Build Coastguard Worker }
169*f6dc9357SAndroid Build Coastguard Worker 
IsSuperUncPath(CFSTR s)170*f6dc9357SAndroid Build Coastguard Worker bool IsSuperUncPath(CFSTR s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
IsNetworkPath(CFSTR s)171*f6dc9357SAndroid Build Coastguard Worker bool IsNetworkPath(CFSTR s) throw()
172*f6dc9357SAndroid Build Coastguard Worker {
173*f6dc9357SAndroid Build Coastguard Worker   if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
174*f6dc9357SAndroid Build Coastguard Worker     return false;
175*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperUncPath(s))
176*f6dc9357SAndroid Build Coastguard Worker     return true;
177*f6dc9357SAndroid Build Coastguard Worker   FChar c = s[2];
178*f6dc9357SAndroid Build Coastguard Worker   return (c != '.' && c != '?');
179*f6dc9357SAndroid Build Coastguard Worker }
180*f6dc9357SAndroid Build Coastguard Worker 
GetNetworkServerPrefixSize(CFSTR s)181*f6dc9357SAndroid Build Coastguard Worker unsigned GetNetworkServerPrefixSize(CFSTR s) throw()
182*f6dc9357SAndroid Build Coastguard Worker {
183*f6dc9357SAndroid Build Coastguard Worker   if (!IS_SEPAR(s[0]) || !IS_SEPAR(s[1]))
184*f6dc9357SAndroid Build Coastguard Worker     return 0;
185*f6dc9357SAndroid Build Coastguard Worker   unsigned prefixSize = 2;
186*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperUncPath(s))
187*f6dc9357SAndroid Build Coastguard Worker     prefixSize = kSuperUncPathPrefixSize;
188*f6dc9357SAndroid Build Coastguard Worker   else
189*f6dc9357SAndroid Build Coastguard Worker   {
190*f6dc9357SAndroid Build Coastguard Worker     FChar c = s[2];
191*f6dc9357SAndroid Build Coastguard Worker     if (c == '.' || c == '?')
192*f6dc9357SAndroid Build Coastguard Worker       return 0;
193*f6dc9357SAndroid Build Coastguard Worker   }
194*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindSepar(s + prefixSize);
195*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
196*f6dc9357SAndroid Build Coastguard Worker     return 0;
197*f6dc9357SAndroid Build Coastguard Worker   return prefixSize + (unsigned)(pos + 1);
198*f6dc9357SAndroid Build Coastguard Worker }
199*f6dc9357SAndroid Build Coastguard Worker 
IsNetworkShareRootPath(CFSTR s)200*f6dc9357SAndroid Build Coastguard Worker bool IsNetworkShareRootPath(CFSTR s) throw()
201*f6dc9357SAndroid Build Coastguard Worker {
202*f6dc9357SAndroid Build Coastguard Worker   const unsigned prefixSize = GetNetworkServerPrefixSize(s);
203*f6dc9357SAndroid Build Coastguard Worker   if (prefixSize == 0)
204*f6dc9357SAndroid Build Coastguard Worker     return false;
205*f6dc9357SAndroid Build Coastguard Worker   s += prefixSize;
206*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindSepar(s);
207*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
208*f6dc9357SAndroid Build Coastguard Worker     return true;
209*f6dc9357SAndroid Build Coastguard Worker   return s[(unsigned)pos + 1] == 0;
210*f6dc9357SAndroid Build Coastguard Worker }
211*f6dc9357SAndroid Build Coastguard Worker 
212*f6dc9357SAndroid Build Coastguard Worker static const unsigned kDrivePrefixSize = 3; /* c:\ */
213*f6dc9357SAndroid Build Coastguard Worker 
IsDrivePath2(const wchar_t * s)214*f6dc9357SAndroid Build Coastguard Worker bool IsDrivePath2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
215*f6dc9357SAndroid Build Coastguard Worker // bool IsDriveName2(const wchar_t *s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
IsSuperPath(const wchar_t * s)216*f6dc9357SAndroid Build Coastguard Worker bool IsSuperPath(const wchar_t *s) throw() { return IS_SUPER_PREFIX(s); }
IsSuperOrDevicePath(const wchar_t * s)217*f6dc9357SAndroid Build Coastguard Worker bool IsSuperOrDevicePath(const wchar_t *s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
218*f6dc9357SAndroid Build Coastguard Worker // bool IsSuperUncPath(const wchar_t *s) throw() { return (IS_SUPER_PREFIX(s) && IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize)); }
219*f6dc9357SAndroid Build Coastguard Worker 
IsAltStreamPrefixWithColon(const UString & s)220*f6dc9357SAndroid Build Coastguard Worker bool IsAltStreamPrefixWithColon(const UString &s) throw()
221*f6dc9357SAndroid Build Coastguard Worker {
222*f6dc9357SAndroid Build Coastguard Worker   if (s.IsEmpty())
223*f6dc9357SAndroid Build Coastguard Worker     return false;
224*f6dc9357SAndroid Build Coastguard Worker   if (s.Back() != ':')
225*f6dc9357SAndroid Build Coastguard Worker     return false;
226*f6dc9357SAndroid Build Coastguard Worker   unsigned pos = 0;
227*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(s))
228*f6dc9357SAndroid Build Coastguard Worker     pos = kSuperPathPrefixSize;
229*f6dc9357SAndroid Build Coastguard Worker   if (s.Len() - pos == 2 && IsDrivePath2(s.Ptr(pos)))
230*f6dc9357SAndroid Build Coastguard Worker     return false;
231*f6dc9357SAndroid Build Coastguard Worker   return true;
232*f6dc9357SAndroid Build Coastguard Worker }
233*f6dc9357SAndroid Build Coastguard Worker 
If_IsSuperPath_RemoveSuperPrefix(UString & s)234*f6dc9357SAndroid Build Coastguard Worker bool If_IsSuperPath_RemoveSuperPrefix(UString &s)
235*f6dc9357SAndroid Build Coastguard Worker {
236*f6dc9357SAndroid Build Coastguard Worker   if (!IsSuperPath(s))
237*f6dc9357SAndroid Build Coastguard Worker     return false;
238*f6dc9357SAndroid Build Coastguard Worker   unsigned start = 0;
239*f6dc9357SAndroid Build Coastguard Worker   unsigned count = kSuperPathPrefixSize;
240*f6dc9357SAndroid Build Coastguard Worker   const wchar_t *s2 = s.Ptr(kSuperPathPrefixSize);
241*f6dc9357SAndroid Build Coastguard Worker   if (IS_UNC_WITH_SLASH(s2))
242*f6dc9357SAndroid Build Coastguard Worker   {
243*f6dc9357SAndroid Build Coastguard Worker     start = 2;
244*f6dc9357SAndroid Build Coastguard Worker     count = kSuperUncPathPrefixSize - 2;
245*f6dc9357SAndroid Build Coastguard Worker   }
246*f6dc9357SAndroid Build Coastguard Worker   s.Delete(start, count);
247*f6dc9357SAndroid Build Coastguard Worker   return true;
248*f6dc9357SAndroid Build Coastguard Worker }
249*f6dc9357SAndroid Build Coastguard Worker 
250*f6dc9357SAndroid Build Coastguard Worker 
251*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
IsDrivePath2(CFSTR s)252*f6dc9357SAndroid Build Coastguard Worker bool IsDrivePath2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':'; }
253*f6dc9357SAndroid Build Coastguard Worker // bool IsDriveName2(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && s[2] == 0; }
IsDrivePath(CFSTR s)254*f6dc9357SAndroid Build Coastguard Worker bool IsDrivePath(CFSTR s) throw() { return IS_LETTER_CHAR(s[0]) && s[1] == ':' && IS_SEPAR(s[2]); }
IsSuperPath(CFSTR s)255*f6dc9357SAndroid Build Coastguard Worker bool IsSuperPath(CFSTR s) throw() { return IS_SUPER_PREFIX(s); }
IsSuperOrDevicePath(CFSTR s)256*f6dc9357SAndroid Build Coastguard Worker bool IsSuperOrDevicePath(CFSTR s) throw() { return IS_SUPER_OR_DEVICE_PATH(s); }
257*f6dc9357SAndroid Build Coastguard Worker #endif // USE_UNICODE_FSTRING
258*f6dc9357SAndroid Build Coastguard Worker 
IsDrivePath_SuperAllowed(CFSTR s)259*f6dc9357SAndroid Build Coastguard Worker bool IsDrivePath_SuperAllowed(CFSTR s) throw()
260*f6dc9357SAndroid Build Coastguard Worker {
261*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(s))
262*f6dc9357SAndroid Build Coastguard Worker     s += kSuperPathPrefixSize;
263*f6dc9357SAndroid Build Coastguard Worker   return IsDrivePath(s);
264*f6dc9357SAndroid Build Coastguard Worker }
265*f6dc9357SAndroid Build Coastguard Worker 
IsDriveRootPath_SuperAllowed(CFSTR s)266*f6dc9357SAndroid Build Coastguard Worker bool IsDriveRootPath_SuperAllowed(CFSTR s) throw()
267*f6dc9357SAndroid Build Coastguard Worker {
268*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(s))
269*f6dc9357SAndroid Build Coastguard Worker     s += kSuperPathPrefixSize;
270*f6dc9357SAndroid Build Coastguard Worker   return IsDrivePath(s) && s[kDrivePrefixSize] == 0;
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker 
IsAbsolutePath(const wchar_t * s)273*f6dc9357SAndroid Build Coastguard Worker bool IsAbsolutePath(const wchar_t *s) throw()
274*f6dc9357SAndroid Build Coastguard Worker {
275*f6dc9357SAndroid Build Coastguard Worker   return IS_SEPAR(s[0]) || IsDrivePath2(s);
276*f6dc9357SAndroid Build Coastguard Worker }
277*f6dc9357SAndroid Build Coastguard Worker 
FindAltStreamColon(CFSTR path)278*f6dc9357SAndroid Build Coastguard Worker int FindAltStreamColon(CFSTR path) throw()
279*f6dc9357SAndroid Build Coastguard Worker {
280*f6dc9357SAndroid Build Coastguard Worker   unsigned i = 0;
281*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(path))
282*f6dc9357SAndroid Build Coastguard Worker     i = kSuperPathPrefixSize;
283*f6dc9357SAndroid Build Coastguard Worker   if (IsDrivePath2(path + i))
284*f6dc9357SAndroid Build Coastguard Worker     i += 2;
285*f6dc9357SAndroid Build Coastguard Worker   int colonPos = -1;
286*f6dc9357SAndroid Build Coastguard Worker   for (;; i++)
287*f6dc9357SAndroid Build Coastguard Worker   {
288*f6dc9357SAndroid Build Coastguard Worker     const FChar c = path[i];
289*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
290*f6dc9357SAndroid Build Coastguard Worker       return colonPos;
291*f6dc9357SAndroid Build Coastguard Worker     if (c == ':')
292*f6dc9357SAndroid Build Coastguard Worker     {
293*f6dc9357SAndroid Build Coastguard Worker       if (colonPos < 0)
294*f6dc9357SAndroid Build Coastguard Worker         colonPos = (int)i;
295*f6dc9357SAndroid Build Coastguard Worker       continue;
296*f6dc9357SAndroid Build Coastguard Worker     }
297*f6dc9357SAndroid Build Coastguard Worker     if (IS_SEPAR(c))
298*f6dc9357SAndroid Build Coastguard Worker       colonPos = -1;
299*f6dc9357SAndroid Build Coastguard Worker   }
300*f6dc9357SAndroid Build Coastguard Worker }
301*f6dc9357SAndroid Build Coastguard Worker 
302*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
303*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize_Of_NetworkPath(CFSTR s)304*f6dc9357SAndroid Build Coastguard Worker static unsigned GetRootPrefixSize_Of_NetworkPath(CFSTR s)
305*f6dc9357SAndroid Build Coastguard Worker {
306*f6dc9357SAndroid Build Coastguard Worker   // Network path: we look "server\path\" as root prefix
307*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindSepar(s);
308*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
309*f6dc9357SAndroid Build Coastguard Worker     return 0;
310*f6dc9357SAndroid Build Coastguard Worker   const int pos2 = FindSepar(s + (unsigned)pos + 1);
311*f6dc9357SAndroid Build Coastguard Worker   if (pos2 < 0)
312*f6dc9357SAndroid Build Coastguard Worker     return 0;
313*f6dc9357SAndroid Build Coastguard Worker   return (unsigned)pos + (unsigned)pos2 + 2;
314*f6dc9357SAndroid Build Coastguard Worker }
315*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize_Of_SimplePath(CFSTR s)316*f6dc9357SAndroid Build Coastguard Worker static unsigned GetRootPrefixSize_Of_SimplePath(CFSTR s)
317*f6dc9357SAndroid Build Coastguard Worker {
318*f6dc9357SAndroid Build Coastguard Worker   if (IsDrivePath(s))
319*f6dc9357SAndroid Build Coastguard Worker     return kDrivePrefixSize;
320*f6dc9357SAndroid Build Coastguard Worker   if (!IS_SEPAR(s[0]))
321*f6dc9357SAndroid Build Coastguard Worker     return 0;
322*f6dc9357SAndroid Build Coastguard Worker   if (s[1] == 0 || !IS_SEPAR(s[1]))
323*f6dc9357SAndroid Build Coastguard Worker     return 1;
324*f6dc9357SAndroid Build Coastguard Worker   const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
325*f6dc9357SAndroid Build Coastguard Worker   return (size == 0) ? 0 : 2 + size;
326*f6dc9357SAndroid Build Coastguard Worker }
327*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize_Of_SuperPath(CFSTR s)328*f6dc9357SAndroid Build Coastguard Worker static unsigned GetRootPrefixSize_Of_SuperPath(CFSTR s)
329*f6dc9357SAndroid Build Coastguard Worker {
330*f6dc9357SAndroid Build Coastguard Worker   if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
331*f6dc9357SAndroid Build Coastguard Worker   {
332*f6dc9357SAndroid Build Coastguard Worker     const unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
333*f6dc9357SAndroid Build Coastguard Worker     return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
334*f6dc9357SAndroid Build Coastguard Worker   }
335*f6dc9357SAndroid Build Coastguard Worker   // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
336*f6dc9357SAndroid Build Coastguard Worker   const int pos = FindSepar(s + kSuperPathPrefixSize);
337*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
338*f6dc9357SAndroid Build Coastguard Worker     return 0;
339*f6dc9357SAndroid Build Coastguard Worker   return kSuperPathPrefixSize + (unsigned)pos + 1;
340*f6dc9357SAndroid Build Coastguard Worker }
341*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize(CFSTR s)342*f6dc9357SAndroid Build Coastguard Worker unsigned GetRootPrefixSize(CFSTR s) throw()
343*f6dc9357SAndroid Build Coastguard Worker {
344*f6dc9357SAndroid Build Coastguard Worker   if (IS_DEVICE_PATH(s))
345*f6dc9357SAndroid Build Coastguard Worker     return kDevicePathPrefixSize;
346*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(s))
347*f6dc9357SAndroid Build Coastguard Worker     return GetRootPrefixSize_Of_SuperPath(s);
348*f6dc9357SAndroid Build Coastguard Worker   return GetRootPrefixSize_Of_SimplePath(s);
349*f6dc9357SAndroid Build Coastguard Worker }
350*f6dc9357SAndroid Build Coastguard Worker 
351*f6dc9357SAndroid Build Coastguard Worker #endif // USE_UNICODE_FSTRING
352*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize_Of_NetworkPath(const wchar_t * s)353*f6dc9357SAndroid Build Coastguard Worker static unsigned GetRootPrefixSize_Of_NetworkPath(const wchar_t *s) throw()
354*f6dc9357SAndroid Build Coastguard Worker {
355*f6dc9357SAndroid Build Coastguard Worker   // Network path: we look "server\path\" as root prefix
356*f6dc9357SAndroid Build Coastguard Worker   int pos = FindSepar(s);
357*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
358*f6dc9357SAndroid Build Coastguard Worker     return 0;
359*f6dc9357SAndroid Build Coastguard Worker   int pos2 = FindSepar(s + (unsigned)pos + 1);
360*f6dc9357SAndroid Build Coastguard Worker   if (pos2 < 0)
361*f6dc9357SAndroid Build Coastguard Worker     return 0;
362*f6dc9357SAndroid Build Coastguard Worker   return (unsigned)(pos + pos2 + 2);
363*f6dc9357SAndroid Build Coastguard Worker }
364*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize_Of_SimplePath(const wchar_t * s)365*f6dc9357SAndroid Build Coastguard Worker static unsigned GetRootPrefixSize_Of_SimplePath(const wchar_t *s) throw()
366*f6dc9357SAndroid Build Coastguard Worker {
367*f6dc9357SAndroid Build Coastguard Worker   if (IsDrivePath(s))
368*f6dc9357SAndroid Build Coastguard Worker     return kDrivePrefixSize;
369*f6dc9357SAndroid Build Coastguard Worker   if (!IS_SEPAR(s[0]))
370*f6dc9357SAndroid Build Coastguard Worker     return 0;
371*f6dc9357SAndroid Build Coastguard Worker   if (s[1] == 0 || !IS_SEPAR(s[1]))
372*f6dc9357SAndroid Build Coastguard Worker     return 1;
373*f6dc9357SAndroid Build Coastguard Worker   unsigned size = GetRootPrefixSize_Of_NetworkPath(s + 2);
374*f6dc9357SAndroid Build Coastguard Worker   return (size == 0) ? 0 : 2 + size;
375*f6dc9357SAndroid Build Coastguard Worker }
376*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize_Of_SuperPath(const wchar_t * s)377*f6dc9357SAndroid Build Coastguard Worker static unsigned GetRootPrefixSize_Of_SuperPath(const wchar_t *s) throw()
378*f6dc9357SAndroid Build Coastguard Worker {
379*f6dc9357SAndroid Build Coastguard Worker   if (IS_UNC_WITH_SLASH(s + kSuperPathPrefixSize))
380*f6dc9357SAndroid Build Coastguard Worker   {
381*f6dc9357SAndroid Build Coastguard Worker     unsigned size = GetRootPrefixSize_Of_NetworkPath(s + kSuperUncPathPrefixSize);
382*f6dc9357SAndroid Build Coastguard Worker     return (size == 0) ? 0 : kSuperUncPathPrefixSize + size;
383*f6dc9357SAndroid Build Coastguard Worker   }
384*f6dc9357SAndroid Build Coastguard Worker   // we support \\?\c:\ paths and volume GUID paths \\?\Volume{GUID}\"
385*f6dc9357SAndroid Build Coastguard Worker   int pos = FindSepar(s + kSuperPathPrefixSize);
386*f6dc9357SAndroid Build Coastguard Worker   if (pos < 0)
387*f6dc9357SAndroid Build Coastguard Worker     return 0;
388*f6dc9357SAndroid Build Coastguard Worker   return kSuperPathPrefixSize + (unsigned)(pos + 1);
389*f6dc9357SAndroid Build Coastguard Worker }
390*f6dc9357SAndroid Build Coastguard Worker 
GetRootPrefixSize(const wchar_t * s)391*f6dc9357SAndroid Build Coastguard Worker unsigned GetRootPrefixSize(const wchar_t *s) throw()
392*f6dc9357SAndroid Build Coastguard Worker {
393*f6dc9357SAndroid Build Coastguard Worker   if (IS_DEVICE_PATH(s))
394*f6dc9357SAndroid Build Coastguard Worker     return kDevicePathPrefixSize;
395*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(s))
396*f6dc9357SAndroid Build Coastguard Worker     return GetRootPrefixSize_Of_SuperPath(s);
397*f6dc9357SAndroid Build Coastguard Worker   return GetRootPrefixSize_Of_SimplePath(s);
398*f6dc9357SAndroid Build Coastguard Worker }
399*f6dc9357SAndroid Build Coastguard Worker 
400*f6dc9357SAndroid Build Coastguard Worker #else // _WIN32
401*f6dc9357SAndroid Build Coastguard Worker 
IsAbsolutePath(const wchar_t * s)402*f6dc9357SAndroid Build Coastguard Worker bool IsAbsolutePath(const wchar_t *s) throw() { return IS_SEPAR(s[0]); }
403*f6dc9357SAndroid Build Coastguard Worker 
404*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_UNICODE_FSTRING
405*f6dc9357SAndroid Build Coastguard Worker unsigned GetRootPrefixSize(CFSTR s) throw();
GetRootPrefixSize(CFSTR s)406*f6dc9357SAndroid Build Coastguard Worker unsigned GetRootPrefixSize(CFSTR s) throw() { return IS_SEPAR(s[0]) ? 1 : 0; }
407*f6dc9357SAndroid Build Coastguard Worker #endif
GetRootPrefixSize(const wchar_t * s)408*f6dc9357SAndroid Build Coastguard Worker unsigned GetRootPrefixSize(const wchar_t *s) throw() { return IS_SEPAR(s[0]) ? 1 : 0; }
409*f6dc9357SAndroid Build Coastguard Worker 
410*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
411*f6dc9357SAndroid Build Coastguard Worker 
412*f6dc9357SAndroid Build Coastguard Worker 
413*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
414*f6dc9357SAndroid Build Coastguard Worker 
415*f6dc9357SAndroid Build Coastguard Worker 
416*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_UNICODE_FSTRING
417*f6dc9357SAndroid Build Coastguard Worker 
418*f6dc9357SAndroid Build Coastguard Worker #define GetCurDir NDir::GetCurrentDir
419*f6dc9357SAndroid Build Coastguard Worker 
420*f6dc9357SAndroid Build Coastguard Worker #else
421*f6dc9357SAndroid Build Coastguard Worker 
GetCurDir(UString & path)422*f6dc9357SAndroid Build Coastguard Worker static bool GetCurDir(UString &path)
423*f6dc9357SAndroid Build Coastguard Worker {
424*f6dc9357SAndroid Build Coastguard Worker   path.Empty();
425*f6dc9357SAndroid Build Coastguard Worker   FString s;
426*f6dc9357SAndroid Build Coastguard Worker   if (!NDir::GetCurrentDir(s))
427*f6dc9357SAndroid Build Coastguard Worker     return false;
428*f6dc9357SAndroid Build Coastguard Worker   path = fs2us(s);
429*f6dc9357SAndroid Build Coastguard Worker   return true;
430*f6dc9357SAndroid Build Coastguard Worker }
431*f6dc9357SAndroid Build Coastguard Worker 
432*f6dc9357SAndroid Build Coastguard Worker #endif
433*f6dc9357SAndroid Build Coastguard Worker 
434*f6dc9357SAndroid Build Coastguard Worker 
ResolveDotsFolders(UString & s)435*f6dc9357SAndroid Build Coastguard Worker static bool ResolveDotsFolders(UString &s)
436*f6dc9357SAndroid Build Coastguard Worker {
437*f6dc9357SAndroid Build Coastguard Worker   #ifdef _WIN32
438*f6dc9357SAndroid Build Coastguard Worker   // s.Replace(L'/', WCHAR_PATH_SEPARATOR);
439*f6dc9357SAndroid Build Coastguard Worker   #endif
440*f6dc9357SAndroid Build Coastguard Worker 
441*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0;;)
442*f6dc9357SAndroid Build Coastguard Worker   {
443*f6dc9357SAndroid Build Coastguard Worker     const wchar_t c = s[i];
444*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
445*f6dc9357SAndroid Build Coastguard Worker       return true;
446*f6dc9357SAndroid Build Coastguard Worker     if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
447*f6dc9357SAndroid Build Coastguard Worker     {
448*f6dc9357SAndroid Build Coastguard Worker       const wchar_t c1 = s[i + 1];
449*f6dc9357SAndroid Build Coastguard Worker       if (c1 == '.')
450*f6dc9357SAndroid Build Coastguard Worker       {
451*f6dc9357SAndroid Build Coastguard Worker         const wchar_t c2 = s[i + 2];
452*f6dc9357SAndroid Build Coastguard Worker         if (IS_SEPAR(c2) || c2 == 0)
453*f6dc9357SAndroid Build Coastguard Worker         {
454*f6dc9357SAndroid Build Coastguard Worker           if (i == 0)
455*f6dc9357SAndroid Build Coastguard Worker             return false;
456*f6dc9357SAndroid Build Coastguard Worker           int k = (int)i - 2;
457*f6dc9357SAndroid Build Coastguard Worker           i += 2;
458*f6dc9357SAndroid Build Coastguard Worker 
459*f6dc9357SAndroid Build Coastguard Worker           for (;; k--)
460*f6dc9357SAndroid Build Coastguard Worker           {
461*f6dc9357SAndroid Build Coastguard Worker             if (k < 0)
462*f6dc9357SAndroid Build Coastguard Worker               return false;
463*f6dc9357SAndroid Build Coastguard Worker             if (!IS_SEPAR(s[(unsigned)k]))
464*f6dc9357SAndroid Build Coastguard Worker               break;
465*f6dc9357SAndroid Build Coastguard Worker           }
466*f6dc9357SAndroid Build Coastguard Worker 
467*f6dc9357SAndroid Build Coastguard Worker           do
468*f6dc9357SAndroid Build Coastguard Worker             k--;
469*f6dc9357SAndroid Build Coastguard Worker           while (k >= 0 && !IS_SEPAR(s[(unsigned)k]));
470*f6dc9357SAndroid Build Coastguard Worker 
471*f6dc9357SAndroid Build Coastguard Worker           unsigned num;
472*f6dc9357SAndroid Build Coastguard Worker 
473*f6dc9357SAndroid Build Coastguard Worker           if (k >= 0)
474*f6dc9357SAndroid Build Coastguard Worker           {
475*f6dc9357SAndroid Build Coastguard Worker             num = i - (unsigned)k;
476*f6dc9357SAndroid Build Coastguard Worker             i = (unsigned)k;
477*f6dc9357SAndroid Build Coastguard Worker           }
478*f6dc9357SAndroid Build Coastguard Worker           else
479*f6dc9357SAndroid Build Coastguard Worker           {
480*f6dc9357SAndroid Build Coastguard Worker             num = (c2 == 0 ? i : (i + 1));
481*f6dc9357SAndroid Build Coastguard Worker             i = 0;
482*f6dc9357SAndroid Build Coastguard Worker           }
483*f6dc9357SAndroid Build Coastguard Worker 
484*f6dc9357SAndroid Build Coastguard Worker           s.Delete(i, num);
485*f6dc9357SAndroid Build Coastguard Worker           continue;
486*f6dc9357SAndroid Build Coastguard Worker         }
487*f6dc9357SAndroid Build Coastguard Worker       }
488*f6dc9357SAndroid Build Coastguard Worker       else if (IS_SEPAR(c1) || c1 == 0)
489*f6dc9357SAndroid Build Coastguard Worker       {
490*f6dc9357SAndroid Build Coastguard Worker         unsigned num = 2;
491*f6dc9357SAndroid Build Coastguard Worker         if (i != 0)
492*f6dc9357SAndroid Build Coastguard Worker           i--;
493*f6dc9357SAndroid Build Coastguard Worker         else if (c1 == 0)
494*f6dc9357SAndroid Build Coastguard Worker           num = 1;
495*f6dc9357SAndroid Build Coastguard Worker         s.Delete(i, num);
496*f6dc9357SAndroid Build Coastguard Worker         continue;
497*f6dc9357SAndroid Build Coastguard Worker       }
498*f6dc9357SAndroid Build Coastguard Worker     }
499*f6dc9357SAndroid Build Coastguard Worker 
500*f6dc9357SAndroid Build Coastguard Worker     i++;
501*f6dc9357SAndroid Build Coastguard Worker   }
502*f6dc9357SAndroid Build Coastguard Worker }
503*f6dc9357SAndroid Build Coastguard Worker 
504*f6dc9357SAndroid Build Coastguard Worker #endif // UNDER_CE
505*f6dc9357SAndroid Build Coastguard Worker 
506*f6dc9357SAndroid Build Coastguard Worker #define LONG_PATH_DOTS_FOLDERS_PARSING
507*f6dc9357SAndroid Build Coastguard Worker 
508*f6dc9357SAndroid Build Coastguard Worker 
509*f6dc9357SAndroid Build Coastguard Worker /*
510*f6dc9357SAndroid Build Coastguard Worker Windows (at least 64-bit XP) can't resolve "." or ".." in paths that start with SuperPrefix \\?\
511*f6dc9357SAndroid Build Coastguard Worker To solve that problem we check such path:
512*f6dc9357SAndroid Build Coastguard Worker    - super path contains        "." or ".." - we use kSuperPathType_UseOnlySuper
513*f6dc9357SAndroid Build Coastguard Worker    - super path doesn't contain "." or ".." - we use kSuperPathType_UseOnlyMain
514*f6dc9357SAndroid Build Coastguard Worker */
515*f6dc9357SAndroid Build Coastguard Worker #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
516*f6dc9357SAndroid Build Coastguard Worker #ifndef UNDER_CE
AreThereDotsFolders(CFSTR s)517*f6dc9357SAndroid Build Coastguard Worker static bool AreThereDotsFolders(CFSTR s)
518*f6dc9357SAndroid Build Coastguard Worker {
519*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0;; i++)
520*f6dc9357SAndroid Build Coastguard Worker   {
521*f6dc9357SAndroid Build Coastguard Worker     FChar c = s[i];
522*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
523*f6dc9357SAndroid Build Coastguard Worker       return false;
524*f6dc9357SAndroid Build Coastguard Worker     if (c == '.' && (i == 0 || IS_SEPAR(s[i - 1])))
525*f6dc9357SAndroid Build Coastguard Worker     {
526*f6dc9357SAndroid Build Coastguard Worker       FChar c1 = s[i + 1];
527*f6dc9357SAndroid Build Coastguard Worker       if (c1 == 0 || IS_SEPAR(c1) ||
528*f6dc9357SAndroid Build Coastguard Worker           (c1 == '.' && (s[i + 2] == 0 || IS_SEPAR(s[i + 2]))))
529*f6dc9357SAndroid Build Coastguard Worker         return true;
530*f6dc9357SAndroid Build Coastguard Worker     }
531*f6dc9357SAndroid Build Coastguard Worker   }
532*f6dc9357SAndroid Build Coastguard Worker }
533*f6dc9357SAndroid Build Coastguard Worker #endif
534*f6dc9357SAndroid Build Coastguard Worker #endif // LONG_PATH_DOTS_FOLDERS_PARSING
535*f6dc9357SAndroid Build Coastguard Worker 
536*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_LONG_PATH
537*f6dc9357SAndroid Build Coastguard Worker 
538*f6dc9357SAndroid Build Coastguard Worker /*
539*f6dc9357SAndroid Build Coastguard Worker Most of Windows versions have problems, if some file or dir name
540*f6dc9357SAndroid Build Coastguard Worker contains '.' or ' ' at the end of name (Bad Path).
541*f6dc9357SAndroid Build Coastguard Worker To solve that problem, we always use Super Path ("\\?\" prefix and full path)
542*f6dc9357SAndroid Build Coastguard Worker in such cases. Note that "." and ".." are not bad names.
543*f6dc9357SAndroid Build Coastguard Worker 
544*f6dc9357SAndroid Build Coastguard Worker There are 3 cases:
545*f6dc9357SAndroid Build Coastguard Worker   1) If the path is already Super Path, we use that path
546*f6dc9357SAndroid Build Coastguard Worker   2) If the path is not Super Path :
547*f6dc9357SAndroid Build Coastguard Worker      2.1) Bad Path;  we use only Super Path.
548*f6dc9357SAndroid Build Coastguard Worker      2.2) Good Path; we use Main Path. If it fails, we use Super Path.
549*f6dc9357SAndroid Build Coastguard Worker 
550*f6dc9357SAndroid Build Coastguard Worker  NeedToUseOriginalPath returns:
551*f6dc9357SAndroid Build Coastguard Worker     kSuperPathType_UseOnlyMain    : Super already
552*f6dc9357SAndroid Build Coastguard Worker     kSuperPathType_UseOnlySuper    : not Super, Bad Path
553*f6dc9357SAndroid Build Coastguard Worker     kSuperPathType_UseMainAndSuper : not Super, Good Path
554*f6dc9357SAndroid Build Coastguard Worker */
555*f6dc9357SAndroid Build Coastguard Worker 
GetUseSuperPathType(CFSTR s)556*f6dc9357SAndroid Build Coastguard Worker int GetUseSuperPathType(CFSTR s) throw()
557*f6dc9357SAndroid Build Coastguard Worker {
558*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperOrDevicePath(s))
559*f6dc9357SAndroid Build Coastguard Worker   {
560*f6dc9357SAndroid Build Coastguard Worker     #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
561*f6dc9357SAndroid Build Coastguard Worker     if ((s)[2] != '.')
562*f6dc9357SAndroid Build Coastguard Worker       if (AreThereDotsFolders(s + kSuperPathPrefixSize))
563*f6dc9357SAndroid Build Coastguard Worker         return kSuperPathType_UseOnlySuper;
564*f6dc9357SAndroid Build Coastguard Worker     #endif
565*f6dc9357SAndroid Build Coastguard Worker     return kSuperPathType_UseOnlyMain;
566*f6dc9357SAndroid Build Coastguard Worker   }
567*f6dc9357SAndroid Build Coastguard Worker 
568*f6dc9357SAndroid Build Coastguard Worker   for (unsigned i = 0;; i++)
569*f6dc9357SAndroid Build Coastguard Worker   {
570*f6dc9357SAndroid Build Coastguard Worker     FChar c = s[i];
571*f6dc9357SAndroid Build Coastguard Worker     if (c == 0)
572*f6dc9357SAndroid Build Coastguard Worker       return kSuperPathType_UseMainAndSuper;
573*f6dc9357SAndroid Build Coastguard Worker     if (c == '.' || c == ' ')
574*f6dc9357SAndroid Build Coastguard Worker     {
575*f6dc9357SAndroid Build Coastguard Worker       FChar c2 = s[i + 1];
576*f6dc9357SAndroid Build Coastguard Worker       if (c2 == 0 || IS_SEPAR(c2))
577*f6dc9357SAndroid Build Coastguard Worker       {
578*f6dc9357SAndroid Build Coastguard Worker         // if it's "." or "..", it's not bad name.
579*f6dc9357SAndroid Build Coastguard Worker         if (c == '.')
580*f6dc9357SAndroid Build Coastguard Worker         {
581*f6dc9357SAndroid Build Coastguard Worker           if (i == 0 || IS_SEPAR(s[i - 1]))
582*f6dc9357SAndroid Build Coastguard Worker             continue;
583*f6dc9357SAndroid Build Coastguard Worker           if (s[i - 1] == '.')
584*f6dc9357SAndroid Build Coastguard Worker           {
585*f6dc9357SAndroid Build Coastguard Worker             if (i - 1 == 0 || IS_SEPAR(s[i - 2]))
586*f6dc9357SAndroid Build Coastguard Worker               continue;
587*f6dc9357SAndroid Build Coastguard Worker           }
588*f6dc9357SAndroid Build Coastguard Worker         }
589*f6dc9357SAndroid Build Coastguard Worker         return kSuperPathType_UseOnlySuper;
590*f6dc9357SAndroid Build Coastguard Worker       }
591*f6dc9357SAndroid Build Coastguard Worker     }
592*f6dc9357SAndroid Build Coastguard Worker   }
593*f6dc9357SAndroid Build Coastguard Worker }
594*f6dc9357SAndroid Build Coastguard Worker 
595*f6dc9357SAndroid Build Coastguard Worker 
596*f6dc9357SAndroid Build Coastguard Worker 
597*f6dc9357SAndroid Build Coastguard Worker /*
598*f6dc9357SAndroid Build Coastguard Worker    returns false in two cases:
599*f6dc9357SAndroid Build Coastguard Worker      - if GetCurDir was used, and GetCurDir returned error.
600*f6dc9357SAndroid Build Coastguard Worker      - if we can't resolve ".." name.
601*f6dc9357SAndroid Build Coastguard Worker    if path is ".", "..", res is empty.
602*f6dc9357SAndroid Build Coastguard Worker    if it's Super Path already, res is empty.
603*f6dc9357SAndroid Build Coastguard Worker    for \**** , and if GetCurDir is not drive (c:\), res is empty
604*f6dc9357SAndroid Build Coastguard Worker    for absolute paths, returns true, res is Super path.
605*f6dc9357SAndroid Build Coastguard Worker */
606*f6dc9357SAndroid Build Coastguard Worker 
GetSuperPathBase(CFSTR s,UString & res)607*f6dc9357SAndroid Build Coastguard Worker static bool GetSuperPathBase(CFSTR s, UString &res)
608*f6dc9357SAndroid Build Coastguard Worker {
609*f6dc9357SAndroid Build Coastguard Worker   res.Empty();
610*f6dc9357SAndroid Build Coastguard Worker 
611*f6dc9357SAndroid Build Coastguard Worker   FChar c = s[0];
612*f6dc9357SAndroid Build Coastguard Worker   if (c == 0)
613*f6dc9357SAndroid Build Coastguard Worker     return true;
614*f6dc9357SAndroid Build Coastguard Worker   if (c == '.' && (s[1] == 0 || (s[1] == '.' && s[2] == 0)))
615*f6dc9357SAndroid Build Coastguard Worker     return true;
616*f6dc9357SAndroid Build Coastguard Worker 
617*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperOrDevicePath(s))
618*f6dc9357SAndroid Build Coastguard Worker   {
619*f6dc9357SAndroid Build Coastguard Worker     #ifdef LONG_PATH_DOTS_FOLDERS_PARSING
620*f6dc9357SAndroid Build Coastguard Worker 
621*f6dc9357SAndroid Build Coastguard Worker     if ((s)[2] == '.')
622*f6dc9357SAndroid Build Coastguard Worker       return true;
623*f6dc9357SAndroid Build Coastguard Worker 
624*f6dc9357SAndroid Build Coastguard Worker     // we will return true here, so we will try to use these problem paths.
625*f6dc9357SAndroid Build Coastguard Worker 
626*f6dc9357SAndroid Build Coastguard Worker     if (!AreThereDotsFolders(s + kSuperPathPrefixSize))
627*f6dc9357SAndroid Build Coastguard Worker       return true;
628*f6dc9357SAndroid Build Coastguard Worker 
629*f6dc9357SAndroid Build Coastguard Worker     UString temp = fs2us(s);
630*f6dc9357SAndroid Build Coastguard Worker     const unsigned fixedSize = GetRootPrefixSize_Of_SuperPath(temp);
631*f6dc9357SAndroid Build Coastguard Worker     if (fixedSize == 0)
632*f6dc9357SAndroid Build Coastguard Worker       return true;
633*f6dc9357SAndroid Build Coastguard Worker 
634*f6dc9357SAndroid Build Coastguard Worker     UString rem = temp.Ptr(fixedSize);
635*f6dc9357SAndroid Build Coastguard Worker     if (!ResolveDotsFolders(rem))
636*f6dc9357SAndroid Build Coastguard Worker       return true;
637*f6dc9357SAndroid Build Coastguard Worker 
638*f6dc9357SAndroid Build Coastguard Worker     temp.DeleteFrom(fixedSize);
639*f6dc9357SAndroid Build Coastguard Worker     res += temp;
640*f6dc9357SAndroid Build Coastguard Worker     res += rem;
641*f6dc9357SAndroid Build Coastguard Worker 
642*f6dc9357SAndroid Build Coastguard Worker     #endif
643*f6dc9357SAndroid Build Coastguard Worker 
644*f6dc9357SAndroid Build Coastguard Worker     return true;
645*f6dc9357SAndroid Build Coastguard Worker   }
646*f6dc9357SAndroid Build Coastguard Worker 
647*f6dc9357SAndroid Build Coastguard Worker   if (IS_SEPAR(c))
648*f6dc9357SAndroid Build Coastguard Worker   {
649*f6dc9357SAndroid Build Coastguard Worker     if (IS_SEPAR(s[1]))
650*f6dc9357SAndroid Build Coastguard Worker     {
651*f6dc9357SAndroid Build Coastguard Worker       UString temp = fs2us(s + 2);
652*f6dc9357SAndroid Build Coastguard Worker       const unsigned fixedSize = GetRootPrefixSize_Of_NetworkPath(temp);
653*f6dc9357SAndroid Build Coastguard Worker       // we ignore that error to allow short network paths server\share?
654*f6dc9357SAndroid Build Coastguard Worker       /*
655*f6dc9357SAndroid Build Coastguard Worker       if (fixedSize == 0)
656*f6dc9357SAndroid Build Coastguard Worker         return false;
657*f6dc9357SAndroid Build Coastguard Worker       */
658*f6dc9357SAndroid Build Coastguard Worker       UString rem = temp.Ptr(fixedSize);
659*f6dc9357SAndroid Build Coastguard Worker       if (!ResolveDotsFolders(rem))
660*f6dc9357SAndroid Build Coastguard Worker         return false;
661*f6dc9357SAndroid Build Coastguard Worker       res += kSuperUncPrefix;
662*f6dc9357SAndroid Build Coastguard Worker       temp.DeleteFrom(fixedSize);
663*f6dc9357SAndroid Build Coastguard Worker       res += temp;
664*f6dc9357SAndroid Build Coastguard Worker       res += rem;
665*f6dc9357SAndroid Build Coastguard Worker       return true;
666*f6dc9357SAndroid Build Coastguard Worker     }
667*f6dc9357SAndroid Build Coastguard Worker   }
668*f6dc9357SAndroid Build Coastguard Worker   else
669*f6dc9357SAndroid Build Coastguard Worker   {
670*f6dc9357SAndroid Build Coastguard Worker     if (IsDrivePath2(s))
671*f6dc9357SAndroid Build Coastguard Worker     {
672*f6dc9357SAndroid Build Coastguard Worker       UString temp = fs2us(s);
673*f6dc9357SAndroid Build Coastguard Worker       unsigned prefixSize = 2;
674*f6dc9357SAndroid Build Coastguard Worker       if (IsDrivePath(s))
675*f6dc9357SAndroid Build Coastguard Worker         prefixSize = kDrivePrefixSize;
676*f6dc9357SAndroid Build Coastguard Worker       UString rem = temp.Ptr(prefixSize);
677*f6dc9357SAndroid Build Coastguard Worker       if (!ResolveDotsFolders(rem))
678*f6dc9357SAndroid Build Coastguard Worker         return true;
679*f6dc9357SAndroid Build Coastguard Worker       res += kSuperPathPrefix;
680*f6dc9357SAndroid Build Coastguard Worker       temp.DeleteFrom(prefixSize);
681*f6dc9357SAndroid Build Coastguard Worker       res += temp;
682*f6dc9357SAndroid Build Coastguard Worker       res += rem;
683*f6dc9357SAndroid Build Coastguard Worker       return true;
684*f6dc9357SAndroid Build Coastguard Worker     }
685*f6dc9357SAndroid Build Coastguard Worker   }
686*f6dc9357SAndroid Build Coastguard Worker 
687*f6dc9357SAndroid Build Coastguard Worker   UString curDir;
688*f6dc9357SAndroid Build Coastguard Worker   if (!GetCurDir(curDir))
689*f6dc9357SAndroid Build Coastguard Worker     return false;
690*f6dc9357SAndroid Build Coastguard Worker   NormalizeDirPathPrefix(curDir);
691*f6dc9357SAndroid Build Coastguard Worker 
692*f6dc9357SAndroid Build Coastguard Worker   unsigned fixedSizeStart = 0;
693*f6dc9357SAndroid Build Coastguard Worker   unsigned fixedSize = 0;
694*f6dc9357SAndroid Build Coastguard Worker   const char *superMarker = NULL;
695*f6dc9357SAndroid Build Coastguard Worker   if (IsSuperPath(curDir))
696*f6dc9357SAndroid Build Coastguard Worker   {
697*f6dc9357SAndroid Build Coastguard Worker     fixedSize = GetRootPrefixSize_Of_SuperPath(curDir);
698*f6dc9357SAndroid Build Coastguard Worker     if (fixedSize == 0)
699*f6dc9357SAndroid Build Coastguard Worker       return false;
700*f6dc9357SAndroid Build Coastguard Worker   }
701*f6dc9357SAndroid Build Coastguard Worker   else
702*f6dc9357SAndroid Build Coastguard Worker   {
703*f6dc9357SAndroid Build Coastguard Worker     if (IsDrivePath(curDir))
704*f6dc9357SAndroid Build Coastguard Worker     {
705*f6dc9357SAndroid Build Coastguard Worker       superMarker = kSuperPathPrefix;
706*f6dc9357SAndroid Build Coastguard Worker       fixedSize = kDrivePrefixSize;
707*f6dc9357SAndroid Build Coastguard Worker     }
708*f6dc9357SAndroid Build Coastguard Worker     else
709*f6dc9357SAndroid Build Coastguard Worker     {
710*f6dc9357SAndroid Build Coastguard Worker       if (!IsPathSepar(curDir[0]) || !IsPathSepar(curDir[1]))
711*f6dc9357SAndroid Build Coastguard Worker         return false;
712*f6dc9357SAndroid Build Coastguard Worker       fixedSizeStart = 2;
713*f6dc9357SAndroid Build Coastguard Worker       fixedSize = GetRootPrefixSize_Of_NetworkPath(curDir.Ptr(2));
714*f6dc9357SAndroid Build Coastguard Worker       if (fixedSize == 0)
715*f6dc9357SAndroid Build Coastguard Worker         return false;
716*f6dc9357SAndroid Build Coastguard Worker       superMarker = kSuperUncPrefix;
717*f6dc9357SAndroid Build Coastguard Worker     }
718*f6dc9357SAndroid Build Coastguard Worker   }
719*f6dc9357SAndroid Build Coastguard Worker 
720*f6dc9357SAndroid Build Coastguard Worker   UString temp;
721*f6dc9357SAndroid Build Coastguard Worker   if (IS_SEPAR(c))
722*f6dc9357SAndroid Build Coastguard Worker   {
723*f6dc9357SAndroid Build Coastguard Worker     temp = fs2us(s + 1);
724*f6dc9357SAndroid Build Coastguard Worker   }
725*f6dc9357SAndroid Build Coastguard Worker   else
726*f6dc9357SAndroid Build Coastguard Worker   {
727*f6dc9357SAndroid Build Coastguard Worker     temp += &curDir[fixedSizeStart + fixedSize];
728*f6dc9357SAndroid Build Coastguard Worker     temp += fs2us(s);
729*f6dc9357SAndroid Build Coastguard Worker   }
730*f6dc9357SAndroid Build Coastguard Worker   if (!ResolveDotsFolders(temp))
731*f6dc9357SAndroid Build Coastguard Worker     return false;
732*f6dc9357SAndroid Build Coastguard Worker   if (superMarker)
733*f6dc9357SAndroid Build Coastguard Worker     res += superMarker;
734*f6dc9357SAndroid Build Coastguard Worker   res += curDir.Mid(fixedSizeStart, fixedSize);
735*f6dc9357SAndroid Build Coastguard Worker   res += temp;
736*f6dc9357SAndroid Build Coastguard Worker   return true;
737*f6dc9357SAndroid Build Coastguard Worker }
738*f6dc9357SAndroid Build Coastguard Worker 
739*f6dc9357SAndroid Build Coastguard Worker 
740*f6dc9357SAndroid Build Coastguard Worker /*
741*f6dc9357SAndroid Build Coastguard Worker   In that case if GetSuperPathBase doesn't return new path, we don't need
742*f6dc9357SAndroid Build Coastguard Worker   to use same path that was used as main path
743*f6dc9357SAndroid Build Coastguard Worker 
744*f6dc9357SAndroid Build Coastguard Worker   GetSuperPathBase  superPath.IsEmpty() onlyIfNew
745*f6dc9357SAndroid Build Coastguard Worker      false            *                *          GetCurDir Error
746*f6dc9357SAndroid Build Coastguard Worker      true            false             *          use Super path
747*f6dc9357SAndroid Build Coastguard Worker      true            true             true        don't use any path, we already used mainPath
748*f6dc9357SAndroid Build Coastguard Worker      true            true             false       use main path as Super Path, we don't try mainMath
749*f6dc9357SAndroid Build Coastguard Worker                                                   That case is possible now if GetCurDir returns unknown
750*f6dc9357SAndroid Build Coastguard Worker                                                   type of path (not drive and not network)
751*f6dc9357SAndroid Build Coastguard Worker 
752*f6dc9357SAndroid Build Coastguard Worker   We can change that code if we want to try mainPath, if GetSuperPathBase returns error,
753*f6dc9357SAndroid Build Coastguard Worker   and we didn't try mainPath still.
754*f6dc9357SAndroid Build Coastguard Worker   If we want to work that way, we don't need to use GetSuperPathBase return code.
755*f6dc9357SAndroid Build Coastguard Worker */
756*f6dc9357SAndroid Build Coastguard Worker 
GetSuperPath(CFSTR path,UString & superPath,bool onlyIfNew)757*f6dc9357SAndroid Build Coastguard Worker bool GetSuperPath(CFSTR path, UString &superPath, bool onlyIfNew)
758*f6dc9357SAndroid Build Coastguard Worker {
759*f6dc9357SAndroid Build Coastguard Worker   if (GetSuperPathBase(path, superPath))
760*f6dc9357SAndroid Build Coastguard Worker   {
761*f6dc9357SAndroid Build Coastguard Worker     if (superPath.IsEmpty())
762*f6dc9357SAndroid Build Coastguard Worker     {
763*f6dc9357SAndroid Build Coastguard Worker       // actually the only possible when onlyIfNew == true and superPath is empty
764*f6dc9357SAndroid Build Coastguard Worker       // is case when
765*f6dc9357SAndroid Build Coastguard Worker 
766*f6dc9357SAndroid Build Coastguard Worker       if (onlyIfNew)
767*f6dc9357SAndroid Build Coastguard Worker         return false;
768*f6dc9357SAndroid Build Coastguard Worker       superPath = fs2us(path);
769*f6dc9357SAndroid Build Coastguard Worker     }
770*f6dc9357SAndroid Build Coastguard Worker 
771*f6dc9357SAndroid Build Coastguard Worker     NormalizeDirSeparators(superPath);
772*f6dc9357SAndroid Build Coastguard Worker     return true;
773*f6dc9357SAndroid Build Coastguard Worker   }
774*f6dc9357SAndroid Build Coastguard Worker   return false;
775*f6dc9357SAndroid Build Coastguard Worker }
776*f6dc9357SAndroid Build Coastguard Worker 
GetSuperPaths(CFSTR s1,CFSTR s2,UString & d1,UString & d2,bool onlyIfNew)777*f6dc9357SAndroid Build Coastguard Worker bool GetSuperPaths(CFSTR s1, CFSTR s2, UString &d1, UString &d2, bool onlyIfNew)
778*f6dc9357SAndroid Build Coastguard Worker {
779*f6dc9357SAndroid Build Coastguard Worker   if (!GetSuperPathBase(s1, d1) ||
780*f6dc9357SAndroid Build Coastguard Worker       !GetSuperPathBase(s2, d2))
781*f6dc9357SAndroid Build Coastguard Worker     return false;
782*f6dc9357SAndroid Build Coastguard Worker 
783*f6dc9357SAndroid Build Coastguard Worker   NormalizeDirSeparators(d1);
784*f6dc9357SAndroid Build Coastguard Worker   NormalizeDirSeparators(d2);
785*f6dc9357SAndroid Build Coastguard Worker 
786*f6dc9357SAndroid Build Coastguard Worker   if (d1.IsEmpty() && d2.IsEmpty() && onlyIfNew)
787*f6dc9357SAndroid Build Coastguard Worker     return false;
788*f6dc9357SAndroid Build Coastguard Worker   if (d1.IsEmpty()) d1 = fs2us(s1);
789*f6dc9357SAndroid Build Coastguard Worker   if (d2.IsEmpty()) d2 = fs2us(s2);
790*f6dc9357SAndroid Build Coastguard Worker   return true;
791*f6dc9357SAndroid Build Coastguard Worker }
792*f6dc9357SAndroid Build Coastguard Worker 
793*f6dc9357SAndroid Build Coastguard Worker 
794*f6dc9357SAndroid Build Coastguard Worker /*
795*f6dc9357SAndroid Build Coastguard Worker // returns true, if we need additional use with New Super path.
796*f6dc9357SAndroid Build Coastguard Worker bool GetSuperPath(CFSTR path, UString &superPath)
797*f6dc9357SAndroid Build Coastguard Worker {
798*f6dc9357SAndroid Build Coastguard Worker   if (GetSuperPathBase(path, superPath))
799*f6dc9357SAndroid Build Coastguard Worker     return !superPath.IsEmpty();
800*f6dc9357SAndroid Build Coastguard Worker   return false;
801*f6dc9357SAndroid Build Coastguard Worker }
802*f6dc9357SAndroid Build Coastguard Worker */
803*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_LONG_PATH
804*f6dc9357SAndroid Build Coastguard Worker 
GetFullPath(CFSTR dirPrefix,CFSTR s,FString & res)805*f6dc9357SAndroid Build Coastguard Worker bool GetFullPath(CFSTR dirPrefix, CFSTR s, FString &res)
806*f6dc9357SAndroid Build Coastguard Worker {
807*f6dc9357SAndroid Build Coastguard Worker   res = s;
808*f6dc9357SAndroid Build Coastguard Worker 
809*f6dc9357SAndroid Build Coastguard Worker   #ifdef UNDER_CE
810*f6dc9357SAndroid Build Coastguard Worker 
811*f6dc9357SAndroid Build Coastguard Worker   if (!IS_SEPAR(s[0]))
812*f6dc9357SAndroid Build Coastguard Worker   {
813*f6dc9357SAndroid Build Coastguard Worker     if (!dirPrefix)
814*f6dc9357SAndroid Build Coastguard Worker       return false;
815*f6dc9357SAndroid Build Coastguard Worker     res = dirPrefix;
816*f6dc9357SAndroid Build Coastguard Worker     res += s;
817*f6dc9357SAndroid Build Coastguard Worker   }
818*f6dc9357SAndroid Build Coastguard Worker 
819*f6dc9357SAndroid Build Coastguard Worker   #else
820*f6dc9357SAndroid Build Coastguard Worker 
821*f6dc9357SAndroid Build Coastguard Worker   const unsigned prefixSize = GetRootPrefixSize(s);
822*f6dc9357SAndroid Build Coastguard Worker   if (prefixSize != 0)
823*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
824*f6dc9357SAndroid Build Coastguard Worker   if (prefixSize != 1)
825*f6dc9357SAndroid Build Coastguard Worker #endif
826*f6dc9357SAndroid Build Coastguard Worker   {
827*f6dc9357SAndroid Build Coastguard Worker     if (!AreThereDotsFolders(s + prefixSize))
828*f6dc9357SAndroid Build Coastguard Worker       return true;
829*f6dc9357SAndroid Build Coastguard Worker 
830*f6dc9357SAndroid Build Coastguard Worker     UString rem = fs2us(s + prefixSize);
831*f6dc9357SAndroid Build Coastguard Worker     if (!ResolveDotsFolders(rem))
832*f6dc9357SAndroid Build Coastguard Worker       return true; // maybe false;
833*f6dc9357SAndroid Build Coastguard Worker     res.DeleteFrom(prefixSize);
834*f6dc9357SAndroid Build Coastguard Worker     res += us2fs(rem);
835*f6dc9357SAndroid Build Coastguard Worker     return true;
836*f6dc9357SAndroid Build Coastguard Worker   }
837*f6dc9357SAndroid Build Coastguard Worker 
838*f6dc9357SAndroid Build Coastguard Worker   UString curDir;
839*f6dc9357SAndroid Build Coastguard Worker   if (dirPrefix && prefixSize == 0)
840*f6dc9357SAndroid Build Coastguard Worker     curDir = fs2us(dirPrefix);  // we use (dirPrefix), only if (s) path is relative
841*f6dc9357SAndroid Build Coastguard Worker   else
842*f6dc9357SAndroid Build Coastguard Worker   {
843*f6dc9357SAndroid Build Coastguard Worker     if (!GetCurDir(curDir))
844*f6dc9357SAndroid Build Coastguard Worker       return false;
845*f6dc9357SAndroid Build Coastguard Worker   }
846*f6dc9357SAndroid Build Coastguard Worker   NormalizeDirPathPrefix(curDir);
847*f6dc9357SAndroid Build Coastguard Worker 
848*f6dc9357SAndroid Build Coastguard Worker   unsigned fixedSize = GetRootPrefixSize(curDir);
849*f6dc9357SAndroid Build Coastguard Worker 
850*f6dc9357SAndroid Build Coastguard Worker   UString temp;
851*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
852*f6dc9357SAndroid Build Coastguard Worker   if (prefixSize != 0)
853*f6dc9357SAndroid Build Coastguard Worker   {
854*f6dc9357SAndroid Build Coastguard Worker     /* (s) is absolute path, but only (prefixSize == 1) is possible here.
855*f6dc9357SAndroid Build Coastguard Worker        So for full resolving we need root of current folder and
856*f6dc9357SAndroid Build Coastguard Worker        relative part of (s). */
857*f6dc9357SAndroid Build Coastguard Worker     s += prefixSize;
858*f6dc9357SAndroid Build Coastguard Worker     // (s) is relative part now
859*f6dc9357SAndroid Build Coastguard Worker     if (fixedSize == 0)
860*f6dc9357SAndroid Build Coastguard Worker     {
861*f6dc9357SAndroid Build Coastguard Worker       // (curDir) is not absolute.
862*f6dc9357SAndroid Build Coastguard Worker       // That case is unexpected, but we support it too.
863*f6dc9357SAndroid Build Coastguard Worker       curDir.Empty();
864*f6dc9357SAndroid Build Coastguard Worker       curDir.Add_PathSepar();
865*f6dc9357SAndroid Build Coastguard Worker       fixedSize = 1;
866*f6dc9357SAndroid Build Coastguard Worker       // (curDir) now is just Separ character.
867*f6dc9357SAndroid Build Coastguard Worker       // So final (res) path later also will have Separ prefix.
868*f6dc9357SAndroid Build Coastguard Worker     }
869*f6dc9357SAndroid Build Coastguard Worker   }
870*f6dc9357SAndroid Build Coastguard Worker   else
871*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
872*f6dc9357SAndroid Build Coastguard Worker   {
873*f6dc9357SAndroid Build Coastguard Worker     // (s) is relative path
874*f6dc9357SAndroid Build Coastguard Worker     temp = curDir.Ptr(fixedSize);
875*f6dc9357SAndroid Build Coastguard Worker     // (temp) is relative_part_of(curDir)
876*f6dc9357SAndroid Build Coastguard Worker   }
877*f6dc9357SAndroid Build Coastguard Worker   temp += fs2us(s);
878*f6dc9357SAndroid Build Coastguard Worker   if (!ResolveDotsFolders(temp))
879*f6dc9357SAndroid Build Coastguard Worker     return false;
880*f6dc9357SAndroid Build Coastguard Worker   curDir.DeleteFrom(fixedSize);
881*f6dc9357SAndroid Build Coastguard Worker   // (curDir) now contains only absolute prefix part
882*f6dc9357SAndroid Build Coastguard Worker   res = us2fs(curDir);
883*f6dc9357SAndroid Build Coastguard Worker   res += us2fs(temp);
884*f6dc9357SAndroid Build Coastguard Worker 
885*f6dc9357SAndroid Build Coastguard Worker   #endif // UNDER_CE
886*f6dc9357SAndroid Build Coastguard Worker 
887*f6dc9357SAndroid Build Coastguard Worker   return true;
888*f6dc9357SAndroid Build Coastguard Worker }
889*f6dc9357SAndroid Build Coastguard Worker 
890*f6dc9357SAndroid Build Coastguard Worker 
GetFullPath(CFSTR path,FString & fullPath)891*f6dc9357SAndroid Build Coastguard Worker bool GetFullPath(CFSTR path, FString &fullPath)
892*f6dc9357SAndroid Build Coastguard Worker {
893*f6dc9357SAndroid Build Coastguard Worker   return GetFullPath(NULL, path, fullPath);
894*f6dc9357SAndroid Build Coastguard Worker }
895*f6dc9357SAndroid Build Coastguard Worker 
896*f6dc9357SAndroid Build Coastguard Worker }}}
897