aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRon Yorston <rmy@pobox.com>2022-06-25 13:04:46 +0100
committerRon Yorston <rmy@pobox.com>2022-06-25 13:04:46 +0100
commit164a4253b1b16f3923b175f425074ef2d1b04377 (patch)
tree9351bf5f4ba6e793180aa97bff6001bf70ee05c1
parent6c19fb9008e2dcd7a2d4ce42f618ec2079b1230f (diff)
downloadbusybox-w32-164a4253b1b16f3923b175f425074ef2d1b04377.tar.gz
busybox-w32-164a4253b1b16f3923b175f425074ef2d1b04377.tar.bz2
busybox-w32-164a4253b1b16f3923b175f425074ef2d1b04377.zip
Workaround for incomplete junctions created by PowerShell
Scoop uses PowerShell's New-Item to create junctions. However, these junctions lack a PrintName. This is a known issue which has caused problems even for Windows' File Explorer: https://github.com/PowerShell/PowerShell/issues/12923 Revert commit 32de287bb (win32: code shrink readlink(2)) to that readlink(2) uses SubstituteName instead. (GitHub issue #261)
-rw-r--r--win32/mingw.c44
1 files changed, 32 insertions, 12 deletions
diff --git a/win32/mingw.c b/win32/mingw.c
index 72165cdd7..d26f9f2ff 100644
--- a/win32/mingw.c
+++ b/win32/mingw.c
@@ -1533,6 +1533,30 @@ char *realpath(const char *path, char *resolved_path)
1533 return NULL; 1533 return NULL;
1534} 1534}
1535 1535
1536static wchar_t *normalize_ntpath(wchar_t *wbuf)
1537{
1538 int i;
1539 /* fix absolute path prefixes */
1540 if (wbuf[0] == '\\') {
1541 /* strip NT namespace prefixes */
1542 if (!wcsncmp(wbuf, L"\\??\\", 4) ||
1543 !wcsncmp(wbuf, L"\\\\?\\", 4))
1544 wbuf += 4;
1545 else if (!wcsnicmp(wbuf, L"\\DosDevices\\", 12))
1546 wbuf += 12;
1547 /* replace remaining '...UNC\' with '\\' */
1548 if (!wcsnicmp(wbuf, L"UNC\\", 4)) {
1549 wbuf += 2;
1550 *wbuf = '\\';
1551 }
1552 }
1553 /* convert backslashes to slashes */
1554 for (i = 0; wbuf[i]; i++)
1555 if (wbuf[i] == '\\')
1556 wbuf[i] = '/';
1557 return wbuf;
1558}
1559
1536#define SRPB rptr->SymbolicLinkReparseBuffer 1560#define SRPB rptr->SymbolicLinkReparseBuffer
1537ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) 1561ssize_t readlink(const char *pathname, char *buf, size_t bufsiz)
1538{ 1562{
@@ -1553,25 +1577,21 @@ ssize_t readlink(const char *pathname, char *buf, size_t bufsiz)
1553 CloseHandle(h); 1577 CloseHandle(h);
1554 1578
1555 if (status && rptr->ReparseTag == IO_REPARSE_TAG_SYMLINK) { 1579 if (status && rptr->ReparseTag == IO_REPARSE_TAG_SYMLINK) {
1556 len = SRPB.PrintNameLength/sizeof(WCHAR); 1580 len = SRPB.SubstituteNameLength/sizeof(WCHAR);
1557 name = SRPB.PathBuffer + SRPB.PrintNameOffset/sizeof(WCHAR); 1581 name = SRPB.PathBuffer + SRPB.SubstituteNameOffset/sizeof(WCHAR);
1558 } else if (status && rptr->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) { 1582 } else if (status && rptr->ReparseTag == IO_REPARSE_TAG_MOUNT_POINT) {
1559 len = MRPB.PrintNameLength/sizeof(WCHAR); 1583 len = MRPB.SubstituteNameLength/sizeof(WCHAR);
1560 name = MRPB.PathBuffer + MRPB.PrintNameOffset/sizeof(WCHAR); 1584 name = MRPB.PathBuffer + MRPB.SubstituteNameOffset/sizeof(WCHAR);
1561 } 1585 }
1562 1586
1563 if (name) { 1587 if (name) {
1588 name[len] = 0;
1589 name = normalize_ntpath(name);
1590 len = wcslen(name);
1564 if (len > bufsiz) 1591 if (len > bufsiz)
1565 len = bufsiz; 1592 len = bufsiz;
1566 len = WideCharToMultiByte(CP_ACP, 0, name, len, buf, bufsiz, 0, 0); 1593 if (WideCharToMultiByte(CP_ACP, 0, name, len, buf, bufsiz, 0, 0))
1567 if (len) {
1568 int i;
1569
1570 for (i = 0; i < len; i++)
1571 if (buf[i] == '\\')
1572 buf[i] = '/';
1573 return len; 1594 return len;
1574 }
1575 } 1595 }
1576 } 1596 }
1577 errno = err_win_to_posix(); 1597 errno = err_win_to_posix();