Files
Abstraction/vendor/github.com/akrylysov/pogreb/fs/os_windows.go
2022-12-11 06:18:00 +00:00

61 lines
1.3 KiB
Go

// +build windows
package fs
import (
"os"
"syscall"
"unsafe"
)
var (
modkernel32 = syscall.NewLazyDLL("kernel32.dll")
procLockFileEx = modkernel32.NewProc("LockFileEx")
)
const (
errorLockViolation = 0x21
)
func lockfile(f *os.File) error {
var ol syscall.Overlapped
r1, _, err := syscall.Syscall6(
procLockFileEx.Addr(),
6,
uintptr(f.Fd()), // handle
uintptr(0x0003),
uintptr(0), // reserved
uintptr(1), // locklow
uintptr(0), // lockhigh
uintptr(unsafe.Pointer(&ol)),
)
if r1 == 0 && (err == syscall.ERROR_FILE_EXISTS || err == errorLockViolation) {
return os.ErrExist
}
return nil
}
func createLockFile(name string, perm os.FileMode) (LockFile, bool, error) {
acquiredExisting := false
if _, err := os.Stat(name); err == nil {
acquiredExisting = true
}
fd, err := syscall.CreateFile(&(syscall.StringToUTF16(name)[0]),
syscall.GENERIC_READ|syscall.GENERIC_WRITE,
syscall.FILE_SHARE_READ|syscall.FILE_SHARE_WRITE|syscall.FILE_SHARE_DELETE,
nil,
syscall.CREATE_ALWAYS,
syscall.FILE_ATTRIBUTE_NORMAL,
0)
if err != nil {
return nil, false, os.ErrExist
}
f := os.NewFile(uintptr(fd), name)
if err := lockfile(f); err != nil {
f.Close()
return nil, false, err
}
return &osLockFile{f, name}, acquiredExisting, nil
}