mirror of
git://sourceware.org/git/newlib-cygwin.git
synced 2025-02-28 20:15:24 +08:00
Cygwin: fhandler_netdrive: fix character conversion required for NFS shares
While filenames on NFS shares are converted internally to a widechar representation of the input bytes treated as the default system ANSI codepage (CP_ACP), this doesn't hold for share names. The names returned by WNetEnumResourceW are just the original bytes dropped verbatim into WCHAR. The original conversion from 7db1c6fc4e2a ("Cygwin: //server: revert to using WNet and support NFS shares") was erroneous in that it treated the bytes as ISO-8859-1, not as CP_ACP codepoints. Fix the conversion to convert from CP_ACP to widechar. Use a tmp_pathbuf buffer for the new widechar string instead of malloc/free. Extend the comment, better explaining the encoding difference between files and shares. Fixes: 7db1c6fc4e2a ("Cygwin: //server: revert to using WNet and support NFS shares") Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
This commit is contained in:
parent
dc094c7665
commit
d4a5c2be8b
@ -317,6 +317,7 @@ thread_netdrive_wnet (void *arg)
|
|||||||
size_t entry_cache_size = DIR_cache.count ();
|
size_t entry_cache_size = DIR_cache.count ();
|
||||||
WCHAR provider[256], *dummy = NULL;
|
WCHAR provider[256], *dummy = NULL;
|
||||||
wchar_t srv_name[CYG_MAX_PATH];
|
wchar_t srv_name[CYG_MAX_PATH];
|
||||||
|
wchar_t *nfs_namebuf = NULL;
|
||||||
NETRESOURCEW nri = { 0 };
|
NETRESOURCEW nri = { 0 };
|
||||||
LPNETRESOURCEW nro;
|
LPNETRESOURCEW nro;
|
||||||
NETINFOSTRUCT netinfo;
|
NETINFOSTRUCT netinfo;
|
||||||
@ -397,6 +398,10 @@ thread_netdrive_wnet (void *arg)
|
|||||||
ndi->err = ENOENT;
|
ndi->err = ENOENT;
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
/* We need a temporary buffer for the multibyte to widechar conversion
|
||||||
|
only required for NFS shares. */
|
||||||
|
if (!nfs_namebuf)
|
||||||
|
nfs_namebuf = tp.w_get ();
|
||||||
break;
|
break;
|
||||||
case WNNC_NET_DAV:
|
case WNNC_NET_DAV:
|
||||||
/* WebDAV enumeration isn't supported, by the provider, but we can
|
/* WebDAV enumeration isn't supported, by the provider, but we can
|
||||||
@ -447,19 +452,21 @@ thread_netdrive_wnet (void *arg)
|
|||||||
|
|
||||||
if (net_type == WNNC_NET_MS_NFS)
|
if (net_type == WNNC_NET_MS_NFS)
|
||||||
{
|
{
|
||||||
wchar_t *nm = name;
|
/* With MS NFS, the bytes of the share name on the remote side
|
||||||
/* Convert from "ANSI embedded in widechar" to multibyte and convert
|
are simply dropped into a WCHAR buffer without conversion to
|
||||||
back to widechar. */
|
Unicode. So convert from "multibyte embedded in widechar" to
|
||||||
|
real multibyte and then convert back to widechar here.
|
||||||
|
|
||||||
|
Quirky: This conversion is already performed for files on an
|
||||||
|
MS NFS filesystem when calling NtQueryDirectoryFile, but it's
|
||||||
|
not performed on the strings returned by WNetEnumResourceW. */
|
||||||
char mbname[wcslen (name) + 1];
|
char mbname[wcslen (name) + 1];
|
||||||
char *mb = mbname;
|
char *mb = mbname;
|
||||||
while ((*mb++ = *nm++))
|
while ((*mb++ = *name++))
|
||||||
;
|
;
|
||||||
sys_mbstowcs_alloc (&name, HEAP_NOTHEAP, mbname);
|
|
||||||
if (!name)
|
name = nfs_namebuf;
|
||||||
{
|
MultiByteToWideChar (CP_ACP, 0, mbname, -1, name, NT_MAX_PATH);
|
||||||
ndi->err = ENOMEM;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
/* Some providers have deep links so convert embedded '\\' to '/' here */
|
/* Some providers have deep links so convert embedded '\\' to '/' here */
|
||||||
for (wchar_t *bs = name; (bs = wcschr (bs, L'\\')); *bs++ = L'/')
|
for (wchar_t *bs = name; (bs = wcschr (bs, L'\\')); *bs++ = L'/')
|
||||||
@ -470,8 +477,6 @@ thread_netdrive_wnet (void *arg)
|
|||||||
break;
|
break;
|
||||||
if (cache_idx >= entry_cache_size)
|
if (cache_idx >= entry_cache_size)
|
||||||
DIR_cache.add (name);
|
DIR_cache.add (name);
|
||||||
if (net_type == WNNC_NET_MS_NFS)
|
|
||||||
free (name);
|
|
||||||
}
|
}
|
||||||
out:
|
out:
|
||||||
if (dom)
|
if (dom)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user