diff --git a/winsup/cygwin/globals.cc b/winsup/cygwin/globals.cc index 7c84eb637..ebe8b569f 100644 --- a/winsup/cygwin/globals.cc +++ b/winsup/cygwin/globals.cc @@ -130,6 +130,7 @@ const int __collate_load_error = 0; extern UNICODE_STRING _RDATA ro_u_mtx = _ROU (L"mtx"); extern UNICODE_STRING _RDATA ro_u_csc = _ROU (L"CSC-CACHE"); extern UNICODE_STRING _RDATA ro_u_fat = _ROU (L"FAT"); + extern UNICODE_STRING _RDATA ro_u_exfat = _ROU (L"exFAT"); extern UNICODE_STRING _RDATA ro_u_mvfs = _ROU (L"MVFS"); extern UNICODE_STRING _RDATA ro_u_nfs = _ROU (L"NFS"); extern UNICODE_STRING _RDATA ro_u_ntfs = _ROU (L"NTFS"); diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc index c11ae5ace..9fd98541d 100644 --- a/winsup/cygwin/mount.cc +++ b/winsup/cygwin/mount.cc @@ -343,9 +343,11 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) #define FS_IS_WINDOWS_NTFS TEST_GVI(flags () & MINIMAL_WIN_NTFS_FLAGS, \ MINIMAL_WIN_NTFS_FLAGS) /* These are the exact flags of a real Windows FAT/FAT32 filesystem. + Newer FAT32/exFAT support FILE_SUPPORTS_ENCRYPTION as well. Anything else is a filesystem faking to be FAT. */ #define WIN_FAT_FLAGS (FILE_CASE_PRESERVED_NAMES | FILE_UNICODE_ON_DISK) -#define FS_IS_WINDOWS_FAT TEST_GVI(flags (), WIN_FAT_FLAGS) +#define FAT_IGNORE (FILE_SUPPORTS_ENCRYPTION) +#define FS_IS_WINDOWS_FAT TEST_GVI(flags () & ~FAT_IGNORE, WIN_FAT_FLAGS) if ((flags () & FILE_SUPPORTS_OBJECT_IDS) && NT_SUCCESS (NtQueryVolumeInformationFile (vol, &io, &ffoi, @@ -379,6 +381,8 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) is_cifs (!FS_IS_WINDOWS_FAT); /* Then check remote filesystems honest about their name. */ if (!got_fs () + /* Microsoft exFAT */ + && !is_exfat (RtlEqualUnicodeString (&fsname, &ro_u_exfat, FALSE)) /* Microsoft NFS needs distinct access methods for metadata. */ && !is_nfs (RtlEqualUnicodeString (&fsname, &ro_u_nfs, FALSE)) /* MVFS == Rational ClearCase remote filesystem. Has a couple of @@ -430,6 +434,7 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol) if (!got_fs () && !is_ntfs (RtlEqualUnicodeString (&fsname, &ro_u_ntfs, FALSE)) && !is_fat (RtlEqualUnicodePathPrefix (&fsname, &ro_u_fat, TRUE)) + && !is_exfat (RtlEqualUnicodeString (&fsname, &ro_u_exfat, FALSE)) && !is_refs (RtlEqualUnicodeString (&fsname, &ro_u_refs, FALSE)) && !is_csc_cache (RtlEqualUnicodeString (&fsname, &ro_u_csc, FALSE)) && is_cdrom (ffdi.DeviceType == FILE_DEVICE_CD_ROM)) @@ -1553,6 +1558,7 @@ mount_info::del_item (const char *path, unsigned flags) fs_names_t fs_names[] = { { "none", false }, { "vfat", true }, + { "exfat", true }, { "ntfs", true }, { "refs", true }, { "smbfs", false }, diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h index 0b392ca85..86e1b19c1 100644 --- a/winsup/cygwin/mount.h +++ b/winsup/cygwin/mount.h @@ -31,6 +31,7 @@ enum fs_info_type { none = 0, fat, + exfat, ntfs, refs, samba, @@ -100,6 +101,7 @@ class fs_info IMPLEMENT_STATUS_FLAG (bool, has_buggy_basic_info) IMPLEMENT_STATUS_FLAG (bool, has_dos_filenames_only) IMPLEMENT_FS_FLAG (fat) + IMPLEMENT_FS_FLAG (exfat) IMPLEMENT_FS_FLAG (ntfs) IMPLEMENT_FS_FLAG (refs) IMPLEMENT_FS_FLAG (samba) diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h index 69954d8a5..309247d5f 100644 --- a/winsup/cygwin/path.h +++ b/winsup/cygwin/path.h @@ -369,6 +369,8 @@ class path_conv DWORD fs_name_len () const {return fs.name_len ();} bool fs_got_fs () const { return fs.got_fs (); } bool fs_is_fat () const {return fs.is_fat ();} + bool fs_is_exfat () const {return fs.is_exfat ();} + bool fs_is_any_fat () const {return fs.is_fat () || fs.is_exfat ();} bool fs_is_ntfs () const {return fs.is_ntfs ();} bool fs_is_refs () const {return fs.is_refs ();} bool fs_is_samba () const {return fs.is_samba ();}