Skip to content

Commit

Permalink
hack on windows mount point enumeration
Browse files Browse the repository at this point in the history
  • Loading branch information
jeremyd2019 committed Feb 7, 2025
1 parent e5eb9ee commit 79a1e74
Show file tree
Hide file tree
Showing 4 changed files with 122 additions and 32 deletions.
7 changes: 7 additions & 0 deletions winsup/cygwin/cygtls.cc
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,13 @@ _cygtls::remove (DWORD wait)
CloseHandle (h);
}

/* Close handle and free memory used by getmntent */
if (locals.volumesearchhandle)
{
FindVolumeClose (locals.volumesearchhandle);
locals.volumesearchhandle = NULL;
free_local (volumemountpoints);
}
/* Close handle and free memory used by select. */
if (locals.select.sockevt)
{
Expand Down
6 changes: 4 additions & 2 deletions winsup/cygwin/fhandler/process.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1373,7 +1373,8 @@ format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)

/* Store old value of _my_tls.locals here. */
int iteration = _my_tls.locals.iteration;
unsigned available_drives = _my_tls.locals.available_drives;
//TODO
//unsigned available_drives = _my_tls.locals.available_drives;
/* This reinitializes the above values in _my_tls. */
setmntent (NULL, NULL);
/* Restore iteration immediately since it's not used below. We use the
Expand Down Expand Up @@ -1447,7 +1448,8 @@ format_process_mountstuff (void *data, char *&destbuf, bool mountinfo)
}

/* Restore available_drives */
_my_tls.locals.available_drives = available_drives;
//TODO
//_my_tls.locals.available_drives = available_drives;

if (u_hdl) /* Only not-NULL if open_shared has been called. */
{
Expand Down
9 changes: 6 additions & 3 deletions winsup/cygwin/local_includes/cygtls.h
Original file line number Diff line number Diff line change
Expand Up @@ -93,10 +93,13 @@ struct _local_storage
int dl_error;
char dl_buffer[256];

/* path.cc */
/* mount.cc */
struct mntent mntbuf;
int iteration;
unsigned available_drives;
int volumemountpointoffset;
HANDLE volumesearchhandle;
WCHAR *volumemountpoints; // note: malloced
DWORD volumemountpointslen;
char mnt_type[80];
char mnt_opts[80];
char mnt_fsname[CYG_MAX_PATH];
Expand Down Expand Up @@ -181,7 +184,7 @@ class _cygtls
siginfo_t *sigwait_info;
HANDLE signal_arrived;
bool will_wait_for_signal;
#if 1
#if 0
long __align; /* Needed to align context to 16 byte. */
#endif
/* context MUST be aligned to 16 byte, otherwise RtlCaptureContext fails.
Expand Down
132 changes: 105 additions & 27 deletions winsup/cygwin/mount.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1786,9 +1786,10 @@ fillout_mntent (const char *native_path, const char *posix_path, unsigned flags)
/* Remove drivenum from list if we see a x: style path */
if (strlen (native_path) == 2 && native_path[1] == ':')
{
int drivenum = cyg_tolower (native_path[0]) - 'a';
// TODO
/*int drivenum = cyg_tolower (native_path[0]) - 'a';
if (drivenum >= 0 && drivenum <= 31)
_my_tls.locals.available_drives &= ~(1 << drivenum);
_my_tls.locals.available_drives &= ~(1 << drivenum);*/
append_bs = true;
}

Expand Down Expand Up @@ -1885,30 +1886,115 @@ mount_item::getmntent ()
static struct mntent *
cygdrive_getmntent ()
{
char native_path[4];
char posix_path[CYG_MAX_PATH];
DWORD mask = 1, drive = 'a';
struct mntent *ret = NULL;
WCHAR volumename[64];
volumename[0] = L'\0';
if (!_my_tls.locals.volumesearchhandle)
{
_my_tls.locals.volumesearchhandle = FindFirstVolumeW (volumename,
sizeof (volumename) / sizeof (WCHAR));
if (_my_tls.locals.volumesearchhandle == INVALID_HANDLE_VALUE)
{
__seterrno();
_my_tls.locals.volumesearchhandle = NULL;
return NULL;
}
}

while (_my_tls.locals.available_drives)
if (!_my_tls.locals.volumemountpoints)
{
for (/* nothing */; drive <= 'z'; mask <<= 1, drive++)
if (_my_tls.locals.available_drives & mask)
break;
_my_tls.locals.volumemountpoints = (WCHAR *) malloc (NT_MAX_PATH * sizeof (WCHAR));
_my_tls.locals.volumemountpoints[0] = L'\0';
_my_tls.locals.volumemountpointoffset = 0;
_my_tls.locals.volumemountpointslen = NT_MAX_PATH;
}

__small_sprintf (native_path, "%c:\\", cyg_toupper (drive));
if (GetFileAttributes (native_path) == INVALID_FILE_ATTRIBUTES)
if (!_my_tls.locals.volumemountpoints[_my_tls.locals.volumemountpointoffset])
{
if (!volumename[0] &&
!FindNextVolumeW (_my_tls.locals.volumesearchhandle, volumename,
sizeof (volumename) / sizeof (WCHAR)))
{
_my_tls.locals.available_drives &= ~mask;
continue;
DWORD le = GetLastError ();
if (_my_tls.locals.volumesearchhandle)
{
FindVolumeClose (_my_tls.locals.volumesearchhandle);
_my_tls.locals.volumesearchhandle = NULL;
}
if (_my_tls.locals.volumemountpoints)
{
free (_my_tls.locals.volumemountpoints);
_my_tls.locals.volumemountpoints = NULL;
}

__seterrno_from_win_error (le);
return NULL;
}

WCHAR *volumemountpoints = _my_tls.locals.volumemountpoints;
DWORD volumemountpointslen = _my_tls.locals.volumemountpointslen;
BOOL success;
while (!(success = GetVolumePathNamesForVolumeNameW (volumename,
volumemountpoints, volumemountpointslen,
&volumemountpointslen)) &&
GetLastError () == ERROR_MORE_DATA &&
(volumemountpoints = (WCHAR *) realloc (volumemountpoints,
volumemountpointslen * sizeof (WCHAR))))
{
_my_tls.locals.volumemountpoints = volumemountpoints;
_my_tls.locals.volumemountpointslen = volumemountpointslen;
}

if (!volumemountpoints)
{
if (_my_tls.locals.volumesearchhandle)
{
FindVolumeClose (_my_tls.locals.volumesearchhandle);
_my_tls.locals.volumesearchhandle = NULL;
}
if (_my_tls.locals.volumemountpoints)
{
free (_my_tls.locals.volumemountpoints);
_my_tls.locals.volumemountpoints = NULL;
}

set_errno (ENOMEM);
return NULL;
}

_my_tls.locals.volumemountpointoffset = 0;
if (!success)
{
DWORD le = GetLastError ();
if (_my_tls.locals.volumesearchhandle)
{
FindVolumeClose (_my_tls.locals.volumesearchhandle);
_my_tls.locals.volumesearchhandle = NULL;
}
if (_my_tls.locals.volumemountpoints)
{
free (_my_tls.locals.volumemountpoints);
_my_tls.locals.volumemountpoints = NULL;
}

if (le != ERROR_NO_MORE_FILES)
__seterrno_from_win_error (le);
return NULL;
}
native_path[2] = '\0';
__small_sprintf (posix_path, "%s%c", mount_table->cygdrive, drive);
ret = fillout_mntent (native_path, posix_path, mount_table->cygdrive_flags);
break;
}

return ret;

UNICODE_STRING uc;
uc.Buffer = _my_tls.locals.volumemountpoints +
_my_tls.locals.volumemountpointoffset;
uc.Length = wcslen (uc.Buffer);
uc.MaximumLength = uc.Length;

_my_tls.locals.volumemountpointoffset += uc.Length + 1;

path_conv pc;
pc.check (&uc, PC_SYM_NOFOLLOW | PC_POSIX | PC_NO_ACCESS_CHECK);

return fillout_mntent (pc.get_win32 (), pc.get_posix (), mount_table->cygdrive_flags);
}

struct mntent *
Expand Down Expand Up @@ -2081,14 +2167,6 @@ extern "C" FILE *
setmntent (const char *filep, const char *)
{
_my_tls.locals.iteration = 0;
_my_tls.locals.available_drives = GetLogicalDrives ();
/* Filter floppy drives on A: and B: */
if ((_my_tls.locals.available_drives & 1)
&& get_disk_type (L"A:") == DT_FLOPPY)
_my_tls.locals.available_drives &= ~1;
if ((_my_tls.locals.available_drives & 2)
&& get_disk_type (L"B:") == DT_FLOPPY)
_my_tls.locals.available_drives &= ~2;
return (FILE *) filep;
}

Expand Down

0 comments on commit 79a1e74

Please sign in to comment.