mirror of
git://source.winehq.org/git/wine.git
synced 2024-10-14 10:47:18 +00:00
ntdll: Set xattr in NtCreateFile if inferred and requested attributes don't match.
And make sure it doesn't get deleted. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=53826 Signed-off-by: Torge Matthies <tmatthies@codeweavers.com>
This commit is contained in:
parent
d433986924
commit
8245478055
|
@ -4094,7 +4094,7 @@ static void test_dotfile_file_attributes(void)
|
||||||
|
|
||||||
status = nt_get_file_attrs(filename, &attrs);
|
status = nt_get_file_attrs(filename, &attrs);
|
||||||
ok( status == STATUS_SUCCESS, "got %#lx\n", status );
|
ok( status == STATUS_SUCCESS, "got %#lx\n", status );
|
||||||
todo_wine ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs );
|
ok( !(attrs & FILE_ATTRIBUTE_HIDDEN), "got attributes %#lx\n", attrs );
|
||||||
|
|
||||||
status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation );
|
status = pNtQueryInformationFile( h, &io, &info, sizeof(info), FileBasicInformation );
|
||||||
ok( status == STATUS_SUCCESS, "got %#lx\n", status );
|
ok( status == STATUS_SUCCESS, "got %#lx\n", status );
|
||||||
|
|
|
@ -1604,11 +1604,11 @@ static int fd_get_file_info( int fd, unsigned int options, struct stat *st, ULON
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int fd_set_dos_attrib( int fd, UINT attr )
|
static int fd_set_dos_attrib( int fd, UINT attr, BOOL force_set )
|
||||||
{
|
{
|
||||||
/* we only store the HIDDEN and SYSTEM attributes */
|
/* we only store the HIDDEN and SYSTEM attributes */
|
||||||
attr &= XATTR_ATTRIBS_MASK;
|
attr &= XATTR_ATTRIBS_MASK;
|
||||||
if (attr != 0)
|
if (force_set || attr != 0)
|
||||||
{
|
{
|
||||||
/* encode the attributes in Samba 3 ASCII format. Samba 4 has extended
|
/* encode the attributes in Samba 3 ASCII format. Samba 4 has extended
|
||||||
* this format with more features, but retains compatibility with the
|
* this format with more features, but retains compatibility with the
|
||||||
|
@ -1622,7 +1622,7 @@ static int fd_set_dos_attrib( int fd, UINT attr )
|
||||||
|
|
||||||
|
|
||||||
/* set the stat info and file attributes for a file (by file descriptor) */
|
/* set the stat info and file attributes for a file (by file descriptor) */
|
||||||
static NTSTATUS fd_set_file_info( int fd, UINT attr )
|
static NTSTATUS fd_set_file_info( int fd, UINT attr, BOOL force_set_xattr )
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
@ -1641,7 +1641,11 @@ static NTSTATUS fd_set_file_info( int fd, UINT attr )
|
||||||
}
|
}
|
||||||
if (fchmod( fd, st.st_mode ) == -1) return errno_to_status( errno );
|
if (fchmod( fd, st.st_mode ) == -1) return errno_to_status( errno );
|
||||||
|
|
||||||
if (fd_set_dos_attrib( fd, attr ) == -1 && errno != ENOTSUP)
|
/* if the file has multiple names, we can't be sure that it is safe to not
|
||||||
|
set the extended attribute, since any of the names could start with a dot */
|
||||||
|
force_set_xattr = force_set_xattr || st.st_nlink > 1;
|
||||||
|
|
||||||
|
if (fd_set_dos_attrib( fd, attr, force_set_xattr ) == -1 && errno != ENOTSUP)
|
||||||
WARN( "Failed to set extended attribute " SAMBA_XATTR_DOS_ATTRIB ". errno %d (%s)\n",
|
WARN( "Failed to set extended attribute " SAMBA_XATTR_DOS_ATTRIB ". errno %d (%s)\n",
|
||||||
errno, strerror( errno ) );
|
errno, strerror( errno ) );
|
||||||
|
|
||||||
|
@ -3967,6 +3971,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
OBJECT_ATTRIBUTES new_attr;
|
OBJECT_ATTRIBUTES new_attr;
|
||||||
UNICODE_STRING nt_name;
|
UNICODE_STRING nt_name;
|
||||||
char *unix_name;
|
char *unix_name;
|
||||||
|
BOOL name_hidden = FALSE;
|
||||||
BOOL created = FALSE;
|
BOOL created = FALSE;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
|
|
||||||
|
@ -4009,6 +4014,7 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
|
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
{
|
{
|
||||||
|
name_hidden = is_hidden_file( unix_name );
|
||||||
status = open_unix_file( handle, unix_name, access, &new_attr, attributes,
|
status = open_unix_file( handle, unix_name, access, &new_attr, attributes,
|
||||||
sharing, disposition, options, ea_buffer, ea_length );
|
sharing, disposition, options, ea_buffer, ea_length );
|
||||||
free( unix_name );
|
free( unix_name );
|
||||||
|
@ -4036,14 +4042,15 @@ NTSTATUS WINAPI NtCreateFile( HANDLE *handle, ACCESS_MASK access, OBJECT_ATTRIBU
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (io->Information == FILE_CREATED && (attributes & XATTR_ATTRIBS_MASK))
|
if (io->Information == FILE_CREATED &&
|
||||||
|
((attributes & XATTR_ATTRIBS_MASK) || name_hidden))
|
||||||
{
|
{
|
||||||
int fd, needs_close;
|
int fd, needs_close;
|
||||||
|
|
||||||
/* set any DOS extended attributes */
|
/* set any DOS extended attributes */
|
||||||
if (!server_get_unix_fd( *handle, 0, &fd, &needs_close, NULL, NULL ))
|
if (!server_get_unix_fd( *handle, 0, &fd, &needs_close, NULL, NULL ))
|
||||||
{
|
{
|
||||||
if (fd_set_dos_attrib( fd, attributes ) == -1 && errno != ENOTSUP)
|
if (fd_set_dos_attrib( fd, attributes, TRUE ) == -1 && errno != ENOTSUP)
|
||||||
WARN( "Failed to set extended attribute " SAMBA_XATTR_DOS_ATTRIB ". errno %d (%s)",
|
WARN( "Failed to set extended attribute " SAMBA_XATTR_DOS_ATTRIB ". errno %d (%s)",
|
||||||
errno, strerror( errno ) );
|
errno, strerror( errno ) );
|
||||||
if (needs_close) close( fd );
|
if (needs_close) close( fd );
|
||||||
|
@ -4565,20 +4572,25 @@ NTSTATUS WINAPI NtSetInformationFile( HANDLE handle, IO_STATUS_BLOCK *io,
|
||||||
{
|
{
|
||||||
const FILE_BASIC_INFORMATION *info = ptr;
|
const FILE_BASIC_INFORMATION *info = ptr;
|
||||||
LARGE_INTEGER mtime, atime;
|
LARGE_INTEGER mtime, atime;
|
||||||
|
char *unix_name;
|
||||||
|
|
||||||
if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
|
if ((status = server_get_unix_fd( handle, 0, &fd, &needs_close, NULL, NULL )))
|
||||||
return io->u.Status = status;
|
return io->u.Status = status;
|
||||||
|
|
||||||
|
if (server_get_unix_name( handle, &unix_name )) unix_name = NULL;
|
||||||
|
|
||||||
mtime.QuadPart = info->LastWriteTime.QuadPart == -1 ? 0 : info->LastWriteTime.QuadPart;
|
mtime.QuadPart = info->LastWriteTime.QuadPart == -1 ? 0 : info->LastWriteTime.QuadPart;
|
||||||
atime.QuadPart = info->LastAccessTime.QuadPart == -1 ? 0 : info->LastAccessTime.QuadPart;
|
atime.QuadPart = info->LastAccessTime.QuadPart == -1 ? 0 : info->LastAccessTime.QuadPart;
|
||||||
|
|
||||||
if (atime.QuadPart || mtime.QuadPart)
|
if (atime.QuadPart || mtime.QuadPart)
|
||||||
status = set_file_times( fd, &mtime, &atime );
|
status = set_file_times( fd, &mtime, &atime );
|
||||||
|
|
||||||
if (status == STATUS_SUCCESS && info->FileAttributes)
|
if (status == STATUS_SUCCESS)
|
||||||
status = fd_set_file_info( fd, info->FileAttributes );
|
status = fd_set_file_info( fd, info->FileAttributes,
|
||||||
|
unix_name && is_hidden_file( unix_name ));
|
||||||
|
|
||||||
if (needs_close) close( fd );
|
if (needs_close) close( fd );
|
||||||
|
free( unix_name );
|
||||||
}
|
}
|
||||||
else status = STATUS_INVALID_PARAMETER_3;
|
else status = STATUS_INVALID_PARAMETER_3;
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Reference in a new issue