Directory traversal complete
This commit is contained in:
@@ -86,10 +86,16 @@ std::vector<String> CSiaApi::_CSiaFileTree::QueryDirectories(String rootFolder)
|
||||
if ((dir.length() > rootFolder.length()) && (dir.substr(0, rootFolder.length()) == rootFolder))
|
||||
{
|
||||
String subFolder = dir.substr(rootFolder.length());
|
||||
int f = subFolder.find_first_of('\\');
|
||||
if (f > 0)
|
||||
int idx = subFolder.find_first_of('\\');
|
||||
if (idx == 0)
|
||||
{
|
||||
subFolder = subFolder.substr(0, f);
|
||||
subFolder = subFolder.substr(1);
|
||||
idx = subFolder.find_first_of('\\');
|
||||
}
|
||||
|
||||
if (idx > 0)
|
||||
{
|
||||
subFolder = subFolder.substr(0, idx);
|
||||
}
|
||||
|
||||
auto it = std::find(ret.begin(), ret.end(), subFolder);
|
||||
|
@@ -158,7 +158,7 @@ private:
|
||||
::PathCombine(&cacheFilePath[0], GetCacheLocation().c_str(), &FileName[1]);
|
||||
DWORD fileAttr = ::GetFileAttributes(cacheFilePath.c_str());
|
||||
|
||||
if (fileAttr != INVALID_FILE_ATTRIBUTES &&
|
||||
if ((fileAttr != INVALID_FILE_ATTRIBUTES) &&
|
||||
(fileAttr & FILE_ATTRIBUTE_DIRECTORY) &&
|
||||
!(CreateOptions & FILE_NON_DIRECTORY_FILE))
|
||||
{
|
||||
@@ -170,12 +170,25 @@ private:
|
||||
}
|
||||
}
|
||||
|
||||
if (!DokanFileInfo->IsDirectory)
|
||||
// Folder (cache operation only)
|
||||
if (DokanFileInfo->IsDirectory)
|
||||
{
|
||||
HANDLE handle = ::CreateFile(cacheFilePath.c_str(), genericDesiredAccess, ShareAccess, &securityAttrib, creationDisposition, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ret = DokanNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
DokanFileInfo->Context = reinterpret_cast<ULONG64>(handle); // save the file handle in Context
|
||||
}
|
||||
}
|
||||
else // File (cache and/or Sia operation)
|
||||
{
|
||||
// Formulate Sia path and cache path
|
||||
String siaPath = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName)); // Strip drive letter to get Sia path
|
||||
if (siaPath.length())
|
||||
{
|
||||
{
|
||||
// If cache file already exists and is a directory, requested file operation isn't valid
|
||||
DWORD attribs = ::GetFileAttributes(cacheFilePath.c_str());
|
||||
if ((attribs != INVALID_FILE_ATTRIBUTES) && (attribs & FILE_ATTRIBUTE_DIRECTORY))
|
||||
@@ -309,15 +322,15 @@ private:
|
||||
_openFileMap.insert({ DokanFileInfo->Context, ofi });
|
||||
|
||||
/*if (creationDisposition == OPEN_ALWAYS ||
|
||||
creationDisposition == CREATE_ALWAYS) {
|
||||
error = GetLastError();
|
||||
if (error == ERROR_ALREADY_EXISTS) {
|
||||
DbgPrint(L"\tOpen an already existing file\n");
|
||||
// Open succeed but we need to inform the driver
|
||||
// that the file open and not created by returning STATUS_OBJECT_NAME_COLLISION
|
||||
return STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
}*/
|
||||
creationDisposition == CREATE_ALWAYS) {
|
||||
error = GetLastError();
|
||||
if (error == ERROR_ALREADY_EXISTS) {
|
||||
DbgPrint(L"\tOpen an already existing file\n");
|
||||
// Open succeed but we need to inform the driver
|
||||
// that the file open and not created by returning STATUS_OBJECT_NAME_COLLISION
|
||||
return STATUS_OBJECT_NAME_COLLISION;
|
||||
}
|
||||
}*/
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -334,18 +347,6 @@ private:
|
||||
ret = STATUS_OBJECT_NAME_INVALID;
|
||||
}
|
||||
}
|
||||
else // Folder Operation (cache operation only)
|
||||
{
|
||||
HANDLE handle = ::CreateFile(cacheFilePath.c_str(), genericDesiredAccess, ShareAccess, &securityAttrib, creationDisposition, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ret = DokanNtStatusFromWin32(GetLastError());
|
||||
}
|
||||
else
|
||||
{
|
||||
DokanFileInfo->Context = reinterpret_cast<ULONG64>(handle); // save the file handle in Context
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
@@ -357,16 +358,30 @@ private:
|
||||
auto siaFileTree = _siaFileTree;
|
||||
if (siaFileTree)
|
||||
{
|
||||
String siaQuery = CSiaApi::FormatToSiaPath(PathSkipRoot(FileName));
|
||||
String rootPath = FileName;
|
||||
if (::PathIsDirectory(FileName))
|
||||
String siaQuery = CSiaApi::FormatToSiaPath(::PathSkipRoot(FileName));
|
||||
|
||||
String cachePath;
|
||||
String rootPath = siaQuery;
|
||||
if (wcscmp(FileName, L"\\") == 0)
|
||||
{
|
||||
cachePath = GetCacheLocation().c_str();
|
||||
siaQuery += L"/*.*";
|
||||
}
|
||||
else
|
||||
{
|
||||
::PathRemoveFileSpec(&rootPath[0]);
|
||||
rootPath = rootPath.c_str();
|
||||
cachePath.resize(MAX_PATH + 1);
|
||||
::PathCombine(&cachePath[0], GetCacheLocation().c_str(), &FileName[1]);
|
||||
cachePath = cachePath.c_str();
|
||||
if (::GetFileAttributes(&cachePath[0]) & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
siaQuery += L"/*.*";
|
||||
}
|
||||
else
|
||||
{
|
||||
rootPath = cachePath;
|
||||
::PathRemoveFileSpec(&rootPath[0]);
|
||||
rootPath = CSiaApi::FormatToSiaPath(rootPath);
|
||||
}
|
||||
}
|
||||
|
||||
auto dirList = siaFileTree->QueryDirectories(rootPath);
|
||||
@@ -374,22 +389,15 @@ private:
|
||||
{
|
||||
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);
|
||||
|
||||
// Create cache sub-folder
|
||||
String subCachePath = cachePath.c_str();
|
||||
subCachePath.resize(MAX_PATH + 1);
|
||||
::PathAppend(&subCachePath[0], dir.c_str());
|
||||
subCachePath = subCachePath.c_str();
|
||||
::CreateDirectory(subCachePath.c_str(), nullptr);
|
||||
}
|
||||
|
||||
auto fileList = siaFileTree->Query(siaQuery);
|
||||
|
Reference in New Issue
Block a user