This patch adds support for drive mappings added with SUBST and NET USE.
Example: After

  subst p: C:\Users\Public
  net use t: \\larid\tmp

the test program now prints:

  ??? C:\ ??? NFTS local
  ??? P:\ C:\Users\Public NFTS local
  ??? T:\ \\larid\tmp NTFS remote


2025-03-19  Bruno Haible  <br...@clisp.org>

        mountlist: Improve implementation on native Windows.
        * lib/mountlist.c (read_file_system_list) [_WIN32 && !__CYGWIN__]:
        Return the mntroot of drives mapped by SUBST or NET USE.

diff --git a/lib/mountlist.c b/lib/mountlist.c
index 1385db43fd..23ebdf6750 100644
--- a/lib/mountlist.c
+++ b/lib/mountlist.c
@@ -1131,8 +1131,58 @@ read_file_system_list (bool need_fs_type)
                 /* Check if drive is remote.  See:
                    
<https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-getdrivetypea>.
  */
                 me->me_remote = GetDriveType (mountdir) == DRIVE_REMOTE;
+                /* Here we could use
+                   QueryDosDeviceW -> returns something like 
'\Device\HarddiskVolume2'
+                   GetVolumeNameForVolumeMountPointW -> return something like 
'\\?\Volume{...}'
+                 */
                 me->me_devname = NULL;
-                me->me_mntroot = NULL;
+                {
+                  /* Find the SUBST or NET USE mapping of the given drive.
+                     
<https://learn.microsoft.com/en-us/windows/win32/api/fileapi/nf-fileapi-querydosdevicew>
+                     For testing of SUBST:   <https://ss64.com/nt/subst.html>
+                     For testing of NET USE: 
<https://ss64.com/nt/net-use.html>  */
+                  wchar_t drive[3];
+                  wchar_t mapping[MAX_PATH + 1];
+                  drive[0] = L'A' + i;
+                  drive[1] = L':';
+                  drive[2] = L'\0';
+                  DWORD mapping_len = QueryDosDeviceW (drive, mapping, sizeof 
(mapping) / sizeof (mapping[0]));
+                  if (mapping_len > 4 && wcsncmp (mapping, L"\\??\\", 4) == 0)
+                    {
+                      /* It's a SUBSTed drive.  */
+                      char subst_dir[MAX_PATH + 1];
+                      size_t subst_dir_len = wcstombs (subst_dir, mapping + 4, 
sizeof (subst_dir));
+                      if (subst_dir_len > 0 && subst_dir_len <= MAX_PATH)
+                        me->me_mntroot = xstrdup (subst_dir);
+                      else
+                        /* mapping is too long or not convertible to the
+                           locale encoding.  */
+                        me->me_mntroot = NULL;
+                    }
+                  else if (mapping_len > 26
+                           && wcsncmp (mapping, 
L"\\Device\\LanmanRedirector\\;", 26) == 0)
+                    {
+                      wchar_t *next_backslash = wcschr (mapping + 26, L'\\');
+                      if (next_backslash != NULL)
+                        {
+                          *--next_backslash = L'\\';
+                          char share_dir[MAX_PATH + 1];
+                          size_t share_dir_len = wcstombs (share_dir, 
next_backslash, sizeof (share_dir));
+                          if (share_dir_len > 0 && share_dir_len <= MAX_PATH)
+                            me->me_mntroot = xstrdup (share_dir);
+                          else
+                            /* mapping is too long or not convertible to the
+                               locale encoding.  */
+                            me->me_mntroot = NULL;
+                        }
+                      else
+                        /* mapping does not have the expected form.  */
+                        me->me_mntroot = NULL;
+                    }
+                  else
+                    /* It's neither a SUBSTed nor a NET USEd drive.  */
+                    me->me_mntroot = NULL;
+                }
                 me->me_dev = (dev_t) -1;
                 me->me_dummy = 0;
                 me->me_type = xstrdup (fs_name);




Reply via email to