Index: src/libchcore/TSubTaskDelete.cpp =================================================================== diff -u -N -re96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3 -rd468098a278a0d16c5b700236ea276b9c9677c9f --- src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision e96806b7f8ff7ca7e9f4afbea603e6351a3dc3e3) +++ src/libchcore/TSubTaskDelete.cpp (.../TSubTaskDelete.cpp) (revision d468098a278a0d16c5b700236ea276b9c9677c9f) @@ -38,6 +38,7 @@ #include "TFeedbackHandlerWrapper.h" #include #include "TBufferSizes.h" +#include "TFileException.h" namespace chcore { @@ -64,7 +65,6 @@ icpf::log_file& rLog = GetContext().GetLog(); TFileInfoArray& rFilesCache = GetContext().GetFilesCache(); TWorkerThreadController& rThreadController = GetContext().GetThreadController(); - const TConfig& rConfig = GetContext().GetConfig(); IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); // log @@ -79,7 +79,6 @@ m_tSubTaskStats.SetCurrentPath(TString()); // current processed path - BOOL bSuccess; TFileInfoPtr spFileInfo; TString strFormat; @@ -110,63 +109,161 @@ continue; } + ESubOperationResult eResult = TSubTaskBase::eSubResult_Continue; // delete data if (spFileInfo->IsDirectory()) + eResult = RemoveDirectoryFB(spFeedbackHandler, spFileInfo); + else + eResult = DeleteFileFB(spFeedbackHandler, spFileInfo); + + ++fcIndex; + } + + m_tSubTaskStats.SetCurrentIndex(fcIndex); + m_tSubTaskStats.SetProcessedCount(fcIndex); + m_tSubTaskStats.SetCurrentPath(TString()); + + // log + rLog.logi(_T("Deleting files finished")); + + return TSubTaskBase::eSubResult_Continue; + } + + TSubTaskBase::ESubOperationResult TSubTaskDelete::RemoveDirectoryFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo) + { + const TConfig& rConfig = GetContext().GetConfig(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + icpf::log_file& rLog = GetContext().GetLog(); + + bool bRetry = false; + do + { + bRetry = false; + + // #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response) + // for now it is ignored + try { if (!GetTaskPropValue(rConfig)) spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); - bSuccess = spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath()); } - else + catch (const TFileException&) { - // set files attributes to normal - it'd slow processing a bit, but it's better. - if (!GetTaskPropValue(rConfig)) - spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); - bSuccess = spFilesystem->DeleteFile(spFileInfo->GetFullFilePath()); } - // operation failed - DWORD dwLastError = GetLastError(); - if (!bSuccess && dwLastError != ERROR_PATH_NOT_FOUND && dwLastError != ERROR_FILE_NOT_FOUND) + DWORD dwLastError = ERROR_SUCCESS; + try { - // log - strFormat = _T("Error #%errno while deleting file/folder %path"); - strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); - strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); - rLog.loge(strFormat.c_str()); + spFilesystem->RemoveDirectory(spFileInfo->GetFullFilePath()); + return TSubTaskBase::eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } - EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); - switch (frResult) - { - case EFeedbackResult::eResult_Cancel: - rLog.logi(_T("Cancel request while deleting file.")); - return TSubTaskBase::eSubResult_CancelRequest; + if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND) + return TSubTaskBase::eSubResult_Continue; - case EFeedbackResult::eResult_Retry: - continue; // no fcIndex bump, since we are trying again + // log + TString strFormat = _T("Error #%errno while deleting file/folder %path"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); + rLog.loge(strFormat.c_str()); - case EFeedbackResult::eResult_Pause: - return TSubTaskBase::eSubResult_PauseRequest; + EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Cancel: + rLog.logi(_T("Cancel request while deleting file.")); + return TSubTaskBase::eSubResult_CancelRequest; - case EFeedbackResult::eResult_Skip: - break; // just do nothing + case EFeedbackResult::eResult_Retry: + bRetry = true; + continue; // no fcIndex bump, since we are trying again - default: - BOOST_ASSERT(FALSE); // unknown result - THROW_CORE_EXCEPTION(eErr_UnhandledCase); - } + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + case EFeedbackResult::eResult_Skip: + break; // just do nothing + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); } + } + while (bRetry); - ++fcIndex; - }//while + return TSubTaskBase::eSubResult_Continue; + } - m_tSubTaskStats.SetCurrentIndex(fcIndex); - m_tSubTaskStats.SetProcessedCount(fcIndex); - m_tSubTaskStats.SetCurrentPath(TString()); + TSubTaskBase::ESubOperationResult TSubTaskDelete::DeleteFileFB(const IFeedbackHandlerPtr& spFeedbackHandler, const TFileInfoPtr& spFileInfo) + { + const TConfig& rConfig = GetContext().GetConfig(); + IFilesystemPtr spFilesystem = GetContext().GetLocalFilesystem(); + icpf::log_file& rLog = GetContext().GetLog(); - // log - rLog.logi(_T("Deleting files finished")); + bool bRetry = false; + do + { + bRetry = false; + // #bug - changing read-only attribute should only be done when user explicitly requests it (via feedback response) + // for now it is ignored + try + { + if (!GetTaskPropValue(rConfig)) + spFilesystem->SetAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); + } + catch (const TFileException&) + { + } + + DWORD dwLastError = ERROR_SUCCESS; + try + { + spFilesystem->DeleteFile(spFileInfo->GetFullFilePath()); + return TSubTaskBase::eSubResult_Continue; + } + catch (const TFileException& e) + { + dwLastError = e.GetNativeError(); + } + + if (dwLastError == ERROR_PATH_NOT_FOUND || dwLastError == ERROR_FILE_NOT_FOUND) + return TSubTaskBase::eSubResult_Continue; + + // log + TString strFormat = _T("Error #%errno while deleting file/folder %path"); + strFormat.Replace(_T("%errno"), boost::lexical_cast(dwLastError).c_str()); + strFormat.Replace(_T("%path"), spFileInfo->GetFullFilePath().ToString()); + rLog.loge(strFormat.c_str()); + + EFeedbackResult frResult = spFeedbackHandler->FileError(spFileInfo->GetFullFilePath().ToWString(), TString(), EFileError::eDeleteError, dwLastError); + switch (frResult) + { + case EFeedbackResult::eResult_Cancel: + rLog.logi(_T("Cancel request while deleting file.")); + return TSubTaskBase::eSubResult_CancelRequest; + + case EFeedbackResult::eResult_Retry: + bRetry = true; + continue; // no fcIndex bump, since we are trying again + + case EFeedbackResult::eResult_Pause: + return TSubTaskBase::eSubResult_PauseRequest; + + case EFeedbackResult::eResult_Skip: + break; // just do nothing + + default: + BOOST_ASSERT(FALSE); // unknown result + THROW_CORE_EXCEPTION(eErr_UnhandledCase); + } + } + while (bRetry); + return TSubTaskBase::eSubResult_Continue; }