Rebase against 16c6c249a5134de2422fbd3471ead7425c968301.

This commit is contained in:
Zebediah Figura
2022-10-10 22:27:34 -05:00
parent 0ea57a0262
commit e6f9a449cd
13 changed files with 58 additions and 636 deletions

View File

@@ -1,122 +0,0 @@
From 80cb1bf9077b1e754fc2f3426229733c3417c397 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Tue, 19 Aug 2014 22:10:49 -0600
Subject: [PATCH] ntdll: Implement retrieving DOS attributes in
[fd_]get_file_info().
---
configure.ac | 12 ++++++++++++
dlls/ntdll/unix/file.c | 39 ++++++++++++++++++++++++++++++++++++++-
2 files changed, 50 insertions(+), 1 deletion(-)
diff --git a/configure.ac b/configure.ac
index c68c5975e63..84efc670ca4 100644
--- a/configure.ac
+++ b/configure.ac
@@ -64,6 +64,7 @@ AC_ARG_WITH(unwind, AS_HELP_STRING([--without-unwind],[do not use the libunwi
AC_ARG_WITH(usb, AS_HELP_STRING([--without-usb],[do not use the libusb library]))
AC_ARG_WITH(v4l2, AS_HELP_STRING([--without-v4l2],[do not use v4l2 (video capture)]))
AC_ARG_WITH(vulkan, AS_HELP_STRING([--without-vulkan],[do not use Vulkan]))
+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]),
@@ -634,6 +635,17 @@ AC_CHECK_HEADERS([libprocstat.h],,,
#include <sys/queue.h>
#endif])
+if test "x$with_xattr" != "xno"
+then
+ AC_CHECK_HEADERS(attr/xattr.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 libattr at the very least.])
+fi
+
dnl **** Check for working dll ****
AC_SUBST(DLLFLAGS,"")
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index a29b5cbb980..1ae4645c6fb 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -98,6 +98,9 @@
#ifdef HAVE_SYS_STATFS_H
#include <sys/statfs.h>
#endif
+#ifdef HAVE_ATTR_XATTR_H
+#include <attr/xattr.h>
+#endif
#include <time.h>
#include <unistd.h>
@@ -355,6 +358,20 @@ NTSTATUS errno_to_status( int err )
}
}
+#ifndef XATTR_USER_PREFIX
+#define XATTR_USER_PREFIX "user."
+#endif
+
+static int xattr_get( const char *path, const char *name, void *value, size_t size )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return getxattr( path, name, value, size );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
/* get space from the current directory data buffer, allocating a new one if necessary */
static void *get_dir_data_space( struct dir_data *data, unsigned int size )
{
@@ -1436,6 +1453,22 @@ static BOOL append_entry( struct dir_data *data, const char *long_name,
}
+/* Match the Samba conventions for storing DOS file attributes */
+#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)
+
+/* decode the xattr-stored DOS attributes */
+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;
+}
+
/* fetch the attributes of a file */
static inline ULONG get_file_attributes( const struct stat *st )
{
@@ -1479,7 +1512,8 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
char *parent_path;
- int ret;
+ char hexattr[11];
+ int len, ret;
*attr = 0;
ret = lstat( path, st );
@@ -1505,6 +1539,9 @@ static int get_file_info( const char *path, struct stat *st, ULONG *attr )
free( parent_path );
}
*attr |= get_file_attributes( st );
+ len = xattr_get( path, SAMBA_XATTR_DOS_ATTRIB, hexattr, sizeof(hexattr)-1 );
+ if (len == -1) return ret;
+ *attr |= get_file_xattr( hexattr, len );
return ret;
}
--
2.34.1

View File

