2008-10-21 8 views
12

Windows 6 (Vista et Server 2008) prend en charge les liens symboliques appropriés, qui peuvent être créés via la fonction CreateSymbolicLink. Mais il ne semble pas y avoir de fonction correspondante pour interroger un lien symbolique afin d'obtenir le chemin de la cible du lien.Comment accéder par programme au chemin cible d'un lien symbolique Windows?

J'ai découvert que les liens symboliques sont une implémentation de points d'analyse, et donc les fonctions de point d'analyse peuvent être utilisées pour obtenir le chemin cible. Mais les fichiers d'en-tête dont j'ai besoin pour utiliser les points d'analyse semblent venir avec le Windows Driver Kit. La configuration de ce kit avec VS2008 semble être une tâche non triviale.

Y a-t-il une fonction simple que j'ai manquée pour obtenir la cible d'un lien, ou dois-je vraiment mettre en place un environnement de développement de pilotes Windows pour écrire du code pour accéder à cette information?

EDIT: Adam Mitz a proposé la suggestion de GetFinalPathNameByHandle. Cette fonction fonctionne très bien pour les liens symboliques locaux, mais ne semble pas fonctionner pour résoudre les liens distants (via un chemin UNC).

EDIT 2: A la demande d'Adam, voici plus de détails sur ce que j'ai essayé:

je suis allé d'abord dans la voie FSCTL_GET_REPARSE_POINT/DeviceIoControl, mais qui donne une structure REPARSE_DATA_BUFFER. Les en-têtes qui définissent cette structure semblent exister uniquement dans le kit de pilotes Windows. Fonctionne correctement lorsque le lien existe sur un disque local (C:\...\link, etc.)

Curieusement, j'ai trouvé que je pouvais obtenir le handle du lien - et donc obtenir la cible - en utilisant CreateFileW() si le drapeau FILE_FLAG_OPEN_REPARSE_POINT était spécifié ou non, que le fichier cible existe ou non.

Lorsque CreateFileW() et GetFinalPathNameByHandle() sont utilisés pour interroger un lien distant (\\?\UNC\....), les choses commencent à se défaire. Si FILE_FLAG_OPEN_REPARSE_POINT est spécifié, GetFinalPathNameByHandle() renvoie toujours le chemin du lien, pas le chemin cible. Si FILE_FLAG_OPEN_REPARSE_POINT n'est pas spécifié, le chemin cible est renvoyé, mais uniquement si la cible existe et se trouve sur la même machine que le lien. Si le lien pointe vers une autre machine, j'obtiens une erreur d'autorisation réseau. Si le lien pointe vers un fichier local - inexistant -, j'obtiens une erreur de fichier introuvable.

+0

Veuillez préciser si le lien symbolique se trouve sur un serveur distant (via UNC) ou s'il s'agit d'une cible UNC. –

+0

Aussi, je ne pense pas que vous ayez besoin de DDK pour lire les points d'analyse (pas de "points d'analyse"). Voir l'indicateur FILE_FLAG_OPEN_REPARSE_POINT sur CreateFile ou l'indicateur FSCTL_GET_REPARSE_POINT pour DeviceIoControl. Que cela aide ou non dépend de votre réponse à mon commentaire précédent. –

+0

Explorer fait en quelque sorte, je doute que ce soit directement en envoyant IO_CTL. Essayez-le: créez un lien symbolique de répertoire, le propriétés et vous obtiendrez un onglet "raccourci" avec une destination grisée. – Fowl

Répondre

13

GetFinalPathNameByHandle

Un chemin final est le chemin qui est retourné lorsqu'un chemin est entièrement résolu. Par exemple, pour un lien symbolique nommé "C: \ tmp \ mydir" qui pointe vers "D: \ yourdir", le chemin d'accès au système de fichiers final sera "D: \ yourdir".

+0

@Adam, malheureusement, alors que GetFinalPathNameByHandle() fonctionne pour un lien symbolique local, il renvoie le lien, pas la cible pour les liens symboliques UNC distants. J'ai donc "rouvert" la question. –

+0

Je pense que j'ai répondu à la question posée (même chose qu'avec votre question JNI/Mock BTW ... ahem). Peut-être que c'est une nouvelle question. –

+0

GetFinalPathNameByHandle est fondamentalement la réponse, si l'on veut seulement utiliser des liens locaux. Il semble qu'il y ait un bug dans la fonction en ce qui concerne les liens distants. J'ai donc marqué cette fois comme la bonne réponse, et documenté la mise en garde. –

Questions connexes