diff options
Diffstat (limited to '')
-rw-r--r-- | CPP/Windows/FileDir.cpp | 235 |
1 files changed, 165 insertions, 70 deletions
diff --git a/CPP/Windows/FileDir.cpp b/CPP/Windows/FileDir.cpp index cce2638..5b1f340 100644 --- a/CPP/Windows/FileDir.cpp +++ b/CPP/Windows/FileDir.cpp | |||
@@ -65,46 +65,55 @@ namespace NDir { | |||
65 | 65 | ||
66 | bool GetWindowsDir(FString &path) | 66 | bool GetWindowsDir(FString &path) |
67 | { | 67 | { |
68 | UINT needLength; | 68 | const unsigned kBufSize = MAX_PATH + 16; |
69 | UINT len; | ||
69 | #ifndef _UNICODE | 70 | #ifndef _UNICODE |
70 | if (!g_IsNT) | 71 | if (!g_IsNT) |
71 | { | 72 | { |
72 | TCHAR s[MAX_PATH + 2]; | 73 | TCHAR s[kBufSize + 1]; |
73 | s[0] = 0; | 74 | s[0] = 0; |
74 | needLength = ::GetWindowsDirectory(s, MAX_PATH + 1); | 75 | len = ::GetWindowsDirectory(s, kBufSize); |
75 | path = fas2fs(s); | 76 | path = fas2fs(s); |
76 | } | 77 | } |
77 | else | 78 | else |
78 | #endif | 79 | #endif |
79 | { | 80 | { |
80 | WCHAR s[MAX_PATH + 2]; | 81 | WCHAR s[kBufSize + 1]; |
81 | s[0] = 0; | 82 | s[0] = 0; |
82 | needLength = ::GetWindowsDirectoryW(s, MAX_PATH + 1); | 83 | len = ::GetWindowsDirectoryW(s, kBufSize); |
83 | path = us2fs(s); | 84 | path = us2fs(s); |
84 | } | 85 | } |
85 | return (needLength > 0 && needLength <= MAX_PATH); | 86 | return (len != 0 && len < kBufSize); |
86 | } | 87 | } |
87 | 88 | ||
89 | |||
90 | /* | ||
91 | new DOCs for GetSystemDirectory: | ||
92 | returned path does not end with a backslash unless the | ||
93 | system directory is the root directory. | ||
94 | */ | ||
95 | |||
88 | bool GetSystemDir(FString &path) | 96 | bool GetSystemDir(FString &path) |
89 | { | 97 | { |
90 | UINT needLength; | 98 | const unsigned kBufSize = MAX_PATH + 16; |
99 | UINT len; | ||
91 | #ifndef _UNICODE | 100 | #ifndef _UNICODE |
92 | if (!g_IsNT) | 101 | if (!g_IsNT) |
93 | { | 102 | { |
94 | TCHAR s[MAX_PATH + 2]; | 103 | TCHAR s[kBufSize + 1]; |
95 | s[0] = 0; | 104 | s[0] = 0; |
96 | needLength = ::GetSystemDirectory(s, MAX_PATH + 1); | 105 | len = ::GetSystemDirectory(s, kBufSize); |
97 | path = fas2fs(s); | 106 | path = fas2fs(s); |
98 | } | 107 | } |
99 | else | 108 | else |
100 | #endif | 109 | #endif |
101 | { | 110 | { |
102 | WCHAR s[MAX_PATH + 2]; | 111 | WCHAR s[kBufSize + 1]; |
103 | s[0] = 0; | 112 | s[0] = 0; |
104 | needLength = ::GetSystemDirectoryW(s, MAX_PATH + 1); | 113 | len = ::GetSystemDirectoryW(s, kBufSize); |
105 | path = us2fs(s); | 114 | path = us2fs(s); |
106 | } | 115 | } |
107 | return (needLength > 0 && needLength <= MAX_PATH); | 116 | return (len != 0 && len < kBufSize); |
108 | } | 117 | } |
109 | #endif // UNDER_CE | 118 | #endif // UNDER_CE |
110 | 119 | ||
@@ -123,7 +132,7 @@ bool SetDirTime(CFSTR path, const CFiTime *cTime, const CFiTime *aTime, const CF | |||
123 | IF_USE_MAIN_PATH | 132 | IF_USE_MAIN_PATH |
124 | hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, | 133 | hDir = ::CreateFileW(fs2us(path), GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, |
125 | NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); | 134 | NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, NULL); |
126 | #ifdef WIN_LONG_PATH | 135 | #ifdef Z7_LONG_PATH |
127 | if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH) | 136 | if (hDir == INVALID_HANDLE_VALUE && USE_SUPER_PATH) |
128 | { | 137 | { |
129 | UString superPath; | 138 | UString superPath; |
@@ -158,7 +167,7 @@ bool SetFileAttrib(CFSTR path, DWORD attrib) | |||
158 | IF_USE_MAIN_PATH | 167 | IF_USE_MAIN_PATH |
159 | if (::SetFileAttributesW(fs2us(path), attrib)) | 168 | if (::SetFileAttributesW(fs2us(path), attrib)) |
160 | return true; | 169 | return true; |
161 | #ifdef WIN_LONG_PATH | 170 | #ifdef Z7_LONG_PATH |
162 | if (USE_SUPER_PATH) | 171 | if (USE_SUPER_PATH) |
163 | { | 172 | { |
164 | UString superPath; | 173 | UString superPath; |
@@ -195,7 +204,7 @@ bool RemoveDir(CFSTR path) | |||
195 | IF_USE_MAIN_PATH | 204 | IF_USE_MAIN_PATH |
196 | if (::RemoveDirectoryW(fs2us(path))) | 205 | if (::RemoveDirectoryW(fs2us(path))) |
197 | return true; | 206 | return true; |
198 | #ifdef WIN_LONG_PATH | 207 | #ifdef Z7_LONG_PATH |
199 | if (USE_SUPER_PATH) | 208 | if (USE_SUPER_PATH) |
200 | { | 209 | { |
201 | UString superPath; | 210 | UString superPath; |
@@ -224,7 +233,7 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile) | |||
224 | if (::MoveFileW(fs2us(oldFile), fs2us(newFile))) | 233 | if (::MoveFileW(fs2us(oldFile), fs2us(newFile))) |
225 | return true; | 234 | return true; |
226 | } | 235 | } |
227 | #ifdef WIN_LONG_PATH | 236 | #ifdef Z7_LONG_PATH |
228 | if (USE_SUPER_PATH_2) | 237 | if (USE_SUPER_PATH_2) |
229 | { | 238 | { |
230 | UString d1, d2; | 239 | UString d1, d2; |
@@ -261,8 +270,11 @@ bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName) | |||
261 | else | 270 | else |
262 | #endif | 271 | #endif |
263 | { | 272 | { |
264 | Func_CreateHardLinkW my_CreateHardLinkW = (Func_CreateHardLinkW) | 273 | const |
265 | (void *)::GetProcAddress(::GetModuleHandleW(L"kernel32.dll"), "CreateHardLinkW"); | 274 | Func_CreateHardLinkW |
275 | my_CreateHardLinkW = Z7_GET_PROC_ADDRESS( | ||
276 | Func_CreateHardLinkW, ::GetModuleHandleW(L"kernel32.dll"), | ||
277 | "CreateHardLinkW"); | ||
266 | if (!my_CreateHardLinkW) | 278 | if (!my_CreateHardLinkW) |
267 | return false; | 279 | return false; |
268 | IF_USE_MAIN_PATH_2(newFileName, existFileName) | 280 | IF_USE_MAIN_PATH_2(newFileName, existFileName) |
@@ -270,7 +282,7 @@ bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName) | |||
270 | if (my_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL)) | 282 | if (my_CreateHardLinkW(fs2us(newFileName), fs2us(existFileName), NULL)) |
271 | return true; | 283 | return true; |
272 | } | 284 | } |
273 | #ifdef WIN_LONG_PATH | 285 | #ifdef Z7_LONG_PATH |
274 | if (USE_SUPER_PATH_2) | 286 | if (USE_SUPER_PATH_2) |
275 | { | 287 | { |
276 | UString d1, d2; | 288 | UString d1, d2; |
@@ -320,7 +332,7 @@ bool CreateDir(CFSTR path) | |||
320 | IF_USE_MAIN_PATH | 332 | IF_USE_MAIN_PATH |
321 | if (::CreateDirectoryW(fs2us(path), NULL)) | 333 | if (::CreateDirectoryW(fs2us(path), NULL)) |
322 | return true; | 334 | return true; |
323 | #ifdef WIN_LONG_PATH | 335 | #ifdef Z7_LONG_PATH |
324 | if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH) | 336 | if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH) |
325 | { | 337 | { |
326 | UString superPath; | 338 | UString superPath; |
@@ -355,7 +367,7 @@ static bool CreateDir2(CFSTR path) | |||
355 | IF_USE_MAIN_PATH | 367 | IF_USE_MAIN_PATH |
356 | if (::CreateDirectoryW(fs2us(path), NULL)) | 368 | if (::CreateDirectoryW(fs2us(path), NULL)) |
357 | return true; | 369 | return true; |
358 | #ifdef WIN_LONG_PATH | 370 | #ifdef Z7_LONG_PATH |
359 | if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH) | 371 | if ((!USE_MAIN_PATH || ::GetLastError() != ERROR_ALREADY_EXISTS) && USE_SUPER_PATH) |
360 | { | 372 | { |
361 | UString superPath; | 373 | UString superPath; |
@@ -390,7 +402,7 @@ bool CreateComplexDir(CFSTR _path) | |||
390 | #ifdef _WIN32 | 402 | #ifdef _WIN32 |
391 | 403 | ||
392 | { | 404 | { |
393 | DWORD attrib = NFind::GetFileAttrib(_path); | 405 | const DWORD attrib = NFind::GetFileAttrib(_path); |
394 | if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) | 406 | if (attrib != INVALID_FILE_ATTRIBUTES && (attrib & FILE_ATTRIBUTE_DIRECTORY) != 0) |
395 | return true; | 407 | return true; |
396 | } | 408 | } |
@@ -496,7 +508,7 @@ bool DeleteFileAlways(CFSTR path) | |||
496 | IF_USE_MAIN_PATH | 508 | IF_USE_MAIN_PATH |
497 | if (::DeleteFileW(fs2us(path))) | 509 | if (::DeleteFileW(fs2us(path))) |
498 | return true; | 510 | return true; |
499 | #ifdef WIN_LONG_PATH | 511 | #ifdef Z7_LONG_PATH |
500 | if (USE_SUPER_PATH) | 512 | if (USE_SUPER_PATH) |
501 | { | 513 | { |
502 | UString superPath; | 514 | UString superPath; |
@@ -586,9 +598,12 @@ bool MyGetFullPathName(CFSTR path, FString &resFullPath) | |||
586 | 598 | ||
587 | #ifdef _WIN32 | 599 | #ifdef _WIN32 |
588 | 600 | ||
601 | /* Win10: SetCurrentDirectory() doesn't support long paths and | ||
602 | doesn't support super prefix "\\?\", if long path behavior is not | ||
603 | enabled in registry (LongPathsEnabled) and in manifest (longPathAware). */ | ||
604 | |||
589 | bool SetCurrentDir(CFSTR path) | 605 | bool SetCurrentDir(CFSTR path) |
590 | { | 606 | { |
591 | // SetCurrentDirectory doesn't support \\?\ prefix | ||
592 | #ifndef _UNICODE | 607 | #ifndef _UNICODE |
593 | if (!g_IsNT) | 608 | if (!g_IsNT) |
594 | { | 609 | { |
@@ -602,28 +617,74 @@ bool SetCurrentDir(CFSTR path) | |||
602 | } | 617 | } |
603 | 618 | ||
604 | 619 | ||
620 | /* | ||
621 | we use system function GetCurrentDirectory() | ||
622 | new GetCurrentDirectory() DOCs: | ||
623 | - If the function fails, the return value is zero. | ||
624 | - If the function succeeds, the return value specifies | ||
625 | the number of characters that are written to the buffer, | ||
626 | not including the terminating null character. | ||
627 | - If the buffer is not large enough, the return value specifies | ||
628 | the required size of the buffer, in characters, | ||
629 | including the null-terminating character. | ||
630 | |||
631 | GetCurrentDir() calls GetCurrentDirectory(). | ||
632 | GetCurrentDirectory() in win10 in tests: | ||
633 | the returned (path) does not end with a backslash, if | ||
634 | current directory is not root directory of drive. | ||
635 | But that behavior is not guarantied in specification docs. | ||
636 | */ | ||
637 | |||
605 | bool GetCurrentDir(FString &path) | 638 | bool GetCurrentDir(FString &path) |
606 | { | 639 | { |
640 | const unsigned kBufSize = MAX_PATH + 16; | ||
607 | path.Empty(); | 641 | path.Empty(); |
608 | 642 | ||
609 | DWORD needLength; | ||
610 | #ifndef _UNICODE | 643 | #ifndef _UNICODE |
611 | if (!g_IsNT) | 644 | if (!g_IsNT) |
612 | { | 645 | { |
613 | TCHAR s[MAX_PATH + 2]; | 646 | TCHAR s[kBufSize + 1]; |
614 | s[0] = 0; | 647 | s[0] = 0; |
615 | needLength = ::GetCurrentDirectory(MAX_PATH + 1, s); | 648 | const DWORD len = ::GetCurrentDirectory(kBufSize, s); |
649 | if (len == 0 || len >= kBufSize) | ||
650 | return false; | ||
651 | s[kBufSize] = 0; // optional guard | ||
616 | path = fas2fs(s); | 652 | path = fas2fs(s); |
653 | return true; | ||
617 | } | 654 | } |
618 | else | 655 | else |
619 | #endif | 656 | #endif |
620 | { | 657 | { |
621 | WCHAR s[MAX_PATH + 2]; | 658 | DWORD len; |
622 | s[0] = 0; | 659 | { |
623 | needLength = ::GetCurrentDirectoryW(MAX_PATH + 1, s); | 660 | WCHAR s[kBufSize + 1]; |
624 | path = us2fs(s); | 661 | s[0] = 0; |
662 | len = ::GetCurrentDirectoryW(kBufSize, s); | ||
663 | if (len == 0) | ||
664 | return false; | ||
665 | if (len < kBufSize) | ||
666 | { | ||
667 | s[kBufSize] = 0; // optional guard | ||
668 | path = us2fs(s); | ||
669 | return true; | ||
670 | } | ||
671 | } | ||
672 | UString temp; | ||
673 | const DWORD len2 = ::GetCurrentDirectoryW(len, temp.GetBuf(len)); | ||
674 | if (len2 == 0) | ||
675 | return false; | ||
676 | temp.ReleaseBuf_CalcLen(len); | ||
677 | if (temp.Len() != len2 || len - 1 != len2) | ||
678 | { | ||
679 | /* it's unexpected case, if current dir of process | ||
680 | was changed between two function calls, | ||
681 | or some unexpected function implementation */ | ||
682 | // SetLastError((DWORD)E_FAIL); // we can set some error code | ||
683 | return false; | ||
684 | } | ||
685 | path = us2fs(temp); | ||
686 | return true; | ||
625 | } | 687 | } |
626 | return (needLength > 0 && needLength <= MAX_PATH); | ||
627 | } | 688 | } |
628 | 689 | ||
629 | #endif // _WIN32 | 690 | #endif // _WIN32 |
@@ -648,41 +709,59 @@ bool GetOnlyDirPrefix(CFSTR path, FString &resDirPrefix) | |||
648 | return GetFullPathAndSplit(path, resDirPrefix, resFileName); | 709 | return GetFullPathAndSplit(path, resDirPrefix, resFileName); |
649 | } | 710 | } |
650 | 711 | ||
712 | |||
713 | |||
651 | bool MyGetTempPath(FString &path) | 714 | bool MyGetTempPath(FString &path) |
652 | { | 715 | { |
653 | #ifdef _WIN32 | 716 | #ifdef _WIN32 |
654 | path.Empty(); | 717 | |
655 | DWORD needLength; | 718 | /* |
719 | new DOCs for GetTempPathW(): | ||
720 | - The returned string ends with a backslash. | ||
721 | - The maximum possible return value is MAX_PATH+1 (261). | ||
722 | */ | ||
723 | |||
724 | const unsigned kBufSize = MAX_PATH + 16; | ||
725 | DWORD len; | ||
656 | #ifndef _UNICODE | 726 | #ifndef _UNICODE |
657 | if (!g_IsNT) | 727 | if (!g_IsNT) |
658 | { | 728 | { |
659 | TCHAR s[MAX_PATH + 2]; | 729 | TCHAR s[kBufSize + 1]; |
660 | s[0] = 0; | 730 | s[0] = 0; |
661 | needLength = ::GetTempPath(MAX_PATH + 1, s); | 731 | len = ::GetTempPath(kBufSize, s); |
662 | path = fas2fs(s); | 732 | path = fas2fs(s); |
663 | } | 733 | } |
664 | else | 734 | else |
665 | #endif | 735 | #endif |
666 | { | 736 | { |
667 | WCHAR s[MAX_PATH + 2]; | 737 | WCHAR s[kBufSize + 1]; |
668 | s[0] = 0; | 738 | s[0] = 0; |
669 | needLength = ::GetTempPathW(MAX_PATH + 1, s);; | 739 | len = ::GetTempPathW(kBufSize, s); |
670 | path = us2fs(s); | 740 | path = us2fs(s); |
671 | } | 741 | } |
672 | return (needLength > 0 && needLength <= MAX_PATH); | 742 | /* win10: GetTempPathW() doesn't set backslash at the end of path, |
743 | if (buffer_size == len_of(path_with_backslash)). | ||
744 | So we normalize path here: */ | ||
745 | NormalizeDirPathPrefix(path); | ||
746 | return (len != 0 && len < kBufSize); | ||
673 | 747 | ||
674 | #else | 748 | #else // !_WIN32 |
675 | 749 | ||
676 | // FIXME: improve that code | 750 | // FIXME: improve that code |
677 | path = "/tmp/"; | 751 | path = STRING_PATH_SEPARATOR "tmp"; |
678 | if (!NFind::DoesDirExist_FollowLink(path)) | 752 | const char *s; |
679 | path = "./"; | 753 | if (NFind::DoesDirExist_FollowLink(path)) |
754 | s = STRING_PATH_SEPARATOR "tmp" STRING_PATH_SEPARATOR; | ||
755 | else | ||
756 | s = "." STRING_PATH_SEPARATOR; | ||
757 | path = s; | ||
680 | return true; | 758 | return true; |
759 | |||
681 | #endif | 760 | #endif |
682 | } | 761 | } |
683 | 762 | ||
684 | 763 | ||
685 | static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COutFile *outFile) | 764 | bool CreateTempFile2(CFSTR prefix, bool addRandom, AString &postfix, NIO::COutFile *outFile) |
686 | { | 765 | { |
687 | UInt32 d = | 766 | UInt32 d = |
688 | #ifdef _WIN32 | 767 | #ifdef _WIN32 |
@@ -693,7 +772,7 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu | |||
693 | 772 | ||
694 | for (unsigned i = 0; i < 100; i++) | 773 | for (unsigned i = 0; i < 100; i++) |
695 | { | 774 | { |
696 | path = prefix; | 775 | postfix.Empty(); |
697 | if (addRandom) | 776 | if (addRandom) |
698 | { | 777 | { |
699 | char s[16]; | 778 | char s[16]; |
@@ -701,14 +780,14 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu | |||
701 | unsigned k; | 780 | unsigned k; |
702 | for (k = 0; k < 8; k++) | 781 | for (k = 0; k < 8; k++) |
703 | { | 782 | { |
704 | unsigned t = val & 0xF; | 783 | const unsigned t = val & 0xF; |
705 | val >>= 4; | 784 | val >>= 4; |
706 | s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); | 785 | s[k] = (char)((t < 10) ? ('0' + t) : ('A' + (t - 10))); |
707 | } | 786 | } |
708 | s[k] = '\0'; | 787 | s[k] = '\0'; |
709 | if (outFile) | 788 | if (outFile) |
710 | path += '.'; | 789 | postfix.Add_Dot(); |
711 | path += s; | 790 | postfix += s; |
712 | UInt32 step = GetTickCount() + 2; | 791 | UInt32 step = GetTickCount() + 2; |
713 | if (step == 0) | 792 | if (step == 0) |
714 | step = 1; | 793 | step = 1; |
@@ -716,7 +795,9 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu | |||
716 | } | 795 | } |
717 | addRandom = true; | 796 | addRandom = true; |
718 | if (outFile) | 797 | if (outFile) |
719 | path += ".tmp"; | 798 | postfix += ".tmp"; |
799 | FString path (prefix); | ||
800 | path += postfix; | ||
720 | if (NFind::DoesFileOrDirExist(path)) | 801 | if (NFind::DoesFileOrDirExist(path)) |
721 | { | 802 | { |
722 | SetLastError(ERROR_ALREADY_EXISTS); | 803 | SetLastError(ERROR_ALREADY_EXISTS); |
@@ -732,12 +813,12 @@ static bool CreateTempFile(CFSTR prefix, bool addRandom, FString &path, NIO::COu | |||
732 | if (CreateDir(path)) | 813 | if (CreateDir(path)) |
733 | return true; | 814 | return true; |
734 | } | 815 | } |
735 | DWORD error = GetLastError(); | 816 | const DWORD error = GetLastError(); |
736 | if (error != ERROR_FILE_EXISTS && | 817 | if (error != ERROR_FILE_EXISTS && |
737 | error != ERROR_ALREADY_EXISTS) | 818 | error != ERROR_ALREADY_EXISTS) |
738 | break; | 819 | break; |
739 | } | 820 | } |
740 | path.Empty(); | 821 | postfix.Empty(); |
741 | return false; | 822 | return false; |
742 | } | 823 | } |
743 | 824 | ||
@@ -745,8 +826,12 @@ bool CTempFile::Create(CFSTR prefix, NIO::COutFile *outFile) | |||
745 | { | 826 | { |
746 | if (!Remove()) | 827 | if (!Remove()) |
747 | return false; | 828 | return false; |
748 | if (!CreateTempFile(prefix, false, _path, outFile)) | 829 | _path.Empty(); |
830 | AString postfix; | ||
831 | if (!CreateTempFile2(prefix, false, postfix, outFile)) | ||
749 | return false; | 832 | return false; |
833 | _path = prefix; | ||
834 | _path += postfix; | ||
750 | _mustBeDeleted = true; | 835 | _mustBeDeleted = true; |
751 | return true; | 836 | return true; |
752 | } | 837 | } |
@@ -755,11 +840,16 @@ bool CTempFile::CreateRandomInTempFolder(CFSTR namePrefix, NIO::COutFile *outFil | |||
755 | { | 840 | { |
756 | if (!Remove()) | 841 | if (!Remove()) |
757 | return false; | 842 | return false; |
843 | _path.Empty(); | ||
758 | FString tempPath; | 844 | FString tempPath; |
759 | if (!MyGetTempPath(tempPath)) | 845 | if (!MyGetTempPath(tempPath)) |
760 | return false; | 846 | return false; |
761 | if (!CreateTempFile(tempPath + namePrefix, true, _path, outFile)) | 847 | AString postfix; |
848 | tempPath += namePrefix; | ||
849 | if (!CreateTempFile2(tempPath, true, postfix, outFile)) | ||
762 | return false; | 850 | return false; |
851 | _path = tempPath; | ||
852 | _path += postfix; | ||
763 | _mustBeDeleted = true; | 853 | _mustBeDeleted = true; |
764 | return true; | 854 | return true; |
765 | } | 855 | } |
@@ -802,11 +892,16 @@ bool CTempDir::Create(CFSTR prefix) | |||
802 | { | 892 | { |
803 | if (!Remove()) | 893 | if (!Remove()) |
804 | return false; | 894 | return false; |
895 | _path.Empty(); | ||
805 | FString tempPath; | 896 | FString tempPath; |
806 | if (!MyGetTempPath(tempPath)) | 897 | if (!MyGetTempPath(tempPath)) |
807 | return false; | 898 | return false; |
808 | if (!CreateTempFile(tempPath + prefix, true, _path, NULL)) | 899 | tempPath += prefix; |
900 | AString postfix; | ||
901 | if (!CreateTempFile2(tempPath, true, postfix, NULL)) | ||
809 | return false; | 902 | return false; |
903 | _path = tempPath; | ||
904 | _path += postfix; | ||
810 | _mustBeDeleted = true; | 905 | _mustBeDeleted = true; |
811 | return true; | 906 | return true; |
812 | } | 907 | } |
@@ -830,7 +925,7 @@ bool RemoveDir(CFSTR path) | |||
830 | } | 925 | } |
831 | 926 | ||
832 | 927 | ||
833 | static BOOL My__CopyFile(CFSTR oldFile, CFSTR newFile) | 928 | static BOOL My_CopyFile(CFSTR oldFile, CFSTR newFile) |
834 | { | 929 | { |
835 | NWindows::NFile::NIO::COutFile outFile; | 930 | NWindows::NFile::NIO::COutFile outFile; |
836 | if (!outFile.Create(newFile, false)) | 931 | if (!outFile.Create(newFile, false)) |
@@ -865,7 +960,7 @@ bool MyMoveFile(CFSTR oldFile, CFSTR newFile) | |||
865 | if (errno != EXDEV) // (oldFile and newFile are not on the same mounted filesystem) | 960 | if (errno != EXDEV) // (oldFile and newFile are not on the same mounted filesystem) |
866 | return false; | 961 | return false; |
867 | 962 | ||
868 | if (My__CopyFile(oldFile, newFile) == FALSE) | 963 | if (My_CopyFile(oldFile, newFile) == FALSE) |
869 | return false; | 964 | return false; |
870 | 965 | ||
871 | struct stat info_file; | 966 | struct stat info_file; |
@@ -906,11 +1001,11 @@ bool GetCurrentDir(FString &path) | |||
906 | { | 1001 | { |
907 | path.Empty(); | 1002 | path.Empty(); |
908 | 1003 | ||
909 | #define MY__PATH_MAX PATH_MAX | 1004 | #define MY_PATH_MAX PATH_MAX |
910 | // #define MY__PATH_MAX 1024 | 1005 | // #define MY_PATH_MAX 1024 |
911 | 1006 | ||
912 | char s[MY__PATH_MAX + 1]; | 1007 | char s[MY_PATH_MAX + 1]; |
913 | char *res = getcwd(s, MY__PATH_MAX); | 1008 | char *res = getcwd(s, MY_PATH_MAX); |
914 | if (res) | 1009 | if (res) |
915 | { | 1010 | { |
916 | path = fas2fs(s); | 1011 | path = fas2fs(s); |
@@ -1035,10 +1130,10 @@ static C_umask g_umask; | |||
1035 | #define PRF(x) | 1130 | #define PRF(x) |
1036 | 1131 | ||
1037 | #define TRACE_SetFileAttrib(msg) \ | 1132 | #define TRACE_SetFileAttrib(msg) \ |
1038 | PRF(printf("\nSetFileAttrib(%s, %x) : %s\n", (const char *)path, attrib, msg)); | 1133 | PRF(printf("\nSetFileAttrib(%s, %x) : %s\n", (const char *)path, attrib, msg);) |
1039 | 1134 | ||
1040 | #define TRACE_chmod(s, mode) \ | 1135 | #define TRACE_chmod(s, mode) \ |
1041 | PRF(printf("\n chmod(%s, %o)\n", (const char *)path, (unsigned)(mode))); | 1136 | PRF(printf("\n chmod(%s, %o)\n", (const char *)path, (unsigned)(mode));) |
1042 | 1137 | ||
1043 | int my_chown(CFSTR path, uid_t owner, gid_t group) | 1138 | int my_chown(CFSTR path, uid_t owner, gid_t group) |
1044 | { | 1139 | { |
@@ -1047,7 +1142,7 @@ int my_chown(CFSTR path, uid_t owner, gid_t group) | |||
1047 | 1142 | ||
1048 | bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | 1143 | bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) |
1049 | { | 1144 | { |
1050 | TRACE_SetFileAttrib(""); | 1145 | TRACE_SetFileAttrib("") |
1051 | 1146 | ||
1052 | struct stat st; | 1147 | struct stat st; |
1053 | 1148 | ||
@@ -1056,7 +1151,7 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
1056 | { | 1151 | { |
1057 | if (lstat(path, &st) != 0) | 1152 | if (lstat(path, &st) != 0) |
1058 | { | 1153 | { |
1059 | TRACE_SetFileAttrib("bad lstat()"); | 1154 | TRACE_SetFileAttrib("bad lstat()") |
1060 | return false; | 1155 | return false; |
1061 | } | 1156 | } |
1062 | // TRACE_chmod("lstat", st.st_mode); | 1157 | // TRACE_chmod("lstat", st.st_mode); |
@@ -1065,14 +1160,14 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
1065 | { | 1160 | { |
1066 | if (stat(path, &st) != 0) | 1161 | if (stat(path, &st) != 0) |
1067 | { | 1162 | { |
1068 | TRACE_SetFileAttrib("bad stat()"); | 1163 | TRACE_SetFileAttrib("bad stat()") |
1069 | return false; | 1164 | return false; |
1070 | } | 1165 | } |
1071 | } | 1166 | } |
1072 | 1167 | ||
1073 | if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) | 1168 | if (attrib & FILE_ATTRIBUTE_UNIX_EXTENSION) |
1074 | { | 1169 | { |
1075 | TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION"); | 1170 | TRACE_SetFileAttrib("attrib & FILE_ATTRIBUTE_UNIX_EXTENSION") |
1076 | st.st_mode = attrib >> 16; | 1171 | st.st_mode = attrib >> 16; |
1077 | if (S_ISDIR(st.st_mode)) | 1172 | if (S_ISDIR(st.st_mode)) |
1078 | { | 1173 | { |
@@ -1092,7 +1187,7 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
1092 | } | 1187 | } |
1093 | else | 1188 | else |
1094 | { | 1189 | { |
1095 | TRACE_SetFileAttrib("Only Windows Attributes"); | 1190 | TRACE_SetFileAttrib("Only Windows Attributes") |
1096 | // Only Windows Attributes | 1191 | // Only Windows Attributes |
1097 | if (S_ISDIR(st.st_mode) | 1192 | if (S_ISDIR(st.st_mode) |
1098 | || (attrib & FILE_ATTRIBUTE_READONLY) == 0) | 1193 | || (attrib & FILE_ATTRIBUTE_READONLY) == 0) |
@@ -1105,7 +1200,7 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
1105 | if (S_ISLNK(st.st_mode)) | 1200 | if (S_ISLNK(st.st_mode)) |
1106 | { | 1201 | { |
1107 | printf("\nfchmodat()\n"); | 1202 | printf("\nfchmodat()\n"); |
1108 | TRACE_chmod(path, (st.st_mode) & g_umask.mask); | 1203 | TRACE_chmod(path, (st.st_mode) & g_umask.mask) |
1109 | // AT_SYMLINK_NOFOLLOW is not implemted still in Linux. | 1204 | // AT_SYMLINK_NOFOLLOW is not implemted still in Linux. |
1110 | res = fchmodat(AT_FDCWD, path, (st.st_mode) & g_umask.mask, | 1205 | res = fchmodat(AT_FDCWD, path, (st.st_mode) & g_umask.mask, |
1111 | S_ISLNK(st.st_mode) ? AT_SYMLINK_NOFOLLOW : 0); | 1206 | S_ISLNK(st.st_mode) ? AT_SYMLINK_NOFOLLOW : 0); |
@@ -1113,7 +1208,7 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
1113 | else | 1208 | else |
1114 | */ | 1209 | */ |
1115 | { | 1210 | { |
1116 | TRACE_chmod(path, (st.st_mode) & g_umask.mask); | 1211 | TRACE_chmod(path, (st.st_mode) & g_umask.mask) |
1117 | res = chmod(path, (st.st_mode) & g_umask.mask); | 1212 | res = chmod(path, (st.st_mode) & g_umask.mask); |
1118 | } | 1213 | } |
1119 | // TRACE_SetFileAttrib("End") | 1214 | // TRACE_SetFileAttrib("End") |
@@ -1123,7 +1218,7 @@ bool SetFileAttrib_PosixHighDetect(CFSTR path, DWORD attrib) | |||
1123 | 1218 | ||
1124 | bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName) | 1219 | bool MyCreateHardLink(CFSTR newFileName, CFSTR existFileName) |
1125 | { | 1220 | { |
1126 | PRF(printf("\nhard link() %s -> %s\n", newFileName, existFileName)); | 1221 | PRF(printf("\nhard link() %s -> %s\n", newFileName, existFileName);) |
1127 | return (link(existFileName, newFileName) == 0); | 1222 | return (link(existFileName, newFileName) == 0); |
1128 | } | 1223 | } |
1129 | 1224 | ||