diff --git a/SiaDrive.Dokan.Api/SiaDokenDrive.cpp b/SiaDrive.Dokan.Api/SiaDokenDrive.cpp index 3e0b18e..1c782fd 100644 --- a/SiaDrive.Dokan.Api/SiaDokenDrive.cpp +++ b/SiaDrive.Dokan.Api/SiaDokenDrive.cpp @@ -1,48 +1,107 @@ #include "stdafx.h" #include "SiaDokenDrive.h" #include -#include using namespace Sia::Api; using namespace Sia::Api::Dokan; - -static bool s_dokenInitialized = false; -static CSiaDokenDrive* s_dokenDrive = nullptr; -static DOKAN_OPERATIONS s_dokanOps = {0}; - - -static NTSTATUS DOKAN_CALLBACK SiaDrive_ZwCreateFile( - LPCWSTR FileName, - PDOKAN_IO_SECURITY_CONTEXT SecurityContext, - ACCESS_MASK DesiredAccess, - ULONG FileAttributes, - ULONG ShareAccess, - ULONG CreateDisposition, - ULONG CreateOptions, - PDOKAN_FILE_INFO DokanFileInfo) +class DokanImpl { -} +private: + static std::mutex _dokanMutex; + static CSiaApi* _siaApi; + static DOKAN_OPERATIONS _dokanOps; +private: + static NTSTATUS DOKAN_CALLBACK SiaDrive_ZwCreateFile( + LPCWSTR FileName, + PDOKAN_IO_SECURITY_CONTEXT SecurityContext, + ACCESS_MASK DesiredAccess, + ULONG FileAttributes, + ULONG ShareAccess, + ULONG CreateDisposition, + ULONG CreateOptions, + PDOKAN_FILE_INFO DokanFileInfo) + { + } + + static NTSTATUS DOKAN_CALLBACK SiaDrive_FindFiles( + LPCWSTR FileName, + PFillFindData FillFindData, + PDOKAN_FILE_INFO DokanFileInfo) + { + } + +public: + static void Initialize(CSiaApi* siaApi) + { + _siaApi = siaApi; + _dokanOps.Cleanup = nullptr; + _dokanOps.CloseFile = nullptr; + _dokanOps.DeleteDirectory = nullptr; + _dokanOps.DeleteFileW = nullptr; + _dokanOps.FindFiles = SiaDrive_FindFiles; + _dokanOps.FindFilesWithPattern = nullptr; + _dokanOps.FindStreams = nullptr; + _dokanOps.FlushFileBuffers = nullptr; + _dokanOps.GetDiskFreeSpaceW = nullptr; + _dokanOps.GetFileInformation = nullptr; + _dokanOps.GetFileSecurityW = nullptr; + _dokanOps.GetVolumeInformationW = nullptr; + _dokanOps.LockFile = nullptr; + _dokanOps.Mounted = nullptr; + _dokanOps.MoveFileW = nullptr; + _dokanOps.ReadFile = nullptr; + _dokanOps.SetAllocationSize = nullptr; + _dokanOps.SetEndOfFile = nullptr; + _dokanOps.SetFileAttributesW = nullptr; + _dokanOps.SetFileSecurityW = nullptr; + _dokanOps.SetFileTime = nullptr; + _dokanOps.UnlockFile = nullptr; + _dokanOps.Unmounted = nullptr; + _dokanOps.WriteFile = nullptr; + _dokanOps.ZwCreateFile = SiaDrive_ZwCreateFile; + } + + static void Shutdown() + { + _siaApi = nullptr; + ZeroMemory(&_dokanOps, sizeof(_dokanOps)); + } + + static std::mutex& GetMutex() + { + return _dokanMutex; + } + + static bool IsInitialized() + { + return _siaApi != nullptr; + } +}; +std::mutex DokanImpl::_dokanMutex; +CSiaApi* DokanImpl::_siaApi = nullptr; +DOKAN_OPERATIONS DokanImpl::_dokanOps = { 0 }; CSiaDokenDrive::CSiaDokenDrive(CSiaApi& siaApi) : _siaApi(siaApi) { - if (s_dokenDrive) + std::lock_guard l(DokanImpl::GetMutex()); + if (DokanImpl::IsInitialized()) { throw SiaDokenDriveException("Sia drive has already been activated"); } else { - s_dokenDrive = this; - s_dokanOps.ZwCreateFile = SiaDrive_ZwCreateFile; + DokanImpl::Initialize(&_siaApi); } } CSiaDokenDrive::~CSiaDokenDrive() { + std::lock_guard l(DokanImpl::GetMutex()); Unmount(); - s_dokenDrive = nullptr; + DokanImpl::Shutdown(); } void CSiaDokenDrive::Mount(const wchar_t& driveLetter) diff --git a/SiaDrive.Dokan.Api/SiaDokenDrive.h b/SiaDrive.Dokan.Api/SiaDokenDrive.h index 8f7cd4b..26e85c4 100644 --- a/SiaDrive.Dokan.Api/SiaDokenDrive.h +++ b/SiaDrive.Dokan.Api/SiaDokenDrive.h @@ -1,5 +1,6 @@ #pragma once #include +#include NS_BEGIN(Sia) NS_BEGIN(Api)