* fhandler_disk_file.cc: Use get_handle throughout.
(fhandler_disk_file::fchmod): Always try to open file with required access rights. Use NtSetInformationFile instead of SetFileAttributes. (fhandler_disk_file::facl): Use NtSetInformationFile instead of SetFileAttributes. (fhandler_base::utimes_fs): Change lastaccess and lastwrite to LARGE_INTEGER. Drop 9x directory case. Use NtSetInformationFile instead of SetFileAttributes. Drop temporarily changing R/O attribute since NtSetInformationFile(FileBasicInformation) also works on R/O files. * ntdll.h (STATUS_NOT_SUPPORTED): Define.
This commit is contained in:
parent
ee2984326b
commit
4368984a7b
@ -1,3 +1,17 @@
|
|||||||
|
2007-07-29 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler_disk_file.cc: Use get_handle throughout.
|
||||||
|
(fhandler_disk_file::fchmod): Always try to open file with required
|
||||||
|
access rights. Use NtSetInformationFile instead of SetFileAttributes.
|
||||||
|
(fhandler_disk_file::facl): Use NtSetInformationFile instead of
|
||||||
|
SetFileAttributes.
|
||||||
|
(fhandler_base::utimes_fs): Change lastaccess and lastwrite to
|
||||||
|
LARGE_INTEGER. Drop 9x directory case. Use NtSetInformationFile
|
||||||
|
instead of SetFileAttributes. Drop temporarily changing R/O attribute
|
||||||
|
since NtSetInformationFile(FileBasicInformation) also works on R/O
|
||||||
|
files.
|
||||||
|
* ntdll.h (STATUS_NOT_SUPPORTED): Define.
|
||||||
|
|
||||||
2007-07-29 Christopher Faylor <me+cygwin@cgf.cx>
|
2007-07-29 Christopher Faylor <me+cygwin@cgf.cx>
|
||||||
|
|
||||||
* cygtls.h (_cygtls::inside_kernel): Move function declaration into
|
* cygtls.h (_cygtls::inside_kernel): Move function declaration into
|
||||||
|
@ -418,7 +418,7 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
|||||||
int oret;
|
int oret;
|
||||||
int open_flags = O_RDONLY | O_BINARY;
|
int open_flags = O_RDONLY | O_BINARY;
|
||||||
|
|
||||||
if (get_io_handle ())
|
if (get_handle ())
|
||||||
{
|
{
|
||||||
if (!nohandle () && !is_fs_special ())
|
if (!nohandle () && !is_fs_special ())
|
||||||
res = fstat_by_handle (buf);
|
res = fstat_by_handle (buf);
|
||||||
@ -501,8 +501,8 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
buf->st_blocks = (nAllocSize + S_BLKSIZE - 1) / S_BLKSIZE;
|
buf->st_blocks = (nAllocSize + S_BLKSIZE - 1) / S_BLKSIZE;
|
||||||
else if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_COMPRESSED
|
else if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_COMPRESSED
|
||||||
| FILE_ATTRIBUTE_SPARSE_FILE)
|
| FILE_ATTRIBUTE_SPARSE_FILE)
|
||||||
&& get_io_handle () && !is_fs_special ()
|
&& get_handle () && !is_fs_special ()
|
||||||
&& !NtQueryInformationFile (get_io_handle (), &st, (PVOID) &fci,
|
&& !NtQueryInformationFile (get_handle (), &st, (PVOID) &fci,
|
||||||
sizeof fci, FileCompressionInformation))
|
sizeof fci, FileCompressionInformation))
|
||||||
/* Otherwise we request the actual amount of bytes allocated for
|
/* Otherwise we request the actual amount of bytes allocated for
|
||||||
compressed and sparsed files. */
|
compressed and sparsed files. */
|
||||||
@ -521,14 +521,14 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
buf->st_size = pc.get_symlink_length ();
|
buf->st_size = pc.get_symlink_length ();
|
||||||
/* symlinks are everything for everyone! */
|
/* symlinks are everything for everyone! */
|
||||||
buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
|
buf->st_mode = S_IFLNK | S_IRWXU | S_IRWXG | S_IRWXO;
|
||||||
get_file_attribute (get_io_handle (), pc, NULL,
|
get_file_attribute (get_handle (), pc, NULL,
|
||||||
&buf->st_uid, &buf->st_gid);
|
&buf->st_uid, &buf->st_gid);
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
else if (pc.issocket ())
|
else if (pc.issocket ())
|
||||||
buf->st_mode = S_IFSOCK;
|
buf->st_mode = S_IFSOCK;
|
||||||
|
|
||||||
if (!get_file_attribute (is_fs_special () ? NULL: get_io_handle (), pc,
|
if (!get_file_attribute (is_fs_special () ? NULL: get_handle (), pc,
|
||||||
&buf->st_mode, &buf->st_uid, &buf->st_gid))
|
&buf->st_mode, &buf->st_uid, &buf->st_gid))
|
||||||
{
|
{
|
||||||
/* If read-only attribute is set, modify ntsec return value */
|
/* If read-only attribute is set, modify ntsec return value */
|
||||||
@ -569,6 +569,12 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
buf->st_mode |= S_IFREG;
|
buf->st_mode |= S_IFREG;
|
||||||
|
#if 0
|
||||||
|
/* FIXME: Is this code really necessary? There are already
|
||||||
|
two places in path_conv which look for executability.
|
||||||
|
Also, by using the fhandler's io HANDLE, a stat call might
|
||||||
|
change the file position for a short period of time in
|
||||||
|
a not thread-safe way. */
|
||||||
if (pc.exec_state () == dont_know_if_executable)
|
if (pc.exec_state () == dont_know_if_executable)
|
||||||
{
|
{
|
||||||
DWORD cur, done;
|
DWORD cur, done;
|
||||||
@ -593,8 +599,8 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
|||||||
SetFilePointer (get_handle (), cur, &curhigh, FILE_BEGIN);
|
SetFilePointer (get_handle (), cur, &curhigh, FILE_BEGIN);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pc.exec_state () == is_executable)
|
if (pc.exec_state () == is_executable)
|
||||||
buf->st_mode |= STD_XBITS;
|
buf->st_mode |= STD_XBITS;
|
||||||
|
|
||||||
@ -735,15 +741,18 @@ fhandler_disk_file::fchmod (mode_t mode)
|
|||||||
if (pc.is_fs_special ())
|
if (pc.is_fs_special ())
|
||||||
return chmod_device (pc, mode);
|
return chmod_device (pc, mode);
|
||||||
|
|
||||||
if (!get_io_handle ())
|
if (!get_handle ())
|
||||||
{
|
{
|
||||||
query_open (query_write_control);
|
query_open (query_write_control);
|
||||||
if (!(oret = open (O_BINARY, 0)))
|
if (!(oret = open (O_BINARY, 0)))
|
||||||
{
|
{
|
||||||
/* If the file couldn't be opened, that's really only a problem if
|
/* Need WRITE_DAC|WRITE_OWNER to write ACLs. */
|
||||||
ACLs or EAs should get written. */
|
|
||||||
if (allow_ntsec && pc.has_acls ())
|
if (allow_ntsec && pc.has_acls ())
|
||||||
return -1;
|
return -1;
|
||||||
|
/* Otherwise FILE_WRITE_ATTRIBUTES is sufficient. */
|
||||||
|
query_open (query_write_attributes);
|
||||||
|
if (!(oret = open (O_BINARY, 0)))
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -751,7 +760,7 @@ fhandler_disk_file::fchmod (mode_t mode)
|
|||||||
{
|
{
|
||||||
if (pc.isdir ())
|
if (pc.isdir ())
|
||||||
mode |= S_IFDIR;
|
mode |= S_IFDIR;
|
||||||
if (!set_file_attribute (get_io_handle (), pc,
|
if (!set_file_attribute (get_handle (), pc,
|
||||||
ILLEGAL_UID, ILLEGAL_GID, mode)
|
ILLEGAL_UID, ILLEGAL_GID, mode)
|
||||||
&& allow_ntsec)
|
&& allow_ntsec)
|
||||||
res = 0;
|
res = 0;
|
||||||
@ -763,8 +772,15 @@ fhandler_disk_file::fchmod (mode_t mode)
|
|||||||
else
|
else
|
||||||
pc |= (DWORD) FILE_ATTRIBUTE_READONLY;
|
pc |= (DWORD) FILE_ATTRIBUTE_READONLY;
|
||||||
|
|
||||||
if (!SetFileAttributes (pc, pc))
|
IO_STATUS_BLOCK io;
|
||||||
__seterrno ();
|
FILE_BASIC_INFORMATION fbi;
|
||||||
|
fbi.CreationTime.QuadPart = fbi.LastAccessTime.QuadPart
|
||||||
|
= fbi.LastWriteTime.QuadPart = fbi.ChangeTime.QuadPart = 0LL;
|
||||||
|
fbi.FileAttributes = pc.file_attributes ();
|
||||||
|
NTSTATUS status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,
|
||||||
|
FileBasicInformation);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
|
__seterrno_from_nt_status (status);
|
||||||
else if (!allow_ntsec || !pc.has_acls ())
|
else if (!allow_ntsec || !pc.has_acls ())
|
||||||
/* Correct NTFS security attributes have higher priority */
|
/* Correct NTFS security attributes have higher priority */
|
||||||
res = 0;
|
res = 0;
|
||||||
@ -787,7 +803,7 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!get_io_handle ())
|
if (!get_handle ())
|
||||||
{
|
{
|
||||||
query_open (query_write_control);
|
query_open (query_write_control);
|
||||||
if (!(oret = fhandler_disk_file::open (O_BINARY, 0)))
|
if (!(oret = fhandler_disk_file::open (O_BINARY, 0)))
|
||||||
@ -797,7 +813,7 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
mode_t attrib = 0;
|
mode_t attrib = 0;
|
||||||
if (pc.isdir ())
|
if (pc.isdir ())
|
||||||
attrib |= S_IFDIR;
|
attrib |= S_IFDIR;
|
||||||
int res = get_file_attribute (get_io_handle (), pc, &attrib, NULL, NULL);
|
int res = get_file_attribute (get_handle (), pc, &attrib, NULL, NULL);
|
||||||
if (!res)
|
if (!res)
|
||||||
{
|
{
|
||||||
/* Typical Windows default ACLs can contain permissions for one
|
/* Typical Windows default ACLs can contain permissions for one
|
||||||
@ -809,7 +825,7 @@ fhandler_disk_file::fchown (__uid32_t uid, __gid32_t gid)
|
|||||||
world to read the symlink and only the new owner to change it. */
|
world to read the symlink and only the new owner to change it. */
|
||||||
if (pc.issymlink ())
|
if (pc.issymlink ())
|
||||||
attrib = S_IFLNK | STD_RBITS | STD_WBITS;
|
attrib = S_IFLNK | STD_RBITS | STD_WBITS;
|
||||||
res = set_file_attribute (get_io_handle (), pc, uid, gid, attrib);
|
res = set_file_attribute (get_handle (), pc, uid, gid, attrib);
|
||||||
}
|
}
|
||||||
if (oret)
|
if (oret)
|
||||||
close ();
|
close ();
|
||||||
@ -832,7 +848,7 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
|||||||
case SETACL:
|
case SETACL:
|
||||||
/* Open for writing required to be able to set ctime
|
/* Open for writing required to be able to set ctime
|
||||||
(even though setting the ACL is just pretended). */
|
(even though setting the ACL is just pretended). */
|
||||||
if (!get_io_handle ())
|
if (!get_handle ())
|
||||||
oret = open (O_WRONLY | O_BINARY, 0);
|
oret = open (O_WRONLY | O_BINARY, 0);
|
||||||
res = 0;
|
res = 0;
|
||||||
break;
|
break;
|
||||||
@ -843,7 +859,7 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
|||||||
set_errno (ENOSPC);
|
set_errno (ENOSPC);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!get_io_handle ())
|
if (!get_handle ())
|
||||||
{
|
{
|
||||||
query_open (query_read_attributes);
|
query_open (query_read_attributes);
|
||||||
oret = open (O_BINARY, 0);
|
oret = open (O_BINARY, 0);
|
||||||
@ -877,7 +893,7 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!get_io_handle ())
|
if (!get_handle ())
|
||||||
{
|
{
|
||||||
query_open (cmd == SETACL ? query_write_control : query_read_attributes);
|
query_open (cmd == SETACL ? query_write_control : query_read_attributes);
|
||||||
if (!(oret = open (O_BINARY, 0)))
|
if (!(oret = open (O_BINARY, 0)))
|
||||||
@ -889,19 +905,30 @@ fhandler_disk_file::facl (int cmd, int nentries, __aclent32_t *aclbufp)
|
|||||||
if (!aclsort32 (nentries, 0, aclbufp))
|
if (!aclsort32 (nentries, 0, aclbufp))
|
||||||
{
|
{
|
||||||
bool rw = false;
|
bool rw = false;
|
||||||
res = setacl (get_io_handle (), pc, nentries, aclbufp, rw);
|
res = setacl (get_handle (), pc, nentries, aclbufp, rw);
|
||||||
if (rw)
|
if (rw)
|
||||||
SetFileAttributes (pc, (DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
|
{
|
||||||
|
IO_STATUS_BLOCK io;
|
||||||
|
FILE_BASIC_INFORMATION fbi;
|
||||||
|
fbi.CreationTime.QuadPart
|
||||||
|
= fbi.LastAccessTime.QuadPart
|
||||||
|
= fbi.LastWriteTime.QuadPart
|
||||||
|
= fbi.ChangeTime.QuadPart = 0LL;
|
||||||
|
fbi.FileAttributes = pc.file_attributes ()
|
||||||
|
& ~FILE_ATTRIBUTE_READONLY;
|
||||||
|
NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,
|
||||||
|
FileBasicInformation);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case GETACL:
|
case GETACL:
|
||||||
if (!aclbufp)
|
if (!aclbufp)
|
||||||
set_errno(EFAULT);
|
set_errno(EFAULT);
|
||||||
else
|
else
|
||||||
res = getacl (get_io_handle (), pc, nentries, aclbufp);
|
res = getacl (get_handle (), pc, nentries, aclbufp);
|
||||||
break;
|
break;
|
||||||
case GETACLCNT:
|
case GETACLCNT:
|
||||||
res = getacl (get_io_handle (), pc, 0, NULL);
|
res = getacl (get_handle (), pc, 0, NULL);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
@ -1119,13 +1146,11 @@ fhandler_disk_file::utimes (const struct timeval *tvp)
|
|||||||
int
|
int
|
||||||
fhandler_base::utimes_fs (const struct timeval *tvp)
|
fhandler_base::utimes_fs (const struct timeval *tvp)
|
||||||
{
|
{
|
||||||
FILETIME lastaccess, lastwrite;
|
LARGE_INTEGER lastaccess, lastwrite;
|
||||||
struct timeval tmp[2];
|
struct timeval tmp[2];
|
||||||
bool closeit;
|
bool closeit = false;
|
||||||
|
|
||||||
if (get_handle ())
|
if (!get_handle ())
|
||||||
closeit = false;
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
query_open (query_write_attributes);
|
query_open (query_write_attributes);
|
||||||
if (!open_fs (O_BINARY, 0))
|
if (!open_fs (O_BINARY, 0))
|
||||||
@ -1144,34 +1169,34 @@ fhandler_base::utimes_fs (const struct timeval *tvp)
|
|||||||
closeit = true;
|
closeit = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nohandle ()) /* Directory query_open on 9x. */
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
gettimeofday (&tmp[0], 0);
|
gettimeofday (&tmp[0], 0);
|
||||||
if (!tvp)
|
if (!tvp)
|
||||||
{
|
{
|
||||||
tmp[1] = tmp[0];
|
tmp[1] = tmp[0];
|
||||||
tvp = tmp;
|
tvp = tmp;
|
||||||
}
|
}
|
||||||
timeval_to_filetime (&tvp[0], &lastaccess);
|
timeval_to_filetime (&tvp[0], (FILETIME *) &lastaccess);
|
||||||
timeval_to_filetime (&tvp[1], &lastwrite);
|
timeval_to_filetime (&tvp[1], (FILETIME *) &lastwrite);
|
||||||
debug_printf ("incoming lastaccess %08x %08x", tvp[0].tv_sec, tvp[0].tv_usec);
|
debug_printf ("incoming lastaccess %08x %08x", tvp[0].tv_sec, tvp[0].tv_usec);
|
||||||
|
|
||||||
if (is_fs_special ())
|
IO_STATUS_BLOCK io;
|
||||||
SetFileAttributes (pc, (DWORD) pc & ~FILE_ATTRIBUTE_READONLY);
|
FILE_BASIC_INFORMATION fbi;
|
||||||
BOOL res = SetFileTime (get_handle (), NULL, &lastaccess, &lastwrite);
|
fbi.CreationTime.QuadPart = 0LL;
|
||||||
DWORD errcode = GetLastError ();
|
fbi.LastAccessTime= lastaccess;
|
||||||
if (is_fs_special ())
|
fbi.LastWriteTime = lastwrite;
|
||||||
SetFileAttributes (pc, pc);
|
fbi.ChangeTime.QuadPart = 0LL;
|
||||||
|
fbi.FileAttributes = 0;
|
||||||
|
NTSTATUS status = NtSetInformationFile (get_handle (), &io, &fbi, sizeof fbi,
|
||||||
|
FileBasicInformation);
|
||||||
/* Opening a directory on a 9x share from a NT machine works(!), but
|
/* Opening a directory on a 9x share from a NT machine works(!), but
|
||||||
then the SetFileTimes fails with ERROR_NOT_SUPPORTED. Oh well... */
|
then NtSetInformationFile fails with STATUS_NOT_SUPPORTED. Oh well... */
|
||||||
if (!res && errcode != ERROR_NOT_SUPPORTED)
|
if (!NT_SUCCESS (status) && status != STATUS_NOT_SUPPORTED)
|
||||||
{
|
{
|
||||||
close ();
|
if (closeit)
|
||||||
__seterrno_from_win_error (errcode);
|
close ();
|
||||||
|
__seterrno_from_nt_status (status);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (closeit)
|
if (closeit)
|
||||||
close ();
|
close ();
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -20,6 +20,7 @@
|
|||||||
#define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xc0000043)
|
#define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xc0000043)
|
||||||
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xc0000056)
|
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xc0000056)
|
||||||
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
|
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
|
||||||
|
#define STATUS_NOT_SUPPORTED ((NTSTATUS) 0xc00000bb)
|
||||||
#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106)
|
#define STATUS_NOT_ALL_ASSIGNED ((NTSTATUS) 0x00000106)
|
||||||
#define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148)
|
#define STATUS_INVALID_LEVEL ((NTSTATUS) 0xc0000148)
|
||||||
#define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006)
|
#define STATUS_NO_MORE_FILES ((NTSTATUS) 0x80000006)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user