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