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

@ -13,7 +13,7 @@ which are not present in regular wine, and always report such issues to us
Included bugfixes and improvements
----------------------------------
**Bugfixes and features included in the next upcoming release [11]:**
**Bugfixes and features included in the next upcoming release [12]:**
* Adobe Reader requires NtProtectVirtualMemory and NtCreateSection to be on separate pages ([Wine Bug #33162](http://bugs.winehq.org/show_bug.cgi?id=33162 "Acrobat Reader 11 crashes on start (native API application virtualization, NtProtectVirtualMemory removes execute page protection on its own code)"))
* Fix ITERATE_MoveFiles when no source- and destname is specified ([Wine Bug #10085](http://bugs.winehq.org/show_bug.cgi?id=10085 "Adobe Bridge CS2 complains that it can't start due to licensing restrictions (affects photoshop)"))
@ -22,6 +22,7 @@ Included bugfixes and improvements
* Multiple applications need BCryptGetFipsAlgorithmMode ([Wine Bug #32194](http://bugs.winehq.org/show_bug.cgi?id=32194 "Multiple games and applications need bcrypt.dll.BCryptGetFipsAlgorithmMode (Chess Position Trainer, Terraria, .NET System.Security.Cryptography)"))
* Other Pipelight-specific enhancements
* Prevent window managers from grouping all wine programs together ([Wine Bug #32699](http://bugs.winehq.org/show_bug.cgi?id=32699 "Add StartupWMClass to .desktop files."))
* Support for DOS hidden/system file attributes ([Wine Bug #9158](http://bugs.winehq.org/show_bug.cgi?id=9158 "Multiple Microsoft development tools online/web installers fail to skip \"$shtdwn$.req\" with FILE_ATTRIBUTE_HIDDEN (Visual Studio Express Editions, .NET Framework 3.0)"))
* Support for DwmInvalidateIconicBitmaps ([Wine Bug #32977](http://bugs.winehq.org/show_bug.cgi?id=32977 "Solidworks 2012 needs unimplemented function dwmapi.dll.DwmInvalidateIconicBitmaps (Win7 mode)"))
* Support for Dynamic DST (daylight saving time) information in registry
* Support for GetFinalPathNameByHandle ([Wine Bug #36073](http://bugs.winehq.org/show_bug.cgi?id=36073 "OneDrive crashes on unimplemented function KERNEL32.dll.GetFinalPathNameByHandleW"))

1
debian/changelog vendored
View File

@ -2,6 +2,7 @@ wine-compholio (1.7.25) UNRELEASED; urgency=low
* Improve generation of README.md on patch update.
* Added patch with stub for DwmInvalidateIconicBitmaps.
* Added Courier Prime (OFLv1.1) as a Courier New replacement.
* Added patch to implement DOS hidden/system file attributes.
* Added patch to better detect broken nVidia RandR 1.2 support.
* Removed patch to return empty D3D hardware flags for RGB device enumeration (accepted upstream).
-- Erich E. Hoover <erich.e.hoover@gmail.com> Mon, 11 Aug 2014 16:21:22 -0600

View File

@ -26,6 +26,7 @@ PATCHLIST := \
libs-Unicode_Collation.ok \
loader-Cmdline_Diagnostics.ok \
msi-MoveFiles.ok \
ntdll-DOS_Attributes.ok \
ntdll-Dynamic_DST.ok \
ntdll-FD_Cache.ok \
ntdll-FileDispositionInformation.ok \
@ -423,6 +424,31 @@ msi-MoveFiles.ok:
echo '+ { "msi-MoveFiles", "Sebastian Lackner", "Fix ITERATE_MoveFiles when no source- and destname is specified." },'; \
) > msi-MoveFiles.ok
# Patchset ntdll-DOS_Attributes
# |
# | Included patches:
# | * Implement DOS hidden/system file attributes [by Erich E. Hoover]
# |
# | This patchset fixes the following Wine bugs:
# | * [#9158] Support for DOS hidden/system file attributes
# |
# | Modified files:
# | * configure.ac, dlls/ntdll/directory.c, dlls/ntdll/file.c, dlls/ntdll/ntdll_misc.h, dlls/ntdll/tests/directory.c,
# | dlls/ntdll/tests/file.c, include/wine/port.h, libs/port/Makefile.in, libs/port/xattr.c
# |
.INTERMEDIATE: ntdll-DOS_Attributes.ok
ntdll-DOS_Attributes.ok:
$(call APPLY_FILE,ntdll-DOS_Attributes/0001-ntdll-Unify-retrieving-the-attributes-of-a-file.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0002-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0003-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0004-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0005-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0006-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch)
$(call APPLY_FILE,ntdll-DOS_Attributes/0007-ntdll-Perform-the-Unix-style-hidden-file-check-withi.patch)
@( \
echo '+ { "ntdll-DOS_Attributes", "Erich E. Hoover", "Implement DOS hidden/system file attributes" },'; \
) > ntdll-DOS_Attributes.ok
# Patchset ntdll-Dynamic_DST
# |
# | Included patches:
@ -517,6 +543,7 @@ ntdll-Junction_Points.ok:
$(call APPLY_FILE,ntdll-Junction_Points/0005-kernel32-ntdll-Add-support-for-deleting-junction-poi.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0007-ntdll-tests-Add-test-for-deleting-junction-point-tar.patch)
$(call APPLY_FILE,ntdll-Junction_Points/0008-ntdll-Use-relative-paths-for-creating-links.patch)
@( \
echo '+ { "ntdll-Junction_Points", "Erich E. Hoover", "Support for junction points/reparse points." },'; \
) > ntdll-Junction_Points.ok
@ -620,7 +647,7 @@ riched20-IText_Interface.ok:
# |
.INTERMEDIATE: server-ACL_Compat.ok
server-ACL_Compat.ok: server-Inherited_ACLs.ok
$(call APPLY_FILE,server-ACL_Compat/0010-server-Add-compatibility-code-for-handling-the-old-m.patch)
$(call APPLY_FILE,server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch)
@( \
echo '+ { "server-ACL_Compat", "Erich E. Hoover", "Compatibility patch for old method of storing extended file system attributes. [rev 6]" },'; \
) > server-ACL_Compat.ok
@ -728,16 +755,16 @@ server-Process.ok:
# Patchset server-Stored_ACLs
# |
# | Included patches:
# | * Store and return security attributes with extended file attributes. [rev 6, by Erich E. Hoover]
# | * Store and return security attributes with extended file attributes. [rev 7, by Erich E. Hoover]
# |
# | This patchset fixes the following Wine bugs:
# | * [#31858] Support for stored file ACLs
# |
# | Modified files:
# | * configure.ac, dlls/advapi32/tests/security.c, server/change.c, server/file.c, server/file.h
# | * dlls/advapi32/tests/security.c, include/wine/port.h, server/change.c, server/file.c, server/file.h
# |
.INTERMEDIATE: server-Stored_ACLs.ok
server-Stored_ACLs.ok:
server-Stored_ACLs.ok: ntdll-DOS_Attributes.ok
$(call APPLY_FILE,server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch)
$(call APPLY_FILE,server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch)
$(call APPLY_FILE,server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch)
@ -745,7 +772,7 @@ server-Stored_ACLs.ok:
$(call APPLY_FILE,server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch)
$(call APPLY_FILE,server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch)
@( \
echo '+ { "server-Stored_ACLs", "Erich E. Hoover", "Store and return security attributes with extended file attributes. [rev 6]" },'; \
echo '+ { "server-Stored_ACLs", "Erich E. Hoover", "Store and return security attributes with extended file attributes. [rev 7]" },'; \
) > server-Stored_ACLs.ok
# Patchset shell32-Default_Folder_ACLs

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

View File

@ -1,4 +1,4 @@
From 4d377524363a3e33e2df29c38fe16542b6cd0aa1 Mon Sep 17 00:00:00 2001
From 3ef7e99e837ddc153bc3f608c9e33b4ec4f47d5b Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 20:56:49 -0700
Subject: ntdll: Add support for junction point creation.
@ -11,7 +11,7 @@ Subject: ntdll: Add support for junction point creation.
create mode 100644 include/ntifs.h
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index d2efcc1..7164d1e 100644
index 91f96ee..f56facd 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -89,12 +89,14 @@
@ -29,7 +29,7 @@ index d2efcc1..7164d1e 100644
#define SECSPERDAY 86400
#define SECS_1601_TO_1970 ((369 * 365 + 89) * (ULONGLONG)SECSPERDAY)
@@ -1470,6 +1472,76 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event,
@@ -1576,6 +1578,76 @@ NTSTATUS WINAPI NtDeviceIoControlFile(HANDLE handle, HANDLE event,
}
@ -106,7 +106,7 @@ index d2efcc1..7164d1e 100644
/**************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
@@ -1617,6 +1689,23 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
@@ -1723,6 +1795,23 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
}
break;
}
@ -131,7 +131,7 @@ index d2efcc1..7164d1e 100644
case FSCTL_PIPE_WAIT:
default:
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 695f034..127681a 100644
index 7a8e5d4..333ea44 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -37,6 +37,7 @@
@ -142,7 +142,7 @@ index 695f034..127681a 100644
#ifndef IO_COMPLETION_ALL_ACCESS
#define IO_COMPLETION_ALL_ACCESS 0x001F0003
@@ -2672,6 +2673,98 @@ todo_wine
@@ -2683,6 +2684,98 @@ todo_wine
CloseHandle(hfile);
}
@ -241,7 +241,7 @@ index 695f034..127681a 100644
START_TEST(file)
{
HMODULE hkernel32 = GetModuleHandleA("kernel32.dll");
@@ -2725,4 +2818,5 @@ START_TEST(file)
@@ -2736,4 +2829,5 @@ START_TEST(file)
test_file_disposition_information();
test_query_volume_information_file();
test_query_attribute_information_file();

View File

@ -1,4 +1,4 @@
From c191da3e2cf2136800fbf0658ced3a3534280806 Mon Sep 17 00:00:00 2001
From 3870b0d2c6309e4aa93922d8af21ae32ddcf5652 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 20:57:57 -0700
Subject: ntdll: Add support for reading junction points.
@ -9,10 +9,10 @@ Subject: ntdll: Add support for reading junction points.
2 files changed, 76 insertions(+), 1 deletion(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 7164d1e..56e0ef6 100644
index f56facd..b02fe76 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1542,6 +1542,60 @@ cleanup:
@@ -1648,6 +1648,60 @@ cleanup:
}
@ -73,7 +73,7 @@ index 7164d1e..56e0ef6 100644
/**************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
@@ -1690,6 +1744,15 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
@@ -1796,6 +1850,15 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
break;
}
@ -90,10 +90,10 @@ index 7164d1e..56e0ef6 100644
{
REPARSE_DATA_BUFFER *buffer = (REPARSE_DATA_BUFFER *)in_buffer;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 127681a..595276a 100644
index 333ea44..a109376 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2702,9 +2702,10 @@ static void test_junction_points(void)
@@ -2713,9 +2713,10 @@ static void test_junction_points(void)
static const WCHAR dotW[] = {'.',0};
REPARSE_DATA_BUFFER *buffer = NULL;
DWORD dwret, dwLen, dwFlags;
@ -105,7 +105,7 @@ index 127681a..595276a 100644
BOOL bret;
/* Create a temporary folder for the junction point tests */
@@ -2752,6 +2753,17 @@ static void test_junction_points(void)
@@ -2763,6 +2764,17 @@ static void test_junction_points(void)
buffer_len = build_reparse_buffer(nameW.Buffer, &buffer);
bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());

View File

@ -1,4 +1,4 @@
From 9a592e9dd065355f785e997fb72ee5a586665dc0 Mon Sep 17 00:00:00 2001
From 87bd79756bb80f37751ea79a449e70bad0a08465 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:00:21 -0700
Subject: ntdll: Add support for deleting junction points.
@ -10,10 +10,10 @@ Subject: ntdll: Add support for deleting junction points.
3 files changed, 85 insertions(+)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 56e0ef6..396bdf9 100644
index b02fe76..682e2e8 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1596,6 +1596,41 @@ cleanup:
@@ -1702,6 +1702,41 @@ cleanup:
}
@ -55,7 +55,7 @@ index 56e0ef6..396bdf9 100644
/**************************************************************************
* NtFsControlFile [NTDLL.@]
* ZwFsControlFile [NTDLL.@]
@@ -1744,6 +1779,22 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
@@ -1850,6 +1885,22 @@ NTSTATUS WINAPI NtFsControlFile(HANDLE handle, HANDLE event, PIO_APC_ROUTINE apc
break;
}
@ -79,10 +79,10 @@ index 56e0ef6..396bdf9 100644
{
REPARSE_DATA_BUFFER *buffer = (REPARSE_DATA_BUFFER *)out_buffer;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 595276a..d3c6cf0 100644
index a109376..cc241c8 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2697,12 +2697,15 @@ static void test_junction_points(void)
@@ -2708,12 +2708,15 @@ static void test_junction_points(void)
static const WCHAR junctionW[] = {'\\','j','u','n','c','t','i','o','n',0};
WCHAR path[MAX_PATH], junction_path[MAX_PATH], target_path[MAX_PATH];
static const WCHAR targetW[] = {'\\','t','a','r','g','e','t',0};
@ -98,7 +98,7 @@ index 595276a..d3c6cf0 100644
UNICODE_STRING nameW;
HANDLE hJunction;
WCHAR *dest;
@@ -2750,6 +2753,8 @@ static void test_junction_points(void)
@@ -2761,6 +2764,8 @@ static void test_junction_points(void)
win_skip("Failed to open junction point directory handle (0x%x).\n", GetLastError());
goto cleanup;
}
@ -107,7 +107,7 @@ index 595276a..d3c6cf0 100644
buffer_len = build_reparse_buffer(nameW.Buffer, &buffer);
bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());
@@ -2764,6 +2769,24 @@ static void test_junction_points(void)
@@ -2775,6 +2780,24 @@ static void test_junction_points(void)
ok(bret, "Failed to read junction point!\n");
ok((memcmp(dest, nameW.Buffer, string_len) == 0), "Junction point destination does not match ('%s' != '%s')!\n",
wine_dbgstr_w(dest), wine_dbgstr_w(nameW.Buffer));

View File

@ -1,46 +1,51 @@
From f35e4dc0c96de3e9fbeb4ff1bdefc9db7c7d56d8 Mon Sep 17 00:00:00 2001
From 624df21e36009121bf5d7ecab86fb0ace8ca15d7 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:01:25 -0700
Subject: ntdll: Advertise that a file is a junction point.
---
dlls/ntdll/file.c | 7 ++++++-
dlls/ntdll/file.c | 7 +++++--
dlls/ntdll/tests/file.c | 5 +++++
2 files changed, 11 insertions(+), 1 deletion(-)
2 files changed, 10 insertions(+), 2 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 396bdf9..b4e06d1 100644
index 682e2e8..3230d95 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -1988,10 +1988,11 @@ NTSTATUS fill_stat_info( const struct stat *st, void *ptr, FILE_INFORMATION_CLAS
@@ -182,8 +182,8 @@ int get_file_info( const char *path, struct stat *st, ULONG *xattr )
if (S_ISLNK( st->st_mode ))
{
ret = stat( path, st );
+ st->st_mode |= S_IFLNK;
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;
@@ -2088,7 +2088,7 @@ static inline ULONG get_file_attributes( const ULONG xattr, const struct stat *s
{
ULONG attr;
get_file_times( st, &info->LastWriteTime, &info->ChangeTime,
&info->LastAccessTime, &info->CreationTime );
- if (S_ISDIR(st->st_mode)) info->FileAttributes = FILE_ATTRIBUTE_DIRECTORY;
+ if (st->st_mode & S_IFDIR) 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;
+ if ((st->st_mode & S_IFLNK) == S_IFLNK) info->FileAttributes |= FILE_ATTRIBUTE_REPARSE_POINT;
}
break;
case FileStandardInformation:
@@ -2657,6 +2658,10 @@ NTSTATUS WINAPI NtQueryAttributesFile( const OBJECT_ATTRIBUTES *attr, FILE_BASIC
status = STATUS_INVALID_INFO_CLASS;
else
{
+ struct stat lst;
- if (S_ISDIR(st->st_mode))
+ if (st->st_mode & S_IFDIR)
attr = FILE_ATTRIBUTE_DIRECTORY;
else
attr = FILE_ATTRIBUTE_ARCHIVE;
@@ -2098,6 +2098,9 @@ static inline ULONG get_file_attributes( const ULONG xattr, const struct stat *s
if (!(st->st_mode & (S_IWUSR | S_IWGRP | S_IWOTH)))
attr |= FILE_ATTRIBUTE_READONLY;
+
+ if (lstat( unix_name.Buffer, &lst ) != -1)
+ st.st_mode |= (lst.st_mode & S_IFLNK);
status = fill_stat_info( &st, info, FileBasicInformation );
if (DIR_is_hidden_file( attr->ObjectName ))
info->FileAttributes |= FILE_ATTRIBUTE_HIDDEN;
+ if (st->st_mode & S_IFLNK)
+ attr |= FILE_ATTRIBUTE_REPARSE_POINT;
return attr;
}
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index d3c6cf0..c75ba47 100644
index cc241c8..3f1973c 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2759,6 +2759,11 @@ static void test_junction_points(void)
@@ -2770,6 +2770,11 @@ static void test_junction_points(void)
bret = DeviceIoControl(hJunction, FSCTL_SET_REPARSE_POINT, (LPVOID)buffer, buffer_len, NULL, 0, &dwret, 0);
ok(bret, "Failed to create junction point! (0x%x)\n", GetLastError());

View File

@ -1,4 +1,4 @@
From e6a876330230784a2b2be6588b94e5555de169da Mon Sep 17 00:00:00 2001
From e5c5d522bdf363ef1b07e7d18e73ddc2f7ff9305 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:02:11 -0700
Subject: kernel32,ntdll: Add support for deleting junction points with
@ -47,10 +47,10 @@ index 09fb04b..c328cc0 100644
NtClose( handle );
return ret;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index c75ba47..f94a61c 100644
index 3f1973c..be6898b 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2703,7 +2703,7 @@ static void test_junction_points(void)
@@ -2714,7 +2714,7 @@ static void test_junction_points(void)
REPARSE_GUID_DATA_BUFFER guid_buffer;
static const WCHAR dotW[] = {'.',0};
REPARSE_DATA_BUFFER *buffer = NULL;
@ -59,7 +59,7 @@ index c75ba47..f94a61c 100644
INT buffer_len, string_len;
IO_STATUS_BLOCK iosb;
UNICODE_STRING nameW;
@@ -2794,6 +2794,38 @@ static void test_junction_points(void)
@@ -2805,6 +2805,38 @@ static void test_junction_points(void)
new_attrib.LastAccessTime.QuadPart, old_attrib.LastAccessTime.QuadPart);
CloseHandle(hJunction);

View File

@ -1,4 +1,4 @@
From 18631ce985f75851cd6f00eb8ff03aa7d3e852ec Mon Sep 17 00:00:00 2001
From 38d297f6be2c232433e9093ecbfcc45b2de715d2 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:03:47 -0700
Subject: kernel32: Advertise junction point support.
@ -23,7 +23,7 @@ index d396764..0fb0aef 100644
}
ret = TRUE;
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index acc9197..3112081 100644
index be6898b..57e7fc1 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2799,10 +2799,9 @@ static void test_junction_points(void)

View File

@ -1,4 +1,4 @@
From f70c0d8ae00629148df5e16efb30960704b8bbf8 Mon Sep 17 00:00:00 2001
From 1a343f1a7d57ed717c07026091bca8efe47a8fd6 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 16 Jan 2014 21:06:24 -0700
Subject: ntdll/tests: Add test for deleting junction point target.
@ -8,10 +8,10 @@ Subject: ntdll/tests: Add test for deleting junction point target.
1 file changed, 11 insertions(+)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index f94a61c..ffb9ff2 100644
index 57e7fc1..0feda4a 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -2826,6 +2826,17 @@ static void test_junction_points(void)
@@ -2836,6 +2836,17 @@ static void test_junction_points(void)
ok(dwret != (DWORD)~0, "Junction point doesn't exist (attributes: 0x%x)!\n", dwret);
ok(dwret & FILE_ATTRIBUTE_REPARSE_POINT, "File is not a junction point! (attributes: 0x%x)\n", dwret);

View File

@ -1,24 +1,23 @@
From 0be335ce9c2c93a186cf35be0a99519868ab8a0d Mon Sep 17 00:00:00 2001
From cc8ce50fa0194313f2ac9d8f967350fdeb643ad7 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 18 Apr 2014 15:21:00 -0600
Subject: server: Add compatibility code for handling the old method of
storing ACLs.
---
server/file.c | 162 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 162 insertions(+)
server/file.c | 158 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 158 insertions(+)
diff --git a/server/file.c b/server/file.c
index e29d06b..08231a7 100644
index bbb9358..309c49d 100644
--- a/server/file.c
+++ b/server/file.c
@@ -750,6 +750,167 @@ struct security_descriptor *get_xattr_sd( int fd )
#endif
@@ -755,6 +755,163 @@ struct security_descriptor *get_xattr_sd( int fd )
return sd;
}
+struct security_descriptor *get_xattr_acls( int fd, const SID *user, const SID *group )
+{
+#ifdef HAVE_ATTR_XATTR_H
+ int ace_count = 0, dacl_size = sizeof(ACL), i, n;
+ char buffer[XATTR_SIZE_MAX], *p = buffer, *pn;
+ struct security_descriptor *sd;
@ -29,7 +28,7 @@ index e29d06b..08231a7 100644
+ ACL *dacl;
+ char *ptr;
+
+ n = fgetxattr( fd, "user.wine.acl", buffer, sizeof(buffer) );
+ n = xattr_fget( fd, "user.wine.acl", buffer, sizeof(buffer) );
+ if (n == -1) return NULL;
+ buffer[n] = 0; /* ensure NULL terminated buffer for string functions */
+
@ -172,15 +171,12 @@ index e29d06b..08231a7 100644
+ }
+
+ return sd;
+#else
+ return NULL;
+#endif
+}
+
/* Convert generic rights into standard access rights */
void convert_generic_sd( struct security_descriptor *sd )
{
@@ -790,6 +951,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -795,6 +952,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
user = security_unix_uid_to_sid( st.st_uid );
group = token_get_primary_group( current->process->token );
sd = get_xattr_sd( unix_fd );

View File

@ -1,4 +1,4 @@
From c6052d785f4419a80ca091d978ee1ff3e7400ca9 Mon Sep 17 00:00:00 2001
From 4c0c7fc3e73d39e30be7cba5c2e63f8c6f6c2792 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 18 Apr 2014 14:08:36 -0600
Subject: server: Inherit security attributes from parent directories on
@ -12,10 +12,10 @@ Subject: server: Inherit security attributes from parent directories on
4 files changed, 179 insertions(+), 6 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 48a3291..f3a3c09 100644
index 82c0639..3e88c2e 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3030,10 +3030,11 @@ static void test_CreateDirectoryA(void)
@@ -3117,10 +3117,11 @@ static void test_CreateDirectoryA(void)
ACL_SIZE_INFORMATION acl_size;
ACCESS_ALLOWED_ACE *ace;
SECURITY_ATTRIBUTES sa;
@ -28,7 +28,7 @@ index 48a3291..f3a3c09 100644
DWORD error;
PACL pDacl;
@@ -3126,6 +3127,43 @@ static void test_CreateDirectoryA(void)
@@ -3213,6 +3214,43 @@ static void test_CreateDirectoryA(void)
}
LocalFree(pSD);
@ -73,10 +73,10 @@ index 48a3291..f3a3c09 100644
HeapFree(GetProcessHeap(), 0, user);
bret = RemoveDirectoryA(tmpdir);
diff --git a/server/change.c b/server/change.c
index 77c01bb..2cf1cab 100644
index 27dbe25..0a82358 100644
--- a/server/change.c
+++ b/server/change.c
@@ -287,7 +287,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
@@ -290,7 +290,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
assert( obj->ops == &dir_ops );
fd = dir_get_fd( obj );
@ -86,11 +86,11 @@ index 77c01bb..2cf1cab 100644
return sd;
}
diff --git a/server/file.c b/server/file.c
index 75f015b..6ce8806 100644
index 3582493..1414ee6 100644
--- a/server/file.c
+++ b/server/file.c
@@ -245,11 +245,141 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user
#endif
@@ -248,11 +248,141 @@ void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user
xattr_fset( fd, WINE_XATTR_SD, buffer, len );
}
+struct security_descriptor *inherit_sd( const struct security_descriptor *parent_sd, int is_dir )
@ -231,7 +231,7 @@ index 75f015b..6ce8806 100644
const SID *owner = NULL, *group = NULL;
struct object *obj = NULL;
struct fd *fd;
@@ -279,6 +409,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -282,6 +412,10 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
default: set_error( STATUS_INVALID_PARAMETER ); goto done;
}
@ -242,7 +242,7 @@ index 75f015b..6ce8806 100644
if (sd)
{
owner = sd_get_owner( sd );
@@ -322,6 +456,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -325,6 +459,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
release_object( fd );
done:
@ -250,7 +250,7 @@ index 75f015b..6ce8806 100644
free( name );
return obj;
}
@@ -538,7 +673,7 @@ void convert_generic_sd( struct security_descriptor *sd )
@@ -543,7 +678,7 @@ void convert_generic_sd( struct security_descriptor *sd )
}
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
@ -259,7 +259,7 @@ index 75f015b..6ce8806 100644
{
int unix_fd = get_unix_fd( fd );
struct stat st;
@@ -556,7 +691,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -561,7 +696,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
user = security_unix_uid_to_sid( st.st_uid );
group = token_get_primary_group( current->process->token );
sd = get_xattr_sd( unix_fd );
@ -268,7 +268,7 @@ index 75f015b..6ce8806 100644
if (!sd) sd = mode_to_sd( st.st_mode, user, group);
if (!sd) return obj->sd;
@@ -576,7 +711,7 @@ static struct security_descriptor *file_get_sd( struct object *obj )
@@ -581,7 +716,7 @@ static struct security_descriptor *file_get_sd( struct object *obj )
assert( obj->ops == &file_ops );
fd = file_get_fd( obj );

View File

@ -1,4 +1,4 @@
From 04bbc2e2841b01a5a5344bb1f62c94ff84b25350 Mon Sep 17 00:00:00 2001
From 6a598ee04025242f900fdf2726a21afe93d018bd Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 18 Apr 2014 14:10:49 -0600
Subject: server: Inherit security attributes from parent directories on
@ -13,10 +13,10 @@ Subject: server: Inherit security attributes from parent directories on
5 files changed, 207 insertions(+), 8 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 68b63a0..c981c1b 100644
index 3e88c2e..952d001 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3350,6 +3350,74 @@ static void test_GetNamedSecurityInfoA(void)
@@ -3440,6 +3440,74 @@ static void test_GetNamedSecurityInfoA(void)
"Administators Group ACE has unexpected mask (0x%x != 0x1f01ff)\n", ace->Mask);
}
LocalFree(pSD);
@ -92,10 +92,10 @@ index 68b63a0..c981c1b 100644
CloseHandle(hTemp);
diff --git a/include/winnt.h b/include/winnt.h
index 3f33c6b..5d2234f 100644
index 709a93f..63882bb 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5057,14 +5057,15 @@ typedef struct _TAPE_GET_MEDIA_PARAMETERS {
@@ -5078,14 +5078,15 @@ typedef struct _TAPE_GET_MEDIA_PARAMETERS {
BOOLEAN WriteProtected;
} TAPE_GET_MEDIA_PARAMETERS, *PTAPE_GET_MEDIA_PARAMETERS;
@ -115,10 +115,10 @@ index 3f33c6b..5d2234f 100644
#define REG_OPTION_NON_VOLATILE 0x00000000
#define REG_OPTION_VOLATILE 0x00000001
diff --git a/server/fd.c b/server/fd.c
index fa8874c..9e6b9a8 100644
index e3b722c..7d50ab6 100644
--- a/server/fd.c
+++ b/server/fd.c
@@ -1629,6 +1629,16 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
@@ -1634,6 +1634,16 @@ struct fd *alloc_pseudo_fd( const struct fd_ops *fd_user_ops, struct object *use
return fd;
}
@ -135,7 +135,7 @@ index fa8874c..9e6b9a8 100644
/* duplicate an fd object for a different user */
struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sharing, unsigned int options )
{
@@ -1642,8 +1652,7 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha
@@ -1647,8 +1657,7 @@ struct fd *dup_fd_object( struct fd *orig, unsigned int access, unsigned int sha
if (orig->unix_name)
{
@ -146,10 +146,10 @@ index fa8874c..9e6b9a8 100644
if (orig->inode)
diff --git a/server/file.c b/server/file.c
index 6ce8806..e29d06b 100644
index 1414ee6..bbb9358 100644
--- a/server/file.c
+++ b/server/file.c
@@ -325,6 +325,105 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent
@@ -328,6 +328,105 @@ struct security_descriptor *inherit_sd( const struct security_descriptor *parent
return sd;
}
@ -255,7 +255,7 @@ index 6ce8806..e29d06b 100644
static struct security_descriptor *file_get_parent_sd( struct fd *root, const char *child_name,
int child_len, int is_dir )
{
@@ -795,16 +894,33 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
@@ -800,16 +899,33 @@ mode_t sd_to_mode( const struct security_descriptor *sd, const SID *owner )
return new_mode & ~denied_mode;
}
@ -290,7 +290,7 @@ index 6ce8806..e29d06b 100644
if (set_info & OWNER_SECURITY_INFORMATION)
{
owner = sd_get_owner( sd );
@@ -854,10 +970,14 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
@@ -859,10 +975,14 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
if (((st.st_mode ^ mode) & (S_IRWXU|S_IRWXG|S_IRWXO)) && fchmod( unix_fd, mode ) == -1)
{
file_set_error();

View File

@ -1,4 +1,4 @@
From 379e01b2aea67fa305d2ccd08b589d2d31cd0da0 Mon Sep 17 00:00:00 2001
From f2866f1d9f575eab3034f71128c9e68c81e0138a Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:07:46 -0600
Subject: server: Unify the storage of security attributes for files and
@ -11,10 +11,10 @@ Subject: server: Unify the storage of security attributes for files and
3 files changed, 25 insertions(+), 48 deletions(-)
diff --git a/server/change.c b/server/change.c
index f6d56b0..7cea06b 100644
index 3ac70a4..4f6ce81 100644
--- a/server/change.c
+++ b/server/change.c
@@ -317,49 +317,15 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
@@ -320,49 +320,15 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
static int dir_set_sd( struct object *obj, const struct security_descriptor *sd,
unsigned int set_info )
{

View File

@ -1,4 +1,4 @@
From e20db446df6bb0177f90964cd09dd9a993d120f3 Mon Sep 17 00:00:00 2001
From ba94c25ed29ed6d3fc1c49a13ddb5257f5b3f385 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Thu, 17 Apr 2014 16:07:50 -0600
Subject: server: Unify the retrieval of security attributes for files and
@ -11,10 +11,10 @@ Subject: server: Unify the retrieval of security attributes for files and
3 files changed, 28 insertions(+), 38 deletions(-)
diff --git a/server/change.c b/server/change.c
index 7cea06b..c391180 100644
index 4f6ce81..27dbe25 100644
--- a/server/change.c
+++ b/server/change.c
@@ -278,39 +278,17 @@ static struct fd *dir_get_fd( struct object *obj )
@@ -281,39 +281,17 @@ static struct fd *dir_get_fd( struct object *obj )
return (struct fd *)grab_object( dir->fd );
}
@ -54,7 +54,7 @@ index 7cea06b..c391180 100644
- free( obj->sd );
- obj->sd = sd;
+ fd = dir_get_fd( obj );
+ sd = set_file_sd( obj, fd, &dir->mode, &dir->uid );
+ sd = get_file_sd( obj, fd, &dir->mode, &dir->uid );
+ release_object( fd );
return sd;
}

View File

@ -1,46 +1,30 @@
From a424efd08ebe4a247b4a3b874137faadb7f59266 Mon Sep 17 00:00:00 2001
From 0184c0316ba0e8ebbce82d8058f4979bfd2b8c97 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 18 Apr 2014 15:34:47 -0600
Subject: server: Store file security attributes with extended file
attributes.
---
configure.ac | 12 ++++++++++++
server/file.c | 39 +++++++++++++++++++++++++++++++++++++++
2 files changed, 51 insertions(+)
include/wine/port.h | 3 +++
server/file.c | 34 ++++++++++++++++++++++++++++++++++
2 files changed, 37 insertions(+)
diff --git a/configure.ac b/configure.ac
index c913f9f..2d5d5ee 100644
--- a/configure.ac
+++ b/configure.ac
@@ -73,6 +73,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]),
@@ -664,6 +665,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
#include <sys/socket.h>
#endif])
diff --git a/include/wine/port.h b/include/wine/port.h
index f989731..433f1b9 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -371,6 +371,9 @@ extern int _spawnvp(int mode, const char *cmdname, const char * const argv[]);
#ifndef XATTR_USER_PREFIX_LEN
#define XATTR_USER_PREFIX_LEN (sizeof(XATTR_USER_PREFIX) - 1)
#endif
+#ifndef XATTR_SIZE_MAX
+#define XATTR_SIZE_MAX 65536
+#endif
+if test "x$with_xattr" != "xno"
+then
+ AC_CHECK_HEADERS(attr/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")
extern int xattr_fget( int filedes, const char *name, void *value, size_t size );
extern int xattr_fremove( int filedes, const char *name );
diff --git a/server/file.c b/server/file.c
index 1f008ea..951e25b 100644
index 1f008ea..502951c 100644
--- a/server/file.c
+++ b/server/file.c
@@ -32,6 +32,7 @@
@ -51,27 +35,27 @@ index 1f008ea..951e25b 100644
#include <unistd.h>
#ifdef HAVE_UTIME_H
#include <utime.h>
@@ -39,6 +40,13 @@
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
+#ifdef HAVE_SYS_EXTATTR_H
+#include <sys/extattr.h>
+#define XATTR_SIZE_MAX 65536
+#endif
@@ -52,6 +53,14 @@
#include "process.h"
#include "security.h"
#include "ntstatus.h"
#define WIN32_NO_STATUS
@@ -178,6 +186,34 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
+/* We intentionally do not match the Samba 4 extended attribute for NT security descriptors (SDs):
+ * 1) Samba stores this information using an internal data structure (we use a flat NT SD).
+ * 2) Samba uses the attribute "security.NTACL". This attribute is within a namespace that only
+ * the administrator has write access to, which prohibits the user from copying the attributes
+ * when copying a file and would require Wine to run with adminstrative privileges.
+ */
+#define WINE_XATTR_SD XATTR_USER_PREFIX "wine.sd"
+
struct file
{
struct object obj; /* object header */
@@ -178,6 +187,28 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
return &file->obj;
}
+void set_xattr_sd( int fd, const struct security_descriptor *sd )
+{
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
+ char buffer[XATTR_SIZE_MAX];
+ int present, len;
+ const ACL *dacl;
@ -89,18 +73,13 @@ index 1f008ea..951e25b 100644
+ buffer[0] = SECURITY_DESCRIPTOR_REVISION;
+ buffer[1] = 0;
+ memcpy( &buffer[2], sd, len - 2 );
+#if defined(HAVE_ATTR_XATTR_H)
+ fsetxattr( fd, "user.wine.sd", buffer, len, 0 );
+#else
+ extattr_set_fd( fd, EXTATTR_NAMESPACE_USER, "wine.sd", buffer, len );
+#endif
+#endif
+ xattr_fset( fd, WINE_XATTR_SD, buffer, len );
+}
+
static struct object *create_file( struct fd *root, const char *nameptr, data_size_t len,
unsigned int access, unsigned int sharing, int create,
unsigned int options, unsigned int attrs,
@@ -239,6 +275,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -239,6 +270,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
if (!fd) goto done;
@ -108,7 +87,7 @@ index 1f008ea..951e25b 100644
if (S_ISDIR(mode))
obj = create_dir_obj( fd, access, mode );
@@ -580,6 +617,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
@@ -580,6 +612,8 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
mode |= sd_to_mode( sd, owner );

View File

@ -1,4 +1,4 @@
From 9b59ad02610a11d39ee8338404fd26021e0458c6 Mon Sep 17 00:00:00 2001
From 52669858326cb82bafd0cfbb0afa354f8991fe11 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 18 Apr 2014 15:35:24 -0600
Subject: server: Store user and group inside stored extended file attribute
@ -9,17 +9,16 @@ Subject: server: Store user and group inside stored extended file attribute
1 file changed, 70 insertions(+), 9 deletions(-)
diff --git a/server/file.c b/server/file.c
index 951e25b..6981fca 100644
index 502951c..4f7e5b5 100644
--- a/server/file.c
+++ b/server/file.c
@@ -186,11 +186,12 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
@@ -187,10 +187,11 @@ static struct object *create_file_obj( struct fd *fd, unsigned int access, mode_
return &file->obj;
}
-void set_xattr_sd( int fd, const struct security_descriptor *sd )
+void set_xattr_sd( int fd, const struct security_descriptor *sd, const SID *user, const SID *group )
{
#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
- char buffer[XATTR_SIZE_MAX];
- int present, len;
+ char buffer[XATTR_SIZE_MAX], *dst_ptr = &buffer[2], *src_ptr = (char *)sd;
@ -80,10 +79,10 @@ index 951e25b..6981fca 100644
+ memcpy( dst_ptr, src_ptr, sd->dacl_len );
+ src_ptr += sd->dacl_len;
+ dst_ptr += sd->dacl_len;
#if defined(HAVE_ATTR_XATTR_H)
fsetxattr( fd, "user.wine.sd", buffer, len, 0 );
#else
@@ -219,6 +258,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
xattr_fset( fd, WINE_XATTR_SD, buffer, len );
}
@@ -214,6 +253,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
unsigned int options, unsigned int attrs,
const struct security_descriptor *sd )
{
@ -91,7 +90,7 @@ index 951e25b..6981fca 100644
struct object *obj = NULL;
struct fd *fd;
int flags;
@@ -249,9 +289,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -244,9 +284,12 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
if (sd)
{
@ -105,7 +104,7 @@ index 951e25b..6981fca 100644
mode = sd_to_mode( sd, owner );
}
else if (options & FILE_DIRECTORY_FILE)
@@ -275,7 +318,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
@@ -270,7 +313,7 @@ static struct object *create_file( struct fd *root, const char *nameptr, data_si
/* FIXME: should set error to STATUS_OBJECT_NAME_COLLISION if file existed before */
fd = open_fd( root, name, flags | O_NONBLOCK | O_LARGEFILE, &mode, access, sharing, options );
if (!fd) goto done;
@ -114,7 +113,7 @@ index 951e25b..6981fca 100644
if (S_ISDIR(mode))
obj = create_dir_obj( fd, access, mode );
@@ -585,7 +628,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
@@ -580,7 +623,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
unsigned int set_info )
{
int unix_fd = get_unix_fd( fd );
@ -123,7 +122,7 @@ index 951e25b..6981fca 100644
struct stat st;
mode_t mode;
@@ -609,6 +652,24 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
@@ -604,6 +647,24 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
else
owner = token_get_user( current->process->token );
@ -148,7 +147,7 @@ index 951e25b..6981fca 100644
/* group and sacl not supported */
if (set_info & DACL_SECURITY_INFORMATION)
@@ -617,7 +678,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
@@ -612,7 +673,7 @@ int set_file_sd( struct object *obj, struct fd *fd, const struct security_descri
mode = st.st_mode & (S_ISUID|S_ISGID|S_ISVTX);
mode |= sd_to_mode( sd, owner );

View File

@ -1,4 +1,4 @@
From 0fea62714c3bdf5384f2f47c1985c21470710cfd Mon Sep 17 00:00:00 2001
From 3a670acdf6684edb9bc050c8cbded452e8fc3139 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 18 Apr 2014 14:01:35 -0600
Subject: server: Retrieve file security attributes with extended file
@ -6,15 +6,14 @@ Subject: server: Retrieve file security attributes with extended file
---
dlls/advapi32/tests/security.c | 49 ++++++++++++++++++++--------------------
server/change.c | 2 +-
server/file.c | 38 ++++++++++++++++++++++++++++---
3 files changed, 60 insertions(+), 29 deletions(-)
server/file.c | 30 +++++++++++++++++++++---
2 files changed, 51 insertions(+), 28 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index f3ccc8e..4352ba6 100644
index b44496a..02094a4 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3131,24 +3131,24 @@ static void test_CreateDirectoryA(void)
@@ -3192,24 +3192,24 @@ static void test_CreateDirectoryA(void)
bret = pGetAce(pDacl, 0, (VOID **)&ace);
ok(bret, "Failed to get Current User ACE.\n");
bret = EqualSid(&ace->SidStart, user_sid);
@ -51,7 +50,7 @@ index f3ccc8e..4352ba6 100644
}
LocalFree(pSD);
@@ -3323,23 +3323,22 @@ static void test_GetNamedSecurityInfoA(void)
@@ -3384,23 +3384,22 @@ static void test_GetNamedSecurityInfoA(void)
bret = pGetAce(pDacl, 0, (VOID **)&ace);
ok(bret, "Failed to get Current User ACE.\n");
bret = EqualSid(&ace->SidStart, user_sid);
@ -81,7 +80,7 @@ index f3ccc8e..4352ba6 100644
}
LocalFree(pSD);
HeapFree(GetProcessHeap(), 0, user);
@@ -3989,22 +3988,22 @@ static void test_GetSecurityInfo(void)
@@ -4050,22 +4049,22 @@ static void test_GetSecurityInfo(void)
bret = pGetAce(pDacl, 0, (VOID **)&ace);
ok(bret, "Failed to get Current User ACE.\n");
bret = EqualSid(&ace->SidStart, user_sid);
@ -110,39 +109,21 @@ index f3ccc8e..4352ba6 100644
}
LocalFree(pSD);
CloseHandle(obj);
diff --git a/server/change.c b/server/change.c
index c673c48..27dbe25 100644
--- a/server/change.c
+++ b/server/change.c
@@ -290,7 +290,7 @@ static struct security_descriptor *dir_get_sd( struct object *obj )
assert( obj->ops == &dir_ops );
fd = dir_get_fd( obj );
- sd = set_file_sd( obj, fd, &dir->mode, &dir->uid );
+ sd = get_file_sd( obj, fd, &dir->mode, &dir->uid );
release_object( fd );
return sd;
}
diff --git a/server/file.c b/server/file.c
index 6981fca..26962df 100644
index 4f7e5b5..cf3fe86 100644
--- a/server/file.c
+++ b/server/file.c
@@ -504,12 +504,43 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
@@ -499,12 +499,35 @@ struct security_descriptor *mode_to_sd( mode_t mode, const SID *user, const SID
return sd;
}
+struct security_descriptor *get_xattr_sd( int fd )
+{
+#if defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_EXTATTR_H)
+ struct security_descriptor *sd;
+ char buffer[XATTR_SIZE_MAX];
+ int n;
+
+#if defined(HAVE_ATTR_XATTR_H)
+ n = fgetxattr( fd, "user.wine.sd", buffer, sizeof(buffer) );
+#else
+ n = extattr_get_fd( fd, EXTATTR_NAMESPACE_USER, "wine.sd", buffer, sizeof(buffer) );
+#endif
+ n = xattr_fget( fd, WINE_XATTR_SD, buffer, sizeof(buffer) );
+ if (n == -1 || n < 2 + sizeof(struct security_descriptor)) return NULL;
+
+ /* validate that we can handle the descriptor */
@ -156,9 +137,6 @@ index 6981fca..26962df 100644
+ sd = mem_alloc( n - 2 );
+ if (sd) memcpy( sd, &buffer[2], n - 2 );
+ return sd;
+#else
+ return NULL;
+#endif
+}
+
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
@ -171,7 +149,7 @@ index 6981fca..26962df 100644
if (unix_fd == -1 || fstat( unix_fd, &st ) == -1)
return obj->sd;
@@ -519,9 +550,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -514,9 +537,10 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
(st.st_uid == *uid))
return obj->sd;

View File

@ -1,4 +1,4 @@
From 689b660afba80654cde0a2dd6cf1d647a6e3705c Mon Sep 17 00:00:00 2001
From 21655f45376f4a0c18d6bd6ae38e59d346b867fc Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Fri, 18 Apr 2014 14:05:32 -0600
Subject: server: Convert return of file security masks with generic access
@ -10,10 +10,10 @@ Subject: server: Convert return of file security masks with generic access
2 files changed, 34 insertions(+), 12 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 26cde37..48a3291 100644
index 02094a4..82c0639 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -3109,8 +3109,8 @@ static void test_CreateDirectoryA(void)
@@ -3196,8 +3196,8 @@ static void test_CreateDirectoryA(void)
ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
"Current User ACE has unexpected flags (0x%x != 0x03)\n",
((ACE_HEADER *)ace)->AceFlags);
@ -24,7 +24,7 @@ index 26cde37..48a3291 100644
}
if (acl_size.AceCount > 1)
{
@@ -3121,8 +3121,8 @@ static void test_CreateDirectoryA(void)
@@ -3208,8 +3208,8 @@ static void test_CreateDirectoryA(void)
ok(((ACE_HEADER *)ace)->AceFlags == (OBJECT_INHERIT_ACE|CONTAINER_INHERIT_ACE),
"Administators Group ACE has unexpected flags (0x%x != 0x03)\n",
((ACE_HEADER *)ace)->AceFlags);
@ -35,7 +35,7 @@ index 26cde37..48a3291 100644
}
LocalFree(pSD);
@@ -3300,8 +3300,8 @@ static void test_GetNamedSecurityInfoA(void)
@@ -3387,8 +3387,8 @@ static void test_GetNamedSecurityInfoA(void)
ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
@ -46,7 +46,7 @@ index 26cde37..48a3291 100644
}
if (acl_size.AceCount > 1)
{
@@ -3311,8 +3311,8 @@ static void test_GetNamedSecurityInfoA(void)
@@ -3398,8 +3398,8 @@ static void test_GetNamedSecurityInfoA(void)
ok(bret || broken(!bret) /* win2k */, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
@ -57,7 +57,7 @@ index 26cde37..48a3291 100644
}
LocalFree(pSD);
HeapFree(GetProcessHeap(), 0, user);
@@ -3965,8 +3965,8 @@ static void test_GetSecurityInfo(void)
@@ -4052,8 +4052,8 @@ static void test_GetSecurityInfo(void)
ok(bret, "Current User ACE != Current User SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Current User ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
@ -68,7 +68,7 @@ index 26cde37..48a3291 100644
}
if (acl_size.AceCount > 1)
{
@@ -3976,8 +3976,8 @@ static void test_GetSecurityInfo(void)
@@ -4063,8 +4063,8 @@ static void test_GetSecurityInfo(void)
ok(bret, "Administators Group ACE != Administators Group SID.\n");
ok(((ACE_HEADER *)ace)->AceFlags == 0,
"Administators Group ACE has unexpected flags (0x%x != 0x0)\n", ((ACE_HEADER *)ace)->AceFlags);
@ -80,11 +80,11 @@ index 26cde37..48a3291 100644
LocalFree(pSD);
CloseHandle(obj);
diff --git a/server/file.c b/server/file.c
index c4706b6..75f015b 100644
index cf3fe86..3582493 100644
--- a/server/file.c
+++ b/server/file.c
@@ -516,6 +516,27 @@ struct security_descriptor *get_xattr_sd( int fd )
#endif
@@ -521,6 +521,27 @@ struct security_descriptor *get_xattr_sd( int fd )
return sd;
}
+/* Convert generic rights into standard access rights */
@ -111,7 +111,7 @@ index c4706b6..75f015b 100644
struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode_t *mode,
uid_t *uid )
{
@@ -535,6 +556,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
@@ -540,6 +561,7 @@ struct security_descriptor *get_file_sd( struct object *obj, struct fd *fd, mode
user = security_unix_uid_to_sid( st.st_uid );
group = token_get_primary_group( current->process->token );
sd = get_xattr_sd( unix_fd );

View File

@ -1,4 +1,5 @@
Author: Erich E. Hoover
Subject: Store and return security attributes with extended file attributes.
Revision: 6
Revision: 7
Depends: ntdll-DOS_Attributes
Fixes: [31858] Support for stored file ACLs