[PATCH V2 3/7] ntdll: Implement storing DOS attributes in NtSetInformationFile.
Vijay Kiran Kamuju
infyquest at gmail.com
Sat Apr 27 21:20:00 CDT 2019
From: "Erich E. Hoover" <erich.e.hoover at gmail.com>
v2: merge macos support
From: Erich E. Hoover <erich.e.hoover at gmail.com>
Signed-off-by: Vijay Kiran Kamuju <infyquest at gmail.com>
---
dlls/ntdll/file.c | 54 ++++++++++++++++++++++++++---------------
dlls/ntdll/tests/file.c | 8 +++---
include/wine/port.h | 2 ++
libs/port/xattr.c | 24 ++++++++++++++++++
4 files changed, 64 insertions(+), 24 deletions(-)
diff --git a/dlls/ntdll/file.c b/dlls/ntdll/file.c
index 02fd7a940b..852b2462fe 100644
--- a/dlls/ntdll/file.c
+++ b/dlls/ntdll/file.c
@@ -168,6 +168,39 @@ int fd_get_file_info( int fd, struct stat *st, ULONG *attr )
return ret;
}
+/* 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 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 */
+ 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) */
int get_file_info( const char *path, struct stat *st, ULONG *attr )
{
@@ -2544,7 +2577,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 )))
@@ -2554,25 +2586,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 8e54dbb541..fc20615550 100644
--- a/dlls/ntdll/tests/file.c
+++ b/dlls/ntdll/tests/file.c
@@ -1340,7 +1340,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));
@@ -1353,7 +1353,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));
@@ -1410,7 +1410,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));
@@ -1423,7 +1423,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 15b7b3f666..1c9fe93745 100644
--- a/include/wine/port.h
+++ b/include/wine/port.h
@@ -342,6 +342,8 @@ extern int mkstemps(char *template, int suffix_len);
#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 38f978cfb2..1366e72f3d 100644
--- a/libs/port/xattr.c
+++ b/libs/port/xattr.c
@@ -43,6 +43,30 @@ int xattr_fget( int filedes, const char *name, void *value, size_t size )
#endif
}
+int xattr_fremove( int filedes, const char *name )
+{
+#if defined(XATTR_ADDITIONAL_OPTIONS)
+ return fremovexattr( filedes, name, 0 );
+#elif defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_XATTR_H)
+ return fremovexattr( filedes, name );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
+int xattr_fset( int filedes, const char *name, void *value, size_t size )
+{
+#if defined(XATTR_ADDITIONAL_OPTIONS)
+ return fsetxattr( filedes, name, value, size, 0, 0 );
+#elif defined(HAVE_ATTR_XATTR_H) || defined(HAVE_SYS_XATTR_H)
+ return fsetxattr( filedes, name, value, size, 0 );
+#else
+ errno = ENOSYS;
+ return -1;
+#endif
+}
+
int xattr_get( const char *path, const char *name, void *value, size_t size )
{
#if defined(XATTR_ADDITIONAL_OPTIONS)
--
2.21.0
More information about the wine-devel
mailing list