Created
February 21, 2017 05:39
-
-
Save BillyONeal/7209d5d118a301ffec86fb195222d62a to your computer and use it in GitHub Desktop.
std::filesystem::equivalent
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <vcruntime.h> | |
__std_win32_error __std_fs_equivalent(bool * _Result, const wchar_t *_Path1, const wchar_t *_Path2) noexcept | |
{ // test for equivalent file names | |
const __vcp_unique_handle _Handle1(_FilesysOpenFile(_Path1, FILE_READ_ATTRIBUTES, | |
FILE_FLAG_BACKUP_SEMANTICS)); | |
if (!_Handle1.is_valid()) | |
{ | |
*_Result = false; | |
return (GetLastError()); | |
} | |
const __vcp_unique_handle _Handle2(_FilesysOpenFile(_Path2, FILE_READ_ATTRIBUTES, | |
FILE_FLAG_BACKUP_SEMANTICS)); | |
if (!_Handle2.is_valid()) | |
{ | |
*_Result = false; | |
return (GetLastError()); | |
} | |
if (__vcp_has_GetFileInformationByHandleEx()) | |
{ | |
_FILE_ID_INFO _Info1; | |
if (__vcp_GetFileInformationByHandleEx(_Handle1.get(), FileIdInfo, &_Info1, sizeof(_Info1)) == 0) | |
{ | |
DWORD _LastError = GetLastError(); | |
if (_LastError == ERROR_INVALID_PARAMETER) | |
{ // Windows Vista through Windows 7 don't support FileIdInfo | |
goto tryGetFileInformationByHandle; | |
} | |
*_Result = false; | |
return (_LastError); | |
} | |
_FILE_ID_INFO _Info2; | |
if (__vcp_GetFileInformationByHandleEx(_Handle2.get(), FileIdInfo, &_Info2, sizeof(_Info2)) == 0) | |
{ | |
*_Result = false; | |
return (GetLastError()); | |
} | |
static_assert(sizeof(_Info1) == sizeof(_Info1.VolumeSerialNumber) + sizeof(_Info1.FileId), | |
"cannot combine comparisons"); | |
*_Result = memcmp(&_Info1, &_Info2, sizeof(_Info1)) == 0; | |
return (__std_win32_success); | |
} | |
tryGetFileInformationByHandle: | |
if (__vcp_has_GetFileInformationByHandle()) | |
{ | |
BY_HANDLE_FILE_INFORMATION _Info1; | |
if (__vcp_GetFileInformationByHandle(_Handle1.get(), &_Info1) == 0) | |
{ | |
*_Result = false; | |
return (GetLastError()); | |
} | |
BY_HANDLE_FILE_INFORMATION _Info2; | |
if (__vcp_GetFileInformationByHandle(_Handle2.get(), &_Info2) == 0) | |
{ | |
*_Result = false; | |
return (GetLastError()); | |
} | |
*_Result = _Info1.dwVolumeSerialNumber == _Info2.dwVolumeSerialNumber | |
&& _Info1.nFileIndexHigh == _Info2.nFileIndexHigh | |
&& _Info1.nFileIndexLow == _Info2.nFileIndexLow; | |
return (__std_win32_success); | |
} | |
return (ERROR_NOT_SUPPORTED); | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment