/* Distributed under the OSI-approved BSD 3-Clause License. See accompanying file Copyright.txt or https://cmake.org/licensing for details. */ #include "cmFileLock.h" #include "cmSystemTools.h" #include // CreateFileW cmFileLock::cmFileLock() : File(INVALID_HANDLE_VALUE) { } cmFileLockResult cmFileLock::Release() { if (this->Filename.empty()) { return cmFileLockResult::MakeOk(); } const unsigned long len = static_cast(-1); static OVERLAPPED overlapped; const DWORD reserved = 0; const BOOL unlockResult = UnlockFileEx(File, reserved, len, len, &overlapped); this->Filename = ""; CloseHandle(this->File); this->File = INVALID_HANDLE_VALUE; if (unlockResult) { return cmFileLockResult::MakeOk(); } else { return cmFileLockResult::MakeSystem(); } } cmFileLockResult cmFileLock::OpenFile() { const DWORD access = GENERIC_READ | GENERIC_WRITE; const DWORD shareMode = FILE_SHARE_READ | FILE_SHARE_WRITE; const PSECURITY_ATTRIBUTES security = NULL; const DWORD attr = 0; const HANDLE templ = NULL; this->File = CreateFileW( cmSystemTools::ConvertToWindowsExtendedPath(this->Filename).c_str(), access, shareMode, security, OPEN_EXISTING, attr, templ); if (this->File == INVALID_HANDLE_VALUE) { return cmFileLockResult::MakeSystem(); } else { return cmFileLockResult::MakeOk(); } } cmFileLockResult cmFileLock::LockWithoutTimeout() { if (!this->LockFile(LOCKFILE_EXCLUSIVE_LOCK)) { return cmFileLockResult::MakeSystem(); } else { return cmFileLockResult::MakeOk(); } } cmFileLockResult cmFileLock::LockWithTimeout(unsigned long seconds) { const DWORD flags = LOCKFILE_EXCLUSIVE_LOCK | LOCKFILE_FAIL_IMMEDIATELY; while (true) { const BOOL result = this->LockFile(flags); if (result) { return cmFileLockResult::MakeOk(); } const DWORD error = GetLastError(); if (error != ERROR_LOCK_VIOLATION) { return cmFileLockResult::MakeSystem(); } if (seconds == 0) { return cmFileLockResult::MakeTimeout(); } --seconds; cmSystemTools::Delay(1000); } } BOOL cmFileLock::LockFile(DWORD flags) { const DWORD reserved = 0; const unsigned long len = static_cast(-1); static OVERLAPPED overlapped; return LockFileEx(this->File, flags, reserved, len, len, &overlapped); }