1
0
This commit is contained in:
Scott E. Graves
2017-04-05 23:49:49 -05:00
parent 2be0d08359
commit 8834eb76d2
2 changed files with 361 additions and 245 deletions

View File

@@ -61,9 +61,9 @@ class SIADRIVE_DOKAN_EXPORTABLE DriveMountEnded :
public CEvent
{
public:
DriveMountEnded(const SString mountLocation, const NTSTATUS& mountStatus) :
DriveMountEnded(const SString mountLocation, const NTSTATUS& result) :
_mountLocation(mountLocation),
_mountStatus(mountStatus)
_result(result)
{
}
@@ -74,17 +74,17 @@ public:
private:
const SString _mountLocation;
const NTSTATUS _mountStatus;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DriveMountEnded(_mountLocation, _mountStatus));
return std::shared_ptr<CEvent>(new DriveMountEnded(_mountLocation, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DriveMountEnded|LOC|" + _mountLocation + L"|STATUS|" + SString::FromInt32(_mountStatus);
return L"DriveMountEnded|LOC|" + _mountLocation + L"|RET|" + SString::FromInt32(_result);
}
};
@@ -153,13 +153,13 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanCreateFile :
public CEvent
{
public:
DokanCreateFile(const SString& filePath, const DWORD& fileAttributesAndFlags, const DWORD& creationDisposition, const ACCESS_MASK& genericDesiredAccess, const NTSTATUS& returnStatus) :
DokanCreateFile(const SString& filePath, const DWORD& fileAttributesAndFlags, const DWORD& creationDisposition, const ACCESS_MASK& genericDesiredAccess, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_filePath(filePath),
_fileAttributesAndFlags(fileAttributesAndFlags),
_creationDisposition(creationDisposition),
_genericDesiredAccess(genericDesiredAccess),
_returnStatus(returnStatus)
_result(result)
{
}
@@ -174,12 +174,12 @@ private:
const DWORD _fileAttributesAndFlags;
const DWORD _creationDisposition;
const ACCESS_MASK _genericDesiredAccess;
const NTSTATUS _returnStatus;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanCreateFile(_filePath, _fileAttributesAndFlags, _creationDisposition, _genericDesiredAccess, _returnStatus));
return std::shared_ptr<CEvent>(new DokanCreateFile(_filePath, _fileAttributesAndFlags, _creationDisposition, _genericDesiredAccess, _result));
}
virtual SString GetSingleLineMessage() const override
@@ -188,7 +188,7 @@ public:
"|ATTR|" + SString::FromUInt32(_fileAttributesAndFlags) +
"|DISP|" + SString::FromUInt32(_creationDisposition) +
"|MASK|" + SString::FromUInt32(_genericDesiredAccess) +
"|RET|" + SString::FromUInt32(_returnStatus);
"|RET|" + SString::FromUInt32(_result);
}
};
@@ -197,13 +197,14 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanFindFiles :
public CEvent
{
public:
DokanFindFiles(const SString& cachePath, const SString& rootPath, const SString& siaQuery, const SString& findFile, const SString& fileName) :
DokanFindFiles(const SString& cachePath, const SString& rootPath, const SString& siaQuery, const SString& findFile, const SString& fileName, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath),
_rootPath(rootPath),
_siaQuery(siaQuery),
_findFile(findFile),
_fileName(fileName)
_fileName(fileName),
_result(result)
{
}
@@ -218,11 +219,12 @@ private:
const SString _siaQuery;
const SString _findFile;
const SString _fileName;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanFindFiles(_cachePath, _rootPath, _siaQuery, _findFile, _fileName));
return std::shared_ptr<CEvent>(new DokanFindFiles(_cachePath, _rootPath, _siaQuery, _findFile, _fileName, _result));
}
virtual SString GetSingleLineMessage() const override
@@ -231,7 +233,8 @@ public:
"|ROOT|" + _rootPath +
"|QUERY|" + _siaQuery +
"|FIND|" + _findFile +
"|FN|" + _fileName;
"|FN|" + _fileName +
"|RET|" + SString::FromUInt32(_result);
}
};
@@ -270,10 +273,11 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanGetFileInformation :
public CEvent
{
public:
DokanGetFileInformation(const SString& cachePath, const SString& fileName, const NTSTATUS& result) :
DokanGetFileInformation(const SString& cachePath, const SString& fileName, const bool& opened, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath),
_fileName(fileName),
_opened(opened),
_result(result)
{
}
@@ -286,17 +290,21 @@ public:
private:
const SString _cachePath;
const SString _fileName;
const bool _opened;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanGetFileInformation(_cachePath, _fileName, _result));
return std::shared_ptr<CEvent>(new DokanGetFileInformation(_cachePath, _fileName, _opened, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanGetFileInformation|PATH|" + _cachePath + "|FN|" + _fileName + "|RES|" + SString::FromUInt32(_result);
return L"DokanGetFileInformation|PATH|" + _cachePath +
"|FN|" + _fileName +
"|OPN|" + SString::FromBool(_opened) +
"|RES|" + SString::FromUInt32(_result);
}
};
@@ -305,9 +313,11 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanReadFile :
public CEvent
{
public:
DokanReadFile(const SString& cachePath) :
DokanReadFile(const SString& cachePath, const bool& opened, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath)
_cachePath(cachePath),
_opened(opened),
_result(result)
{
}
@@ -318,27 +328,32 @@ public:
private:
const SString _cachePath;
const bool _opened;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanReadFile(_cachePath));
return std::shared_ptr<CEvent>(new DokanReadFile(_cachePath, _opened, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanReadFile|PATH|" + _cachePath;
return L"DokanReadFile|PATH|" + _cachePath +
"|OPN|" + SString::FromBool(_opened) +
"|RES|" + SString::FromUInt32(_result);
}
};
class SIADRIVE_DOKAN_EXPORTABLE DokanWriteFile :
public CEvent
{
public:
DokanWriteFile(const SString& cachePath) :
DokanWriteFile(const SString& cachePath, const bool& opened, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath)
_cachePath(cachePath),
_opened(opened),
_result(result)
{
}
@@ -349,16 +364,20 @@ public:
private:
const SString _cachePath;
const bool _opened;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanWriteFile(_cachePath));
return std::shared_ptr<CEvent>(new DokanWriteFile(_cachePath, _opened, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanWriteFile|PATH|" + _cachePath;
return L"DokanWriteFile|PATH|" + _cachePath +
"|OPN|" + SString::FromBool(_opened) +
"|RES|" + SString::FromUInt32(_result);
}
};
@@ -367,9 +386,10 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanSetEndOfFile :
public CEvent
{
public:
DokanSetEndOfFile(const SString& cachePath) :
DokanSetEndOfFile(const SString& cachePath, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath)
_cachePath(cachePath),
_result(result)
{
}
@@ -380,16 +400,18 @@ public:
private:
const SString _cachePath;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanSetEndOfFile(_cachePath));
return std::shared_ptr<CEvent>(new DokanSetEndOfFile(_cachePath, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanSetEndOfFile|PATH|" + _cachePath;
return L"DokanSetEndOfFile|PATH|" + _cachePath +
"|RES|" + SString::FromUInt32(_result);
}
};
@@ -398,9 +420,10 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanFlushFileBuffers :
public CEvent
{
public:
DokanFlushFileBuffers(const SString& cachePath) :
DokanFlushFileBuffers(const SString& cachePath, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath)
_cachePath(cachePath),
_result(result)
{
}
@@ -411,16 +434,18 @@ public:
private:
const SString _cachePath;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanFlushFileBuffers(_cachePath));
return std::shared_ptr<CEvent>(new DokanFlushFileBuffers(_cachePath, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanFlushFileBuffers|PATH|" + _cachePath;
return L"DokanFlushFileBuffers|PATH|" + _cachePath +
"|RES|" + SString::FromUInt32(_result);
}
};
@@ -429,8 +454,9 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanDeleteDirectory :
public CEvent
{
public:
DokanDeleteDirectory(const SString& cachePath) :
_cachePath(cachePath)
DokanDeleteDirectory(const SString& cachePath, const NTSTATUS& result) :
_cachePath(cachePath),
_result(result)
{
}
@@ -441,16 +467,18 @@ public:
private:
const SString _cachePath;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanDeleteDirectory(_cachePath));
return std::shared_ptr<CEvent>(new DokanDeleteDirectory(_cachePath, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanDeleteDirectory|PATH|" + _cachePath;
return L"DokanDeleteDirectory|PATH|" + _cachePath +
"|RES|" + SString::FromUInt32(_result);
}
};
@@ -459,9 +487,10 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanDeleteFileW :
public CEvent
{
public:
DokanDeleteFileW(const SString& cachePath) :
DokanDeleteFileW(const SString& cachePath, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath)
_cachePath(cachePath),
_result(result)
{
}
@@ -472,16 +501,18 @@ public:
private:
const SString _cachePath;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanDeleteFileW(_cachePath));
return std::shared_ptr<CEvent>(new DokanDeleteFileW(_cachePath, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanDeleteFileW|PATH|" + _cachePath;
return L"DokanDeleteFileW|PATH|" + _cachePath +
"|RES|" + SString::FromUInt32(_result);
}
};
@@ -490,10 +521,10 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanSetFileAttributesW :
public CEvent
{
public:
DokanSetFileAttributesW(const SString& cachePath, const NTSTATUS& ret) :
DokanSetFileAttributesW(const SString& cachePath, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath),
_ret(ret)
_result(result)
{
}
@@ -504,17 +535,18 @@ public:
private:
const SString _cachePath;
const NTSTATUS _ret;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanSetFileAttributesW(_cachePath, _ret));
return std::shared_ptr<CEvent>(new DokanSetFileAttributesW(_cachePath, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanSetFileAttributesW|PATH|" + _cachePath + "|RET|" + SString::FromUInt64(_ret);
return L"DokanSetFileAttributesW|PATH|" + _cachePath +
"|RES|" + SString::FromUInt64(_result);
}
};
@@ -585,9 +617,10 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanSetFileTime :
public CEvent
{
public:
DokanSetFileTime(const SString& cachePath) :
DokanSetFileTime(const SString& cachePath, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath)
_cachePath(cachePath),
_result(result)
{
}
@@ -598,16 +631,18 @@ public:
private:
const SString _cachePath;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanSetFileTime(_cachePath));
return std::shared_ptr<CEvent>(new DokanSetFileTime(_cachePath, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanSetFileTime|PATH|" + _cachePath;
return L"DokanSetFileTime|PATH|" + _cachePath +
"|RES|" + SString::FromUInt64(_result);
}
};
@@ -616,9 +651,10 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanSetAllocationSize :
public CEvent
{
public:
DokanSetAllocationSize(const SString& cachePath) :
DokanSetAllocationSize(const SString& cachePath, const NTSTATUS& result) :
CEvent(EventLevel::Debug),
_cachePath(cachePath)
_cachePath(cachePath),
_result(result)
{
}
@@ -629,16 +665,18 @@ public:
private:
const SString _cachePath;
const NTSTATUS _result;
public:
virtual std::shared_ptr<CEvent> Clone() const override
{
return std::shared_ptr<CEvent>(new DokanSetAllocationSize(_cachePath));
return std::shared_ptr<CEvent>(new DokanSetAllocationSize(_cachePath, _result));
}
virtual SString GetSingleLineMessage() const override
{
return L"DokanSetAllocationSize|PATH|" + _cachePath;
return L"DokanSetAllocationSize|PATH|" + _cachePath +
"|RES|" + SString::FromUInt64(_result);
}
};

