views:

1232

answers:

2

Windows 6 (Vista and Server 2008) support proper symbolic links, which can be created via the CreateSymbolicLink function. But there doesn't appear to be a corresponding function for interrogating a symbolic link to obtain the path of the link's target.

I have found out that symbolic links are an implementation of reparse points, and so the reparse point functions can be used to obtain the target path. But the header files that I need to use reparse points appear to come with the Windows Driver Kit. Setting up this kit with VS2008 appears to be a non trivial task.

Is there a nice simple function that I've missed for obtaining a link's target, or do I really have to set up a windows driver development environment just to write code to access this information?

EDIT: Adam Mitz came up with the suggestion of GetFinalPathNameByHandle. This function works just great for local symlinks, but doesn't appear to work for resolving remote links (via a UNC path).

EDIT 2: At Adam's request, here are more details of what I've tried:

I initially went down the FSCTL_GET_REPARSE_POINT/ DeviceIoControl route, but that yields a REPARSE_DATA_BUFFER structure. The headers that define this structure seem to exist solely within the Windows Driver Kit.

GetFinalPathNameByHandle() works fine when the link exists on a local disk (C:\...\link etc). Curiously, I found that I could obtain the handle to the link - and thus get the target - using CreateFileW() whether the FILE_FLAG_OPEN_REPARSE_POINT flag was specified or not, regardless of whether the target file exists.

When CreateFileW() and GetFinalPathNameByHandle() are used to interrogate a remote link though (\\?\UNC\....), things start to unravel. If FILE_FLAG_OPEN_REPARSE_POINT is specified, GetFinalPathNameByHandle() always returns the link path, not the target path. If FILE_FLAG_OPEN_REPARSE_POINT is not specified, then the target path is returned, but only if the target exists and is on the same machine as the link. If the link points to another machine, I get a network permissions error. If the link points to a local - non-existent - file, I get a file not found error.

A: 

Try this

http://msdn.microsoft.com/en-us/library/aa363940.aspx

I found the link on this page

http://msdn.microsoft.com/en-us/library/aa365460.aspx

The 4th bullet down

Nick Berardi
Unfortunately that flag simply indicates that the object is a symbolic link, it doesn't provide information on the target.
David Arno
+3  A: 

GetFinalPathNameByHandle

A final path is the path that is returned when a path is fully resolved. For example, for a symbolic link named "C:\tmp\mydir" that points to "D:\yourdir", the final filesystem path would be "D:\yourdir".

Adam Mitz
Perfect. That is exactly what I was looking for. Thanks.
David Arno
@Adam, unfortunately, whilst GetFinalPathNameByHandle() works for a local symlink, it returns the link, not the target for remote UNC-based symlinks. So I've "re-opened" the question.
David Arno
I think I answered the question as asked (same as with your JNI/Mock question BTW... ahem). Maybe this is a new question.
Adam Mitz
GetFinalPathNameByHandle is basically the answer, if one only wants to use local links. It looks like there is a bug in the function though as far as remote links are concerned. So I've marked this as the correct answer once more, and documented the caveat.
David Arno