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