Last active
April 25, 2020 10:02
-
-
Save asquigglytwist/4b08ea822f704e3d3c112d19db4a8ff5 to your computer and use it in GitHub Desktop.
File locking in Windows
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#pragma once | |
#ifndef FILELOCKER_H | |
#define FILELOCKER_H | |
#include <Windows.h> | |
#include <string> | |
#include <tchar.h> | |
#include <iostream> | |
#if UNICODE | |
typedef std::wstring tstring; | |
#define tcout std::wcout | |
#else | |
typedef std::string tstring; | |
#define tcout std::cout | |
#endif // UNICODE | |
enum class FileLockModes | |
{ | |
AllowReading, | |
AllowWriting, | |
AllowDeletion | |
}; | |
class FileLocker | |
{ | |
tstring m_tsFileToLock; | |
HANDLE m_hLockedFileHandle; | |
DWORD m_dwLastError; | |
bool m_bSharingViolation; | |
public: | |
FileLocker(tstring& fileToLock) : | |
m_tsFileToLock(fileToLock), | |
m_hLockedFileHandle(nullptr), | |
m_dwLastError(ERROR_SUCCESS), | |
m_bSharingViolation(false) | |
{ | |
} | |
bool LockFile(FileLockModes); | |
bool UnLockFile(); | |
auto GetLastErrorCode() { return m_dwLastError; } | |
}; | |
bool FileLocker::LockFile(FileLockModes lockMode) | |
{ | |
auto fileSharingMode = FILE_SHARE_READ; | |
switch (lockMode) | |
{ | |
case FileLockModes::AllowReading: | |
break; | |
case FileLockModes::AllowWriting: | |
fileSharingMode = FILE_SHARE_WRITE; | |
break; | |
case FileLockModes::AllowDeletion: | |
fileSharingMode = FILE_SHARE_DELETE; | |
break; | |
default: | |
tcout << _T("Invalid mode specified; Will not attempt to lock file."); | |
return false; | |
} | |
m_hLockedFileHandle = ::CreateFile(m_tsFileToLock.c_str(), | |
GENERIC_READ | GENERIC_WRITE, | |
fileSharingMode, | |
nullptr, | |
OPEN_EXISTING, | |
0, | |
nullptr); | |
auto bRet = (INVALID_HANDLE_VALUE != m_hLockedFileHandle); | |
if (bRet) | |
{ | |
tcout << _T("File: ") << m_tsFileToLock << _T(" locked successfully.\n"); | |
} | |
else | |
{ | |
m_dwLastError = ::GetLastError(); | |
if (ERROR_SHARING_VIOLATION == m_dwLastError) | |
{ | |
m_bSharingViolation = true; | |
tcout << _T("ERROR_SHARING_VIOLATION; File is already in use by another process.\n"); | |
} | |
} | |
return bRet; | |
} | |
bool FileLocker::UnLockFile() | |
{ | |
auto bRet = false; | |
if (m_hLockedFileHandle) | |
{ | |
bRet = static_cast<bool>(::CloseHandle(m_hLockedFileHandle)); | |
if (bRet) | |
{ | |
m_dwLastError = ERROR_SUCCESS; | |
m_hLockedFileHandle = nullptr; | |
} | |
else | |
{ | |
m_dwLastError = ::GetLastError(); | |
} | |
} | |
return bRet; | |
} | |
#endif // !FILELOCKER_H |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment