You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

flock_winapi.go 1.9KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576
  1. // Copyright 2015 Tim Heckman. All rights reserved.
  2. // Use of this source code is governed by the BSD 3-Clause
  3. // license that can be found in the LICENSE file.
  4. // +build windows
  5. package flock
  6. import (
  7. "syscall"
  8. "unsafe"
  9. )
  10. var (
  11. kernel32, _ = syscall.LoadLibrary("kernel32.dll")
  12. procLockFileEx, _ = syscall.GetProcAddress(kernel32, "LockFileEx")
  13. procUnlockFileEx, _ = syscall.GetProcAddress(kernel32, "UnlockFileEx")
  14. )
  15. const (
  16. winLockfileFailImmediately = 0x00000001
  17. winLockfileExclusiveLock = 0x00000002
  18. winLockfileSharedLock = 0x00000000
  19. )
  20. // Use of 0x00000000 for the shared lock is a guess based on some the MS Windows
  21. // `LockFileEX` docs, which document the `LOCKFILE_EXCLUSIVE_LOCK` flag as:
  22. //
  23. // > The function requests an exclusive lock. Otherwise, it requests a shared
  24. // > lock.
  25. //
  26. // https://msdn.microsoft.com/en-us/library/windows/desktop/aa365203(v=vs.85).aspx
  27. func lockFileEx(handle syscall.Handle, flags uint32, reserved uint32, numberOfBytesToLockLow uint32, numberOfBytesToLockHigh uint32, offset *syscall.Overlapped) (bool, syscall.Errno) {
  28. r1, _, errNo := syscall.Syscall6(
  29. uintptr(procLockFileEx),
  30. 6,
  31. uintptr(handle),
  32. uintptr(flags),
  33. uintptr(reserved),
  34. uintptr(numberOfBytesToLockLow),
  35. uintptr(numberOfBytesToLockHigh),
  36. uintptr(unsafe.Pointer(offset)))
  37. if r1 != 1 {
  38. if errNo == 0 {
  39. return false, syscall.EINVAL
  40. }
  41. return false, errNo
  42. }
  43. return true, 0
  44. }
  45. func unlockFileEx(handle syscall.Handle, reserved uint32, numberOfBytesToLockLow uint32, numberOfBytesToLockHigh uint32, offset *syscall.Overlapped) (bool, syscall.Errno) {
  46. r1, _, errNo := syscall.Syscall6(
  47. uintptr(procUnlockFileEx),
  48. 5,
  49. uintptr(handle),
  50. uintptr(reserved),
  51. uintptr(numberOfBytesToLockLow),
  52. uintptr(numberOfBytesToLockHigh),
  53. uintptr(unsafe.Pointer(offset)),
  54. 0)
  55. if r1 != 1 {
  56. if errNo == 0 {
  57. return false, syscall.EINVAL
  58. }
  59. return false, errNo
  60. }
  61. return true, 0
  62. }