From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: by sourceware.org (Postfix, from userid 2155) id 5F219385BF92; Thu, 2 Apr 2020 20:30:20 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 5F219385BF92 Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: Corinna Vinschen To: cygwin-cvs@sourceware.org Subject: [newlib-cygwin] Cygwin: symlinks: fix WSL symlinks pointing to /mnt X-Act-Checkin: newlib-cygwin X-Git-Author: Corinna Vinschen X-Git-Refname: refs/heads/master X-Git-Oldrev: 1171927f1a0073821d0b0266f9d8eff42742d1cf X-Git-Newrev: fb834beebe10c9dac33dacc657af29c4e136cd59 Message-Id: <20200402203020.5F219385BF92@sourceware.org> Date: Thu, 2 Apr 2020 20:30:20 +0000 (GMT) X-BeenThere: cygwin-cvs@cygwin.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Cygwin core component git logs List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 02 Apr 2020 20:30:20 -0000 https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=fb834beebe10c9dac33dacc657af29c4e136cd59 commit fb834beebe10c9dac33dacc657af29c4e136cd59 Author: Corinna Vinschen Date: Thu Apr 2 22:25:55 2020 +0200 Cygwin: symlinks: fix WSL symlinks pointing to /mnt Commit 4a36897af392 allowed to convert /mnt/ 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 Diff: --- winsup/cygwin/path.cc | 50 +++++++++++++++++++++++++++++++++++--------------- 1 file 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)