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

View File

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