1
0

Drive changes

This commit is contained in:
Scott E. Graves
2017-03-04 01:09:16 -06:00
parent 9e61c30ba9
commit d3714a6fdd
2 changed files with 75 additions and 47 deletions

View File

@@ -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);
}
}
});

View File

@@ -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);
}