mirror of
https://github.com/rwinkhart/sys.git
synced 2026-08-27 20:36:31 -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]))
|
||||
if uintptr(bytesReturned) < unsafe.Sizeof(*rdb) ||
|
||||
rdb.ReparseTag != IO_REPARSE_TAG_SYMLINK {
|
||||
// the path is not a symlink but another type of reparse point
|
||||
var s string
|
||||
switch rdb.ReparseTag {
|
||||
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
|
||||
}
|
||||
|
||||
s := UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(&rdb.PathBuffer[0]))[:rdb.PrintNameLength/2])
|
||||
n = copy(buf, []byte(s))
|
||||
|
||||
return n, nil
|
||||
}
|
||||
|
||||
@@ -1089,12 +1089,7 @@ type TCPKeepalive struct {
|
||||
Interval uint32
|
||||
}
|
||||
|
||||
type reparseDataBuffer struct {
|
||||
ReparseTag uint32
|
||||
ReparseDataLength uint16
|
||||
Reserved uint16
|
||||
|
||||
// SymbolicLinkReparseBuffer
|
||||
type symbolicLinkReparseBuffer struct {
|
||||
SubstituteNameOffset uint16
|
||||
SubstituteNameLength uint16
|
||||
PrintNameOffset uint16
|
||||
@@ -1103,9 +1098,27 @@ type reparseDataBuffer struct {
|
||||
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 (
|
||||
FSCTL_GET_REPARSE_POINT = 0x900A8
|
||||
MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16 * 1024
|
||||
IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003
|
||||
IO_REPARSE_TAG_SYMLINK = 0xA000000C
|
||||
SYMBOLIC_LINK_FLAG_DIRECTORY = 0x1
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user