Does this patch cover global mounts, i.e. SMB mounted by user LocalSystem on a driver letter are visible to ALL users. Local users logons can override the same drive letter via per-user net use
Example: LocalSystem mounts H: to \\homeserver\disk4\users, this is visible to all users in a system User "lionel" mounts H: to \\lionelsserver\data\homedir, this is visible to the current Logon session Lionel On Tue, 18 Feb 2025 at 22:25, Jeremy Drake via Cygwin-patches <cygwin-patches@cygwin.com> wrote: > > After migrating from GetLogicalDrives to Find(First|Next)VolumeW, mapped > network drives no longer showed up in getmntent output. To fix that, > also iterate GetLogicalDriveStringsW when builing dos_drive_mappings, > and merge with volume mounts (skipping any volume mounts that are just > mounted on the root of a drive, and replacing the dos mounts in the > mapping for a volume which is mounted on both a drive root and a > directory). > > Fixes: 04a5b072940cc ("Cygwin: expose all windows volume mount points.") > Addresses: https://cygwin.com/pipermail/cygwin/2025-February/257384.html > Signed-off-by: Jeremy Drake <cyg...@jdrake.com> > --- > > This was generated on top of the patch > https://cygwin.com/pipermail/cygwin-patches/2025q1/013390.html but should > be able to be applied without it. > > winsup/cygwin/mount.cc | 145 ++++++++++++++++++++++++++++++++--------- > 1 file changed, 113 insertions(+), 32 deletions(-) > > diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc > index a3d9e5bd0f..68414f13af 100644 > --- a/winsup/cygwin/mount.cc > +++ b/winsup/cygwin/mount.cc > @@ -1995,6 +1995,40 @@ endmntent (FILE *) > return 1; > } > > +static bool > +resolve_dos_device (const wchar_t *dosname, wchar_t *devpath) > +{ > + if (QueryDosDeviceW (dosname, 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'; > + } > + return true; > + } > + return false; > +} > + > dos_drive_mappings::dos_drive_mappings () > : mappings(0) > , cur_mapping(0) > @@ -2004,6 +2038,44 @@ dos_drive_mappings::dos_drive_mappings () > wchar_t vol[64]; /* Long enough for Volume GUID string */ > wchar_t *devpath = tp.w_get (); > wchar_t *mounts = tp.w_get (); > + mapping **nextm = &mappings; > + mapping *endfirstloop = NULL; > + DWORD len; > + > + /* Iterate over all drive letters, fetch the DOS device path */ > + if (!(len = GetLogicalDriveStringsW (NT_MAX_PATH - 1, mounts)) || > + len >= NT_MAX_PATH) > + debug_printf ("GetLogicalDriveStringsW, %E"); > + else { > + for (wchar_t *mount = mounts; *mount; mount += len + 2) > + { > + len = wcslen (mount); > + mount[--len] = L'\0'; /* Drop trailing backslash */ > + if (resolve_dos_device (mount, devpath)) > + { > + mapping *m = new mapping (); > + if (m) > + { > + m->dos.path = wcsdup (mount); > + m->ntdevpath = wcsdup (devpath); > + if (!m->dos.path || !m->ntdevpath) > + { > + free (m->dos.path); > + free (m->ntdevpath); > + delete m; > + continue; > + } > + m->dos.len = len; > + m->ntlen = wcslen (m->ntdevpath); > + *nextm = endfirstloop = m; > + nextm = &m->next; > + } > + } > + else > + debug_printf ("Unable to determine the native mapping for %ls " > + "(error %E)", mount); > + } > + } > > /* Iterate over all volumes, fetch the list of DOS paths the volume is > mounted to. */ > @@ -2011,43 +2083,22 @@ dos_drive_mappings::dos_drive_mappings () > if (sh == INVALID_HANDLE_VALUE) > debug_printf ("FindFirstVolumeW, %E"); > else { > - mapping **nextm = &mappings; > do > { > - /* Skip drives which are not mounted. */ > - DWORD len; > + /* Skip volumes which are not mounted. */ > if (!GetVolumePathNamesForVolumeNameW (vol, mounts, NT_MAX_PATH, &len) > || mounts[0] == L'\0') > continue; > + /* Skip volumes which are only mounted to the root of a drive letter: > + they were handled in the loop above */ > + if (len == 5 && mounts[1] == L':' && mounts[2] == L'\\' && !mounts[3]) > + continue; > + > *wcsrchr (vol, L'\\') = L'\0'; > - if (QueryDosDeviceW (vol + 4, devpath, NT_MAX_PATH)) > + if (resolve_dos_device (vol + 4, devpath)) > { > - /* 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 (); > + bool hadrootmount = false; > if (m) > { > /* store mount point list */ > @@ -2072,15 +2123,45 @@ dos_drive_mappings::dos_drive_mappings () > dos->path = mount; > dos->len = wcslen (dos->path); > dos->path[--dos->len] = L'\0'; /* Drop trailing backslash > */ > + if (dos->len == 2 && dos->path[1] == L':') > + hadrootmount = true; > } > m->ntlen = wcslen (m->ntdevpath); > - *nextm = m; > - nextm = &m->next; > + if (hadrootmount) > + { > + /* This device has already been added to the mappings list > + in the first loop above, but with only the drive root > + mount. Find that entry and replace it with the complete > + list of mounts. */ > + hadrootmount = false; > + for (mapping *m2 = mappings; > + endfirstloop && m2 != endfirstloop->next; > + m2 = m2->next) > + { > + if (m->ntlen == m2->ntlen && > + !wcscmp (m->ntdevpath, m2->ntdevpath)) > + { > + free (m2->dos.path); > + m2->dos.next = m->dos.next; > + m2->dos.path = m->dos.path; > + m2->dos.len = m->dos.len; > + free (m->ntdevpath); > + delete m; > + hadrootmount = true; > + break; > + } > + } > + } > + if (!hadrootmount) > + { > + *nextm = m; > + nextm = &m->next; > + } > } > } > else > debug_printf ("Unable to determine the native mapping for %ls " > - "(error %u)", vol, GetLastError ()); > + "(error %E)", vol); > } > while (FindNextVolumeW (sh, vol, 64)); > FindVolumeClose (sh); > -- > 2.48.1.windows.1 > -- Lionel