Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2011-12-22 16:25:10 +0400
committerCorinna Vinschen <corinna@vinschen.de>2011-12-22 16:25:10 +0400
commit3a24189bbae9d1b1943e17038e78bb7d65f2a848 (patch)
tree6a8935c6f5899db38525d5b9daeae79cf1c0e707
parent3a03267d6d695b678128db6a8b7028b8b5f93e1f (diff)
* 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.
-rw-r--r--winsup/cygwin/ChangeLog16
-rw-r--r--winsup/cygwin/external.cc25
-rw-r--r--winsup/cygwin/fhandler_process.cc164
-rw-r--r--winsup/cygwin/include/cygwin/version.h3
-rw-r--r--winsup/cygwin/include/sys/cygwin.h5
-rw-r--r--winsup/cygwin/mount.cc151
-rw-r--r--winsup/cygwin/mount.h18
7 files changed, 217 insertions, 165 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 197bf3fe4..586220188 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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>
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index 947680420..e6e349395 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -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);
}
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index 18d1ea90f..12ba292c7 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -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
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index db9a18b4d..997578ed8 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -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
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 85c452677..97f3e959e 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -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
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index bfb63f801..1bdd0a2e8 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -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;
+ }
+}
diff --git a/winsup/cygwin/mount.h b/winsup/cygwin/mount.h
index 0f0690a82..606e9f595 100644
--- a/winsup/cygwin/mount.h
+++ b/winsup/cygwin/mount.h
@@ -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