Native RAM disks, e.g. as are used in WinPE environments, have other
characteristics than regular filesystems such as NTFS. For instance,
re-opening files with NtOpenFile is buggy.

This commit checks whether a volume is a RAM disk through the NT object
the drive letter link refers to. This seems to be the only reliable
method of checking whether a volume is a native RAM disk.

Signed-off-by: Les De Ridder <l...@lesderid.net>
---
 winsup/cygwin/local_includes/mount.h |  2 ++
 winsup/cygwin/local_includes/path.h  |  1 +
 winsup/cygwin/mount.cc               | 12 ++++++++++++
 3 files changed, 15 insertions(+)

diff --git a/winsup/cygwin/local_includes/mount.h 
b/winsup/cygwin/local_includes/mount.h
index 5bb84b976..e8a71a994 100644
--- a/winsup/cygwin/local_includes/mount.h
+++ b/winsup/cygwin/local_includes/mount.h
@@ -47,6 +47,7 @@ enum fs_info_type
   ncfsd,
   afs,
   prlfs,
+  ramdisk,
   /* Always last. */
   max_fs_type
 };
@@ -117,6 +118,7 @@ class fs_info
   IMPLEMENT_FS_FLAG (ncfsd)
   IMPLEMENT_FS_FLAG (afs)
   IMPLEMENT_FS_FLAG (prlfs)
+  IMPLEMENT_FS_FLAG (ramdisk)
   fs_info_type what_fs () const { return status.fs_type; }
   bool got_fs () const { return status.fs_type != none; }
 
diff --git a/winsup/cygwin/local_includes/path.h 
b/winsup/cygwin/local_includes/path.h
index 74f831e53..2e34f0e18 100644
--- a/winsup/cygwin/local_includes/path.h
+++ b/winsup/cygwin/local_includes/path.h
@@ -387,6 +387,7 @@ class path_conv
   bool fs_is_ncfsd () const {return fs.is_ncfsd ();}
   bool fs_is_afs () const {return fs.is_afs ();}
   bool fs_is_prlfs () const {return fs.is_prlfs ();}
+  bool fs_is_ramdisk () const {return fs.is_ramdisk ();}
   fs_info_type fs_type () const {return fs.what_fs ();}
   ULONG fs_serial_number () const {return fs.serial_number ();}
   inline const char *set_path (const char *p)
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index 36ab042a7..1950dadb0 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -292,6 +292,17 @@ fs_info::update (PUNICODE_STRING upath, HANDLE in_vol)
   if (!NT_SUCCESS (status))
     ffdi.DeviceType = ffdi.Characteristics = 0;
 
+  if (upath->Buffer[5] == L':' && upath->Buffer[6] == L'\\')
+   {
+     WCHAR dos[3] = {upath->Buffer[4], upath->Buffer[5], L'\0'};
+     WCHAR dev[MAX_PATH];
+     if (QueryDosDeviceW (dos, dev, MAX_PATH))
+       {
+          is_ramdisk (wcsncmp (dev, L"\\Device\\Ramdisk", 15));
+          has_buggy_reopen (is_ramdisk ());
+       }
+   }
+
   if ((ffdi.Characteristics & FILE_REMOTE_DEVICE)
       || (!ffdi.DeviceType
          && RtlEqualUnicodePathPrefix (attr.ObjectName, &ro_u_uncp, TRUE)))
@@ -1612,6 +1623,7 @@ fs_names_t fs_names[] = {
     { "ncfsd", false },
     { "afs", false },
     { "prlfs", false },
+    { "ramdisk", false },
     { NULL, false }
 };
 
-- 
2.41.0

Reply via email to