mirror of
https://github.com/rwinkhart/sys.git
synced 2026-08-28 04:46:44 -04:00
windows: change Readlink to handle junction
Related issue golang/go#10150 Change-Id: I38e3e13238624655bb828d501bc865ff8a4312e9 Reviewed-on: https://go-review.googlesource.com/7493 Reviewed-by: Alex Brainman <alex.brainman@gmail.com>
This commit is contained in:
committed by
Alex Brainman
parent
d008cdcf32
commit
61f8ff32f5
@@ -962,13 +962,22 @@ func Readlink(path string, buf []byte) (n int, err error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
|
rdb := (*reparseDataBuffer)(unsafe.Pointer(&rdbbuf[0]))
|
||||||
if uintptr(bytesReturned) < unsafe.Sizeof(*rdb) ||
|
var s string
|
||||||
rdb.ReparseTag != IO_REPARSE_TAG_SYMLINK {
|
switch rdb.ReparseTag {
|
||||||
// the path is not a symlink but another type of reparse point
|
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])
|
||||||
|
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])
|
||||||
|
default:
|
||||||
|
// the path is not a symlink or junction but another type of reparse
|
||||||
|
// point
|
||||||
return -1, syscall.ENOENT
|
return -1, syscall.ENOENT
|
||||||
}
|
}
|
||||||
|
|
||||||
s := UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(&rdb.PathBuffer[0]))[:rdb.PrintNameLength/2])
|
|
||||||
n = copy(buf, []byte(s))
|
n = copy(buf, []byte(s))
|
||||||
|
|
||||||
return n, nil
|
return n, nil
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1089,12 +1089,7 @@ type TCPKeepalive struct {
|
|||||||
Interval uint32
|
Interval uint32
|
||||||
}
|
}
|
||||||
|
|
||||||
type reparseDataBuffer struct {
|
type symbolicLinkReparseBuffer struct {
|
||||||
ReparseTag uint32
|
|
||||||
ReparseDataLength uint16
|
|
||||||
Reserved uint16
|
|
||||||
|
|
||||||
// SymbolicLinkReparseBuffer
|
|
||||||
SubstituteNameOffset uint16
|
SubstituteNameOffset uint16
|
||||||
SubstituteNameLength uint16
|
SubstituteNameLength uint16
|
||||||
PrintNameOffset uint16
|
PrintNameOffset uint16
|
||||||
@@ -1103,9 +1098,27 @@ type reparseDataBuffer struct {
|
|||||||
PathBuffer [1]uint16
|
PathBuffer [1]uint16
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type mountPointReparseBuffer struct {
|
||||||
|
SubstituteNameOffset uint16
|
||||||
|
SubstituteNameLength uint16
|
||||||
|
PrintNameOffset uint16
|
||||||
|
PrintNameLength uint16
|
||||||
|
PathBuffer [1]uint16
|
||||||
|
}
|
||||||
|
|
||||||
|
type reparseDataBuffer struct {
|
||||||
|
ReparseTag uint32
|
||||||
|
ReparseDataLength uint16
|
||||||
|
Reserved uint16
|
||||||
|
|
||||||
|
// GenericReparseBuffer
|
||||||
|
reparseBuffer byte
|
||||||
|
}
|
||||||
|
|
||||||
const (
|
const (
|
||||||
FSCTL_GET_REPARSE_POINT = 0x900A8
|
FSCTL_GET_REPARSE_POINT = 0x900A8
|
||||||
MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
|
MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
|
||||||
|
IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
|
||||||
IO_REPARSE_TAG_SYMLINK = 0xA000000C
|
IO_REPARSE_TAG_SYMLINK = 0xA000000C
|
||||||
SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1
|
SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1
|
||||||
)
|
)
|
||||||
|
|||||||
Reference in New Issue
Block a user