Commit b9dd1636 authored by Brad King's avatar Brad King Committed by Kitware Robot

Merge topic 'SystemTools-windows-dedup'

aa1f7f7c SystemTools: Fix FileIsSymlink with Windows data deduplication
Acked-by: Kitware Robot's avatarKitware Robot <kwrobot@kitware.com>
Merge-request: !122
parents c44652ee aa1f7f7c
......@@ -3005,10 +3005,36 @@ bool SystemTools::FileIsDirectory(const std::string& inName)
bool SystemTools::FileIsSymlink(const std::string& name)
{
#if defined(_WIN32)
DWORD attr =
GetFileAttributesW(Encoding::ToWindowsExtendedPath(name).c_str());
std::wstring path = Encoding::ToWindowsExtendedPath(name);
DWORD attr = GetFileAttributesW(path.c_str());
if (attr != INVALID_FILE_ATTRIBUTES) {
return (attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0;
if ((attr & FILE_ATTRIBUTE_REPARSE_POINT) != 0) {
// FILE_ATTRIBUTE_REPARSE_POINT means:
// * a file or directory that has an associated reparse point, or
// * a file that is a symbolic link.
HANDLE hFile = CreateFileW(
path.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTICS, NULL);
if (hFile == INVALID_HANDLE_VALUE) {
return false;
}
byte buffer[MAXIMUM_REPARSE_DATA_BUFFER_SIZE];
DWORD bytesReturned = 0;
if (!DeviceIoControl(hFile, FSCTL_GET_REPARSE_POINT, NULL, 0, buffer,
MAXIMUM_REPARSE_DATA_BUFFER_SIZE, &bytesReturned,
NULL)) {
CloseHandle(hFile);
// Since FILE_ATTRIBUTE_REPARSE_POINT is set this file must be
// a symbolic link if it is not a reparse point.
return GetLastError() == ERROR_NOT_A_REPARSE_POINT;
}
CloseHandle(hFile);
ULONG reparseTag =
reinterpret_cast<PREPARSE_GUID_DATA_BUFFER>(&buffer[0])->ReparseTag;
return (reparseTag == IO_REPARSE_TAG_SYMLINK) ||
(reparseTag == IO_REPARSE_TAG_MOUNT_POINT);
}
return false;
} else {
return false;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment