Sometimes I face this problem too, though I'm sure I didn't touch system reparse points.
I think there is a way to reliably detect that folders are the same. You should remember file system indexes for processed folders. If two files or folders have same indexes it is the same file system object. Even if there's no access to problematic junctions themselves, this will help to ignore their subfolders. This code reads file indexes (which are unique per file within a volume) and compares them:
Code: Select all
wchar_t buf[MAX_PATH];
ExpandEnvironmentStrings(L"%LOCALAPPDATA%\\GHISLER", buf, ARRAYSIZE(buf));
HANDLE h1 = CreateFile(buf, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
DWORD e1 = GetLastError();
BY_HANDLE_FILE_INFORMATION bhfi1;
GetFileInformationByHandle(h1, &bhfi1);
CloseHandle(h1);
ExpandEnvironmentStrings(L"%LOCALAPPDATA%\\Application Data\\GHISLER", buf, ARRAYSIZE(buf));
HANDLE h2 = CreateFile(buf, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTICS, nullptr);
DWORD e2 = GetLastError();
BY_HANDLE_FILE_INFORMATION bhfi2;
GetFileInformationByHandle(h2, &bhfi2);
CloseHandle(h2);
bool areSame = bhfi1.nFileIndexLow == bhfi2.nFileIndexLow && bhfi1.nFileIndexHigh == bhfi2.nFileIndexHigh;
Here FILE_FLAG_BACKUP_SEMANTICS flag is required to obtain a directory handle.
You can also compare dwVolumeSerialNumber values to check that two folders are within same volume, but it seems that it is possible for two volumes to have same serial number (it is incorrect and may cause various problems but it is possible).
Perhaps to avoid loops it is enough to keep such "hashes" for folders that form current path, but keeping "hashes" for all processed folders will also allow to ignore folders if they were already accessed via another route.