View File

@@ -102,7 +102,6 @@ private:
});
th.detach();
DokanResetTimeout(1000 * 60 * 5, dokanFileInfo);
while (active)
{
::Sleep(10);
@@ -123,6 +122,7 @@ private:
if (deleteOnClose)
{
// TODO Handle failure
::CloseHandle(openFileInfo.FileHandle);
_uploadManager->Remove(openFileInfo.SiaPath);
}
else
@@ -142,16 +142,26 @@ private:
FILETIME fileTimes[3];
if (GetFileTime(openFileInfo.FileHandle, &fileTimes[0], &fileTimes[1], &fileTimes[2]))
{
::CloseHandle(openFileInfo.FileHandle);
_uploadManager->AddOrUpdate(openFileInfo.SiaPath, openFileInfo.CacheFilePath, *reinterpret_cast<std::uint64_t*>(&fileTimes[2]));
}
else
{
::CloseHandle(openFileInfo.FileHandle);
}
}
else
{
::CloseHandle(openFileInfo.FileHandle);
// TODO Handle error return
// Treat 0 length files as deleted in Sia - cache retains 0-length
_uploadManager->Remove(openFileInfo.SiaPath);
}
}
else
{
::CloseHandle(openFileInfo.FileHandle);
}
}
static void StartFileListThread()
@@ -189,10 +199,7 @@ private:
CSiaFileTreePtr siaFileTree;
_siaApi->GetRenter()->GetFileTree(siaFileTree);
{
std::lock_guard<std::mutex> l(_fileTreeMutex);
_siaFileTree = siaFileTree;
}
_siaFileTree = siaFileTree;
}
// Dokan callbacks
@@ -506,8 +513,6 @@ private:
}
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFindFiles(cachePath, siaDirQuery, siaFileQuery, findFile, fileName)));
WIN32_FIND_DATA findData = { 0 };
HANDLE findHandle = ::FindFirstFile(&findFile[0], &findData);
if (findHandle == INVALID_HANDLE_VALUE)
@@ -602,7 +607,13 @@ private:
ret = DokanNtStatusFromWin32(error);
}
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFindFiles(cachePath, siaDirQuery, siaFileQuery, findFile, fileName, ret)));
}
else
{
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFindFiles("", "", "", "", fileName, ret)));
}
return ret;
}
@@ -613,13 +624,17 @@ private:
if (dokanFileInfo->Context)
{
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (!dokanFileInfo->IsDirectory)
if (dokanFileInfo->IsDirectory)
{
::CloseHandle(openFileInfo->FileHandle);
}
else
{
LARGE_INTEGER li = { 0 };
::GetFileSizeEx(openFileInfo->FileHandle, &li);
HandleSiaFileClose(*openFileInfo, li.QuadPart, dokanFileInfo->DeleteOnClose ? true : false);
}
::CloseHandle(openFileInfo->FileHandle);
delete openFileInfo;
dokanFileInfo->Context = 0;
}
@@ -628,7 +643,7 @@ private:
static NTSTATUS DOKAN_CALLBACK Sia_GetFileInformation(LPCWSTR fileName, LPBY_HANDLE_FILE_INFORMATION handleFileInfo, PDOKAN_FILE_INFO dokanFileInfo)
{
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
BOOL opened = FALSE;
bool opened = false;
NTSTATUS ret = STATUS_SUCCESS;
auto siaFileTree = GetFileTree();
@@ -645,7 +660,7 @@ private:
}
else
{
opened = TRUE;
opened = true;
}
}
@@ -697,7 +712,7 @@ private:
::CloseHandle(tempHandle);
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanGetFileInformation(openFileInfo->CacheFilePath, fileName, ret)));
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanGetFileInformation(openFileInfo->CacheFilePath, fileName, opened, ret)));
return ret;
}
@@ -763,55 +778,73 @@ private:
LONGLONG offset,
PDOKAN_FILE_INFO dokanFileInfo)
{
FilePath filePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanReadFile(filePath)));
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
NTSTATUS ret = STATUS_SUCCESS;
bool opened = false;
FilePath filePath(GetCacheLocation(), fileName);
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (openFileInfo && openFileInfo->Dummy)
{
// TODO taking too long
if (!AddFileToCache(*openFileInfo, dokanFileInfo))
{
return STATUS_INVALID_DEVICE_STATE;
ret = STATUS_INVALID_DEVICE_STATE;
}
}
HANDLE tempHandle = openFileInfo ? openFileInfo->FileHandle : 0;
BOOL opened = FALSE;
if (!tempHandle || (tempHandle == INVALID_HANDLE_VALUE))
{
// TODO Need to add to cache if missing
tempHandle = ::CreateFile(&filePath[0], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (tempHandle == INVALID_HANDLE_VALUE)
{
DWORD error = GetLastError();
return DokanNtStatusFromWin32(error);
}
opened = TRUE;
}
if (ret == STATUS_SUCCESS)
{
if (!tempHandle || (tempHandle == INVALID_HANDLE_VALUE))
{
// TODO taking too long
if (!filePath.IsFile())
{
if (!AddFileToCache(*openFileInfo, dokanFileInfo))
{
ret = STATUS_INVALID_DEVICE_STATE;
}
}
LARGE_INTEGER distanceToMove;
distanceToMove.QuadPart = offset;
if (!::SetFilePointerEx(tempHandle, distanceToMove, nullptr, FILE_BEGIN))
{
DWORD error = GetLastError();
if (opened)
CloseHandle(tempHandle);
return DokanNtStatusFromWin32(error);
}
if (ret == STATUS_SUCCESS)
{
tempHandle = ::CreateFile(&filePath[0], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (tempHandle == INVALID_HANDLE_VALUE)
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
else
{
opened = true;
}
}
}
if (!::ReadFile(tempHandle, buffer, bufferLen, readLength, nullptr))
{
DWORD error = GetLastError();
if (opened)
CloseHandle(tempHandle);
return DokanNtStatusFromWin32(error);
}
if (ret == STATUS_SUCCESS)
{
LARGE_INTEGER distanceToMove;
distanceToMove.QuadPart = offset;
if (!::SetFilePointerEx(tempHandle, distanceToMove, nullptr, FILE_BEGIN))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
else if (!::ReadFile(tempHandle, buffer, bufferLen, readLength, nullptr))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
}
}
if (opened)
CloseHandle(tempHandle);
if (opened)
{
::CloseHandle(tempHandle);
}
return STATUS_SUCCESS;
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanReadFile(filePath, opened, ret)));
return ret;
}
static NTSTATUS DOKAN_CALLBACK Sia_WriteFile(LPCWSTR fileName, LPCVOID buffer,
@@ -820,149 +853,193 @@ private:
LONGLONG offset,
PDOKAN_FILE_INFO dokanFileInfo)
{
// TODO Check dummy and add to cache if not found
NTSTATUS ret = STATUS_SUCCESS;
FilePath filePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanWriteFile(filePath)));
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (openFileInfo && openFileInfo->Dummy)
{
// TODO taking too long
if (!AddFileToCache(*openFileInfo, dokanFileInfo))
{
ret = STATUS_INVALID_DEVICE_STATE;
}
}
BOOL opened = FALSE;
bool opened = false;
HANDLE tempHandle = openFileInfo ? openFileInfo->FileHandle : 0;
if (!tempHandle || (tempHandle == INVALID_HANDLE_VALUE))
{
tempHandle = ::CreateFile(&filePath[0], GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (tempHandle == INVALID_HANDLE_VALUE)
{
DWORD error = GetLastError();
return DokanNtStatusFromWin32(error);
}
opened = TRUE;
// TODO taking too long
if (!filePath.IsFile())
{
if (!AddFileToCache(*openFileInfo, dokanFileInfo))
{
ret = STATUS_INVALID_DEVICE_STATE;
}
}
if (ret == STATUS_SUCCESS)
{
tempHandle = ::CreateFile(&filePath[0], GENERIC_WRITE, FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr);
if (tempHandle == INVALID_HANDLE_VALUE)
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
else
{
opened = true;
}
}
}
LARGE_INTEGER li = { 0 };
if (!::GetFileSizeEx(tempHandle, &li))
{
DWORD error = GetLastError();
if (opened)
CloseHandle(tempHandle);
return DokanNtStatusFromWin32(error);
}
LARGE_INTEGER distanceToMove;
if (dokanFileInfo->WriteToEndOfFile)
{
LARGE_INTEGER z = {0};
if (!::SetFilePointerEx(tempHandle, z, nullptr, FILE_END))
{
DWORD error = GetLastError();
if (opened)
::CloseHandle(tempHandle);
return DokanNtStatusFromWin32(error);
}
}
else
{
// Paging IO cannot write after allocate file size.
if (dokanFileInfo->PagingIo)
{
if (offset >= li.QuadPart)
{
*bytesWritten = 0;
if (opened)
CloseHandle(tempHandle);
return STATUS_SUCCESS;
}
if ((offset + bytesToWrite) > li.QuadPart)
{
UINT64 bytes = li.QuadPart - offset;
if (bytes >> 32)
{
bytesToWrite = static_cast<DWORD>(bytes & 0xFFFFFFFFUL);
}
else
{
bytesToWrite = static_cast<DWORD>(bytes);
}
}
}
if (offset > li.QuadPart)
{
// In the mirror sample helperZeroFileData is not necessary. NTFS will
// zero a hole.
// But if user's file system is different from NTFS( or other Windows's
// file systems ) then users will have to zero the hole themselves.
}
distanceToMove.QuadPart = offset;
if (!::SetFilePointerEx(tempHandle, distanceToMove, nullptr, FILE_BEGIN))
{
DWORD error = GetLastError();
if (opened)
CloseHandle(tempHandle);
return DokanNtStatusFromWin32(error);
}
}
if (::WriteFile(tempHandle, buffer, bytesToWrite, bytesWritten, nullptr))
{
if (openFileInfo)
openFileInfo->Changed = true;
}
else
if (ret == STATUS_SUCCESS)
{
DWORD error = GetLastError();
if (opened)
CloseHandle(tempHandle);
return DokanNtStatusFromWin32(error);
}
if (!::GetFileSizeEx(tempHandle, &li))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
else
{
LARGE_INTEGER distanceToMove;
if (dokanFileInfo->WriteToEndOfFile)
{
LARGE_INTEGER z = { 0 };
if (!::SetFilePointerEx(tempHandle, z, nullptr, FILE_END))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
}
else
{
// Paging IO cannot write after allocate file size.
if (dokanFileInfo->PagingIo)
{
if (offset >= li.QuadPart)
{
*bytesWritten = 0;
if (opened)
{
::CloseHandle(tempHandle);
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanWriteFile(filePath, opened, ret)));
return ret;
}
if ((offset + bytesToWrite) > li.QuadPart)
{
UINT64 bytes = li.QuadPart - offset;
if (bytes >> 32)
{
bytesToWrite = static_cast<DWORD>(bytes & 0xFFFFFFFFUL);
}
else
{
bytesToWrite = static_cast<DWORD>(bytes);
}
}
}
if (offset > li.QuadPart)
{
// In the mirror sample helperZeroFileData is not necessary. NTFS will
// zero a hole.
// But if user's file system is different from NTFS( or other Windows's
// file systems ) then users will have to zero the hole themselves.
}
distanceToMove.QuadPart = offset;
if (!::SetFilePointerEx(tempHandle, distanceToMove, nullptr, FILE_BEGIN))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
}
if (ret == STATUS_SUCCESS)
{
if (::WriteFile(tempHandle, buffer, bytesToWrite, bytesWritten, nullptr))
{
if (openFileInfo)
{
openFileInfo->Changed = true;
}
}
else
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
}
}
}
if (opened)
{
// TODO HandleSiaFileClose
CloseHandle(tempHandle);
OpenFileInfo ofi;
ofi.FileHandle = tempHandle;
ofi.CacheFilePath = filePath;
ofi.Changed = true;
ofi.Dummy = false;
ofi.SiaPath = CSiaApi::FormatToSiaPath(fileName);;
HandleSiaFileClose(ofi, li.QuadPart, false);
}
return STATUS_SUCCESS;
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanWriteFile(filePath, opened, ret)));
return ret;
}
static NTSTATUS DOKAN_CALLBACK Sia_SetEndOfFile(LPCWSTR fileName, LONGLONG byteOffset, PDOKAN_FILE_INFO dokanFileInfo)
{
NTSTATUS ret = STATUS_SUCCESS;
// TODO Check dummy and add to cache if not found
FilePath filePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanSetEndOfFile(filePath)));
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (!openFileInfo || !openFileInfo->FileHandle || (openFileInfo->FileHandle == INVALID_HANDLE_VALUE))
{
ret = STATUS_INVALID_HANDLE;
}
else
if (openFileInfo && openFileInfo->Dummy)
{
LARGE_INTEGER sz = { 0 };
::GetFileSizeEx(openFileInfo->FileHandle, &sz);
LARGE_INTEGER offset;
offset.QuadPart = byteOffset;
if (!::SetFilePointerEx(openFileInfo->FileHandle, offset, nullptr, FILE_BEGIN))
// TODO taking too long
if (!AddFileToCache(*openFileInfo, dokanFileInfo))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
else if (!::SetEndOfFile(openFileInfo->FileHandle))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
if (ret == STATUS_SUCCESS)
{
openFileInfo->Changed = (offset.QuadPart != (sz.QuadPart - 1)) ;
ret = STATUS_INVALID_DEVICE_STATE;
}
}
if (ret == STATUS_SUCCESS)
{
if (!openFileInfo || !openFileInfo->FileHandle || (openFileInfo->FileHandle == INVALID_HANDLE_VALUE))
{
ret = STATUS_INVALID_HANDLE;
}
else
{
LARGE_INTEGER sz = { 0 };
::GetFileSizeEx(openFileInfo->FileHandle, &sz);
LARGE_INTEGER offset;
offset.QuadPart = byteOffset;
if (!::SetFilePointerEx(openFileInfo->FileHandle, offset, nullptr, FILE_BEGIN))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
else if (!::SetEndOfFile(openFileInfo->FileHandle))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
if (ret == STATUS_SUCCESS)
{
openFileInfo->Changed = (offset.QuadPart != (sz.QuadPart - 1));
}
}
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanSetEndOfFile(filePath, ret)));
return ret;
}
@@ -972,13 +1049,17 @@ private:
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (dokanFileInfo->Context)
{
if (!dokanFileInfo->IsDirectory)
if (dokanFileInfo->IsDirectory)
{
::CloseHandle(openFileInfo->FileHandle);
}
else
{
LARGE_INTEGER li = { 0 };
::GetFileSizeEx(openFileInfo->FileHandle, &li);
HandleSiaFileClose(*openFileInfo, li.QuadPart, dokanFileInfo->DeleteOnClose ? true : false);
}
::CloseHandle(openFileInfo->FileHandle);
delete openFileInfo;
dokanFileInfo->Context = 0;
}
@@ -1011,31 +1092,26 @@ private:
static NTSTATUS DOKAN_CALLBACK Sia_FlushFileBuffers(LPCWSTR fileName, PDOKAN_FILE_INFO dokanFileInfo)
{
NTSTATUS ret = STATUS_SUCCESS;
FilePath filePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFlushFileBuffers(filePath)));
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (!openFileInfo || !openFileInfo->FileHandle || (openFileInfo->FileHandle == INVALID_HANDLE_VALUE))
{
return STATUS_SUCCESS;
}
if (openFileInfo && openFileInfo->FileHandle && (openFileInfo->FileHandle != INVALID_HANDLE_VALUE))
{
if (!::FlushFileBuffers(openFileInfo->FileHandle))
{
DWORD error = GetLastError();
ret = DokanNtStatusFromWin32(error);
}
}
if (::FlushFileBuffers(openFileInfo->FileHandle))
{
return STATUS_SUCCESS;
}
else
{
DWORD error = GetLastError();
return DokanNtStatusFromWin32(error);
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFlushFileBuffers(filePath, ret)));
return ret;
}
static NTSTATUS DOKAN_CALLBACK Sia_DeleteDirectory(LPCWSTR fileName, PDOKAN_FILE_INFO dokanFileInfo)
{
FilePath filePath = FilePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanDeleteDirectory(filePath)));
NTSTATUS ret = STATUS_SUCCESS;
if (dokanFileInfo->DeleteOnClose)
{
@@ -1071,6 +1147,7 @@ private:
}
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanDeleteDirectory(filePath, ret)));
return ret;
}
@@ -1081,7 +1158,6 @@ private:
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
FilePath filePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanDeleteFileW(filePath)));
DWORD dwAttrib = ::GetFileAttributes(&filePath[0]);
if ((dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY))
@@ -1098,12 +1174,14 @@ private:
}
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanDeleteFileW(filePath, ret)));
return ret;
}
static NTSTATUS DOKAN_CALLBACK Sia_MoveFileW(LPCWSTR fileName, LPCWSTR NewFileName, BOOL ReplaceIfExisting, PDOKAN_FILE_INFO dokanFileInfo)
{
// TODO Check dummy and add to cache if not found
// TODO Implement Sia rename
NTSTATUS ret = STATUS_SUCCESS;
FilePath filePath(GetCacheLocation(), fileName);
@@ -1245,22 +1323,22 @@ private:
CONST FILETIME *lastAccessTime, CONST FILETIME *lastWriteTime,
PDOKAN_FILE_INFO dokanFileInfo)
{
NTSTATUS ret = STATUS_SUCCESS;
FilePath filePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanSetFileTime(filePath)));
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (!openFileInfo || !openFileInfo->FileHandle || (openFileInfo->FileHandle == INVALID_HANDLE_VALUE))
{
return STATUS_INVALID_HANDLE;
ret = STATUS_INVALID_HANDLE;
}
if (!::SetFileTime(openFileInfo->FileHandle, creationTime, lastAccessTime, lastWriteTime))
else if (!::SetFileTime(openFileInfo->FileHandle, creationTime, lastAccessTime, lastWriteTime))
{
DWORD error = GetLastError();
return DokanNtStatusFromWin32(error);
ret = DokanNtStatusFromWin32(error);
}
return STATUS_SUCCESS;
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanSetFileTime(filePath, ret)));
return ret;
}
static NTSTATUS DOKAN_CALLBACK Sia_SetAllocationSize(LPCWSTR fileName, LONGLONG allocSize, PDOKAN_FILE_INFO dokanFileInfo)
@@ -1268,7 +1346,6 @@ private:
// TODO Check dummy and add to cache if not found
NTSTATUS ret = STATUS_SUCCESS;
FilePath filePath(GetCacheLocation(), fileName);
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanSetAllocationSize(filePath)));
auto openFileInfo = reinterpret_cast<OpenFileInfo*>(dokanFileInfo->Context);
if (!openFileInfo || !openFileInfo->FileHandle || (openFileInfo->FileHandle == INVALID_HANDLE_VALUE))
@@ -1302,6 +1379,7 @@ private:
}
}
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanSetAllocationSize(filePath, ret)));
return ret;
}