Subject: Re: bug#77589: 30.1; On Windows, dired does not display Junctions specially

From: Eli Zaretskii <[email-masked]>
Date: Mon, 07 Apr 2025 14:39:36 +0300

severity 77589 wishlist
thanks

> From: dino chiesa <[email-masked]>
> Date: Sun, 6 Apr 2025 23:15:59 +0000
> msip_labels: 
> 
> When using dired on emacs in Windows, Symlinks are displayed helpfully,
> with an indication of the target of the symlink.  Junction entries are
> not displayed specially.  There is no indication of the target of a
> Junction.
> 
> Junctions in Windows are similar to Symbolic Links
> (symlinks) but slightly different. You can read a comparison here:
> https://superuser.com/a/1291446/3614
> (Why there are both Junctions and symlinks, I do not know)
> 
> Junctions always use a directory as the target, and it is possible
> to create a Junction without elevated (Administrator) privileges. So it
> is sometimes more convenient to use a Junction, instead of a symlink.

AFAIK, Junction points are legacy/deprecated kind of symbolic links,
which are restricted wrt symlinks available on modern versions of
MS-Windows: junction points can only link to local directories (and
have security issues).  Their only advantage is that they are
available on older Windows versions.

Emacs does support symlinks on MS-Windows, but I don't see a point in
adding complexity to the MS-Windows specific code to support this
deprecated kind of symlinks.  It would add complexity, because
junctions are subtly different from symlinks, but the Posix model of
file attributes used by Emacs doesn't allow to distinguish between
them easily, so we'd need some kludges in all kinds of places.  For
example, what to do when copying a junction -- create another junction
or a symlink?  And how to display that in Dired buffers, given that
the "->" notation is already taken by symlinks, and nothing similar
exists on Posix systems (which Emacs on Windows emulates)?  And how to
indicate the fact that a file is a junction point in the output of
file-attributes?  Treating junctions as symlinks will cause trouble,
because a junction has restrictions that need to be observed.

So, on balance, I don't think we should add this to Emacs.

> That gets its information from dired.c (which I am not looking at), which 
> populates a string for (file-attribute-type file-attr) in the case of symbolic link,
> but does not do the same for Junction.  So I think maybe a change in dired.c 
> for Windows might be necessary.

The current support for symlink is not in dired.c, it is in w32.c,
where we have our custom implementation of the 'stat' and 'lstat'
functions, which have symlink support built-in.

> This page discusses an approach to interrogating a file on Windows to determine if it is a Symlink or Junction: 
> 
> https://sourceware.org/pipermail/cygwin/2023-November/254786.html
> 
> 	  HANDLE h = ...
>           FILE_ATTRIBUTE_TAG_INFO at;
> 	  if (GetFileInformationByHandleEx (h, FileAttributeTagInfo,
> 					    &at, sizeof at))
> 	    {
> 	      if (at.FileAttributes & FILE_ATTRIBUTE_REPARSE_POINT)
> 	        {
> 		  /* Check at.ReparseTag:
> 		  IO_REPARSE_TAG_LX_SYMLINK: WSL symlink
> 		  IO_REPARSE_TAG_SYMLINK: Windows symlink
> 		  IO_REPARSE_TAG_MOUNT_POINT: Volume mount point
> 					      or directory junction
> 		  IO_REPARSE_TAG_APPEXECLINK: App execution alias
> 		  Anything else: *shrug*
> 		}
> 	    }

Thanks, this is well-known, and you will see that we have a similar
code in w32.c in the Emacs source tree.

Bottom line: I don't think we should add this to Emacs.  Other
opinions (with rationale) are welcome.