Index: src/libchcore/TFilesystemFileFeedbackWrapper.cpp =================================================================== diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r6eefe6212611518e13af7771d406612c0a7a2bed --- src/libchcore/TFilesystemFileFeedbackWrapper.cpp (.../TFilesystemFileFeedbackWrapper.cpp) (revision 09d769045d1d5c45d8df16d209c754b872348c26) +++ src/libchcore/TFilesystemFileFeedbackWrapper.cpp (.../TFilesystemFileFeedbackWrapper.cpp) (revision 6eefe6212611518e13af7771d406612c0a7a2bed) @@ -20,15 +20,18 @@ #include "TFilesystemFileFeedbackWrapper.h" #include "TFileException.h" #include +#include namespace chcore { - TFilesystemFileFeedbackWrapper::TFilesystemFileFeedbackWrapper(icpf::log_file& rLog) : + TFilesystemFileFeedbackWrapper::TFilesystemFileFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, icpf::log_file& rLog) : + m_spFeedbackHandler(spFeedbackHandler), + m_spFilesystem(spFilesystem), m_rLog(rLog) { } - TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileSrc) + TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::OpenSourceFileFB(const IFilesystemFilePtr& fileSrc) { bool bRetry = false; @@ -50,7 +53,7 @@ dwLastError = e.GetNativeError(); } - EFeedbackResult frResult = spFeedbackHandler->FileError(fileSrc->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(fileSrc->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Skip: @@ -91,7 +94,7 @@ return TSubTaskBase::eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst) + TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::OpenExistingDestinationFileFB(const IFilesystemFilePtr& fileDst) { bool bRetry = false; @@ -112,7 +115,7 @@ dwLastError = e.GetNativeError(); } - EFeedbackResult frResult = spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Retry: @@ -153,8 +156,127 @@ return TSubTaskBase::eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::TruncateFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, file_size_t fsNewSize, const TSmartPath& pathFile, bool& bSkip) + TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::OpenDestinationFileFB(const IFilesystemFilePtr& fileDst, + const TFileInfoPtr& spSrcFileInfo, + unsigned long long& ullSeekTo, bool& bFreshlyCreated) { + bool bRetry = false; + + ullSeekTo = 0; + bFreshlyCreated = true; + + fileDst->Close(); + do + { + bRetry = false; + + DWORD dwLastError = ERROR_SUCCESS; + try + { + fileDst->CreateNewForWriting(); + return TSubTaskBase::eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + if (dwLastError == ERROR_FILE_EXISTS) + { + bFreshlyCreated = false; + + // pass it to the specialized method + TSubTaskBase::ESubOperationResult eResult = OpenExistingDestinationFileFB(fileDst); + if (eResult != TSubTaskBase::eSubResult_Continue) + return eResult; + else if (!fileDst->IsOpen()) + return TSubTaskBase::eSubResult_Continue; + + // read info about the existing destination file, + // NOTE: it is not known which one would be faster - reading file parameters + // 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()); + m_spFilesystem->GetFileInfo(fileDst->GetFilePath(), spDstFileInfo); + + // src and dst files are the same + EFeedbackResult frResult = m_spFeedbackHandler->FileAlreadyExists(spSrcFileInfo, spDstFileInfo); + switch (frResult) + { + case EFeedbackResult::eResult_Overwrite: + ullSeekTo = 0; + break; + + case EFeedbackResult::eResult_CopyRest: + ullSeekTo = spDstFileInfo->GetLength64(); + break; + + case EFeedbackResult::eResult_Skip: + return TSubTaskBase::eSubResult_Continue; + + case EFeedbackResult::eResult_Cancel: + { + // log + TString strFormat = _T("Cancel request while checking result of dialog before opening source file %path (CustomCopyFileFB)"); + strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString()); + m_rLog.logi(strFormat.c_str()); + + return TSubTaskBase::eSubResult_CancelRequest; + } + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } + else + { + EFeedbackResult frResult = m_spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Retry: + { + // log + TString strFormat = _T("Retrying [error %errno] to open destination file %path (CustomCopyFileFB)"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString()); + m_rLog.loge(strFormat.c_str()); + + bRetry = true; + + break; + } + case EFeedbackResult::eResult_Cancel: + { + // log + TString strFormat = _T("Cancel request [error %errno] while opening destination file %path (CustomCopyFileFB)"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString()); + m_rLog.loge(strFormat.c_str()); + + return TSubTaskBase::eSubResult_CancelRequest; + } + + case EFeedbackResult::eResult_Skip: + break; // will return invalid handle value + + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } + } while (bRetry); + + return TSubTaskBase::eSubResult_Continue; + } + + TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::TruncateFileFB(const IFilesystemFilePtr& spFile, file_size_t fsNewSize, const TSmartPath& pathFile, bool& bSkip) + { bSkip = false; bool bRetry = false; @@ -177,7 +299,7 @@ strFormat.Replace(_t("%path"), pathFile.ToString()); m_rLog.loge(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eResizeError, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eResizeError, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Cancel: @@ -203,7 +325,7 @@ return TSubTaskBase::eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::ReadFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) + TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::ReadFileFB(const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) { bSkip = false; bool bRetry = false; @@ -229,7 +351,7 @@ strFormat.Replace(_t("%path"), pathFile.ToString()); m_rLog.loge(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eReadError, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eReadError, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Cancel: @@ -255,7 +377,7 @@ return TSubTaskBase::eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::WriteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) + TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::WriteFileFB(const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) { bSkip = false; @@ -282,7 +404,7 @@ strFormat.Replace(_t("%path"), pathFile.ToString()); m_rLog.loge(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eWriteError, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Cancel: @@ -308,7 +430,7 @@ return TSubTaskBase::eSubResult_Continue; } - TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) + TSubTaskBase::ESubOperationResult TFilesystemFileFeedbackWrapper::FinalizeFileFB(const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip) { bSkip = false; @@ -334,7 +456,7 @@ strFormat.Replace(_t("%path"), pathFile.ToString()); m_rLog.loge(strFormat.c_str()); - EFeedbackResult frResult = spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eFinalizeError, dwLastError); + EFeedbackResult frResult = m_spFeedbackHandler->FileError(pathFile.ToWString(), TString(), EFileError::eFinalizeError, dwLastError); switch (frResult) { case EFeedbackResult::eResult_Cancel: @@ -359,5 +481,4 @@ return TSubTaskBase::eSubResult_Continue; } - } Index: src/libchcore/TFilesystemFileFeedbackWrapper.h =================================================================== diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r6eefe6212611518e13af7771d406612c0a7a2bed --- src/libchcore/TFilesystemFileFeedbackWrapper.h (.../TFilesystemFileFeedbackWrapper.h) (revision 09d769045d1d5c45d8df16d209c754b872348c26) +++ src/libchcore/TFilesystemFileFeedbackWrapper.h (.../TFilesystemFileFeedbackWrapper.h) (revision 6eefe6212611518e13af7771d406612c0a7a2bed) @@ -24,29 +24,34 @@ #include "..\libicpf\log.h" #include "TSubTaskBase.h" #include "IFeedbackHandler.h" +#include "IFilesystem.h" namespace chcore { class TFilesystemFileFeedbackWrapper { public: - TFilesystemFileFeedbackWrapper(icpf::log_file& rLog); + TFilesystemFileFeedbackWrapper(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemPtr& spFilesystem, icpf::log_file& rLog); - TSubTaskBase::ESubOperationResult OpenSourceFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileSrc); - TSubTaskBase::ESubOperationResult OpenExistingDestinationFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst); + TSubTaskBase::ESubOperationResult OpenSourceFileFB(const IFilesystemFilePtr& fileSrc); + TSubTaskBase::ESubOperationResult OpenExistingDestinationFileFB(const IFilesystemFilePtr& fileDst); + TSubTaskBase::ESubOperationResult OpenDestinationFileFB(const IFilesystemFilePtr& fileDst, const TFileInfoPtr& spSrcFileInfo, + unsigned long long& ullSeekTo, bool& bFreshlyCreated); - TSubTaskBase::ESubOperationResult TruncateFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, file_size_t fsNewSize, + TSubTaskBase::ESubOperationResult TruncateFileFB(const IFilesystemFilePtr& spFile, file_size_t fsNewSize, const TSmartPath& pathFile, bool& bSkip); - TSubTaskBase::ESubOperationResult ReadFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + TSubTaskBase::ESubOperationResult ReadFileFB(const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); - TSubTaskBase::ESubOperationResult WriteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + TSubTaskBase::ESubOperationResult WriteFileFB(const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); - TSubTaskBase::ESubOperationResult FinalizeFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& spFile, + TSubTaskBase::ESubOperationResult FinalizeFileFB(const IFilesystemFilePtr& spFile, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); private: + IFeedbackHandlerPtr m_spFeedbackHandler; + IFilesystemPtr m_spFilesystem; icpf::log_file& m_rLog; }; } Index: src/libchcore/TSubTaskCopyMove.cpp =================================================================== diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r6eefe6212611518e13af7771d406612c0a7a2bed --- src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 09d769045d1d5c45d8df16d209c754b872348c26) +++ src/libchcore/TSubTaskCopyMove.cpp (.../TSubTaskCopyMove.cpp) (revision 6eefe6212611518e13af7771d406612c0a7a2bed) @@ -281,7 +281,7 @@ const TConfig& rConfig = GetContext().GetConfig(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); - TFilesystemFileFeedbackWrapper tFileFBWrapper(rLog); + TFilesystemFileFeedbackWrapper tFileFBWrapper(spFeedbackHandler, spFilesystem, rLog); TString strFormat; TSubTaskBase::ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; @@ -297,7 +297,7 @@ IFilesystemFilePtr fileDst = spFilesystem->CreateFileObject(pData->pathDstFile, bNoBuffer); bool bSkip = false; - eResult = OpenSrcAndDstFilesFB(tFileFBWrapper, spFeedbackHandler, pData, fileSrc, fileDst, bSkip); + eResult = OpenSrcAndDstFilesFB(tFileFBWrapper, pData, fileSrc, fileDst, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -364,7 +364,7 @@ pBuffer->InitForRead(ullNextReadPos, dwToRead); ullNextReadPos += dwToRead; - eResult = tFileFBWrapper.ReadFileFB(spFeedbackHandler, fileSrc, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); + eResult = tFileFBWrapper.ReadFileFB(fileSrc, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -391,7 +391,7 @@ if(eResult == TSubTaskBase::eSubResult_Retry) { // re-request read of the same data - eResult = tFileFBWrapper.ReadFileFB(spFeedbackHandler, fileSrc, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); + eResult = tFileFBWrapper.ReadFileFB(fileSrc, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -416,7 +416,7 @@ { pBuffer->InitForWrite(); - eResult = tFileFBWrapper.WriteFileFB(spFeedbackHandler, fileDst, *pBuffer, pData->pathDstFile, bSkip); + eResult = tFileFBWrapper.WriteFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -442,7 +442,7 @@ eResult = HandleWriteError(spFeedbackHandler, *pBuffer, pData->spSrcFile->GetFullFilePath(), bSkip); if(eResult == TSubTaskBase::eSubResult_Retry) { - eResult = tFileFBWrapper.WriteFileFB(spFeedbackHandler, fileDst, *pBuffer, pData->pathDstFile, bSkip); + eResult = tFileFBWrapper.WriteFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -465,7 +465,7 @@ } else { - eResult = tFileFBWrapper.FinalizeFileFB(spFeedbackHandler, fileDst, *pBuffer, pData->pathDstFile, bSkip); + eResult = tFileFBWrapper.FinalizeFileFB(fileDst, *pBuffer, pData->pathDstFile, bSkip); if (eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if (bSkip) @@ -544,7 +544,7 @@ m_tSubTaskStats.AdjustProcessedSize(m_tSubTaskStats.GetCurrentItemProcessedSize(), spSrcFileInfo->GetLength64()); } - TSubTaskCopyMove::ESubOperationResult TSubTaskCopyMove::OpenSrcAndDstFilesFB(TFilesystemFileFeedbackWrapper& rFileFBWrapper, const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData, + TSubTaskCopyMove::ESubOperationResult TSubTaskCopyMove::OpenSrcAndDstFilesFB(TFilesystemFileFeedbackWrapper& rFileFBWrapper, CUSTOM_COPY_PARAMS* pData, const IFilesystemFilePtr& spFileSrc, const IFilesystemFilePtr& spFileDst, bool& bSkip) { const TConfig& rConfig = GetContext().GetConfig(); @@ -555,7 +555,7 @@ unsigned long long ullProcessedSize = m_tSubTaskStats.GetCurrentItemProcessedSize(); // first open the source file and handle any failures - TSubTaskCopyMove::ESubOperationResult eResult = rFileFBWrapper.OpenSourceFileFB(spFeedbackHandler, spFileSrc); + TSubTaskCopyMove::ESubOperationResult eResult = rFileFBWrapper.OpenSourceFileFB(spFileSrc); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(!spFileSrc->IsOpen()) @@ -585,7 +585,16 @@ // NOTE: probably should be removed from here and report problems with read-only files // directly to the user (as feedback request) if(!GetTaskPropValue(rConfig)) - spFilesystem->SetAttributes(pData->pathDstFile, FILE_ATTRIBUTE_NORMAL); + { + try + { + spFilesystem->SetAttributes(pData->pathDstFile, FILE_ATTRIBUTE_NORMAL); + } + catch (const TFileException&) + { + // currently ignore that problem; this should be handled with user feedback + } + } // open destination file, handle the failures and possibly existence of the destination file unsigned long long ullSeekTo = ullProcessedSize; @@ -613,7 +622,7 @@ // we are resuming previous operation if(bContinue) { - eResult = rFileFBWrapper.OpenExistingDestinationFileFB(spFeedbackHandler, spFileDst); + eResult = rFileFBWrapper.OpenExistingDestinationFileFB(spFileDst); if (eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if (!spFileDst->IsOpen()) @@ -633,7 +642,7 @@ { // open destination file for case, when we start operation on this file (i.e. it is not resume of the // old operation) - eResult = OpenDestinationFileFB(rFileFBWrapper, spFeedbackHandler, spFileDst, pData->spSrcFile, ullSeekTo, bDstFileFreshlyCreated); + eResult = rFileFBWrapper.OpenDestinationFileFB(spFileDst, pData->spSrcFile, ullSeekTo, bDstFileFreshlyCreated); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(!spFileDst->IsOpen()) @@ -670,7 +679,7 @@ if(!bDstFileFreshlyCreated) { // if destination file was opened (as opposed to newly created) - eResult = rFileFBWrapper.TruncateFileFB(spFeedbackHandler, spFileDst, fsMoveTo, pData->pathDstFile, bSkip); + eResult = rFileFBWrapper.TruncateFileFB(spFileDst, fsMoveTo, pData->pathDstFile, bSkip); if(eResult != TSubTaskBase::eSubResult_Continue) return eResult; else if(bSkip) @@ -718,128 +727,6 @@ return false; // buffer did not need adjusting } - TSubTaskBase::ESubOperationResult TSubTaskCopyMove::OpenDestinationFileFB(TFilesystemFileFeedbackWrapper& rFileFBWrapper, const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, - 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(); - do - { - bRetry = false; - - DWORD dwLastError = ERROR_SUCCESS; - try - { - fileDst->CreateNewForWriting(); - return TSubTaskBase::eSubResult_Continue; - } - catch (const TFileException& e) - { - dwLastError = e.GetNativeError(); - } - - if(dwLastError == ERROR_FILE_EXISTS) - { - bFreshlyCreated = false; - - // pass it to the specialized method - TSubTaskBase::ESubOperationResult eResult = rFileFBWrapper.OpenExistingDestinationFileFB(spFeedbackHandler, fileDst); - if(eResult != TSubTaskBase::eSubResult_Continue) - return eResult; - else if(!fileDst->IsOpen()) - return TSubTaskBase::eSubResult_Continue; - - // read info about the existing destination file, - // NOTE: it is not known which one would be faster - reading file parameters - // 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); - - // src and dst files are the same - EFeedbackResult frResult = spFeedbackHandler->FileAlreadyExists(spSrcFileInfo, spDstFileInfo); - switch(frResult) - { - case EFeedbackResult::eResult_Overwrite: - ullSeekTo = 0; - break; - - case EFeedbackResult::eResult_CopyRest: - ullSeekTo = spDstFileInfo->GetLength64(); - break; - - case EFeedbackResult::eResult_Skip: - return TSubTaskBase::eSubResult_Continue; - - case EFeedbackResult::eResult_Cancel: - { - // log - TString strFormat = _T("Cancel request while checking result of dialog before opening source file %path (CustomCopyFileFB)"); - strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString()); - rLog.logi(strFormat.c_str()); - - return TSubTaskBase::eSubResult_CancelRequest; - } - case EFeedbackResult::eResult_Pause: - return TSubTaskBase::eSubResult_PauseRequest; - - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } - } - else - { - EFeedbackResult frResult = spFeedbackHandler->FileError(fileDst->GetFilePath().ToWString(), TString(), EFileError::eCreateError, dwLastError); - switch(frResult) - { - case EFeedbackResult::eResult_Retry: - { - // log - TString strFormat = _T("Retrying [error %errno] to open destination file %path (CustomCopyFileFB)"); - strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); - strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString()); - rLog.loge(strFormat.c_str()); - - bRetry = true; - - break; - } - case EFeedbackResult::eResult_Cancel: - { - // log - TString strFormat = _T("Cancel request [error %errno] while opening destination file %path (CustomCopyFileFB)"); - strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); - strFormat.Replace(_T("%path"), fileDst->GetFilePath().ToString()); - rLog.loge(strFormat.c_str()); - - return TSubTaskBase::eSubResult_CancelRequest; - } - - case EFeedbackResult::eResult_Skip: - break; // will return invalid handle value - - case EFeedbackResult::eResult_Pause: - return TSubTaskBase::eSubResult_PauseRequest; - - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } - } - } - while(bRetry); - - return TSubTaskBase::eSubResult_Continue; - } - TSubTaskBase::ESubOperationResult TSubTaskCopyMove::HandleReadError(const IFeedbackHandlerPtr& spFeedbackHandler, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, Index: src/libchcore/TSubTaskCopyMove.h =================================================================== diff -u -r09d769045d1d5c45d8df16d209c754b872348c26 -r6eefe6212611518e13af7771d406612c0a7a2bed --- src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 09d769045d1d5c45d8df16d209c754b872348c26) +++ src/libchcore/TSubTaskCopyMove.h (.../TSubTaskCopyMove.h) (revision 6eefe6212611518e13af7771d406612c0a7a2bed) @@ -65,12 +65,9 @@ ESubOperationResult CustomCopyFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData); - ESubOperationResult OpenSrcAndDstFilesFB(TFilesystemFileFeedbackWrapper& rFileFBWrapper, const IFeedbackHandlerPtr& spFeedbackHandler, CUSTOM_COPY_PARAMS* pData, + ESubOperationResult OpenSrcAndDstFilesFB(TFilesystemFileFeedbackWrapper& rFileFBWrapper, CUSTOM_COPY_PARAMS* pData, const IFilesystemFilePtr& spFileSrc, const IFilesystemFilePtr& spFileDst, bool& bSkip); - ESubOperationResult OpenDestinationFileFB(TFilesystemFileFeedbackWrapper& rFileFBWrapper, const IFeedbackHandlerPtr& spFeedbackHandler, const IFilesystemFilePtr& fileDst, const TFileInfoPtr& spSrcFileInfo, - unsigned long long& ullSeekTo, bool& bFreshlyCreated); - ESubOperationResult HandleReadError(const IFeedbackHandlerPtr& spFeedbackHandler, TOverlappedDataBuffer& rBuffer, const TSmartPath& pathFile, bool& bSkip); ESubOperationResult HandleWriteError(const IFeedbackHandlerPtr& spFeedbackHandler, TOverlappedDataBuffer& rBuffer,