Index: src/ch/CustomCopyDlg.cpp =================================================================== diff -u -r2d7bee54f998ae8f5d4145a2cf3f4a589253016f -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/CustomCopyDlg.cpp (.../CustomCopyDlg.cpp) (revision 2d7bee54f998ae8f5d4145a2cf3f4a589253016f) +++ src/ch/CustomCopyDlg.cpp (.../CustomCopyDlg.cpp) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -17,6 +17,7 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "stdafx.h" +#include #include "resource.h" #include "FileInfo.h" #include "CustomCopyDlg.h" @@ -26,7 +27,7 @@ #include "FilterDlg.h" #include "StringHelpers.h" #include "ch.h" -#include +#include "../libicpf/file.h" #ifdef _DEBUG #define new DEBUG_NEW Index: src/ch/FileSupport.cpp =================================================================== diff -u -r633a533cb6e741d44fe28aa56339e1d2709b1b27 -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/FileSupport.cpp (.../FileSupport.cpp) (revision 633a533cb6e741d44fe28aa56339e1d2709b1b27) +++ src/ch/FileSupport.cpp (.../FileSupport.cpp) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -19,66 +19,12 @@ #include "stdafx.h" #include "wtypes.h" #include "FileSupport.h" -//#include "tchar.h" #ifdef _DEBUG #define new DEBUG_NEW #endif -__int64 SetFilePointer64(HANDLE hFile, __int64 llDistance, DWORD dwMoveMethod) -{ - LARGE_INTEGER li = { 0, 0 }; - LARGE_INTEGER liNew = { 0, 0 }; - - li.QuadPart = llDistance; - - if(!SetFilePointerEx(hFile, li, &liNew, dwMoveMethod)) - return -1; - - return liNew.QuadPart; -} - -__int64 GetFilePointer64(HANDLE hFile) -{ - return SetFilePointer64(hFile, 0, FILE_CURRENT); -} - -__int64 GetFileSize64(HANDLE hFile) -{ - LARGE_INTEGER li = { 0, 0 }; - - if(!GetFileSizeEx(hFile, &li)) - return -1; - - return li.QuadPart; -} - -bool SetFileSize64(LPCTSTR lpszFilename, __int64 llSize) -{ - HANDLE hFile = CreateFile(lpszFilename, GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if(hFile == INVALID_HANDLE_VALUE) - return false; - - if(SetFilePointer64(hFile, llSize, FILE_BEGIN) == -1) - { - CloseHandle(hFile); - return false; - } - - if(!SetEndOfFile(hFile)) - { - CloseHandle(hFile); - return false; - } - - if(!CloseHandle(hFile)) - return false; - - return true; -} - // disk support routines - bool GetDynamicFreeSpace(LPCTSTR lpszPath, ull_t* pFree, ull_t* pTotal) { ULARGE_INTEGER ui64Available, ui64Total; Index: src/ch/FileSupport.h =================================================================== diff -u -r633a533cb6e741d44fe28aa56339e1d2709b1b27 -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/FileSupport.h (.../FileSupport.h) (revision 633a533cb6e741d44fe28aa56339e1d2709b1b27) +++ src/ch/FileSupport.h (.../FileSupport.h) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -19,12 +19,6 @@ #ifndef __FILESUPPORT_ROUTINES_H__ #define __FILESUPPORT_ROUTINES_H__ -// file support routines -__int64 SetFilePointer64(HANDLE hFile, __int64 llDistance, DWORD dwMoveMethod); -__int64 GetFilePointer64(HANDLE hFile); -__int64 GetFileSize64(HANDLE hFile); -bool SetFileSize64(LPCTSTR lpszFilename, __int64 llSize); - // disk support routines bool GetDynamicFreeSpace(LPCTSTR lpszPath, ull_t* pFree, ull_t* pTotal); Index: src/ch/MainWnd.cpp =================================================================== diff -u -r5fd6beaad9f1eccb664b997d151acb59961e4827 -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 5fd6beaad9f1eccb664b997d151acb59961e4827) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -39,6 +39,7 @@ #include "FileSupport.h" #include "StringHelpers.h" #include "../libchcore/TCoreException.h" +#include "../libicpf/exception.h" #ifdef _DEBUG #define new DEBUG_NEW Index: src/ch/Stdafx.h =================================================================== diff -u -r5fd6beaad9f1eccb664b997d151acb59961e4827 -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/Stdafx.h (.../Stdafx.h) (revision 5fd6beaad9f1eccb664b997d151acb59961e4827) +++ src/ch/Stdafx.h (.../Stdafx.h) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -44,7 +44,7 @@ #include #include "debug.h" -#include "../libicpf/file.h" +#include "../libicpf/exception.h" #include "../libictranslate/LanguageDialog.h" #include "../common/ErrorConstants.h" #include "../libchcore/TLogger.h" Index: src/ch/TLocalFilesystem.cpp =================================================================== diff -u -r117248f68a61e817de78e501c44ccb4ac7c97ec9 -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision 117248f68a61e817de78e501c44ccb4ac7c97ec9) +++ src/ch/TLocalFilesystem.cpp (.../TLocalFilesystem.cpp) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -22,11 +22,10 @@ // ============================================================================ #include "stdafx.h" #include "TLocalFilesystem.h" +#include #include "TAutoHandles.h" #include "FileInfo.h" #include "DataBuffer.h" -#include -#include "FileSupport.h" #include UINT TLocalFilesystem::GetDriveData(const chcore::TSmartPath& spPath) @@ -275,6 +274,20 @@ return pDiskExtent->DiskNumber; } +bool TLocalFilesystem::GetDynamicFreeSpace(const chcore::TSmartPath& path, unsigned long long& rullFree) +{ + rullFree = 0; + + ULARGE_INTEGER ui64Available, ui64Total; + if(GetDiskFreeSpaceEx(path.ToString(), &ui64Available, &ui64Total, NULL)) + { + rullFree = ui64Available.QuadPart; + return true; + } + else + return false; +} + ///////////////////////////////////////////////////////////////////////////////////// // class TLocalFilesystemFind @@ -384,7 +397,12 @@ if(!IsOpen()) return false; - return (SetFilePointer64(m_hFile, llNewPos, dwMoveMethod) != -1); + LARGE_INTEGER li = { 0, 0 }; + LARGE_INTEGER liNew = { 0, 0 }; + + li.QuadPart = llNewPos; + + return SetFilePointerEx(m_hFile, li, &liNew, dwMoveMethod) != FALSE; } bool TLocalFilesystemFile::SetEndOfFile() Index: src/ch/TLocalFilesystem.h =================================================================== diff -u -r117248f68a61e817de78e501c44ccb4ac7c97ec9 -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision 117248f68a61e817de78e501c44ccb4ac7c97ec9) +++ src/ch/TLocalFilesystem.h (.../TLocalFilesystem.h) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -24,7 +24,6 @@ #define __TLOCALFILESYSTEM_H__ #include "../libchcore/TPath.h" -#include #include class CFileInfo; @@ -65,6 +64,8 @@ EPathsRelation GetPathsRelation(const chcore::TSmartPath& pathFirst, const chcore::TSmartPath& pathSecond); + bool GetDynamicFreeSpace(const chcore::TSmartPath& path, unsigned long long& rullFree); + private: static chcore::TSmartPath PrependPathExtensionIfNeeded(const chcore::TSmartPath& pathInput); static UINT GetDriveData(const chcore::TSmartPath& spPath); Index: src/ch/TSubTaskCopyMove.cpp =================================================================== diff -u -rab32897e61cc637a1e28d9dc3f0489b8d16a429c -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision ab32897e61cc637a1e28d9dc3f0489b8d16a429c) +++ src/ch/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -43,7 +43,7 @@ }; TSubTaskCopyMove::TSubTaskCopyMove(TSubTaskContext& tSubTaskContext) : -TSubTaskBase(tSubTaskContext) + TSubTaskBase(tSubTaskContext) { } @@ -68,6 +68,11 @@ // count how much has been done (updates also a member in TSubTaskCopyMoveArray) rLocalStats.SetProcessedSize(rFilesCache.CalculatePartialSize(rBasicProgressInfo.GetCurrentIndex())); + // now it's time to check if there is enough space on destination device + TSubTaskBase::ESubOperationResult eResult = CheckForFreeSpaceFB(); + if(eResult != TSubTaskBase::eSubResult_Continue) + return eResult; + // begin at index which wasn't processed previously size_t stSize = rFilesCache.GetSize(); bool bIgnoreFolders = GetTaskPropValue(rTaskDefinition.GetConfiguration()); @@ -1057,3 +1062,65 @@ return TSubTaskBase::eSubResult_Continue; } + +TSubTaskBase::ESubOperationResult TSubTaskCopyMove::CheckForFreeSpaceFB() +{ + icpf::log_file& rLog = GetContext().GetLog(); + chcore::TTaskDefinition& rTaskDefinition = GetContext().GetTaskDefinition(); + chcore::IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler(); + TTaskLocalStats& rLocalStats = GetContext().GetTaskLocalStats(); + TLocalFilesystem& rLocalFilesystem = GetContext().GetLocalFilesystem(); + + ull_t ullNeededSize = 0, ullAvailableSize = 0; + bool bRetry = false; + + do + { + bRetry = false; + + rLog.logi(_T("Checking for free space on destination disk...")); + + ullNeededSize = rLocalStats.GetUnProcessedSize(); // it'd be nice to round up to take cluster size into consideration, + + // get free space + bool bResult = rLocalFilesystem.GetDynamicFreeSpace(rTaskDefinition.GetDestinationPath(), ullAvailableSize); + if(bResult && ullNeededSize > ullAvailableSize) + { + ictranslate::CFormat fmt; + fmt.SetFormat(_T("Not enough free space on disk - needed %needsize bytes for data, available: %availablesize bytes.")); + fmt.SetParam(_t("%needsize"), ullNeededSize); + fmt.SetParam(_t("%availablesize"), ullAvailableSize); + rLog.logw(fmt); + + if(rTaskDefinition.GetSourcePathCount() > 0) + { + FEEDBACK_NOTENOUGHSPACE feedStruct = { ullNeededSize, rTaskDefinition.GetSourcePathAt(0).ToString(), rTaskDefinition.GetDestinationPath().ToString() }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_NotEnoughSpace, &feedStruct); + + // default + switch(frResult) + { + case CFeedbackHandler::eResult_Cancel: + rLog.logi(_T("Cancel request while checking for free space on disk.")); + return TSubTaskBase::eSubResult_CancelRequest; + + case CFeedbackHandler::eResult_Retry: + rLog.logi(_T("Retrying to read drive's free space...")); + bRetry = true; + break; + + case CFeedbackHandler::eResult_Ignore: + rLog.logi(_T("Ignored warning about not enough place on disk to copy data.")); + return TSubTaskBase::eSubResult_Continue; + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW(_T("Unhandled case"), 0, 0, 0); + } + } + } + } + while(bRetry); + + return TSubTaskBase::eSubResult_Continue; +} Index: src/ch/TSubTaskCopyMove.h =================================================================== diff -u -r7749d67cd70821fef9cc51303d42625fbcc2aa9d -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 7749d67cd70821fef9cc51303d42625fbcc2aa9d) +++ src/ch/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -26,7 +26,6 @@ #include "TSubTaskBase.h" struct CUSTOM_COPY_PARAMS; -class TAutoFileHandle; class CDataBuffer; class TLocalFilesystemFile; @@ -53,6 +52,8 @@ ESubOperationResult ReadFileFB(TLocalFilesystemFile& file, CDataBuffer& rBuffer, DWORD dwToRead, DWORD& rdwBytesRead, const chcore::TSmartPath& pathFile, bool& bSkip); ESubOperationResult WriteFileFB(TLocalFilesystemFile& file, CDataBuffer& rBuffer, DWORD dwToWrite, DWORD& rdwBytesWritten, const chcore::TSmartPath& pathFile, bool& bSkip); ESubOperationResult CreateDirectoryFB(const chcore::TSmartPath& pathDirectory); + + ESubOperationResult CheckForFreeSpaceFB(); }; #endif Index: src/ch/TSubTaskScanDirectory.cpp =================================================================== diff -u -rab32897e61cc637a1e28d9dc3f0489b8d16a429c -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision ab32897e61cc637a1e28d9dc3f0489b8d16a429c) +++ src/ch/TSubTaskScanDirectory.cpp (.../TSubTaskScanDirectory.cpp) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -27,13 +27,13 @@ #include "../libchcore/TTaskDefinition.h" #include "FeedbackHandler.h" #include "TLocalFilesystem.h" -#include "..\libchcore\FeedbackHandlerBase.h" +#include "../libchcore/FeedbackHandlerBase.h" #include "TBasePathData.h" #include "../libchcore/TWorkerThreadController.h" #include "TTaskLocalStats.h" TSubTaskScanDirectories::TSubTaskScanDirectories(TSubTaskContext& rContext) : -TSubTaskBase(rContext) + TSubTaskBase(rContext) { } @@ -50,9 +50,14 @@ chcore::IFeedbackHandler* piFeedbackHandler = GetContext().GetFeedbackHandler(); const TBasePathDataContainer& rarrSourcePathsInfo = GetContext().GetBasePathDataContainer(); chcore::TWorkerThreadController& rThreadController = GetContext().GetThreadController(); + TTaskLocalStats& rTaskLocalStats = GetContext().GetTaskLocalStats(); rLog.logi(_T("Searching for files...")); + // reset progress + rTaskLocalStats.SetProcessedSize(0); + rTaskLocalStats.SetTotalSize(0); + // delete the content of rFilesCache rFilesCache.Clear(); @@ -205,7 +210,7 @@ } // calc size of all files - GetContext().GetTaskLocalStats().SetTotalSize(rFilesCache.CalculateTotalSize()); + rTaskLocalStats.SetTotalSize(rFilesCache.CalculateTotalSize()); // log rLog.logi(_T("Searching for files finished")); Index: src/ch/task.cpp =================================================================== diff -u -r4c09a2d7ab35a30114ff2b7c4db12bc413bf538c -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/task.cpp (.../task.cpp) (revision 4c09a2d7ab35a30114ff2b7c4db12bc413bf538c) +++ src/ch/task.cpp (.../task.cpp) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -481,22 +481,6 @@ return bRet; } -bool CTask::GetRequiredFreeSpace(ull_t *pullNeeded, ull_t *pullAvailable) -{ - BOOST_ASSERT(pullNeeded && pullAvailable); - if(!pullNeeded || !pullAvailable) - THROW(_T("Invalid argument"), 0, 0, 0); - - *pullNeeded = m_localStats.GetUnProcessedSize(); // it'd be nice to round up to take cluster size into consideration, - // but GetDiskFreeSpace returns false values - - // get free space - if(!GetDynamicFreeSpace(m_tTaskDefinition.GetDestinationPath().ToString(), pullAvailable, NULL)) - return true; - - return (*pullNeeded <= *pullAvailable); -} - void CTask::SetTaskDirectory(const chcore::TSmartPath& strDir) { boost::unique_lock lock(m_lock); @@ -602,58 +586,6 @@ return TSubTaskBase::eSubResult_Continue; } -TSubTaskBase::ESubOperationResult CTask::CheckForFreeSpaceFB() -{ - ull_t ullNeededSize = 0, ullAvailableSize = 0; - bool bRetry = false; - - do - { - bRetry = false; - - m_log.logi(_T("Checking for free space on destination disk...")); - - if(!GetRequiredFreeSpace(&ullNeededSize, &ullAvailableSize)) - { - ictranslate::CFormat fmt; - fmt.SetFormat(_T("Not enough free space on disk - needed %needsize bytes for data, available: %availablesize bytes.")); - fmt.SetParam(_t("%needsize"), ullNeededSize); - fmt.SetParam(_t("%availablesize"), ullAvailableSize); - m_log.logw(fmt); - - if(m_tTaskDefinition.GetSourcePathCount() > 0) - { - FEEDBACK_NOTENOUGHSPACE feedStruct = { ullNeededSize, m_tTaskDefinition.GetSourcePathAt(0).ToString(), m_tTaskDefinition.GetDestinationPath().ToString() }; - CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)m_piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_NotEnoughSpace, &feedStruct); - - // default - switch(frResult) - { - case CFeedbackHandler::eResult_Cancel: - m_log.logi(_T("Cancel request while checking for free space on disk.")); - return TSubTaskBase::eSubResult_CancelRequest; - - case CFeedbackHandler::eResult_Retry: - m_log.logi(_T("Retrying to read drive's free space...")); - bRetry = true; - break; - - case CFeedbackHandler::eResult_Ignore: - m_log.logi(_T("Ignored warning about not enough place on disk to copy data.")); - return TSubTaskBase::eSubResult_Continue; - - default: - BOOST_ASSERT(FALSE); // unknown result - THROW(_T("Unhandled case"), 0, 0, 0); - } - } - } - } - while(bRetry); - - return TSubTaskBase::eSubResult_Continue; -} - DWORD WINAPI CTask::DelegateThreadProc(LPVOID pParam) { BOOST_ASSERT(pParam); @@ -710,19 +642,11 @@ { case chcore::eSubOperation_Scanning: { - // get rid of info about processed sizes - m_localStats.SetProcessedSize(0); - m_localStats.SetTotalSize(0); - // start searching TSubTaskScanDirectories tSubTaskScanDir(tSubTaskContext); //eResult = RecurseDirectories(); eResult = tSubTaskScanDir.Exec(); - // check for free space - if(eResult == TSubTaskBase::eSubResult_Continue) - eResult = CheckForFreeSpaceFB(); - // if we didn't wait for permission to start earlier, then ask now (but only in case this is the first search) if(eResult == TSubTaskBase::eSubResult_Continue && bReadTasksSize && stSubOperationIndex == 0) { Index: src/ch/task.h =================================================================== diff -u -rab32897e61cc637a1e28d9dc3f0489b8d16a429c -r4be0f47d68a1a161529dc55901659b9daec996e3 --- src/ch/task.h (.../task.h) (revision ab32897e61cc637a1e28d9dc3f0489b8d16a429c) +++ src/ch/task.h (.../task.h) (revision 4be0f47d68a1a161529dc55901659b9daec996e3) @@ -176,11 +176,6 @@ TSubTaskBase::ESubOperationResult CheckForWaitState(); - // Helper filesystem methods - bool GetRequiredFreeSpace(ull_t *pi64Needed, ull_t *pi64Available); - - TSubTaskBase::ESubOperationResult CheckForFreeSpaceFB(); - // m_nStatus void SetStatusNL(UINT nStatus, UINT nMask); UINT GetStatusNL(UINT nMask = 0xffffffff);