copy_windows.go 1.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667
  1. //go:build windows
  2. // +build windows
  3. package cmd
  4. import (
  5. "os"
  6. "path/filepath"
  7. "syscall"
  8. "unsafe"
  9. )
  10. func localCopy(src, target string) error {
  11. // Create target directory if it doesn't exist
  12. dirPath := filepath.Dir(target)
  13. if err := os.MkdirAll(dirPath, 0o755); err != nil {
  14. return err
  15. }
  16. // Open source file
  17. sourceFile, err := os.Open(src)
  18. if err != nil {
  19. return err
  20. }
  21. defer sourceFile.Close()
  22. // Create target file
  23. targetFile, err := os.Create(target)
  24. if err != nil {
  25. return err
  26. }
  27. defer targetFile.Close()
  28. // Use CopyFileExW to copy the file
  29. err = copyFileEx(src, target)
  30. if err != nil {
  31. return err
  32. }
  33. return nil
  34. }
  35. func copyFileEx(src, dst string) error {
  36. kernel32 := syscall.NewLazyDLL("kernel32.dll")
  37. copyFileEx := kernel32.NewProc("CopyFileExW")
  38. srcPtr, err := syscall.UTF16PtrFromString(src)
  39. if err != nil {
  40. return err
  41. }
  42. dstPtr, err := syscall.UTF16PtrFromString(dst)
  43. if err != nil {
  44. return err
  45. }
  46. r1, _, err := copyFileEx.Call(
  47. uintptr(unsafe.Pointer(srcPtr)),
  48. uintptr(unsafe.Pointer(dstPtr)),
  49. 0, 0, 0, 0)
  50. if r1 == 0 {
  51. return err
  52. }
  53. return nil
  54. }