mirror of
https://github.com/PeernetOfficial/Abstraction.git
synced 2026-07-23 05:27:52 +01:00
61 lines
1.3 KiB
Go
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
|
|
}
|