diff --git a/SiaDrive.Api/SiaApi.h b/SiaDrive.Api/SiaApi.h index 140241d..7aeebf9 100644 --- a/SiaDrive.Api/SiaApi.h +++ b/SiaDrive.Api/SiaApi.h @@ -104,6 +104,8 @@ public: std::shared_ptr<_CSiaFile> GetFile(const String& siaPath) const; + std::vector QueryDirectories(String query) const; + bool FileExists(const String& siaPath) const; }; diff --git a/SiaDrive.Api/SiaFileTree.cpp b/SiaDrive.Api/SiaFileTree.cpp index 3d18bd4..fca3322 100644 --- a/SiaDrive.Api/SiaFileTree.cpp +++ b/SiaDrive.Api/SiaFileTree.cpp @@ -52,14 +52,39 @@ CSiaFilePtr CSiaApi::_CSiaFileTree::GetFile(const String& siaPath) const CSiaFileCollection CSiaApi::_CSiaFileTree::Query(String query) const { query = CSiaApi::FormatToSiaPath(query); - ReplaceStringInPlace(ReplaceStringInPlace(ReplaceStringInPlace(query, L".", L"\\."), L"*", L".+"), L"?", L".?"); + ReplaceStringInPlace(ReplaceStringInPlace(ReplaceStringInPlace(query, L".", L"\\."), L"*", L"[^/]+"), L"?", L"[^/]?"); std::wregex r(query); CSiaFileCollection ret; - std::copy_if(_fileList.begin(), _fileList.end(), std::back_inserter(ret), [&](const CSiaFilePtr& v) -> bool + std::copy_if(_fileList.begin(), _fileList.end(), std::back_inserter(ret), [&](const CSiaFilePtr& v) -> bool { return std::regex_match(v->GetSiaPath(), r); }); + return std::move(ret); +} + +std::vector CSiaApi::_CSiaFileTree::QueryDirectories(String query) const +{ + query = CSiaApi::FormatToSiaPath(query); + ReplaceStringInPlace(ReplaceStringInPlace(ReplaceStringInPlace(query, L".", L"\\."), L"*", L"[^/]+"), L"?", L"[^/]?"); + std::wregex r(query); + + std::vector ret; + std::for_each(_fileList.begin(), _fileList.end(), [&](const CSiaFilePtr& v) + { + String dir = v->GetSiaPath(); + int pos = dir.find_last_of('/'); + if (pos > -1) + { + pos = dir.find_first_of('/'); + dir = dir.substr(0, pos); + if (std::find(ret.begin(), ret.end(), dir) == ret.end()) + { + ret.push_back(dir); + } + } + }); + return std::move(ret); } \ No newline at end of file diff --git a/SiaDrive.Dokan.Api/SiaDokanDrive.cpp b/SiaDrive.Dokan.Api/SiaDokanDrive.cpp index 204255c..6d7916c 100644 --- a/SiaDrive.Dokan.Api/SiaDokanDrive.cpp +++ b/SiaDrive.Dokan.Api/SiaDokanDrive.cpp @@ -352,11 +352,41 @@ private: if (siaFileTree) { String siaQuery = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName)); + String dirQuery = siaQuery; + if (::PathIsDirectory(FileName)) + { + siaQuery += L"/*.*"; + dirQuery = siaQuery; + } + else + { + String dir = FileName; + ::PathRemoveFileSpec(&dir[0]); + dirQuery = dir + L"/*.*"; + } + + auto dirList = siaFileTree->QueryDirectories(dirQuery); + for (auto& dir : dirList) + { + WIN32_FIND_DATA fd = { 0 }; + wcscpy_s(fd.cFileName, dir.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().c_str())); + + 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); }