File search loops on symbolic links

Please report only one bug per message!

Moderators: white, Hacker, petermad, Stefan2

Post Reply
Dragokas
New Member
New Member
Posts: 1
Joined: 2020-11-16, 13:03 UTC

File search loops on symbolic links

Post by *Dragokas »

Hi,

Search results contain:
C:\Users\Alex\Local Settings\Application Data\Application Data\Application Data ...
everything is on the screenshot:

Image: https://ibb.co/myn1xSh

Code: Select all

C:\Users\Alex>dir /a "c:\users\alex\local settings\app*"
 Том в устройстве C имеет метку System
 Серийный номер тома: EA3B-CC12

 Содержимое папки c:\users\alex\local settings

18.04.2018  22:17    <JUNCTION>     Application Data [C:\Users\Alex\AppData\Local]
OS: Windows 7 x64.
TC: v9.51 x64

Thanks for fixing.
Alex.
User avatar
MVV
Power Member
Power Member
Posts: 8702
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Re: File search loops on symbolic links

Post by *MVV »

It seems that your junction has incorrect permissions, because by default these compatibility links don't allow viewing contents.
User avatar
ghisler(Author)
Site Admin
Site Admin
Posts: 48005
Joined: 2003-02-04, 09:46 UTC
Location: Switzerland
Contact:

Re: File search loops on symbolic links

Post by *ghisler(Author) »

Indeed this happens when the permisions are set to allow following the link, but not read the link target. Then TC cannot determine that there is an infinite loop.
Author of Total Commander
https://www.ghisler.com
User avatar
MVV
Power Member
Power Member
Posts: 8702
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Re: File search loops on symbolic links

Post by *MVV »

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.
User avatar
elgonzo
Power Member
Power Member
Posts: 866
Joined: 2013-09-04, 14:07 UTC

Re: File search loops on symbolic links

Post by *elgonzo »

Alright, i'll admit ReFS is still (forever? :twisted:) a somewhat exotic file system, but on ReFS the nFileIndexHigh/nFileIndexLow identifier is not guaranteed to be unique (as per official doc: https://docs.microsoft.com/en-us/windows/win32/api/fileapi/ns-fileapi-by_handle_file_information), and GetFileInformationByHandleEx should be used instead to obtain a unique 128-bit file ID. (I am absolutely not sure how probable possible nFileIndexHigh/nFileIndexLow identifier collisions would be on ReFS, though.)
Begrudgingly back to Windows... now 11... sigh... but i have no nerve for Linux desktop anymore...
User avatar
Usher
Power Member
Power Member
Posts: 1675
Joined: 2011-03-11, 10:11 UTC

Re: File search loops on symbolic links

Post by *Usher »

MVV wrote: 2020-11-18, 08:41 UTCIf 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)
Note that:
1. User made junctions usually redirect to directories on other volumes.
2. You may search all local drives and find files in some directory on volume D:, then search volume Z: and find junction linked to that directory. It may take a long time and the content of the directory may be changed.
Andrzej P. Wozniak
Polish subforum moderator
User avatar
MVV
Power Member
Power Member
Posts: 8702
Joined: 2008-08-03, 12:51 UTC
Location: Russian Federation

Re: File search loops on symbolic links

Post by *MVV »

elgonzo,
Thank you for the details regarding Windows servers, I agree that FileId+VolumeSerialNumber from FILE_ID_INFO should be used if available, and nFileIndexHigh+nFileIndexLow+dwVolumeSerialNumber from BY_HANDLE_FILE_INFORMATION otherwise.

Usher,
In case of links to different volumes, such "file id" (consisting of a "file index within a volume" and "volume id") may be used too, for avoiding multiple searches in same folders when there are junctions pointint to the same dir or to a dir and its subdir, Windows will return target volume id in case of a link pointing to another volume.
Post Reply