* 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.
This commit is contained in:
		| @@ -1,3 +1,13 @@ | ||||
| 2008-10-20  Corinna Vinschen  <corinna@vinschen.de> | ||||
|  | ||||
| 	* 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  <corinna@vinschen.de> | ||||
|  | ||||
| 	* dtable.cc (dtable::get_debugger_info): Call SetStdHandle | ||||
|   | ||||
| @@ -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 ()) | ||||
|     { | ||||
|   | ||||
| @@ -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); | ||||
|   } | ||||
| } | ||||
|   | ||||
| @@ -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; | ||||
|   | ||||
| @@ -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)) | ||||
| 	{ | ||||
|   | ||||
		Reference in New Issue
	
	Block a user