* 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.
This commit is contained in:
parent
3a03267d6d
commit
3a24189bba
|
@ -1,3 +1,19 @@
|
||||||
|
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>
|
2011-12-22 Corinna Vinschen <vinschen@redhat.com>
|
||||||
|
|
||||||
* fhandler_process.cc: Drop unneeded includes.
|
* fhandler_process.cc: Drop unneeded includes.
|
||||||
|
|
|
@ -528,6 +528,31 @@ cygwin_internal (cygwin_getinfo_types t, ...)
|
||||||
}
|
}
|
||||||
break;
|
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:
|
default:
|
||||||
set_errno (ENOSYS);
|
set_errno (ENOSYS);
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,6 +25,7 @@ details. */
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "cygtls.h"
|
#include "cygtls.h"
|
||||||
#include "pwdgrp.h"
|
#include "pwdgrp.h"
|
||||||
|
#include "mount.h"
|
||||||
#include "tls_pbuf.h"
|
#include "tls_pbuf.h"
|
||||||
#include <sys/param.h>
|
#include <sys/param.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
@ -541,169 +542,6 @@ format_process_winexename (void *data, char *&destbuf)
|
||||||
return len + 1;
|
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_info
|
||||||
{
|
{
|
||||||
struct heap
|
struct heap
|
||||||
|
|
|
@ -424,12 +424,13 @@ details. */
|
||||||
253: Export TIOCSCTTY, tcgetsid.
|
253: Export TIOCSCTTY, tcgetsid.
|
||||||
254: Export getgrouplist.
|
254: Export getgrouplist.
|
||||||
255: Export ptsname_r.
|
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 */
|
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
|
||||||
|
|
||||||
#define CYGWIN_VERSION_API_MAJOR 0
|
#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
|
/* There is also a compatibity version number associated with the
|
||||||
shared memory regions. It is incremented when incompatible
|
shared memory regions. It is incremented when incompatible
|
||||||
|
|
|
@ -137,7 +137,10 @@ typedef enum
|
||||||
CW_CVT_MNT_OPTS,
|
CW_CVT_MNT_OPTS,
|
||||||
CW_LST_MNT_OPTS,
|
CW_LST_MNT_OPTS,
|
||||||
CW_STRERROR,
|
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;
|
} cygwin_getinfo_types;
|
||||||
|
|
||||||
#define CW_LOCK_PINFO CW_LOCK_PINFO
|
#define CW_LOCK_PINFO CW_LOCK_PINFO
|
||||||
|
|
|
@ -1873,3 +1873,154 @@ endmntent (FILE *)
|
||||||
{
|
{
|
||||||
return 1;
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -197,4 +197,22 @@ class mount_info
|
||||||
|
|
||||||
int cygdrive_win32_path (const char *src, char *dst, int& unit);
|
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
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue