diff --git a/README.md b/README.md index c7f2a157..681bf30c 100644 --- a/README.md +++ b/README.md @@ -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")) diff --git a/debian/changelog b/debian/changelog index 2cd5a794..7ab07bdd 100644 --- a/debian/changelog +++ b/debian/changelog @@ -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 Mon, 11 Aug 2014 16:21:22 -0600 diff --git a/patches/Makefile b/patches/Makefile index 7294d6c2..356fd77c 100644 --- a/patches/Makefile +++ b/patches/Makefile @@ -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 diff --git a/patches/ntdll-DOS_Attributes/0001-ntdll-Unify-retrieving-the-attributes-of-a-file.patch b/patches/ntdll-DOS_Attributes/0001-ntdll-Unify-retrieving-the-attributes-of-a-file.patch new file mode 100644 index 00000000..dba8d88c --- /dev/null +++ b/patches/ntdll-DOS_Attributes/0001-ntdll-Unify-retrieving-the-attributes-of-a-file.patch @@ -0,0 +1,68 @@ +From 7922ba3b2a5414d30053821394962afed4e5b13c Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +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 + diff --git a/patches/ntdll-DOS_Attributes/0002-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch b/patches/ntdll-DOS_Attributes/0002-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch new file mode 100644 index 00000000..0e98e644 --- /dev/null +++ b/patches/ntdll-DOS_Attributes/0002-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch @@ -0,0 +1,408 @@ +From 07b0e6fe66d8ac19d7584f52a066d2957d858144 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +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 + #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 ++#endif ++#ifdef HAVE_ATTR_XATTR_H ++# include ++#endif ++#ifdef HAVE_SYS_EXTATTR_H ++# include ++#endif ++ ++#include ++#include ++ ++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 + diff --git a/patches/ntdll-DOS_Attributes/0003-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch b/patches/ntdll-DOS_Attributes/0003-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch new file mode 100644 index 00000000..879bc045 --- /dev/null +++ b/patches/ntdll-DOS_Attributes/0003-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch @@ -0,0 +1,106 @@ +From aca454765b4a1cd8b7a50761fb0bd9f82043b895 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +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 + diff --git a/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch b/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch new file mode 100644 index 00000000..97df250f --- /dev/null +++ b/patches/ntdll-DOS_Attributes/0004-ntdll-Implement-retrieving-DOS-attributes-in-NtQuery.patch @@ -0,0 +1,52 @@ +From 2e97bfb51b37d8b3bd85a486b706bb1608ebd132 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +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 + diff --git a/patches/ntdll-DOS_Attributes/0005-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch b/patches/ntdll-DOS_Attributes/0005-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch new file mode 100644 index 00000000..dd171159 --- /dev/null +++ b/patches/ntdll-DOS_Attributes/0005-ntdll-Implement-storing-DOS-attributes-in-NtSetInfor.patch @@ -0,0 +1,185 @@ +From 1313cd2f5b09593702acd6d71187afdd50ccea4d Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +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 + diff --git a/patches/ntdll-DOS_Attributes/0006-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch b/patches/ntdll-DOS_Attributes/0006-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch new file mode 100644 index 00000000..3f73c639 --- /dev/null +++ b/patches/ntdll-DOS_Attributes/0006-ntdll-Implement-storing-DOS-attributes-in-NtCreateFi.patch @@ -0,0 +1,237 @@ +From f9c827c6a03c5741aebdcada20d512c9ceb44284 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +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 + diff --git a/patches/ntdll-DOS_Attributes/0007-ntdll-Perform-the-Unix-style-hidden-file-check-withi.patch b/patches/ntdll-DOS_Attributes/0007-ntdll-Perform-the-Unix-style-hidden-file-check-withi.patch new file mode 100644 index 00000000..7742ef88 --- /dev/null +++ b/patches/ntdll-DOS_Attributes/0007-ntdll-Perform-the-Unix-style-hidden-file-check-withi.patch @@ -0,0 +1,115 @@ +From 398cf0a70a0d313bf84c4ff8335f49ca68e1ee84 Mon Sep 17 00:00:00 2001 +From: "Erich E. Hoover" +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 + diff --git a/patches/ntdll-DOS_Attributes/definition b/patches/ntdll-DOS_Attributes/definition new file mode 100644 index 00000000..35ec2be2 --- /dev/null +++ b/patches/ntdll-DOS_Attributes/definition @@ -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 diff --git a/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch b/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch index 1e1cacf5..2f4018c5 100644 --- a/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch +++ b/patches/ntdll-Junction_Points/0001-ntdll-Add-support-for-junction-point-creation.patch @@ -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" 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(); diff --git a/patches/ntdll-Junction_Points/0002-ntdll-Add-support-for-reading-junction-points.patch b/patches/ntdll-Junction_Points/0002-ntdll-Add-support-for-reading-junction-points.patch index e82ef8a1..377edc0d 100644 --- a/patches/ntdll-Junction_Points/0002-ntdll-Add-support-for-reading-junction-points.patch +++ b/patches/ntdll-Junction_Points/0002-ntdll-Add-support-for-reading-junction-points.patch @@ -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" 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()); diff --git a/patches/ntdll-Junction_Points/0003-ntdll-Add-support-for-deleting-junction-points.patch b/patches/ntdll-Junction_Points/0003-ntdll-Add-support-for-deleting-junction-points.patch index ea83dcb3..0a762117 100644 --- a/patches/ntdll-Junction_Points/0003-ntdll-Add-support-for-deleting-junction-points.patch +++ b/patches/ntdll-Junction_Points/0003-ntdll-Add-support-for-deleting-junction-points.patch @@ -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" 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)); diff --git a/patches/ntdll-Junction_Points/0004-ntdll-Advertise-that-a-file-is-a-junction-point.patch b/patches/ntdll-Junction_Points/0004-ntdll-Advertise-that-a-file-is-a-junction-point.patch index 856609eb..ff46b37d 100644 --- a/patches/ntdll-Junction_Points/0004-ntdll-Advertise-that-a-file-is-a-junction-point.patch +++ b/patches/ntdll-Junction_Points/0004-ntdll-Advertise-that-a-file-is-a-junction-point.patch @@ -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" 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()); diff --git a/patches/ntdll-Junction_Points/0005-kernel32-ntdll-Add-support-for-deleting-junction-poi.patch b/patches/ntdll-Junction_Points/0005-kernel32-ntdll-Add-support-for-deleting-junction-poi.patch index 1f78f93a..7a7d18a6 100644 --- a/patches/ntdll-Junction_Points/0005-kernel32-ntdll-Add-support-for-deleting-junction-poi.patch +++ b/patches/ntdll-Junction_Points/0005-kernel32-ntdll-Add-support-for-deleting-junction-poi.patch @@ -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" 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); diff --git a/patches/ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch b/patches/ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch index 630d840a..62a6b75f 100644 --- a/patches/ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch +++ b/patches/ntdll-Junction_Points/0006-kernel32-Advertise-junction-point-support.patch @@ -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" 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) diff --git a/patches/ntdll-Junction_Points/0007-ntdll-tests-Add-test-for-deleting-junction-point-tar.patch b/patches/ntdll-Junction_Points/0007-ntdll-tests-Add-test-for-deleting-junction-point-tar.patch index c8f54f1f..458caa6c 100644 --- a/patches/ntdll-Junction_Points/0007-ntdll-tests-Add-test-for-deleting-junction-point-tar.patch +++ b/patches/ntdll-Junction_Points/0007-ntdll-tests-Add-test-for-deleting-junction-point-tar.patch @@ -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" 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); diff --git a/patches/server-ACL_Compat/0010-server-Add-compatibility-code-for-handling-the-old-m.patch b/patches/server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch similarity index 93% rename from patches/server-ACL_Compat/0010-server-Add-compatibility-code-for-handling-the-old-m.patch rename to patches/server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch index e89c83ea..1aa12f2c 100644 --- a/patches/server-ACL_Compat/0010-server-Add-compatibility-code-for-handling-the-old-m.patch +++ b/patches/server-ACL_Compat/0001-server-Add-compatibility-code-for-handling-the-old-m.patch @@ -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" 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 ); diff --git a/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch b/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch index ff1b525b..c64a1793 100644 --- a/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch +++ b/patches/server-Inherited_ACLs/0001-server-Inherit-security-attributes-from-parent-direc.patch @@ -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" 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 ); diff --git a/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch b/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch index ff0fe766..a8e4d264 100644 --- a/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch +++ b/patches/server-Inherited_ACLs/0002-server-Inherit-security-attributes-from-parent-direc.patch @@ -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" 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(); diff --git a/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch b/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch index fea97603..85896868 100644 --- a/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch +++ b/patches/server-Stored_ACLs/0001-server-Unify-the-storage-of-security-attributes-for-.patch @@ -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" 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 ) { diff --git a/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch b/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch index 4ce0790b..f54b490b 100644 --- a/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch +++ b/patches/server-Stored_ACLs/0002-server-Unify-the-retrieval-of-security-attributes-fo.patch @@ -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" 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; } diff --git a/patches/server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch b/patches/server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch index 3088f6df..fd49779b 100644 --- a/patches/server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch +++ b/patches/server-Stored_ACLs/0003-server-Store-file-security-attributes-with-extended-.patch @@ -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" 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 - #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 #ifdef HAVE_UTIME_H #include -@@ -39,6 +40,13 @@ - #ifdef HAVE_POLL_H - #include - #endif -+#ifdef HAVE_ATTR_XATTR_H -+#include -+#endif -+#ifdef HAVE_SYS_EXTATTR_H -+#include -+#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 ); diff --git a/patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch b/patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch index adf81152..955a7a25 100644 --- a/patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch +++ b/patches/server-Stored_ACLs/0004-server-Store-user-and-group-inside-stored-extended-f.patch @@ -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" 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 ); diff --git a/patches/server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch b/patches/server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch index f1b70713..edae1c90 100644 --- a/patches/server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch +++ b/patches/server-Stored_ACLs/0005-server-Retrieve-file-security-attributes-with-extend.patch @@ -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" 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; diff --git a/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch b/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch index 50c08e72..000bb8a2 100644 --- a/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch +++ b/patches/server-Stored_ACLs/0006-server-Convert-return-of-file-security-masks-with-ge.patch @@ -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" 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 ); diff --git a/patches/server-Stored_ACLs/definition b/patches/server-Stored_ACLs/definition index 8cb556f3..80a71273 100644 --- a/patches/server-Stored_ACLs/definition +++ b/patches/server-Stored_ACLs/definition @@ -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