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; +}