From 1b29dfe82eab39b3fc91bfadb82c2822abcef859 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 11:26:48 -0600
Subject: ntdll: Perform the Unix-style hidden file check within the unified
 file info grabbing routine.

---
 dlls/ntdll/directory.c  | 13 +++++--------
 dlls/ntdll/file.c       | 10 ++++------
 dlls/ntdll/ntdll_misc.h |  2 +-
 3 files changed, 10 insertions(+), 15 deletions(-)

diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 94b6d77..9bb0e13 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1214,15 +1214,15 @@ void DIR_init_options(void)
  *
  * Check if the specified file should be hidden based on its name and the show dot files option.
  */
-BOOL DIR_is_hidden_file( const UNICODE_STRING *name )
+BOOL DIR_is_hidden_file( const char *name )
 {
-    WCHAR *p, *end;
+    char *p, *end;
 
     if (show_dot_files) return FALSE;
 
-    end = p = name->Buffer + name->Length/sizeof(WCHAR);
-    while (p > name->Buffer && IS_SEPARATOR(p[-1])) p--;
-    while (p > name->Buffer && !IS_SEPARATOR(p[-1])) p--;
+    end = p = (char *)name + strlen(name);
+    while (p > name && IS_SEPARATOR(p[-1])) p--;
+    while (p > name && !IS_SEPARATOR(p[-1])) p--;
     if (p == end || *p != '.') return FALSE;
     /* make sure it isn't '.' or '..' */
     if (p + 1 == end) return FALSE;
@@ -1437,9 +1437,6 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
         TRACE( "ignoring file %s\n", long_name );
         return NULL;
     }
-    if (!show_dot_files && long_name[0] == '.' && long_name[1] && (long_name[1] != '.' || long_name[2]))
-        attributes |= FILE_ATTRIBUTE_HIDDEN;
-
     total_len = dir_info_size( class, long_len );
     if (io->Information + total_len > max_length)
     {
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 0b4754e..cfd967e 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -213,6 +213,10 @@ int get_file_info( const char *path, struct stat *st, ULONG *attr )
         if (S_ISDIR( st->st_mode )) *attr |= FILE_ATTRIBUTE_REPARSE_POINT;
     }
     *attr |= get_file_attributes( st );
+    /* convert Unix-style hidden files to a DOS hidden file attribute */
+    if (DIR_is_hidden_file( path ))
+        *attr |= FILE_ATTRIBUTE_HIDDEN;
+    /* retrieve any stored DOS attributes */
     len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
     if (len == -1) return ret;
     *attr |= get_file_xattr( hexattr, len );
@@ -2997,8 +3001,6 @@ NTSTATUS WINAPI SYSCALL(NtQueryFullAttributesFile)( const OBJECT_ATTRIBUTES *att
             info->AllocationSize = std.AllocationSize;
             info->EndOfFile      = std.EndOfFile;
             info->FileAttributes = basic.FileAttributes;
-            if (DIR_is_hidden_file( attr->ObjectName ))
-                info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
         }
         RtlFreeAnsiString( &unix_name );
     }
@@ -3027,11 +3029,7 @@ NTSTATUS WINAPI SYSCALL(NtQueryAttributesFile)( const OBJECT_ATTRIBUTES *attr, F
         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 (DIR_is_hidden_file( attr->ObjectName ))
-                info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
-        }
         RtlFreeAnsiString( &unix_name );
     }
     else WARN("%s not found (%x)\n", debugstr_us(attr->ObjectName), status );
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 5ba1308..e46ba22 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -155,7 +155,7 @@ extern NTSTATUS fill_file_info( const struct stat *st, ULONG attr, void *ptr,
 extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
 extern void DIR_init_options(void) DECLSPEC_HIDDEN;
 extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ) DECLSPEC_HIDDEN;
-extern BOOL DIR_is_hidden_file( const UNICODE_STRING *name ) DECLSPEC_HIDDEN;
+extern BOOL DIR_is_hidden_file( const char *name ) DECLSPEC_HIDDEN;
 extern NTSTATUS DIR_unmount_device( HANDLE handle ) DECLSPEC_HIDDEN;
 extern NTSTATUS DIR_get_unix_cwd( char **cwd ) DECLSPEC_HIDDEN;
 extern unsigned int DIR_get_drives_info( struct drive_info info[MAX_DOS_DRIVES] ) DECLSPEC_HIDDEN;
-- 
2.6.1

