diff --git a/src/siadrive_dokan_api/siadokandrive.cpp b/src/siadrive_dokan_api/siadokandrive.cpp index 0537c47..07fadfa 100644 --- a/src/siadrive_dokan_api/siadokandrive.cpp +++ b/src/siadrive_dokan_api/siadokandrive.cpp @@ -121,7 +121,7 @@ private: if (!_fileListStopRequested) { // TODO Change to WaitForSingleObject() for immediate termination - Sleep(5000); + Sleep(1000); } } })); @@ -431,6 +431,8 @@ private: } CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFindFiles(cachePath, rootPath, siaQuery))); + + // TODO Grab live filesystem items auto dirList = siaFileTree->QueryDirectories(rootPath); for (auto& dir : dirList) @@ -476,8 +478,8 @@ private: HANDLE handle = reinterpret_cast(id); if (!DokanFileInfo->IsDirectory) { - LARGE_INTEGER li; - li.LowPart = ::GetFileSize(handle, reinterpret_cast(&li.HighPart)); + LARGE_INTEGER li = { 0 }; + ::GetFileSizeEx(handle, &li); HandleFileClose(filePath, id, li.QuadPart); } ::CloseHandle(reinterpret_cast(DokanFileInfo->Context)); @@ -620,6 +622,7 @@ private: if (!handle || (handle == INVALID_HANDLE_VALUE)) { + // TODO Need to add to cache if missing handle = ::CreateFile(&filePath[0], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr); if (handle == INVALID_HANDLE_VALUE) { @@ -679,9 +682,8 @@ private: opened = TRUE; } - DWORD fileSizeHigh = 0; - DWORD fileSizeLow = ::GetFileSize(handle, &fileSizeHigh); - if (fileSizeLow == INVALID_FILE_SIZE) + LARGE_INTEGER li = { 0 }; + if (!::GetFileSizeEx(handle, &li)) { DWORD error = GetLastError(); if (opened) @@ -689,8 +691,6 @@ private: return DokanNtStatusFromWin32(error); } - UINT64 fileSize = (static_cast(fileSizeHigh) << 32) | fileSizeLow; - LARGE_INTEGER distanceToMove; if (DokanFileInfo->WriteToEndOfFile) { @@ -709,7 +709,7 @@ private: // Paging IO cannot write after allocate file size. if (DokanFileInfo->PagingIo) { - if (static_cast(Offset) >= fileSize) + if (static_cast(Offset) >= li.QuadPart) { *NumberOfBytesWritten = 0; if (opened) @@ -717,9 +717,9 @@ private: return STATUS_SUCCESS; } - if ((static_cast(Offset) + NumberOfBytesToWrite) > fileSize) + if ((static_cast(Offset) + NumberOfBytesToWrite) > li.QuadPart) { - UINT64 bytes = fileSize - Offset; + UINT64 bytes = li.QuadPart - Offset; if (bytes >> 32) { NumberOfBytesToWrite = static_cast(bytes & 0xFFFFFFFFUL); @@ -731,7 +731,7 @@ private: } } - if (static_cast(Offset) > fileSize) + if (static_cast(Offset) > li.QuadPart) { // In the mirror sample helperZeroFileData is not necessary. NTFS will // zero a hole. @@ -749,15 +749,16 @@ private: } } - if (!::WriteFile(handle, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten, nullptr)) + if (::WriteFile(handle, Buffer, NumberOfBytesToWrite, NumberOfBytesWritten, nullptr)) { + // TODO Set status to changed + } + else + { DWORD error = GetLastError(); if (opened) CloseHandle(handle); return DokanNtStatusFromWin32(error); - - } - else { } // close the file when it is reopene bxkjuoqoa'qq d @@ -769,29 +770,31 @@ private: static NTSTATUS DOKAN_CALLBACK Sia_SetEndOfFile(LPCWSTR FileName, LONGLONG ByteOffset, PDOKAN_FILE_INFO DokanFileInfo) { - HANDLE handle; - LARGE_INTEGER offset; + NTSTATUS ret = STATUS_SUCCESS; - handle = reinterpret_cast(DokanFileInfo->Context); - if (!handle || handle == INVALID_HANDLE_VALUE) + HANDLE handle = reinterpret_cast(DokanFileInfo->Context); + if (!handle || (handle == INVALID_HANDLE_VALUE)) { - return STATUS_INVALID_HANDLE; + ret = STATUS_INVALID_HANDLE; } + else + { + // TODO Set status to changed + LARGE_INTEGER offset; + offset.QuadPart = ByteOffset; + if (!::SetFilePointerEx(handle, offset, nullptr, FILE_BEGIN)) + { + DWORD error = GetLastError(); + ret = DokanNtStatusFromWin32(error); + } + else if (!::SetEndOfFile(handle)) + { + DWORD error = GetLastError(); + ret = DokanNtStatusFromWin32(error); + } + } - offset.QuadPart = ByteOffset; - if (!::SetFilePointerEx(handle, offset, nullptr, FILE_BEGIN)) - { - DWORD error = GetLastError(); - return DokanNtStatusFromWin32(error); - } - - if (!::SetEndOfFile(handle)) - { - DWORD error = GetLastError(); - return DokanNtStatusFromWin32(error); - } - - return STATUS_SUCCESS; + return ret; } static void DOKAN_CALLBACK Sia_Cleanup(LPCWSTR FileName, PDOKAN_FILE_INFO DokanFileInfo) @@ -802,10 +805,11 @@ private: HANDLE handle = reinterpret_cast(DokanFileInfo->Context); if (!DokanFileInfo->IsDirectory) { - LARGE_INTEGER li; - li.LowPart = ::GetFileSize(handle, reinterpret_cast(&li.HighPart)); + LARGE_INTEGER li = { 0 }; + ::GetFileSizeEx(handle, &li); HandleFileClose(filePath, DokanFileInfo->Context, li.QuadPart); } + ::CloseHandle(handle); DokanFileInfo->Context = 0; } @@ -898,6 +902,7 @@ private: 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); @@ -905,76 +910,81 @@ private: DWORD dwAttrib = ::GetFileAttributes(&filePath[0]); if ((dwAttrib != INVALID_FILE_ATTRIBUTES) && (dwAttrib & FILE_ATTRIBUTE_DIRECTORY)) { - return STATUS_ACCESS_DENIED; + ret = STATUS_ACCESS_DENIED; } - - if (handle && (handle != INVALID_HANDLE_VALUE)) + else if (handle && (handle != INVALID_HANDLE_VALUE)) { FILE_DISPOSITION_INFO fdi; fdi.DeleteFile = DokanFileInfo->DeleteOnClose; if (!::SetFileInformationByHandle(handle, FileDispositionInfo, &fdi, sizeof(FILE_DISPOSITION_INFO))) { - return DokanNtStatusFromWin32(GetLastError()); + ret = DokanNtStatusFromWin32(GetLastError()); } } - return STATUS_SUCCESS; + return ret; } 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 newFilePath(GetCacheLocation(), NewFileName); HANDLE handle = reinterpret_cast(DokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { - return STATUS_INVALID_HANDLE; + ret = STATUS_INVALID_HANDLE; } - - size_t len = wcslen(&newFilePath[0]); - DWORD bufferSize = static_cast(sizeof(FILE_RENAME_INFO) + (len * sizeof(newFilePath[0]))); - - PFILE_RENAME_INFO renameInfo = static_cast(malloc(bufferSize)); - if (!renameInfo) + else { - return STATUS_BUFFER_OVERFLOW; + size_t len = wcslen(&newFilePath[0]); + DWORD bufferSize = static_cast(sizeof(FILE_RENAME_INFO) + (len * sizeof(newFilePath[0]))); + + PFILE_RENAME_INFO renameInfo = static_cast(malloc(bufferSize)); + if (renameInfo) + { + ::ZeroMemory(renameInfo, bufferSize); + + renameInfo->ReplaceIfExists = ReplaceIfExisting ? TRUE : FALSE; // some warning about converting BOOL to BOOLEAN + renameInfo->RootDirectory = nullptr; // hope it is never needed, shouldn't be + renameInfo->FileNameLength = static_cast(len) * sizeof(newFilePath[0]); // they want length in bytes + + wcscpy_s(renameInfo->FileName, len + 1, &newFilePath[0]); + + BOOL result = ::SetFileInformationByHandle(handle, FileRenameInfo, renameInfo, bufferSize); + free(renameInfo); + + if (!result) + { + DWORD error = GetLastError(); + ret = DokanNtStatusFromWin32(error); + } + } + else + { + ret = STATUS_BUFFER_OVERFLOW; + } } - ::ZeroMemory(renameInfo, bufferSize); - renameInfo->ReplaceIfExists = ReplaceIfExisting ? TRUE : FALSE; // some warning about converting BOOL to BOOLEAN - renameInfo->RootDirectory = nullptr; // hope it is never needed, shouldn't be - renameInfo->FileNameLength = static_cast(len) * sizeof(newFilePath[0]); // they want length in bytes - - wcscpy_s(renameInfo->FileName, len + 1, &newFilePath[0]); - - BOOL result = ::SetFileInformationByHandle(handle, FileRenameInfo, renameInfo, bufferSize); - free(renameInfo); - - if (result) - { - return STATUS_SUCCESS; - } - else - { - DWORD error = GetLastError(); - return DokanNtStatusFromWin32(error); - } + return ret; } static NTSTATUS DOKAN_CALLBACK Sia_SetFileAttributesW(LPCWSTR FileName, DWORD FileAttributes, PDOKAN_FILE_INFO DokanFileInfo) { UNREFERENCED_PARAMETER(DokanFileInfo); + NTSTATUS ret = STATUS_SUCCESS; FilePath filePath(GetCacheLocation(), FileName); if (!::SetFileAttributes(&filePath[0], FileAttributes)) { DWORD error = GetLastError(); - return DokanNtStatusFromWin32(error); + ret = DokanNtStatusFromWin32(error); } - return STATUS_SUCCESS; + return ret; } static NTSTATUS DOKAN_CALLBACK Sia_GetFileSecurityW( @@ -1057,7 +1067,6 @@ private: FilePath filePath(GetCacheLocation(), FileName); HANDLE handle = reinterpret_cast(DokanFileInfo->Context); - if (!handle || (handle == INVALID_HANDLE_VALUE)) { return STATUS_INVALID_HANDLE; @@ -1074,39 +1083,42 @@ private: static NTSTATUS DOKAN_CALLBACK Sia_SetAllocationSize(LPCWSTR FileName, LONGLONG AllocSize, PDOKAN_FILE_INFO DokanFileInfo) { + NTSTATUS ret = STATUS_SUCCESS; FilePath filePath(GetCacheLocation(), FileName); HANDLE handle = reinterpret_cast(DokanFileInfo->Context); if (!handle || (handle == INVALID_HANDLE_VALUE)) { - return STATUS_INVALID_HANDLE; + ret = STATUS_INVALID_HANDLE; } - - LARGE_INTEGER fileSize; - if (::GetFileSizeEx(handle, &fileSize)) + else { - if (AllocSize < fileSize.QuadPart) + LARGE_INTEGER fileSize = { 0 }; + if (::GetFileSizeEx(handle, &fileSize)) { - fileSize.QuadPart = AllocSize; - if (!::SetFilePointerEx(handle, fileSize, nullptr, FILE_BEGIN)) + if (AllocSize < fileSize.QuadPart) { - DWORD error = GetLastError(); - return DokanNtStatusFromWin32(error); - } - - if (!::SetEndOfFile(handle)) - { - DWORD error = GetLastError(); - return DokanNtStatusFromWin32(error); + fileSize.QuadPart = AllocSize; + if (!::SetFilePointerEx(handle, fileSize, nullptr, FILE_BEGIN)) + { + DWORD error = GetLastError(); + ret = DokanNtStatusFromWin32(error); + } + else if (!::SetEndOfFile(handle)) + { + DWORD error = GetLastError(); + ret = DokanNtStatusFromWin32(error); + } } } + else + { + DWORD error = GetLastError(); + ret = DokanNtStatusFromWin32(error); + } } - else - { - DWORD error = GetLastError(); - return DokanNtStatusFromWin32(error); - } - return STATUS_SUCCESS; + + return ret; } public: