From: "Erich E. Hoover" erich.e.hoover@gmail.com
--- 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 2a5fedb4659..dda2afe3703 100644 --- a/dlls/ntdll/tests/directory.c +++ b/dlls/ntdll/tests/directory.c @@ -55,7 +55,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 */ @@ -63,16 +62,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 */ @@ -162,8 +161,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 c9594510fb8..094c5eb5ab5 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 ) { @@ -3827,6 +3847,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 @@ -3912,13 +3946,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) { @@ -3940,6 +3975,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) { @@ -3948,6 +3988,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU }
free( nt_name.Buffer ); + free( unix_name ); return io->u.Status = status; }