diff --git a/src/siadrive_dokan_api/siadokandrive.cpp b/src/siadrive_dokan_api/siadokandrive.cpp index 07fadfa..97574dc 100644 --- a/src/siadrive_dokan_api/siadokandrive.cpp +++ b/src/siadrive_dokan_api/siadokandrive.cpp @@ -33,7 +33,7 @@ private: static FilePath _cacheLocation; static std::unordered_map _openFileMap; static std::unique_ptr _fileListThread; - static bool _fileListStopRequested; + static HANDLE _fileListStopEvent; static CSiaFileTreePtr _siaFileTree; static std::mutex _fileTreeMutex; static std::unique_ptr _mountThread; @@ -48,12 +48,11 @@ private: static bool AddFileToCache(const SString& siaPath, const SString& cacheLocation) { - bool ret = false; FilePath tempFilePath = FilePath::GetTempDirectory(); tempFilePath.Append(GenerateSha256(siaPath) + ".siatmp"); // TODO Check cache size is large enough to hold new file - ret = ApiSuccess(_siaApi->GetRenter()->DownloadFile(siaPath, tempFilePath)); + bool ret = ApiSuccess(_siaApi->GetRenter()->DownloadFile(siaPath, tempFilePath)); if (ret) { FilePath src(tempFilePath); @@ -106,10 +105,10 @@ private: { if (!_fileListThread) { - _fileListStopRequested = false; + _fileListStopEvent = ::CreateEvent(nullptr, FALSE, FALSE, nullptr); _fileListThread.reset(new std::thread([]() { - while (!_fileListStopRequested) + do { CSiaFileTreePtr siaFileTree; _siaApi->GetRenter()->GetFileTree(siaFileTree); @@ -117,13 +116,7 @@ private: std::lock_guard l(_fileTreeMutex); _siaFileTree = siaFileTree; } - - if (!_fileListStopRequested) - { - // TODO Change to WaitForSingleObject() for immediate termination - Sleep(1000); - } - } + } while (::WaitForSingleObject(_fileListStopEvent, 1000) == WAIT_TIMEOUT); })); } } @@ -132,63 +125,64 @@ private: { if (_fileListThread) { - _fileListStopRequested = true; + ::SetEvent(_fileListStopEvent); _fileListThread->join(); _fileListThread.reset(nullptr); + ::CloseHandle(_fileListStopEvent); } } // Dokan callbacks private: static NTSTATUS DOKAN_CALLBACK Sia_ZwCreateFile( - LPCWSTR FileName, - PDOKAN_IO_SECURITY_CONTEXT SecurityContext, - ACCESS_MASK DesiredAccess, - ULONG FileAttributes, - ULONG ShareAccess, - ULONG CreateDisposition, - ULONG CreateOptions, - PDOKAN_FILE_INFO DokanFileInfo) + LPCWSTR fileName, + PDOKAN_IO_SECURITY_CONTEXT securityContext, + ACCESS_MASK desiredAccess, + ULONG fileAttributes, + ULONG shareAccess, + ULONG createDisposition, + ULONG createOptions, + PDOKAN_FILE_INFO dokanFileInfo) { SECURITY_ATTRIBUTES securityAttrib; securityAttrib.nLength = sizeof(securityAttrib); - securityAttrib.lpSecurityDescriptor = SecurityContext->AccessState.SecurityDescriptor; + securityAttrib.lpSecurityDescriptor = securityContext->AccessState.SecurityDescriptor; securityAttrib.bInheritHandle = FALSE; DWORD fileAttributesAndFlags; DWORD creationDisposition; - DokanMapKernelToUserCreateFileFlags(FileAttributes, CreateOptions, CreateDisposition, &fileAttributesAndFlags, &creationDisposition); + DokanMapKernelToUserCreateFileFlags(fileAttributes, createOptions, createDisposition, &fileAttributesAndFlags, &creationDisposition); - ACCESS_MASK genericDesiredAccess = DokanMapStandardToGenericAccess(DesiredAccess); + ACCESS_MASK genericDesiredAccess = DokanMapStandardToGenericAccess(desiredAccess); NTSTATUS ret = STATUS_SUCCESS; // Probably not going to happen, but just in case - if (FilePath(FileName).IsUNC()) + if (FilePath(fileName).IsUNC()) { ret = STATUS_ILLEGAL_ELEMENT_ADDRESS; - CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanCreateFile(FileName, fileAttributesAndFlags, creationDisposition, genericDesiredAccess, ret))); + CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanCreateFile(fileName, fileAttributesAndFlags, creationDisposition, genericDesiredAccess, ret))); } else { // When filePath is a directory, needs to change the flag so that the file can // be opened. - FilePath cacheFilePath(GetCacheLocation(), &FileName[1]); + FilePath cacheFilePath(GetCacheLocation(), &fileName[1]); DWORD fileAttr = ::GetFileAttributes(&cacheFilePath[0]); if ((fileAttr != INVALID_FILE_ATTRIBUTES) && (fileAttr & FILE_ATTRIBUTE_DIRECTORY) && - !(CreateOptions & FILE_NON_DIRECTORY_FILE)) + !(createOptions & FILE_NON_DIRECTORY_FILE)) { - DokanFileInfo->IsDirectory = TRUE; - if (DesiredAccess & DELETE) + dokanFileInfo->IsDirectory = TRUE; + if (desiredAccess & DELETE) { // Needed by FindFirstFile to see if directory is empty or not - ShareAccess |= FILE_SHARE_READ; + shareAccess |= FILE_SHARE_READ; } } // Folder (cache operation only) - if (DokanFileInfo->IsDirectory) + if (dokanFileInfo->IsDirectory) { if (creationDisposition == CREATE_NEW) { @@ -215,13 +209,13 @@ private: //Check first if we're trying to open a file as a directory. if (fileAttr != INVALID_FILE_ATTRIBUTES && !(fileAttr & FILE_ATTRIBUTE_DIRECTORY) && - (CreateOptions & FILE_DIRECTORY_FILE)) + (createOptions & FILE_DIRECTORY_FILE)) { return STATUS_NOT_A_DIRECTORY; } // FILE_FLAG_BACKUP_SEMANTICS is required for opening directory handles - HANDLE handle = ::CreateFile(&cacheFilePath[0], genericDesiredAccess, ShareAccess, &securityAttrib, OPEN_EXISTING, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS, nullptr); + HANDLE handle = ::CreateFile(&cacheFilePath[0], genericDesiredAccess, shareAccess, &securityAttrib, OPEN_EXISTING, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS, nullptr); if (handle == INVALID_HANDLE_VALUE) { DWORD error = GetLastError(); @@ -229,14 +223,14 @@ private: } else { - DokanFileInfo->Context = reinterpret_cast(handle); // save the file handle in Context + dokanFileInfo->Context = reinterpret_cast(handle); // save the file handle in Context } } } else // File (cache and/or Sia operation) { // Formulate Sia path - SString siaPath = CSiaApi::FormatToSiaPath(FilePath(FileName).SkipRoot()); // Strip drive letter to get Sia path + SString siaPath = CSiaApi::FormatToSiaPath(FilePath(fileName).SkipRoot()); // Strip drive letter to get Sia path if (siaPath.Length()) { // If cache file already exists and is a directory, requested file operation isn't valid @@ -351,7 +345,7 @@ private: HANDLE handle = ::CreateFile( &cacheFilePath[0], genericDesiredAccess, - ShareAccess, + shareAccess, &securityAttrib, creationDisposition, fileAttributesAndFlags, @@ -362,7 +356,7 @@ private: } else { - DokanFileInfo->Context = reinterpret_cast(handle); // save the file handle in Context + dokanFileInfo->Context = reinterpret_cast(handle); // save the file handle in Context if ((creationDisposition == OPEN_ALWAYS) || (creationDisposition == CREATE_ALWAYS)) { DWORD error = GetLastError(); @@ -376,10 +370,9 @@ private: ofi.SiaPath = siaPath; ofi.CacheFilePath = cacheFilePath; // TODO Detect if file is read-only - // TODO Quick hash to detect changes ofi.Changed = false; std::lock_guard l(_dokanMutex); - _openFileMap.insert({ DokanFileInfo->Context, ofi }); + _openFileMap.insert({ dokanFileInfo->Context, ofi }); } } } @@ -403,22 +396,23 @@ private: return ret; } - static NTSTATUS DOKAN_CALLBACK Sia_FindFiles(LPCWSTR FileName, PFillFindData FillFindData, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_FindFiles(LPCWSTR fileName, PFillFindData fillFindData, PDOKAN_FILE_INFO dokanFileInfo) { + NTSTATUS ret = STATUS_SUCCESS; auto siaFileTree = _siaFileTree; if (siaFileTree) { - SString siaQuery = CSiaApi::FormatToSiaPath(FilePath(FileName).SkipRoot()); + SString siaQuery = CSiaApi::FormatToSiaPath(FilePath(fileName).SkipRoot()); FilePath cachePath = GetCacheLocation();; FilePath rootPath = siaQuery; - if (FilePath::DirSep == FileName) + if (FilePath::DirSep == fileName) { siaQuery += L"/*.*"; } else { - cachePath.Append(&FileName[1]); + cachePath.Append(&fileName[1]); if (cachePath.IsDirectory()) { siaQuery += L"/*.*"; @@ -432,79 +426,120 @@ private: CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFindFiles(cachePath, rootPath, siaQuery))); - // TODO Grab live filesystem items + WIN32_FIND_DATA findData = { 0 }; + HANDLE findHandle = ::FindFirstFile(&cachePath[0], &findData); + if (findHandle == INVALID_HANDLE_VALUE) + { + DWORD error = GetLastError(); + ret = DokanNtStatusFromWin32(error); + } + else + { + // Find local files + std::vector dirs; + std::vector files; + do + { + if ((wcscmp(findData.cFileName, L".") != 0) && (wcscmp(findData.cFileName, L"..") != 0)) + { + if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) + { + dirs.push_back(findData.cFileName); + } + else + { + files.push_back(findData.cFileName); + } + fillFindData(&findData, dokanFileInfo); + } + } while (::FindNextFile(findHandle, &findData) != 0); + ::FindClose(findHandle); - auto dirList = siaFileTree->QueryDirectories(rootPath); - for (auto& dir : dirList) - { - WIN32_FIND_DATA fd = { 0 }; - wcscpy_s(fd.cFileName, dir.str().c_str()); - fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; - FillFindData(&fd, DokanFileInfo); - - // Create cache sub-folder - FilePath subCachePath(cachePath, dir); - if (!subCachePath.IsDirectory()) - { - subCachePath.CreateDirectory(); - } - } + // Find Sia directories + auto dirList = siaFileTree->QueryDirectories(rootPath); + for (auto& dir : dirList) + { + if (std::find(dirs.begin(), dirs.end(), dir) == dirs.end()) + { + WIN32_FIND_DATA fd = { 0 }; + wcscpy_s(fd.cFileName, dir.str().c_str()); + fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY; + fillFindData(&fd, dokanFileInfo); - auto fileList = siaFileTree->Query(siaQuery); - for (auto& file : fileList) - { - WIN32_FIND_DATA fd = { 0 }; - wcscpy_s(fd.cFileName, ::PathFindFileName(file->GetSiaPath().str().c_str())); + // Create cache sub-folder + FilePath subCachePath(cachePath, dir); + if (!subCachePath.IsDirectory()) + { + subCachePath.CreateDirectory(); + } + } + } - LARGE_INTEGER li = { 0 }; - li.QuadPart = file->GetFileSize(); - fd.nFileSizeHigh = li.HighPart; - fd.nFileSizeLow = li.LowPart; - fd.dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_NORMAL; - FillFindData(&fd, DokanFileInfo); - } + // Find Sia files + auto fileList = siaFileTree->Query(siaQuery); + for (auto& file : fileList) + { + FilePath fp = file->GetSiaPath(); + fp.RemoveFileName(); + if (std::find(files.begin(), files.end(), fp) == files.end()) + { + WIN32_FIND_DATA fd = { 0 }; + wcscpy_s(fd.cFileName, &fp[0]); + + LARGE_INTEGER li = { 0 }; + li.QuadPart = file->GetFileSize(); + fd.nFileSizeHigh = li.HighPart; + fd.nFileSizeLow = li.LowPart; + fd.dwFileAttributes = FILE_ATTRIBUTE_ARCHIVE | FILE_ATTRIBUTE_NORMAL; + fillFindData(&fd, dokanFileInfo); + } + } + } } - return STATUS_SUCCESS; + return ret; } - static void DOKAN_CALLBACK Sia_CloseFile(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) + static void DOKAN_CALLBACK Sia_CloseFile(LPCWSTR fileName, PDOKAN_FILE_INFO dokanFileInfo) { - FilePath filePath(GetCacheLocation(), FileName); + FilePath filePath(GetCacheLocation(), fileName); - if (DokanFileInfo->Context) + if (dokanFileInfo->Context) { - auto id = DokanFileInfo->Context; + auto id = dokanFileInfo->Context; HANDLE handle = reinterpret_cast(id); - if (!DokanFileInfo->IsDirectory) + if (!dokanFileInfo->IsDirectory) { LARGE_INTEGER li = { 0 }; ::GetFileSizeEx(handle, &li); HandleFileClose(filePath, id, li.QuadPart); } - ::CloseHandle(reinterpret_cast(DokanFileInfo->Context)); - DokanFileInfo->Context = 0; + ::CloseHandle(reinterpret_cast(dokanFileInfo->Context)); + dokanFileInfo->Context = 0; } } - static NTSTATUS DOKAN_CALLBACK Sia_GetFileInformation(LPCWSTR FileName, LPBY_HANDLE_FILE_INFORMATION HandleFileInformation, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_GetFileInformation(LPCWSTR fileName, LPBY_HANDLE_FILE_INFORMATION handleFileInfo, PDOKAN_FILE_INFO dokanFileInfo) { - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); BOOL opened = FALSE; NTSTATUS ret = STATUS_SUCCESS; FilePath cachePath = GetCacheLocation(); - if (FilePath::DirSep == FileName) + if (FilePath::DirSep == fileName) { - cachePath.Append(FileName); + cachePath.Append(fileName); } - - if (!handle || (handle == INVALID_HANDLE_VALUE)) + + SString siaPath = CSiaApi::FormatToSiaPath(FilePath(fileName).SkipRoot()); + auto siaFileTree = _siaFileTree; + auto siaFile = siaFileTree->GetFile(siaPath); + if (!siaFile && (!handle || (handle == INVALID_HANDLE_VALUE))) { handle = ::CreateFile(&cachePath[0], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { - ret = DokanNtStatusFromWin32(GetLastError()); + ret = DokanNtStatusFromWin32(::GetLastError()); } else { @@ -514,13 +549,13 @@ private: if (ret == STATUS_SUCCESS) { - if (!::GetFileInformationByHandle(handle, HandleFileInformation)) + if (!::GetFileInformationByHandle(handle, handleFileInfo)) { - // FileName is a root directory + // fileName is a root directory // in this case, FindFirstFile can't get directory information - if (wcslen(FileName) == 1) + if (wcslen(fileName) == 1) { - HandleFileInformation->dwFileAttributes = ::GetFileAttributes(&cachePath[0]); + handleFileInfo->dwFileAttributes = ::GetFileAttributes(&cachePath[0]); } else { @@ -528,33 +563,45 @@ private: HANDLE findHandle = ::FindFirstFile(&cachePath[0], &find); if (findHandle == INVALID_HANDLE_VALUE) { - // TODO Not Cached, so manual attributes - ret = STATUS_SUCCESS;// DokanNtStatusFromWin32(::GetLastError()); + DWORD error = ::GetLastError(); + if (siaFile) + { + LARGE_INTEGER li = { 0 }; + li.QuadPart = siaFile->GetFileSize(); + handleFileInfo->dwFileAttributes = FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_ARCHIVE; + handleFileInfo->nFileSizeHigh = li.HighPart; + handleFileInfo->nFileSizeLow = li.LowPart; + ret = STATUS_SUCCESS; + } + else + { + ret = DokanNtStatusFromWin32(error); + } } else { - HandleFileInformation->dwFileAttributes = find.dwFileAttributes; - HandleFileInformation->ftCreationTime = find.ftCreationTime; - HandleFileInformation->ftLastAccessTime = find.ftLastAccessTime; - HandleFileInformation->ftLastWriteTime = find.ftLastWriteTime; - HandleFileInformation->nFileSizeHigh = find.nFileSizeHigh; - HandleFileInformation->nFileSizeLow = find.nFileSizeLow; + handleFileInfo->dwFileAttributes = find.dwFileAttributes; + handleFileInfo->ftCreationTime = find.ftCreationTime; + handleFileInfo->ftLastAccessTime = find.ftLastAccessTime; + handleFileInfo->ftLastWriteTime = find.ftLastWriteTime; + handleFileInfo->nFileSizeHigh = find.nFileSizeHigh; + handleFileInfo->nFileSizeLow = find.nFileSizeLow; ::FindClose(findHandle); } } } + } - if (opened) - { - ::CloseHandle(handle); - } + if (opened) + { + ::CloseHandle(handle); } return ret; } - static NTSTATUS DOKAN_CALLBACK Sia_Mounted(PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_Mounted(PDOKAN_FILE_INFO dokanFileInfo) { // May spend a little wait time here while files are cleaned-up and re-added to queue _uploadManager.reset(new CUploadManager(CSiaCurl(_siaApi->GetHostConfig()), _siaDriveConfig)); @@ -564,7 +611,7 @@ private: return STATUS_SUCCESS; } - static NTSTATUS DOKAN_CALLBACK Sia_Unmounted(PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_Unmounted(PDOKAN_FILE_INFO dokanFileInfo) { _uploadManager.reset(nullptr); StopFileListThread(); @@ -574,9 +621,9 @@ private: static NTSTATUS DOKAN_CALLBACK Sia_GetDiskFreeSpaceW( PULONGLONG FreeBytesAvailable, PULONGLONG TotalNumberOfBytes, - PULONGLONG TotalNumberOfFreeBytes, PDOKAN_FILE_INFO DokanFileInfo) + PULONGLONG TotalNumberOfFreeBytes, PDOKAN_FILE_INFO dokanFileInfo) { - UNREFERENCED_PARAMETER(DokanFileInfo); + UNREFERENCED_PARAMETER(dokanFileInfo); // TODO Implement this correctly *FreeBytesAvailable = static_cast(512 * 1024 * 1024); @@ -590,8 +637,8 @@ private: LPWSTR VolumeNameBuffer, DWORD VolumeNameSize, LPDWORD VolumeSerialNumber, LPDWORD MaximumComponentLength, LPDWORD FileSystemFlags, LPWSTR FileSystemNameBuffer, DWORD FileSystemNameSize, - PDOKAN_FILE_INFO DokanFileInfo) { - UNREFERENCED_PARAMETER(DokanFileInfo); + PDOKAN_FILE_INFO dokanFileInfo) { + UNREFERENCED_PARAMETER(dokanFileInfo); wcscpy_s(VolumeNameBuffer, VolumeNameSize, L"SiaDrive"); *VolumeSerialNumber = 0x19831116; @@ -609,15 +656,15 @@ private: } - static NTSTATUS DOKAN_CALLBACK Sia_ReadFile(LPCWSTR FileName, LPVOID Buffer, - DWORD BufferLength, - LPDWORD ReadLength, - LONGLONG Offset, - PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_ReadFile(LPCWSTR fileName, LPVOID buffer, + DWORD bufferLen, + LPDWORD readLength, + LONGLONG offset, + PDOKAN_FILE_INFO dokanFileInfo) { - FilePath filePath(GetCacheLocation(), FileName); + FilePath filePath(GetCacheLocation(), fileName); - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); BOOL opened = FALSE; if (!handle || (handle == INVALID_HANDLE_VALUE)) @@ -633,7 +680,7 @@ private: } LARGE_INTEGER distanceToMove; - distanceToMove.QuadPart = Offset; + distanceToMove.QuadPart = offset; if (!::SetFilePointerEx(handle, distanceToMove, nullptr, FILE_BEGIN)) { DWORD error = GetLastError(); @@ -642,7 +689,7 @@ private: return DokanNtStatusFromWin32(error); } - if (!ReadFile(handle, Buffer, BufferLength, ReadLength, nullptr)) + if (!ReadFile(handle, buffer, bufferLen, readLength, nullptr)) { DWORD error = GetLastError(); if (opened) @@ -659,14 +706,14 @@ private: return STATUS_SUCCESS; } - static NTSTATUS DOKAN_CALLBACK Sia_WriteFile(LPCWSTR FileName, LPCVOID Buffer, - DWORD NumberOfBytesToWrite, - LPDWORD NumberOfBytesWritten, - LONGLONG Offset, - PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_WriteFile(LPCWSTR fileName, LPCVOID buffer, + DWORD bytesToWrite, + LPDWORD bytesWritten, + LONGLONG offset, + PDOKAN_FILE_INFO dokanFileInfo) { - FilePath filePath(GetCacheLocation(), FileName); - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + FilePath filePath(GetCacheLocation(), fileName); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); BOOL opened = FALSE; // reopen the file @@ -692,46 +739,45 @@ private: } LARGE_INTEGER distanceToMove; - if (DokanFileInfo->WriteToEndOfFile) + if (dokanFileInfo->WriteToEndOfFile) { - LARGE_INTEGER z; - z.QuadPart = 0; + LARGE_INTEGER z = {0}; if (!::SetFilePointerEx(handle, z, nullptr, FILE_END)) { DWORD error = GetLastError(); if (opened) - CloseHandle(handle); + ::CloseHandle(handle); return DokanNtStatusFromWin32(error); } } else { // Paging IO cannot write after allocate file size. - if (DokanFileInfo->PagingIo) + if (dokanFileInfo->PagingIo) { - if (static_cast(Offset) >= li.QuadPart) + if (static_cast(offset) >= li.QuadPart) { - *NumberOfBytesWritten = 0; + *bytesWritten = 0; if (opened) CloseHandle(handle); return STATUS_SUCCESS; } - if ((static_cast(Offset) + NumberOfBytesToWrite) > li.QuadPart) + if ((static_cast(offset) + bytesToWrite) > li.QuadPart) { - UINT64 bytes = li.QuadPart - Offset; + UINT64 bytes = li.QuadPart - offset; if (bytes >> 32) { - NumberOfBytesToWrite = static_cast(bytes & 0xFFFFFFFFUL); + bytesToWrite = static_cast(bytes & 0xFFFFFFFFUL); } else { - NumberOfBytesToWrite = static_cast(bytes); + bytesToWrite = static_cast(bytes); } } } - if (static_cast(Offset) > li.QuadPart) + if (static_cast(offset) > li.QuadPart) { // In the mirror sample helperZeroFileData is not necessary. NTFS will // zero a hole. @@ -739,7 +785,7 @@ private: // file systems ) then users will have to zero the hole themselves. } - distanceToMove.QuadPart = Offset; + distanceToMove.QuadPart = offset; if (!::SetFilePointerEx(handle, distanceToMove, nullptr, FILE_BEGIN)) { DWORD error = GetLastError(); @@ -749,7 +795,7 @@ private: } } - if (::WriteFile(handle, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten, nullptr)) + if (::WriteFile(handle, buffer, bytesToWrite, bytesWritten, nullptr)) { // TODO Set status to changed } @@ -768,11 +814,11 @@ private: return STATUS_SUCCESS; } - static NTSTATUS DOKAN_CALLBACK Sia_SetEndOfFile(LPCWSTR FileName, LONGLONG ByteOffset, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_SetEndOfFile(LPCWSTR fileName, LONGLONG byteOffset, PDOKAN_FILE_INFO dokanFileInfo) { NTSTATUS ret = STATUS_SUCCESS; - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { ret = STATUS_INVALID_HANDLE; @@ -781,7 +827,7 @@ private: { // TODO Set status to changed LARGE_INTEGER offset; - offset.QuadPart = ByteOffset; + offset.QuadPart = byteOffset; if (!::SetFilePointerEx(handle, offset, nullptr, FILE_BEGIN)) { DWORD error = GetLastError(); @@ -797,28 +843,28 @@ private: return ret; } - static void DOKAN_CALLBACK Sia_Cleanup(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) + static void DOKAN_CALLBACK Sia_Cleanup(LPCWSTR fileName, PDOKAN_FILE_INFO dokanFileInfo) { - FilePath filePath(GetCacheLocation(), FileName); - if (DokanFileInfo->Context) + FilePath filePath(GetCacheLocation(), fileName); + if (dokanFileInfo->Context) { - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); - if (!DokanFileInfo->IsDirectory) + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); + if (!dokanFileInfo->IsDirectory) { LARGE_INTEGER li = { 0 }; ::GetFileSizeEx(handle, &li); - HandleFileClose(filePath, DokanFileInfo->Context, li.QuadPart); + HandleFileClose(filePath, dokanFileInfo->Context, li.QuadPart); } ::CloseHandle(handle); - DokanFileInfo->Context = 0; + dokanFileInfo->Context = 0; } - if (DokanFileInfo->DeleteOnClose) + if (dokanFileInfo->DeleteOnClose) { // Should already be deleted by CloseHandle // if open with FILE_FLAG_DELETE_ON_CLOSE - if (DokanFileInfo->IsDirectory) + if (dokanFileInfo->IsDirectory) { if (filePath.RemoveDirectory()) { @@ -840,9 +886,9 @@ private: } } - static NTSTATUS DOKAN_CALLBACK Sia_FlushFileBuffers(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_FlushFileBuffers(LPCWSTR fileName, PDOKAN_FILE_INFO dokanFileInfo) { - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { return STATUS_SUCCESS; @@ -859,11 +905,11 @@ private: } } - static NTSTATUS DOKAN_CALLBACK Sia_DeleteDirectory(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_DeleteDirectory(LPCWSTR fileName, PDOKAN_FILE_INFO dokanFileInfo) { - FilePath filePath = FilePath(GetCacheLocation(), FileName); + FilePath filePath = FilePath(GetCacheLocation(), fileName); NTSTATUS ret = STATUS_SUCCESS; - if (DokanFileInfo->DeleteOnClose) + if (dokanFileInfo->DeleteOnClose) { filePath.Append("*"); @@ -899,13 +945,13 @@ private: } - static NTSTATUS DOKAN_CALLBACK Sia_DeleteFileW(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_DeleteFileW(LPCWSTR fileName, PDOKAN_FILE_INFO dokanFileInfo) { // TODO Handle files that aren't cached NTSTATUS ret = STATUS_SUCCESS; - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); - FilePath filePath(GetCacheLocation(), FileName); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); + FilePath filePath(GetCacheLocation(), fileName); DWORD dwAttrib = ::GetFileAttributes(&filePath[0]); if ((dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) @@ -915,7 +961,7 @@ private: else if (handle && (handle != INVALID_HANDLE_VALUE)) { FILE_DISPOSITION_INFO fdi; - fdi.DeleteFile = DokanFileInfo->DeleteOnClose; + fdi.DeleteFile = dokanFileInfo->DeleteOnClose; if (!::SetFileInformationByHandle(handle, FileDispositionInfo, &fdi, sizeof(FILE_DISPOSITION_INFO))) { ret = DokanNtStatusFromWin32(GetLastError()); @@ -925,15 +971,15 @@ private: return ret; } - static NTSTATUS DOKAN_CALLBACK Sia_MoveFileW(LPCWSTR FileName, LPCWSTR NewFileName, BOOL ReplaceIfExisting, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_MoveFileW(LPCWSTR fileName, LPCWSTR NewFileName, BOOL ReplaceIfExisting, PDOKAN_FILE_INFO dokanFileInfo) { // TODO Handle files that aren't cached NTSTATUS ret = STATUS_SUCCESS; - FilePath filePath(GetCacheLocation(), FileName); + FilePath filePath(GetCacheLocation(), fileName); FilePath newFilePath(GetCacheLocation(), NewFileName); - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { ret = STATUS_INVALID_HANDLE; @@ -972,13 +1018,13 @@ private: return ret; } - static NTSTATUS DOKAN_CALLBACK Sia_SetFileAttributesW(LPCWSTR FileName, DWORD FileAttributes, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_SetFileAttributesW(LPCWSTR fileName, DWORD fileAttributes, PDOKAN_FILE_INFO dokanFileInfo) { - UNREFERENCED_PARAMETER(DokanFileInfo); + UNREFERENCED_PARAMETER(dokanFileInfo); NTSTATUS ret = STATUS_SUCCESS; - FilePath filePath(GetCacheLocation(), FileName); - if (!::SetFileAttributes(&filePath[0], FileAttributes)) + FilePath filePath(GetCacheLocation(), fileName); + if (!::SetFileAttributes(&filePath[0], fileAttributes)) { DWORD error = GetLastError(); ret = DokanNtStatusFromWin32(error); @@ -988,19 +1034,19 @@ private: } static NTSTATUS DOKAN_CALLBACK Sia_GetFileSecurityW( - LPCWSTR FileName, PSECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG BufferLength, - PULONG LengthNeeded, PDOKAN_FILE_INFO DokanFileInfo) + LPCWSTR fileName, PSECURITY_INFORMATION securityInfo, + PSECURITY_DESCRIPTOR securityDescriptor, ULONG bufferLen, + PULONG lengthNeeded, PDOKAN_FILE_INFO dokanFileInfo) { - UNREFERENCED_PARAMETER(DokanFileInfo); - FilePath filePath(GetCacheLocation(), FileName); - SECURITY_INFORMATION requestingSaclInfo = ((*SecurityInformation & SACL_SECURITY_INFORMATION) || (*SecurityInformation & BACKUP_SECURITY_INFORMATION)); + UNREFERENCED_PARAMETER(dokanFileInfo); + FilePath filePath(GetCacheLocation(), fileName); + SECURITY_INFORMATION requestingSaclInfo = ((*securityInfo & SACL_SECURITY_INFORMATION) || (*securityInfo & BACKUP_SECURITY_INFORMATION)); //if (!g_HasSeSecurityPrivilege) { if (true) { - *SecurityInformation &= ~SACL_SECURITY_INFORMATION; - *SecurityInformation &= ~BACKUP_SECURITY_INFORMATION; + *securityInfo &= ~SACL_SECURITY_INFORMATION; + *securityInfo &= ~BACKUP_SECURITY_INFORMATION; } HANDLE handle = ::CreateFile(&filePath[0], READ_CONTROL | ((requestingSaclInfo && false) ? ACCESS_SYSTEM_SECURITY : 0), @@ -1016,7 +1062,7 @@ private: return DokanNtStatusFromWin32(error); } - if (!::GetUserObjectSecurity(handle, SecurityInformation, SecurityDescriptor, BufferLength, LengthNeeded)) + if (!::GetUserObjectSecurity(handle, securityInfo, securityDescriptor, bufferLen, lengthNeeded)) { int error = ::GetLastError(); if (error == ERROR_INSUFFICIENT_BUFFER) @@ -1037,21 +1083,21 @@ private: static NTSTATUS DOKAN_CALLBACK Sia_SetFileSecurityW( - LPCWSTR FileName, PSECURITY_INFORMATION SecurityInformation, - PSECURITY_DESCRIPTOR SecurityDescriptor, ULONG SecurityDescriptorLength, - PDOKAN_FILE_INFO DokanFileInfo) + LPCWSTR fileName, PSECURITY_INFORMATION securityInfo, + PSECURITY_DESCRIPTOR securityDescriptor, ULONG securityDescriptorLength, + PDOKAN_FILE_INFO dokanFileInfo) { - UNREFERENCED_PARAMETER(SecurityDescriptorLength); + UNREFERENCED_PARAMETER(securityDescriptorLength); - FilePath filePath(GetCacheLocation(), FileName); + FilePath filePath(GetCacheLocation(), fileName); - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { return STATUS_INVALID_HANDLE; } - if (!::SetUserObjectSecurity(handle, SecurityInformation, SecurityDescriptor)) + if (!::SetUserObjectSecurity(handle, securityInfo, securityDescriptor)) { int error = ::GetLastError(); return DokanNtStatusFromWin32(error); @@ -1060,19 +1106,19 @@ private: return STATUS_SUCCESS; } - static NTSTATUS DOKAN_CALLBACK Sia_SetFileTime(LPCWSTR FileName, CONST FILETIME *CreationTime, - CONST FILETIME *LastAccessTime, CONST FILETIME *LastWriteTime, - PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_SetFileTime(LPCWSTR fileName, CONST FILETIME *creationTime, + CONST FILETIME *lastAccessTime, CONST FILETIME *lastWriteTime, + PDOKAN_FILE_INFO dokanFileInfo) { - FilePath filePath(GetCacheLocation(), FileName); + FilePath filePath(GetCacheLocation(), fileName); - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { return STATUS_INVALID_HANDLE; } - if (!::SetFileTime(handle, CreationTime, LastAccessTime, LastWriteTime)) + if (!::SetFileTime(handle, creationTime, lastAccessTime, lastWriteTime)) { DWORD error = GetLastError(); return DokanNtStatusFromWin32(error); @@ -1081,12 +1127,12 @@ private: return STATUS_SUCCESS; } - static NTSTATUS DOKAN_CALLBACK Sia_SetAllocationSize(LPCWSTR FileName, LONGLONG AllocSize, PDOKAN_FILE_INFO DokanFileInfo) + static NTSTATUS DOKAN_CALLBACK Sia_SetAllocationSize(LPCWSTR fileName, LONGLONG allocSize, PDOKAN_FILE_INFO dokanFileInfo) { NTSTATUS ret = STATUS_SUCCESS; - FilePath filePath(GetCacheLocation(), FileName); + FilePath filePath(GetCacheLocation(), fileName); - HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + HANDLE handle = reinterpret_cast(dokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { ret = STATUS_INVALID_HANDLE; @@ -1096,9 +1142,9 @@ private: LARGE_INTEGER fileSize = { 0 }; if (::GetFileSizeEx(handle, &fileSize)) { - if (AllocSize < fileSize.QuadPart) + if (allocSize < fileSize.QuadPart) { - fileSize.QuadPart = AllocSize; + fileSize.QuadPart = allocSize; if (!::SetFilePointerEx(handle, fileSize, nullptr, FILE_BEGIN)) { DWORD error = GetLastError(); @@ -1217,7 +1263,7 @@ std::unique_ptr DokanImpl::_uploadManager; DOKAN_OPERATIONS DokanImpl::_dokanOps; DOKAN_OPTIONS DokanImpl::_dokanOptions; FilePath DokanImpl::_cacheLocation; -bool DokanImpl::_fileListStopRequested; +HANDLE DokanImpl::_fileListStopEvent; CSiaFileTreePtr DokanImpl::_siaFileTree; std::mutex DokanImpl::_fileTreeMutex; std::unique_ptr DokanImpl::_fileListThread;