summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorCorinna Vinschen <corinna@vinschen.de>2020-04-02 22:25:55 +0200
committerCorinna Vinschen <corinna@vinschen.de>2020-04-02 22:25:55 +0200
commitfb834beebe10c9dac33dacc657af29c4e136cd59 (patch)
treea5d07394d54d5220842228e57f672eaed5956d3f
parent1171927f1a0073821d0b0266f9d8eff42742d1cf (diff)
downloadcygnal-fb834beebe10c9dac33dacc657af29c4e136cd59.tar.gz
cygnal-fb834beebe10c9dac33dacc657af29c4e136cd59.tar.bz2
cygnal-fb834beebe10c9dac33dacc657af29c4e136cd59.zip
Cygwin: symlinks: fix WSL symlinks pointing to /mnt
Commit 4a36897af392 allowed to convert /mnt/<drive> path prefixes to Cygwin cygdrive prefixes on the fly. However, the patch neglected WSL symlinks pointing to the /mnt directory. Rearrange path conversion so /mnt is converted to the cygdrive prefix path itself. Signed-off-by: Corinna Vinschen <corinna@vinschen.de>
-rw-r--r--winsup/cygwin/path.cc50
1 files changed, 35 insertions, 15 deletions
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 7fa2bc5b5..7d9d61fcd 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -2466,32 +2466,52 @@ check_reparse_point_target (HANDLE h, bool remote, PREPARSE_DATA_BUFFER rp,
PREPARSE_LX_SYMLINK_BUFFER rpl = (PREPARSE_LX_SYMLINK_BUFFER) rp;
char *path_buf = rpl->LxSymlinkReparseBuffer.PathBuffer;
DWORD path_len = rpl->ReparseDataLength - sizeof (DWORD);
+ bool full_path = false;
+ const size_t drv_prefix_len = strlen ("/mnt");
PBYTE utf16_ptr;
PWCHAR utf16_buf;
int utf16_bufsize;
- bool full_path = false;
- const size_t drv_prefix_len = strlen ("/mnt");
+ /* 0-terminate path_buf for easier testing. */
+ path_buf[path_len] = '\0';
+ if (path_prefix_p ("/mnt", path_buf, drv_prefix_len, false))
+ {
+ size_t len = strlen (path_buf);
+
+ if (len <= drv_prefix_len + 1)
+ {
+ /* /mnt or /mnt/. Replace with cygdrive prefix. */
+ stpcpy (path_buf, mount_table->cygdrive);
+ path_len = mount_table->cygdrive_len;
+ if (len == drv_prefix_len)
+ {
+ path_buf[mount_table->cygdrive_len - 1] = '\0';
+ --path_len;
+ }
+ rp->ReparseDataLength = path_len + sizeof (DWORD);
+ }
+ else if (islower (path_buf[drv_prefix_len + 1])
+ && (path_len == drv_prefix_len + 2
+ || path_buf[drv_prefix_len + 2] == '/'))
+ {
+ /* Skip forward to the slash leading the drive letter.
+ That leaves room for adding the colon. */
+ path_buf += drv_prefix_len;
+ path_len -= drv_prefix_len;
+ full_path = true;
+ }
+ }
/* Compute buffer for path converted to UTF-16. */
utf16_ptr = (PBYTE) rpl + sizeof (REPARSE_LX_SYMLINK_BUFFER)
+ rp->ReparseDataLength;
+ /* Skip \0-termination added above. */
+ ++utf16_ptr;
+ /* Make sure pointer is aligned */
while ((intptr_t) utf16_ptr % sizeof (WCHAR))
++utf16_ptr;
utf16_buf = (PWCHAR) utf16_ptr;
utf16_bufsize = NT_MAX_PATH - (utf16_buf - (PWCHAR) rpl);
- /* Check for abs path /mnt/x. Convert to x: after conversion to UTF-16. */
- if (path_len >= drv_prefix_len + 2
- && !strncmp (path_buf, "/mnt/", drv_prefix_len + 1)
- && islower (path_buf[drv_prefix_len + 1])
- && (path_len == drv_prefix_len + 2
- || path_buf[drv_prefix_len + 2] == '/'))
- {
- /* Skip forward to the slash leading the drive letter. That leaves
- room for adding the colon. */
- path_buf += drv_prefix_len;
- path_len -= drv_prefix_len;
- full_path = true;
- }
+ /* Now convert path to UTF-16. */
utf16_bufsize = MultiByteToWideChar (CP_UTF8, 0, path_buf, path_len,
utf16_buf, utf16_bufsize);
if (utf16_bufsize)