1baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// Windows/FileDir.cpp
2baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
3baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "StdAfx.h"
4baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
5baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
6baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "../Common/StringConvert.h"
7baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
8baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
9baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "FileDir.h"
10baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "FileFind.h"
11baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#include "FileName.h"
12baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
13baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
14baa3858d3f5d128a5c8466b700098109edcad5f2repo syncextern bool g_IsNT;
15baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
16baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
17baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NWindows {
18baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NFile {
19baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
20baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#if defined(WIN_LONG_PATH) && defined(_UNICODE)
21baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#define WIN_LONG_PATH2
22baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
23baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
24baa3858d3f5d128a5c8466b700098109edcad5f2repo sync// SetCurrentDirectory doesn't support \\?\ prefix
25baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
26baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef WIN_LONG_PATH
27baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetLongPathBase(LPCWSTR fileName, UString &res);
28baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetLongPath(LPCWSTR fileName, UString &res);
29baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
30baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
31baa3858d3f5d128a5c8466b700098109edcad5f2repo syncnamespace NDirectory {
32baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
33baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
34baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic inline UINT GetCurrentCodePage() { return ::AreFileApisANSI() ? CP_ACP : CP_OEMCP; }
35baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UString GetUnicodePath(const CSysString &sysPath)
36baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { return MultiByteToUnicodeString(sysPath, GetCurrentCodePage()); }
37baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic CSysString GetSysPath(LPCWSTR sysPath)
38baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  { return UnicodeStringToMultiByte(sysPath, GetCurrentCodePage()); }
39baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
40baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
41baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef UNDER_CE
42baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
43baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetWindowsDirectory(CSysString &path)
44baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
45baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UINT needLength = ::GetWindowsDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
46baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path.ReleaseBuffer();
47baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (needLength > 0 && needLength <= MAX_PATH);
48baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
49baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
50baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetSystemDirectory(CSysString &path)
51baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
52baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UINT needLength = ::GetSystemDirectory(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
53baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path.ReleaseBuffer();
54baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (needLength > 0 && needLength <= MAX_PATH);
55baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
56baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
57baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
58baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
59baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
60baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetWindowsDirectory(UString &path)
61baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
62baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
63baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
64baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UINT needLength = ::GetWindowsDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
65baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    path.ReleaseBuffer();
66baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return (needLength > 0 && needLength <= MAX_PATH);
67baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
68baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString sysPath;
69baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetWindowsDirectory(sysPath))
70baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
71baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path = GetUnicodePath(sysPath);
72baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
73baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
74baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
75baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetSystemDirectory(UString &path)
76baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
77baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
78baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
79baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UINT needLength = ::GetSystemDirectoryW(path.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
80baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    path.ReleaseBuffer();
81baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return (needLength > 0 && needLength <= MAX_PATH);
82baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
83baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString sysPath;
84baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetSystemDirectory(sysPath))
85baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
86baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path = GetUnicodePath(sysPath);
87baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
88baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
89baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
90baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
91baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
92baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
93baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifndef _UNICODE
94baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!g_IsNT)
95baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
96baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ::SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
97baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
98baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
99baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
100baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  HANDLE hDir = ::CreateFileW(fileName, GENERIC_WRITE,
101baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      FILE_SHARE_READ | FILE_SHARE_WRITE,
102baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
103baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH
104baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (hDir == INVALID_HANDLE_VALUE)
105baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
106baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString longPath;
107baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (GetLongPath(fileName, longPath))
108baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      hDir = ::CreateFileW(longPath, GENERIC_WRITE,
109baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        FILE_SHARE_READ | FILE_SHARE_WRITE,
110baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL);
111baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
112baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
113baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
114baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  bool res = false;
115baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (hDir != INVALID_HANDLE_VALUE)
116baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
117baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime));
118baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    ::CloseHandle(hDir);
119baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
120baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return res;
121baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
122baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
123baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MySetFileAttributes(LPCTSTR fileName, DWORD fileAttributes)
124baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
125baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::SetFileAttributes(fileName, fileAttributes))
126baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
127baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH2
128baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString longPath;
129baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPath(fileName, longPath))
130baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
131baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
132baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
133baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
134baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
135baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyRemoveDirectory(LPCTSTR pathName)
136baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
137baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::RemoveDirectory(pathName))
138baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
139baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH2
140baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString longPath;
141baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPath(pathName, longPath))
142baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::RemoveDirectoryW(longPath));
143baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
144baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
145baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
146baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
147baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef WIN_LONG_PATH
148baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetLongPaths(LPCWSTR s1, LPCWSTR s2, UString &d1, UString &d2)
149baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
150baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!GetLongPathBase(s1, d1) || !GetLongPathBase(s2, d2))
151baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
152baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (d1.IsEmpty() && d2.IsEmpty()) return false;
153baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (d1.IsEmpty()) d1 = s1;
154baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (d2.IsEmpty()) d2 = s2;
155baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
156baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
157baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
158baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
159baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyMoveFile(LPCTSTR existFileName, LPCTSTR newFileName)
160baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
161baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::MoveFile(existFileName, newFileName))
162baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
163baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH2
164baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString d1, d2;
165baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPaths(existFileName, newFileName, d1, d2))
166baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::MoveFileW(d1, d2));
167baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
168baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
169baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
170baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
171baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
172baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MySetFileAttributes(LPCWSTR fileName, DWORD fileAttributes)
173baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
174baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!g_IsNT)
175baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return MySetFileAttributes(GetSysPath(fileName), fileAttributes);
176baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::SetFileAttributesW(fileName, fileAttributes))
177baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
178baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH
179baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString longPath;
180baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPath(fileName, longPath))
181baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::SetFileAttributesW(longPath, fileAttributes));
182baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
183baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
184baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
185baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
186baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
187baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyRemoveDirectory(LPCWSTR pathName)
188baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
189baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!g_IsNT)
190baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return MyRemoveDirectory(GetSysPath(pathName));
191baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::RemoveDirectoryW(pathName))
192baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
193baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH
194baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString longPath;
195baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPath(pathName, longPath))
196baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::RemoveDirectoryW(longPath));
197baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
198baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
199baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
200baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
201baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyMoveFile(LPCWSTR existFileName, LPCWSTR newFileName)
202baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
203baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!g_IsNT)
204baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return MyMoveFile(GetSysPath(existFileName), GetSysPath(newFileName));
205baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::MoveFileW(existFileName, newFileName))
206baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
207baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH
208baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString d1, d2;
209baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPaths(existFileName, newFileName, d1, d2))
210baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::MoveFileW(d1, d2));
211baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
212baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
213baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
214baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
215baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
216baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyCreateDirectory(LPCTSTR pathName)
217baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
218baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::CreateDirectory(pathName, NULL))
219baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
220baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH2
221baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::GetLastError() != ERROR_ALREADY_EXISTS)
222baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
223baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString longPath;
224baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (GetLongPath(pathName, longPath))
225baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return BOOLToBool(::CreateDirectoryW(longPath, NULL));
226baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
227baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
228baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
229baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
230baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
231baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
232baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyCreateDirectory(LPCWSTR pathName)
233baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
234baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!g_IsNT)
235baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return MyCreateDirectory(GetSysPath(pathName));
236baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::CreateDirectoryW(pathName, NULL))
237baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
238baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH
239baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::GetLastError() != ERROR_ALREADY_EXISTS)
240baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
241baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString longPath;
242baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (GetLongPath(pathName, longPath))
243baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return BOOLToBool(::CreateDirectoryW(longPath, NULL));
244baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
245baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
246baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
247baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
248baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
249baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
250baa3858d3f5d128a5c8466b700098109edcad5f2repo sync/*
251baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CreateComplexDirectory(LPCTSTR pathName)
252baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
253baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NName::CParsedPath path;
254baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path.ParsePath(pathName);
255baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString fullPath = path.Prefix;
256baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  DWORD errorCode = ERROR_SUCCESS;
257baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (int i = 0; i < path.PathParts.Size(); i++)
258baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
259baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    const CSysString &string = path.PathParts[i];
260baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (string.IsEmpty())
261baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
262baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (i != path.PathParts.Size() - 1)
263baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
264baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return true;
265baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
266baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fullPath += path.PathParts[i];
267baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!MyCreateDirectory(fullPath))
268baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
269baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      DWORD errorCode = GetLastError();
270baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (errorCode != ERROR_ALREADY_EXISTS)
271baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
272baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
273baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fullPath += NName::kDirDelimiter;
274baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
275baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
276baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
277baa3858d3f5d128a5c8466b700098109edcad5f2repo sync*/
278baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
279baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CreateComplexDirectory(LPCTSTR _aPathName)
280baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
281baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString pathName = _aPathName;
282baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
283baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (pos > 0 && pos == pathName.Length() - 1)
284baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
285baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pathName.Length() == 3 && pathName[1] == ':')
286baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return true; // Disk folder;
287baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pathName.Delete(pos);
288baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
289baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString pathName2 = pathName;
290baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pos = pathName.Length();
291baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
292baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
293baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (MyCreateDirectory(pathName))
294baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
295baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (::GetLastError() == ERROR_ALREADY_EXISTS)
296baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
297baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NFind::CFileInfo fileInfo;
298baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!fileInfo.Find(pathName)) // For network folders
299baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return true;
300baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!fileInfo.IsDir())
301baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
302baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
303baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
304baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pos = pathName.ReverseFind(TEXT(CHAR_PATH_SEPARATOR));
305baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pos < 0 || pos == 0)
306baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
307baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pathName[pos - 1] == ':')
308baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
309baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pathName = pathName.Left(pos);
310baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
311baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pathName = pathName2;
312baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (pos < pathName.Length())
313baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
314baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pos = pathName.Find(TEXT(CHAR_PATH_SEPARATOR), pos + 1);
315baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pos < 0)
316baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      pos = pathName.Length();
317baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!MyCreateDirectory(pathName.Left(pos)))
318baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
319baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
320baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
321baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
322baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
323baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
324baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
325baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CreateComplexDirectory(LPCWSTR _aPathName)
326baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
327baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString pathName = _aPathName;
328baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
329baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (pos > 0 && pos == pathName.Length() - 1)
330baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
331baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pathName.Length() == 3 && pathName[1] == L':')
332baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return true; // Disk folder;
333baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pathName.Delete(pos);
334baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
335baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString pathName2 = pathName;
336baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pos = pathName.Length();
337baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
338baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
339baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (MyCreateDirectory(pathName))
340baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
341baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (::GetLastError() == ERROR_ALREADY_EXISTS)
342baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
343baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      NFind::CFileInfoW fileInfo;
344baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!fileInfo.Find(pathName)) // For network folders
345baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return true;
346baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!fileInfo.IsDir())
347baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
348baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
349baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
350baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pos = pathName.ReverseFind(WCHAR_PATH_SEPARATOR);
351baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pos < 0 || pos == 0)
352baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
353baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pathName[pos - 1] == L':')
354baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
355baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pathName = pathName.Left(pos);
356baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
357baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  pathName = pathName2;
358baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  while (pos < pathName.Length())
359baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
360baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    pos = pathName.Find(WCHAR_PATH_SEPARATOR, pos + 1);
361baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (pos < 0)
362baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      pos = pathName.Length();
363baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!MyCreateDirectory(pathName.Left(pos)))
364baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
365baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
366baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
367baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
368baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
369baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
370baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
371baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool DeleteFileAlways(LPCTSTR name)
372baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
373baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MySetFileAttributes(name, 0))
374baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
375baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::DeleteFile(name))
376baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
377baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH2
378baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString longPath;
379baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPath(name, longPath))
380baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::DeleteFileW(longPath));
381baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
382baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
383baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
384baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
385baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
386baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool DeleteFileAlways(LPCWSTR name)
387baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
388baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!g_IsNT)
389baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return DeleteFileAlways(GetSysPath(name));
390baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MySetFileAttributes(name, 0))
391baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
392baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (::DeleteFileW(name))
393baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
394baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH
395baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString longPath;
396baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (GetLongPath(name, longPath))
397baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::DeleteFileW(longPath));
398baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
399baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
400baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
401baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
402baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
403baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
404baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
405baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (fileInfo.IsDir())
406baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
407baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return DeleteFileAlways(pathPrefix + fileInfo.Name);
408baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
409baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
410baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool RemoveDirectoryWithSubItems(const CSysString &path)
411baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
412baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NFind::CFileInfo fileInfo;
413baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString pathPrefix = path + NName::kDirDelimiter;
414baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
415baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFind::CEnumerator enumerator(pathPrefix + TCHAR(NName::kAnyStringWildcard));
416baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    while (enumerator.Next(fileInfo))
417baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
418baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
419baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
420baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MySetFileAttributes(path, 0))
421baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
422baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MyRemoveDirectory(path);
423baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
424baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
425baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
426baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
427baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
428baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (fileInfo.IsDir())
429baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
430baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return DeleteFileAlways(pathPrefix + fileInfo.Name);
431baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
432baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool RemoveDirectoryWithSubItems(const UString &path)
433baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
434baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  NFind::CFileInfoW fileInfo;
435baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString pathPrefix = path + UString(NName::kDirDelimiter);
436baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
437baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    NFind::CEnumeratorW enumerator(pathPrefix + UString(NName::kAnyStringWildcard));
438baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    while (enumerator.Next(fileInfo))
439baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!RemoveDirectorySubItems2(pathPrefix, fileInfo))
440baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
441baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
442baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MySetFileAttributes(path, 0))
443baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
444baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MyRemoveDirectory(path);
445baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
446baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
447baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
448baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetOnlyDirPrefix(LPCTSTR fileName, CSysString &resultName)
449baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
450baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index;
451baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetFullPathName(fileName, resultName, index))
452baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
453baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultName = resultName.Left(index);
454baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
455baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
456baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
457baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetOnlyName(LPCTSTR fileName, CSysString &resultName)
458baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
459baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index;
460baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetFullPathName(fileName, resultName, index))
461baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
462baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultName = resultName.Mid(index);
463baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
464baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
465baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
466baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef UNDER_CE
467baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetFullPathName(LPCWSTR fileName, UString &resultPath)
468baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
469baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultPath = fileName;
470baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
471baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
472baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
473baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
474baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
475baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultPath = fileName;
476baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  // change it
477baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fileNamePartStartIndex = resultPath.ReverseFind(WCHAR_PATH_SEPARATOR);
478baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  fileNamePartStartIndex++;
479baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
480baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
481baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
482baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#else
483baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
484baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetShortPathName(LPCTSTR longPath, CSysString &shortPath)
485baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
486baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  DWORD needLength = ::GetShortPathName(longPath, shortPath.GetBuffer(MAX_PATH + 1), MAX_PATH + 1);
487baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  shortPath.ReleaseBuffer();
488baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (needLength > 0 && needLength < MAX_PATH);
489baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
490baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
491baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifdef WIN_LONG_PATH
492baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
493baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic UString GetLastPart(LPCWSTR path)
494baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
495baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i = (int)wcslen(path);
496baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (; i > 0; i--)
497baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
498baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    WCHAR c = path[i - 1];
499baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (c == WCHAR_PATH_SEPARATOR || c == '/')
500baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      break;
501baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
502baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return path + i;
503baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
504baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
505baa3858d3f5d128a5c8466b700098109edcad5f2repo syncstatic void AddTrailingDots(LPCWSTR oldPath, UString &newPath)
506baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
507baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int len = (int)wcslen(oldPath);
508baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int i;
509baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (i = len; i > 0 && oldPath[i - 1] == '.'; i--);
510baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (i == 0 || i == len)
511baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
512baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString oldName = GetLastPart(oldPath);
513baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString newName = GetLastPart(newPath);
514baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int nonDotsLen = oldName.Length() - (len - i);
515baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (nonDotsLen == 0 || newName.CompareNoCase(oldName.Left(nonDotsLen)) != 0)
516baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return;
517baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (; i != len; i++)
518baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    newPath += '.';
519baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
520baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
521baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
522baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
523baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetFullPathName(LPCTSTR fileName, CSysString &resultPath, int &fileNamePartStartIndex)
524baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
525baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultPath.Empty();
526baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LPTSTR fileNamePointer = 0;
527baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LPTSTR buffer = resultPath.GetBuffer(MAX_PATH);
528baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  DWORD needLength = ::GetFullPathName(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
529baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultPath.ReleaseBuffer();
530baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (needLength == 0)
531baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
532baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (needLength >= MAX_PATH)
533baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
534baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifdef WIN_LONG_PATH2
535baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    needLength++;
536baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    buffer = resultPath.GetBuffer(needLength + 1);
537baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
538baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    resultPath.ReleaseBuffer();
539baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (needLength2 == 0 || needLength2 > needLength)
540baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
541baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
542baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
543baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (fileNamePointer == 0)
544baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fileNamePartStartIndex = lstrlen(fileName);
545baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
546baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fileNamePartStartIndex = (int)(fileNamePointer - buffer);
547baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef _UNICODE
548baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef WIN_LONG_PATH
549baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  AddTrailingDots(fileName, resultPath);
550baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
551baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
552baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
553baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
554baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
555baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
556baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetFullPathName(LPCWSTR fileName, UString &resultPath, int &fileNamePartStartIndex)
557baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
558baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultPath.Empty();
559baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
560baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
561baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    LPWSTR fileNamePointer = 0;
562baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    LPWSTR buffer = resultPath.GetBuffer(MAX_PATH);
563baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DWORD needLength = ::GetFullPathNameW(fileName, MAX_PATH + 1, buffer, &fileNamePointer);
564baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    resultPath.ReleaseBuffer();
565baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (needLength == 0)
566baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
567baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (needLength >= MAX_PATH)
568baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
569baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #ifdef WIN_LONG_PATH
570baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      needLength++;
571baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      buffer = resultPath.GetBuffer(needLength + 1);
572baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      DWORD needLength2 = ::GetFullPathNameW(fileName, needLength, buffer, &fileNamePointer);
573baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      resultPath.ReleaseBuffer();
574baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (needLength2 == 0 || needLength2 > needLength)
575baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      #endif
576baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
577baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
578baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (fileNamePointer == 0)
579baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileNamePartStartIndex = MyStringLen(fileName);
580baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    else
581baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileNamePartStartIndex = (int)(fileNamePointer - buffer);
582baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #ifdef WIN_LONG_PATH
583baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    AddTrailingDots(fileName, resultPath);
584baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    #endif
585baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
586baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  else
587baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
588baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    CSysString sysPath;
589baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (!MyGetFullPathName(GetSysPath(fileName), sysPath, fileNamePartStartIndex))
590baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
591baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString resultPath1 = GetUnicodePath(sysPath.Left(fileNamePartStartIndex));
592baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UString resultPath2 = GetUnicodePath(sysPath.Mid(fileNamePartStartIndex));
593baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    fileNamePartStartIndex = resultPath1.Length();
594baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    resultPath = resultPath1 + resultPath2;
595baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
596baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
597baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
598baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
599baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
600baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
601baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
602baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
603baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index;
604baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MyGetFullPathName(fileName, path, index);
605baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
606baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
607baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
608baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetFullPathName(LPCWSTR fileName, UString &path)
609baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
610baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index;
611baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MyGetFullPathName(fileName, path, index);
612baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
613baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
614baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
615baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
616baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetOnlyName(LPCWSTR fileName, UString &resultName)
617baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
618baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index;
619baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetFullPathName(fileName, resultName, index))
620baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
621baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultName = resultName.Mid(index);
622baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
623baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
624baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
625baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
626baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
627baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool GetOnlyDirPrefix(LPCWSTR fileName, UString &resultName)
628baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
629baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  int index;
630baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetFullPathName(fileName, resultName, index))
631baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
632baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultName = resultName.Left(index);
633baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
634baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
635baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
636baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
637baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetCurrentDirectory(CSysString &path)
638baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
639baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  DWORD needLength = ::GetCurrentDirectory(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
640baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path.ReleaseBuffer();
641baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (needLength > 0 && needLength <= MAX_PATH);
642baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
643baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
644baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
645baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MySetCurrentDirectory(LPCWSTR path)
646baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
647baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
648baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return BOOLToBool(::SetCurrentDirectoryW(path));
649baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return MySetCurrentDirectory(GetSysPath(path));
650baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
651baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetCurrentDirectory(UString &path)
652baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
653baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
654baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
655baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DWORD needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
656baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    path.ReleaseBuffer();
657baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return (needLength > 0 && needLength <= MAX_PATH);
658baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
659baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString sysPath;
660baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetCurrentDirectory(sysPath))
661baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
662baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path = GetUnicodePath(sysPath);
663baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
664baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
665baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
666baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
667baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MySearchPath(LPCTSTR path, LPCTSTR fileName, LPCTSTR extension,
668baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString &resultPath, UINT32 &filePart)
669baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
670baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  LPTSTR filePartPointer;
671baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  DWORD value = ::SearchPath(path, fileName, extension,
672baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
673baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  filePart = (UINT32)(filePartPointer - (LPCTSTR)resultPath);
674baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultPath.ReleaseBuffer();
675baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (value > 0 && value <= MAX_PATH);
676baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
677baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
678baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
679baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
680baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MySearchPath(LPCWSTR path, LPCWSTR fileName, LPCWSTR extension,
681baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString &resultPath, UINT32 &filePart)
682baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
683baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
684baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
685baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    LPWSTR filePartPointer = 0;
686baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DWORD value = ::SearchPathW(path, fileName, extension,
687baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        MAX_PATH, resultPath.GetBuffer(MAX_PATH + 1), &filePartPointer);
688baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    filePart = (UINT32)(filePartPointer - (LPCWSTR)resultPath);
689baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    resultPath.ReleaseBuffer();
690baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return (value > 0 && value <= MAX_PATH);
691baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
692baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
693baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString sysPath;
694baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MySearchPath(
695baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      path != 0 ? (LPCTSTR)GetSysPath(path): 0,
696baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      fileName != 0 ? (LPCTSTR)GetSysPath(fileName): 0,
697baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      extension != 0 ? (LPCTSTR)GetSysPath(extension): 0,
698baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sysPath, filePart))
699baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
700baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString resultPath1 = GetUnicodePath(sysPath.Left(filePart));
701baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString resultPath2 = GetUnicodePath(sysPath.Mid(filePart));
702baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  filePart = resultPath1.Length();
703baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  resultPath = resultPath1 + resultPath2;
704baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
705baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
706baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
707baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
708baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetTempPath(CSysString &path)
709baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
710baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  DWORD needLength = ::GetTempPath(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
711baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path.ReleaseBuffer();
712baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (needLength > 0 && needLength <= MAX_PATH);
713baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
714baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
715baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
716baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool MyGetTempPath(UString &path)
717baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
718baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path.Empty();
719baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
720baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
721baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    DWORD needLength = ::GetTempPathW(MAX_PATH + 1, path.GetBuffer(MAX_PATH + 1));
722baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    path.ReleaseBuffer();
723baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return (needLength > 0 && needLength <= MAX_PATH);
724baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
725baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString sysPath;
726baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetTempPath(sysPath))
727baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
728baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path = GetUnicodePath(sysPath);
729baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return true;
730baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
731baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
732baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
733baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUINT MyGetTempFileName(LPCTSTR dirPath, LPCTSTR prefix, CSysString &path)
734baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
735baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UINT number = ::GetTempFileName(dirPath, prefix, 0, path.GetBuffer(MAX_PATH + 1));
736baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path.ReleaseBuffer();
737baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return number;
738baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
739baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
740baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
741baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUINT MyGetTempFileName(LPCWSTR dirPath, LPCWSTR prefix, UString &path)
742baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
743baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (g_IsNT)
744baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
745baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UINT number = ::GetTempFileNameW(dirPath, prefix, 0, path.GetBuffer(MAX_PATH));
746baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    path.ReleaseBuffer();
747baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return number;
748baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
749baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString sysPath;
750baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UINT number = MyGetTempFileName(
751baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      dirPath ? (LPCTSTR)GetSysPath(dirPath): 0,
752baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      prefix ? (LPCTSTR)GetSysPath(prefix): 0,
753baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      sysPath);
754baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  path = GetUnicodePath(sysPath);
755baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return number;
756baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
757baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
758baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
759baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUINT CTempFile::Create(LPCTSTR dirPath, LPCTSTR prefix, CSysString &resultPath)
760baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
761baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Remove();
762baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
763baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (number != 0)
764baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
765baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _fileName = resultPath;
766baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _mustBeDeleted = true;
767baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
768baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return number;
769baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
770baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
771baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CTempFile::Create(LPCTSTR prefix, CSysString &resultPath)
772baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
773baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString tempPath;
774baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetTempPath(tempPath))
775baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
776baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (Create(tempPath, prefix, resultPath) != 0)
777baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
778baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #ifdef UNDER_CE
779baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return false;
780baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #else
781baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetWindowsDirectory(tempPath))
782baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
783baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (Create(tempPath, prefix, resultPath) != 0);
784baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  #endif
785baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
786baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
787baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CTempFile::Remove()
788baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
789baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_mustBeDeleted)
790baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
791baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _mustBeDeleted = !DeleteFileAlways(_fileName);
792baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return !_mustBeDeleted;
793baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
794baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
795baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
796baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
797baa3858d3f5d128a5c8466b700098109edcad5f2repo syncUINT CTempFileW::Create(LPCWSTR dirPath, LPCWSTR prefix, UString &resultPath)
798baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
799baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Remove();
800baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UINT number = MyGetTempFileName(dirPath, prefix, resultPath);
801baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (number != 0)
802baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
803baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _fileName = resultPath;
804baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _mustBeDeleted = true;
805baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
806baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return number;
807baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
808baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
809baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CTempFileW::Create(LPCWSTR prefix, UString &resultPath)
810baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
811baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  UString tempPath;
812baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetTempPath(tempPath))
813baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
814baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (Create(tempPath, prefix, resultPath) != 0)
815baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
816baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!MyGetWindowsDirectory(tempPath))
817baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return false;
818baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (Create(tempPath, prefix, resultPath) != 0);
819baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
820baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
821baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CTempFileW::Remove()
822baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
823baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  if (!_mustBeDeleted)
824baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    return true;
825baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  _mustBeDeleted = !DeleteFileAlways(_fileName);
826baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return !_mustBeDeleted;
827baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
828baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
829baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
830baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
831baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CreateTempDirectory(LPCTSTR prefix, CSysString &dirName)
832baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
833baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  /*
834baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString prefix = tempPath + prefixChars;
835baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRandom random;
836baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  random.Init();
837baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  */
838baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
839baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
840baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
841baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CTempFile tempFile;
842baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!tempFile.Create(prefix, dirName))
843baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
844baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!tempFile.Remove())
845baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
846baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
847baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
848baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UINT32 randomNumber = random.Generate();
849baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    TCHAR randomNumberString[32];
850baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _stprintf(randomNumberString, _T("%04X"), randomNumber);
851baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dirName = prefix + randomNumberString;
852baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
853baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (NFind::DoesFileOrDirExist(dirName))
854baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
855baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (MyCreateDirectory(dirName))
856baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return true;
857baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (::GetLastError() != ERROR_ALREADY_EXISTS)
858baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
859baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
860baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
861baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
862baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CTempDirectory::Create(LPCTSTR prefix)
863baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
864baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Remove();
865baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
866baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
867baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
868baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#ifndef _UNICODE
869baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
870baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CreateTempDirectory(LPCWSTR prefix, UString &dirName)
871baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
872baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  /*
873baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CSysString prefix = tempPath + prefixChars;
874baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  CRandom random;
875baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  random.Init();
876baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  */
877baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  for (;;)
878baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  {
879baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    {
880baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      CTempFileW tempFile;
881baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!tempFile.Create(prefix, dirName))
882baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
883baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      if (!tempFile.Remove())
884baa3858d3f5d128a5c8466b700098109edcad5f2repo sync        return false;
885baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    }
886baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    /*
887baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    UINT32 randomNumber = random.Generate();
888baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    TCHAR randomNumberString[32];
889baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    _stprintf(randomNumberString, _T("%04X"), randomNumber);
890baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    dirName = prefix + randomNumberString;
891baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    */
892baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (NFind::DoesFileOrDirExist(dirName))
893baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      continue;
894baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (MyCreateDirectory(dirName))
895baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return true;
896baa3858d3f5d128a5c8466b700098109edcad5f2repo sync    if (::GetLastError() != ERROR_ALREADY_EXISTS)
897baa3858d3f5d128a5c8466b700098109edcad5f2repo sync      return false;
898baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  }
899baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
900baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
901baa3858d3f5d128a5c8466b700098109edcad5f2repo syncbool CTempDirectoryW::Create(LPCWSTR prefix)
902baa3858d3f5d128a5c8466b700098109edcad5f2repo sync{
903baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  Remove();
904baa3858d3f5d128a5c8466b700098109edcad5f2repo sync  return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
905baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}
906baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
907baa3858d3f5d128a5c8466b700098109edcad5f2repo sync#endif
908baa3858d3f5d128a5c8466b700098109edcad5f2repo sync
909baa3858d3f5d128a5c8466b700098109edcad5f2repo sync}}}
910