@@ -1,160 +0,0 @@
From 49f8ae15c8065c9133e0c08eaba68049cdb85e0b Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 00:08:52 -0600
Subject: [PATCH] ntdll: Implement storing DOS attributes in
NtSetInformationFile.
---
dlls/ntdll/tests/file.c | 8 ++---
dlls/ntdll/unix/file.c | 74 ++++++++++++++++++++++++++++++-----------
2 files changed, 58 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/tests/file.c b/dlls/ntdll/tests/file.c
index 4014b395b56..ad718fab828 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1401,7 +1401,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 %lx not FILE_ATTRIBUTE_SYSTEM\n", fbi.FileAttributes );
+ ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx not FILE_ATTRIBUTE_SYSTEM (ok in old linux without xattr)\n", fbi.FileAttributes );
/* Then HIDDEN */
memset(&fbi, 0, sizeof(fbi));
@@ -1414,7 +1414,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 %lx not FILE_ATTRIBUTE_HIDDEN\n", fbi.FileAttributes );
+ ok ( (fbi.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx 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));
@@ -1471,7 +1471,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 %lx not FILE_ATTRIBUTE_SYSTEM\n", fai_buf.fai.BasicInformation.FileAttributes );
+ ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_SYSTEM, "attribute %lx 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));
@@ -1484,7 +1484,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 %lx not FILE_ATTRIBUTE_HIDDEN\n", fai_buf.fai.BasicInformation.FileAttributes );
+ ok ( (fai_buf.fai.BasicInformation.FileAttributes & attrib_mask) == FILE_ATTRIBUTE_HIDDEN, "attribute %lx 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/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index a3520898d57..cd53ca36238 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -362,6 +362,26 @@ NTSTATUS errno_to_status( int err )
#define XATTR_USER_PREFIX "user."
#endif
+static int xattr_fremove( int filedes, const char *name )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return fremovexattr( filedes, name );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int xattr_fset( int filedes, const char *name, void *value, size_t size )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return fsetxattr( filedes, name, value, size, 0 );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
static int xattr_get( const char *path, const char *name, void *value, size_t size )
{
#if defined(HAVE_ATTR_XATTR_H)
@@ -1508,6 +1528,39 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
}
+/* set the stat info and file attributes for a file (by file descriptor) */
+NTSTATUS fd_set_file_info( int fd, ULONG attr )
+{
+ char hexattr[11];
+ struct stat st;
+
+ if (fstat( fd, &st ) == -1) return errno_to_status( errno );
+ 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)) & (~start_umask);
+ }
+ if (fchmod( fd, st.st_mode ) == -1) return errno_to_status( errno );
+ attr &= ~FILE_ATTRIBUTE_NORMAL; /* do not store everything, but keep everything Samba can use */
+ if (attr != 0)
+ {
+ int len;
+
+ len = sprintf( hexattr, "0x%x", attr );
+ xattr_fset( fd, SAMBA_XATTR_DOS_ATTRIB, hexattr, len );
+ }
+ else
+ xattr_fremove( fd, SAMBA_XATTR_DOS_ATTRIB );
+ return STATUS_SUCCESS;
+}
+
/* get the stat info and file attributes for a file (by name) */
static int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
@@ -4359,7 +4412,6 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
case FileBasicInformation:
if (len >= sizeof(FILE_BASIC_INFORMATION))
{
- struct stat st;
const FILE_BASIC_INFORMATION *info = ptr;
LARGE_INTEGER mtime, atime;
@@ -4373,25 +4425,7 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
status = set_file_times( fd, &mtime, &atime );
if (status == STATUS_SUCCESS && info->FileAttributes)
- {
- if (fstat( fd, &st ) == -1) status = errno_to_status( errno );
- 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)) & (~start_umask);
- }
- if (fchmod( fd, st.st_mode ) == -1) status = errno_to_status( errno );
- }
- }
+ status = fd_set_file_info( fd, info->FileAttributes );
if (needs_close) close( fd );
}
--
2.35.1

View File

