// Copyright 2016 The Go Authors. All rights reserved. // Use of this source code is governed by a BSD-style // license that can be found in the LICENSE file. package windows import ( "syscall" "unsafe" ) const ( FSCTL_SET_REPARSE_POINT = 0x000900A4 IO_REPARSE_TAG_MOUNT_POINT = 0xA0000003 IO_REPARSE_TAG_DEDUP = 0x80000013 SYMLINK_FLAG_RELATIVE = 1 ) // These structures are described // in https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/ca069dad-ed16-42aa-b057-b6b207f447cc // and https://learn.microsoft.com/en-us/openspecs/windows_protocols/ms-fscc/b41f1cbf-10df-4a47-98d4-1c52a833d913. type REPARSE_DATA_BUFFER struct { ReparseTag uint32 ReparseDataLength uint16 Reserved uint16 DUMMYUNIONNAME byte } // REPARSE_DATA_BUFFER_HEADER is a common part of REPARSE_DATA_BUFFER structure. type REPARSE_DATA_BUFFER_HEADER struct { ReparseTag uint32 // The size, in bytes, of the reparse data that follows // the common portion of the REPARSE_DATA_BUFFER element. // This value is the length of the data starting at the // SubstituteNameOffset field. ReparseDataLength uint16 Reserved uint16 } type SymbolicLinkReparseBuffer struct { // The integer that contains the offset, in bytes, // of the substitute name string in the PathBuffer array, // computed as an offset from byte 0 of PathBuffer. Note that // this offset must be divided by 2 to get the array index. SubstituteNameOffset uint16 // The integer that contains the length, in bytes, of the // substitute name string. If this string is null-terminated, // SubstituteNameLength does not include the Unicode null character. SubstituteNameLength uint16 // PrintNameOffset is similar to SubstituteNameOffset. PrintNameOffset uint16 // PrintNameLength is similar to SubstituteNameLength. PrintNameLength uint16 // Flags specifies whether the substitute name is a full path name or // a path name relative to the directory containing the symbolic link. Flags uint32 PathBuffer [1]uint16 } // Path returns path stored in rb. func (rb *SymbolicLinkReparseBuffer) Path() string { n1 := rb.SubstituteNameOffset / 2 n2 := (rb.SubstituteNameOffset + rb.SubstituteNameLength) / 2 return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(&rb.PathBuffer[0]))[n1:n2:n2]) } type MountPointReparseBuffer struct { // The integer that contains the offset, in bytes, // of the substitute name string in the PathBuffer array, // computed as an offset from byte 0 of PathBuffer. Note that // this offset must be divided by 2 to get the array index. SubstituteNameOffset uint16 // The integer that contains the length, in bytes, of the // substitute name string. If this string is null-terminated, // SubstituteNameLength does not include the Unicode null character. SubstituteNameLength uint16 // PrintNameOffset is similar to SubstituteNameOffset. PrintNameOffset uint16 // PrintNameLength is similar to SubstituteNameLength. PrintNameLength uint16 PathBuffer [1]uint16 } // Path returns path stored in rb. func (rb *MountPointReparseBuffer) Path() string { n1 := rb.SubstituteNameOffset / 2 n2 := (rb.SubstituteNameOffset + rb.SubstituteNameLength) / 2 return syscall.UTF16ToString((*[0xffff]uint16)(unsafe.Pointer(&rb.PathBuffer[0]))[n1:n2:n2]) }