github.com/ActiveState/cli@v0.0.0-20240508170324-6801f60cd051/internal/osutils/lockfile/flock_syscall_windows.go (about) 1 // Copyright (c) 2015, Tim Heckman 2 // All rights reserved. 3 // 4 // Redistribution and use in source and binary forms, with or without 5 // modification, are permitted provided that the following conditions are met: 6 // 7 // * Redistributions of source code must retain the above copyright notice, this 8 // list of conditions and the following disclaimer. 9 // 10 // * Redistributions in binary form must reproduce the above copyright notice, 11 // this list of conditions and the following disclaimer in the documentation 12 // and/or other materials provided with the distribution. 13 // 14 // * Neither the name of linode-netint nor the names of its 15 // contributors may be used to endorse or promote products derived from 16 // this software without specific prior written permission. 17 // 18 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" 19 // AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 20 // IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 21 // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE 22 // FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 // DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 24 // SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER 25 // CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 26 // OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 27 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 28 29 //go:build windows 30 // +build windows 31 32 package lockfile 33 34 import ( 35 "syscall" 36 "unsafe" 37 ) 38 39 var ( 40 kernel32, _ = syscall.LoadLibrary("kernel32.dll") 41 procLockFileEx, _ = syscall.GetProcAddress(kernel32, "LockFileEx") 42 procUnlockFileEx, _ = syscall.GetProcAddress(kernel32, "UnlockFileEx") 43 ) 44 45 const ( 46 winLockfileFailImmediately = 0x00000001 47 winLockfileExclusiveLock = 0x00000002 48 winLockfileSharedLock = 0x00000000 49 ) 50 51 // Use of 0x00000000 for the shared lock is a guess based on some the MS Windows 52 // `LockFileEX` docs, which document the `LOCKFILE_EXCLUSIVE_LOCK` flag as: 53 // 54 // > The function requests an exclusive lock. Otherwise, it requests a shared 55 // > lock. 56 // 57 // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx 58 59 func lockFileEx(handle syscall.Handle, flags uint32, reserved uint32, numberOfBytesToLockLow uint32, numberOfBytesToLockHigh uint32, offset *syscall.Overlapped) (bool, syscall.Errno) { 60 r1, _, errNo := syscall.Syscall6( 61 uintptr(procLockFileEx), 62 6, 63 uintptr(handle), 64 uintptr(flags), 65 uintptr(reserved), 66 uintptr(numberOfBytesToLockLow), 67 uintptr(numberOfBytesToLockHigh), 68 uintptr(unsafe.Pointer(offset))) 69 70 if r1 != 1 { 71 if errNo == 0 { 72 return false, syscall.EINVAL 73 } 74 75 return false, errNo 76 } 77 78 return true, 0 79 } 80 81 func unlockFileEx(handle syscall.Handle, reserved uint32, numberOfBytesToLockLow uint32, numberOfBytesToLockHigh uint32, offset *syscall.Overlapped) (bool, syscall.Errno) { 82 r1, _, errNo := syscall.Syscall6( 83 uintptr(procUnlockFileEx), 84 5, 85 uintptr(handle), 86 uintptr(reserved), 87 uintptr(numberOfBytesToLockLow), 88 uintptr(numberOfBytesToLockHigh), 89 uintptr(unsafe.Pointer(offset)), 90 0) 91 92 if r1 != 1 { 93 if errNo == 0 { 94 return false, syscall.EINVAL 95 } 96 97 return false, errNo 98 } 99 100 return true, 0 101 }