Re: [PATCH] Cygwin: include network mounts in cygdrive_getmntent.

2025-02-18 Thread Lionel Cons
Does this patch cover global mounts, i.e. SMB mounted by user
LocalSystem on a driver letter are visible to ALL users. Local users
logons can override the same drive letter via per-user net use

Example:
LocalSystem mounts H: to \\homeserver\disk4\users, this is visible to
all users in a system
User "lionel" mounts H: to \\lionelsserver\data\homedir, this is
visible to the current Logon session

Lionel

On Tue, 18 Feb 2025 at 22:25, Jeremy Drake via Cygwin-patches
 wrote:
>
> After migrating from GetLogicalDrives to Find(First|Next)VolumeW, mapped
> network drives no longer showed up in getmntent output.  To fix that,
> also iterate GetLogicalDriveStringsW when builing dos_drive_mappings,
> and merge with volume mounts (skipping any volume mounts that are just
> mounted on the root of a drive, and replacing the dos mounts in the
> mapping for a volume which is mounted on both a drive root and a
> directory).
>
> Fixes: 04a5b072940cc ("Cygwin: expose all windows volume mount points.")
> Addresses: https://cygwin.com/pipermail/cygwin/2025-February/257384.html
> Signed-off-by: Jeremy Drake 
> ---
>
> This was generated on top of the patch
> https://cygwin.com/pipermail/cygwin-patches/2025q1/013390.html but should
> be able to be applied without it.
>
>  winsup/cygwin/mount.cc | 145 -
>  1 file changed, 113 insertions(+), 32 deletions(-)
>
> diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
> index a3d9e5bd0f..68414f13af 100644
> --- a/winsup/cygwin/mount.cc
> +++ b/winsup/cygwin/mount.cc
> @@ -1995,6 +1995,40 @@ endmntent (FILE *)
>return 1;
>  }
>
> +static bool
> +resolve_dos_device (const wchar_t *dosname, wchar_t *devpath)
> +{
> +  if (QueryDosDeviceW (dosname, devpath, NT_MAX_PATH))
> +{
> +  /* The DOS drive mapping can be another symbolic link.  If so,
> +the mapping won't work since the section name is the name
> +after resolving all symlinks.  Resolve symlinks here, too. */
> +  for (int syml_cnt = 0; syml_cnt < SYMLOOP_MAX; ++syml_cnt)
> +   {
> + UNICODE_STRING upath;
> + OBJECT_ATTRIBUTES attr;
> + NTSTATUS status;
> + HANDLE h;
> +
> + RtlInitUnicodeString (&upath, devpath);
> + InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
> + NULL, NULL);
> + status = NtOpenSymbolicLinkObject (&h, SYMBOLIC_LINK_QUERY, &attr);
> + if (!NT_SUCCESS (status))
> +   break;
> + RtlInitEmptyUnicodeString (&upath, devpath, (NT_MAX_PATH - 1)
> + * sizeof (WCHAR));
> + status = NtQuerySymbolicLinkObject (h, &upath, NULL);
> + NtClose (h);
> + if (!NT_SUCCESS (status))
> +   break;
> + devpath[upath.Length / sizeof (WCHAR)] = L'\0';
> +   }
> +  return true;
> +}
> +  return false;
> +}
> +
>  dos_drive_mappings::dos_drive_mappings ()
>  : mappings(0)
>  , cur_mapping(0)
> @@ -2004,6 +2038,44 @@ dos_drive_mappings::dos_drive_mappings ()
>wchar_t vol[64]; /* Long enough for Volume GUID string */
>wchar_t *devpath = tp.w_get ();
>wchar_t *mounts = tp.w_get ();
> +  mapping **nextm = &mappings;
> +  mapping *endfirstloop = NULL;
> +  DWORD len;
> +
> +  /* Iterate over all drive letters, fetch the DOS device path */
> +  if (!(len = GetLogicalDriveStringsW (NT_MAX_PATH - 1, mounts)) ||
> +  len >= NT_MAX_PATH)
> +debug_printf ("GetLogicalDriveStringsW, %E");
> +  else {
> +for (wchar_t *mount = mounts; *mount; mount += len + 2)
> +  {
> +   len = wcslen (mount);
> +   mount[--len] = L'\0'; /* Drop trailing backslash */
> +   if (resolve_dos_device (mount, devpath))
> + {
> +   mapping *m = new mapping ();
> +   if (m)
> + {
> +   m->dos.path = wcsdup (mount);
> +   m->ntdevpath = wcsdup (devpath);
> +   if (!m->dos.path || !m->ntdevpath)
> + {
> +   free (m->dos.path);
> +   free (m->ntdevpath);
> +   delete m;
> +   continue;
> + }
> +   m->dos.len = len;
> +   m->ntlen = wcslen (m->ntdevpath);
> +   *nextm = endfirstloop = m;
> +   nextm = &m->next;
> + }
> + }
> +   else
> + debug_printf ("Unable to determine the native mapping for %ls "
> +   "(error %E)", mount);
> +  }
> +  }
>
>/* Iterate over all volumes, fetch the list of DOS paths the volume is
>   mounted to. */
> @@ -2011,43 +2083,22 @@ dos_drive_mappings::dos_drive_mappings ()
>if (sh == INVALID_HANDLE_VALUE)
>  debug_printf ("FindFirstVolumeW, %E");
>else {
> -mapping **nextm = &mappings;
>  do
>{
> -   /* Skip drives which are not mounted. */
> -   DWORD len;
> +   /* Skip volumes which

Re: [PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
On Tue, 18 Feb 2025, Jeremy Drake via Cygwin-patches wrote:

> On Tue, 18 Feb 2025, Corinna Vinschen wrote:
>
> > Alternatively... calling the constructor with a parameter
> > `bool with_floppies'?
>
> I can buy that.  I'll wait for your review of the patch I just sent before
> sending a patch on top of that to implement this.

I lied... new patches incoming.


[PATCH v2 2/2] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
This was previously done, but was lost when the function was updated to
list all Windows mount points, not just drive letters.

Fixes: 04a5b072940cc ("Cygwin: expose all windows volume mount points.")
Signed-off-by: Jeremy Drake 
---
 winsup/cygwin/local_includes/mount.h |  3 ++-
 winsup/cygwin/mount.cc   | 23 +--
 2 files changed, 19 insertions(+), 7 deletions(-)

diff --git a/winsup/cygwin/local_includes/mount.h 
b/winsup/cygwin/local_includes/mount.h
index 3049de8ba3..b719d98359 100644
--- a/winsup/cygwin/local_includes/mount.h
+++ b/winsup/cygwin/local_includes/mount.h
@@ -23,6 +23,7 @@ enum disk_type
   DT_SHARE_NFS
 };

+disk_type get_device_type (LPCWSTR);
 disk_type get_disk_type (LPCWSTR);

 /* Don't add new fs types without adding them to fs_names in mount.cc!
@@ -236,7 +237,7 @@ class dos_drive_mappings
   mapping::dosmount *cur_dos;

 public:
-  dos_drive_mappings ();
+  dos_drive_mappings (bool with_floppies = true);
   ~dos_drive_mappings ();
   wchar_t *fixup_if_match (wchar_t *path);
   const wchar_t *next_dos_mount ();
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index ab07c5abef..c921c7691c 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -1746,7 +1746,7 @@ mount_info::cygdrive_getmntent ()
   char *win32_path, *posix_path;

   if (!_my_tls.locals.drivemappings)
-_my_tls.locals.drivemappings = new dos_drive_mappings ();
+_my_tls.locals.drivemappings = new dos_drive_mappings (false);

   wide_path = _my_tls.locals.drivemappings->next_dos_mount ();
   if (wide_path)
@@ -1899,11 +1899,9 @@ cygwin_umount (const char *path, unsigned flags)
 #define is_dev(d,s)wcsncmp((d),(s),sizeof(s) - 1)

 disk_type
-get_disk_type (LPCWSTR dos)
+get_device_type (LPCWSTR dev)
 {
-  WCHAR dev[MAX_PATH], *d = dev;
-  if (!QueryDosDeviceW (dos, dev, MAX_PATH))
-return DT_NODISK;
+  const WCHAR *d = dev;
   if (is_dev (dev, L"\\Device\\"))
 {
   d += 8;
@@ -1934,6 +1932,15 @@ get_disk_type (LPCWSTR dos)
   return DT_NODISK;
 }

+disk_type
+get_disk_type (LPCWSTR dos)
+{
+  WCHAR dev[MAX_PATH];
+  if (!QueryDosDeviceW (dos, dev, MAX_PATH))
+return DT_NODISK;
+  return get_device_type (dev);
+}
+
 extern "C" FILE *
 setmntent (const char *filep, const char *)
 {
@@ -2020,7 +2027,7 @@ resolve_dos_device (const wchar_t *dosname, wchar_t 
*devpath)
   return false;
 }

-dos_drive_mappings::dos_drive_mappings ()
+dos_drive_mappings::dos_drive_mappings (bool with_floppies)
 : mappings(0)
 , cur_mapping(0)
 , cur_dos(0)
@@ -2044,6 +2051,8 @@ dos_drive_mappings::dos_drive_mappings ()
mount[--len] = L'\0'; /* Drop trailing backslash */
if (resolve_dos_device (mount, devpath))
  {
+   if (!with_floppies && get_device_type (devpath) == DT_FLOPPY)
+ continue;
mapping *m = new mapping ();
if (m)
  {
@@ -2088,6 +2097,8 @@ dos_drive_mappings::dos_drive_mappings ()
*wcsrchr (vol, L'\\') = L'\0';
if (resolve_dos_device (vol + 4, devpath))
  {
+   if (!with_floppies && get_device_type (devpath) == DT_FLOPPY)
+ continue;
mapping *m = new mapping ();
bool hadrootmount = false;
if (m)
-- 
2.48.1.windows.1



[PATCH v2 1/2] Cygwin: include network mounts in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
After migrating from GetLogicalDrives to Find(First|Next)VolumeW, mapped
network drives no longer showed up in getmntent output.  To fix that,
also iterate GetLogicalDriveStringsW when builing dos_drive_mappings,
and merge with volume mounts (skipping any volume mounts that are just
mounted on the root of a drive, and replacing the dos mounts in the
mapping for a volume which is mounted on both a drive root and a
directory).

Fixes: 04a5b072940cc ("Cygwin: expose all windows volume mount points.")
Addresses: https://cygwin.com/pipermail/cygwin/2025-February/257384.html
Signed-off-by: Jeremy Drake 
---
 winsup/cygwin/mount.cc | 145 -
 1 file changed, 113 insertions(+), 32 deletions(-)

diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index b8d8d4a974..ab07c5abef 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -1986,6 +1986,40 @@ endmntent (FILE *)
   return 1;
 }

+static bool
+resolve_dos_device (const wchar_t *dosname, wchar_t *devpath)
+{
+  if (QueryDosDeviceW (dosname, devpath, NT_MAX_PATH))
+{
+  /* The DOS drive mapping can be another symbolic link.  If so,
+the mapping won't work since the section name is the name
+after resolving all symlinks.  Resolve symlinks here, too. */
+  for (int syml_cnt = 0; syml_cnt < SYMLOOP_MAX; ++syml_cnt)
+   {
+ UNICODE_STRING upath;
+ OBJECT_ATTRIBUTES attr;
+ NTSTATUS status;
+ HANDLE h;
+
+ RtlInitUnicodeString (&upath, devpath);
+ InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
+ NULL, NULL);
+ status = NtOpenSymbolicLinkObject (&h, SYMBOLIC_LINK_QUERY, &attr);
+ if (!NT_SUCCESS (status))
+   break;
+ RtlInitEmptyUnicodeString (&upath, devpath, (NT_MAX_PATH - 1)
+ * sizeof (WCHAR));
+ status = NtQuerySymbolicLinkObject (h, &upath, NULL);
+ NtClose (h);
+ if (!NT_SUCCESS (status))
+   break;
+ devpath[upath.Length / sizeof (WCHAR)] = L'\0';
+   }
+  return true;
+}
+  return false;
+}
+
 dos_drive_mappings::dos_drive_mappings ()
 : mappings(0)
 , cur_mapping(0)
@@ -1995,6 +2029,44 @@ dos_drive_mappings::dos_drive_mappings ()
   wchar_t vol[64]; /* Long enough for Volume GUID string */
   wchar_t *devpath = tp.w_get ();
   wchar_t *mounts = tp.w_get ();
+  mapping **nextm = &mappings;
+  mapping *endfirstloop = NULL;
+  DWORD len;
+
+  /* Iterate over all drive letters, fetch the DOS device path */
+  if (!(len = GetLogicalDriveStringsW (NT_MAX_PATH - 1, mounts)) ||
+  len >= NT_MAX_PATH)
+debug_printf ("GetLogicalDriveStringsW, %E");
+  else {
+for (wchar_t *mount = mounts; *mount; mount += len + 2)
+  {
+   len = wcslen (mount);
+   mount[--len] = L'\0'; /* Drop trailing backslash */
+   if (resolve_dos_device (mount, devpath))
+ {
+   mapping *m = new mapping ();
+   if (m)
+ {
+   m->dos.path = wcsdup (mount);
+   m->ntdevpath = wcsdup (devpath);
+   if (!m->dos.path || !m->ntdevpath)
+ {
+   free (m->dos.path);
+   free (m->ntdevpath);
+   delete m;
+   continue;
+ }
+   m->dos.len = len;
+   m->ntlen = wcslen (m->ntdevpath);
+   *nextm = endfirstloop = m;
+   nextm = &m->next;
+ }
+ }
+   else
+ debug_printf ("Unable to determine the native mapping for %ls "
+   "(error %E)", mount);
+  }
+  }

   /* Iterate over all volumes, fetch the list of DOS paths the volume is
  mounted to. */
@@ -2002,43 +2074,22 @@ dos_drive_mappings::dos_drive_mappings ()
   if (sh == INVALID_HANDLE_VALUE)
 debug_printf ("FindFirstVolumeW, %E");
   else {
-mapping **nextm = &mappings;
 do
   {
-   /* Skip drives which are not mounted. */
-   DWORD len;
+   /* Skip volumes which are not mounted. */
if (!GetVolumePathNamesForVolumeNameW (vol, mounts, NT_MAX_PATH, &len)
|| mounts[0] == L'\0')
  continue;
+   /* Skip volumes which are only mounted to the root of a drive letter:
+  they were handled in the loop above */
+   if (len == 5 && mounts[1] == L':' && mounts[2] == L'\\' && !mounts[3])
+ continue;
+
*wcsrchr (vol, L'\\') = L'\0';
-   if (QueryDosDeviceW (vol + 4, devpath, NT_MAX_PATH))
+   if (resolve_dos_device (vol + 4, devpath))
  {
-   /* The DOS drive mapping can be another symbolic link.  If so,
-  the mapping won't work since the section name is the name
-  after resolving all symlinks.  Resolve symlinks here, too. */
-   for (int syml_cnt = 0; syml_cnt < SYMLOOP_MAX; ++syml_cnt)
- {
-  

Re: [PATCH] Cygwin: include network mounts in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
On Wed, 19 Feb 2025, Lionel Cons wrote:

> Does this patch cover global mounts, i.e. SMB mounted by user
> LocalSystem on a driver letter are visible to ALL users. Local users
> logons can override the same drive letter via per-user net use
>
> Example:
> LocalSystem mounts H: to \\homeserver\disk4\users, this is visible to
> all users in a system
> User "lionel" mounts H: to \\lionelsserver\data\homedir, this is
> visible to the current Logon session

I believe so, but it doesn't actually matter.  From the Cygwin
perspective, it would just show a mount of H: on /cygdrive/h.


Re: [PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Corinna Vinschen
Hi Jeremy,

On Feb 18 10:38, Jeremy Drake via Cygwin-patches wrote:
> @@ -1742,17 +1742,19 @@ struct mntent *
>  mount_info::cygdrive_getmntent ()
>  {
>tmp_pathbuf tp;
> -  const wchar_t *wide_path;
> +  dos_drive_mappings::dos_device_mountpoint dos_mount;
>char *win32_path, *posix_path;
> 
>if (!_my_tls.locals.drivemappings)
>  _my_tls.locals.drivemappings = new dos_drive_mappings ();
> 
> -  wide_path = _my_tls.locals.drivemappings->next_dos_mount ();
> -  if (wide_path)
> +  dos_mount = _my_tls.locals.drivemappings->next_dos_mount ();
> +  while (dos_mount.device && get_device_type (dos_mount.device) == DT_FLOPPY)
> +dos_mount = _my_tls.locals.drivemappings->next_dos_mount ();

Actually, given that we can't do without GetLogicalDrives anyway,
this could be folded into the mapping list creation within
dos_drive_mappings::dos_drive_mappings.


Corinna


Re: [PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
On Tue, 18 Feb 2025, Corinna Vinschen wrote:

> Actually, given that we can't do without GetLogicalDrives anyway,
> this could be folded into the mapping list creation within
> dos_drive_mappings::dos_drive_mappings.

I don't agree.  That would affect the other user(s) of dos_drive_mappings.
What if somebody had a mapped file on a file on a floppy drive and looked
in /proc//maps?


Re: [PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Corinna Vinschen
On Feb 18 22:17, Corinna Vinschen wrote:
> On Feb 18 13:10, Jeremy Drake via Cygwin-patches wrote:
> > On Tue, 18 Feb 2025, Corinna Vinschen wrote:
> > 
> > > Actually, given that we can't do without GetLogicalDrives anyway,
> > > this could be folded into the mapping list creation within
> > > dos_drive_mappings::dos_drive_mappings.
> > 
> > I don't agree.  That would affect the other user(s) of dos_drive_mappings.
> > What if somebody had a mapped file on a file on a floppy drive and looked
> > in /proc//maps?
> 
> Good point.  Bad enough we still have to care for floppies.

Alternatively... calling the constructor with a parameter
`bool with_floppies'?


Corinna


Re: [PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Corinna Vinschen
On Feb 18 13:10, Jeremy Drake via Cygwin-patches wrote:
> On Tue, 18 Feb 2025, Corinna Vinschen wrote:
> 
> > Actually, given that we can't do without GetLogicalDrives anyway,
> > this could be folded into the mapping list creation within
> > dos_drive_mappings::dos_drive_mappings.
> 
> I don't agree.  That would affect the other user(s) of dos_drive_mappings.
> What if somebody had a mapped file on a file on a floppy drive and looked
> in /proc//maps?

Good point.  Bad enough we still have to care for floppies.


Corinna


[PATCH] Cygwin: include network mounts in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
After migrating from GetLogicalDrives to Find(First|Next)VolumeW, mapped
network drives no longer showed up in getmntent output.  To fix that,
also iterate GetLogicalDriveStringsW when builing dos_drive_mappings,
and merge with volume mounts (skipping any volume mounts that are just
mounted on the root of a drive, and replacing the dos mounts in the
mapping for a volume which is mounted on both a drive root and a
directory).

Fixes: 04a5b072940cc ("Cygwin: expose all windows volume mount points.")
Addresses: https://cygwin.com/pipermail/cygwin/2025-February/257384.html
Signed-off-by: Jeremy Drake 
---

This was generated on top of the patch
https://cygwin.com/pipermail/cygwin-patches/2025q1/013390.html but should
be able to be applied without it.

 winsup/cygwin/mount.cc | 145 -
 1 file changed, 113 insertions(+), 32 deletions(-)

diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index a3d9e5bd0f..68414f13af 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -1995,6 +1995,40 @@ endmntent (FILE *)
   return 1;
 }

+static bool
+resolve_dos_device (const wchar_t *dosname, wchar_t *devpath)
+{
+  if (QueryDosDeviceW (dosname, devpath, NT_MAX_PATH))
+{
+  /* The DOS drive mapping can be another symbolic link.  If so,
+the mapping won't work since the section name is the name
+after resolving all symlinks.  Resolve symlinks here, too. */
+  for (int syml_cnt = 0; syml_cnt < SYMLOOP_MAX; ++syml_cnt)
+   {
+ UNICODE_STRING upath;
+ OBJECT_ATTRIBUTES attr;
+ NTSTATUS status;
+ HANDLE h;
+
+ RtlInitUnicodeString (&upath, devpath);
+ InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE,
+ NULL, NULL);
+ status = NtOpenSymbolicLinkObject (&h, SYMBOLIC_LINK_QUERY, &attr);
+ if (!NT_SUCCESS (status))
+   break;
+ RtlInitEmptyUnicodeString (&upath, devpath, (NT_MAX_PATH - 1)
+ * sizeof (WCHAR));
+ status = NtQuerySymbolicLinkObject (h, &upath, NULL);
+ NtClose (h);
+ if (!NT_SUCCESS (status))
+   break;
+ devpath[upath.Length / sizeof (WCHAR)] = L'\0';
+   }
+  return true;
+}
+  return false;
+}
+
 dos_drive_mappings::dos_drive_mappings ()
 : mappings(0)
 , cur_mapping(0)
@@ -2004,6 +2038,44 @@ dos_drive_mappings::dos_drive_mappings ()
   wchar_t vol[64]; /* Long enough for Volume GUID string */
   wchar_t *devpath = tp.w_get ();
   wchar_t *mounts = tp.w_get ();
+  mapping **nextm = &mappings;
+  mapping *endfirstloop = NULL;
+  DWORD len;
+
+  /* Iterate over all drive letters, fetch the DOS device path */
+  if (!(len = GetLogicalDriveStringsW (NT_MAX_PATH - 1, mounts)) ||
+  len >= NT_MAX_PATH)
+debug_printf ("GetLogicalDriveStringsW, %E");
+  else {
+for (wchar_t *mount = mounts; *mount; mount += len + 2)
+  {
+   len = wcslen (mount);
+   mount[--len] = L'\0'; /* Drop trailing backslash */
+   if (resolve_dos_device (mount, devpath))
+ {
+   mapping *m = new mapping ();
+   if (m)
+ {
+   m->dos.path = wcsdup (mount);
+   m->ntdevpath = wcsdup (devpath);
+   if (!m->dos.path || !m->ntdevpath)
+ {
+   free (m->dos.path);
+   free (m->ntdevpath);
+   delete m;
+   continue;
+ }
+   m->dos.len = len;
+   m->ntlen = wcslen (m->ntdevpath);
+   *nextm = endfirstloop = m;
+   nextm = &m->next;
+ }
+ }
+   else
+ debug_printf ("Unable to determine the native mapping for %ls "
+   "(error %E)", mount);
+  }
+  }

   /* Iterate over all volumes, fetch the list of DOS paths the volume is
  mounted to. */
@@ -2011,43 +2083,22 @@ dos_drive_mappings::dos_drive_mappings ()
   if (sh == INVALID_HANDLE_VALUE)
 debug_printf ("FindFirstVolumeW, %E");
   else {
-mapping **nextm = &mappings;
 do
   {
-   /* Skip drives which are not mounted. */
-   DWORD len;
+   /* Skip volumes which are not mounted. */
if (!GetVolumePathNamesForVolumeNameW (vol, mounts, NT_MAX_PATH, &len)
|| mounts[0] == L'\0')
  continue;
+   /* Skip volumes which are only mounted to the root of a drive letter:
+  they were handled in the loop above */
+   if (len == 5 && mounts[1] == L':' && mounts[2] == L'\\' && !mounts[3])
+ continue;
+
*wcsrchr (vol, L'\\') = L'\0';
-   if (QueryDosDeviceW (vol + 4, devpath, NT_MAX_PATH))
+   if (resolve_dos_device (vol + 4, devpath))
  {
-   /* The DOS drive mapping can be another symbolic link.  If so,
-  the mapping won't work since the section name is the name
-  aft

Re: [PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Corinna Vinschen
Hi Jeremy,

On Feb 18 10:38, Jeremy Drake via Cygwin-patches wrote:
> @@ -1742,17 +1742,19 @@ struct mntent *
>  mount_info::cygdrive_getmntent ()
>  {
>tmp_pathbuf tp;
> -  const wchar_t *wide_path;
> +  dos_drive_mappings::dos_device_mountpoint dos_mount;
>char *win32_path, *posix_path;
> 
>if (!_my_tls.locals.drivemappings)
>  _my_tls.locals.drivemappings = new dos_drive_mappings ();
> 
> -  wide_path = _my_tls.locals.drivemappings->next_dos_mount ();
> -  if (wide_path)
> +  dos_mount = _my_tls.locals.drivemappings->next_dos_mount ();
> +  while (dos_mount.device && get_device_type (dos_mount.device) == DT_FLOPPY)
> +dos_mount = _my_tls.locals.drivemappings->next_dos_mount ();

Actually, given that we can't do without GetLogicalDrives anyway,
this could be folded into the mapping list creation within
dos_drive_mappings::dos_drive_mappings.


Corinna


Re: [PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
On Tue, 18 Feb 2025, Corinna Vinschen wrote:

> Alternatively... calling the constructor with a parameter
> `bool with_floppies'?

I can buy that.  I'll wait for your review of the patch I just sent before
sending a patch on top of that to implement this.


[PATCH] Cygwin: skip floppy drives in cygdrive_getmntent.

2025-02-18 Thread Jeremy Drake via Cygwin-patches
This was previously done, but was lost when the function was updated to
list all Windows mount points, not just drive letters.

Fixes: 04a5b072940cc ("Cygwin: expose all windows volume mount points.")
Signed-off-by: Jeremy Drake 
---

I finally got a chance to test on a machine that still has a physical
floppy drive, and running "mount" resulted in the annoying
floppy-drive-spinup sound.  I changed next_dos_mount () to return both the
device and mount point, and used the existing logic from get_disk_type
without the extra call to QueryDosDeviceW.  This same function could be
used by https://cygwin.com/pipermail/cygwin-patches/2023q3/012436.html if
that ever comes up again.

 winsup/cygwin/local_includes/mount.h |  8 ++-
 winsup/cygwin/mount.cc   | 31 ++--
 2 files changed, 27 insertions(+), 12 deletions(-)

diff --git a/winsup/cygwin/local_includes/mount.h 
b/winsup/cygwin/local_includes/mount.h
index 3049de8ba3..2ae67a7035 100644
--- a/winsup/cygwin/local_includes/mount.h
+++ b/winsup/cygwin/local_includes/mount.h
@@ -23,6 +23,7 @@ enum disk_type
   DT_SHARE_NFS
 };

+disk_type get_device_type (LPCWSTR);
 disk_type get_disk_type (LPCWSTR);

 /* Don't add new fs types without adding them to fs_names in mount.cc!
@@ -239,6 +240,11 @@ public:
   dos_drive_mappings ();
   ~dos_drive_mappings ();
   wchar_t *fixup_if_match (wchar_t *path);
-  const wchar_t *next_dos_mount ();
+  struct dos_device_mountpoint
+  {
+const wchar_t *device;
+const wchar_t *mountpoint;
+  };
+  dos_device_mountpoint next_dos_mount ();
 };
 #endif
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index b8d8d4a974..a3d9e5bd0f 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -1742,17 +1742,19 @@ struct mntent *
 mount_info::cygdrive_getmntent ()
 {
   tmp_pathbuf tp;
-  const wchar_t *wide_path;
+  dos_drive_mappings::dos_device_mountpoint dos_mount;
   char *win32_path, *posix_path;

   if (!_my_tls.locals.drivemappings)
 _my_tls.locals.drivemappings = new dos_drive_mappings ();

-  wide_path = _my_tls.locals.drivemappings->next_dos_mount ();
-  if (wide_path)
+  dos_mount = _my_tls.locals.drivemappings->next_dos_mount ();
+  while (dos_mount.device && get_device_type (dos_mount.device) == DT_FLOPPY)
+dos_mount = _my_tls.locals.drivemappings->next_dos_mount ();
+  if (dos_mount.mountpoint)
 {
   win32_path = tp.c_get ();
-  sys_wcstombs (win32_path, NT_MAX_PATH, wide_path);
+  sys_wcstombs (win32_path, NT_MAX_PATH, dos_mount.mountpoint);
   posix_path = tp.c_get ();
   cygdrive_posix_path (win32_path, posix_path, 0);
   return fillout_mntent (win32_path, posix_path, cygdrive_flags);
@@ -1899,11 +1901,9 @@ cygwin_umount (const char *path, unsigned flags)
 #define is_dev(d,s)wcsncmp((d),(s),sizeof(s) - 1)

 disk_type
-get_disk_type (LPCWSTR dos)
+get_device_type (LPCWSTR dev)
 {
-  WCHAR dev[MAX_PATH], *d = dev;
-  if (!QueryDosDeviceW (dos, dev, MAX_PATH))
-return DT_NODISK;
+  const WCHAR *d = dev;
   if (is_dev (dev, L"\\Device\\"))
 {
   d += 8;
@@ -1934,6 +1934,15 @@ get_disk_type (LPCWSTR dos)
   return DT_NODISK;
 }

+disk_type
+get_disk_type (LPCWSTR dos)
+{
+  WCHAR dev[MAX_PATH];
+  if (!QueryDosDeviceW (dos, dev, MAX_PATH))
+return DT_NODISK;
+  return get_device_type (dev);
+}
+
 extern "C" FILE *
 setmntent (const char *filep, const char *)
 {
@@ -2106,7 +2115,7 @@ dos_drive_mappings::fixup_if_match (wchar_t *path)
   return path;
 }

-const wchar_t *
+dos_drive_mappings::dos_device_mountpoint
 dos_drive_mappings::next_dos_mount ()
 {
   if (cur_dos)
@@ -2118,10 +2127,10 @@ dos_drive_mappings::next_dos_mount ()
   else
cur_mapping = mappings;
   if (!cur_mapping)
-   return NULL;
+   return {NULL, NULL};
   cur_dos = &cur_mapping->dos;
 }
-  return cur_dos->path;
+  return {cur_mapping->ntdevpath, cur_dos->path};
 }

 dos_drive_mappings::~dos_drive_mappings ()
-- 
2.48.1.windows.1