| 210 | } |
| 211 | |
| 212 | TString WinReadLink(const TString& name) { |
| 213 | TFileHandle h = CreateFileWithUtf8Name(name, GENERIC_READ, FILE_SHARE_READ, OPEN_EXISTING, |
| 214 | FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, true); |
| 215 | if (h == INVALID_HANDLE_VALUE) { |
| 216 | ythrow TIoSystemError() << "can't open file " << name; |
| 217 | } |
| 218 | TTempBuf buf; |
| 219 | REPARSE_DATA_BUFFER* rdb = ReadReparsePoint(h, buf); |
| 220 | if (rdb == nullptr) { |
| 221 | ythrow TIoSystemError() << "can't read reparse point " << name; |
| 222 | } |
| 223 | if (rdb->ReparseTag == IO_REPARSE_TAG_SYMLINK) { |
| 224 | wchar16* str = (wchar16*)&rdb->SymbolicLinkReparseBuffer.PathBuffer[rdb->SymbolicLinkReparseBuffer.SubstituteNameOffset / sizeof(wchar16)]; |
| 225 | size_t len = rdb->SymbolicLinkReparseBuffer.SubstituteNameLength / sizeof(wchar16); |
| 226 | return WideToUTF8(str, len); |
| 227 | } else if (rdb->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { |
| 228 | wchar16* str = (wchar16*)&rdb->MountPointReparseBuffer.PathBuffer[rdb->MountPointReparseBuffer.SubstituteNameOffset / sizeof(wchar16)]; |
| 229 | size_t len = rdb->MountPointReparseBuffer.SubstituteNameLength / sizeof(wchar16); |
| 230 | return WideToUTF8(str, len); |
| 231 | } |
| 232 | // this reparse point is unsupported in arcadia |
| 233 | return TString(); |
| 234 | } |
| 235 | |
| 236 | ULONG WinReadReparseTag(HANDLE h) { |
| 237 | TTempBuf buf; |
no test coverage detected