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  }