Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -N -r27a43e40952cf2f3e0bb0e608a8f3142042ceb46 -rd468098a278a0d16c5b700236ea276b9c9677c9f --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 27a43e40952cf2f3e0bb0e608a8f3142042ceb46) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) @@ -803,10 +803,8 @@ // by using spDstFileInfo->Create() (which uses FindFirstFile()) or by // reading parameters using opened handle; need to be tested in the future TFileInfoPtr spDstFileInfo(boost::make_shared()); + spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo); - if(!spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo)) - THROW_CORE_EXCEPTION_WIN32(eErr_CannotGetFileInfo, GetLastError()); - // src and dst files are the same EFeedbackResult frResult = spFeedbackHandler->FileAlreadyExists(spSrcFileInfo, spDstFileInfo); switch(frResult) @@ -1165,33 +1163,33 @@ bSkip = false; - // log - TString strFormat = _T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFileFB)"); - strFormat.Replace(_t("%errno"), boost::lexical_cast(rBuffer.GetErrorCode()).c_str()); - strFormat.Replace(_t("%count"), boost::lexical_cast(rBuffer.GetBytesTransferred()).c_str()); - strFormat.Replace(_t("%path"), pathFile.ToString()); - rLog.loge(strFormat.c_str()); +// log +TString strFormat = _T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFileFB)"); +strFormat.Replace(_t("%errno"), boost::lexical_cast(rBuffer.GetErrorCode()).c_str()); +strFormat.Replace(_t("%count"), boost::lexical_cast(rBuffer.GetBytesTransferred()).c_str()); +strFormat.Replace(_t("%path"), pathFile.ToString()); +rLog.loge(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError); - switch(frResult) - { - case EFeedbackResult::eResult_Cancel: - return TSubTaskBase::eSubResult_CancelRequest; +EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError); +switch (frResult) +{ +case EFeedbackResult::eResult_Cancel: + return TSubTaskBase::eSubResult_CancelRequest; - case EFeedbackResult::eResult_Retry: - return TSubTaskBase::eSubResult_Retry; +case EFeedbackResult::eResult_Retry: + return TSubTaskBase::eSubResult_Retry; - case EFeedbackResult::eResult_Pause: - return TSubTaskBase::eSubResult_PauseRequest; +case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; - case EFeedbackResult::eResult_Skip: - bSkip = true; - return TSubTaskBase::eSubResult_Continue; +case EFeedbackResult::eResult_Skip: + bSkip = true; + return TSubTaskBase::eSubResult_Continue; - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } +default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); +} } TSubTaskBase::ESubOperationResult TSubTaskCopyMove::FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, @@ -1244,8 +1242,7 @@ BOOST_ASSERT(FALSE); // unknown result THROW_CORE_EXCEPTION(eErr_UnhandledCase); } - } - while (bRetry); + } while (bRetry); return TSubTaskBase::eSubResult_Continue; } @@ -1255,10 +1252,25 @@ icpf::log_file& rLog = GetContext().GetLog(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - bool bRetry = true; - DWORD dwLastError = ERROR_SUCCESS; - while(bRetry && !spFilesystem->CreateDirectory(pathDirectory, false) && (dwLastError = GetLastError()) != ERROR_ALREADY_EXISTS) + bool bRetry = false; + do { + bRetry = false; + + DWORD dwLastError = ERROR_SUCCESS; + try + { + spFilesystem->CreateDirectory(pathDirectory, false); + return TSubTaskBase::eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + if (dwLastError == ERROR_ALREADY_EXISTS) + return TSubTaskBase::eSubResult_Continue; + // log TString strFormat; strFormat = _T("Error %errno while calling CreateDirectory %path (ProcessFiles)"); @@ -1273,21 +1285,21 @@ return TSubTaskBase::eSubResult_CancelRequest; case EFeedbackResult::eResult_Retry: - bRetry = false; + bRetry = true; break; case EFeedbackResult::eResult_Pause: return TSubTaskBase::eSubResult_PauseRequest; case EFeedbackResult::eResult_Skip: - bRetry = false; break; // just do nothing default: BOOST_ASSERT(FALSE); // unknown result THROW_CORE_EXCEPTION(eErr_UnhandledCase); } } + while (bRetry); return TSubTaskBase::eSubResult_Continue; } @@ -1313,9 +1325,50 @@ ullNeededSize = rFilesCache.CalculateTotalSize() - rFilesCache.CalculatePartialSize(m_tSubTaskStats.GetCurrentIndex()); // get free space - bool bResult = spFilesystem->GetDynamicFreeSpace(pathDestination, ullAvailableSize); - if(bResult && ullNeededSize > ullAvailableSize) + DWORD dwLastError = ERROR_SUCCESS; + bool bCheckFailed = false; + try { + spFilesystem->GetDynamicFreeSpace(pathDestination, ullAvailableSize); + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + bCheckFailed = true; + } + + if(bCheckFailed) + { + TString strFormat; + strFormat = _T("Error %errno while checking free space at %path"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%path"), pathDestination.ToString()); + rLog.loge(strFormat.c_str()); + + EFeedbackResult frResult = spFeedbackHandler->FileError(pathDestination.ToWString(), TString(), EFileError::eCheckForFreeSpace, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Cancel: + return TSubTaskBase::eSubResult_CancelRequest; + + case EFeedbackResult::eResult_Retry: + bRetry = true; + continue; + + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + case EFeedbackResult::eResult_Skip: + return TSubTaskBase::eSubResult_Continue; + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } + + if(ullNeededSize > ullAvailableSize) + { TString strFormat = _T("Not enough free space on disk - needed %needsize bytes for data, available: %availablesize bytes."); strFormat.Replace(_t("%needsize"), boost::lexical_cast(ullNeededSize).c_str()); strFormat.Replace(_t("%availablesize"), boost::lexical_cast(ullAvailableSize).c_str());