Drive changes
This commit is contained in:
@@ -64,24 +64,38 @@ CSiaFileCollection CSiaApi::_CSiaFileTree::Query(String query) const
|
||||
return std::move(ret);
|
||||
}
|
||||
|
||||
std::vector<String> CSiaApi::_CSiaFileTree::QueryDirectories(String query) const
|
||||
std::vector<String> CSiaApi::_CSiaFileTree::QueryDirectories(String rootFolder) const
|
||||
{
|
||||
query = CSiaApi::FormatToSiaPath(query);
|
||||
ReplaceStringInPlace(ReplaceStringInPlace(ReplaceStringInPlace(query, L".", L"\\."), L"*", L"[^/]+"), L"?", L"[^/]?");
|
||||
std::wregex r(query);
|
||||
CSiaFileCollection col;
|
||||
ReplaceStringInPlace(rootFolder, L"/", L"\\");
|
||||
if (rootFolder[0] == '\\')
|
||||
{
|
||||
rootFolder = rootFolder.substr(1);
|
||||
}
|
||||
|
||||
std::vector<String> ret;
|
||||
std::for_each(_fileList.begin(), _fileList.end(), [&](const CSiaFilePtr& v)
|
||||
{
|
||||
String dir = v->GetSiaPath();
|
||||
int pos = dir.find_last_of('/');
|
||||
if (pos > -1)
|
||||
ReplaceStringInPlace(dir, L"/", L"\\");
|
||||
::PathRemoveFileSpec(&dir[0]);
|
||||
::PathRemoveBackslash(&dir[0]);
|
||||
::PathRemoveBackslash(&rootFolder[0]);
|
||||
dir = dir.c_str();
|
||||
rootFolder = rootFolder.c_str();
|
||||
if ((dir.length() > rootFolder.length()) && (dir.substr(0, rootFolder.length()) == rootFolder))
|
||||
{
|
||||
pos = dir.find_first_of('/');
|
||||
dir = dir.substr(0, pos);
|
||||
if (std::find(ret.begin(), ret.end(), dir) == ret.end())
|
||||
String subFolder = dir.substr(rootFolder.length());
|
||||
int f = subFolder.find_first_of('\\');
|
||||
if (f > 0)
|
||||
{
|
||||
ret.push_back(dir);
|
||||
subFolder = subFolder.substr(0, f);
|
||||
}
|
||||
|
||||
auto it = std::find(ret.begin(), ret.end(), subFolder);
|
||||
if (it == ret.end())
|
||||
{
|
||||
ret.push_back(subFolder);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
@@ -148,20 +148,36 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
bool isFile = (FileAttributes & FILE_NON_DIRECTORY_FILE) ? true : false;
|
||||
DokanFileInfo->IsDirectory = !isFile;
|
||||
if (isFile)
|
||||
OutputDebugString(FileName);
|
||||
OutputDebugString(L"\n");
|
||||
// When filePath is a directory, needs to change the flag so that the file can
|
||||
// be opened.
|
||||
String cacheFilePath;
|
||||
cacheFilePath.resize(MAX_PATH + 1);
|
||||
PathCombine(&cacheFilePath[0], GetCacheLocation().c_str(), &FileName[1]);
|
||||
DWORD fileAttr = GetFileAttributes(cacheFilePath.c_str());
|
||||
|
||||
if (fileAttr != INVALID_FILE_ATTRIBUTES &&
|
||||
(fileAttr & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
!(CreateOptions & FILE_NON_DIRECTORY_FILE))
|
||||
{
|
||||
DokanFileInfo->IsDirectory = TRUE;
|
||||
if (DesiredAccess & DELETE)
|
||||
{
|
||||
// Needed by FindFirstFile to see if directory is empty or not
|
||||
ShareAccess |= FILE_SHARE_READ;
|
||||
}
|
||||
}
|
||||
|
||||
if (!DokanFileInfo->IsDirectory)
|
||||
{
|
||||
// Formulate Sia path and cache path
|
||||
String siaPath = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName)); // Strip drive letter to get Sia path
|
||||
if (siaPath.length())
|
||||
{
|
||||
String cacheFilePath;
|
||||
cacheFilePath.resize(MAX_PATH + 1);
|
||||
PathCombine(&cacheFilePath[0], GetCacheLocation().c_str(), siaPath.c_str());
|
||||
|
||||
{
|
||||
// If cache file already exists and is a directory, requested file operation isn't valid
|
||||
if (GetFileAttributes(cacheFilePath.c_str()) & FILE_ATTRIBUTE_DIRECTORY)
|
||||
DWORD attribs = GetFileAttributes(cacheFilePath.c_str());
|
||||
if ((attribs != INVALID_FILE_ATTRIBUTES) && (attribs & FILE_ATTRIBUTE_DIRECTORY))
|
||||
{
|
||||
ret = STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
@@ -278,16 +294,14 @@ private:
|
||||
else
|
||||
{
|
||||
DokanFileInfo->Context = reinterpret_cast<ULONG64>(handle); // save the file handle in Context
|
||||
if (isFile)
|
||||
{
|
||||
OpenFileInfo ofi;
|
||||
ofi.SiaPath = siaPath;
|
||||
ofi.CacheFilePath = cacheFilePath;
|
||||
// TODO Detect if file is read-only
|
||||
// TODO Quick hash to detect changes
|
||||
ofi.ReadOnly = false;
|
||||
_openFileMap.insert({ DokanFileInfo->Context, ofi });
|
||||
}
|
||||
|
||||
OpenFileInfo ofi;
|
||||
ofi.SiaPath = siaPath;
|
||||
ofi.CacheFilePath = cacheFilePath;
|
||||
// TODO Detect if file is read-only
|
||||
// TODO Quick hash to detect changes
|
||||
ofi.ReadOnly = false;
|
||||
_openFileMap.insert({ DokanFileInfo->Context, ofi });
|
||||
|
||||
/*if (creationDisposition == OPEN_ALWAYS ||
|
||||
creationDisposition == CREATE_ALWAYS) {
|
||||
@@ -316,17 +330,7 @@ private:
|
||||
}
|
||||
}
|
||||
else // Folder Operation (cache operation only)
|
||||
{
|
||||
String cacheFilePath;
|
||||
cacheFilePath.resize(MAX_PATH + 1);
|
||||
if (String(L"\\") == FileName)
|
||||
{
|
||||
cacheFilePath = GetCacheLocation();
|
||||
}
|
||||
else
|
||||
{
|
||||
PathCombine(&cacheFilePath[0], GetCacheLocation().c_str(), FileName);
|
||||
}
|
||||
{
|
||||
HANDLE handle = ::CreateFile(cacheFilePath.c_str(), genericDesiredAccess, ShareAccess, &securityAttrib, creationDisposition, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
@@ -352,27 +356,37 @@ private:
|
||||
if (siaFileTree)
|
||||
{
|
||||
String siaQuery = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName));
|
||||
String dirQuery = siaQuery;
|
||||
String rootPath = FileName;
|
||||
if (::PathIsDirectory(FileName))
|
||||
{
|
||||
siaQuery += L"/*.*";
|
||||
dirQuery = siaQuery;
|
||||
}
|
||||
else
|
||||
{
|
||||
String dir = FileName;
|
||||
::PathRemoveFileSpec(&dir[0]);
|
||||
dirQuery = dir + L"/*.*";
|
||||
::PathRemoveFileSpec(&rootPath[0]);
|
||||
rootPath = rootPath.c_str();
|
||||
}
|
||||
|
||||
auto dirList = siaFileTree->QueryDirectories(dirQuery);
|
||||
auto dirList = siaFileTree->QueryDirectories(rootPath);
|
||||
for (auto& dir : dirList)
|
||||
{
|
||||
WIN32_FIND_DATA fd = { 0 };
|
||||
wcscpy_s(fd.cFileName, dir.c_str());
|
||||
|
||||
fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
|
||||
String cachePath;
|
||||
cachePath.resize(MAX_PATH + 1);
|
||||
if (rootPath == L"\\")
|
||||
{
|
||||
::PathCombine(&cachePath[0], GetCacheLocation().c_str(), dir.c_str());
|
||||
}
|
||||
else
|
||||
{
|
||||
::PathCombine(&cachePath[0], GetCacheLocation().c_str(), rootPath.c_str());
|
||||
::PathAppend(&cachePath[0], dir.c_str());
|
||||
}
|
||||
cachePath = cachePath.c_str();
|
||||
::CreateDirectory(cachePath.c_str(), nullptr);
|
||||
FillFindData(&fd, DokanFileInfo);
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user