1
0

Directory listing changes

This commit is contained in:
Scott E. Graves
2017-03-12 14:00:51 -05:00
parent d3714a6fdd
commit 170a79d0fc

View File

@@ -6,6 +6,8 @@
using namespace Sia::Api;
using namespace Sia::Api::Dokan;
// TODO Handle paths greater than MAX_PATH!!
// The general idea is that normal file I/O occurs in a local cache folder and once the file is closed, it is scheduled for upload into Sia.
// Files requested to be openned that are not cached will be downloaded first. If the file is not found in Sia, it will be treated as new.
// Keeping cache and Sia in synch will be a bit of a hastle, so it's strongly suggested to treat the cache folder as if it doesn't exist;
@@ -48,8 +50,9 @@ private:
bool ret = false;
std::wstring tempPath;
tempPath.resize(MAX_PATH + 1);
if (GetTempPath(MAX_PATH + 1, &tempPath[0]))
if (::GetTempPath(MAX_PATH + 1, &tempPath[0]))
{
// Check cache size is large enough to hold new file
ret = ApiSuccess(_siaApi->GetRenter()->DownloadFile(siaPath, tempPath));
if (ret)
{
@@ -148,14 +151,12 @@ private:
}
else
{
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());
::PathCombine(&cacheFilePath[0], GetCacheLocation().c_str(), &FileName[1]);
DWORD fileAttr = ::GetFileAttributes(cacheFilePath.c_str());
if (fileAttr != INVALID_FILE_ATTRIBUTES &&
(fileAttr & FILE_ATTRIBUTE_DIRECTORY) &&
@@ -176,7 +177,7 @@ private:
if (siaPath.length())
{
// If cache file already exists and is a directory, requested file operation isn't valid
DWORD attribs = GetFileAttributes(cacheFilePath.c_str());
DWORD attribs = ::GetFileAttributes(cacheFilePath.c_str());
if ((attribs != INVALID_FILE_ATTRIBUTES) && (attribs & FILE_ATTRIBUTE_DIRECTORY))
{
ret = STATUS_OBJECT_NAME_COLLISION;
@@ -243,6 +244,10 @@ private:
}
}
break;
default:
// Nothing to do
break;
}
if (ret == STATUS_SUCCESS)
@@ -251,7 +256,7 @@ private:
{
// Since this is a request to replace an existing file, make sure cache is deleted first.
// If file isn't cached, delete from Sia only
if (!PathFileExists(cacheFilePath.c_str()) || ::DeleteFile(cacheFilePath.c_str()))
if (!::PathFileExists(cacheFilePath.c_str()) || ::DeleteFile(cacheFilePath.c_str()))
{
if (!ApiSuccess(_uploadManager->Remove(siaPath)))
{
@@ -279,7 +284,7 @@ private:
if (ret == STATUS_SUCCESS)
{
// Create file as specified
HANDLE handle = CreateFile(
HANDLE handle = ::CreateFile(
cacheFilePath.c_str(),
genericDesiredAccess,
ShareAccess,
@@ -346,10 +351,7 @@ private:
return ret;
}
static NTSTATUS DOKAN_CALLBACK SiaDrive_FindFiles(
LPCWSTR FileName,
PFillFindData FillFindData,
PDOKAN_FILE_INFO DokanFileInfo)
static NTSTATUS DOKAN_CALLBACK SiaDrive_FindFiles(LPCWSTR FileName, PFillFindData FillFindData, PDOKAN_FILE_INFO DokanFileInfo)
{
std::lock_guard<std::mutex> l(_dokanMutex);
auto siaFileTree = _siaFileTree;
@@ -394,7 +396,7 @@ private:
for (auto& file : fileList)
{
WIN32_FIND_DATA fd = { 0 };
wcscpy_s(fd.cFileName, PathFindFileName(file->GetSiaPath().c_str()));
wcscpy_s(fd.cFileName, ::PathFindFileName(file->GetSiaPath().c_str()));
LARGE_INTEGER li = { 0 };
li.QuadPart = file->GetFileSize();
@@ -424,7 +426,7 @@ private:
else
{
LARGE_INTEGER li = { 0 };
BOOL sizeOk = GetFileSizeEx(handle, &li);
BOOL sizeOk = ::GetFileSizeEx(handle, &li);
::CloseHandle(handle);
@@ -440,6 +442,75 @@ private:
}
}
static NTSTATUS DOKAN_CALLBACK Sia_GetFileInformation(LPCWSTR FileName, LPBY_HANDLE_FILE_INFORMATION HandleFileInformation, PDOKAN_FILE_INFO DokanFileInfo)
{
HANDLE handle = reinterpret_cast<HANDLE>(DokanFileInfo->Context);
BOOL opened = FALSE;
NTSTATUS ret = STATUS_SUCCESS;
String cachePath = GetCacheLocation().c_str();
if (wcscmp(FileName, L"\\") != 0)
{
cachePath.resize(MAX_PATH + 1);
::PathAppend(&cachePath[0], FileName);
cachePath = cachePath.c_str();
}
if (!handle || (handle == INVALID_HANDLE_VALUE))
{
handle = ::CreateFile(&cachePath[0], GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, nullptr);
if (handle == INVALID_HANDLE_VALUE)
{
ret = DokanNtStatusFromWin32(GetLastError());
}
else
{
opened = TRUE;
}
}
if (ret == STATUS_SUCCESS)
{
if (!::GetFileInformationByHandle(handle, HandleFileInformation))
{
// FileName is a root directory
// in this case, FindFirstFile can't get directory information
if (wcslen(FileName) == 1)
{
HandleFileInformation->dwFileAttributes = ::GetFileAttributes(&cachePath[0]);
}
else
{
WIN32_FIND_DATAW find = { 0 };
HANDLE findHandle = ::FindFirstFile(&cachePath[0], &find);
if (findHandle == INVALID_HANDLE_VALUE)
{
// TODO Not Cached, so manual attributes
ret = DokanNtStatusFromWin32(::GetLastError());
}
else
{
HandleFileInformation->dwFileAttributes = find.dwFileAttributes;
HandleFileInformation->ftCreationTime = find.ftCreationTime;
HandleFileInformation->ftLastAccessTime = find.ftLastAccessTime;
HandleFileInformation->ftLastWriteTime = find.ftLastWriteTime;
HandleFileInformation->nFileSizeHigh = find.nFileSizeHigh;
HandleFileInformation->nFileSizeLow = find.nFileSizeLow;
FindClose(findHandle);
}
}
}
if (opened)
{
CloseHandle(handle);
}
}
return ret;
}
static NTSTATUS DOKAN_CALLBACK Sia_Mounted(PDOKAN_FILE_INFO DokanFileInfo)
{
std::lock_guard<std::mutex> l(_dokanMutex);
@@ -505,7 +576,7 @@ public:
_dokanOps.FindStreams = nullptr;
_dokanOps.FlushFileBuffers = nullptr;
_dokanOps.GetDiskFreeSpaceW = Sia_GetDiskFreeSpaceW;
_dokanOps.GetFileInformation = nullptr;
_dokanOps.GetFileInformation = Sia_GetFileInformation;
_dokanOps.GetFileSecurityW = nullptr;
_dokanOps.GetVolumeInformationW = Sia_GetVolumeInformation;
_dokanOps.LockFile = nullptr;