Partial fix for delete directory
This commit is contained in:
@@ -196,11 +196,12 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanFindFiles :
|
||||
public CEvent
|
||||
{
|
||||
public:
|
||||
DokanFindFiles(const SString& cachePath, const SString& rootPath, const SString& siaQuery, const SString& findFile) :
|
||||
DokanFindFiles(const SString& cachePath, const SString& rootPath, const SString& siaQuery, const SString& findFile, const SString& fileName) :
|
||||
_cachePath(cachePath),
|
||||
_rootPath(rootPath),
|
||||
_siaQuery(siaQuery),
|
||||
_findFile(findFile)
|
||||
_findFile(findFile),
|
||||
_fileName(fileName)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -214,11 +215,12 @@ private:
|
||||
const SString _rootPath;
|
||||
const SString _siaQuery;
|
||||
const SString _findFile;
|
||||
const SString _fileName;
|
||||
|
||||
public:
|
||||
virtual std::shared_ptr<CEvent> Clone() const override
|
||||
{
|
||||
return std::shared_ptr<CEvent>(new DokanFindFiles(_cachePath, _rootPath, _siaQuery, _findFile));
|
||||
return std::shared_ptr<CEvent>(new DokanFindFiles(_cachePath, _rootPath, _siaQuery, _findFile, _fileName));
|
||||
}
|
||||
|
||||
virtual SString GetSingleLineMessage() const override
|
||||
@@ -226,7 +228,8 @@ public:
|
||||
return L"DokanFindFiles|PATH|" + _cachePath +
|
||||
"|ROOT|" + _rootPath +
|
||||
"|QUERY|" + _siaQuery +
|
||||
"|FIND|" + _findFile;
|
||||
"|FIND|" + _findFile +
|
||||
"|FN|" + _fileName;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -265,8 +268,10 @@ class SIADRIVE_DOKAN_EXPORTABLE DokanGetFileInformation :
|
||||
public CEvent
|
||||
{
|
||||
public:
|
||||
DokanGetFileInformation(const SString& cachePath) :
|
||||
_cachePath(cachePath)
|
||||
DokanGetFileInformation(const SString& cachePath, const SString& fileName, const NTSTATUS& result) :
|
||||
_cachePath(cachePath),
|
||||
_fileName(fileName),
|
||||
_result(result)
|
||||
{
|
||||
}
|
||||
|
||||
@@ -277,16 +282,18 @@ public:
|
||||
|
||||
private:
|
||||
const SString _cachePath;
|
||||
const SString _fileName;
|
||||
const NTSTATUS _result;
|
||||
|
||||
public:
|
||||
virtual std::shared_ptr<CEvent> Clone() const override
|
||||
{
|
||||
return std::shared_ptr<CEvent>(new DokanGetFileInformation(_cachePath));
|
||||
return std::shared_ptr<CEvent>(new DokanGetFileInformation(_cachePath, _fileName, _result));
|
||||
}
|
||||
|
||||
virtual SString GetSingleLineMessage() const override
|
||||
{
|
||||
return L"DokanGetFileInformation|PATH|" + _cachePath;
|
||||
return L"DokanGetFileInformation|PATH|" + _cachePath + "|FN|" + _fileName + "|RES|" + SString::FromUInt32(_result);
|
||||
}
|
||||
};
|
||||
|
||||
|
@@ -274,7 +274,7 @@ private:
|
||||
else
|
||||
{
|
||||
// FILE_FLAG_BACKUP_SEMANTICS is required for opening directory handles
|
||||
HANDLE handle = ::CreateFile(&cacheFilePath[0], genericDesiredAccess, shareAccess, &securityAttrib, OPEN_EXISTING, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS, nullptr);
|
||||
HANDLE handle = ::CreateFile(&cacheFilePath[0], genericDesiredAccess, shareAccess, &securityAttrib, OPEN_EXISTING, fileAttributesAndFlags | FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_POSIX_SEMANTICS, nullptr);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
@@ -295,7 +295,7 @@ private:
|
||||
else // File (cache and/or Sia operation)
|
||||
{
|
||||
// Formulate Sia path
|
||||
SString siaPath = CSiaApi::FormatToSiaPath(FilePath(fileName).SkipRoot()); // Strip drive letter to get Sia path
|
||||
SString siaPath = CSiaApi::FormatToSiaPath(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
|
||||
@@ -474,37 +474,36 @@ private:
|
||||
|
||||
static NTSTATUS DOKAN_CALLBACK Sia_FindFiles(LPCWSTR fileName, PFillFindData fillFindData, PDOKAN_FILE_INFO dokanFileInfo)
|
||||
{
|
||||
NTSTATUS ret = STATUS_SUCCESS;
|
||||
NTSTATUS ret = STATUS_INVALID_SERVER_STATE;
|
||||
auto siaFileTree = GetFileTree();
|
||||
if (siaFileTree)
|
||||
{
|
||||
SString siaFileQuery = CSiaApi::FormatToSiaPath(FilePath(fileName).SkipRoot());
|
||||
SString siaRootPath = CSiaApi::FormatToSiaPath(FilePath(fileName).SkipRoot());
|
||||
SString siaFileQuery = CSiaApi::FormatToSiaPath(fileName);
|
||||
SString siaRootPath = CSiaApi::FormatToSiaPath(fileName);
|
||||
FilePath siaDirQuery = siaFileQuery;
|
||||
FilePath findFile = GetCacheLocation();
|
||||
FilePath cachePath = GetCacheLocation();
|
||||
if (FilePath::DirSep == fileName)
|
||||
{
|
||||
siaFileQuery += L"/*.*";
|
||||
findFile.Append("*.*");
|
||||
findFile.Append("*");
|
||||
}
|
||||
else
|
||||
{
|
||||
cachePath.Append(fileName);
|
||||
findFile.Append(fileName);
|
||||
if (cachePath.IsDirectory())
|
||||
if (dokanFileInfo->IsDirectory)
|
||||
{
|
||||
siaFileQuery += L"/*.*";
|
||||
findFile.Append("*.*");
|
||||
findFile.Append("*");
|
||||
}
|
||||
else
|
||||
{
|
||||
siaDirQuery = cachePath;
|
||||
siaDirQuery = CSiaApi::FormatToSiaPath(siaDirQuery.RemoveFileName());
|
||||
siaDirQuery = FilePath();
|
||||
}
|
||||
}
|
||||
|
||||
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFindFiles(cachePath, siaDirQuery, siaFileQuery, findFile)));
|
||||
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanFindFiles(cachePath, siaDirQuery, siaFileQuery, findFile, fileName)));
|
||||
|
||||
WIN32_FIND_DATA findData = { 0 };
|
||||
HANDLE findHandle = ::FindFirstFile(&findFile[0], &findData);
|
||||
@@ -525,10 +524,12 @@ private:
|
||||
if (findData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
|
||||
{
|
||||
dirs.insert({ findData.cFileName, 0 });
|
||||
fillFindData(&findData, dokanFileInfo);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
bool exists;
|
||||
if (!ApiSuccess(_siaApi->GetRenter()->FileExists(CSiaApi::FormatToSiaPath(FilePath(siaRootPath, findData.cFileName)), exists)))
|
||||
if (!ApiSuccess(_siaApi->GetRenter()->FileExists(CSiaApi::FormatToSiaPath(FilePath(fileName, findData.cFileName)), exists)))
|
||||
{
|
||||
::FindClose(findHandle);
|
||||
return STATUS_INVALID_DEVICE_STATE;
|
||||
@@ -540,26 +541,34 @@ private:
|
||||
files.insert({ findData.cFileName, 1 });
|
||||
}
|
||||
}
|
||||
}
|
||||
} while (::FindNextFile(findHandle, &findData) != 0);
|
||||
|
||||
DWORD error = GetLastError();
|
||||
::FindClose(findHandle);
|
||||
|
||||
if (error == ERROR_NO_MORE_FILES)
|
||||
{
|
||||
// Find Sia directories
|
||||
if (!static_cast<SString>(siaDirQuery).IsNullOrEmpty())
|
||||
{
|
||||
auto dirList = siaFileTree->QueryDirectories(siaDirQuery);
|
||||
for (auto& dir : dirList)
|
||||
{
|
||||
if (dirs.find(dir) == dirs.end())
|
||||
{
|
||||
WIN32_FIND_DATA fd = { 0 };
|
||||
wcscpy_s(fd.cFileName, dir.str().c_str());
|
||||
fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
fillFindData(&fd, dokanFileInfo);
|
||||
|
||||
// Create cache sub-folder
|
||||
FilePath subCachePath(cachePath, dir);
|
||||
if (!subCachePath.IsDirectory())
|
||||
{
|
||||
subCachePath.CreateDirectory();
|
||||
}
|
||||
|
||||
WIN32_FIND_DATA fd = { 0 };
|
||||
wcscpy_s(fd.cFileName, dir.str().c_str());
|
||||
fd.dwFileAttributes = FILE_ATTRIBUTE_DIRECTORY;
|
||||
fillFindData(&fd, dokanFileInfo);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -582,6 +591,13 @@ private:
|
||||
fillFindData(&fd, dokanFileInfo);
|
||||
}
|
||||
}
|
||||
|
||||
ret = STATUS_SUCCESS;
|
||||
}
|
||||
else
|
||||
{
|
||||
ret = DokanNtStatusFromWin32(error);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -612,17 +628,13 @@ private:
|
||||
BOOL opened = FALSE;
|
||||
NTSTATUS ret = STATUS_SUCCESS;
|
||||
|
||||
FilePath cachePath(GetCacheLocation(), fileName);
|
||||
|
||||
SString siaPath = CSiaApi::FormatToSiaPath(FilePath(fileName).SkipRoot());
|
||||
auto siaFileTree = GetFileTree();
|
||||
auto siaFile = siaFileTree ? siaFileTree->GetFile(siaPath) : nullptr;
|
||||
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanGetFileInformation(cachePath)));
|
||||
auto siaFile = siaFileTree ? siaFileTree->GetFile(openFileInfo->SiaPath) : nullptr;
|
||||
|
||||
HANDLE tempHandle = openFileInfo->FileHandle;
|
||||
if (!siaFile && (!openFileInfo->FileHandle || (openFileInfo->FileHandle == INVALID_HANDLE_VALUE)))
|
||||
if (!siaFile && (!tempHandle || (tempHandle == INVALID_HANDLE_VALUE)))
|
||||
{
|
||||
tempHandle = ::CreateFile(&cachePath[0], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
tempHandle = ::CreateFile(&openFileInfo->CacheFilePath[0], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
|
||||
if (tempHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
ret = DokanNtStatusFromWin32(::GetLastError());
|
||||
@@ -650,12 +662,12 @@ private:
|
||||
// in this case, FindFirstFile can't get directory information
|
||||
if (wcscmp(fileName, L"\\") == 0)
|
||||
{
|
||||
handleFileInfo->dwFileAttributes = ::GetFileAttributes(&cachePath[0]);
|
||||
handleFileInfo->dwFileAttributes = ::GetFileAttributes(&openFileInfo->CacheFilePath[0]);
|
||||
}
|
||||
else
|
||||
{
|
||||
WIN32_FIND_DATAW find = { 0 };
|
||||
HANDLE findHandle = ::FindFirstFile(&cachePath[0], &find);
|
||||
HANDLE findHandle = ::FindFirstFile(&openFileInfo->CacheFilePath[0], &find);
|
||||
if (findHandle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
DWORD error = ::GetLastError();
|
||||
@@ -681,6 +693,8 @@ private:
|
||||
::CloseHandle(tempHandle);
|
||||
}
|
||||
|
||||
CEventSystem::EventSystem.NotifyEvent(CreateSystemEvent(DokanGetFileInformation(openFileInfo->CacheFilePath, fileName, ret)));
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
@@ -709,7 +723,7 @@ private:
|
||||
UNREFERENCED_PARAMETER(dokanFileInfo);
|
||||
|
||||
// TODO Implement this correctly
|
||||
*FreeBytesAvailable = static_cast<ULONGLONG>(512 * 1024 * 1024);
|
||||
*FreeBytesAvailable = static_cast<ULONGLONG>(1024 * 1024 * 1024);
|
||||
*TotalNumberOfBytes = 9223372036854775807;
|
||||
*TotalNumberOfFreeBytes = 9223372036854775807;
|
||||
|
||||
@@ -724,7 +738,7 @@ private:
|
||||
UNREFERENCED_PARAMETER(dokanFileInfo);
|
||||
|
||||
wcscpy_s(VolumeNameBuffer, VolumeNameSize, L"SiaDrive");
|
||||
*VolumeSerialNumber = 0x19831116;
|
||||
*VolumeSerialNumber = 0x19831186;
|
||||
*MaximumComponentLength = 256;
|
||||
*FileSystemFlags = FILE_CASE_SENSITIVE_SEARCH | FILE_CASE_PRESERVED_NAMES |
|
||||
FILE_SUPPORTS_REMOTE_STORAGE | FILE_UNICODE_ON_DISK |
|
||||
@@ -971,7 +985,7 @@ private:
|
||||
// if open with FILE_FLAG_DELETE_ON_CLOSE
|
||||
if (dokanFileInfo->IsDirectory)
|
||||
{
|
||||
if (filePath.RemoveDirectory())
|
||||
if (RetryableAction(filePath.RemoveDirectory(), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS))
|
||||
{
|
||||
}
|
||||
else
|
||||
@@ -980,7 +994,7 @@ private:
|
||||
}
|
||||
else
|
||||
{
|
||||
if (filePath.DeleteFile())
|
||||
if (RetryableAction(filePath.RemoveDirectory(), DEFAULT_RETRY_COUNT, DEFAULT_RETRY_DELAY_MS))
|
||||
{
|
||||
}
|
||||
else
|
||||
@@ -1040,12 +1054,14 @@ private:
|
||||
}
|
||||
}
|
||||
while ((ret == STATUS_SUCCESS) && (::FindNextFile(findHandle, &findData) != 0));
|
||||
|
||||
if (ret != STATUS_DIRECTORY_NOT_EMPTY)
|
||||
{
|
||||
DWORD error = GetLastError();
|
||||
if (error != ERROR_NO_MORE_FILES)
|
||||
{
|
||||
ret = DokanNtStatusFromWin32(error);
|
||||
}
|
||||
}
|
||||
|
||||
::FindClose(findHandle);
|
||||
}
|
||||
@@ -1321,6 +1337,9 @@ public:
|
||||
_dokanOptions.ThreadCount = 0; // use default
|
||||
#ifdef _DEBUG
|
||||
_dokanOptions.Options = DOKAN_OPTION_DEBUG | DOKAN_OPTION_DEBUG_LOG_FILE;
|
||||
_dokanOptions.Timeout = (60 * 1000) * 60;
|
||||
#else
|
||||
_dokanOptions.Options = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user