diff options
author | Corinna Vinschen <corinna@vinschen.de> | 2020-04-02 22:25:55 +0200 |
---|---|---|
committer | Corinna Vinschen <corinna@vinschen.de> | 2020-04-02 22:25:55 +0200 |
commit | fb834beebe10c9dac33dacc657af29c4e136cd59 (patch) | |
tree | a5d07394d54d5220842228e57f672eaed5956d3f | |
parent | 1171927f1a0073821d0b0266f9d8eff42742d1cf (diff) | |
download | cygnal-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.cc | 50 |
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) |