github.com/Xenoex/gopm@v0.6.5/cmd/helper_windows.go (about) 1 package cmd 2 3 import ( 4 "os" 5 "os/exec" 6 "path/filepath" 7 "strings" 8 "syscall" 9 "unsafe" 10 11 "github.com/Unknwon/com" 12 13 "github.com/gpmgo/gopm/doc" 14 ) 15 16 func makeLink(srcPath, destPath string) error { 17 // Check if Windows version is XP. 18 if getWindowsVersion() >= 6 { 19 cmd := exec.Command("cmd", "/c", "mklink", "/j", destPath, srcPath) 20 return cmd.Run() 21 } 22 23 // XP. 24 isWindowsXP = true 25 // if both are ntfs file system 26 if volumnType(srcPath) == "NTFS" && volumnType(destPath) == "NTFS" { 27 // if has junction command installed 28 file, err := exec.LookPath("junction") 29 if err == nil { 30 path, _ := filepath.Abs(file) 31 if com.IsFile(path) { 32 cmd := exec.Command("cmd", "/c", "junction", destPath, srcPath) 33 return cmd.Run() 34 } 35 } 36 } 37 os.RemoveAll(destPath) 38 39 return com.CopyDir(srcPath, destPath, func(filePath string) bool { 40 return strings.Contains(filePath, doc.VENDOR) 41 }) 42 } 43 44 func volumnType(dir string) string { 45 pd := dir[:3] 46 dll := syscall.MustLoadDLL("kernel32.dll") 47 GetVolumeInformation := dll.MustFindProc("GetVolumeInformationW") 48 49 var volumeNameSize uint32 = 260 50 var nFileSystemNameSize, lpVolumeSerialNumber uint32 51 var lpFileSystemFlags, lpMaximumComponentLength uint32 52 var lpFileSystemNameBuffer, volumeName [260]byte 53 var ps *uint16 = syscall.StringToUTF16Ptr(pd) 54 55 _, _, _ = GetVolumeInformation.Call(uintptr(unsafe.Pointer(ps)), 56 uintptr(unsafe.Pointer(&volumeName)), 57 uintptr(volumeNameSize), 58 uintptr(unsafe.Pointer(&lpVolumeSerialNumber)), 59 uintptr(unsafe.Pointer(&lpMaximumComponentLength)), 60 uintptr(unsafe.Pointer(&lpFileSystemFlags)), 61 uintptr(unsafe.Pointer(&lpFileSystemNameBuffer)), 62 uintptr(unsafe.Pointer(&nFileSystemNameSize)), 0) 63 64 var bytes []byte 65 if lpFileSystemNameBuffer[6] == 0 { 66 bytes = []byte{lpFileSystemNameBuffer[0], lpFileSystemNameBuffer[2], 67 lpFileSystemNameBuffer[4]} 68 } else { 69 bytes = []byte{lpFileSystemNameBuffer[0], lpFileSystemNameBuffer[2], 70 lpFileSystemNameBuffer[4], lpFileSystemNameBuffer[6]} 71 } 72 73 return string(bytes) 74 } 75 76 func getWindowsVersion() int { 77 dll := syscall.MustLoadDLL("kernel32.dll") 78 p := dll.MustFindProc("GetVersion") 79 v, _, _ := p.Call() 80 return int(byte(v)) 81 }