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 8, 2025
1 parent e5eb9ee commit cd244c9
Show file tree
Hide file tree
Showing 5 changed files with 116 additions and 34 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
1 change: 1 addition & 0 deletions winsup/cygwin/local_includes/mount.h
Original file line number Diff line number Diff line change
Expand Up @@ -217,6 +217,7 @@ class mount_info
bool from_fstab (bool user, WCHAR [], PWCHAR);

int cygdrive_win32_path (const char *src, char *dst, int& unit);
struct mntent *cygdrive_getmntent ();
};

class dos_drive_mappings
Expand Down
127 changes: 98 additions & 29 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 @@ -1882,33 +1883,109 @@ mount_item::getmntent ()
return fillout_mntent (native_path, posix_path, flags);
}

static struct mntent *
cygdrive_getmntent ()
struct mntent *
mount_info::cygdrive_getmntent ()
{
char native_path[4];
char posix_path[CYG_MAX_PATH];
DWORD mask = 1, drive = 'a';
struct mntent *ret = NULL;
tmp_pathbuf tp;
char *win32_path, *posix_path;
DWORD endpos;
int err;
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;
goto cleanup;
}
}

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)
while (!_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;
__seterrno ();
goto cleanup;
}

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)
{
set_errno (ENOMEM);
goto cleanup;
}
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;

if (!success)
{
if (GetLastError () != ERROR_NO_MORE_FILES)
__seterrno ();
goto cleanup;
}

_my_tls.locals.volumemountpointoffset = 0;
volumename[0] = L'\0';
}

return ret;
endpos = _my_tls.locals.volumemountpointoffset +
wcslen (_my_tls.locals.volumemountpoints +
_my_tls.locals.volumemountpointoffset);
if (_my_tls.locals.volumemountpoints[endpos - 1] == L'\\')
_my_tls.locals.volumemountpoints[endpos - 1] = L'\0';
win32_path = tp.c_get ();
sys_wcstombs (win32_path, NT_MAX_PATH, _my_tls.locals.volumemountpoints +
_my_tls.locals.volumemountpointoffset);
_my_tls.locals.volumemountpointoffset = endpos + 1;

posix_path = tp.c_get ();
if ((err = conv_to_posix_path(win32_path, posix_path, 0)))
{
set_errno (err);
goto cleanup;
}

return fillout_mntent (win32_path, posix_path, cygdrive_flags);

cleanup:
save_errno errno_saver;

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;
}
return NULL;
}

struct mntent *
Expand Down Expand Up @@ -2081,14 +2158,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 cd244c9

Please sign in to comment.