Drive changes
This commit is contained in:
@@ -64,24 +64,38 @@ CSiaFileCollection CSiaApi::_CSiaFileTree::Query(String query) const
|
|||||||
return std::move(ret);
|
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);
|
CSiaFileCollection col;
|
||||||
ReplaceStringInPlace(ReplaceStringInPlace(ReplaceStringInPlace(query, L".", L"\\."), L"*", L"[^/]+"), L"?", L"[^/]?");
|
ReplaceStringInPlace(rootFolder, L"/", L"\\");
|
||||||
std::wregex r(query);
|
if (rootFolder[0] == '\\')
|
||||||
|
{
|
||||||
|
rootFolder = rootFolder.substr(1);
|
||||||
|
}
|
||||||
|
|
||||||
std::vector<String> ret;
|
std::vector<String> ret;
|
||||||
std::for_each(_fileList.begin(), _fileList.end(), [&](const CSiaFilePtr& v)
|
std::for_each(_fileList.begin(), _fileList.end(), [&](const CSiaFilePtr& v)
|
||||||
{
|
{
|
||||||
String dir = v->GetSiaPath();
|
String dir = v->GetSiaPath();
|
||||||
int pos = dir.find_last_of('/');
|
ReplaceStringInPlace(dir, L"/", L"\\");
|
||||||
if (pos > -1)
|
::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('/');
|
String subFolder = dir.substr(rootFolder.length());
|
||||||
dir = dir.substr(0, pos);
|
int f = subFolder.find_first_of('\\');
|
||||||
if (std::find(ret.begin(), ret.end(), dir) == ret.end())
|
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
|
else
|
||||||
{
|
{
|
||||||
bool isFile = (FileAttributes & FILE_NON_DIRECTORY_FILE) ? true : false;
|
OutputDebugString(FileName);
|
||||||
DokanFileInfo->IsDirectory = !isFile;
|
OutputDebugString(L"\n");
|
||||||
if (isFile)
|
// 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
|
// Formulate Sia path and cache path
|
||||||
String siaPath = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName)); // Strip drive letter to get Sia path
|
String siaPath = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName)); // Strip drive letter to get Sia path
|
||||||
if (siaPath.length())
|
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 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;
|
ret = STATUS_OBJECT_NAME_COLLISION;
|
||||||
}
|
}
|
||||||
@@ -278,16 +294,14 @@ private:
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
DokanFileInfo->Context = reinterpret_cast<ULONG64>(handle); // save the file handle in Context
|
DokanFileInfo->Context = reinterpret_cast<ULONG64>(handle); // save the file handle in Context
|
||||||
if (isFile)
|
|
||||||
{
|
OpenFileInfo ofi;
|
||||||
OpenFileInfo ofi;
|
ofi.SiaPath = siaPath;
|
||||||
ofi.SiaPath = siaPath;
|
ofi.CacheFilePath = cacheFilePath;
|
||||||
ofi.CacheFilePath = cacheFilePath;
|
// TODO Detect if file is read-only
|
||||||
// TODO Detect if file is read-only
|
// TODO Quick hash to detect changes
|
||||||
// TODO Quick hash to detect changes
|
ofi.ReadOnly = false;
|
||||||
ofi.ReadOnly = false;
|
_openFileMap.insert({ DokanFileInfo->Context, ofi });
|
||||||
_openFileMap.insert({ DokanFileInfo->Context, ofi });
|
|
||||||
}
|
|
||||||
|
|
||||||
/*if (creationDisposition == OPEN_ALWAYS ||
|
/*if (creationDisposition == OPEN_ALWAYS ||
|
||||||
creationDisposition == CREATE_ALWAYS) {
|
creationDisposition == CREATE_ALWAYS) {
|
||||||
@@ -316,17 +330,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // Folder Operation (cache operation only)
|
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);
|
HANDLE handle = ::CreateFile(cacheFilePath.c_str(), genericDesiredAccess, ShareAccess, &securityAttrib, creationDisposition, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||||
if (handle == INVALID_HANDLE_VALUE)
|
if (handle == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
@@ -352,27 +356,37 @@ private:
|
|||||||
if (siaFileTree)
|
if (siaFileTree)
|
||||||
{
|
{
|
||||||
String siaQuery = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName));
|
String siaQuery = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName));
|
||||||
String dirQuery = siaQuery;
|
String rootPath = FileName;
|
||||||
if (::PathIsDirectory(FileName))
|
if (::PathIsDirectory(FileName))
|
||||||
{
|
{
|
||||||
siaQuery += L"/*.*";
|
siaQuery += L"/*.*";
|
||||||
dirQuery = siaQuery;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
String dir = FileName;
|
::PathRemoveFileSpec(&rootPath[0]);
|
||||||
::PathRemoveFileSpec(&dir[0]);
|
rootPath = rootPath.c_str();
|
||||||
dirQuery = dir + L"/*.*";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
auto dirList = siaFileTree->QueryDirectories(dirQuery);
|
auto dirList = siaFileTree->QueryDirectories(rootPath);
|
||||||
for (auto& dir : dirList)
|
for (auto& dir : dirList)
|
||||||
{
|
{
|
||||||
WIN32_FIND_DATA fd = { 0 };
|
WIN32_FIND_DATA fd = { 0 };
|
||||||
wcscpy_s(fd.cFileName, dir.c_str());
|
wcscpy_s(fd.cFileName, dir.c_str());
|
||||||
|
|
||||||
fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
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);
|
FillFindData(&fd, DokanFileInfo);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user