This is the mail archive of the
cygwin-developers
mailing list for the Cygwin project.
Utilize reparse points for symlinks
- From: Corinna Vinschen <corinna-cygwin at cygwin dot com>
- To: cygwin-developers at cygwin dot com
- Date: Thu, 23 Sep 2010 17:26:40 +0200
- Subject: Utilize reparse points for symlinks
- Reply-to: cygwin-developers at cygwin dot com
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;
} CYGWIN_REPARSE_BUFFER, *PCYGWIN_REPARSE_BUFFER;
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?
Corinna
(*) 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