Created
March 24, 2019 00:31
-
-
Save hymkor/19a2f425b53ce21e6bcbe4a95e39e8c3 to your computer and use it in GitHub Desktop.
Go で Windows のジャンクションを作ろうとしているけれども、なんかうまくいかないソース
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package main | |
import ( | |
"os" | |
"unsafe" | |
"errors" | |
"golang.org/x/sys/windows" | |
"golang.org/x/xerrors" | |
) | |
const ( | |
_MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 | |
_FSCTL_SET_REPARSE_POINT = 589988 | |
_INVALID_HANDLE_VALUE = ^windows.Handle(0) | |
) | |
type _MountPointInfo struct { | |
Tag uint32 | |
DataLength uint16 | |
Reserved uint16 | |
TargetOffset uint16 | |
TargetByteLength uint16 | |
DescriptionOffset uint16 | |
DescriptionByteLength uint16 | |
Buffer [(_MAXIMUM_REPARSE_DATA_BUFFER_SIZE - 4 - 2*6) / 2]uint16 | |
} | |
func MountPointCreate(mountPointPath, target string) error { | |
_mountPointPath, err := windows.UTF16FromString(mountPointPath) | |
if err != nil { | |
return xerrors.Errorf("UTF16FromString(%s): %v", mountPointPath, err) | |
} | |
_target, err := windows.UTF16FromString(target) | |
if err != nil { | |
return xerrors.Errorf("UTF16FromString(%s): %v", target, err) | |
} | |
var info _MountPointInfo | |
info.Tag = windows.IO_REPARSE_TAG_MOUNT_POINT | |
info.TargetOffset = 0 | |
info.TargetByteLength = uint16(len(_target) * 2 ) | |
for i := 0 ; i < len(_target) ; i++ { | |
info.Buffer[i] = _target[i] | |
} | |
// copy(info.Buffer[:], _target) | |
info.Buffer[len(_target)] = 0 | |
info.DescriptionOffset = uint16((len(_target)+1) * 2) | |
info.DescriptionByteLength = 0 | |
info.DataLength = uint16(8 + (len(_target)+1+1)*2) | |
err = windows.CreateDirectory(&_mountPointPath[0], nil) | |
if err != nil { | |
return xerrors.Errorf("windows.CreateDirectory(%s): %v", mountPointPath, err) | |
} | |
handle, err := windows.CreateFile(&_mountPointPath[0], | |
windows.GENERIC_WRITE, | |
0, | |
nil, | |
windows.OPEN_EXISTING, | |
windows.FILE_FLAG_BACKUP_SEMANTICS, | |
0) | |
if err != nil { | |
return xerrors.Errorf("windows.CreateFile(%s): %v", mountPointPath, err) | |
} | |
if handle == _INVALID_HANDLE_VALUE { | |
return errors.New("windows.CreateFile: invalid handle value") | |
} | |
defer windows.CloseHandle(handle) | |
var size uint32 | |
err = windows.DeviceIoControl( | |
handle, | |
_FSCTL_SET_REPARSE_POINT, | |
(*byte)(unsafe.Pointer(&info)), | |
uint32(8+info.DataLength), | |
nil, | |
0, | |
&size, | |
nil) | |
if err != nil { | |
return xerrors.Errorf("windows.DeviceIoControl: %v", err) | |
} | |
return nil | |
} | |
func main() { | |
if len(os.Args) < 3 { | |
println("go run junction.go DST SRC") | |
return | |
} | |
if err := MountPointCreate(os.Args[1], os.Args[2]); err != nil { | |
println(err.Error()) | |
os.Exit(1) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment