-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
16 changed files
with
1,244 additions
and
0 deletions.
There are no files selected for viewing
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
#include "stdafx.h" | ||
#include "FileOpLock.h" | ||
#include <threadpoolapiset.h> | ||
|
||
|
||
|
||
FileOpLock::FileOpLock(UserCallback cb): | ||
g_inputBuffer({ 0 }), g_outputBuffer({ 0 }), g_o({ 0 }), g_hFile(INVALID_HANDLE_VALUE), g_hLockCompleted(nullptr), g_wait(nullptr), _cb(cb) | ||
{ | ||
g_inputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; | ||
g_inputBuffer.StructureLength = sizeof(g_inputBuffer); | ||
g_inputBuffer.RequestedOplockLevel = OPLOCK_LEVEL_CACHE_READ | OPLOCK_LEVEL_CACHE_HANDLE | OPLOCK_LEVEL_CACHE_WRITE; | ||
g_inputBuffer.Flags = REQUEST_OPLOCK_INPUT_FLAG_REQUEST; | ||
g_outputBuffer.StructureVersion = REQUEST_OPLOCK_CURRENT_VERSION; | ||
g_outputBuffer.StructureLength = sizeof(g_outputBuffer); | ||
} | ||
|
||
|
||
FileOpLock::~FileOpLock() | ||
{ | ||
if (g_wait) | ||
{ | ||
SetThreadpoolWait(g_wait, nullptr, nullptr); | ||
CloseThreadpoolWait(g_wait); | ||
g_wait = nullptr; | ||
} | ||
|
||
if (g_o.hEvent) | ||
{ | ||
CloseHandle(g_o.hEvent); | ||
g_o.hEvent = nullptr; | ||
} | ||
|
||
if (g_hFile != INVALID_HANDLE_VALUE) | ||
{ | ||
CloseHandle(g_hFile); | ||
g_hFile = INVALID_HANDLE_VALUE; | ||
} | ||
} | ||
|
||
bool FileOpLock::BeginLock(const std::wstring& filename) | ||
{ | ||
g_hLockCompleted = CreateEvent(nullptr, TRUE, FALSE, nullptr); | ||
g_o.hEvent = CreateEvent(nullptr, FALSE, FALSE, nullptr); | ||
|
||
|
||
|
||
g_hFile = CreateFileW(filename.c_str(), GENERIC_READ, FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, | ||
0, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_BACKUP_SEMANTICS, 0); | ||
if (g_hFile == INVALID_HANDLE_VALUE) { | ||
|
||
return false; | ||
} | ||
|
||
g_wait = CreateThreadpoolWait(WaitCallback, this, nullptr); | ||
if (g_wait == nullptr) | ||
{ | ||
|
||
return false; | ||
} | ||
|
||
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); | ||
if (GetLastError() != ERROR_IO_PENDING) { | ||
|
||
return false; | ||
} | ||
|
||
return true; | ||
} | ||
|
||
FileOpLock* FileOpLock::CreateLock(const std::wstring& name, FileOpLock::UserCallback cb) | ||
{ | ||
FileOpLock* ret = new FileOpLock(cb); | ||
|
||
if (ret->BeginLock(name)) | ||
{ | ||
return ret; | ||
} | ||
else | ||
{ | ||
delete ret; | ||
return nullptr; | ||
} | ||
} | ||
|
||
void FileOpLock::WaitForLock(UINT Timeout) | ||
{ | ||
WaitForSingleObject(g_hLockCompleted, Timeout); | ||
} | ||
|
||
void FileOpLock::WaitCallback(PTP_CALLBACK_INSTANCE Instance, | ||
PVOID Parameter, PTP_WAIT Wait, | ||
TP_WAIT_RESULT WaitResult) | ||
{ | ||
UNREFERENCED_PARAMETER(Instance); | ||
UNREFERENCED_PARAMETER(Wait); | ||
UNREFERENCED_PARAMETER(WaitResult); | ||
|
||
FileOpLock* lock = reinterpret_cast<FileOpLock*>(Parameter); | ||
|
||
lock->DoWaitCallback(); | ||
} | ||
|
||
void FileOpLock::DoWaitCallback() | ||
{ | ||
DWORD dwBytes; | ||
if (!GetOverlappedResult(g_hFile, &g_o, &dwBytes, TRUE)) { | ||
|
||
} | ||
|
||
if (_cb) | ||
{ | ||
_cb(); | ||
} | ||
|
||
|
||
CloseHandle(g_hFile); | ||
g_hFile = INVALID_HANDLE_VALUE; | ||
SetEvent(g_hLockCompleted); | ||
} |
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,36 @@ | ||
#pragma once | ||
|
||
#include <Windows.h> | ||
#include <string> | ||
|
||
class FileOpLock | ||
{ | ||
public: | ||
typedef void(*UserCallback)(); | ||
|
||
static FileOpLock* CreateLock(const std::wstring& name, FileOpLock::UserCallback cb); | ||
void WaitForLock(UINT Timeout); | ||
|
||
~FileOpLock(); | ||
private: | ||
|
||
HANDLE g_hFile; | ||
OVERLAPPED g_o; | ||
REQUEST_OPLOCK_INPUT_BUFFER g_inputBuffer; | ||
REQUEST_OPLOCK_OUTPUT_BUFFER g_outputBuffer; | ||
HANDLE g_hLockCompleted; | ||
PTP_WAIT g_wait; | ||
UserCallback _cb; | ||
|
||
FileOpLock(UserCallback cb); | ||
|
||
static void CALLBACK WaitCallback(PTP_CALLBACK_INSTANCE Instance, | ||
PVOID Parameter, PTP_WAIT Wait, | ||
TP_WAIT_RESULT WaitResult); | ||
|
||
void DoWaitCallback(); | ||
|
||
bool BeginLock(const std::wstring& name); | ||
|
||
}; | ||
|
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
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,134 @@ | ||
#include "stdafx.h" | ||
#include "FileOpLock.h" | ||
#include "ReparsePoint.h" | ||
#include <string> | ||
#include <sddl.h> | ||
#include <iostream> | ||
#include <Msi.h> | ||
#define BUFFERSIZE 400 | ||
|
||
#pragma comment(lib, "Msi.lib") | ||
const char* targetfile; | ||
bool succeeded = false; | ||
std::wstring s2ws(const std::string& str) | ||
{ | ||
int size_needed = MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), NULL, 0); | ||
std::wstring wstrTo(size_needed, 0); | ||
MultiByteToWideChar(CP_UTF8, 0, &str[0], (int)str.size(), &wstrTo[0], size_needed); | ||
return wstrTo; | ||
} | ||
|
||
DWORD WINAPI MyThreadFunction(LPVOID lpParam) | ||
{ | ||
LPCWSTR filename1; | ||
LPCWSTR root = L"c:\\windows\\installer\\"; | ||
HANDLE hDir = CreateFile( | ||
L"c:\\windows\\installer", | ||
FILE_LIST_DIRECTORY, | ||
FILE_SHARE_WRITE | FILE_SHARE_READ | FILE_SHARE_DELETE, | ||
NULL, | ||
OPEN_EXISTING, | ||
FILE_FLAG_BACKUP_SEMANTICS, | ||
NULL | ||
); | ||
|
||
FILE_NOTIFY_INFORMATION strFileNotifyInfo[1024]; | ||
DWORD dwBytesReturned = 0; | ||
std::wstring extension = L".msi"; | ||
char buff[401]; | ||
std::string targetf(targetfile); | ||
std::wstring targetfw = s2ws(targetf); | ||
const wchar_t* targetfww = targetfw.c_str(); | ||
|
||
|
||
while (TRUE) | ||
{ | ||
ReadDirectoryChangesW(hDir, (LPVOID)&strFileNotifyInfo, sizeof(strFileNotifyInfo), TRUE, FILE_NOTIFY_CHANGE_FILE_NAME, &dwBytesReturned, NULL, NULL); | ||
|
||
filename1 = strFileNotifyInfo[0].FileName; | ||
|
||
std::wstring df = std::wstring(root) + filename1; | ||
std::wstring::size_type found = df.find(extension); | ||
if (found != std::wstring::npos) | ||
{ | ||
ReparsePoint::CreateMountPoint(L"c:\\blah", targetfww, L""); | ||
} | ||
if (found != std::wstring::npos) | ||
{ | ||
LPCWSTR dfc = df.c_str(); | ||
HANDLE hFile; | ||
|
||
|
||
do { | ||
hFile = CreateFile(dfc,GENERIC_READ,FILE_SHARE_READ | FILE_SHARE_DELETE | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL); | ||
DWORD dwBytesRead = 0; | ||
ReadFile(hFile, buff, 400, &dwBytesRead, NULL); | ||
if (dwBytesRead > 0) | ||
{ | ||
succeeded = true; | ||
for (int i = 0; i < 400; i++) { | ||
std::cout << buff[i]; | ||
} | ||
std::cout << std::endl << "press any key to exit"; | ||
return 0; | ||
} | ||
CloseHandle(hFile); | ||
|
||
} while (TRUE); | ||
|
||
} | ||
|
||
} | ||
return 0; | ||
} | ||
|
||
void runme() { | ||
HANDLE mThread = CreateThread(NULL,0,MyThreadFunction,NULL,0,NULL); | ||
SetThreadPriority(mThread, THREAD_PRIORITY_TIME_CRITICAL); | ||
} | ||
|
||
int main(int argc, const char * argv[]) | ||
{ | ||
|
||
|
||
char splitpath[MAX_PATH]; | ||
char* splitfile; | ||
GetFullPathNameA(argv[1], MAX_PATH, splitpath, &splitfile); | ||
std::string path = "c:\\blah\\"; | ||
std::string filename(splitfile); | ||
char* ptr; | ||
int ch = '\\'; | ||
ptr = strrchr(splitpath, ch); | ||
char* nullbyte = "\0"; | ||
*ptr = *nullbyte; | ||
targetfile = splitpath; | ||
|
||
|
||
|
||
path.append(filename); | ||
const char * c = path.c_str(); | ||
CreateDirectory(L"c:\\blah", NULL); | ||
CreateDirectory(L"c:\\blah2", NULL); | ||
|
||
while (succeeded == false) | ||
{ | ||
|
||
ReparsePoint::CreateMountPoint(L"c:\\blah", L"c:\\blah2", L""); | ||
CopyFileA("file", c, true); | ||
MSIHANDLE blah; | ||
LANGID langid = 0x0409; | ||
runme(); | ||
MsiSetInternalUI(INSTALLUILEVEL_NONE, NULL); | ||
MsiAdvertiseProductA(c, "c:\\blah\\test", NULL, langid); | ||
|
||
} | ||
ReparsePoint::CreateMountPoint(L"c:\\blah", L"c:\\blah2", L""); | ||
DeleteFileA(c); | ||
DeleteFile(L"c:\\blah2\\test"); | ||
RemoveDirectory(L"c:\\blah"); | ||
RemoveDirectory(L"c:\\blah2"); | ||
|
||
getchar(); | ||
return 0; | ||
} | ||
|
Oops, something went wrong.