* fhandler.h (fhandler_base::fstat_helper): Declare with additional
file attributes argument. * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Use file attributes evaluated from NtQueryFileInformation or FileInformationByHandle in call to fstat_helper. Set pc.fileattr from just evaluated file attributes here. (fhandler_base::fstat_by_name): Use file attributes evaluated from FindFileFirst or default attribute in call to fstat_helper. Set pc.fileattr from just evaluated file attributes here. (fhandler_base::fstat_helper): Use file attributes given as argument, not file attributes stored in this fhandler, since this information is potentially wrong. Add comment to explain this. * path.h (has_attribute): New global inline function. (path_conv::set_attributes): New method to change fileattr.
This commit is contained in:
parent
f3a61fc4aa
commit
f3810c7281
|
@ -1,3 +1,20 @@
|
||||||
|
2005-09-22 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* fhandler.h (fhandler_base::fstat_helper): Declare with additional
|
||||||
|
file attributes argument.
|
||||||
|
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Use
|
||||||
|
file attributes evaluated from NtQueryFileInformation or
|
||||||
|
FileInformationByHandle in call to fstat_helper.
|
||||||
|
Set pc.fileattr from just evaluated file attributes here.
|
||||||
|
(fhandler_base::fstat_by_name): Use file attributes evaluated from
|
||||||
|
FindFileFirst or default attribute in call to fstat_helper.
|
||||||
|
Set pc.fileattr from just evaluated file attributes here.
|
||||||
|
(fhandler_base::fstat_helper): Use file attributes given as argument,
|
||||||
|
not file attributes stored in this fhandler, since this information
|
||||||
|
is potentially wrong. Add comment to explain this.
|
||||||
|
* path.h (has_attribute): New global inline function.
|
||||||
|
(path_conv::set_attributes): New method to change fileattr.
|
||||||
|
|
||||||
2005-09-21 Christopher Faylor <cgf@timesys.com>
|
2005-09-21 Christopher Faylor <cgf@timesys.com>
|
||||||
|
|
||||||
* cygthread.cc (cygthread::operator new): Just use getenv() to look for
|
* cygthread.cc (cygthread::operator new): Just use getenv() to look for
|
||||||
|
|
|
@ -272,7 +272,8 @@ class fhandler_base
|
||||||
LONGLONG nAllocSize,
|
LONGLONG nAllocSize,
|
||||||
DWORD nFileIndexHigh,
|
DWORD nFileIndexHigh,
|
||||||
DWORD nFileIndexLow,
|
DWORD nFileIndexLow,
|
||||||
DWORD nNumberOfLinks)
|
DWORD nNumberOfLinks,
|
||||||
|
DWORD dwFileAttributes)
|
||||||
__attribute__ ((regparm (3)));
|
__attribute__ ((regparm (3)));
|
||||||
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_handle (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
int __stdcall fstat_by_name (struct __stat64 *buf) __attribute__ ((regparm (2)));
|
||||||
|
|
|
@ -124,22 +124,26 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
||||||
status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size,
|
status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size,
|
||||||
FileAllInformation);
|
FileAllInformation);
|
||||||
if (NT_SUCCESS (status))
|
if (NT_SUCCESS (status))
|
||||||
/* If the change time is 0, it's a file system which doesn't
|
{
|
||||||
support a change timestamp. In that case use the LastWriteTime
|
/* If the change time is 0, it's a file system which doesn't
|
||||||
entry, as in other calls to fstat_helper. */
|
support a change timestamp. In that case use the LastWriteTime
|
||||||
return fstat_helper (buf,
|
entry, as in other calls to fstat_helper. */
|
||||||
pfai->BasicInformation.ChangeTime.QuadPart ?
|
pc.set_attributes (pfai->BasicInformation.FileAttributes);
|
||||||
*(FILETIME *) &pfai->BasicInformation.ChangeTime :
|
return fstat_helper (buf,
|
||||||
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
|
pfai->BasicInformation.ChangeTime.QuadPart ?
|
||||||
*(FILETIME *) &pfai->BasicInformation.LastAccessTime,
|
*(FILETIME *) &pfai->BasicInformation.ChangeTime :
|
||||||
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
|
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
|
||||||
pfvi->VolumeSerialNumber,
|
*(FILETIME *) &pfai->BasicInformation.LastAccessTime,
|
||||||
pfai->StandardInformation.EndOfFile.HighPart,
|
*(FILETIME *) &pfai->BasicInformation.LastWriteTime,
|
||||||
pfai->StandardInformation.EndOfFile.LowPart,
|
pfvi->VolumeSerialNumber,
|
||||||
pfai->StandardInformation.AllocationSize.QuadPart,
|
pfai->StandardInformation.EndOfFile.HighPart,
|
||||||
pfai->InternalInformation.IndexNumber.HighPart,
|
pfai->StandardInformation.EndOfFile.LowPart,
|
||||||
pfai->InternalInformation.IndexNumber.LowPart,
|
pfai->StandardInformation.AllocationSize.QuadPart,
|
||||||
pfai->StandardInformation.NumberOfLinks);
|
pfai->InternalInformation.IndexNumber.HighPart,
|
||||||
|
pfai->InternalInformation.IndexNumber.LowPart,
|
||||||
|
pfai->StandardInformation.NumberOfLinks,
|
||||||
|
pfai->BasicInformation.FileAttributes);
|
||||||
|
}
|
||||||
|
|
||||||
debug_printf ("%u = NtQueryInformationFile)",
|
debug_printf ("%u = NtQueryInformationFile)",
|
||||||
RtlNtStatusToDosError (status));
|
RtlNtStatusToDosError (status));
|
||||||
|
@ -160,6 +164,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
||||||
local.nFileSizeLow = 0;
|
local.nFileSizeLow = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pc.set_attributes (local.dwFileAttributes);
|
||||||
return fstat_helper (buf,
|
return fstat_helper (buf,
|
||||||
local.ftLastWriteTime, /* see fstat_helper comment */
|
local.ftLastWriteTime, /* see fstat_helper comment */
|
||||||
local.ftLastAccessTime,
|
local.ftLastAccessTime,
|
||||||
|
@ -170,7 +175,8 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
|
||||||
-1LL,
|
-1LL,
|
||||||
local.nFileIndexHigh,
|
local.nFileIndexHigh,
|
||||||
local.nFileIndexLow,
|
local.nFileIndexLow,
|
||||||
local.nNumberOfLinks);
|
local.nNumberOfLinks,
|
||||||
|
local.dwFileAttributes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int __stdcall
|
int __stdcall
|
||||||
|
@ -189,6 +195,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
||||||
else if ((handle = FindFirstFile (pc, &local)) != INVALID_HANDLE_VALUE)
|
else if ((handle = FindFirstFile (pc, &local)) != INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
FindClose (handle);
|
FindClose (handle);
|
||||||
|
pc.set_attributes (local.dwFileAttributes);
|
||||||
res = fstat_helper (buf,
|
res = fstat_helper (buf,
|
||||||
local.ftLastWriteTime, /* see fstat_helper comment */
|
local.ftLastWriteTime, /* see fstat_helper comment */
|
||||||
local.ftLastAccessTime,
|
local.ftLastAccessTime,
|
||||||
|
@ -199,12 +206,14 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
|
||||||
-1LL,
|
-1LL,
|
||||||
0,
|
0,
|
||||||
0,
|
0,
|
||||||
1);
|
1,
|
||||||
|
local.dwFileAttributes);
|
||||||
}
|
}
|
||||||
else if (pc.isdir ())
|
else if (pc.isdir ())
|
||||||
{
|
{
|
||||||
FILETIME ft = {};
|
FILETIME ft = {};
|
||||||
res = fstat_helper (buf, ft, ft, ft, pc.volser (), 0, 0, -1LL, 0, 0, 1);
|
res = fstat_helper (buf, ft, ft, ft, pc.volser (), 0, 0, -1LL, 0, 0, 1,
|
||||||
|
FILE_ATTRIBUTE_DIRECTORY);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
@ -270,7 +279,11 @@ fhandler_base::fstat_fs (struct __stat64 *buf)
|
||||||
it's faked using the LastWriteTime entry from GetFileInformationByHandle
|
it's faked using the LastWriteTime entry from GetFileInformationByHandle
|
||||||
or FindFirstFile. We're deliberatly not using the creation time anymore
|
or FindFirstFile. We're deliberatly not using the creation time anymore
|
||||||
to simplify interaction with native Windows applications which choke on
|
to simplify interaction with native Windows applications which choke on
|
||||||
creation times >= access or write times. */
|
creation times >= access or write times.
|
||||||
|
|
||||||
|
Note that the dwFileAttributes member of the file information evaluated
|
||||||
|
in the calling function is used here, not the pc.fileattr member, since
|
||||||
|
the latter might be old and not reflect the actual state of the file. */
|
||||||
int __stdcall
|
int __stdcall
|
||||||
fhandler_base::fstat_helper (struct __stat64 *buf,
|
fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
FILETIME ftChangeTime,
|
FILETIME ftChangeTime,
|
||||||
|
@ -282,7 +295,8 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
LONGLONG nAllocSize,
|
LONGLONG nAllocSize,
|
||||||
DWORD nFileIndexHigh,
|
DWORD nFileIndexHigh,
|
||||||
DWORD nFileIndexLow,
|
DWORD nFileIndexLow,
|
||||||
DWORD nNumberOfLinks)
|
DWORD nNumberOfLinks,
|
||||||
|
DWORD dwFileAttributes)
|
||||||
{
|
{
|
||||||
IO_STATUS_BLOCK st;
|
IO_STATUS_BLOCK st;
|
||||||
FILE_COMPRESSION_INFORMATION fci;
|
FILE_COMPRESSION_INFORMATION fci;
|
||||||
|
@ -328,11 +342,11 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
/* A successful NtQueryInformationFile returns the allocation size
|
/* A successful NtQueryInformationFile returns the allocation size
|
||||||
correctly for compressed and sparse files as well. */
|
correctly for compressed and sparse files as well. */
|
||||||
buf->st_blocks = (nAllocSize + S_BLKSIZE - 1) / S_BLKSIZE;
|
buf->st_blocks = (nAllocSize + S_BLKSIZE - 1) / S_BLKSIZE;
|
||||||
else if (pc.has_attribute (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_io_handle () && !is_fs_special ()
|
||||||
&& !NtQueryInformationFile (get_io_handle (), &st, (PVOID) &fci,
|
&& !NtQueryInformationFile (get_io_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. */
|
||||||
buf->st_blocks = (fci.CompressedSize.QuadPart + S_BLKSIZE - 1) / S_BLKSIZE;
|
buf->st_blocks = (fci.CompressedSize.QuadPart + S_BLKSIZE - 1) / S_BLKSIZE;
|
||||||
|
@ -357,11 +371,14 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
else if (pc.issocket ())
|
else if (pc.issocket ())
|
||||||
buf->st_mode = S_IFSOCK;
|
buf->st_mode = S_IFSOCK;
|
||||||
|
|
||||||
if (!get_file_attribute (pc.has_acls (), is_fs_special () ? NULL: get_io_handle (),
|
if (!get_file_attribute (pc.has_acls (),
|
||||||
get_win32_name (), &buf->st_mode, &buf->st_uid, &buf->st_gid))
|
is_fs_special () ? NULL: get_io_handle (),
|
||||||
|
get_win32_name (), &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 */
|
||||||
if (pc.has_attribute (FILE_ATTRIBUTE_READONLY) && !pc.issymlink ())
|
if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_READONLY)
|
||||||
|
&& !pc.issymlink ())
|
||||||
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
buf->st_mode &= ~(S_IWUSR | S_IWGRP | S_IWOTH);
|
||||||
|
|
||||||
if (buf->st_mode & S_IFMT)
|
if (buf->st_mode & S_IFMT)
|
||||||
|
@ -378,7 +395,8 @@ fhandler_base::fstat_helper (struct __stat64 *buf,
|
||||||
{
|
{
|
||||||
buf->st_mode |= STD_RBITS;
|
buf->st_mode |= STD_RBITS;
|
||||||
|
|
||||||
if (!pc.has_attribute (FILE_ATTRIBUTE_READONLY) && !pc.issymlink ())
|
if (::has_attribute (dwFileAttributes, FILE_ATTRIBUTE_READONLY)
|
||||||
|
&& !pc.issymlink ())
|
||||||
buf->st_mode |= STD_WBITS;
|
buf->st_mode |= STD_WBITS;
|
||||||
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
|
/* | S_IWGRP | S_IWOTH; we don't give write to group etc */
|
||||||
|
|
||||||
|
|
|
@ -14,6 +14,13 @@ details. */
|
||||||
#include <fcntl.h>
|
#include <fcntl.h>
|
||||||
#include <ntdef.h>
|
#include <ntdef.h>
|
||||||
|
|
||||||
|
inline bool
|
||||||
|
has_attribute (DWORD attributes, DWORD attribs_to_test)
|
||||||
|
{
|
||||||
|
return attributes != INVALID_FILE_ATTRIBUTES
|
||||||
|
&& (attributes & attribs_to_test);
|
||||||
|
}
|
||||||
|
|
||||||
enum executable_states
|
enum executable_states
|
||||||
{
|
{
|
||||||
is_executable,
|
is_executable,
|
||||||
|
@ -161,6 +168,7 @@ class path_conv
|
||||||
bool isro () const {return !!(path_flags & PATH_RO);}
|
bool isro () const {return !!(path_flags & PATH_RO);}
|
||||||
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
|
bool exists () const {return fileattr != INVALID_FILE_ATTRIBUTES;}
|
||||||
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
|
bool has_attribute (DWORD x) const {return exists () && (fileattr & x);}
|
||||||
|
void set_attributes (DWORD x) {fileattr = x;}
|
||||||
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
|
int isdir () const {return has_attribute (FILE_ATTRIBUTE_DIRECTORY);}
|
||||||
executable_states exec_state ()
|
executable_states exec_state ()
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue