Utilize reparse points for symlinks

Corinna Vinschen corinna-cygwin@cygwin.com
Thu Sep 23 15:27:00 GMT 2010

Hi guys,

I experimented a bit further with reparse points, since it occured to me
that they are still an excellent method to implement symlinks on NTFS.

What we can't do is to use the offical symlink reparse point introduced
with Windows Vista for the well-known reasons.

However, what we *could* do is to go the official way and request a
Cygwin reparse point tag at Microsoft(*).  For testing I implemented
this method locally, using the offical REPARSE_GUID_DATA_BUFFER reserved
for 3PPs, a reparse tag 0x20007654, and a GUID I generated by using the
uuidgen tool from the Microsoft SDK.  Works fine, even as non-admin user,
unlike the native Vista symlinks.

Why am I pursuing this at all?

The reason is that a reparse point can be easily (read: quickly)
recognized by the DOS reparse attribute.  The reparse point content can
be read without having to use ReadFile, so the access time doesn't
change when reading it.  The reparse tag can even be recognized already
in readdir for free(**).

The reparse tag would be ours, so we can fill the structure with
whatever information we need, for a simple distinction between symlinks,
device files, pipes, and sockets, for instance:

  typedef struct {
    DWORD  ReparseTag;
    WORD   ReparseDataLength;
    WORD   Reserved;
    GUID   ReparseGuid;
    struct {
      mode_t mode;
      union {
	struct {
	  dev_t major;
	  dev_t minor;
	} device;
	struct {
	  uint16_t   type;	/* SOCK_STREAM / SOCK_DGRAM */
	  uint16_t   port;
	  uint32_t   secret[4];
	} socket;
	struct {
	  uint16_t len;
	  wchar_t  path[1];
	} symlink;
    } CygwinReparseBuffer;

The only downside is that reparse points are not supported by NT4 but
there are still the other two implementations available, which we need
for non-NTFS anyway.

Oh, and, I don't know if Microsoft assigns a reparse tag if the project
using it isn't an IFS.  That's something I'd have to ask first.

Thoughts?  Do you think this is worth looking into further?


(*) http://www.microsoft.com/whdc/devtools/ifskit/reparse.mspx

    Btw., this page contains a hint to a "publicly-viewable database",
    but no link to it.  I neither found it via google nor via MSDN search.
    Does anybody know how to find it?

(**) For a reparse point, the EaSize member in FILE_ID_BOTH_DIR_INFORMATION
     or FILE_BOTH_DIRECTORY_INFORMATION is set to the ReparseTag.

Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

More information about the Cygwin-developers mailing list