@@ -1,154 +0,0 @@
From 2f6ec5b1accc1ac275bcb4edeb44c15e271d2f72 Mon Sep 17 00:00:00 2001
From: "Erich E. Hoover" <erich.e.hoover@gmail.com>
Date: Wed, 20 Aug 2014 15:28:00 -0600
Subject: [PATCH] ntdll: Implement storing DOS attributes in NtCreateFile.
---
dlls/ntdll/tests/directory.c | 24 ++++++++---------
dlls/ntdll/unix/file.c | 51 ++++++++++++++++++++++++++++++++----
2 files changed, 57 insertions(+), 18 deletions(-)
diff --git a/dlls/ntdll/tests/directory.c b/dlls/ntdll/tests/directory.c
index 77b17a50037..07211ebf5de 100644
--- a/dlls/ntdll/tests/directory.c
+++ b/dlls/ntdll/tests/directory.c
@@ -56,7 +56,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 */
WCHAR name[20]; /* filename to use */
@@ -64,16 +63,16 @@ static struct testfile_s {
const char *description; /* for error messages */
int nfound; /* How many were found (expect 1) */
} testfiles[] = {
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {'l','o','n','g','f','i','l','e','n','a','m','e','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {'n','.','t','m','p',}, "normal" },
- { 1, 0, FILE_ATTRIBUTE_HIDDEN, {'h','.','t','m','p',}, "hidden" },
- { 1, 0, FILE_ATTRIBUTE_SYSTEM, {'s','.','t','m','p',}, "system" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'d','.','t','m','p',}, "directory" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {0xe9,'a','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {0xc9,'b','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p'}, "normal" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" },
- { 0, 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" }
+ { 0, FILE_ATTRIBUTE_NORMAL, {'l','o','n','g','f','i','l','e','n','a','m','e','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {'n','.','t','m','p',}, "normal" },
+ { 0, FILE_ATTRIBUTE_HIDDEN, {'h','.','t','m','p',}, "hidden" },
+ { 0, FILE_ATTRIBUTE_SYSTEM, {'s','.','t','m','p',}, "system" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, {'d','.','t','m','p',}, "directory" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {0xe9,'a','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {0xc9,'b','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_NORMAL, {'e','a','.','t','m','p'}, "normal" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, {'.'}, ". directory" },
+ { 0, FILE_ATTRIBUTE_DIRECTORY, {'.','.'}, ".. directory" }
};
static const int test_dir_count = ARRAY_SIZE(testfiles);
static const int max_test_dir_size = ARRAY_SIZE(testfiles) + 5; /* size of above plus some for .. etc */
@@ -163,8 +162,7 @@ static void tally_test_file(FILE_BOTH_DIRECTORY_INFORMATION *dir_info)
if (namelen != len || memcmp(nameW, testfiles[i].name, len*sizeof(WCHAR)))
continue;
if (!testfiles[i].attr_done) {
- todo_wine_if (testfiles[i].todo)
- ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%lx), got %lx (is your linux new enough?)\n", wine_dbgstr_w(testfiles[i].name), testfiles[i].description, testfiles[i].attr, attrib);
+ ok (attrib == (testfiles[i].attr & attribmask), "file %s: expected %s (%lx), got %lx (is your linux new enough?)\n", wine_dbgstr_w(testfiles[i].name), testfiles[i].description, testfiles[i].attr, attrib);
testfiles[i].attr_done = TRUE;
}
testfiles[i].nfound++;
diff --git a/dlls/ntdll/unix/file.c b/dlls/ntdll/unix/file.c
index cd53ca36238..185db877d55 100644
--- a/dlls/ntdll/unix/file.c
+++ b/dlls/ntdll/unix/file.c
@@ -392,6 +392,26 @@ static int xattr_get( const char *path, const char *name, void *value, size_t si
#endif
}
+static int xattr_remove( const char *path, const char *name )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return removexattr( path, name );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+static int xattr_set( const char *path, const char *name, void *value, size_t size )
+{
+#if defined(HAVE_ATTR_XATTR_H)
+ return setxattr( path, name, value, size, 0 );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
/* get space from the current directory data buffer, allocating a new one if necessary */
static void *get_dir_data_space( struct dir_data *data, unsigned int size )
{
@@ -3786,6 +3806,20 @@ static NTSTATUS unmount_device( HANDLE handle )
return status;
}
+NTSTATUS set_file_info( const char *path, ULONG attr )
+{
+ char hexattr[11];
+ 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;
+}
/******************************************************************************
* open_unix_file
@@ -3871,13 +3905,14 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
status = STATUS_SUCCESS;
}
- if (status == STATUS_SUCCESS)
+ if (status != STATUS_SUCCESS)
{
- status = open_unix_file( handle, unix_name, access, &new_attr, attributes,
- sharing, disposition, options, ea_buffer, ea_length );
- free( unix_name );
+ WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), io->u.Status );
+ return status;
}
- else WARN( "%s not found (%x)\n", debugstr_us(attr->ObjectName), status );
+
+ status = open_unix_file( handle, unix_name, access, &new_attr, attributes,
+ sharing, disposition, options, ea_buffer, ea_length );
if (status == STATUS_SUCCESS)
{
@@ -3899,6 +3934,11 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
io->Information = FILE_OVERWRITTEN;
break;
}
+ if (io->Information == FILE_CREATED)
+ {
+ /* set any DOS extended attributes */
+ set_file_info( unix_name, attributes );
+ }
}
else if (status == STATUS_TOO_MANY_OPENED_FILES)
{
@@ -3907,6 +3947,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
}
free( nt_name.Buffer );
+ free( unix_name );
return io->u.Status = status;
}
--
2.35.1

View File

@@ -1,2 +1,4 @@
Fixes: [9158] Support for DOS hidden/system file attributes
Fixes: [15679] cygwin symlinks not working in wine
# Hopefully in the process of upstreaming.
Disabled: true