Index: src/libchcore/IFilesystem.cpp =================================================================== diff -u -N --- src/libchcore/IFilesystem.cpp (revision 0) +++ src/libchcore/IFilesystem.cpp (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,28 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "IFilesystem.h" + +BEGIN_CHCORE_NAMESPACE + +IFilesystem::~IFilesystem() +{ +} + +END_CHCORE_NAMESPACE Index: src/libchcore/IFilesystem.h =================================================================== diff -u -N --- src/libchcore/IFilesystem.h (revision 0) +++ src/libchcore/IFilesystem.h (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,71 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __IFILESYSTEM_H__ +#define __IFILESYSTEM_H__ + +#include "libchcore.h" +#include "TPath.h" +#include "TFileInfoFwd.h" +#include "TBasePathDataFwd.h" +#include "TFileTime.h" +#include "IFilesystemFind.h" +#include "IFilesystemFile.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API IFilesystem +{ +public: + enum EPathsRelation + { + eRelation_Network, // at least one of the paths is network one + eRelation_CDRom, // at least one of the paths relates to cd/dvd drive + eRelation_TwoPhysicalDisks, // paths lies on two separate physical disks + eRelation_SinglePhysicalDisk, // paths lies on the same physical disk + eRelation_Other // other type of relation + }; + +public: + virtual ~IFilesystem(); + + virtual bool PathExist(const TSmartPath& strPath) = 0; + + virtual bool SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime) = 0; + virtual bool SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes) = 0; + + virtual bool CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath) = 0; + virtual bool RemoveDirectory(const TSmartPath& pathFile) = 0; + virtual bool DeleteFile(const TSmartPath& pathFile) = 0; + + virtual bool GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()) = 0; + virtual bool FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) = 0; + + virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) = 0; + virtual IFilesystemFilePtr CreateFileObject() = 0; + + virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) = 0; + + virtual bool GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) = 0; +}; + +typedef std::shared_ptr IFilesystemPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/IFilesystemFile.cpp =================================================================== diff -u -N --- src/libchcore/IFilesystemFile.cpp (revision 0) +++ src/libchcore/IFilesystemFile.cpp (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,28 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "IFilesystemFile.h" + +BEGIN_CHCORE_NAMESPACE + +IFilesystemFile::~IFilesystemFile() +{ +} + +END_CHCORE_NAMESPACE Index: src/libchcore/IFilesystemFile.h =================================================================== diff -u -N --- src/libchcore/IFilesystemFile.h (revision 0) +++ src/libchcore/IFilesystemFile.h (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,57 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __IFILESYSTEMFILE_H__ +#define __IFILESYSTEMFILE_H__ + +#include "libchcore.h" +#include "TPath.h" +#include "TOverlappedDataBuffer.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API IFilesystemFile +{ +public: + static const unsigned int MaxSectorSize = 4096; + +public: + virtual ~IFilesystemFile(); + + virtual bool OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering) = 0; + virtual bool CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering) = 0; + virtual bool OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering) = 0; + + virtual bool SetFilePointer(long long llNewPos, DWORD dwMoveMethod) = 0; + virtual bool SetEndOfFile() = 0; + + virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) = 0; + virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) = 0; + virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) = 0; + + virtual bool IsOpen() const = 0; + virtual unsigned long long GetFileSize() const = 0; + + virtual void Close() = 0; +}; + +typedef std::shared_ptr IFilesystemFilePtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/IFilesystemFind.cpp =================================================================== diff -u -N --- src/libchcore/IFilesystemFind.cpp (revision 0) +++ src/libchcore/IFilesystemFind.cpp (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,28 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "IFilesystemFind.h" + +BEGIN_CHCORE_NAMESPACE + +IFilesystemFind::~IFilesystemFind() +{ +} + +END_CHCORE_NAMESPACE Index: src/libchcore/IFilesystemFind.h =================================================================== diff -u -N --- src/libchcore/IFilesystemFind.h (revision 0) +++ src/libchcore/IFilesystemFind.h (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,40 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __IFILESYSTEMFIND_H__ +#define __IFILESYSTEMFIND_H__ + +#include "libchcore.h" +#include "TFileInfoFwd.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API IFilesystemFind +{ +public: + virtual ~IFilesystemFind(); + + virtual bool FindNext(TFileInfoPtr& rspFileInfo) = 0; + virtual void Close() = 0; +}; + +typedef std::shared_ptr IFilesystemFindPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TBasePathDataFwd.h =================================================================== diff -u -N --- src/libchcore/TBasePathDataFwd.h (revision 0) +++ src/libchcore/TBasePathDataFwd.h (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,31 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TBASEPATHDATAFWD_H__ +#define __TBASEPATHDATAFWD_H__ + +#include + +BEGIN_CHCORE_NAMESPACE + +class TBasePathData; +typedef boost::shared_ptr TBasePathDataPtr; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TLocalFilesystem.cpp =================================================================== diff -u -N -rcdc76e1a95383dff63a5254aeb8d37035028512c -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision cdc76e1a95383dff63a5254aeb8d37035028512c) +++ src/libchcore/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -41,12 +41,20 @@ #include "RoundingFunctions.h" #include #include "TBufferSizes.h" +#include "TLocalFilesystemFile.h" +#include +#include "TLocalFilesystemFind.h" BEGIN_CHCORE_NAMESPACE -// compile-time check - ensure the buffer granularity used for transfers are bigger than expected sector size -static_assert(TLocalFilesystemFile::MaxSectorSize <= TBufferSizes::BufferGranularity, "Buffer granularity must be equal to or bigger than the max sector size"); +TLocalFilesystem::TLocalFilesystem() +{ +} +TLocalFilesystem::~TLocalFilesystem() +{ +} + UINT TLocalFilesystem::GetDriveData(const TSmartPath& spPath) { UINT uiDrvType = DRIVE_UNKNOWN; @@ -68,7 +76,7 @@ return uiDrvType; } -bool TLocalFilesystem::PathExist(TSmartPath pathToCheck) +bool TLocalFilesystem::PathExist(const TSmartPath& pathToCheck) { WIN32_FIND_DATA fd; @@ -82,9 +90,10 @@ // another try (add '\\' if needed and '*' for marking that we look for ie. c:\* // instead of c:\, which would never be found prev. way) - pathToCheck.AppendIfNotExists(_T("*"), false); + TSmartPath findPath = pathToCheck; + findPath.AppendIfNotExists(_T("*"), false); - hFind = FindFirstFile(PrependPathExtensionIfNeeded(pathToCheck).ToString(), &fd); + hFind = FindFirstFile(PrependPathExtensionIfNeeded(findPath).ToString(), &fd); if(hFind != INVALID_HANDLE_VALUE) { ::FindClose(hFind); @@ -189,14 +198,14 @@ return ::MoveFile(PrependPathExtensionIfNeeded(pathSource).ToString(), PrependPathExtensionIfNeeded(pathDestination).ToString()) != FALSE; } -TLocalFilesystemFind TLocalFilesystem::CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) +IFilesystemFindPtr TLocalFilesystem::CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) { - return TLocalFilesystemFind(pathDir, pathMask); + return std::shared_ptr(new TLocalFilesystemFind(pathDir, pathMask)); } -TLocalFilesystemFile TLocalFilesystem::CreateFileObject() +IFilesystemFilePtr TLocalFilesystem::CreateFileObject() { - return TLocalFilesystemFile(); + return std::shared_ptr(new TLocalFilesystemFile()); } TSmartPath TLocalFilesystem::PrependPathExtensionIfNeeded(const TSmartPath& pathInput) @@ -320,251 +329,4 @@ ///////////////////////////////////////////////////////////////////////////////////// // class TLocalFilesystemFind -TLocalFilesystemFind::TLocalFilesystemFind(const TSmartPath& pathDir, const TSmartPath& pathMask) : - m_pathDir(pathDir), - m_pathMask(pathMask), - m_hFind(INVALID_HANDLE_VALUE) -{ -} - -TLocalFilesystemFind::~TLocalFilesystemFind() -{ - Close(); -} - -bool TLocalFilesystemFind::FindNext(TFileInfoPtr& rspFileInfo) -{ - WIN32_FIND_DATA wfd; - TSmartPath pathCurrent = m_pathDir + m_pathMask; - - // Iterate through dirs & files - bool bContinue = true; - if(m_hFind != INVALID_HANDLE_VALUE) - bContinue = (FindNextFile(m_hFind, &wfd) != FALSE); - else - { - m_hFind = FindFirstFile(TLocalFilesystem::PrependPathExtensionIfNeeded(pathCurrent).ToString(), &wfd); // in this case we always continue - bContinue = (m_hFind != INVALID_HANDLE_VALUE); - } - if(bContinue) - { - do - { - if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) - { - rspFileInfo->Init(m_pathDir + PathFromString(wfd.cFileName), wfd.dwFileAttributes, (((ULONGLONG) wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime, - wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0); - return true; - } - else if(wfd.cFileName[0] != _T('.') || (wfd.cFileName[1] != _T('\0') && (wfd.cFileName[1] != _T('.') || wfd.cFileName[2] != _T('\0')))) - { - // Add directory itself - rspFileInfo->Init(m_pathDir + PathFromString(wfd.cFileName), - wfd.dwFileAttributes, (((ULONGLONG) wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime, - wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0); - return true; - } - } - while(m_hFind != INVALID_HANDLE_VALUE && ::FindNextFile(m_hFind, &wfd)); // checking m_hFind in case other thread changed it (it shouldn't happen though) - - Close(); - } - - return false; -} - -void TLocalFilesystemFind::Close() -{ - if(m_hFind != INVALID_HANDLE_VALUE) - FindClose(m_hFind); - m_hFind = INVALID_HANDLE_VALUE; -} - -TLocalFilesystemFile::TLocalFilesystemFile() : - m_hFile(INVALID_HANDLE_VALUE), - m_pathFile(), - m_bNoBuffering(false) -{ -} - -TLocalFilesystemFile::~TLocalFilesystemFile() -{ - Close(); -} - -DWORD TLocalFilesystemFile::GetFlagsAndAttributes(bool bNoBuffering) const -{ - return FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffering ? FILE_FLAG_NO_BUFFERING /*| FILE_FLAG_WRITE_THROUGH*/ : 0); -} - -bool TLocalFilesystemFile::OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering) -{ - Close(); - - m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile); - m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL); - if(m_hFile == INVALID_HANDLE_VALUE) - return false; - - m_bNoBuffering = bNoBuffering; - return true; -} - -bool TLocalFilesystemFile::CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering) -{ - Close(); - - m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile); - m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, GetFlagsAndAttributes(bNoBuffering), NULL); - if(m_hFile == INVALID_HANDLE_VALUE) - return false; - - m_bNoBuffering = bNoBuffering; - return true; -} - -bool TLocalFilesystemFile::OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering) -{ - Close(); - - m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile); - m_hFile = CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL); - if(m_hFile == INVALID_HANDLE_VALUE) - return false; - - m_bNoBuffering = bNoBuffering; - return true; -} - -bool TLocalFilesystemFile::SetFilePointer(long long llNewPos, DWORD dwMoveMethod) -{ - if(!IsOpen()) - return false; - - LARGE_INTEGER li = { 0, 0 }; - LARGE_INTEGER liNew = { 0, 0 }; - - li.QuadPart = llNewPos; - - return SetFilePointerEx(m_hFile, li, &liNew, dwMoveMethod) != FALSE; -} - -bool TLocalFilesystemFile::SetEndOfFile() -{ - if(!IsOpen()) - return false; - - return ::SetEndOfFile(m_hFile) != FALSE; -} - -bool TLocalFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer) -{ - if (!IsOpen()) - THROW_CORE_EXCEPTION(eErr_InternalProblem); - - ATLTRACE(_T("Reading %lu bytes\n"), rBuffer.GetRequestedDataSize()); - if(!::ReadFileEx(m_hFile, rBuffer.GetBufferPtr(), rBuffer.GetRequestedDataSize(), &rBuffer, OverlappedReadCompleted)) - { - DWORD dwLastError = GetLastError(); - switch(dwLastError) - { - case ERROR_IO_PENDING: - return true; - - case ERROR_HANDLE_EOF: - { - rBuffer.SetBytesTransferred(0); - rBuffer.SetStatusCode(0); - rBuffer.SetErrorCode(ERROR_SUCCESS); - rBuffer.SetLastPart(true); - - rBuffer.RequeueAsFull(); // basically the same as OverlappedReadCompleted - - return true; - } - } - - return false; - } - return true; -} - -bool TLocalFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer) -{ - if (!IsOpen()) - THROW_CORE_EXCEPTION(eErr_InternalProblem); - - DWORD dwToWrite = boost::numeric_cast(rBuffer.GetRealDataSize()); - - if (m_bNoBuffering && rBuffer.IsLastPart()) - dwToWrite = RoundUp(dwToWrite, MaxSectorSize); - - ATLTRACE(_T("Writing %lu bytes\n"), dwToWrite); - if (!::WriteFileEx(m_hFile, rBuffer.GetBufferPtr(), dwToWrite, &rBuffer, OverlappedWriteCompleted)) - { - if (GetLastError() == ERROR_IO_PENDING) - return true; - return false; - } - - return true; -} - -bool TLocalFilesystemFile::FinalizeFile(TOverlappedDataBuffer& rBuffer) -{ - if (!IsOpen()) - THROW_CORE_EXCEPTION(eErr_InternalProblem); - - if (m_bNoBuffering && rBuffer.IsLastPart()) - { - DWORD dwToWrite = boost::numeric_cast(rBuffer.GetRealDataSize()); - DWORD dwReallyWritten = RoundUp(dwToWrite, MaxSectorSize); - - ATLTRACE(_T("Finalize file - size diff: written: %I64u, required: %I64u\n"), dwReallyWritten, dwToWrite); - - if (dwToWrite != dwReallyWritten) - { - unsigned long long ullNewFileSize = rBuffer.GetFilePosition() + dwToWrite; // new size - - if (!OpenExistingForWriting(m_pathFile, false)) - return false; - - //seek - ATLTRACE(_T("Truncating file to %I64u bytes\n"), ullNewFileSize); - if (!SetFilePointer(ullNewFileSize, FILE_BEGIN)) - return false; - - //set eof - if (!SetEndOfFile()) - return false; - } - } - - return true; -} - -void TLocalFilesystemFile::Close() -{ - if(m_hFile != INVALID_HANDLE_VALUE) - ::CloseHandle(m_hFile); - m_hFile = INVALID_HANDLE_VALUE; -} - -unsigned long long TLocalFilesystemFile::GetFileSize() const -{ - if(!IsOpen()) - return 0; - - BY_HANDLE_FILE_INFORMATION bhfi; - - if(!::GetFileInformationByHandle(m_hFile, &bhfi)) - return 0; - - ULARGE_INTEGER uli; - uli.HighPart = bhfi.nFileSizeHigh; - uli.LowPart = bhfi.nFileSizeLow; - - return uli.QuadPart; -} - END_CHCORE_NAMESPACE Index: src/libchcore/TLocalFilesystem.h =================================================================== diff -u -N -r3c343f2e7aa0d489706136e78f2f56cdd5d417a9 -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision 3c343f2e7aa0d489706136e78f2f56cdd5d417a9) +++ src/libchcore/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -26,50 +26,42 @@ #include "libchcore.h" #include "TPath.h" #include "TBasePathData.h" +#include "TFileInfoFwd.h" +#include "IFilesystem.h" BEGIN_CHCORE_NAMESPACE -class TFileInfo; -typedef boost::shared_ptr TFileInfoPtr; - class TAutoFileHandle; class TLocalFilesystemFind; class TLocalFilesystemFile; class TSimpleDataBuffer; class TFileTime; class TOverlappedDataBuffer; -class LIBCHCORE_API TLocalFilesystem +class LIBCHCORE_API TLocalFilesystem : public IFilesystem { public: - enum EPathsRelation - { - eRelation_Network, // at least one of the paths is network one - eRelation_CDRom, // at least one of the paths relates to cd/dvd drive - eRelation_TwoPhysicalDisks, // paths lies on two separate physical disks - eRelation_SinglePhysicalDisk, // paths lies on the same physical disk - eRelation_Other // other type of relation - }; + TLocalFilesystem(); + virtual ~TLocalFilesystem(); -public: - static bool PathExist(TSmartPath strPath); // check for file or folder existence + virtual bool PathExist(const TSmartPath& strPath) override; // check for file or folder existence - static bool SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime); - static bool SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes); + virtual bool SetFileDirectoryTime(const TSmartPath& pathFileDir, const TFileTime& ftCreationTime, const TFileTime& ftLastAccessTime, const TFileTime& ftLastWriteTime) override; + virtual bool SetAttributes(const TSmartPath& pathFileDir, DWORD dwAttributes) override; - static bool CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath); - static bool RemoveDirectory(const TSmartPath& pathFile); - static bool DeleteFile(const TSmartPath& pathFile); + virtual bool CreateDirectory(const TSmartPath& pathDirectory, bool bCreateFullPath) override; + virtual bool RemoveDirectory(const TSmartPath& pathFile) override; + virtual bool DeleteFile(const TSmartPath& pathFile) override; - static bool GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()); - static bool FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination); + virtual bool GetFileInfo(const TSmartPath& pathFile, TFileInfoPtr& rFileInfo, const TBasePathDataPtr& spBasePathData = TBasePathDataPtr()) override; + virtual bool FastMove(const TSmartPath& pathSource, const TSmartPath& pathDestination) override; - static TLocalFilesystemFind CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask); - static TLocalFilesystemFile CreateFileObject(); + virtual IFilesystemFindPtr CreateFinderObject(const TSmartPath& pathDir, const TSmartPath& pathMask) override; + virtual IFilesystemFilePtr CreateFileObject() override; - EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond); + virtual EPathsRelation GetPathsRelation(const TSmartPath& pathFirst, const TSmartPath& pathSecond) override; - bool GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree); + virtual bool GetDynamicFreeSpace(const TSmartPath& path, unsigned long long& rullFree) override; private: static TSmartPath PrependPathExtensionIfNeeded(const TSmartPath& pathInput); @@ -87,61 +79,6 @@ friend class TLocalFilesystemFile; }; -class LIBCHCORE_API TLocalFilesystemFind -{ -public: - ~TLocalFilesystemFind(); - - bool FindNext(TFileInfoPtr& rspFileInfo); - void Close(); - -private: - TLocalFilesystemFind(const TSmartPath& pathDir, const TSmartPath& pathMask); - -private: - TSmartPath m_pathDir; - TSmartPath m_pathMask; - HANDLE m_hFind; - - friend class TLocalFilesystem; -}; - -class LIBCHCORE_API TLocalFilesystemFile -{ -public: - static const unsigned int MaxSectorSize = 4096; - -public: - ~TLocalFilesystemFile(); - - bool OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering); - bool CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering); - bool OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering); - - bool SetFilePointer(long long llNewPos, DWORD dwMoveMethod); - bool SetEndOfFile(); - - bool ReadFile(TOverlappedDataBuffer& rBuffer); - bool WriteFile(TOverlappedDataBuffer& rBuffer); - bool FinalizeFile(TOverlappedDataBuffer& rBuffer); - - bool IsOpen() const { return m_hFile != INVALID_HANDLE_VALUE; } - unsigned long long GetFileSize() const; - - void Close(); - -private: - TLocalFilesystemFile(); - DWORD GetFlagsAndAttributes(bool bNoBuffering) const; - -private: - TSmartPath m_pathFile; - HANDLE m_hFile; - bool m_bNoBuffering; - - friend class TLocalFilesystem; -}; - END_CHCORE_NAMESPACE #endif Index: src/libchcore/TLocalFilesystemFile.cpp =================================================================== diff -u -N --- src/libchcore/TLocalFilesystemFile.cpp (revision 0) +++ src/libchcore/TLocalFilesystemFile.cpp (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,221 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TLocalFilesystemFile.h" +#include "TBufferSizes.h" +#include "TCoreException.h" +#include "ErrorCodes.h" +#include +#include +#include "RoundingFunctions.h" +#include "TLocalFilesystem.h" + +BEGIN_CHCORE_NAMESPACE + +// compile-time check - ensure the buffer granularity used for transfers are bigger than expected sector size +static_assert(TLocalFilesystemFile::MaxSectorSize <= TBufferSizes::BufferGranularity, "Buffer granularity must be equal to or bigger than the max sector size"); + +TLocalFilesystemFile::TLocalFilesystemFile() : + m_hFile(INVALID_HANDLE_VALUE), + m_pathFile(), + m_bNoBuffering(false) +{ +} + +TLocalFilesystemFile::~TLocalFilesystemFile() +{ + Close(); +} + +DWORD TLocalFilesystemFile::GetFlagsAndAttributes(bool bNoBuffering) const +{ + return FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffering ? FILE_FLAG_NO_BUFFERING /*| FILE_FLAG_WRITE_THROUGH*/ : 0); +} + +bool TLocalFilesystemFile::OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering) +{ + Close(); + + m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile); + m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL); + if (m_hFile == INVALID_HANDLE_VALUE) + return false; + + m_bNoBuffering = bNoBuffering; + return true; +} + +bool TLocalFilesystemFile::CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering) +{ + Close(); + + m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile); + m_hFile = ::CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, CREATE_NEW, GetFlagsAndAttributes(bNoBuffering), NULL); + if (m_hFile == INVALID_HANDLE_VALUE) + return false; + + m_bNoBuffering = bNoBuffering; + return true; +} + +bool TLocalFilesystemFile::OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering) +{ + Close(); + + m_pathFile = TLocalFilesystem::PrependPathExtensionIfNeeded(pathFile); + m_hFile = CreateFile(m_pathFile.ToString(), GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, GetFlagsAndAttributes(bNoBuffering), NULL); + if (m_hFile == INVALID_HANDLE_VALUE) + return false; + + m_bNoBuffering = bNoBuffering; + return true; +} + +bool TLocalFilesystemFile::SetFilePointer(long long llNewPos, DWORD dwMoveMethod) +{ + if (!IsOpen()) + return false; + + LARGE_INTEGER li = { 0, 0 }; + LARGE_INTEGER liNew = { 0, 0 }; + + li.QuadPart = llNewPos; + + return SetFilePointerEx(m_hFile, li, &liNew, dwMoveMethod) != FALSE; +} + +bool TLocalFilesystemFile::SetEndOfFile() +{ + if (!IsOpen()) + return false; + + return ::SetEndOfFile(m_hFile) != FALSE; +} + +bool TLocalFilesystemFile::ReadFile(TOverlappedDataBuffer& rBuffer) +{ + if (!IsOpen()) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + + ATLTRACE(_T("Reading %lu bytes\n"), rBuffer.GetRequestedDataSize()); + if (!::ReadFileEx(m_hFile, rBuffer.GetBufferPtr(), rBuffer.GetRequestedDataSize(), &rBuffer, OverlappedReadCompleted)) + { + DWORD dwLastError = GetLastError(); + switch (dwLastError) + { + case ERROR_IO_PENDING: + return true; + + case ERROR_HANDLE_EOF: + { + rBuffer.SetBytesTransferred(0); + rBuffer.SetStatusCode(0); + rBuffer.SetErrorCode(ERROR_SUCCESS); + rBuffer.SetLastPart(true); + + rBuffer.RequeueAsFull(); // basically the same as OverlappedReadCompleted + + return true; + } + } + + return false; + } + return true; +} + +bool TLocalFilesystemFile::WriteFile(TOverlappedDataBuffer& rBuffer) +{ + if (!IsOpen()) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + + DWORD dwToWrite = boost::numeric_cast(rBuffer.GetRealDataSize()); + + if (m_bNoBuffering && rBuffer.IsLastPart()) + dwToWrite = RoundUp(dwToWrite, MaxSectorSize); + + ATLTRACE(_T("Writing %lu bytes\n"), dwToWrite); + if (!::WriteFileEx(m_hFile, rBuffer.GetBufferPtr(), dwToWrite, &rBuffer, OverlappedWriteCompleted)) + { + if (GetLastError() == ERROR_IO_PENDING) + return true; + return false; + } + + return true; +} + +bool TLocalFilesystemFile::FinalizeFile(TOverlappedDataBuffer& rBuffer) +{ + if (!IsOpen()) + THROW_CORE_EXCEPTION(eErr_InternalProblem); + + if (m_bNoBuffering && rBuffer.IsLastPart()) + { + DWORD dwToWrite = boost::numeric_cast(rBuffer.GetRealDataSize()); + DWORD dwReallyWritten = RoundUp(dwToWrite, MaxSectorSize); + + ATLTRACE(_T("Finalize file - size diff: written: %I64u, required: %I64u\n"), dwReallyWritten, dwToWrite); + + if (dwToWrite != dwReallyWritten) + { + unsigned long long ullNewFileSize = rBuffer.GetFilePosition() + dwToWrite; // new size + + if (!OpenExistingForWriting(m_pathFile, false)) + return false; + + //seek + ATLTRACE(_T("Truncating file to %I64u bytes\n"), ullNewFileSize); + if (!SetFilePointer(ullNewFileSize, FILE_BEGIN)) + return false; + + //set eof + if (!SetEndOfFile()) + return false; + } + } + + return true; +} + +void TLocalFilesystemFile::Close() +{ + if (m_hFile != INVALID_HANDLE_VALUE) + ::CloseHandle(m_hFile); + m_hFile = INVALID_HANDLE_VALUE; +} + +unsigned long long TLocalFilesystemFile::GetFileSize() const +{ + if (!IsOpen()) + return 0; + + BY_HANDLE_FILE_INFORMATION bhfi; + + if (!::GetFileInformationByHandle(m_hFile, &bhfi)) + return 0; + + ULARGE_INTEGER uli; + uli.HighPart = bhfi.nFileSizeHigh; + uli.LowPart = bhfi.nFileSizeLow; + + return uli.QuadPart; +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TLocalFilesystemFile.h =================================================================== diff -u -N --- src/libchcore/TLocalFilesystemFile.h (revision 0) +++ src/libchcore/TLocalFilesystemFile.h (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,64 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TLOCALFILESYSTEMFILE_H__ +#define __TLOCALFILESYSTEMFILE_H__ + +#include "libchcore.h" +#include "TPath.h" +#include "TOverlappedDataBuffer.h" +#include "IFilesystemFile.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TLocalFilesystemFile : public IFilesystemFile +{ +public: + virtual ~TLocalFilesystemFile(); + + virtual bool OpenExistingForReading(const TSmartPath& pathFile, bool bNoBuffering) override; + virtual bool CreateNewForWriting(const TSmartPath& pathFile, bool bNoBuffering) override; + virtual bool OpenExistingForWriting(const TSmartPath& pathFile, bool bNoBuffering) override; + + virtual bool SetFilePointer(long long llNewPos, DWORD dwMoveMethod) override; + virtual bool SetEndOfFile() override; + + virtual bool ReadFile(TOverlappedDataBuffer& rBuffer) override; + virtual bool WriteFile(TOverlappedDataBuffer& rBuffer) override; + virtual bool FinalizeFile(TOverlappedDataBuffer& rBuffer) override; + + virtual bool IsOpen() const override { return m_hFile != INVALID_HANDLE_VALUE; } + virtual unsigned long long GetFileSize() const override; + + virtual void Close() override; + +private: + TLocalFilesystemFile(); + DWORD GetFlagsAndAttributes(bool bNoBuffering) const; + +private: + TSmartPath m_pathFile; + HANDLE m_hFile; + bool m_bNoBuffering; + + friend class TLocalFilesystem; +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TLocalFilesystemFind.cpp =================================================================== diff -u -N --- src/libchcore/TLocalFilesystemFind.cpp (revision 0) +++ src/libchcore/TLocalFilesystemFind.cpp (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,85 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#include "stdafx.h" +#include "TLocalFilesystemFind.h" +#include "TLocalFilesystem.h" +#include "TFileInfo.h" + +BEGIN_CHCORE_NAMESPACE + +TLocalFilesystemFind::TLocalFilesystemFind(const TSmartPath& pathDir, const TSmartPath& pathMask) : + m_pathDir(pathDir), + m_pathMask(pathMask), + m_hFind(INVALID_HANDLE_VALUE) +{ +} + +TLocalFilesystemFind::~TLocalFilesystemFind() +{ + Close(); +} + +bool TLocalFilesystemFind::FindNext(TFileInfoPtr& rspFileInfo) +{ + WIN32_FIND_DATA wfd; + TSmartPath pathCurrent = m_pathDir + m_pathMask; + + // Iterate through dirs & files + bool bContinue = true; + if (m_hFind != INVALID_HANDLE_VALUE) + bContinue = (FindNextFile(m_hFind, &wfd) != FALSE); + else + { + m_hFind = FindFirstFile(TLocalFilesystem::PrependPathExtensionIfNeeded(pathCurrent).ToString(), &wfd); // in this case we always continue + bContinue = (m_hFind != INVALID_HANDLE_VALUE); + } + if (bContinue) + { + do + { + if (!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + rspFileInfo->Init(m_pathDir + PathFromString(wfd.cFileName), wfd.dwFileAttributes, (((ULONGLONG)wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime, + wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0); + return true; + } + else if (wfd.cFileName[0] != _T('.') || (wfd.cFileName[1] != _T('\0') && (wfd.cFileName[1] != _T('.') || wfd.cFileName[2] != _T('\0')))) + { + // Add directory itself + rspFileInfo->Init(m_pathDir + PathFromString(wfd.cFileName), + wfd.dwFileAttributes, (((ULONGLONG)wfd.nFileSizeHigh) << 32) + wfd.nFileSizeLow, wfd.ftCreationTime, + wfd.ftLastAccessTime, wfd.ftLastWriteTime, 0); + return true; + } + } while (m_hFind != INVALID_HANDLE_VALUE && ::FindNextFile(m_hFind, &wfd)); // checking m_hFind in case other thread changed it (it shouldn't happen though) + + Close(); + } + + return false; +} + +void TLocalFilesystemFind::Close() +{ + if (m_hFind != INVALID_HANDLE_VALUE) + FindClose(m_hFind); + m_hFind = INVALID_HANDLE_VALUE; +} + +END_CHCORE_NAMESPACE Index: src/libchcore/TLocalFilesystemFind.h =================================================================== diff -u -N --- src/libchcore/TLocalFilesystemFind.h (revision 0) +++ src/libchcore/TLocalFilesystemFind.h (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -0,0 +1,50 @@ +// ============================================================================ +// Copyright (C) 2001-2015 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// ============================================================================ +#ifndef __TLOCALFILESYSTEMFIND_H__ +#define __TLOCALFILESYSTEMFIND_H__ + +#include "libchcore.h" +#include "TFileInfoFwd.h" +#include "TPath.h" +#include "IFilesystemFind.h" + +BEGIN_CHCORE_NAMESPACE + +class LIBCHCORE_API TLocalFilesystemFind : public IFilesystemFind +{ +public: + virtual ~TLocalFilesystemFind(); + + virtual bool FindNext(TFileInfoPtr& rspFileInfo) override; + virtual void Close() override; + +private: + TLocalFilesystemFind(const TSmartPath& pathDir, const TSmartPath& pathMask); + +private: + TSmartPath m_pathDir; + TSmartPath m_pathMask; + HANDLE m_hFind; + + friend class TLocalFilesystem; +}; + +END_CHCORE_NAMESPACE + +#endif Index: src/libchcore/TSubTaskBase.cpp =================================================================== diff -u -N -r2fe97a93f21771d75901d4b6559057d1ea055104 -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskBase.cpp (.../TSubTaskBase.cpp) (revision 2fe97a93f21771d75901d4b6559057d1ea055104) +++ src/libchcore/TSubTaskBase.cpp (.../TSubTaskBase.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -37,7 +37,7 @@ // TSubTaskBase TSubTaskBase::TSubTaskBase(TSubTaskContext& rContext) : -m_rContext(rContext) + m_rContext(rContext) { } @@ -47,6 +47,8 @@ TSmartPath TSubTaskBase::CalculateDestinationPath(const TFileInfoPtr& spFileInfo, TSmartPath pathDst, int iFlags) { + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + if(!spFileInfo) THROW_CORE_EXCEPTION(eErr_InvalidArgument); @@ -57,7 +59,7 @@ TSmartPath pathCombined = pathDst + spFileInfo->GetFullFilePath().GetFileDir(); // force create directory - TLocalFilesystem::CreateDirectory(pathCombined, true); + spFilesystem->CreateDirectory(pathCombined, true); return pathCombined + spFileInfo->GetFullFilePath().GetFileName(); } @@ -91,6 +93,7 @@ TSmartPath TSubTaskBase::FindFreeSubstituteName(TSmartPath pathSrcPath, TSmartPath pathDstPath) const { const TConfig& rConfig = GetContext().GetConfig(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); // get the name from src path pathSrcPath.StripSeparatorAtEnd(); @@ -105,7 +108,7 @@ // when adding to strDstPath check if the path already exists - if so - try again int iCounter = 1; TString strFmt = GetTaskPropValue(rConfig); - while(TLocalFilesystem::PathExist(pathDstPath + pathCheckPath)) + while(spFilesystem->PathExist(pathDstPath + pathCheckPath)) { strCheckPath = strFmt; strCheckPath.Replace(_t("%name"), pathFilename.ToString()); Index: src/libchcore/TSubTaskContext.cpp =================================================================== diff -u -N -r11b0a299be97bc3afaa633d6522c17b214ba3b79 -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskContext.cpp (.../TSubTaskContext.cpp) (revision 11b0a299be97bc3afaa633d6522c17b214ba3b79) +++ src/libchcore/TSubTaskContext.cpp (.../TSubTaskContext.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -31,17 +31,19 @@ TSubTaskContext::TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths, const TFileFiltersArray& rFilters, TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, - TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal) : + TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem) : m_rConfig(rConfig), m_eOperationType(eOperation_None), m_spBasePaths(spBasePaths), m_pathDestination(), m_rCfgTracker(rCfgTracker), m_rLog(rLog), m_rThreadController(rThreadController), - m_rfsLocal(rfsLocal), + m_spFilesystem(spFilesystem), m_rFilters(rFilters) { + if (!spFilesystem) + THROW_CORE_EXCEPTION(eErr_InvalidArgument); } TSubTaskContext::~TSubTaskContext() @@ -123,14 +125,14 @@ return m_rThreadController; } -TLocalFilesystem& TSubTaskContext::GetLocalFilesystem() +IFilesystemPtr TSubTaskContext::GetLocalFilesystem() { - return m_rfsLocal; + return m_spFilesystem; } -const TLocalFilesystem& TSubTaskContext::GetLocalFilesystem() const +const IFilesystemPtr TSubTaskContext::GetLocalFilesystem() const { - return m_rfsLocal; + return m_spFilesystem; } const TFileFiltersArray& TSubTaskContext::GetFilters() const Index: src/libchcore/TSubTaskContext.h =================================================================== diff -u -N -r11b0a299be97bc3afaa633d6522c17b214ba3b79 -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskContext.h (.../TSubTaskContext.h) (revision 11b0a299be97bc3afaa633d6522c17b214ba3b79) +++ src/libchcore/TSubTaskContext.h (.../TSubTaskContext.h) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -29,6 +29,7 @@ #include "IFeedbackHandler.h" #include "TBasePathData.h" #include "TFileInfoArray.h" +#include "IFilesystem.h" namespace icpf { @@ -52,7 +53,7 @@ TSubTaskContext(TConfig& rConfig, const TBasePathDataContainerPtr& spBasePaths, const TFileFiltersArray& rFilters, TTaskConfigTracker& rCfgTracker, icpf::log_file& rLog, - TWorkerThreadController& rThreadController, TLocalFilesystem& rfsLocal); + TWorkerThreadController& rThreadController, const IFilesystemPtr& spFilesystem); ~TSubTaskContext(); TConfig& GetConfig(); @@ -79,8 +80,8 @@ TWorkerThreadController& GetThreadController(); const TWorkerThreadController& GetThreadController() const; - TLocalFilesystem& GetLocalFilesystem(); - const TLocalFilesystem& GetLocalFilesystem() const; + IFilesystemPtr GetLocalFilesystem(); + const IFilesystemPtr GetLocalFilesystem() const; private: TSubTaskContext(const TSubTaskContext& rSrc); @@ -108,7 +109,10 @@ TTaskConfigTracker& m_rCfgTracker; // local filesystem access functions - TLocalFilesystem& m_rfsLocal; +#pragma warning(push) +#pragma warning(disable: 4251) + IFilesystemPtr m_spFilesystem; +#pragma warning(pop) // additional data icpf::log_file& m_rLog; Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -N -r7972b0944e0a947144fbdb93262f7d73ac528dc7 -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 7972b0944e0a947144fbdb93262f7d73ac528dc7) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -84,6 +84,7 @@ TWorkerThreadController& rThreadController = GetContext().GetThreadController(); const TConfig& rConfig = GetContext().GetConfig(); TSmartPath pathDestination = GetContext().GetDestinationPath(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); // log rLog.logi(_T("Processing files/folders (ProcessFiles)")); @@ -194,19 +195,19 @@ if(bMove && spFileInfo->IsProcessed() && !GetTaskPropValue(rConfig)) { if(!GetTaskPropValue(rConfig)) - TLocalFilesystem::SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); - TLocalFilesystem::DeleteFile(spFileInfo->GetFullFilePath()); // there will be another try later, so we don't check + spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); + spFilesystem->DeleteFile(spFileInfo->GetFullFilePath()); // there will be another try later, so we don't check // if succeeded } } // set a time if(GetTaskPropValue(rConfig)) - TLocalFilesystem::SetFileDirectoryTime(ccp.pathDstFile, spFileInfo->GetCreationTime(), spFileInfo->GetLastAccessTime(), spFileInfo->GetLastWriteTime()); // no error checking (but most probably it should be checked) + spFilesystem->SetFileDirectoryTime(ccp.pathDstFile, spFileInfo->GetCreationTime(), spFileInfo->GetLastAccessTime(), spFileInfo->GetLastWriteTime()); // no error checking (but most probably it should be checked) // attributes if(GetTaskPropValue(rConfig)) - TLocalFilesystem::SetAttributes(ccp.pathDstFile, spFileInfo->GetAttributes()); // as above + spFilesystem->SetAttributes(ccp.pathDstFile, spFileInfo->GetAttributes()); // as above } m_tSubTaskStats.SetCurrentIndex(fcIndex); @@ -243,7 +244,7 @@ TSmartPath pathSource = spFileInfo->GetFullFilePath(); TSmartPath pathDestination = GetContext().GetDestinationPath(); - TLocalFilesystem::EPathsRelation eRelation = GetContext().GetLocalFilesystem().GetPathsRelation(pathSource, pathDestination); + TLocalFilesystem::EPathsRelation eRelation = GetContext().GetLocalFilesystem()->GetPathsRelation(pathSource, pathDestination); switch(eRelation) { case TLocalFilesystem::eRelation_Network: @@ -269,10 +270,11 @@ TWorkerThreadController& rThreadController = GetContext().GetThreadController(); icpf::log_file& rLog = GetContext().GetLog(); const TConfig& rConfig = GetContext().GetConfig(); - - TLocalFilesystemFile fileSrc = TLocalFilesystem::CreateFileObject(); - TLocalFilesystemFile fileDst = TLocalFilesystem::CreateFileObject(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + IFilesystemFilePtr fileSrc = spFilesystem->CreateFileObject(); + IFilesystemFilePtr fileDst = spFilesystem->CreateFileObject(); + TString strFormat; TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; @@ -302,7 +304,7 @@ TBufferSizes::EBufferType eBufferIndex = GetBufferIndex(pData->tBufferSizes, pData->spSrcFile); m_tSubTaskStats.SetCurrentBufferIndex(eBufferIndex); - DWORD dwToRead = RoundUp(pData->tBufferSizes.GetSizeByType(eBufferIndex), TLocalFilesystemFile::MaxSectorSize); + DWORD dwToRead = RoundUp(pData->tBufferSizes.GetSizeByType(eBufferIndex), IFilesystemFile::MaxSectorSize); // read data from file to buffer enum { eKillThread = 0, eWriteFinished, eWritePossible, eReadPossible, eHandleCount }; @@ -514,17 +516,18 @@ return TSubTaskBase::eSubResult_Continue; } -TSubTaskCopyMove::ESubOperationResult TSubTaskCopyMove::OpenSrcAndDstFilesFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData, TLocalFilesystemFile &fileSrc, TLocalFilesystemFile &fileDst, bool bNoBuffer, bool& bSkip) +TSubTaskCopyMove::ESubOperationResult TSubTaskCopyMove::OpenSrcAndDstFilesFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData, + const IFilesystemFilePtr& spFileSrc, const IFilesystemFilePtr& spFileDst, bool bNoBuffer, bool& bSkip) { const TConfig& rConfig = GetContext().GetConfig(); bSkip = false; // first open the source file and handle any failures - TSubTaskCopyMove::ESubOperationResult eResult = OpenSourceFileFB(spFeedbackHandler, fileSrc, pData->spSrcFile->GetFullFilePath(), bNoBuffer); + TSubTaskCopyMove::ESubOperationResult eResult = OpenSourceFileFB(spFeedbackHandler, spFileSrc, pData->spSrcFile->GetFullFilePath(), bNoBuffer); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; - else if(!fileSrc.IsOpen()) + else if(!spFileSrc->IsOpen()) { // invalid handle = operation skipped by user unsigned long long ullDiff = pData->spSrcFile->GetLength64() - m_tSubTaskStats.GetCurrentItemProcessedSize(); @@ -542,7 +545,7 @@ // but it would require frequent total size updates and thus - serializations). // NOTE2: the by-chunk corrections of stats are still applied when copying to ensure even further size // matching; this update however still allows for better serialization management. - unsigned long long ullNewSize = fileSrc.GetFileSize(); + unsigned long long ullNewSize = spFileSrc->GetFileSize(); unsigned long long ullOldSize = pData->spSrcFile->GetLength64(); if(ullNewSize != ullOldSize) { @@ -575,10 +578,10 @@ { // open destination file for case, when we start operation on this file (i.e. it is not resume of the // old operation) - eResult = OpenDestinationFileFB(spFeedbackHandler, fileDst, pData->pathDstFile, bNoBuffer, pData->spSrcFile, ullSeekTo, bDstFileFreshlyCreated); + eResult = OpenDestinationFileFB(spFeedbackHandler, spFileDst, pData->pathDstFile, bNoBuffer, pData->spSrcFile, ullSeekTo, bDstFileFreshlyCreated); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; - else if(!fileDst.IsOpen()) + else if(!spFileDst->IsOpen()) { unsigned long long ullDiff = pData->spSrcFile->GetLength64() - ullProcessedSize; @@ -593,10 +596,10 @@ else { // we are resuming previous operation - eResult = OpenExistingDestinationFileFB(spFeedbackHandler, fileDst, pData->pathDstFile, bNoBuffer); + eResult = OpenExistingDestinationFileFB(spFeedbackHandler, spFileDst, pData->pathDstFile, bNoBuffer); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; - else if(!fileDst.IsOpen()) + else if(!spFileDst->IsOpen()) { unsigned long long ullDiff = pData->spSrcFile->GetLength64() - ullProcessedSize; @@ -624,9 +627,9 @@ if(ullSeekTo != 0) // src and dst files exists, requested resume at the specified index { // try to move file pointers to the end - ULONGLONG ullMove = (bNoBuffer ? RoundDown(ullSeekTo, TLocalFilesystemFile::MaxSectorSize) : ullSeekTo); + ULONGLONG ullMove = (bNoBuffer ? RoundDown(ullSeekTo, IFilesystemFile::MaxSectorSize) : ullSeekTo); - eResult = SetFilePointerFB(spFeedbackHandler, fileSrc, ullMove, pData->spSrcFile->GetFullFilePath(), bSkip); + eResult = SetFilePointerFB(spFeedbackHandler, spFileSrc, ullMove, pData->spSrcFile->GetFullFilePath(), bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -640,7 +643,7 @@ return TSubTaskBase::eSubResult_Continue; } - eResult = SetFilePointerFB(spFeedbackHandler, fileDst, ullMove, pData->pathDstFile, bSkip); + eResult = SetFilePointerFB(spFeedbackHandler, spFileDst, ullMove, pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -674,7 +677,7 @@ if(!bDstFileFreshlyCreated) { // if destination file was opened (as opposed to newly created) - eResult = SetEndOfFileFB(spFeedbackHandler, fileDst, pData->pathDstFile, bSkip); + eResult = SetEndOfFileFB(spFeedbackHandler, spFileDst, pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -722,7 +725,8 @@ return false; // buffer did not need adjusting } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& fileSrc, const TSmartPath& spPathToOpen, bool bNoBuffering) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFileSrc, + const TSmartPath& spPathToOpen, bool bNoBuffering) { icpf::log_file& rLog = GetContext().GetLog(); @@ -732,13 +736,13 @@ bool bRetry = false; - fileSrc.Close(); + spFileSrc->Close(); do { bRetry = false; - if(!fileSrc.OpenExistingForReading(spPathToOpen, bNoBuffering)) + if(!spFileSrc->OpenExistingForReading(spPathToOpen, bNoBuffering)) { DWORD dwLastError = GetLastError(); @@ -785,32 +789,34 @@ return TSubTaskBase::eSubResult_Continue; } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& fileDst, const TSmartPath& pathDstFile, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo, unsigned long long& ullSeekTo, bool& bFreshlyCreated) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFileDst, + const TSmartPath& pathDstFile, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo, unsigned long long& ullSeekTo, bool& bFreshlyCreated) { icpf::log_file& rLog = GetContext().GetLog(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); bool bRetry = false; ullSeekTo = 0; bFreshlyCreated = true; - fileDst.Close(); + spFileDst->Close(); do { bRetry = false; - if(!fileDst.CreateNewForWriting(pathDstFile, bNoBuffering)) + if(!spFileDst->CreateNewForWriting(pathDstFile, bNoBuffering)) { DWORD dwLastError = GetLastError(); if(dwLastError == ERROR_FILE_EXISTS) { bFreshlyCreated = false; // pass it to the specialized method - TSubTaskBase::ESubOperationResult eResult = OpenExistingDestinationFileFB(spFeedbackHandler, fileDst, pathDstFile, bNoBuffering); + TSubTaskBase::ESubOperationResult eResult = OpenExistingDestinationFileFB(spFeedbackHandler, spFileDst, pathDstFile, bNoBuffering); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; - else if(!fileDst.IsOpen()) + else if(!spFileDst->IsOpen()) return TSubTaskBase::eSubResult_Continue; // read info about the existing destination file, @@ -819,7 +825,7 @@ // reading parameters using opened handle; need to be tested in the future TFileInfoPtr spDstFileInfo(boost::make_shared()); - if(!TLocalFilesystem::GetFileInfo(pathDstFile, spDstFileInfo)) + if(!spFilesystem->GetFileInfo(pathDstFile, spDstFileInfo)) THROW_CORE_EXCEPTION_WIN32(eErr_CannotGetFileInfo, GetLastError()); // src and dst files are the same @@ -900,19 +906,20 @@ return TSubTaskBase::eSubResult_Continue; } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& fileDst, const TSmartPath& pathDstFile, bool bNoBuffering) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFileDst, + const TSmartPath& pathDstFile, bool bNoBuffering) { icpf::log_file& rLog = GetContext().GetLog(); bool bRetry = false; - fileDst.Close(); + spFileDst->Close(); do { bRetry = false; - if(!fileDst.OpenExistingForWriting(pathDstFile, bNoBuffering)) + if(!spFileDst->OpenExistingForWriting(pathDstFile, bNoBuffering)) { DWORD dwLastError = GetLastError(); @@ -959,7 +966,8 @@ return TSubTaskBase::eSubResult_Continue; } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::SetFilePointerFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, long long llDistance, const TSmartPath& pathFile, bool& bSkip) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::SetFilePointerFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + long long llDistance, const TSmartPath& pathFile, bool& bSkip) { icpf::log_file& rLog = GetContext().GetLog(); @@ -969,7 +977,7 @@ { bRetry = false; - if(!file.SetFilePointer(llDistance, FILE_BEGIN)) + if(!spFile->SetFilePointer(llDistance, FILE_BEGIN)) { DWORD dwLastError = GetLastError(); @@ -1008,7 +1016,8 @@ return TSubTaskBase::eSubResult_Continue; } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::SetEndOfFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, const TSmartPath& pathFile, bool& bSkip) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::SetEndOfFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + const TSmartPath& pathFile, bool& bSkip) { icpf::log_file& rLog = GetContext().GetLog(); @@ -1017,7 +1026,7 @@ bool bRetry = false; do { - if(!file.SetEndOfFile()) + if(!spFile->SetEndOfFile()) { // log DWORD dwLastError = GetLastError(); @@ -1054,7 +1063,8 @@ return TSubTaskBase::eSubResult_Continue; } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::ReadFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::ReadFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) { icpf::log_file& rLog = GetContext().GetLog(); @@ -1064,7 +1074,7 @@ { bRetry = false; - if(!file.ReadFile(rBuffer)) + if(!spFile->ReadFile(rBuffer)) { TString strFormat = _T("Error %errno while requesting read of %count bytes from source file %path (CustomCopyFileFB)"); strFormat.Replace(_t("%errno"), boost::lexical_cast(GetLastError()).c_str()); @@ -1139,7 +1149,8 @@ } } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::WriteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::WriteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) { icpf::log_file& rLog = GetContext().GetLog(); @@ -1150,7 +1161,7 @@ { bRetry = false; - if(!file.WriteFile(rBuffer)) + if(!spFile->WriteFile(rBuffer)) { // log DWORD dwLastError = GetLastError(); @@ -1228,7 +1239,8 @@ } } -TSubTaskBase::ESubOperationResult TSubTaskCopyMove::FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) { icpf::log_file& rLog = GetContext().GetLog(); @@ -1239,7 +1251,7 @@ { bRetry = false; - if (!file.FinalizeFile(rBuffer)) + if (!spFile->FinalizeFile(rBuffer)) { // log DWORD dwLastError = GetLastError(); @@ -1280,10 +1292,11 @@ TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CreateDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathDirectory) { icpf::log_file& rLog = GetContext().GetLog(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); bool bRetry = true; DWORD dwLastError = ERROR_SUCCESS; - while(bRetry && !TLocalFilesystem::CreateDirectory(pathDirectory, false) && (dwLastError = GetLastError()) != ERROR_ALREADY_EXISTS) + while(bRetry && !spFilesystem->CreateDirectory(pathDirectory, false) && (dwLastError = GetLastError()) != ERROR_ALREADY_EXISTS) { // log TString strFormat; @@ -1321,7 +1334,7 @@ TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CheckForFreeSpaceFB(const IFeedbackHandlerPtr& spFeedbackHandler) { icpf::log_file& rLog = GetContext().GetLog(); - TLocalFilesystem& rLocalFilesystem = GetContext().GetLocalFilesystem(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TBasePathDataContainerPtr spSrcPaths = GetContext().GetBasePaths(); TSmartPath pathDestination = GetContext().GetDestinationPath(); @@ -1338,7 +1351,7 @@ ullNeededSize = rFilesCache.CalculateTotalSize() - rFilesCache.CalculatePartialSize(m_tSubTaskStats.GetCurrentIndex()); // it'd be nice to round up to take cluster size into consideration // get free space - bool bResult = rLocalFilesystem.GetDynamicFreeSpace(pathDestination, ullAvailableSize); + bool bResult = spFilesystem->GetDynamicFreeSpace(pathDestination, ullAvailableSize); if(bResult && ullNeededSize > ullAvailableSize) { TString strFormat = _T("Not enough free space on disk - needed %needsize bytes for data, available: %availablesize bytes."); Index: src/libchcore/TSubTaskCopyMove.h =================================================================== diff -u -N -rcdc76e1a95383dff63a5254aeb8d37035028512c -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision cdc76e1a95383dff63a5254aeb8d37035028512c) +++ src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -27,6 +27,7 @@ #include "TSubTaskBase.h" #include "CommonDataTypes.h" #include "TBufferSizes.h" +#include "IFilesystemFile.h" BEGIN_CHCORE_NAMESPACE @@ -63,22 +64,34 @@ ESubOperationResult CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData); - ESubOperationResult OpenSrcAndDstFilesFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData, TLocalFilesystemFile &fileSrc, TLocalFilesystemFile &fileDst, bool bNoBuffer, bool& bSkip); + ESubOperationResult OpenSrcAndDstFilesFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData, + const IFilesystemFilePtr& spFileSrc, const IFilesystemFilePtr& spFileDst, bool bNoBuffer, bool& bSkip); - ESubOperationResult OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& fileSrc, const TSmartPath& spPathToOpen, bool bNoBuffering); - ESubOperationResult OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& fileDst, const TSmartPath& pathDstFile, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo, unsigned long long& ullSeekTo, bool& bFreshlyCreated); - ESubOperationResult OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& fileDst, const TSmartPath& pathDstFilePath, bool bNoBuffering); + ESubOperationResult OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileSrc, + const TSmartPath& spPathToOpen, bool bNoBuffering); + ESubOperationResult OpenDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, + const TSmartPath& pathDstFile, bool bNoBuffering, const TFileInfoPtr& spSrcFileInfo, + unsigned long long& ullSeekTo, bool& bFreshlyCreated); + ESubOperationResult OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, + const TSmartPath& pathDstFilePath, bool bNoBuffering); - ESubOperationResult SetFilePointerFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, long long llDistance, const TSmartPath& pathFile, bool& bSkip); - ESubOperationResult SetEndOfFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, const TSmartPath& pathFile, bool& bSkip); + ESubOperationResult SetFilePointerFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file, + long long llDistance, const TSmartPath& pathFile, bool& bSkip); + ESubOperationResult SetEndOfFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file, + const TSmartPath& pathFile, bool& bSkip); - ESubOperationResult ReadFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); - ESubOperationResult HandleReadError(const IFeedbackHandlerPtr& spFeedbackHandler, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); + ESubOperationResult ReadFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file, + TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); + ESubOperationResult HandleReadError(const IFeedbackHandlerPtr& spFeedbackHandler, TOverlappedDataBuffer& rBuffer, + const TSmartPath& pathFile, bool& bSkip); - ESubOperationResult WriteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); - ESubOperationResult HandleWriteError(const IFeedbackHandlerPtr& spFeedbackHandler, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); + ESubOperationResult WriteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file, + TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); + ESubOperationResult HandleWriteError(const IFeedbackHandlerPtr& spFeedbackHandler, TOverlappedDataBuffer& rBuffer, + const TSmartPath& pathFile, bool& bSkip); - ESubOperationResult FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, TLocalFilesystemFile& file, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); + ESubOperationResult FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& file, + TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); ESubOperationResult CreateDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TSmartPath& pathDirectory); Index: src/libchcore/TSubTaskDelete.cpp =================================================================== diff -u -N -rcdc76e1a95383dff63a5254aeb8d37035028512c -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision cdc76e1a95383dff63a5254aeb8d37035028512c) +++ src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -65,6 +65,7 @@ TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); const TConfig& rConfig = GetContext().GetConfig(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); // log rLog.logi(_T("Deleting files (DeleteFiles)...")); @@ -113,15 +114,15 @@ if(spFileInfo->IsDirectory()) { if(!GetTaskPropValue(rConfig)) - TLocalFilesystem::SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); - bSuccess = TLocalFilesystem::RemoveDirectory(spFileInfo->GetFullFilePath()); + spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); + bSuccess = spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath()); } else { // set files attributes to normal - it'd slow processing a bit, but it's better. if(!GetTaskPropValue(rConfig)) - TLocalFilesystem::SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); - bSuccess = TLocalFilesystem::DeleteFile(spFileInfo->GetFullFilePath()); + spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); + bSuccess = spFilesystem->DeleteFile(spFileInfo->GetFullFilePath()); } // operation failed Index: src/libchcore/TSubTaskFastMove.cpp =================================================================== diff -u -N -rcdc76e1a95383dff63a5254aeb8d37035028512c -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision cdc76e1a95383dff63a5254aeb8d37035028512c) +++ src/libchcore/TSubTaskFastMove.cpp (.../TSubTaskFastMove.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -69,6 +69,7 @@ const TConfig& rConfig = GetContext().GetConfig(); TSmartPath pathDestination = GetContext().GetDestinationPath(); const TFileFiltersArray& rafFilters = GetContext().GetFilters(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); rLog.logi(_T("Performing initial fast-move operation...")); @@ -120,7 +121,7 @@ bRetry = false; // read attributes of src file/folder - bool bExists = TLocalFilesystem::GetFileInfo(pathCurrent, spFileInfo, spBasePath); + bool bExists = spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath); if(!bExists) { EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, ERROR_FILE_NOT_FOUND); @@ -166,7 +167,7 @@ { TSmartPath pathDestinationPath = CalculateDestinationPath(spFileInfo, pathDestination, 0); TSmartPath pathSrc = spBasePath->GetSrcPath(); - bResult = TLocalFilesystem::FastMove(pathSrc, pathDestinationPath); + bResult = spFilesystem->FastMove(pathSrc, pathDestinationPath); if(!bResult) { DWORD dwLastError = GetLastError(); Index: src/libchcore/TSubTaskScanDirectory.cpp =================================================================== diff -u -N -rcdc76e1a95383dff63a5254aeb8d37035028512c -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision cdc76e1a95383dff63a5254aeb8d37035028512c) +++ src/libchcore/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -24,7 +24,6 @@ #include "TSubTaskScanDirectory.h" #include "TSubTaskContext.h" #include "TTaskConfiguration.h" -#include "TLocalFilesystem.h" #include "IFeedbackHandler.h" #include "TBasePathData.h" #include "TWorkerThreadController.h" @@ -71,6 +70,7 @@ TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths(); const TConfig& rConfig = GetContext().GetConfig(); const TFileFiltersArray& rafFilters = GetContext().GetFilters(); + const IFilesystemPtr& spFilesystem = GetContext().GetLocalFilesystem(); rLog.logi(_T("Searching for files...")); @@ -123,7 +123,7 @@ bRetry = false; // read attributes of src file/folder - bool bExists = TLocalFilesystem::GetFileInfo(pathCurrent, spFileInfo, spBasePath); + bool bExists = spFilesystem->GetFileInfo(pathCurrent, spFileInfo, spBasePath); if(!bExists) { EFeedbackResult frResult = spFeedbackHandler->FileError(pathCurrent.ToWString(), TString(), EFileError::eFastMoveError, ERROR_FILE_NOT_FOUND); @@ -231,11 +231,12 @@ TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); TBasePathDataContainerPtr spBasePaths = GetContext().GetBasePaths(); + const IFilesystemPtr& spFilesystem = GetContext().GetLocalFilesystem(); - TLocalFilesystemFind finder = TLocalFilesystem::CreateFinderObject(pathDirName, PathFromString(_T("*"))); + IFilesystemFindPtr spFinder = spFilesystem->CreateFinderObject(pathDirName, PathFromString(_T("*"))); TFileInfoPtr spFileInfo(boost::make_shared()); - while(finder.FindNext(spFileInfo)) + while(spFinder->FindNext(spFileInfo)) { if(rThreadController.KillRequested()) break; Index: src/libchcore/TTask.cpp =================================================================== diff -u -N -rcdc76e1a95383dff63a5254aeb8d37035028512c -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/TTask.cpp (.../TTask.cpp) (revision cdc76e1a95383dff63a5254aeb8d37035028512c) +++ src/libchcore/TTask.cpp (.../TTask.cpp) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -52,7 +52,8 @@ m_bForce(false), m_bContinue(false), m_tSubTaskContext(m_tConfiguration, m_spSrcPaths, m_afFilters, - m_cfgTracker, m_log, m_workerThread, m_fsLocal), + m_cfgTracker, m_log, m_workerThread, + std::make_shared()), m_tSubTasksArray(m_tSubTaskContext), m_spSerializer(spSerializer) { Index: src/libchcore/libchcore.vc140.vcxproj =================================================================== diff -u -N -r2755e12daeccb1935f569e7235e685e566b0b098 -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision 2755e12daeccb1935f569e7235e685e566b0b098) +++ src/libchcore/libchcore.vc140.vcxproj (.../libchcore.vc140.vcxproj) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -497,6 +497,9 @@ + + + @@ -511,6 +514,7 @@ + @@ -519,7 +523,10 @@ + + + @@ -618,6 +625,9 @@ + + + @@ -733,6 +743,8 @@ + + Index: src/libchcore/libchcore.vc140.vcxproj.filters =================================================================== diff -u -N -r2755e12daeccb1935f569e7235e685e566b0b098 -r9ebcc7abf1e0e70f0db2d08b2691351a26ef259b --- src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision 2755e12daeccb1935f569e7235e685e566b0b098) +++ src/libchcore/libchcore.vc140.vcxproj.filters (.../libchcore.vc140.vcxproj.filters) (revision 9ebcc7abf1e0e70f0db2d08b2691351a26ef259b) @@ -69,6 +69,9 @@ {202d13d3-126b-4811-8c1c-a14b4f0476b7} + + {3de9b5f5-44fa-4e4b-9a63-f93d940d537a} + @@ -341,9 +344,6 @@ Source Files\Serialization\Fake - - Source Files\Filesystems - Source Files\Tools @@ -395,6 +395,30 @@ Source Files\Tools + + Source Files\Filesystems + + + Source Files\Tools + + + Source Files\Tools + + + Source Files\Filesystems + + + Source Files\Filesystems + + + Source Files\Filesystems\Local + + + Source Files\Filesystems\Local + + + Source Files\Filesystems\Local + @@ -670,9 +694,6 @@ Source Files\Serialization\Fake - - Source Files\Filesystems - Source Files\Tools @@ -736,5 +757,23 @@ Tests + + Source Files\Filesystems + + + Source Files\Filesystems + + + Source Files\Filesystems + + + Source Files\Filesystems\Local + + + Source Files\Filesystems\Local + + + Source Files\Filesystems\Local + \ No newline at end of file