1package copyfile 2 3import ( 4 "context" 5 "fmt" 6 "syscall" 7 "unsafe" 8 9 "github.com/Microsoft/hcsshim/internal/oc" 10 "go.opencensus.io/trace" 11) 12 13var ( 14 modkernel32 = syscall.NewLazyDLL("kernel32.dll") 15 procCopyFileW = modkernel32.NewProc("CopyFileW") 16) 17 18// CopyFile is a utility for copying a file using CopyFileW win32 API for 19// performance. 20func CopyFile(ctx context.Context, srcFile, destFile string, overwrite bool) (err error) { 21 ctx, span := trace.StartSpan(ctx, "copyfile::CopyFile") 22 defer span.End() 23 defer func() { oc.SetSpanStatus(span, err) }() 24 span.AddAttributes( 25 trace.StringAttribute("srcFile", srcFile), 26 trace.StringAttribute("destFile", destFile), 27 trace.BoolAttribute("overwrite", overwrite)) 28 29 var bFailIfExists uint32 = 1 30 if overwrite { 31 bFailIfExists = 0 32 } 33 34 lpExistingFileName, err := syscall.UTF16PtrFromString(srcFile) 35 if err != nil { 36 return err 37 } 38 lpNewFileName, err := syscall.UTF16PtrFromString(destFile) 39 if err != nil { 40 return err 41 } 42 r1, _, err := syscall.Syscall( 43 procCopyFileW.Addr(), 44 3, 45 uintptr(unsafe.Pointer(lpExistingFileName)), 46 uintptr(unsafe.Pointer(lpNewFileName)), 47 uintptr(bFailIfExists)) 48 if r1 == 0 { 49 return fmt.Errorf("failed CopyFileW Win32 call from '%s' to '%s': %s", srcFile, destFile, err) 50 } 51 return nil 52} 53