「DeviceIoControl用の構造体」を作るのに、Microsoft ご本家の Go 言語パッケージ Microsoft/go-winio: Win32 IO-related utilities for Goを使ったら、うまく動作するようになった!やったね、たえちゃん、nyagosの機能が増えるよ
junction_run.go
package main import ( "errors" "os" "golang.org/x/sys/windows" "golang.org/x/xerrors" "github.com/Microsoft/go-winio" ) const ( _FSCTL_SET_REPARSE_POINT = 589988 _INVALID_HANDLE_VALUE = ^windows.Handle(0) ) func MountPointCreate(mountPointPath, target string) error { _mountPointPath, err := windows.UTF16FromString(mountPointPath) if err != nil { return xerrors.Errorf("UTF16FromString(%s): %v", mountPointPath, err) } err = windows.CreateDirectory(&_mountPointPath[0], nil) if err != nil { return xerrors.Errorf("windows.CreateDirectory(%s): %v", mountPointPath, err) } ok := false defer func() { if !ok { os.Remove(mountPointPath) } }() 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) rp := winio.ReparsePoint{ Target: target, IsMountPoint: true, } data := winio.EncodeReparsePoint(&rp) var size uint32 err = windows.DeviceIoControl( handle, _FSCTL_SET_REPARSE_POINT, &data[0], uint32(len(data)), nil, 0, &size, nil) if err != nil { return xerrors.Errorf("windows.DeviceIoControl: %v", err) } ok = true 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) } }
$ go run junction_run.go Hoge c:\tmp $ ls -ld Hoge\ -rw---- 0 Mar 24 20:06:42 Hoge@ -> c:\tmp $ cd Hoge\ $