OSDN Git Service

* external.cc (cygwin_internal): Implement CW_ALLOC_DRIVE_MAP,
authorcorinna <corinna>
Thu, 22 Dec 2011 12:25:03 +0000 (12:25 +0000)
committercorinna <corinna>
Thu, 22 Dec 2011 12:25:03 +0000 (12:25 +0000)
CW_MAP_DRIVE_MAP, CW_FREE_DRIVE_MAP.
* fhandler_process.cc: Include mount.h.
(get_volume_path_names_for_volume_name): Move to mount.cc.
(struct dos_drive_mappings): Ditto.
* mount.cc (get_volume_path_names_for_volume_name): Move here.
(dos_drive_mappings::dos_drive_mappings): Ditto.
(dos_drive_mappings::fixup_if_match): Ditto.
(dos_drive_mappings::~dos_drive_mappings): Ditto.
* mount.h (class dos_drive_mappings): Declare her.
* include/sys/cygwin.h (cygwin_getinfo_types): Add CW_ALLOC_DRIVE_MAP,
CW_MAP_DRIVE_MAP, CW_FREE_DRIVE_MAP.
* include/cygwin/version.h: Bump API minor number.

winsup/cygwin/ChangeLog
winsup/cygwin/external.cc
winsup/cygwin/fhandler_process.cc
winsup/cygwin/include/cygwin/version.h
winsup/cygwin/include/sys/cygwin.h
winsup/cygwin/mount.cc
winsup/cygwin/mount.h

index 197bf3f..5862201 100644 (file)
@@ -1,5 +1,21 @@
 2011-12-22  Corinna Vinschen  <vinschen@redhat.com>
 
+       * external.cc (cygwin_internal): Implement CW_ALLOC_DRIVE_MAP,
+       CW_MAP_DRIVE_MAP, CW_FREE_DRIVE_MAP.
+       * fhandler_process.cc: Include mount.h.
+       (get_volume_path_names_for_volume_name): Move to mount.cc.
+       (struct dos_drive_mappings): Ditto.
+       * mount.cc (get_volume_path_names_for_volume_name): Move here.
+       (dos_drive_mappings::dos_drive_mappings): Ditto.
+       (dos_drive_mappings::fixup_if_match): Ditto.
+       (dos_drive_mappings::~dos_drive_mappings): Ditto.
+       * mount.h (class dos_drive_mappings): Declare her.
+       * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_ALLOC_DRIVE_MAP,
+       CW_MAP_DRIVE_MAP, CW_FREE_DRIVE_MAP.
+       * include/cygwin/version.h: Bump API minor number.
+
+2011-12-22  Corinna Vinschen  <vinschen@redhat.com>
+
        * fhandler_process.cc: Drop unneeded includes.
 
 2011-12-22  Corinna Vinschen  <vinschen@redhat.com>
index 9476804..e6e3493 100644 (file)
@@ -528,6 +528,31 @@ cygwin_internal (cygwin_getinfo_types t, ...)
        }
        break;
 
+      case CW_ALLOC_DRIVE_MAP:
+       {
+         dos_drive_mappings *ddm = new dos_drive_mappings ();
+         res = (uintptr_t) ddm;
+       }
+       break;
+
+      case CW_MAP_DRIVE_MAP:
+       {
+         dos_drive_mappings *ddm = va_arg (arg, dos_drive_mappings *);
+         wchar_t *pathbuf = va_arg (arg, wchar_t *);
+         if (ddm && pathbuf)
+           res = (uintptr_t) ddm->fixup_if_match (pathbuf);
+       }
+       break;
+
+      case CW_FREE_DRIVE_MAP:
+       {
+         dos_drive_mappings *ddm = va_arg (arg, dos_drive_mappings *);
+         if (ddm)
+           delete ddm;
+         res = 0;
+       }
+       break;
+
       default:
        set_errno (ENOSYS);
     }
