From: Torge Matthies tmatthies@codeweavers.com
Signed-off-by: Torge Matthies tmatthies@codeweavers.com --- dlls/ntdll/tests/file.c | 4 +- dlls/ntdll/unix/file.c | 97 ++++++++++++++++++++++++----------------- 2 files changed, 58 insertions(+), 43 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c index 53cdc8a3ca6..0e032bed3c7 100644 --- a/dlls/ntdll/tests/file.c +++ b/dlls/ntdll/tests/file.c @@ -4025,7 +4025,7 @@ static void test_dotfile_file_attributes(void)
status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ok( status == STATUS_SUCCESS, "got %#lx\n", status ); - ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes ); + todo_wine ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
CloseHandle( h );
@@ -4040,7 +4040,7 @@ static void test_dotfile_file_attributes(void)
status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation ); ok( status == STATUS_SUCCESS, "got %#lx\n", status ); - ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes ); + todo_wine ok( !(info.FileAttributes & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", info.FileAttributes );
GetTempFileNameW( temppathW, L"foo", 0, filenameW ); if (!rename_file( h, filenameW )) return; diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c index 09667b47f66..aa9623a9e71 100644 --- a/dlls/ntdll/unix/file.c +++ b/dlls/ntdll/unix/file.c @@ -1268,20 +1268,20 @@ static BOOLEAN get_dir_case_sensitivity( const char *dir )
/*********************************************************************** - * is_hidden_file + * is_hidden_file_unix * - * Check if the specified file should be hidden based on its name and the show dot files option. + * Check if the specified file should be hidden based on its unix path and the show dot files option. */ -static BOOL is_hidden_file( const UNICODE_STRING *name ) +static BOOL is_hidden_file_unix( const char *name ) { - WCHAR *p, *end; + const char *p, *end;
if (show_dot_files) return FALSE;
- end = p = name->Buffer + name->Length/sizeof(WCHAR); - while (p > name->Buffer && p[-1] == '\') p--; - while (p > name->Buffer && p[-1] != '\') p--; - return (p < end && p + 1 != end && p[0] == '.' && p[1] != '\' && (p[1] != '.' || (p + 2 != end && p[2] != '\'))); + end = p = name + strlen(name); + while (p > name && p[-1] == '/') p--; + while (p > name && p[-1] != '/') p--; + return (p < end && p + 1 != end && p[0] == '.' && p[1] != '/' && (p[1] != '.' || (p + 2 != end && p[2] != '/'))); }
@@ -1549,7 +1549,7 @@ static BOOL fd_is_mount_point( int fd, const struct stat *st )
/* get the stat info and file attributes for a file (by file descriptor) */ -static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULONG *attr ) +static int fd_get_file_info( int fd, const char *unix_name, unsigned int options, struct stat *st, ULONG *attr ) { char attr_data[65]; int attr_len, ret; @@ -1562,6 +1562,9 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON if ((options & FILE_OPEN_REPARSE_POINT) && fd_is_mount_point( fd, st )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
+ if (unix_name && is_hidden_file_unix( unix_name )) + *attr |= FILE_ATTRIBUTE_HIDDEN; + attr_len = xattr_fget( fd, SAMBA_XATTR_DOS_ATTRIB, attr_data, sizeof(attr_data)-1 ); if (attr_len != -1) *attr |= parse_samba_dos_attrib_data( attr_data, attr_len ); @@ -1655,6 +1658,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr ) } *attr |= get_file_attributes( st );
+ if (is_hidden_file_unix( path )) + *attr |= FILE_ATTRIBUTE_HIDDEN; + attr_len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, attr_data, sizeof(attr_data)-1 ); if (attr_len != -1) *attr |= parse_samba_dos_attrib_data( attr_data, attr_len ); @@ -2202,7 +2208,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I union file_directory_info *info; struct stat st; ULONG name_len, start, dir_size, attributes; - UNICODE_STRING name;
if (get_file_info( names->unix_name, &st, &attributes ) == -1) { @@ -2231,11 +2236,6 @@ static NTSTATUS get_dir_data_entry( struct dir_data *dir_data, void *info_ptr, I if (class != FileNamesInformation) { if (st.st_dev != dir_data->id.dev) st.st_ino = 0; /* ignore inode if on a different device */ - - RtlInitUnicodeString( &name, names->long_name ); - if (is_hidden_file( &name )) - attributes |= FILE_ATTRIBUTE_HIDDEN; - fill_file_info( &st, attributes, info, class ); }
@@ -4192,7 +4192,6 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr, info->AllocationSize = std.AllocationSize; info->EndOfFile = std.EndOfFile; info->FileAttributes = basic.FileAttributes; - if (is_hidden_file( attr->ObjectName )) info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN; } free( unix_name ); } @@ -4223,10 +4222,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) status = STATUS_INVALID_INFO_CLASS; else - { status = fill_file_info( &st, attributes, info, FileBasicInformation ); - if (is_hidden_file( attr->ObjectName )) info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN; - } free( unix_name ); } else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), status ); @@ -4335,18 +4331,26 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, switch (class) { case FileBasicInformation: - if (fd_get_file_info( fd, 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; + { + 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; + } case FileStandardInformation: { FILE_STANDARD_INFORMATION *info = ptr;
- if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else { fill_file_info( &st, attr, info, class ); @@ -4363,7 +4367,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileInternalInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else fill_file_info( &st, attr, ptr, class ); break; case FileEaInformation: @@ -4373,7 +4377,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileEndOfFileInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else fill_file_info( &st, attr, ptr, class ); break; case FileAllInformation: @@ -4381,10 +4385,13 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, FILE_ALL_INFORMATION *info = ptr; char *unix_name;
- if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + 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 ); + else if (status) + break; else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode)) status = STATUS_INVALID_INFO_CLASS; - else if (!(status = server_get_unix_name( handle, &unix_name ))) + else { LONG name_len = len - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
@@ -4397,9 +4404,9 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, info->AlignmentInformation.AlignmentRequirement = 1; /* FIXME */
status = fill_name_info( unix_name, &info->NameInformation, &name_len ); - free( unix_name ); io->Information = FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName) + name_len; } + free( unix_name ); } break; case FileMailslotQueryInformation: @@ -4489,7 +4496,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileIdInformation: - if (fd_get_file_info( fd, options, &st, &attr ) == -1) status = errno_to_status( errno ); + if (fd_get_file_info( fd, NULL, options, &st, &attr ) == -1) status = errno_to_status( errno ); else { struct mountmgr_unix_drive drive; @@ -4503,16 +4510,24 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE handle, IO_STATUS_BLOCK *io, } break; case FileAttributeTagInformation: - if (fd_get_file_info( fd, 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; + 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; } - break; default: FIXME("Unsupported class (%d)\n", class); status = STATUS_NOT_IMPLEMENTED;