aboutsummaryrefslogtreecommitdiff
path: root/src/syscall
diff options
context:
space:
mode:
Diffstat (limited to 'src/syscall')
-rw-r--r--src/syscall/syscall_windows.go24
-rw-r--r--src/syscall/ztypes_windows.go1
2 files changed, 23 insertions, 2 deletions
diff --git a/src/syscall/syscall_windows.go b/src/syscall/syscall_windows.go
index e13d6e2dd5..f4f8f3ad09 100644
--- a/src/syscall/syscall_windows.go
+++ b/src/syscall/syscall_windows.go
@@ -1024,11 +1024,31 @@ func Readlink(path string, buf []byte) (n int, err error) {
case IO_REPARSE_TAG_SYMLINK:
data := (*symbolicLinkReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
- s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
+ s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
+ if data.Flags&_SYMLINK_FLAG_RELATIVE == 0 {
+ if len(s) >= 4 && s[:4] == `\??\` {
+ s = s[4:]
+ switch {
+ case len(s) >= 2 && s[1] == ':': // \??\C:\foo\bar
+ // do nothing
+ case len(s) >= 4 && s[:4] == `UNC\`: // \??\UNC\foo\bar
+ s = `\\` + s[4:]
+ default:
+ // unexpected; do nothing
+ }
+ } else {
+ // unexpected; do nothing
+ }
+ }
case _IO_REPARSE_TAG_MOUNT_POINT:
data := (*mountPointReparseBuffer)(unsafe.Pointer(&rdb.reparseBuffer))
p := (*[0xffff]uint16)(unsafe.Pointer(&data.PathBuffer[0]))
- s = UTF16ToString(p[data.PrintNameOffset/2 : (data.PrintNameLength-data.PrintNameOffset)/2])
+ s = UTF16ToString(p[data.SubstituteNameOffset/2 : (data.SubstituteNameOffset+data.SubstituteNameLength)/2])
+ if len(s) >= 4 && s[:4] == `\??\` { // \??\C:\foo\bar
+ s = s[4:]
+ } else {
+ // unexpected; do nothing
+ }
default:
// the path is not a symlink or junction but another type of reparse
// point
diff --git a/src/syscall/ztypes_windows.go b/src/syscall/ztypes_windows.go
index 8c2e19653a..1fb6f5c29f 100644
--- a/src/syscall/ztypes_windows.go
+++ b/src/syscall/ztypes_windows.go
@@ -1116,4 +1116,5 @@ const (
_IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
IO_REPARSE_TAG_SYMLINK = 0xA000000C
SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1
+ _SYMLINK_FLAG_RELATIVE = 1
)