index 18d1ea9..12ba292 100644 (file)
@@ -25,6 +25,7 @@ details. */
 #include "ntdll.h"
 #include "cygtls.h"
 #include "pwdgrp.h"
+#include "mount.h"
 #include "tls_pbuf.h"
 #include <sys/param.h>
 #include <ctype.h>
@@ -541,169 +542,6 @@ format_process_winexename (void *data, char *&destbuf)
   return len + 1;
 }
 
-static bool
-get_volume_path_names_for_volume_name (LPCWSTR vol, LPWSTR mounts)
-{
-  DWORD len;
-  if (GetVolumePathNamesForVolumeNameW (vol, mounts, NT_MAX_PATH, &len))
-    return true;
-
-  /* Windows 2000 doesn't have GetVolumePathNamesForVolumeNameW.
-     Just assume that mount points are not longer than MAX_PATH. */
-  WCHAR drives[MAX_PATH], dvol[MAX_PATH], mp[MAX_PATH + 3];
-  if (!GetLogicalDriveStringsW (MAX_PATH, drives))
-    return false;
-  for (PWCHAR drive = drives; *drive; drive = wcschr (drive, '\0') + 1)
-    {
-      if (!GetVolumeNameForVolumeMountPointW (drive, dvol, MAX_PATH))
-       continue;
-      if (!wcscasecmp (vol, dvol))
-       mounts = wcpcpy (mounts, drive) + 1;
-      wcscpy (mp, drive);
-      HANDLE h = FindFirstVolumeMountPointW (dvol, mp + 3, MAX_PATH);
-      if (h == INVALID_HANDLE_VALUE)
-       continue;
-      do
-       {
-         if (GetVolumeNameForVolumeMountPointW (mp, dvol, MAX_PATH))
-           if (!wcscasecmp (vol, dvol))
-             mounts = wcpcpy (mounts, drive) + 1;
-       }
-      while (FindNextVolumeMountPointW (h, mp, MAX_PATH));
-      FindVolumeMountPointClose (h);
-    }
-  *mounts = L'\0';
-  return true;
-}
-
-struct dos_drive_mappings
-{
-  struct mapping
-  {
-    mapping *next;
-    size_t doslen;
-    size_t ntlen;
-    wchar_t *dospath;
-    wchar_t *ntdevpath;
-  };
-  mapping *mappings;
-
-  dos_drive_mappings ()
-    : mappings(0)
-  {
-    tmp_pathbuf tp;
-    wchar_t vol[64]; /* Long enough for Volume GUID string */
-    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. */
-    HANDLE sh = FindFirstVolumeW (vol, 64);
-    if (sh == INVALID_HANDLE_VALUE)
-      debug_printf ("FindFirstVolumeW, %E");
-    else
-      do
-       {
-         /* Skip drives which are not mounted. */
-         if (!get_volume_path_names_for_volume_name (vol, mounts)
-             || mounts[0] == L'\0')
-           continue;
-         *wcsrchr (vol, L'\\') = L'\0';
-         if (QueryDosDeviceW (vol + 4, 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';
-               }
-             mapping *m = new mapping ();
-             if (m)
-               {
-                 m->dospath = wcsdup (mounts);
-                 m->ntdevpath = wcsdup (devpath);
-                 if (!m->dospath || !m->ntdevpath)
-                   {
-                     free (m->dospath);
-                     free (m->ntdevpath);
-                     delete m;
-                     continue;
-                   }
-                 m->doslen = wcslen (m->dospath);
-                 m->dospath[--m->doslen] = L'\0'; /* Drop trailing backslash */
-                 m->ntlen = wcslen (m->ntdevpath);
-                 m->next = mappings;
-                 mappings = m;
-               }
-           }
-         else
-           debug_printf ("Unable to determine the native mapping for %ls "
-                         "(error %lu)", vol, GetLastError ());
-       }
-      while (FindNextVolumeW (sh, vol, 64));
-      FindVolumeClose (sh);
-  }
-
-  wchar_t *fixup_if_match (wchar_t *path)
-  {
-    /* Check for network drive first. */
-    if (!wcsncmp (path, L"\\Device\\Mup\\", 12))
-      {
-       path += 10;
-       path[0] = L'\\';
-       return path;
-      }
-    /* Then test local drives. */
-    for (mapping *m = mappings; m; m = m->next)
-      if (!wcsncmp (m->ntdevpath, path, m->ntlen))
-       {
-         wchar_t *tmppath;
-
-         if (m->ntlen > m->doslen)
-           wcsncpy (path += m->ntlen - m->doslen, m->dospath, m->doslen);
-         else if ((tmppath = wcsdup (path + m->ntlen)) != NULL)
-           {
-             wcpcpy (wcpcpy (path, m->dospath), tmppath);
-             free (tmppath);
-           }
-         break;
-       }
-    return path;
-  }
-
-  ~dos_drive_mappings ()
-  {
-    mapping *n = 0;
-    for (mapping *m = mappings; m; m = n)
-      {
-       n = m->next;
-       free (m->dospath);
-       free (m->ntdevpath);
-       delete m;
-      }
-  }
-};
-
 struct heap_info
 {
   struct heap
index db9a18b..997578e 100644 (file)
@@ -424,12 +424,13 @@ details. */
       253: Export TIOCSCTTY, tcgetsid.
       254: Export getgrouplist.
       255: Export ptsname_r.
+      256: Add CW_ALLOC_DRIVE_MAP, CW_MAP_DRIVE_MAP, CW_FREE_DRIVE_MAP.
      */
 
      /* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
 
 #define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 255
+#define CYGWIN_VERSION_API_MINOR 256
 
      /* There is also a compatibity version number associated with the
        shared memory regions.  It is incremented when incompatible
index 85c4526..97f3e95 100644 (file)
@@ -137,7 +137,10 @@ typedef enum
     CW_CVT_MNT_OPTS,
     CW_LST_MNT_OPTS,
     CW_STRERROR,
-    CW_CVT_ENV_TO_WINENV
+    CW_CVT_ENV_TO_WINENV,
+    CW_ALLOC_DRIVE_MAP,
+    CW_MAP_DRIVE_MAP,
+    CW_FREE_DRIVE_MAP
   } cygwin_getinfo_types;
 
 #define CW_LOCK_PINFO CW_LOCK_PINFO
index bfb63f8..1bdd0a2 100644 (file)
@@ -1873,3 +1873,154 @@ endmntent (FILE *)
 {
   return 1;
 }
+
+static bool
+get_volume_path_names_for_volume_name (LPCWSTR vol, LPWSTR mounts)
+{
+  DWORD len;
+  if (GetVolumePathNamesForVolumeNameW (vol, mounts, NT_MAX_PATH, &len))
+    return true;
+
+  /* Windows 2000 doesn't have GetVolumePathNamesForVolumeNameW.
+     Just assume that mount points are not longer than MAX_PATH. */
+  WCHAR drives[MAX_PATH], dvol[MAX_PATH], mp[MAX_PATH + 3];
+  if (!GetLogicalDriveStringsW (MAX_PATH, drives))
+    return false;
+  for (PWCHAR drive = drives; *drive; drive = wcschr (drive, '\0') + 1)
+    {
+      if (!GetVolumeNameForVolumeMountPointW (drive, dvol, MAX_PATH))
+       continue;
+      if (!wcscasecmp (vol, dvol))
+       mounts = wcpcpy (mounts, drive) + 1;
+      wcscpy (mp, drive);
+      HANDLE h = FindFirstVolumeMountPointW (dvol, mp + 3, MAX_PATH);
+      if (h == INVALID_HANDLE_VALUE)
+       continue;
+      do
+       {
+         if (GetVolumeNameForVolumeMountPointW (mp, dvol, MAX_PATH))
+           if (!wcscasecmp (vol, dvol))
+             mounts = wcpcpy (mounts, drive) + 1;
+       }
+      while (FindNextVolumeMountPointW (h, mp, MAX_PATH));
+      FindVolumeMountPointClose (h);
+    }
+  *mounts = L'\0';
+  return true;
+}
+
+dos_drive_mappings::dos_drive_mappings ()
+: mappings(0)
+{
+  tmp_pathbuf tp;
+  wchar_t vol[64]; /* Long enough for Volume GUID string */
+  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. */
+  HANDLE sh = FindFirstVolumeW (vol, 64);
+  if (sh == INVALID_HANDLE_VALUE)
+    debug_printf ("FindFirstVolumeW, %E");
+  else
+    do
+      {
+       /* Skip drives which are not mounted. */
+       if (!get_volume_path_names_for_volume_name (vol, mounts)
+           || mounts[0] == L'\0')
+         continue;
+       *wcsrchr (vol, L'\\') = L'\0';
+       if (QueryDosDeviceW (vol + 4, 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';
+             }
+           mapping *m = new mapping ();
+           if (m)
+             {
+               m->dospath = wcsdup (mounts);
+               m->ntdevpath = wcsdup (devpath);
+               if (!m->dospath || !m->ntdevpath)
+                 {
+                   free (m->dospath);
+                   free (m->ntdevpath);
+                   delete m;
+                   continue;
+                 }
+               m->doslen = wcslen (m->dospath);
+               m->dospath[--m->doslen] = L'\0'; /* Drop trailing backslash */
+               m->ntlen = wcslen (m->ntdevpath);
+               m->next = mappings;
+               mappings = m;
+             }
+         }
+       else
+         debug_printf ("Unable to determine the native mapping for %ls "
+                       "(error %lu)", vol, GetLastError ());
+      }
+    while (FindNextVolumeW (sh, vol, 64));
+    FindVolumeClose (sh);
+}
+
+wchar_t *
+dos_drive_mappings::fixup_if_match (wchar_t *path)
+{
+  /* Check for network drive first. */
+  if (!wcsncmp (path, L"\\Device\\Mup\\", 12))
+    {
+      path += 10;
+      path[0] = L'\\';
+      return path;
+    }
+  /* Then test local drives. */
+  for (mapping *m = mappings; m; m = m->next)
+    if (!wcsncmp (m->ntdevpath, path, m->ntlen))
+      {
+       wchar_t *tmppath;
+
+       if (m->ntlen > m->doslen)
+         wcsncpy (path += m->ntlen - m->doslen, m->dospath, m->doslen);
+       else if ((tmppath = wcsdup (path + m->ntlen)) != NULL)
+         {
+           wcpcpy (wcpcpy (path, m->dospath), tmppath);
+           free (tmppath);
+         }
+       break;
+      }
+  return path;
+}
+
+dos_drive_mappings::~dos_drive_mappings ()
+{
+  mapping *n = 0;
+  for (mapping *m = mappings; m; m = n)
+    {
+      n = m->next;
+      free (m->dospath);
+      free (m->ntdevpath);
+      delete m;
+    }
+}
index 0f0690a..606e9f5 100644 (file)
@@ -197,4 +197,22 @@ class mount_info
 
   int cygdrive_win32_path (const char *src, char *dst, int& unit);
 };
+
+class dos_drive_mappings
+{
+  struct mapping
+  {
+    mapping *next;
+    size_t doslen;
+    size_t ntlen;
+    wchar_t *dospath;
+    wchar_t *ntdevpath;
+  };
+  mapping *mappings;
+
+public:
+  dos_drive_mappings ();
+  ~dos_drive_mappings ();
+  wchar_t *fixup_if_match (wchar_t *path);
+};
 #endif