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