view src/win32/7zip/7z/CPP/Windows/FileDir.cpp @ 1:f9f4f1b99eed

importing src directory
author Robert McIntyre <rlm@mit.edu>
date Sat, 03 Mar 2012 10:31:27 -0600
parents
children
line wrap: on
line source
1 // Windows/FileDir.cpp
3 #include "StdAfx.h"
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
13 #ifndef _UNICODE
14 extern bool g_IsNT;
15 #endif
17 namespace NWindows {
18 namespace NFile {
20 #if defined(WIN_LONG_PATH) && defined(_UNICODE)
21 #define WIN_LONG_PATH2
22 #endif
24 // SetCurrentDirectory doesn't support \\?\ prefix
26 #ifdef WIN_LONG_PATH
27 bool GetLongPathBase(LPCWSTR fileName, UString &res);
28 bool GetLongPath(LPCWSTR fileName, UString &res);
29 #endif
31 namespace NDirectory {
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
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 }
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 }
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 }
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
87 bool SetDirTime(LPCWSTR fileName, const FILETIME *cTime, const FILETIME *aTime, const FILETIME *mTime)
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
110 bool res = false;
111 if (hDir != INVALID_HANDLE_VALUE)
112 {
113 res = BOOLToBool(::SetFileTime(hDir, cTime, aTime, mTime));
114 ::CloseHandle(hDir);
115 }
116 return res;
117 }
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 }
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 }
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
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 }
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 }
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 }
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
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 }
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
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 */
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.IsDir())
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 }
319 #ifndef _UNICODE
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.IsDir())
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 }
365 #endif
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 }
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
399 static bool RemoveDirectorySubItems2(const CSysString pathPrefix, const NFind::CFileInfo &fileInfo)
400 {
401 if (fileInfo.IsDir())
402 return RemoveDirectoryWithSubItems(pathPrefix + fileInfo.Name);
403 return DeleteFileAlways(pathPrefix + fileInfo.Name);
404 }
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 }
421 #ifndef _UNICODE
422 static bool RemoveDirectorySubItems2(const UString pathPrefix, const NFind::CFileInfoW &fileInfo)
423 {
424 if (fileInfo.IsDir())
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
444 #ifndef _WIN32_WCE
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 }
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 }
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
523 bool MyGetFullPathName(LPCTSTR fileName, CSysString &path)
524 {
525 int index;
526 return MyGetFullPathName(fileName, path, index);
527 }
529 #ifndef _UNICODE
530 bool MyGetFullPathName(LPCWSTR fileName, UString &path)
531 {
532 int index;
533 return MyGetFullPathName(fileName, path, index);
534 }
535 #endif
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 }
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
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 }
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
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 }
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
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 }
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 }
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
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 }
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
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 }
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
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 }
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 }
723 bool CTempFile::Remove()
724 {
725 if (!_mustBeDeleted)
726 return true;
727 _mustBeDeleted = !DeleteFileAlways(_fileName);
728 return !_mustBeDeleted;
729 }
731 #ifndef _UNICODE
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 }
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 }
757 bool CTempFileW::Remove()
758 {
759 if (!_mustBeDeleted)
760 return true;
761 _mustBeDeleted = !DeleteFileAlways(_fileName);
762 return !_mustBeDeleted;
763 }
765 #endif
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 }
796 bool CTempDirectory::Create(LPCTSTR prefix)
797 {
798 Remove();
799 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
800 }
802 #ifndef _UNICODE
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 }
833 bool CTempDirectoryW::Create(LPCWSTR prefix)
834 {
835 Remove();
836 return (_mustBeDeleted = CreateTempDirectory(prefix, _tempDir));
837 }
839 #endif
841 }}}