#define UNICODE
#define _UNICODE
#include "stdio.h"
#include "iostream"
#include <windows.h>
#include <string>
#include <set>
#include <utility>
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
);
HANDLE createFileOverlapped(std::wstring, bool);
VOID WINAPI endOfReading(DWORD errorCode, DWORD numberOfBytes, LPOVERLAPPED infoStruct);
VOID WINAPI endOfWriting(DWORD errorCode, DWORD numberOfBytes, LPOVERLAPPED infoStruct);
HANDLE hFileSource, hFileTarget;
const std::wstring sourceFileName = L"D:\\Petr\\AsyncIO\\source.file";
const std::wstring targetFileName = L"D:\\Petr\\AsyncIO\\target.file";
const size_t numberOfAsyncOps = 1;
const size_t bufferSizeBlocks = 8;
const size_t blockSizeBytes = 4096;
const size_t bufferSizeBytes = blockSizeBytes * bufferSizeBlocks;
OVERLAPPED olStruct[numberOfAsyncOps];
BYTE* buffer[numberOfAsyncOps];
LARGE_INTEGER fileSizeBytes;
LARGE_INTEGER fileSizeBytesCeil;
LARGE_INTEGER bytesReadStarted;
LARGE_INTEGER bytesWriteStarted;
LARGE_INTEGER bytesWriten;
int main() {
HANDLE hThisProcess;
OpenProcessToken(
GetCurrentProcess(), //Process handle
TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY, //Rights we need to manage priviliges
&hThisProcess //Where to write token
);
//Must be here b4 creating(opening) files
bool canEnlargeFile = SetPrivilege(hThisProcess, SE_MANAGE_VOLUME_NAME, true);
if (!canEnlargeFile) {
std::cout << "We will go syncronously :c\n";
}
CloseHandle(hThisProcess);
hFileSource = createFileOverlapped(sourceFileName, true);
hFileTarget = createFileOverlapped(targetFileName, false);
GetFileSizeEx(hFileSource, &fileSizeBytes);
fileSizeBytesCeil.QuadPart = (fileSizeBytes.QuadPart / bufferSizeBytes + ((fileSizeBytes.QuadPart % bufferSizeBytes) ? 1 : 0)) * bufferSizeBytes;
SetFilePointerEx(hFileTarget, fileSizeBytesCeil, 0, FILE_BEGIN);
SetEndOfFile(hFileTarget);
if (canEnlargeFile) {
canEnlargeFile = SetFileValidData(hFileTarget, fileSizeBytesCeil.QuadPart);
if (!canEnlargeFile) {
std::cout << "We will go syncronously :c\n";
}
}
for (int i = 0; i < numberOfAsyncOps; ++i) {
buffer[i] = new BYTE[bufferSizeBytes];
}
bytesReadStarted.QuadPart = 0;
bytesWriteStarted.QuadPart = 0;
bytesWriten.QuadPart = 0;
DWORD beginCopy = GetTickCount();
for (int i = 0; i < numberOfAsyncOps; ++i) {
olStruct[i].OffsetHigh = bytesReadStarted.HighPart;
olStruct[i].Offset = bytesReadStarted.LowPart;
olStruct[i].InternalHigh = 0;
olStruct[i].Internal = 0;
olStruct[i].hEvent = (HANDLE)i;
if (bytesReadStarted.QuadPart < fileSizeBytes.QuadPart) {
ReadFileEx(hFileSource, buffer[i], bufferSizeBytes, olStruct + i, endOfReading);
}
bytesReadStarted.QuadPart += bufferSizeBytes;
}
while (bytesWriten.QuadPart < fileSizeBytesCeil.QuadPart) {
SleepEx(500, true);
//std::cout << bytesWriten.QuadPart << " bytes written of " << fileSizeBytesCeil.QuadPart << std::endl;
}
SetFilePointerEx(hFileTarget, fileSizeBytes, 0, FILE_BEGIN);
SetEndOfFile(hFileTarget);
DWORD endCopy = GetTickCount();
std::cout << (endCopy - beginCopy) << std::endl;
////CLEAR ALL THE STUFF
CloseHandle(hFileSource);
CloseHandle(hFileTarget);
for (int i = 0; i < numberOfAsyncOps; ++i) {
delete[] buffer[i];
}
system("pause");
}
VOID WINAPI endOfReading(DWORD errorCode, DWORD numberOfBytes, LPOVERLAPPED pOl) {
int i = (int)pOl->hEvent;
pOl->InternalHigh = 0;
pOl->Internal = 0;
WriteFileEx(hFileTarget, buffer[i], bufferSizeBytes, pOl, endOfWriting);
bytesWriteStarted.QuadPart += bufferSizeBytes;
}
VOID WINAPI endOfWriting(DWORD errorCode, DWORD numberOfBytes, LPOVERLAPPED pOl) {
int i = (int)pOl->hEvent;
bytesWriten.QuadPart += bufferSizeBytes;
if (bytesReadStarted.QuadPart >= fileSizeBytesCeil.QuadPart) {
return;
}
pOl->OffsetHigh = bytesReadStarted.HighPart;
pOl->Offset = bytesReadStarted.LowPart;
pOl->InternalHigh = 0;
pOl->Internal = 0;
ReadFileEx(hFileSource, buffer[i], bufferSizeBytes, pOl, endOfReading);
bytesReadStarted.QuadPart += bufferSizeBytes;
}
HANDLE createFileOverlapped(std::wstring nameOfFile, bool exist) {
HANDLE handle;
if (exist) {
handle = CreateFile(nameOfFile.c_str(),
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL
);
}
else {
handle = CreateFile(nameOfFile.c_str(),
GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_FLAG_OVERLAPPED | FILE_FLAG_NO_BUFFERING, NULL
);
}
if (handle == INVALID_HANDLE_VALUE) {
std::cerr << GetLastError() << std::endl;
}
return handle;
}
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
LUID luid;
if (!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
printf("LookupPrivilegeValue error: %u\n", GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
if (bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges.
if (!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES)NULL,
(PDWORD)NULL)
)
{
printf("AdjustTokenPrivileges error: %u\n", GetLastError());
return FALSE;
}
if (GetLastError() == ERROR_NOT_ALL_ASSIGNED)
{
printf("The token does not have the specified privilege. \n");
return FALSE;
}
return TRUE;
}