Skip to content

Instantly share code, notes, and snippets.

@DrPizza
Forked from BillyONeal/equivalent.cpp
Last active February 21, 2017 05:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save DrPizza/96814ff823aeef84be5e824eddf906b9 to your computer and use it in GitHub Desktop.
Save DrPizza/96814ff823aeef84be5e824eddf906b9 to your computer and use it in GitHub Desktop.
std::filesystem::equivalent
#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)
{
_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);
}
DWORD _LastError = GetLastError();
if (_LastError != ERROR_INVALID_PARAMETER)
{ // Windows Vista through Windows 7 don't support FileIdInfo
*_Result = false;
return (_LastError);
}
goto tryGetFileInformationByHandle;
}
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