Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2007-08-01 16:55:25 +0400
committerCorinna Vinschen <corinna@vinschen.de>2007-08-01 16:55:25 +0400
commitd3dd7d36822391acdc70aed2133dbda14cdb7fed (patch)
tree3e13df736e85a898e3435b50bdc31577e119d4a6
parent67629eb258e8c487c504dac7517ce787b2f338a9 (diff)
* fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop
usage of path_conv::volser(). (fhandler_base::fstat_by_name): Ditto. * ntdll.h (STATUS_NO_MEDIA_IN_DEVICE): Define. (STATUS_OBJECT_NAME_NOT_FOUND): Define. (FILE_REMOVABLE_MEDIA, FILE_READ_ONLY_DEVICE, FILE_FLOPPY_DISKETTE) (FILE_WRITE_ONCE_MEDIA, FILE_REMOTE_DEVICE, FILE_DEVICE_IS_MOUNTED) (FILE_VIRTUAL_VOLUME, FILE_AUTOGENERATED_DEVICE_NAME) FILE_DEVICE_SECURE_OPEN): Define Device Characteristics. (struct _FILE_FS_DEVICE_INFORMATION): Define. * path.cc (MAX_FS_INFO_CNT): Remove. (fsinfo): Remove. (fsinfo_cnt): Remove. (fs_info::update): Rewrite using native NT functions. Drop fs_info cashing since it's incorrect. (path_conv::fillin): Use NtQueryInformationFile. Drop setting serial number. (path_conv::check): Accommodate new fs_info::update parameters. (fillout_mntent): Ditto. * path.h (fs_info): Drop serial, has_ea and drive_type status flags. (fs_info::update): Declare with new parameters. (path_conf::drive_type): Remove. (path_conf::fs_has_ea): Remove. (path_conf::volser): Remove.
-rw-r--r--winsup/cygwin/ChangeLog28
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc6
-rw-r--r--winsup/cygwin/ntdll.h19
-rw-r--r--winsup/cygwin/path.cc166
-rw-r--r--winsup/cygwin/path.h15
5 files changed, 135 insertions, 99 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 2d2e4bbf9..3a29be76e 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,5 +1,33 @@
2007-08-01 Corinna Vinschen <corinna@vinschen.de>
+ * fhandler_disk_file.cc (fhandler_base::fstat_by_handle): Drop
+ usage of path_conv::volser().
+ (fhandler_base::fstat_by_name): Ditto.
+ * ntdll.h (STATUS_NO_MEDIA_IN_DEVICE): Define.
+ (STATUS_OBJECT_NAME_NOT_FOUND): Define.
+ (FILE_REMOVABLE_MEDIA, FILE_READ_ONLY_DEVICE, FILE_FLOPPY_DISKETTE)
+ (FILE_WRITE_ONCE_MEDIA, FILE_REMOTE_DEVICE, FILE_DEVICE_IS_MOUNTED)
+ (FILE_VIRTUAL_VOLUME, FILE_AUTOGENERATED_DEVICE_NAME)
+ FILE_DEVICE_SECURE_OPEN): Define Device Characteristics.
+ (struct _FILE_FS_DEVICE_INFORMATION): Define.
+ * path.cc (MAX_FS_INFO_CNT): Remove.
+ (fsinfo): Remove.
+ (fsinfo_cnt): Remove.
+ (fs_info::update): Rewrite using native NT functions. Drop fs_info
+ cashing since it's incorrect.
+ (path_conv::fillin): Use NtQueryInformationFile. Drop setting serial
+ number.
+ (path_conv::check): Accommodate new fs_info::update parameters.
+ (fillout_mntent): Ditto.
+ * path.h (fs_info): Drop serial, has_ea and drive_type status
+ flags.
+ (fs_info::update): Declare with new parameters.
+ (path_conf::drive_type): Remove.
+ (path_conf::fs_has_ea): Remove.
+ (path_conf::volser): Remove.
+
+2007-08-01 Corinna Vinschen <corinna@vinschen.de>
+
* fhandler.cc (check_posix_perms): Remove.
(fhandler_base::fpathconf): Return value of pc.has_acls () instead
of calling check_posix_perms.
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 5df3c9945..b61c12f6f 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -279,7 +279,7 @@ fhandler_base::fstat_by_handle (struct __stat64 *buf)
{
debug_printf ("%u = NtQueryVolumeInformationFile)",
RtlNtStatusToDosError (status));
- pfvi->VolumeSerialNumber = pc.volser ();
+ pfvi->VolumeSerialNumber = 0;
}
status = NtQueryInformationFile (get_handle (), &io, pfai, fai_size,
FileAllInformation);
@@ -371,7 +371,7 @@ fhandler_base::fstat_by_name (struct __stat64 *buf)
{
debug_printf ("%u = NtQueryVolumeInformationFile)",
RtlNtStatusToDosError (status));
- pfvi->VolumeSerialNumber = pc.volser ();
+ pfvi->VolumeSerialNumber = 0;
}
NtClose (dir);
/* If the change time is 0, it's a file system which doesn't
@@ -403,7 +403,7 @@ too_bad:
*(FILETIME *) &ft,
*(FILETIME *) &ft,
*(FILETIME *) &ft,
- pc.volser (),
+ 0,
0ULL,
-1LL,
0ULL,
diff --git a/winsup/cygwin/ntdll.h b/winsup/cygwin/ntdll.h
index 25d9b080e..8936dd44c 100644
--- a/winsup/cygwin/ntdll.h
+++ b/winsup/cygwin/ntdll.h
@@ -16,7 +16,9 @@
#define STATUS_INFO_LENGTH_MISMATCH ((NTSTATUS) 0xc0000004)
#define STATUS_INVALID_PARAMETER ((NTSTATUS) 0xc000000d)
#define STATUS_INVALID_DEVICE_REQUEST ((NTSTATUS) 0xc0000010)
+#define STATUS_NO_MEDIA_IN_DEVICE ((NTSTATUS) 0xc0000013)
#define STATUS_BUFFER_TOO_SMALL ((NTSTATUS) 0xc0000023)
+#define STATUS_OBJECT_NAME_NOT_FOUND ((NTSTATUS) 0xc0000034)
#define STATUS_SHARING_VIOLATION ((NTSTATUS) 0xc0000043)
#define STATUS_DELETE_PENDING ((NTSTATUS) 0xc0000056)
#define STATUS_WORKING_SET_QUOTA ((NTSTATUS) 0xc00000a1)
@@ -38,6 +40,17 @@
#define WSLE_PAGE_SHARE_COUNT_MASK 0x0E0
#define WSLE_PAGE_SHAREABLE 0x100
+/* Device Characteristics. */
+#define FILE_REMOVABLE_MEDIA 0x00000001
+#define FILE_READ_ONLY_DEVICE 0x00000002
+#define FILE_FLOPPY_DISKETTE 0x00000004
+#define FILE_WRITE_ONCE_MEDIA 0x00000008
+#define FILE_REMOTE_DEVICE 0x00000010
+#define FILE_DEVICE_IS_MOUNTED 0x00000020
+#define FILE_VIRTUAL_VOLUME 0x00000040
+#define FILE_AUTOGENERATED_DEVICE_NAME 0x00000080
+#define FILE_DEVICE_SECURE_OPEN 0x00000100
+
typedef enum _FILE_INFORMATION_CLASS
{
FileDirectoryInformation = 1,
@@ -633,6 +646,12 @@ typedef struct _FILE_COMPRESSION_INFORMATION
UCHAR ClusterSizeShift;
} FILE_COMPRESSION_INFORMATION, *PFILE_COMPRESSION_INFORMATION;
+typedef struct _FILE_FS_DEVICE_INFORMATION
+{
+ ULONG DeviceType;
+ ULONG Characteristics;
+} FILE_FS_DEVICE_INFORMATION, *PFILE_FS_DEVICE_INFORMATION;
+
typedef struct _FILE_FS_ATTRIBUTE_INFORMATION
{
ULONG FileSystemAttributes;
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index fe4f1d9e0..380029cf0 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -377,61 +377,74 @@ mkrelpath (char *path)
strcpy (path, ".");
}
-#define MAX_FS_INFO_CNT 25
-fs_info fsinfo[MAX_FS_INFO_CNT];
-LONG fsinfo_cnt;
-
bool
-fs_info::update (const char *win32_path)
+fs_info::update (PUNICODE_STRING upath, bool exists)
{
- char fsname [CYG_MAX_PATH];
- char root_dir [CYG_MAX_PATH];
- bool ret;
-
- if (!::rootdir (win32_path, root_dir))
+ NTSTATUS status = STATUS_OBJECT_NAME_NOT_FOUND;
+ HANDLE vol;
+ OBJECT_ATTRIBUTES attr;
+ IO_STATUS_BLOCK io;
+ bool no_media = false;
+ FILE_FS_DEVICE_INFORMATION ffdi;
+ PFILE_FS_ATTRIBUTE_INFORMATION pffai;
+ UNICODE_STRING fsname, testname;
+
+ InitializeObjectAttributes (&attr, upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
+ if (exists)
+ status = NtOpenFile (&vol, READ_CONTROL, &attr, &io, FILE_SHARE_VALID_FLAGS,
+ FILE_OPEN_FOR_BACKUP_INTENT);
+ while (!NT_SUCCESS (status) && attr.ObjectName->Length > 6 * sizeof (WCHAR))
+ {
+ UNICODE_STRING dir;
+ RtlSplitUnicodePath (attr.ObjectName, &dir, NULL);
+ dir.Length -= sizeof (WCHAR);
+ attr.ObjectName = &dir;
+ if (status == STATUS_NO_MEDIA_IN_DEVICE)
+ {
+ no_media = true;
+ dir.Length = 6 * sizeof (WCHAR);
+ }
+ status = NtOpenFile (&vol, READ_CONTROL, &attr, &io,
+ FILE_SHARE_VALID_FLAGS, FILE_OPEN_FOR_BACKUP_INTENT);
+ }
+ if (!NT_SUCCESS (status))
{
- debug_printf ("Cannot get root component of path %s", win32_path);
+ debug_printf ("Cannot access path %S, status %08lx", attr.ObjectName,
+ status);
clear ();
+ NtClose (vol);
return false;
}
+ status = NtQueryVolumeInformationFile (vol, &io, &ffdi, sizeof ffdi,
+ FileFsDeviceInformation);
+ if (!NT_SUCCESS (status))
+ ffdi.DeviceType = ffdi.Characteristics = 0;
- __ino64_t tmp_name_hash = hash_path_name (1, root_dir);
- if (tmp_name_hash == name_hash)
- return true;
- int idx = 0;
- LONG cur_fsinfo_cnt = fsinfo_cnt;
- while (idx < cur_fsinfo_cnt && fsinfo[idx].name_hash)
- {
- if (tmp_name_hash == fsinfo[idx].name_hash)
- {
- *this = fsinfo[idx];
- return true;
- }
- ++idx;
- }
- name_hash = tmp_name_hash;
- root_len = strlen (root_dir);
-
- drive_type (GetDriveType (root_dir));
- if (drive_type () == DRIVE_REMOTE
- || (drive_type () == DRIVE_UNKNOWN
- && (root_dir[0] == '\\' && root_dir[1] == '\\')))
+ if (ffdi.Characteristics & FILE_REMOTE_DEVICE
+ || (!ffdi.DeviceType
+ && RtlEqualUnicodePathPrefix (attr.ObjectName, L"\\??\\UNC\\", TRUE)))
is_remote_drive (true);
else
is_remote_drive (false);
- ret = GetVolumeInformation (root_dir, NULL, 0, &status.serial, NULL,
- &status.flags, fsname, sizeof (fsname));
-
- if (!ret && !is_remote_drive ())
+ if (!no_media)
+ {
+ const ULONG size = sizeof (FILE_FS_ATTRIBUTE_INFORMATION)
+ + NAME_MAX * sizeof (WCHAR);
+ pffai = (PFILE_FS_ATTRIBUTE_INFORMATION) alloca (size);
+ status = NtQueryVolumeInformationFile (vol, &io, pffai, size,
+ FileFsAttributeInformation);
+ }
+ if (no_media || !NT_SUCCESS (status))
{
- debug_printf ("Cannot get volume information (%s), %E", root_dir);
+ debug_printf ("Cannot get volume attributes (%S), %08lx",
+ attr.ObjectName, status);
has_buggy_open (false);
- has_ea (false);
- flags () = serial () = 0;
+ flags () = 0;
+ NtClose (vol);
return false;
}
-
+ flags () = pffai->FileSystemAttributes;
/* Should be reevaluated for each new OS. Right now this mask is valid up
to Vista. The important point here is to test only flags indicating
capabilities and to ignore flags indicating a specific state of this
@@ -455,63 +468,46 @@ fs_info::update (const char *win32_path)
| FILE_UNICODE_ON_DISK \
| FILE_PERSISTENT_ACLS \
| FILE_NAMED_STREAMS)
- is_fat (strncasematch (fsname, "FAT", 3));
- is_samba (strcmp (fsname, "NTFS") == 0 && is_remote_drive ()
+ RtlInitCountedUnicodeString (&fsname, pffai->FileSystemName,
+ pffai->FileSystemNameLength);
+ is_fat (RtlEqualUnicodePathPrefix (&fsname, L"FAT", TRUE));
+ RtlInitUnicodeString (&testname, L"NTFS");
+ is_samba (RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && (ffdi.Characteristics & FILE_REMOTE_DEVICE)
&& (FS_IS_SAMBA || FS_IS_SAMBA_WITH_QUOTA));
- is_netapp (strcmp (fsname, "NTFS") == 0 && is_remote_drive ()
+ is_netapp (RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && (ffdi.Characteristics & FILE_REMOTE_DEVICE)
&& FS_IS_NETAPP_DATAONTAP);
- is_ntfs (strcmp (fsname, "NTFS") == 0 && !is_samba () && !is_netapp ());
- is_nfs (strcmp (fsname, "NFS") == 0);
- is_cdrom (drive_type () == DRIVE_CDROM);
+ is_ntfs (RtlEqualUnicodeString (&fsname, &testname, FALSE)
+ && !is_samba () && !is_netapp ());
+ RtlInitUnicodeString (&testname, L"NFS");
+ is_nfs (RtlEqualUnicodeString (&fsname, &testname, FALSE));
+ is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM);
- has_ea (is_ntfs ());
has_acls ((flags () & FS_PERSISTENT_ACLS)
&& (allow_smbntsec || !is_remote_drive ()));
- hasgood_inode (((flags () & FILE_PERSISTENT_ACLS)
- && drive_type () != DRIVE_UNKNOWN
- && !is_netapp ())
+ hasgood_inode (((flags () & FILE_PERSISTENT_ACLS) && !is_netapp ())
|| is_nfs ());
/* Known file systems with buggy open calls. Further explanation
in fhandler.cc (fhandler_disk_file::open). */
- has_buggy_open (!strcmp (fsname, "SUNWNFS"));
+ RtlInitUnicodeString (&testname, L"SUNWNFS");
+ has_buggy_open (RtlEqualUnicodeString (&fsname, &testname, FALSE));
- /* Only append non-removable drives to the global fsinfo storage */
- if (drive_type () != DRIVE_REMOVABLE && !is_cdrom () && idx < MAX_FS_INFO_CNT)
- {
- LONG exc_cnt;
- while ((exc_cnt = InterlockedExchange (&fsinfo_cnt, -1)) == -1)
- low_priority_sleep (0);
- if (exc_cnt < MAX_FS_INFO_CNT)
- {
- /* Check if another thread has already appended that very drive */
- while (idx < exc_cnt)
- {
- if (fsinfo[idx++].name_hash == name_hash)
- goto done;
- }
- fsinfo[exc_cnt++] = *this;
- }
- done:
- InterlockedExchange (&fsinfo_cnt, exc_cnt);
- }
+ NtClose (vol);
return true;
}
void
path_conv::fillin (HANDLE h)
{
- BY_HANDLE_FILE_INFORMATION local;
- if (!GetFileInformationByHandle (h, &local))
- {
- fileattr = INVALID_FILE_ATTRIBUTES;
- fs.serial () = 0;
- }
+ IO_STATUS_BLOCK io;
+ FILE_BASIC_INFORMATION fbi;
+
+ if (NT_SUCCESS (NtQueryInformationFile (h, &io, &fbi, sizeof fbi,
+ FileBasicInformation)))
+ fileattr = fbi.FileAttributes;
else
- {
- fileattr = local.dwFileAttributes;
- fs.serial () = local.dwVolumeSerialNumber;
- }
- fs.drive_type (DRIVE_UNKNOWN);
+ fileattr = INVALID_FILE_ATTRIBUTES;
}
void
@@ -1111,7 +1107,7 @@ out:
}
}
- if (fs.update (path))
+ if (fs.update (get_nt_native_path (), exists ()))
{
debug_printf ("this->path(%s), has_acls(%d)", path, fs.has_acls ());
if (fs.has_acls () && allow_ntsec)
@@ -2628,7 +2624,11 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
reasonable guesses for popular types. */
fs_info mntinfo;
- mntinfo.update (native_path); /* this pulls from a cache, usually. */
+ UNICODE_STRING unat;
+ size_t size = (strlen (native_path) + 1) * sizeof (WCHAR);
+ RtlInitEmptyUnicodeString (&unat, (PWSTR) alloca (size), size);
+ get_nt_native_path (native_path, unat);
+ mntinfo.update (&unat, true); /* this pulls from a cache, usually. */
if (mntinfo.is_samba())
strcpy (_my_tls.locals.mnt_type, (char *) "smbfs");
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index 390041813..41063e375 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -98,13 +98,10 @@ struct fs_info
struct status_flags
{
DWORD flags; /* Volume flags */
- DWORD serial; /* Volume serial number */
unsigned is_remote_drive : 1;
unsigned has_buggy_open : 1;
- unsigned has_ea : 1;
unsigned has_acls : 1;
unsigned hasgood_inode : 1;
- unsigned drive_type : 3;
unsigned is_fat : 1;
unsigned is_ntfs : 1;
unsigned is_samba : 1;
@@ -117,13 +114,11 @@ struct fs_info
{
name_hash = 0;
root_len = 0;
- flags () = serial () = 0;
+ flags () = 0;
is_remote_drive (false);
has_buggy_open (false);
- has_ea (false);
has_acls (false);
hasgood_inode (false);
- drive_type (false);
is_fat (false);
is_ntfs (false);
is_samba (false);
@@ -132,15 +127,12 @@ struct fs_info
is_cdrom (false);
}
inline DWORD& flags () {return status.flags;};
- inline DWORD& serial () {return status.serial;};
inline int length () const {return root_len;}
IMPLEMENT_STATUS_FLAG (bool, is_remote_drive)
IMPLEMENT_STATUS_FLAG (bool, has_buggy_open)
- IMPLEMENT_STATUS_FLAG (bool, has_ea)
IMPLEMENT_STATUS_FLAG (bool, has_acls)
IMPLEMENT_STATUS_FLAG (bool, hasgood_inode)
- IMPLEMENT_STATUS_FLAG (DWORD, drive_type)
IMPLEMENT_STATUS_FLAG (bool, is_fat)
IMPLEMENT_STATUS_FLAG (bool, is_ntfs)
IMPLEMENT_STATUS_FLAG (bool, is_samba)
@@ -148,7 +140,7 @@ struct fs_info
IMPLEMENT_STATUS_FLAG (bool, is_netapp)
IMPLEMENT_STATUS_FLAG (bool, is_cdrom)
- bool update (const char *);
+ bool update (PUNICODE_STRING, bool) __attribute__ ((regparm (3)));
};
class path_conv
@@ -284,9 +276,7 @@ class path_conv
short get_unitn () const {return dev.minor;}
DWORD file_attributes () const {return fileattr;}
void file_attributes (DWORD new_attr) {fileattr = new_attr;}
- DWORD drive_type () const {return fs.drive_type ();}
DWORD fs_flags () {return fs.flags ();}
- bool fs_has_ea () const {return fs.has_ea ();}
bool fs_is_fat () const {return fs.is_fat ();}
bool fs_is_ntfs () const {return fs.is_ntfs ();}
bool fs_is_samba () const {return fs.is_samba ();}
@@ -294,7 +284,6 @@ class path_conv
bool fs_is_netapp () const {return fs.is_netapp ();}
bool fs_is_cdrom () const {return fs.is_cdrom ();}
void set_path (const char *p) {strcpy (path, p);}
- DWORD volser () { return fs.serial (); }
void fillin (HANDLE h);
inline size_t size ()
{