diff options
author | Ron Yorston <rmy@pobox.com> | 2022-06-25 13:04:46 +0100 |
---|---|---|
committer | Ron Yorston <rmy@pobox.com> | 2022-06-25 13:04:46 +0100 |
commit | 164a4253b1b16f3923b175f425074ef2d1b04377 (patch) | |
tree | 9351bf5f4ba6e793180aa97bff6001bf70ee05c1 | |
parent | 6c19fb9008e2dcd7a2d4ce42f618ec2079b1230f (diff) | |
download | busybox-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.c | 44 |
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 | ||
1536 | static 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 |
1537 | ssize_t readlink(const char *pathname, char *buf, size_t bufsiz) | 1561 | ssize_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(); |