// Copyright 2015 Tim Heckman. All rights reserved. // Use of this source code is governed by the BSD 3-Clause // license that can be found in the LICENSE file. // +build windows package flock import ( "syscall" "unsafe" ) var ( kernel32, _ = syscall.LoadLibrary("kernel32.dll") procLockFileEx, _ = syscall.GetProcAddress(kernel32, "LockFileEx") procUnlockFileEx, _ = syscall.GetProcAddress(kernel32, "UnlockFileEx") ) const ( winLockfileFailImmediately = 0x00000001 winLockfileExclusiveLock = 0x00000002 winLockfileSharedLock = 0x00000000 ) // Use of 0x00000000 for the shared lock is a guess based on some the MS Windows // `LockFileEX` docs, which document the `LOCKFILE_EXCLUSIVE_LOCK` flag as: // // > The function requests an exclusive lock. Otherwise, it requests a shared // > lock. // // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx func lockFileEx(handle syscall.Handle, flags uint32, reserved uint32, numberOfBytesToLockLow uint32, numberOfBytesToLockHigh uint32, offset *syscall.Overlapped) (bool, syscall.Errno) { r1, _, errNo := syscall.Syscall6( uintptr(procLockFileEx), 6, uintptr(handle), uintptr(flags), uintptr(reserved), uintptr(numberOfBytesToLockLow), uintptr(numberOfBytesToLockHigh), uintptr(unsafe.Pointer(offset))) if r1 != 1 { if errNo == 0 { return false, syscall.EINVAL } return false, errNo } return true, 0 } func unlockFileEx(handle syscall.Handle, reserved uint32, numberOfBytesToLockLow uint32, numberOfBytesToLockHigh uint32, offset *syscall.Overlapped) (bool, syscall.Errno) { r1, _, errNo := syscall.Syscall6( uintptr(procUnlockFileEx), 5, uintptr(handle), uintptr(reserved), uintptr(numberOfBytesToLockLow), uintptr(numberOfBytesToLockHigh), uintptr(unsafe.Pointer(offset)), 0) if r1 != 1 { if errNo == 0 { return false, syscall.EINVAL } return false, errNo } return true, 0 }