diff options
| author | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-06-21 00:00:00 +0000 |
|---|---|---|
| committer | Igor Pavlov <87184205+ip7z@users.noreply.github.com> | 2023-12-17 14:59:19 +0500 |
| commit | 5b39dc76f1bc82f941d5c800ab9f34407a06b53a (patch) | |
| tree | fe5e17420300b715021a76328444088d32047963 /CPP/Windows/FileDir.cpp | |
| parent | 93be7d4abfd4233228f58ee1fbbcd76d91be66a4 (diff) | |
| download | 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.gz 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.tar.bz2 7zip-5b39dc76f1bc82f941d5c800ab9f34407a06b53a.zip | |
23.0123.01
Diffstat (limited to 'CPP/Windows/FileDir.cpp')
| -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 | ||
