[PATCH v3 1/2] Cygwin: store list of mounts for volumes in dos_drive_mappings.

Jeremy Drake cygwin@jdrake.com
Wed Feb 12 18:55:18 GMT 2025


The existing code only stored the first mount for each volume, but now
we store the complete list, and split it into a linked list.  This will
be used in a subsequent commit to populate cygdrive mount entries.

Signed-off-by: Jeremy Drake <cygwin@jdrake.com>
---
 winsup/cygwin/local_includes/mount.h | 11 ++++---
 winsup/cygwin/mount.cc               | 46 +++++++++++++++++++---------
 2 files changed, 39 insertions(+), 18 deletions(-)

diff --git a/winsup/cygwin/local_includes/mount.h b/winsup/cygwin/local_includes/mount.h
index b2acdf08b4..c96b34781e 100644
--- a/winsup/cygwin/local_includes/mount.h
+++ b/winsup/cygwin/local_includes/mount.h
@@ -223,12 +223,15 @@ class dos_drive_mappings
   struct mapping
   {
     mapping *next;
-    size_t doslen;
     size_t ntlen;
-    wchar_t *dospath;
     wchar_t *ntdevpath;
-  };
-  mapping *mappings;
+    struct dosmount
+    {
+      dosmount *next;
+      wchar_t *path;
+      size_t len;
+    } dos;
+  } *mappings;

 public:
   dos_drive_mappings ();
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index bf26c4af3e..4be24fbe84 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -2002,13 +2002,13 @@ dos_drive_mappings::dos_drive_mappings ()
   wchar_t *devpath = tp.w_get ();
   wchar_t *mounts = tp.w_get ();

-  /* Iterate over all volumes, fetch the first path from the list of
-     DOS paths the volume is mounted to, or use the GUID volume path
-     otherwise. */
+  /* Iterate over all volumes, fetch the list of DOS paths the volume is
+     mounted to. */
   HANDLE sh = FindFirstVolumeW (vol, 64);
   if (sh == INVALID_HANDLE_VALUE)
     debug_printf ("FindFirstVolumeW, %E");
   else {
+    mapping **nextm = &mappings;
     do
       {
 	/* Skip drives which are not mounted. */
@@ -2047,20 +2047,32 @@ dos_drive_mappings::dos_drive_mappings ()
 	    mapping *m = new mapping ();
 	    if (m)
 	      {
-		m->dospath = wcsdup (mounts);
+		/* store mount point list */
+		if ((m->dos.path = (wchar_t *) malloc (len * sizeof (WCHAR))))
+		  memcpy (m->dos.path, mounts, len * sizeof (WCHAR));
 		m->ntdevpath = wcsdup (devpath);
-		if (!m->dospath || !m->ntdevpath)
+		if (!m->dos.path || !m->ntdevpath)
 		  {
-		    free (m->dospath);
+		    free (m->dos.path);
 		    free (m->ntdevpath);
 		    delete m;
 		    continue;
 		  }
-		m->doslen = wcslen (m->dospath);
-		m->dospath[--m->doslen] = L'\0'; /* Drop trailing backslash */
+		/* split mount point list into dosmount entries */
+		mapping::dosmount *dos = &m->dos;
+		for (wchar_t *mount = m->dos.path;
+		    dos;
+		    mount += dos->len + 2,
+		      dos->next = mount[0] ? new mapping::dosmount () : NULL,
+		      dos = dos->next)
+		  {
+		    dos->path = mount;
+		    dos->len = wcslen (dos->path);
+		    dos->path[--dos->len] = L'\0'; /* Drop trailing backslash */
+		  }
 		m->ntlen = wcslen (m->ntdevpath);
-		m->next = mappings;
-		mappings = m;
+		*nextm = m;
+		nextm = &m->next;
 	      }
 	  }
 	else
@@ -2088,11 +2100,11 @@ dos_drive_mappings::fixup_if_match (wchar_t *path)
       {
 	wchar_t *tmppath;

-	if (m->ntlen > m->doslen)
-	  wcsncpy (path += m->ntlen - m->doslen, m->dospath, m->doslen);
+	if (m->ntlen > m->dos.len)
+	  wcsncpy (path += m->ntlen - m->dos.len, m->dos.path, m->dos.len);
 	else if ((tmppath = wcsdup (path + m->ntlen)) != NULL)
 	  {
-	    wcpcpy (wcpcpy (path, m->dospath), tmppath);
+	    wcpcpy (wcpcpy (path, m->dos.path), tmppath);
 	    free (tmppath);
 	  }
 	break;
@@ -2106,8 +2118,14 @@ dos_drive_mappings::~dos_drive_mappings ()
   for (mapping *m = mappings; m; m = n)
     {
       n = m->next;
-      free (m->dospath);
+      free (m->dos.path);
       free (m->ntdevpath);
+      mapping::dosmount *dn;
+      for (mapping::dosmount *dm = m->dos.next; dm; dm = dn)
+	{
+	  dn = dm->next;
+	  delete dm;
+	}
       delete m;
     }
 }
-- 
2.47.1.windows.2



More information about the Cygwin-patches mailing list