From 669bdeb82236ed53f094702ec4af7d253d828df4 Mon Sep 17 00:00:00 2001 From: Corinna Vinschen Date: Mon, 20 Oct 2008 19:30:06 +0000 Subject: [PATCH] * ntdll.h (NtSetAttributesFile): New inline function. * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Use NtSetAttributesFile. * path.cc (symlink_worker): Ditto. * syscalls.cc (unlink_nt): Ditto. (rename): Omit FILE_SHARE_DELETE when opening files on Samba. Add comment to explain why. --- winsup/cygwin/ChangeLog | 10 ++++++++ winsup/cygwin/fhandler_disk_file.cc | 8 ++---- winsup/cygwin/ntdll.h | 11 ++++++++ winsup/cygwin/path.cc | 15 +++-------- winsup/cygwin/syscalls.cc | 39 +++++++++-------------------- 5 files changed, 38 insertions(+), 45 deletions(-) diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 444d6b702..e3d14635a 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,13 @@ +2008-10-20 Corinna Vinschen + + * ntdll.h (NtSetAttributesFile): New inline function. + * fhandler_disk_file.cc (fhandler_disk_file::fchmod): Use + NtSetAttributesFile. + * path.cc (symlink_worker): Ditto. + * syscalls.cc (unlink_nt): Ditto. + (rename): Omit FILE_SHARE_DELETE when opening files on Samba. Add + comment to explain why. + 2008-10-17 Corinna Vinschen * dtable.cc (dtable::get_debugger_info): Call SetStdHandle diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc index e3c9aaf93..e0880f050 100644 --- a/winsup/cygwin/fhandler_disk_file.cc +++ b/winsup/cygwin/fhandler_disk_file.cc @@ -827,12 +827,8 @@ fhandler_disk_file::fchmod (mode_t mode) if (S_ISSOCK (mode)) pc |= (DWORD) FILE_ATTRIBUTE_SYSTEM; - FILE_BASIC_INFORMATION fbi; - fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart - = fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL; - fbi.FileAttributes = pc.file_attributes () ?: FILE_ATTRIBUTE_NORMAL; - status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi, - FileBasicInformation); + status = NtSetAttributesFile (get_handle (), pc.file_attributes () + ?: FILE_ATTRIBUTE_NORMAL); /* Correct NTFS security attributes have higher priority */ if (!pc.has_acls ()) { diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h index 4d5eed235..1ce348f47 100644 --- a/winsup/cygwin/ntdll.h +++ b/winsup/cygwin/ntdll.h @@ -1072,4 +1072,15 @@ extern "C" NTSTATUS NTAPI RtlInt64ToHexUnicodeString (ULONGLONG value, PUNICODE_STRING dest, BOOLEAN append); + /* Set file attributes. Don't change file times. */ + inline + NTSTATUS NTAPI NtSetAttributesFile (HANDLE h, ULONG attr) + { + IO_STATUS_BLOCK io; + FILE_BASIC_INFORMATION fbi; + fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart = + fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL; + fbi.FileAttributes = attr ?: FILE_ATTRIBUTE_NORMAL; + return NtSetInformationFile(h, &io, &fbi, sizeof fbi, FileBasicInformation); + } } diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc index 442e7bb90..1f9028a4d 100644 --- a/winsup/cygwin/path.cc +++ b/winsup/cygwin/path.cc @@ -1516,7 +1516,6 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, IO_STATUS_BLOCK io; NTSTATUS status; HANDLE fh; - FILE_BASIC_INFORMATION fbi; tmp_pathbuf tp; /* POSIX says that empty 'newpath' is invalid input while empty @@ -1741,11 +1740,7 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, __seterrno_from_nt_status (status); goto done; } - fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart - = fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL; - fbi.FileAttributes = FILE_ATTRIBUTE_NORMAL; - status = NtSetInformationFile (fh, &io, &fbi, sizeof fbi, - FileBasicInformation); + status = NtSetAttributesFile (fh, FILE_ATTRIBUTE_NORMAL); NtClose (fh); if (!NT_SUCCESS (status)) { @@ -1778,12 +1773,8 @@ symlink_worker (const char *oldpath, const char *newpath, bool use_winsym, status = NtWriteFile (fh, NULL, NULL, NULL, &io, buf, cp - buf, NULL, NULL); if (NT_SUCCESS (status) && io.Information == (ULONG) (cp - buf)) { - fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart - = fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL; - fbi.FileAttributes = use_winsym ? FILE_ATTRIBUTE_READONLY - : FILE_ATTRIBUTE_SYSTEM; - status = NtSetInformationFile (fh, &io, &fbi, sizeof fbi, - FileBasicInformation); + status = NtSetAttributesFile (fh, use_winsym ? FILE_ATTRIBUTE_READONLY + : FILE_ATTRIBUTE_SYSTEM); if (!NT_SUCCESS (status)) debug_printf ("Setting attributes failed, status = %p", status); res = 0; diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 68bfa93d3..9b39f7712 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -399,7 +399,6 @@ unlink_nt (path_conv &pc) HANDLE fh; OBJECT_ATTRIBUTES attr; IO_STATUS_BLOCK io; - FILE_BASIC_INFORMATION fbi; ACCESS_MASK access = DELETE; /* If the R/O attribute is set, we have to open the file with @@ -473,13 +472,7 @@ unlink_nt (path_conv &pc) /* Get rid of read-only attribute. */ if (access & FILE_WRITE_ATTRIBUTES) - { - fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart = - fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL; - fbi.FileAttributes = (pc.file_attributes () & ~FILE_ATTRIBUTE_READONLY) - ?: FILE_ATTRIBUTE_NORMAL; - NtSetInformationFile (fh, &io, &fbi, sizeof fbi, FileBasicInformation); - } + NtSetAttributesFile (fh, pc.file_attributes () & ~FILE_ATTRIBUTE_READONLY); FILE_DISPOSITION_INFORMATION disp = { TRUE }; status = NtSetInformationFile (fh, &io, &disp, sizeof disp, @@ -487,22 +480,16 @@ unlink_nt (path_conv &pc) if (!NT_SUCCESS (status)) { syscall_printf ("Setting delete disposition failed, status = %p", status); + /* Restore R/O attributes. */ if (access & FILE_WRITE_ATTRIBUTES) - { - /* Restore R/O attributes. */ - fbi.FileAttributes = pc.file_attributes (); - NtSetInformationFile (fh, &io, &fbi, sizeof fbi, - FileBasicInformation); - } + NtSetAttributesFile (fh, pc.file_attributes ()); } else if ((access & FILE_WRITE_ATTRIBUTES) && !pc.isdir ()) { /* Restore R/O attribute to accommodate hardlinks. Don't try this with directories! For some reason the below NtSetInformationFile changes the disposition for delete back to FALSE, at least on XP. */ - fbi.FileAttributes = pc.file_attributes (); - NtSetInformationFile (fh, &io, &fbi, sizeof fbi, - FileBasicInformation); + NtSetAttributesFile (fh, pc.file_attributes ()); } NtClose (fh); @@ -1727,9 +1714,13 @@ rename (const char *oldpath, const char *newpath) || (!removepc && dstpc->has_attribute (FILE_ATTRIBUTE_READONLY)))) start_transaction (old_trans, trans); - /* DELETE is required to rename a file. */ + /* DELETE is required to rename a file. Samba (only some versions?) doesn't + like the FILE_SHARE_DELETE mode if the file has the R/O attribute set + and returns STATUS_ACCESS_DENIED in that case. */ status = NtOpenFile (&fh, DELETE, oldpc.get_object_attr (attr, sec_none_nih), - &io, FILE_SHARE_VALID_FLAGS, + &io, + oldpc.fs_is_samba () ? FILE_SHARE_READ | FILE_SHARE_WRITE + : FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT | (oldpc.is_rep_symlink () ? FILE_OPEN_REPARSE_POINT : 0)); if (!NT_SUCCESS (status)) @@ -1769,14 +1760,8 @@ rename (const char *oldpath, const char *newpath) __seterrno_from_nt_status (status); goto out; } - FILE_BASIC_INFORMATION fbi; - fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart = - fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL; - fbi.FileAttributes = (dstpc->file_attributes () - & ~FILE_ATTRIBUTE_READONLY) - ?: FILE_ATTRIBUTE_NORMAL; - status = NtSetInformationFile (nfh, &io, &fbi, sizeof fbi, - FileBasicInformation); + status = NtSetAttributesFile (nfh, dstpc->file_attributes () + & ~FILE_ATTRIBUTE_READONLY); NtClose (nfh); if (!NT_SUCCESS (status)) {