| 75 | } |
| 76 | |
| 77 | bool WinSymLink(const TString& targetName, const TString& linkName) { |
| 78 | TString tName(targetName); |
| 79 | { |
| 80 | size_t pos; |
| 81 | while ((pos = tName.find('/')) != TString::npos) { |
| 82 | tName.replace(pos, 1, LOCSLASH_S); |
| 83 | } |
| 84 | } |
| 85 | TUtf16String tstr; |
| 86 | LPCWSTR wname = UTF8ToWCHAR(tName, tstr); |
| 87 | TUtf16String lstr; |
| 88 | LPCWSTR lname = UTF8ToWCHAR(linkName, lstr); |
| 89 | |
| 90 | // we can't create a dangling link to a dir in this way |
| 91 | ui32 attr = ::GetFileAttributesW(wname); |
| 92 | if (attr == INVALID_FILE_ATTRIBUTES) { |
| 93 | TTempBuf result; |
| 94 | if (GetFullPathNameW(lname, result.Size(), (LPWSTR)result.Data(), 0) != 0) { |
| 95 | TString fullPath = WideToUTF8(TWtringBuf((const wchar16*)result.Data())); |
| 96 | TStringBuf linkDir(fullPath); |
| 97 | linkDir.RNextTok('\\'); |
| 98 | |
| 99 | if (linkDir) { |
| 100 | TString fullTarget(tName); |
| 101 | resolvepath(fullTarget, TString{linkDir}); |
| 102 | TUtf16String fullTargetW; |
| 103 | LPCWSTR ptrFullTarget = UTF8ToWCHAR(fullTarget, fullTargetW); |
| 104 | attr = ::GetFileAttributesW(ptrFullTarget); |
| 105 | } |
| 106 | } |
| 107 | } |
| 108 | return 0 != CreateSymbolicLinkW(lname, wname, attr != INVALID_FILE_ATTRIBUTES && (attr & FILE_ATTRIBUTE_DIRECTORY) ? SYMBOLIC_LINK_FLAG_DIRECTORY : 0); |
| 109 | } |
| 110 | |
| 111 | bool WinHardLink(const TString& existingPath, const TString& newPath) { |
| 112 | TUtf16String ep, np; |
no test coverage detected