Commit bb89f10e authored by Ken Thomases's avatar Ken Thomases Committed by Alexandre Julliard

ntdll: Fix read_directory_getattrlist() to get the name of a symlink rather than…

ntdll: Fix read_directory_getattrlist() to get the name of a symlink rather than its target, but still detect if the symlink is broken.
parent 46559245
...@@ -47,6 +47,9 @@ ...@@ -47,6 +47,9 @@
#ifdef HAVE_SYS_ATTR_H #ifdef HAVE_SYS_ATTR_H
#include <sys/attr.h> #include <sys/attr.h>
#endif #endif
#ifdef HAVE_SYS_VNODE_H
#include <sys/vnode.h>
#endif
#ifdef HAVE_SYS_IOCTL_H #ifdef HAVE_SYS_IOCTL_H
#include <sys/ioctl.h> #include <sys/ioctl.h>
#endif #endif
...@@ -2140,12 +2143,15 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer ...@@ -2140,12 +2143,15 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
int unix_len, ret, used_default; int unix_len, ret, used_default;
char *unix_name; char *unix_name;
struct attrlist attrlist; struct attrlist attrlist;
#include "pshpack4.h"
struct struct
{ {
u_int32_t length; u_int32_t length;
struct attrreference name_reference; struct attrreference name_reference;
fsobj_type_t type;
char name[NAME_MAX * 3 + 1]; char name[NAME_MAX * 3 + 1];
} attrlist_buffer; } attrlist_buffer;
#include "poppack.h"
TRACE("looking up file %s\n", debugstr_us( mask )); 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 ...@@ -2173,8 +2179,16 @@ static int read_directory_getattrlist( int fd, IO_STATUS_BLOCK *io, void *buffer
memset( &attrlist, 0, sizeof(attrlist) ); memset( &attrlist, 0, sizeof(attrlist) );
attrlist.bitmapcount = ATTR_BIT_MAP_COUNT; attrlist.bitmapcount = ATTR_BIT_MAP_COUNT;
attrlist.commonattr = ATTR_CMN_NAME; attrlist.commonattr = ATTR_CMN_NAME | ATTR_CMN_OBJTYPE;
ret = getattrlist( unix_name, &attrlist, &attrlist_buffer, sizeof(attrlist_buffer), 0 ); 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) if (!ret)
{ {
union file_directory_info *info = append_entry( buffer, io, length, attrlist_buffer.name, NULL, NULL, class ); union file_directory_info *info = append_entry( buffer, io, length, attrlist_buffer.name, NULL, NULL, class );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment