github.com/atlassian/git-lob@v0.0.0-20150806085256-2386a5ed291a/core/links_windows.go (about) 1 // +build windows 2 3 package core 4 5 // Windows-specific dll functions 6 7 import ( 8 "os" 9 "syscall" 10 "unsafe" 11 ) 12 13 // Create a hard link to a file 14 // This link can be deleted like any other file afterwards 15 func CreateHardLink(target, link string) error { 16 kern32 := syscall.NewLazyDLL("kernel32.dll") 17 proc := kern32.NewProc("CreateHardLinkW") 18 link16, err := syscall.UTF16PtrFromString(link) 19 if err != nil { 20 return err 21 } 22 target16, err := syscall.UTF16PtrFromString(target) 23 if err != nil { 24 return err 25 } 26 ret, _, err := proc.Call( 27 uintptr(unsafe.Pointer(link16)), 28 uintptr(unsafe.Pointer(target16)), 29 0) 30 31 if ret == 0 { 32 // zero return means failure in Win API 33 // err already contains result of GetLastError 34 return err 35 } 36 return nil 37 } 38 39 // Get the number of hard links to a given file (min 1) 40 func GetHardLinkCount(target string) (linkCount int, err error) { 41 // syscall already has a number of windows calls already, including 42 // GetFileInformationByHandle, it just doesn't expose the number of links right 43 // now, since they don't support hard links on Windows 44 // For this reason we can use Go's file open commands & pass the fd to the Win API 45 file, err := os.OpenFile(target, os.O_RDONLY, 0644) 46 if err != nil { 47 return 0, err 48 } 49 defer file.Close() 50 51 var d syscall.ByHandleFileInformation 52 err = syscall.GetFileInformationByHandle(syscall.Handle(file.Fd()), &d) 53 if err != nil { 54 return 0, err 55 } 56 57 return int(d.NumberOfLinks), nil 58 }