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 <cyg...@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

Reply via email to