Skip to content

Instantly share code, notes, and snippets.

@asquigglytwist
Last active April 25, 2020 10:02
Show Gist options
  • Save asquigglytwist/4b08ea822f704e3d3c112d19db4a8ff5 to your computer and use it in GitHub Desktop.
Save asquigglytwist/4b08ea822f704e3d3c112d19db4a8ff5 to your computer and use it in GitHub Desktop.
File locking in Windows
#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