Added patch to implement DOS hidden/system file attributes.

This commit is contained in:
Erich E. Hoover
2014-08-20 19:22:07 -06:00
parent 2ae83d8d8e
commit fa92b283ed
28 changed files with 1388 additions and 226 deletions

View File

@@ -0,0 +1,68 @@
From 7922ba3b2a5414d30053821394962afed4e5b13c Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 19 Aug 2014 20:31:00 -0600
Subject: ntdll: Unify retrieving the attributes of a file.
---
dlls/ntdll/file.c | 25 +++++++++++++++++--------
1 file changed, 17 insertions(+), 8 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 92d9829..78c375a 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1774,6 +1774,21 @@ static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime,
#endif
}
+/* fetch the attributes of a file */
+static inline ULONG get_file_attributes( const struct stat *st )
+{
+ ULONG attr;
+
+ if (S_ISDIR(st->st_mode))
+ attr = FILE_ATTRIBUTE_DIRECTORY;
+ else
+ attr = FILE_ATTRIBUTE_ARCHIVE;
+ if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
+ attr |= FILE_ATTRIBUTE_READONLY;
+ return attr;
+}
+
+
/* fill in the file information that depends on the stat info */
NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class )
{
@@ -1785,10 +1800,7 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
get_file_times( st, &info->LastWriteTime, &info->ChangeTime,
&info->LastAccessTime, &info->CreationTime );
- if (S_ISDIR(st->st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
- else info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
- if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
- info->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+ info->FileAttributes = get_file_attributes( st );
}
break;
case FileStandardInformation:
@@ -1842,16 +1854,13 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
{
info->AllocationSize.QuadPart = 0;
info->EndOfFile.QuadPart = 0;
- info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
}
else
{
info->AllocationSize.QuadPart = (ULONGLONG)st->st_blocks * 512;
info->EndOfFile.QuadPart = st->st_size;
- info->FileAttributes = FILE_ATTRIBUTE_ARCHIVE;
}
- if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
- info->FileAttributes |= FILE_ATTRIBUTE_READONLY;
+ info->FileAttributes = get_file_attributes( st );
}
break;
case FileIdFullDirectoryInformation:
--
1.7.9.5

View File

@@ -0,0 +1,408 @@
From 07b0e6fe66d8ac19d7584f52a066d2957d858144 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 19 Aug 2014 22:10:49 -0600
Subject: ntdll: Implement retrieving DOS attributes in
NtQueryInformationFile.
---
configure.ac | 12 +++++++
dlls/ntdll/directory.c | 3 +-
dlls/ntdll/file.c | 80 ++++++++++++++++++++++++++++++++++++-----------
dlls/ntdll/ntdll_misc.h | 2 +-
include/wine/port.h | 11 +++++++
libs/port/Makefile.in | 3 +-
libs/port/xattr.c | 61 ++++++++++++++++++++++++++++++++++++
7 files changed, 150 insertions(+), 22 deletions(-)
create mode 100644 libs/port/xattr.c
diff --git a/configure.ac b/configure.ac
index 7de7a87..b77c12f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -75,6 +75,7 @@ AC_ARG_WITH(pthread, AS_HELP_STRING([--without-pthread],[do not use the pthrea
AC_ARG_WITH(sane, AS_HELP_STRING([--without-sane],[do not use SANE (scanner support)]))
AC_ARG_WITH(tiff, AS_HELP_STRING([--without-tiff],[do not use TIFF]))
AC_ARG_WITH(v4l, AS_HELP_STRING([--without-v4l],[do not use v4l1 (v4l support)]))
+AC_ARG_WITH(xattr, AS_HELP_STRING([--without-xattr],[do not use xattr (security attributes support)]))
AC_ARG_WITH(xcomposite,AS_HELP_STRING([--without-xcomposite],[do not use the Xcomposite extension]),
[if test "x$withval" = "xno"; then ac_cv_header_X11_extensions_Xcomposite_h=no; fi])
AC_ARG_WITH(xcursor, AS_HELP_STRING([--without-xcursor],[do not use the Xcursor extension]),
@@ -667,6 +668,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
#include <sys/socket.h>
#endif])
+if test "x$with_xattr" != "xno"
+then
+ AC_CHECK_HEADERS(attr/xattr.h sys/xattr.h sys/extattr.h ,HAVE_XATTR=1)
+fi
+if test "x$with_xattr" == "xyes"
+then
+ WINE_ERROR_WITH(xattr,[test "x$HAVE_XATTR" = "x"],[xattr ${notice_platform}development files not \
+found. Wine will be built without extended attribute support, which probably isn't what you want. \
+You will need to install ${notice_platform}development packages of libacl at the very least.])
+fi
+
dnl **** Check for working dll ****
AC_SUBST(dlldir,"\${libdir}/wine")
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index a2796b2..678aef5 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1381,6 +1381,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
WCHAR *filename;
UNICODE_STRING str;
ULONG attributes = 0;
+ ULONG xattr = 0;
io->u.Status = STATUS_SUCCESS;
long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN );
@@ -1440,7 +1441,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
info = (union file_directory_info *)((char *)info_ptr + io->Information);
if (st.st_dev != curdir.dev) st.st_ino = 0; /* ignore inode if on a different device */
/* all the structures start with a FileDirectoryInformation layout */
- fill_stat_info( &st, info, class );
+ fill_file_info( xattr, &st, info, class );
info->dir.NextEntryOffset = total_len;
info->dir.FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
info->dir.FileAttributes |= attributes;
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 78c375a..c8176dd 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -103,6 +103,41 @@ mode_t FILE_umask = 0;
static const WCHAR ntfsW[] = {'N','T','F','S'};
+/* Match the conventions as Samba 3 for storing DOS file attributes;
+ * see {get,set}_ea_dos_attribute() in http://gitweb.samba.org/?p=samba.git;a=blob;f=source3/smbd/dosmode.c
+ * In particular, encode FILE_ATTRIBUTE_* as the string 0x followed by one or two hexadecimal digits.
+ * Differences from Samba 3:
+ * Wine currently only stores hidden and system in xattrs;
+ * Samba 3 also seems to store the readonly and directory bits.
+ * Samba 4 additionally supports NT security descriptors with a different xattr
+ */
+#define SAMBA_XATTR_DOS_ATTRIB XATTR_USER_PREFIX "DOSATTRIB"
+/* We are only interested in some attributes, the others have corresponding Unix attributes */
+#define XATTR_ATTRIBS_MASK (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM)
+
+static inline int get_file_xattr( char *hexattr, int attrlen )
+{
+ if (attrlen > 2 && hexattr[0] == '0' && hexattr[1] == 'x')
+ {
+ hexattr[attrlen] = 0;
+ return strtol( hexattr+2, NULL, 16 ) & XATTR_ATTRIBS_MASK;
+ }
+ return 0;
+}
+
+int fd_get_file_info( int fd, struct stat *st, ULONG *xattr )
+{
+ int len, ret = fstat( fd, st );
+ char hexattr[10];
+
+ *xattr = 0;
+ if (ret == -1) return ret;
+ len = xattr_fget( fd, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *xattr |= get_file_xattr( hexattr, len );
+ return ret;
+}
+
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -1775,7 +1810,7 @@ static inline void get_file_times( const struct stat *st, LARGE_INTEGER *mtime,
}
/* fetch the attributes of a file */
-static inline ULONG get_file_attributes( const struct stat *st )
+static inline ULONG get_file_attributes( const ULONG xattr, const struct stat *st )
{
ULONG attr;
@@ -1783,6 +1818,10 @@ static inline ULONG get_file_attributes( const struct stat *st )
attr = FILE_ATTRIBUTE_DIRECTORY;
else
attr = FILE_ATTRIBUTE_ARCHIVE;
+
+ /* if any extended attributes exist then add them to the traditional attributes */
+ attr |= xattr;
+
if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
attr |= FILE_ATTRIBUTE_READONLY;
return attr;
@@ -1790,7 +1829,7 @@ static inline ULONG get_file_attributes( const struct stat *st )
/* fill in the file information that depends on the stat info */
-NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class )
+NTSTATUS fill_file_info( const ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class )
{
switch (class)
{
@@ -1800,7 +1839,7 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
get_file_times( st, &info->LastWriteTime, &info->ChangeTime,
&info->LastAccessTime, &info->CreationTime );
- info->FileAttributes = get_file_attributes( st );
+ info->FileAttributes = get_file_attributes( xattr, st );
}
break;
case FileStandardInformation:
@@ -1836,9 +1875,9 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
case FileAllInformation:
{
FILE_ALL_INFORMATION *info = ptr;
- fill_stat_info( st, &info->BasicInformation, FileBasicInformation );
- fill_stat_info( st, &info->StandardInformation, FileStandardInformation );
- fill_stat_info( st, &info->InternalInformation, FileInternalInformation );
+ fill_file_info( xattr, st, &info->BasicInformation, FileBasicInformation );
+ fill_file_info( xattr, st, &info->StandardInformation, FileStandardInformation );
+ fill_file_info( xattr, st, &info->InternalInformation, FileInternalInformation );
}
break;
/* all directory structures start with the FileDirectoryInformation layout */
@@ -1860,21 +1899,21 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
info->AllocationSize.QuadPart = (ULONGLONG)st->st_blocks * 512;
info->EndOfFile.QuadPart = st->st_size;
}
- info->FileAttributes = get_file_attributes( st );
+ info->FileAttributes = get_file_attributes( xattr, st );
}
break;
case FileIdFullDirectoryInformation:
{
FILE_ID_FULL_DIRECTORY_INFORMATION *info = ptr;
info->FileId.QuadPart = st->st_ino;
- fill_stat_info( st, info, FileDirectoryInformation );
+ fill_file_info( xattr, st, info, FileDirectoryInformation );
}
break;
case FileIdBothDirectoryInformation:
{
FILE_ID_BOTH_DIRECTORY_INFORMATION *info = ptr;
info->FileId.QuadPart = st->st_ino;
- fill_stat_info( st, info, FileDirectoryInformation );
+ fill_file_info( xattr, st, info, FileDirectoryInformation );
}
break;
@@ -2026,6 +2065,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
struct stat st;
int fd, needs_close = FALSE;
+ ULONG xattr;
TRACE("(%p,%p,%p,0x%08x,0x%08x)\n", hFile, io, ptr, len, class);
@@ -2050,12 +2090,12 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
switch (class)
{
case FileBasicInformation:
- if (fstat( fd, &st ) == -1)
+ if (fd_get_file_info( fd, &st, &xattr ) == -1)
io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
else
- fill_stat_info( &st, ptr, class );
+ fill_file_info( xattr, &st, ptr, class );
break;
case FileStandardInformation:
{
@@ -2064,7 +2104,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
else
{
- fill_stat_info( &st, info, class );
+ fill_file_info( xattr, &st, info, class );
info->DeletePending = FALSE; /* FIXME */
}
}
@@ -2079,7 +2119,7 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
break;
case FileInternalInformation:
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
- else fill_stat_info( &st, ptr, class );
+ else fill_file_info( xattr, &st, ptr, class );
break;
case FileEaInformation:
{
@@ -2089,21 +2129,21 @@ NTSTATUS WINAPI NtQueryInformationFile( HANDLE hFile, PIO_STATUS_BLOCK io,
break;
case FileEndOfFileInformation:
if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
- else fill_stat_info( &st, ptr, class );
+ else fill_file_info( xattr, &st, ptr, class );
break;
case FileAllInformation:
{
FILE_ALL_INFORMATION *info = ptr;
ANSI_STRING unix_name;
- if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
+ if (fd_get_file_info( fd, &st, &xattr ) == -1) io->u.Status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
io->u.Status = STATUS_INVALID_INFO_CLASS;
else if (!(io->u.Status = server_get_unix_name( hFile, &unix_name )))
{
LONG name_len = len - FIELD_OFFSET(FILE_ALL_INFORMATION, NameInformation.FileName);
- fill_stat_info( &st, info, FileAllInformation );
+ fill_file_info( xattr, &st, info, FileAllInformation );
info->StandardInformation.DeletePending = FALSE; /* FIXME */
info->EaInformation.EaSize = 0;
info->AccessInformation.AccessFlags = 0; /* FIXME */
@@ -2455,6 +2495,7 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
+ ULONG xattr = 0;
if (stat( unix_name.Buffer, &st ) == -1)
status = FILE_GetNtStatus();
@@ -2465,8 +2506,8 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
FILE_BASIC_INFORMATION basic;
FILE_STANDARD_INFORMATION std;
- fill_stat_info( &st, &basic, FileBasicInformation );
- fill_stat_info( &st, &std, FileStandardInformation );
+ fill_file_info( xattr, &st, &basic, FileBasicInformation );
+ fill_file_info( xattr, &st, &std, FileStandardInformation );
info->CreationTime = basic.CreationTime;
info->LastAccessTime = basic.LastAccessTime;
@@ -2497,6 +2538,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
+ ULONG xattr = 0;
if (stat( unix_name.Buffer, &st ) == -1)
status = FILE_GetNtStatus();
@@ -2504,7 +2546,7 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
status = STATUS_INVALID_INFO_CLASS;
else
{
- status = fill_stat_info( &st, info, FileBasicInformation );
+ status = fill_file_info( xattr, &st, info, FileBasicInformation );
if (DIR_is_hidden_file( attr->ObjectName ))
info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
}
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index 4370084..ec96427 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -148,7 +148,7 @@ extern NTSTATUS COMM_FlushBuffersFile( int fd ) DECLSPEC_HIDDEN;
/* file I/O */
struct stat;
extern NTSTATUS FILE_GetNtStatus(void) DECLSPEC_HIDDEN;
-extern NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
+extern NTSTATUS fill_file_info( ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) 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;
diff --git a/include/wine/port.h b/include/wine/port.h
index 3548a44..715a9e2 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -363,6 +363,17 @@ extern int mkstemps(char *template, int suffix_len);
extern int _spawnvp(int mode, const char *cmdname, const char * const argv[]);
#endif
+/* Extended attribute functions */
+
+#ifndef XATTR_USER_PREFIX
+#define XATTR_USER_PREFIX "user."
+#endif
+#ifndef XATTR_USER_PREFIX_LEN
+#define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
+#endif
+
+extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
+
/* Interlocked functions */
#if defined(__GNUC__) && (defined(__i386__) || defined(__x86_64__))
diff --git a/libs/port/Makefile.in b/libs/port/Makefile.in
index 65f1714..67efbc7 100644
--- a/libs/port/Makefile.in
+++ b/libs/port/Makefile.in
@@ -23,4 +23,5 @@ C_SRCS = \
strerror.c \
strncasecmp.c \
symlink.c \
- usleep.c
+ usleep.c \
+ xattr.c
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
new file mode 100644
index 0000000..8b64867
--- /dev/null
+++ b/libs/port/xattr.c
@@ -0,0 +1,61 @@
+/*
+ * extended attributes functions
+ *
+ * Copyright 2014 Erich E. Hoover
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
+ */
+
+#include "config.h"
+#include "wine/port.h"
+
+#ifdef HAVE_SYS_XATTR_H
+# include <sys/xattr.h>
+#endif
+#ifdef HAVE_ATTR_XATTR_H
+# include <attr/xattr.h>
+#endif
+#ifdef HAVE_SYS_EXTATTR_H
+# include <sys/extattr.h>
+#endif
+
+#include <ctype.h>
+#include <errno.h>
+
+static inline int xattr_valid_namespace( const char *name )
+{
+ if (strncmp( XATTR_USER_PREFIX, name, XATTR_USER_PREFIX_LEN ) != 0)
+ {
+ errno = EPERM;
+ return 0;
+ }
+ return 1;
+}
+
+int xattr_fget( int filedes, const char *name, void *value, size_t size )
+{
+ if (!xattr_valid_namespace( name )) return -1;
+#if defined(HAVE_ATTR_XATTR_H)
+ return fgetxattr( filedes, name, value, size );
+#elif defined(HAVE_SYS_XATTR_H)
+ return fgetxattr( filedes, name, value, size, 0, 0 );
+#elif defined(HAVE_SYS_EXTATTR_H)
+ return extattr_get_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
+ value, size );
+#else
+ errno = ENOTSUP;
+ return -1;
+#endif
+}
--
1.7.9.5

View File

@@ -0,0 +1,106 @@
From aca454765b4a1cd8b7a50761fb0bd9f82043b895 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 16:04:34 -0600
Subject: ntdll: Implement retrieving DOS attributes in
NtQuery[Full]AttributesFile.
---
dlls/ntdll/file.c | 28 ++++++++++++++++++++++++----
include/wine/port.h | 1 +
libs/port/xattr.c | 16 ++++++++++++++++
3 files changed, 41 insertions(+), 4 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index c8176dd..8b2f398 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -138,6 +138,26 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *xattr )
return ret;
}
+int get_file_info( const char *path, struct stat *st, ULONG *xattr )
+{
+ char hexattr[10];
+ int len, ret;
+
+ *xattr = 0;
+ ret = lstat( path, st );
+ if (ret == -1) return ret;
+ if (S_ISLNK( st->st_mode ))
+ {
+ ret = stat( path, st );
+ if (ret == -1) return ret;
+ if (S_ISDIR( st->st_mode )) *xattr |= FILE_ATTRIBUTE_REPARSE_POINT;
+ }
+ len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *xattr |= get_file_xattr( hexattr, len );
+ return ret;
+}
+
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -2495,9 +2515,9 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
- ULONG xattr = 0;
+ ULONG xattr;
- if (stat( unix_name.Buffer, &st ) == -1)
+ if (get_file_info( unix_name.Buffer, &st, &xattr ) == -1)
status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
@@ -2538,9 +2558,9 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
if (!(status = nt_to_unix_file_name_attr( attr, &unix_name, FILE_OPEN )))
{
struct stat st;
- ULONG xattr = 0;
+ ULONG xattr;
- if (stat( unix_name.Buffer, &st ) == -1)
+ if (get_file_info( unix_name.Buffer, &st, &xattr ) == -1)
status = FILE_GetNtStatus();
else if (!S_ISREG(st.st_mode) && !S_ISDIR(st.st_mode))
status = STATUS_INVALID_INFO_CLASS;
diff --git a/include/wine/port.h b/include/wine/port.h
index 715a9e2..7d8ea1a 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -373,6 +373,7 @@ extern int _spawnvp(int mode, const char *cmdname, const char * const argv[]);
#endif
extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
+extern int xattr_get( const char *path, const char *name, void *value, size_t size );
/* Interlocked functions */
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
index 8b64867..0d77ce3 100644
--- a/libs/port/xattr.c
+++ b/libs/port/xattr.c
@@ -59,3 +59,19 @@ int xattr_fget( int filedes, const char *name, void *value, size_t size )
return -1;
#endif
}
+
+int xattr_get( const char *path, const char *name, void *value, size_t size )
+{
+ if (!xattr_valid_namespace( name )) return -1;
+#if defined(HAVE_ATTR_XATTR_H)
+ return getxattr( path, name, value, size );
+#elif defined(HAVE_SYS_XATTR_H)
+ return getxattr( path, name, value, size, 0, 0 );
+#elif defined(HAVE_SYS_EXTATTR_H)
+ return extattr_get_file( path, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
+ value, size );
+#else
+ errno = ENOTSUP;
+ return -1;
+#endif
+}
--
1.7.9.5

View File

@@ -0,0 +1,52 @@
From 2e97bfb51b37d8b3bd85a486b706bb1608ebd132 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 16:05:38 -0600
Subject: ntdll: Implement retrieving DOS attributes in NtQueryDirectoryFile.
---
dlls/ntdll/directory.c | 9 ++-------
dlls/ntdll/ntdll_misc.h | 1 +
2 files changed, 3 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 678aef5..9fb4b87 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1381,7 +1381,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
WCHAR *filename;
UNICODE_STRING str;
ULONG attributes = 0;
- ULONG xattr = 0;
+ ULONG xattr;
io->u.Status = STATUS_SUCCESS;
long_len = ntdll_umbstowcs( 0, long_name, strlen(long_name), long_nameW, MAX_DIR_ENTRY_LEN );
@@ -1418,12 +1418,7 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
if (!match_filename( &str, mask )) return NULL;
}
- if (lstat( long_name, &st ) == -1) return NULL;
- if (S_ISLNK( st.st_mode ))
- {
- if (stat( long_name, &st ) == -1) return NULL;
- if (S_ISDIR( st.st_mode )) attributes |= FILE_ATTRIBUTE_REPARSE_POINT;
- }
+ if (get_file_info( long_name, &st, &xattr ) == -1) return NULL;
if (is_ignored_file( &st ))
{
TRACE( "ignoring file %s\n", long_name );
diff --git a/dlls/ntdll/ntdll_misc.h b/dlls/ntdll/ntdll_misc.h
index ec96427..226bc85 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -148,6 +148,7 @@ extern NTSTATUS COMM_FlushBuffersFile( int fd ) DECLSPEC_HIDDEN;
/* file I/O */
struct stat;
extern NTSTATUS FILE_GetNtStatus(void) DECLSPEC_HIDDEN;
+extern int get_file_info( const char *path, struct stat *st, ULONG *xattr ) DECLSPEC_HIDDEN;
extern NTSTATUS fill_file_info( ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) DECLSPEC_HIDDEN;
extern void DIR_init_windows_dir( const WCHAR *windir, const WCHAR *sysdir ) DECLSPEC_HIDDEN;
--
1.7.9.5

View File

@@ -0,0 +1,185 @@
From 1313cd2f5b09593702acd6d71187afdd50ccea4d Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 00:08:52 -0600
Subject: ntdll: Implement storing DOS attributes in NtSetInformationFile.
---
dlls/ntdll/file.c | 50 ++++++++++++++++++++++++++++-------------------
dlls/ntdll/tests/file.c | 8 ++++----
include/wine/port.h | 2 ++
libs/port/xattr.c | 31 +++++++++++++++++++++++++++++
4 files changed, 67 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 8b2f398..1294888 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -138,6 +138,35 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *xattr )
return ret;
}
+NTSTATUS fd_set_file_info( int fd, ULONG attr )
+{
+ char hexattr[10];
+ struct stat st;
+ int len;
+
+ if (fstat( fd, &st ) == -1) return FILE_GetNtStatus();
+ if (attr & FILE_ATTRIBUTE_READONLY)
+ {
+ if (S_ISDIR( st.st_mode))
+ WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n");
+ else
+ st.st_mode &= ~0222; /* clear write permission bits */
+ }
+ else
+ {
+ /* add write permission only where we already have read permission */
+ st.st_mode |= (0600 | ((st.st_mode & 044) >> 1)) & (~FILE_umask);
+ }
+ if (fchmod( fd, st.st_mode ) == -1) return FILE_GetNtStatus();
+ attr &= ~FILE_ATTRIBUTE_NORMAL; /* do not store everything, but keep everything Samba can use */
+ len = sprintf( hexattr, "0x%x", attr );
+ if (attr != 0)
+ xattr_fset( fd, SAMBA_XATTR_DOS_ATTRIB, hexattr, len );
+ else
+ xattr_fremove( fd, SAMBA_XATTR_DOS_ATTRIB );
+ return STATUS_SUCCESS;
+}
+
int get_file_info( const char *path, struct stat *st, ULONG *xattr )
{
char hexattr[10];
@@ -2324,7 +2353,6 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
case FileBasicInformation:
if (len >= sizeof(FILE_BASIC_INFORMATION))
{
- struct stat st;
const FILE_BASIC_INFORMATION *info = ptr;
if ((io->u.Status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
@@ -2334,25 +2362,7 @@ NTSTATUS WINAPI NtSetInformationFile(HANDLE handle, PIO_STATUS_BLOCK io,
io->u.Status = set_file_times( fd, &info->LastWriteTime, &info->LastAccessTime );
if (io->u.Status == STATUS_SUCCESS && info->FileAttributes)
- {
- if (fstat( fd, &st ) == -1) io->u.Status = FILE_GetNtStatus();
- else
- {
- if (info->FileAttributes & FILE_ATTRIBUTE_READONLY)
- {
- if (S_ISDIR( st.st_mode))
- WARN("FILE_ATTRIBUTE_READONLY ignored for directory.\n");
- else
- st.st_mode &= ~0222; /* clear write permission bits */
- }
- else
- {
- /* add write permission only where we already have read permission */
- st.st_mode |= (0600 | ((st.st_mode & 044) >> 1)) & (~FILE_umask);
- }
- if (fchmod( fd, st.st_mode ) == -1) io->u.Status = FILE_GetNtStatus();
- }
- }
+ io->u.Status = fd_set_file_info( fd, info->FileAttributes );
if (needs_close) close( fd );
}
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index d70ed6b..7a8e5d4 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1234,7 +1234,7 @@ static void test_file_basic_information(void)
memset(&fbi, 0, sizeof(fbi));
res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
- todo_wine ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM\n", fbi.FileAttributes );
+ ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi.FileAttributes );
/* Then HIDDEN */
memset(&fbi, 0, sizeof(fbi));
@@ -1247,7 +1247,7 @@ static void test_file_basic_information(void)
memset(&fbi, 0, sizeof(fbi));
res = pNtQueryInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
- todo_wine ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN\n", fbi.FileAttributes );
+ ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fbi.FileAttributes );
/* Check NORMAL last of all (to make sure we can clear attributes) */
memset(&fbi, 0, sizeof(fbi));
@@ -1304,7 +1304,7 @@ static void test_file_all_information(void)
memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes, res %x\n", res);
- todo_wine ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM\n", fai_buf.fai.BasicInformation.FileAttributes );
+ ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %x not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes );
/* Then HIDDEN */
memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
@@ -1317,7 +1317,7 @@ static void test_file_all_information(void)
memset(&fai_buf.fai, 0, sizeof(fai_buf.fai));
res = pNtQueryInformationFile(h, &io, &fai_buf.fai, sizeof fai_buf, FileAllInformation);
ok ( res == STATUS_SUCCESS, "can't get attributes\n");
- todo_wine ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN\n", fai_buf.fai.BasicInformation.FileAttributes );
+ ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %x not FILE_ATTRIBUTE_HIDDEN (ok in old linux without xattr)\n", fai_buf.fai.BasicInformation.FileAttributes );
/* Check NORMAL last of all (to make sure we can clear attributes) */
memset(&fai_buf.fai.BasicInformation, 0, sizeof(fai_buf.fai.BasicInformation));
diff --git a/include/wine/port.h b/include/wine/port.h
index 7d8ea1a..af052da 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -373,6 +373,8 @@ extern int _spawnvp(int mode, const char *cmdname, const char * const argv[]);
#endif
extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
+extern int xattr_fremove( int filedes, const char *name );
+extern int xattr_fset( int filedes, const char *name, void *value, size_t size );
extern int xattr_get( const char *path, const char *name, void *value, size_t size );
/* Interlocked functions */
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
index 0d77ce3..2668cf9 100644
--- a/libs/port/xattr.c
+++ b/libs/port/xattr.c
@@ -60,6 +60,37 @@ int xattr_fget( int filedes, const char *name, void *value, size_t size )
#endif
}
+int xattr_fremove( int filedes, const char *name )
+{
+ if (!xattr_valid_namespace( name )) return -1;
+#if defined(HAVE_ATTR_XATTR_H)
+ return fremovexattr( filedes, name );
+#elif defined(HAVE_SYS_XATTR_H)
+ return fremovexattr( filedes, name, 0 );
+#elif defined(HAVE_SYS_EXTATTR_H)
+ return extattr_delete_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN] );
+#else
+ errno = ENOTSUP;
+ return -1;
+#endif
+}
+
+int xattr_fset( int filedes, const char *name, void *value, size_t size )
+{
+ if (!xattr_valid_namespace( name )) return -1;
+#if defined(HAVE_ATTR_XATTR_H)
+ return fsetxattr( filedes, name, value, size, 0 );
+#elif defined(HAVE_SYS_XATTR_H)
+ return fsetxattr( filedes, name, value, size, 0, 0 );
+#elif defined(HAVE_SYS_EXTATTR_H)
+ return extattr_set_fd( filedes, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
+ value, size );
+#else
+ errno = ENOTSUP;
+ return -1;
+#endif
+}
+
int xattr_get( const char *path, const char *name, void *value, size_t size )
{
if (!xattr_valid_namespace( name )) return -1;
--
1.7.9.5

View File

@@ -0,0 +1,237 @@
From f9c827c6a03c5741aebdcada20d512c9ceb44284 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 15:28:00 -0600
Subject: ntdll: Implement storing DOS attributes in NtCreateFile.
---
dlls/ntdll/file.c | 80 ++++++++++++++++++++++++++----------------
dlls/ntdll/tests/directory.c | 22 +++++-------
include/wine/port.h | 2 ++
libs/port/xattr.c | 31 ++++++++++++++++
4 files changed, 91 insertions(+), 44 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 1294888..6c278eb 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -187,6 +187,21 @@ int get_file_info( const char *path, struct stat *st, ULONG *xattr )
return ret;
}
+NTSTATUS set_file_info( const char *path, ULONG attr )
+{
+ char hexattr[10];
+ int len;
+
+ /* Note: unix mode already set when called this way */
+ attr &= ~FILE_ATTRIBUTE_NORMAL; /* do not store everything, but keep everything Samba can use */
+ len = sprintf( hexattr, "0x%x", attr );
+ if (attr != 0)
+ xattr_set( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, len );
+ else
+ xattr_remove( path, SAMBA_XATTR_DOS_ATTRIB );
+ return STATUS_SUCCESS;
+}
+
/**************************************************************************
* FILE_CreateFile (internal)
* Open a file.
@@ -198,6 +213,8 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
ULONG attributes, ULONG sharing, ULONG disposition,
ULONG options, PVOID ea_buffer, ULONG ea_length )
{
+ struct object_attributes objattr;
+ struct security_descriptor *sd;
ANSI_STRING unix_name;
BOOL created = FALSE;
@@ -240,40 +257,37 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
created = TRUE;
io->u.Status = STATUS_SUCCESS;
}
-
- if (io->u.Status == STATUS_SUCCESS)
+ else if (io->u.Status != STATUS_SUCCESS)
{
- struct security_descriptor *sd;
- struct object_attributes objattr;
-
- objattr.rootdir = wine_server_obj_handle( attr->RootDirectory );
- objattr.name_len = 0;
- io->u.Status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len );
- if (io->u.Status != STATUS_SUCCESS)
- {
- RtlFreeAnsiString( &unix_name );
- return io->u.Status;
- }
+ WARN("%s not found (%x)\n", debugstr_us(attr->ObjectName), io->u.Status );
+ return io->u.Status;
+ }
- SERVER_START_REQ( create_file )
- {
- req->access = access;
- req->attributes = attr->Attributes;
- req->sharing = sharing;
- req->create = disposition;
- req->options = options;
- req->attrs = attributes;
- wine_server_add_data( req, &objattr, sizeof(objattr) );
- if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
- wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
- io->u.Status = wine_server_call( req );
- *handle = wine_server_ptr_handle( reply->handle );
- }
- SERVER_END_REQ;
- NTDLL_free_struct_sd( sd );
+ objattr.rootdir = wine_server_obj_handle( attr->RootDirectory );
+ objattr.name_len = 0;
+ io->u.Status = NTDLL_create_struct_sd( attr->SecurityDescriptor, &sd, &objattr.sd_len );
+ if (io->u.Status != STATUS_SUCCESS)
+ {
RtlFreeAnsiString( &unix_name );
+ return io->u.Status;
}
- else WARN("%s not found (%x)\n", debugstr_us(attr->ObjectName), io->u.Status );
+
+ SERVER_START_REQ( create_file )
+ {
+ req->access = access;
+ req->attributes = attr->Attributes;
+ req->sharing = sharing;
+ req->create = disposition;
+ req->options = options;
+ req->attrs = attributes;
+ wine_server_add_data( req, &objattr, sizeof(objattr) );
+ if (objattr.sd_len) wine_server_add_data( req, sd, objattr.sd_len );
+ wine_server_add_data( req, unix_name.Buffer, unix_name.Length );
+ io->u.Status = wine_server_call( req );
+ *handle = wine_server_ptr_handle( reply->handle );
+ }
+ SERVER_END_REQ;
+ NTDLL_free_struct_sd( sd );
if (io->u.Status == STATUS_SUCCESS)
{
@@ -295,6 +309,11 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
io->Information = FILE_OVERWRITTEN;
break;
}
+ if (io->Information == FILE_CREATED)
+ {
+ /* set any DOS extended attributes */
+ set_file_info( unix_name.Buffer, attributes );
+ }
}
else if (io->u.Status == STATUS_TOO_MANY_OPENED_FILES)
{
@@ -302,6 +321,7 @@ static NTSTATUS FILE_CreateFile( PHANDLE handle, ACCESS_MASK access, POBJECT_ATT
if (!once++) ERR_(winediag)( "Too many open files, ulimit -n probably needs to be increased\n" );
}
+ RtlFreeAnsiString( &unix_name );
return io->u.Status;
}
diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c
index f190ff4..68b5406 100644
--- a/dlls/ntdll/tests/directory.c
+++ b/dlls/ntdll/tests/directory.c
@@ -51,7 +51,6 @@ static NTSTATUS (WINAPI *pRtlWow64EnableFsRedirectionEx)( ULONG disable, ULONG *
/* The attribute sets to test */
static struct testfile_s {
- BOOL todo; /* set if it doesn't work on wine yet */
BOOL attr_done; /* set if attributes were tested for this file already */
const DWORD attr; /* desired attribute */
const char *name; /* filename to use */
@@ -60,13 +59,13 @@ static struct testfile_s {
int nfound; /* How many were found (expect 1) */
WCHAR nameW[20]; /* unicode version of name (filled in later) */
} testfiles[] = {
- { 0, 0, FILE_ATTRIBUTE_NORMAL, "n.tmp", NULL, "normal" },
- { 1, 0, FILE_ATTRIBUTE_HIDDEN, "h.tmp", NULL, "hidden" },
- { 1, 0, FILE_ATTRIBUTE_SYSTEM, "s.tmp", NULL, "system" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, "d.tmp", NULL, "directory" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, ".", NULL, ". directory" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, "..", NULL, ".. directory" },
- { 0, 0, 0, NULL }
+ { 0, FILE_ATTRIBUTE_NORMAL, "n.tmp", NULL, "normal" },
+ { 0, FILE_ATTRIBUTE_HIDDEN, "h.tmp", NULL, "hidden" },
+ { 0, FILE_ATTRIBUTE_SYSTEM, "s.tmp", NULL, "system" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, "d.tmp", NULL, "directory" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, ".", NULL, ". directory" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, "..", NULL, ".. directory" },
+ { 0, 0, NULL }
};
static const int max_test_dir_size = 20; /* size of above plus some for .. etc */
@@ -147,12 +146,7 @@ static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info)
if (namelen != len || memcmp(nameW, testfiles[i].nameW, len*sizeof(WCHAR)))
continue;
if (!testfiles[i].attr_done) {
- if (testfiles[i].todo) {
- todo_wine
- ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", testfiles[i].name, testfiles[i].description, testfiles[i].attr, attrib);
- } else {
- ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", testfiles[i].name, testfiles[i].description, testfiles[i].attr, attrib);
- }
+ ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%x), got %x (is your linux new enough?)\n", testfiles[i].name, testfiles[i].description, testfiles[i].attr, attrib);
testfiles[i].attr_done = TRUE;
}
testfiles[i].nfound++;
diff --git a/include/wine/port.h b/include/wine/port.h
index af052da..f989731 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -376,6 +376,8 @@ extern int xattr_fget( int filedes, const char *name, void *value, size_t size )
extern int xattr_fremove( int filedes, const char *name );
extern int xattr_fset( int filedes, const char *name, void *value, size_t size );
extern int xattr_get( const char *path, const char *name, void *value, size_t size );
+extern int xattr_remove( const char *path, const char *name );
+extern int xattr_set( const char *path, const char *name, void *value, size_t size );
/* Interlocked functions */
diff --git a/libs/port/xattr.c b/libs/port/xattr.c
index 2668cf9..3093ecf 100644
--- a/libs/port/xattr.c
+++ b/libs/port/xattr.c
@@ -106,3 +106,34 @@ int xattr_get( const char *path, const char *name, void *value, size_t size )
return -1;
#endif
}
+
+int xattr_remove( const char *path, const char *name )
+{
+ if (!xattr_valid_namespace( name )) return -1;
+#if defined(HAVE_ATTR_XATTR_H)
+ return removexattr( path, name );
+#elif defined(HAVE_SYS_XATTR_H)
+ return removexattr( path, name, 0 );
+#elif defined(HAVE_SYS_EXTATTR_H)
+ return extattr_delete_file( path, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN] );
+#else
+ errno = ENOTSUP;
+ return -1;
+#endif
+}
+
+int xattr_set( const char *path, const char *name, void *value, size_t size )
+{
+ if (!xattr_valid_namespace( name )) return -1;
+#if defined(HAVE_ATTR_XATTR_H)
+ return setxattr( path, name, value, size, 0 );
+#elif defined(HAVE_SYS_XATTR_H)
+ return setxattr( path, name, value, size, 0, 0 );
+#elif defined(HAVE_SYS_EXTATTR_H)
+ return extattr_set_file( path, EXTATTR_NAMESPACE_USER, &name[XATTR_USER_PREFIX_LEN],
+ value, size );
+#else
+ errno = ENOTSUP;
+ return -1;
+#endif
+}
--
1.7.9.5

View File

@@ -0,0 +1,115 @@
From 398cf0a70a0d313bf84c4ff8335f49ca68e1ee84 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 | 15 +++++----------
dlls/ntdll/file.c | 8 ++------
dlls/ntdll/ntdll_misc.h | 2 +-
3 files changed, 8 insertions(+), 17 deletions(-)
diff --git a/dlls/ntdll/directory.c b/dlls/ntdll/directory.c
index 9fb4b87..726af4d 100644
--- a/dlls/ntdll/directory.c
+++ b/dlls/ntdll/directory.c
@@ -1198,17 +1198,17 @@ static DWORD WINAPI init_options( RTL_RUN_ONCE *once, void *param, void **contex
*
* 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;
RtlRunOnceExecuteOnce( &init_once, init_options, NULL, NULL );
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;
@@ -1380,7 +1380,6 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
WCHAR short_nameW[12];
WCHAR *filename;
UNICODE_STRING str;
- ULONG attributes = 0;
ULONG xattr;
io->u.Status = STATUS_SUCCESS;
@@ -1424,9 +1423,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)
{
@@ -1439,7 +1435,6 @@ static union file_directory_info *append_entry( void *info_ptr, IO_STATUS_BLOCK
fill_file_info( xattr, &st, info, class );
info->dir.NextEntryOffset = total_len;
info->dir.FileIndex = 0; /* NTFS always has 0 here, so let's not bother with it */
- info->dir.FileAttributes |= attributes;
switch (class)
{
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 6c278eb..91f96ee 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -173,6 +173,8 @@ int get_file_info( const char *path, struct stat *st, ULONG *xattr )
int len, ret;
*xattr = 0;
+ if (DIR_is_hidden_file( path ))
+ *xattr |= FILE_ATTRIBUTE_HIDDEN;
ret = lstat( path, st );
if (ret == -1) return ret;
if (S_ISLNK( st->st_mode ))
@@ -2566,8 +2568,6 @@ NTSTATUS WINAPI NtQueryFullAttributesFile( const OBJECT_ATTRIBUTES *attr,
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 );
}
@@ -2595,11 +2595,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( xattr, &st, 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 226bc85..be07d59 100644
--- a/dlls/ntdll/ntdll_misc.h
+++ b/dlls/ntdll/ntdll_misc.h
@@ -152,7 +152,7 @@ extern int get_file_info( const char *path, struct stat *st, ULONG *xattr ) DECL
extern NTSTATUS fill_file_info( ULONG xattr, const struct stat *st, void *ptr, FILE_INFORMATION_CLASS class ) DECLSPEC_HIDDEN;
extern NTSTATUS server_get_unix_name( HANDLE handle, ANSI_STRING *unix_name ) 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;
--
1.7.9.5

View File

@@ -0,0 +1,4 @@
Author: Erich E. Hoover
Subject: Implement DOS hidden/system file attributes
Revision: 1
Fixes: [9158] Support for DOS hidden/system file attributes