Skip to content
This repository has been archived by the owner on Feb 15, 2024. It is now read-only.

Commit

Permalink
Added exclusive locking.
Browse files Browse the repository at this point in the history
  • Loading branch information
James Forshaw committed Feb 27, 2017
1 parent 1a3bec5 commit 74a11f6
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 10 deletions.
7 changes: 6 additions & 1 deletion BaitAndSwitch/BaitAndSwitch.cpp
Expand Up @@ -29,7 +29,12 @@ int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 3)
{
printf("Usage: BaitAndSwitch symlink target1 target2 [rwd]\n");
printf("Usage: BaitAndSwitch symlink target1 target2 [rwdx]\n");
printf("Share Mode:\n");
printf("r - FILE_SHARE_READ\n");
printf("w - FILE_SHARE_WRITE\n");
printf("d - FILE_SHARE_DELETE\n");
printf("x - Exclusive lock\n");
return 1;
}
else
Expand Down
35 changes: 28 additions & 7 deletions CommonUtils/FileOpLock.cpp
Expand Up @@ -52,7 +52,7 @@ FileOpLock::~FileOpLock()
}
}

bool FileOpLock::BeginLock(const std::wstring& filename, DWORD dwShareMode)
bool FileOpLock::BeginLock(const std::wstring& filename, DWORD dwShareMode, bool exclusive)
{
g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr);
g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr);
Expand All @@ -61,7 +61,7 @@ bool FileOpLock::BeginLock(const std::wstring& filename, DWORD dwShareMode)

if (GetFileAttributesW(filename.c_str()) & FILE_ATTRIBUTE_DIRECTORY)
{
flags |= FILE_FLAG_BACKUP_SEMANTICS;
flags |= FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OPEN_REPARSE_POINT;
}

g_hFile = CreateFileW(filename.c_str(), GENERIC_READ,
Expand All @@ -81,10 +81,25 @@ bool FileOpLock::BeginLock(const std::wstring& filename, DWORD dwShareMode)

SetThreadpoolWait(g_wait, g_o.hEvent, nullptr);

DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK,
&g_inputBuffer, sizeof(g_inputBuffer),
&g_outputBuffer, sizeof(g_outputBuffer),
nullptr, &g_o);
DWORD bytesReturned;

if (exclusive)
{
DeviceIoControl(g_hFile,
FSCTL_REQUEST_OPLOCK_LEVEL_1,
NULL, 0,
NULL, 0,
&bytesReturned,
&g_o);
}
else
{
DeviceIoControl(g_hFile, FSCTL_REQUEST_OPLOCK,
&g_inputBuffer, sizeof(g_inputBuffer),
&g_outputBuffer, sizeof(g_outputBuffer),
nullptr, &g_o);
}

DWORD err = GetLastError();
if (err != ERROR_IO_PENDING) {
DebugPrintf("Oplock Failed %d\n", err);
Expand All @@ -98,6 +113,7 @@ FileOpLock* FileOpLock::CreateLock(const std::wstring& name, const std::wstring&
{
FileOpLock* ret = new FileOpLock(cb);
DWORD dwShareMode = 0;
bool exclusive = false;

if (share_mode.find('r') != std::wstring::npos)
{
Expand All @@ -114,7 +130,12 @@ FileOpLock* FileOpLock::CreateLock(const std::wstring& name, const std::wstring&
dwShareMode |= FILE_SHARE_DELETE;
}

if (ret->BeginLock(name, dwShareMode))
if (share_mode.find('x') != std::wstring::npos)
{
exclusive = true;
}

if (ret->BeginLock(name, dwShareMode, exclusive))
{
return ret;
}
Expand Down
2 changes: 1 addition & 1 deletion CommonUtils/FileOpLock.h
Expand Up @@ -30,7 +30,7 @@ class FileOpLock

void DoWaitCallback();

bool BeginLock(const std::wstring& name, DWORD dwShareMode);
bool BeginLock(const std::wstring& name, DWORD dwShareMode, bool exclusive);

};

7 changes: 6 additions & 1 deletion SetOpLock/SetOpLock.cpp
Expand Up @@ -27,7 +27,12 @@ int _tmain(int argc, _TCHAR* argv[])
{
if (argc < 2)
{
printf("Usage: SetOpLock target [rwd]\n");
printf("Usage: SetOpLock target [rwdx]\n");
printf("Share Mode:\n");
printf("r - FILE_SHARE_READ\n");
printf("w - FILE_SHARE_WRITE\n");
printf("d - FILE_SHARE_DELETE\n");
printf("x - Exclusive lock\n");
return 1;
}
else
Expand Down

0 comments on commit 74a11f6

Please sign in to comment.