Ken Thomases : ntdll: Fix read_directory_getattrlist() to get the name of a symlink rather than its target, but still detect if the symlink is broken.

Alexandre Julliard julliard at wine.codeweavers.com
Thu May 21 07:24:22 CDT 2015


Module: wine
Branch: master
Commit: bb89f10e5ed690abd191941a6ba5ecadb7d70c12
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=bb89f10e5ed690abd191941a6ba5ecadb7d70c12

Author: Ken Thomases <ken at codeweavers.com>
Date:   Wed May 20 14:59:39 2015 -0500

ntdll: Fix read_directory_getattrlist() to get the name of a symlink rather than its target, but still detect if the symlink is broken.

---

 dlls/ntdll/directory.c | 18 ++++++++++++++++--
 1 file changed, 16 insertions(+), 2 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 267f019..1a8d9cc 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -47,6 +47,9 @@
 #ifdef HAVE_SYS_ATTR_H
 #include <sys/attr.h>
 #endif
+#ifdef HAVE_SYS_VNODE_H
+#include <sys/vnode.h>
+#endif
 #ifdef HAVE_SYS_IOCTL_H
 #include <sys/ioctl.h>
 #endif
@@ -2140,12 +2143,15 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
     int unix_len, ret, used_default;
     char *unix_name;
     struct attrlist attrlist;
+#include "pshpack4.h"
     struct
     {
         u_int32_t length;
         struct attrreference name_reference;
+        fsobj_type_t type;
         char name[NAME_MAX * 3 + 1];
     } attrlist_buffer;
+#include "poppack.h"
 
     TRACE("looking up file %s\n", debugstr_us( mask ));
 
@@ -2173,8 +2179,16 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
 
         memset( &attrlist, 0, sizeof(attrlist) );
         attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
-        attrlist.commonattr = ATTR_CMN_NAME;
-        ret = getattrlist( unix_name, &attrlist, &attrlist_buffer, sizeof(attrlist_buffer), 0 );
+        attrlist.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJTYPE;
+        ret = getattrlist( unix_name, &attrlist, &attrlist_buffer, sizeof(attrlist_buffer), FSOPT_NOFOLLOW );
+        /* If unix_name named a symlink, the above may have succeeded even if the symlink is broken.
+           Check that with another call without FSOPT_NOFOLLOW.  We don't ask for any attributes. */
+        if (!ret && attrlist_buffer.type == VLNK)
+        {
+            u_int32_t dummy;
+            attrlist.commonattr = 0;
+            ret = getattrlist( unix_name, &attrlist, &dummy, sizeof(dummy), 0 );
+        }
         if (!ret)
         {
             union file_directory_info *info = append_entry( buffer, io, length, attrlist_buffer.name, NULL, NULL, class );




More information about the wine-cvs mailing list