From: Torge Matthies tmatthies@codeweavers.com
--- dlls/ntdll/unix/file.c | 126 ++++++++++++++++++----------------------- 1 file changed, 56 insertions(+), 70 deletions(-)
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index d1bef8a0aff..dce59787ba6 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1555,8 +1555,40 @@ static int fd_get_file_stat( int fd, struct stat *st ) }
+static NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name ) +{ + data_size_t size = 1024; + NTSTATUS ret; + char *name; + + for (;;) + { + if (!(name = malloc( size + 1 ))) return STATUS_NO_MEMORY; + + SERVER_START_REQ( get_handle_unix_name ) + { + req->handle = wine_server_obj_handle( handle ); + wine_server_set_reply( req, name, size ); + ret = wine_server_call( req ); + size = reply->name_len; + } + SERVER_END_REQ; + + if (!ret) + { + name[size] = 0; + *unix_name = name; + break; + } + free( name ); + if (ret != STATUS_BUFFER_OVERFLOW) break; + } + return ret; +} + + /* get the stat info and file attributes for a file (by file descriptor) */ -static int fd_get_file_info( int fd, const char *unix_name, unsigned int options, struct stat *st, ULONG *attr ) +static int fd_get_file_info( int fd, char *unix_name, HANDLE handle, unsigned int options, struct stat *st, ULONG *attr ) { char attr_data[65]; int attr_len, ret; @@ -1576,6 +1608,12 @@ static int fd_get_file_info( int fd, const char *unix_name, unsigned int options { if (unix_name && is_hidden_file( unix_name )) *attr |= FILE_ATTRIBUTE_HIDDEN; + else if (handle && server_get_unix_name( handle, &unix_name )) + { + if (is_hidden_file( unix_name )) + *attr |= FILE_ATTRIBUTE_HIDDEN; + free( unix_name ); + } if (errno == ENOTSUP) return ret; #ifdef ENODATA if (errno == ENODATA) return ret; @@ -1924,38 +1962,6 @@ static NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr, return STATUS_SUCCESS; }
- -static NTSTATUS server_get_unix_name( HANDLE handle, char **unix_name ) -{ - data_size_t size = 1024; - NTSTATUS ret; - char *name; - - for (;;) - { - if (!(name = malloc( size + 1 ))) return STATUS_NO_MEMORY; - - SERVER_START_REQ( get_handle_unix_name ) - { - req->handle = wine_server_obj_handle( handle ); - wine_server_set_reply( req, name, size ); - ret = wine_server_call( req ); - size = reply->name_len; - } - SERVER_END_REQ; - - if (!ret) - { - name[size] = 0; - *unix_name = name; - break; - } - free( name ); - if (ret != STATUS_BUFFER_OVERFLOW) break; - } - return ret; -} - static NTSTATUS fill_name_info( const char *unix_name, FILE_NAME_INFORMATION *info, LONG *name_len ) { WCHAR *nt_name; @@ -4340,21 +4346,13 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, switch (class) { case FileBasicInformation: - { - char *unix_name; - - if (server_get_unix_name( handle, &unix_name )) - unix_name = NULL; - - if (fd_get_file_info( fd, unix_name, options, &st, &attr ) == -1) - status = errno_to_status( errno ); - else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) - status = STATUS_INVALID_INFO_CLASS; - else - fill_file_info( &st, attr, ptr, class ); - free( unix_name ); - break; - } + if (fd_get_file_info( fd, NULL, handle, options, &st, &attr ) == -1) + status = errno_to_status( errno ); + else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) + status = STATUS_INVALID_INFO_CLASS; + else + fill_file_info( &st, attr, ptr, class ); + break; case FileStandardInformation: { FILE_STANDARD_INFORMATION *info = ptr; @@ -4395,7 +4393,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, char *unix_name;
status = server_get_unix_name( handle, &unix_name ); - if (fd_get_file_info( fd, unix_name, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, unix_name, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else if (status) break; else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) @@ -4519,24 +4517,16 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileAttributeTagInformation: + if (fd_get_file_info( fd, NULL, handle, options, &st, &attr ) == -1) status = errno_to_status( errno ); + else { - char *unix_name; - - if (server_get_unix_name( handle, &unix_name )) - unix_name = NULL; - - if (fd_get_file_info( fd, unix_name, options, &st, &attr ) == -1) status = errno_to_status( errno ); - else - { - FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr; - info->FileAttributes = attr; - info->ReparseTag = 0; /* FIXME */ - if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, &st )) - info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; - } - free( unix_name ); - break; + FILE_ATTRIBUTE_TAG_INFORMATION *info = ptr; + info->FileAttributes = attr; + info->ReparseTag = 0; /* FIXME */ + if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, &st )) + info->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT; } + break; default: FIXME("Unsupported class (%d)\n", class); status = STATUS_NOT_IMPLEMENTED; @@ -4553,22 +4543,18 @@ static NTSTATUS refresh_file_attrs( HANDLE handle, BOOL force_set_xattr ) unsigned int options; BOOL needs_close; NTSTATUS status; - char *unix_name; struct stat st; ULONG attrib; int fd;
if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, &options ))) return status; - if (server_get_unix_name( handle, &unix_name )) - unix_name = NULL;
- if (fd_get_file_info( fd, unix_name, options, &st, &attrib ) == -1) + if (fd_get_file_info( fd, NULL, handle, options, &st, &attrib ) == -1) status = errno_to_status( errno ); else status = fd_set_file_info( fd, attrib, force_set_xattr );
- free( unix_name ); if (needs_close) close( fd ); return status;