Index: src/ch/FeedbackFileErrorDlg.cpp =================================================================== diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/FeedbackFileErrorDlg.cpp (.../FeedbackFileErrorDlg.cpp) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/FeedbackFileErrorDlg.cpp (.../FeedbackFileErrorDlg.cpp) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -10,10 +10,11 @@ IMPLEMENT_DYNAMIC(CFeedbackFileErrorDlg, ictranslate::CLanguageDialog) -CFeedbackFileErrorDlg::CFeedbackFileErrorDlg(const tchar_t* pszPath, ulong_t ulSysError, CWnd* pParent /*=NULL*/) +CFeedbackFileErrorDlg::CFeedbackFileErrorDlg(const tchar_t* pszSrcPath, const tchar_t* pszDstPath, ulong_t ulSysError, CWnd* pParent /*=NULL*/) : ictranslate::CLanguageDialog(IDD_FEEDBACK_FILE_ERROR_DIALOG, pParent), m_bAllItems(FALSE), - m_strPath(pszPath), + m_strSrcPath(pszSrcPath), + m_strDstPath(pszDstPath), m_ulSysError(ulSysError) { @@ -46,7 +47,7 @@ ictranslate::CResourceManager& rResManager = GetResManager(); CString strFmt; - strFmt = rResManager.LoadString(IDS_INFO_FILE_STRING); + strFmt = rResManager.LoadString(m_strDstPath.IsEmpty() ? IDS_INFO_FILE_STRING : IDS_INFO_TWO_FILE_STRING); strFmt += _T("\r\n"); strFmt += rResManager.LoadString(IDS_INFO_REASON_STRING); @@ -60,7 +61,8 @@ szSystem[dwPos]=_T('\0'); ictranslate::CFormat fmt(strFmt); - fmt.SetParam(_t("%filename"), m_strPath); + fmt.SetParam(_t("%filename"), m_strSrcPath); + fmt.SetParam(_t("%dstfilename"), m_strDstPath); fmt.SetParam(_t("%reason"), szSystem); m_ctlErrorInfo.SetWindowText(fmt); Index: src/ch/FeedbackFileErrorDlg.h =================================================================== diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/FeedbackFileErrorDlg.h (.../FeedbackFileErrorDlg.h) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/FeedbackFileErrorDlg.h (.../FeedbackFileErrorDlg.h) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -25,7 +25,7 @@ DECLARE_DYNAMIC(CFeedbackFileErrorDlg) public: - CFeedbackFileErrorDlg(const tchar_t* pszPath, ulong_t ulSysError, CWnd* pParent = NULL); // standard constructor + CFeedbackFileErrorDlg(const tchar_t* pszSrcPath, const tchar_t* pszDstPath, ulong_t ulSysError, CWnd* pParent = NULL); // standard constructor virtual ~CFeedbackFileErrorDlg(); afx_msg void OnBnClickedRetryButton(); @@ -40,7 +40,8 @@ public: BOOL m_bAllItems; CStatic m_ctlErrorInfo; - CString m_strPath; + CString m_strSrcPath; + CString m_strDstPath; ulong_t m_ulSysError; virtual BOOL OnInitDialog(); }; Index: src/ch/FeedbackHandler.cpp =================================================================== diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/FeedbackHandler.cpp (.../FeedbackHandler.cpp) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/FeedbackHandler.cpp (.../FeedbackHandler.cpp) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -71,7 +71,7 @@ return eResult_Unknown; FEEDBACK_FILEERROR* pData = (FEEDBACK_FILEERROR*)pFeedbackParam; - CFeedbackFileErrorDlg dlg(pData->pszPath, pData->ulError); + CFeedbackFileErrorDlg dlg(pData->pszSrcPath, pData->pszDstPath, pData->ulError); eFeedbackResult = (EFeedbackResult)dlg.DoModal(); bUseForAllItems = dlg.m_bAllItems; Index: src/ch/FeedbackHandler.h =================================================================== diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/FeedbackHandler.h (.../FeedbackHandler.h) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/FeedbackHandler.h (.../FeedbackHandler.h) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -22,6 +22,7 @@ #include "../libchcore/FeedbackHandlerBase.h" class CFileInfo; +enum EFileError; struct FEEDBACK_ALREADYEXISTS { @@ -31,8 +32,10 @@ struct FEEDBACK_FILEERROR { - const tchar_t* pszPath; - ulong_t ulError; + const tchar_t* pszSrcPath; + const tchar_t* pszDstPath; + EFileError eFileError; // error type + ulong_t ulError; // system error }; struct FEEDBACK_NOTENOUGHSPACE Index: src/ch/Stdafx.h =================================================================== diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/Stdafx.h (.../Stdafx.h) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/Stdafx.h (.../Stdafx.h) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -36,6 +36,7 @@ #include "../libicpf/file.h" #include "../libictranslate/LanguageDialog.h" #include +#include "../common/ErrorConstants.h" #ifdef _UNICODE #if defined _M_IX86 Index: src/ch/ch.rc =================================================================== diff -u -r7e9e91404339189d67fe7de08724f33f03906e40 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/ch.rc (.../ch.rc) (revision 7e9e91404339189d67fe7de08724f33f03906e40) +++ src/ch/ch.rc (.../ch.rc) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -1066,6 +1066,12 @@ STRINGTABLE BEGIN + IDS_INFO_TWO_FILE_STRING + "Source file: %filename\nDestination file: %dstfilename" +END + +STRINGTABLE +BEGIN IDS_ABOUTVERSION_STRING "Compilation: " END Index: src/ch/resource.h =================================================================== diff -u -r7e9e91404339189d67fe7de08724f33f03906e40 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/resource.h (.../resource.h) (revision 7e9e91404339189d67fe7de08724f33f03906e40) +++ src/ch/resource.h (.../resource.h) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -485,6 +485,7 @@ #define IDS_TITLEMOVE_STRING 13501 #define IDS_TITLEUNKNOWNOPERATION_STRING 13502 #define IDS_MAINBROWSETEXT_STRING 13503 +#define IDS_INFO_TWO_FILE_STRING 13504 #define IDS_ABTNOTHANX_STRING 14000 #define IDS_ABOUTVERSION_STRING 14001 #define IDS_BUFFERSIZEZERO_STRING 14500 Index: src/ch/task.cpp =================================================================== diff -u -r7e9e91404339189d67fe7de08724f33f03906e40 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/task.cpp (.../task.cpp) (revision 7e9e91404339189d67fe7de08724f33f03906e40) +++ src/ch/task.cpp (.../task.cpp) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -1693,16 +1693,20 @@ // log pTask->m_log.logi(_T("Deleting files (DeleteFiles)...")); + chcore::IFeedbackHandler* piFeedbackHandler = pTask->GetFeedbackHandler(); + BOOST_ASSERT(piFeedbackHandler); + // current processed path BOOL bSuccess; CFileInfo fi; ictranslate::CFormat fmt; // index points to 0 or next item to process - for (int i=pTask->GetCurrentIndex();iFilesGetSize();i++) + int iIndex=pTask->GetCurrentIndex(); + while(iIndex < pTask->FilesGetSize()) { // set index in pTask to currently deleted element - pTask->SetCurrentIndex(i); + pTask->SetCurrentIndex(iIndex); // check for kill flag if (pTask->GetKillFlag()) @@ -1713,9 +1717,12 @@ } // current processed element - fi=pTask->FilesGetAt(pTask->FilesGetSize()-i-1); + fi=pTask->FilesGetAt(pTask->FilesGetSize()-iIndex-1); if(!(fi.GetFlags() & FIF_PROCESSED)) + { + ++iIndex; continue; + } // delete data if (fi.IsDirectory()) @@ -1741,10 +1748,33 @@ fmt.SetParam(_t("%errno"), dwLastError); fmt.SetParam(_t("%path"), fi.GetFullFilePath()); pTask->m_log.loge(fmt); - throw new CProcessingException(E_ERROR, pTask, dwLastError, fmt); + + CString strFile = fi.GetFullFilePath(); + FEEDBACK_FILEERROR ferr = { (PCTSTR)strFile, NULL, eDeleteError, dwLastError }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); + switch(frResult) + { + case CFeedbackHandler::eResult_Cancel: + pTask->m_log.logi(_T("Cancel request while deleting file.")); + throw new CProcessingException(E_CANCEL, pTask); + break; + case CFeedbackHandler::eResult_Retry: + continue; // no iIndex bump, since we are trying again + break; + case CFeedbackHandler::eResult_Pause: + throw new CProcessingException(E_PAUSE, pTask); + break; + case CFeedbackHandler::eResult_Skip: + break; // just do nothing + default: + BOOST_ASSERT(FALSE); // unknown result + throw new CProcessingException(E_ERROR, pTask, 0, _t("Unknown feedback result type")); + } } - }//for + ++iIndex; + }//while + // change status to finished pTask->SetStatus(ST_FINISHED, ST_STEP_MASK); @@ -1847,7 +1877,7 @@ { DWORD dwLastError=GetLastError(); CString strFile = pData->pfiSrcFile->GetFullFilePath(); - FEEDBACK_FILEERROR feedStruct = { (PCTSTR)strFile, dwLastError }; + FEEDBACK_FILEERROR feedStruct = { (PCTSTR)strFile, NULL, eCreateError, dwLastError }; CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &feedStruct); switch (frResult) @@ -1894,7 +1924,7 @@ DWORD dwLastError=GetLastError(); CString strFile = pData->strDstFile; - FEEDBACK_FILEERROR feedStruct = { (PCTSTR)strFile, dwLastError }; + FEEDBACK_FILEERROR feedStruct = { (PCTSTR)strFile, NULL, eCreateError, dwLastError }; CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &feedStruct); switch (frResult) { @@ -1946,153 +1976,238 @@ { // try to move file pointers to the end ULONGLONG ullMove=(bNoBuffer ? ROUNDDOWN(fiDest.GetLength64(), MAXSECTORSIZE) : fiDest.GetLength64()); - if (SetFilePointer64(hSrc, ullMove, FILE_BEGIN) == -1 || SetFilePointer64(hDst, ullMove, FILE_BEGIN) == -1) + bool bRetry = true; + while(bRetry) { - // log - fmt.SetFormat(_T("Error %errno while moving file pointers of %srcpath and %dstpath to %pos")); - fmt.SetParam(_t("%errno"), GetLastError()); - fmt.SetParam(_t("%srcpath"), pData->pfiSrcFile->GetFullFilePath()); - fmt.SetParam(_t("%dstpath"), pData->strDstFile); - fmt.SetParam(_t("%pos"), ullMove); - pData->pTask->m_log.loge(fmt); - - // seek failed - seek to begin - if (SetFilePointer64(hSrc, 0, FILE_BEGIN) == -1 || SetFilePointer64(hDst, 0, FILE_BEGIN) == -1) + if(SetFilePointer64(hSrc, ullMove, FILE_BEGIN) == -1 || SetFilePointer64(hDst, ullMove, FILE_BEGIN) == -1) { + dwLastError = GetLastError(); // log - dwLastError=GetLastError(); - fmt.SetFormat(_T("Error %errno while restoring (moving to beginning) file pointers of %srcpath and %dstpath")); + fmt.SetFormat(_T("Error %errno while moving file pointers of %srcpath and %dstpath to %pos")); fmt.SetParam(_t("%errno"), dwLastError); fmt.SetParam(_t("%srcpath"), pData->pfiSrcFile->GetFullFilePath()); fmt.SetParam(_t("%dstpath"), pData->strDstFile); + fmt.SetParam(_t("%pos"), ullMove); pData->pTask->m_log.loge(fmt); - throw new CProcessingException(E_ERROR, pData->pTask, dwLastError, fmt); + + CString strSrcFile = pData->pfiSrcFile->GetFullFilePath(); + CString strDstFile = pData->strDstFile; + FEEDBACK_FILEERROR ferr = { (PCTSTR)strSrcFile, (PCTSTR)strDstFile, eSeekError, dwLastError }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); + switch(frResult) + { + case CFeedbackHandler::eResult_Cancel: + throw new CProcessingException(E_CANCEL, pData->pTask); + break; + case CFeedbackHandler::eResult_Retry: + continue; + break; + case CFeedbackHandler::eResult_Pause: + throw new CProcessingException(E_PAUSE, pData->pTask); + break; + case CFeedbackHandler::eResult_Skip: + bRetry = false; + pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); + pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + pData->bProcessed = false; + return; + default: + BOOST_ASSERT(FALSE); // unknown result + throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); + } } else { - // file pointers restored - if second pass subtract what's needed - if (!bFirstPass) + bRetry = false; + // file pointers moved - so we have skipped some work - update positions + if (bFirstPass) // przy drugim obiegu jest ju� uwzgl�dnione { - pData->pTask->IncreaseProcessedSize(-static_cast<__int64>(ullMove)); - pData->pTask->IncreaseProcessedTasksSize(-static_cast<__int64>(ullMove)); + pData->pTask->IncreaseProcessedSize(ullMove); + pData->pTask->IncreaseProcessedTasksSize(ullMove); } } } - else - { - // file pointers moved - so we have skipped some work - update positions - if (bFirstPass) // przy drugim obiegu jest ju� uwzgl�dnione - { - pData->pTask->IncreaseProcessedSize(ullMove); - pData->pTask->IncreaseProcessedTasksSize(ullMove); - } - } } } else - if (!SetEndOfFile(hDst)) // if recopying - reset the dest file + { + bool bRetry = true; + while(bRetry && !SetEndOfFile(hDst)) { // log dwLastError=GetLastError(); fmt.SetFormat(_T("Error %errno while setting size of file %path to 0")); fmt.SetParam(_t("%errno"), dwLastError); fmt.SetParam(_t("%path"), pData->strDstFile); pData->pTask->m_log.loge(fmt); - throw new CProcessingException(E_ERROR, pData->pTask, dwLastError, fmt); - } - // copying - unsigned long tord, rd, wr; - int iBufferIndex; - do - { - // kill flag checks - if (pData->pTask->GetKillFlag()) + FEEDBACK_FILEERROR ferr = { (PCTSTR)pData->strDstFile, NULL, eResizeError, dwLastError }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); + switch(frResult) { - // log - fmt.SetFormat(_T("Kill request while main copying file %srcpath -> %dstpath")); - fmt.SetParam(_t("%srcpath"), pData->pfiSrcFile->GetFullFilePath()); - fmt.SetParam(_t("%dstpath"), pData->strDstFile); - pData->pTask->m_log.logi(fmt); - throw new CProcessingException(E_KILL_REQUEST, pData->pTask); + case CFeedbackHandler::eResult_Cancel: + throw new CProcessingException(E_CANCEL, pData->pTask); + break; + case CFeedbackHandler::eResult_Retry: + continue; + break; + case CFeedbackHandler::eResult_Pause: + throw new CProcessingException(E_PAUSE, pData->pTask); + break; + case CFeedbackHandler::eResult_Skip: + bRetry = false; + break; // just do nothing + default: + BOOST_ASSERT(FALSE); // unknown result + throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); } + } + } - // recreate buffer if needed - if (!(*pData->dbBuffer.GetSizes() == *pData->pTask->GetBufferSizes())) - { - // log - const BUFFERSIZES *pbs1=pData->dbBuffer.GetSizes(), *pbs2=pData->pTask->GetBufferSizes(); + // copying + unsigned long tord = 0, rd = 0, wr = 0; + int iBufferIndex; + do + { + // kill flag checks + if (pData->pTask->GetKillFlag()) + { + // log + fmt.SetFormat(_T("Kill request while main copying file %srcpath -> %dstpath")); + fmt.SetParam(_t("%srcpath"), pData->pfiSrcFile->GetFullFilePath()); + fmt.SetParam(_t("%dstpath"), pData->strDstFile); + pData->pTask->m_log.logi(fmt); + throw new CProcessingException(E_KILL_REQUEST, pData->pTask); + } - fmt.SetFormat(_T("Changing buffer size from [Def:%defsize, One:%onesize, Two:%twosize, CD:%cdsize, LAN:%lansize] to [Def:%defsize2, One:%onesize2, Two:%twosize2, CD:%cdsize2, LAN:%lansize2] wile copying %srcfile -> %dstfile (CustomCopyFile)")); + // recreate buffer if needed + if (!(*pData->dbBuffer.GetSizes() == *pData->pTask->GetBufferSizes())) + { + // log + const BUFFERSIZES *pbs1=pData->dbBuffer.GetSizes(), *pbs2=pData->pTask->GetBufferSizes(); - fmt.SetParam(_t("%defsize"), pbs1->m_uiDefaultSize); - fmt.SetParam(_t("%onesize"), pbs1->m_uiOneDiskSize); - fmt.SetParam(_t("%twosize"), pbs1->m_uiTwoDisksSize); - fmt.SetParam(_t("%cdsize"), pbs1->m_uiCDSize); - fmt.SetParam(_t("%lansize"), pbs1->m_uiLANSize); - fmt.SetParam(_t("%defsize2"), pbs2->m_uiDefaultSize); - fmt.SetParam(_t("%onesize2"), pbs2->m_uiOneDiskSize); - fmt.SetParam(_t("%twosize2"), pbs2->m_uiTwoDisksSize); - fmt.SetParam(_t("%cdsize2"), pbs2->m_uiCDSize); - fmt.SetParam(_t("%lansize2"), pbs2->m_uiLANSize); - fmt.SetParam(_t("%srcfile"), pData->pfiSrcFile->GetFullFilePath()); - fmt.SetParam(_t("%dstfile"), pData->strDstFile); + fmt.SetFormat(_T("Changing buffer size from [Def:%defsize, One:%onesize, Two:%twosize, CD:%cdsize, LAN:%lansize] to [Def:%defsize2, One:%onesize2, Two:%twosize2, CD:%cdsize2, LAN:%lansize2] wile copying %srcfile -> %dstfile (CustomCopyFile)")); - pData->pTask->m_log.logi(fmt); - pData->pTask->SetBufferSizes(pData->dbBuffer.Create(pData->pTask->GetBufferSizes())); - } + fmt.SetParam(_t("%defsize"), pbs1->m_uiDefaultSize); + fmt.SetParam(_t("%onesize"), pbs1->m_uiOneDiskSize); + fmt.SetParam(_t("%twosize"), pbs1->m_uiTwoDisksSize); + fmt.SetParam(_t("%cdsize"), pbs1->m_uiCDSize); + fmt.SetParam(_t("%lansize"), pbs1->m_uiLANSize); + fmt.SetParam(_t("%defsize2"), pbs2->m_uiDefaultSize); + fmt.SetParam(_t("%onesize2"), pbs2->m_uiOneDiskSize); + fmt.SetParam(_t("%twosize2"), pbs2->m_uiTwoDisksSize); + fmt.SetParam(_t("%cdsize2"), pbs2->m_uiCDSize); + fmt.SetParam(_t("%lansize2"), pbs2->m_uiLANSize); + fmt.SetParam(_t("%srcfile"), pData->pfiSrcFile->GetFullFilePath()); + fmt.SetParam(_t("%dstfile"), pData->strDstFile); - // establish count of data to read - iBufferIndex=pData->pTask->GetBufferSizes()->m_bOnlyDefault ? 0 : pData->pfiSrcFile->GetBufferIndex(); - tord=bNoBuffer ? ROUNDUP(pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex], MAXSECTORSIZE) : pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex]; + pData->pTask->m_log.logi(fmt); + pData->pTask->SetBufferSizes(pData->dbBuffer.Create(pData->pTask->GetBufferSizes())); + } - // read - if (!ReadFile(hSrc, pData->dbBuffer, tord, &rd, NULL)) + // establish count of data to read + iBufferIndex=pData->pTask->GetBufferSizes()->m_bOnlyDefault ? 0 : pData->pfiSrcFile->GetBufferIndex(); + tord=bNoBuffer ? ROUNDUP(pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex], MAXSECTORSIZE) : pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex]; + + // read + bool bRetry = true; + while(bRetry && !ReadFile(hSrc, pData->dbBuffer, tord, &rd, NULL)) + { + // log + dwLastError=GetLastError(); + fmt.SetFormat(_T("Error %errno while trying to read %count bytes from source file %path (CustomCopyFile)")); + fmt.SetParam(_t("%errno"), dwLastError); + fmt.SetParam(_t("%count"), tord); + fmt.SetParam(_t("%path"), pData->pfiSrcFile->GetFullFilePath()); + pData->pTask->m_log.loge(fmt); + + CString strFile = pData->pfiSrcFile->GetFullFilePath(); + FEEDBACK_FILEERROR ferr = { (PCTSTR)strFile, NULL, eReadError, dwLastError }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); + switch(frResult) { - // log - dwLastError=GetLastError(); - fmt.SetFormat(_T("Error %errno while trying to read %count bytes from source file %path (CustomCopyFile)")); - fmt.SetParam(_t("%errno"), dwLastError); - fmt.SetParam(_t("%count"), tord); - fmt.SetParam(_t("%path"), pData->pfiSrcFile->GetFullFilePath()); - pData->pTask->m_log.loge(fmt); - throw new CProcessingException(E_ERROR, pData->pTask, dwLastError, fmt); + case CFeedbackHandler::eResult_Cancel: + throw new CProcessingException(E_CANCEL, pData->pTask); + break; + case CFeedbackHandler::eResult_Retry: + continue; + break; + case CFeedbackHandler::eResult_Pause: + throw new CProcessingException(E_PAUSE, pData->pTask); + break; + case CFeedbackHandler::eResult_Skip: + bRetry = false; + // TODO: correct the skip length handling + pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); + pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + pData->bProcessed = false; + return; + default: + BOOST_ASSERT(FALSE); // unknown result + throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); } + } - // change count of stored data - if (bNoBuffer && (ROUNDUP(rd, MAXSECTORSIZE)) != rd) - { - // we need to copy rest so do the second pass - // close files - CloseHandle(hSrc); - CloseHandle(hDst); + // change count of stored data + if (bNoBuffer && (ROUNDUP(rd, MAXSECTORSIZE)) != rd) + { + // we need to copy rest so do the second pass + // close files + CloseHandle(hSrc); + CloseHandle(hDst); - // second pass - bFirstPass=false; - bCopyRest=true; // nedd to copy rest + // second pass + bFirstPass=false; + bCopyRest=true; // nedd to copy rest - goto l_start; - } + goto l_start; + } - // zapisz - if (!WriteFile(hDst, pData->dbBuffer, rd, &wr, NULL) || wr != rd) + // write + bRetry = true; + while(bRetry && !WriteFile(hDst, pData->dbBuffer, rd, &wr, NULL) || wr != rd) + { + // log + dwLastError=GetLastError(); + fmt.SetFormat(_T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFile)")); + fmt.SetParam(_t("%errno"), dwLastError); + fmt.SetParam(_t("%count"), rd); + fmt.SetParam(_t("%path"), pData->strDstFile); + pData->pTask->m_log.loge(fmt); + + CString strFile = pData->strDstFile; + FEEDBACK_FILEERROR ferr = { (PCTSTR)strFile, NULL, eWriteError, dwLastError }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); + switch(frResult) { - // log - dwLastError=GetLastError(); - fmt.SetFormat(_T("Error %errno while trying to write %count bytes to destination file %path (CustomCopyFile)")); - fmt.SetParam(_t("%errno"), dwLastError); - fmt.SetParam(_t("%count"), rd); - fmt.SetParam(_t("%path"), pData->strDstFile); - pData->pTask->m_log.loge(fmt); - throw new CProcessingException(E_ERROR, pData->pTask, dwLastError, fmt); + case CFeedbackHandler::eResult_Cancel: + throw new CProcessingException(E_CANCEL, pData->pTask); + break; + case CFeedbackHandler::eResult_Retry: + continue; + break; + case CFeedbackHandler::eResult_Pause: + throw new CProcessingException(E_PAUSE, pData->pTask); + break; + case CFeedbackHandler::eResult_Skip: + bRetry = false; + // TODO: correct the skip length handling + pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); + pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + pData->bProcessed = false; + return; + default: + BOOST_ASSERT(FALSE); // unknown result + throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); } - - // increase count of processed data - pData->pTask->IncreaseProcessedSize(rd); - pData->pTask->IncreaseProcessedTasksSize(rd); - // TRACE("Read: %d, Written: %d\n", rd, wr); } - while ( rd != 0 ); + + // increase count of processed data + pData->pTask->IncreaseProcessedSize(rd); + pData->pTask->IncreaseProcessedTasksSize(rd); + // TRACE("Read: %d, Written: %d\n", rd, wr); + } + while ( rd != 0 ); } else { @@ -2109,16 +2224,10 @@ } catch(...) { - // log - fmt.SetFormat(_T("Caught exception in CustomCopyFile [last error: %errno] (at time %timestamp)")); - fmt.SetParam(_t("%errno"), GetLastError()); - fmt.SetParam(_t("%timestamp"), GetTickCount()); - pData->pTask->m_log.loge(fmt); - // close handles - if (hSrc != INVALID_HANDLE_VALUE) + if(hSrc != INVALID_HANDLE_VALUE) CloseHandle(hSrc); - if (hDst != INVALID_HANDLE_VALUE) + if(hDst != INVALID_HANDLE_VALUE) CloseHandle(hDst); throw; @@ -2128,6 +2237,9 @@ // function processes files/folders void CTask::ProcessFiles(CTask* pTask) { + chcore::IFeedbackHandler* piFeedbackHandler = pTask->GetFeedbackHandler(); + BOOST_ASSERT(piFeedbackHandler); + // log pTask->m_log.logi(_T("Processing files/folders (ProcessFiles)")); @@ -2146,8 +2258,8 @@ DWORD dwLastError; // begin at index which wasn't processed previously - int nSize=pTask->FilesGetSize(); // wielko�� tablicy - int iCopiesCount=pTask->GetCopies(); // ilo�� kopii + int nSize=pTask->FilesGetSize(); + int iCopiesCount=pTask->GetCopies(); bool bIgnoreFolders=(pTask->GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_DIRS) != 0; bool bForceDirectories=(pTask->GetStatus(ST_SPECIAL_MASK) & ST_FORCE_DIRS) != 0; const CDestPath& dpDestPath=pTask->GetDestPath(); @@ -2196,7 +2308,8 @@ bool bMove=pTask->GetStatus(ST_OPERATION_MASK) == ST_MOVE; if (bMove && dpDestPath.GetDriveNumber() != -1 && dpDestPath.GetDriveNumber() == fi.GetDriveNumber() && iCopiesCount == 1 && fi.GetMove()) { - if (!MoveFile(fi.GetFullFilePath(), ccp.strDstFile)) + bool bRetry = true; + if(bRetry && !MoveFile(fi.GetFullFilePath(), ccp.strDstFile)) { dwLastError=GetLastError(); //log @@ -2205,7 +2318,29 @@ fmt.SetParam(_t("%srcpath"), fi.GetFullFilePath()); fmt.SetParam(_t("%dstpath"), ccp.strDstFile); pTask->m_log.loge(fmt); - throw new CProcessingException(E_ERROR, pTask, dwLastError, fmt); + + CString strSrcFile = fi.GetFullFilePath(); + CString strDstFile = ccp.strDstFile; + FEEDBACK_FILEERROR ferr = { (PCTSTR)strSrcFile, (PCTSTR)strDstFile, eFastMoveError, dwLastError }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); + switch(frResult) + { + case CFeedbackHandler::eResult_Cancel: + throw new CProcessingException(E_CANCEL, pTask); + break; + case CFeedbackHandler::eResult_Retry: + continue; + break; + case CFeedbackHandler::eResult_Pause: + throw new CProcessingException(E_PAUSE, pTask); + break; + case CFeedbackHandler::eResult_Skip: + bRetry = false; + break; // just do nothing + default: + BOOST_ASSERT(FALSE); // unknown result + throw new CProcessingException(E_ERROR, pTask, 0, _t("Unknown feedback result type")); + } } else fi.SetFlags(FIF_PROCESSED, FIF_PROCESSED); @@ -2215,14 +2350,36 @@ // if folder - create it if ( fi.IsDirectory() ) { - if (!CreateDirectory(ccp.strDstFile, NULL) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS ) + bool bRetry = true; + if(bRetry && !CreateDirectory(ccp.strDstFile, NULL) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS ) { // log fmt.SetFormat(_T("Error %errno while calling CreateDirectory %path (ProcessFiles)")); fmt.SetParam(_t("%errno"), dwLastError); fmt.SetParam(_t("%path"), ccp.strDstFile); pTask->m_log.loge(fmt); - throw new CProcessingException(E_ERROR, pTask, dwLastError, fmt); + + CString strFile = ccp.strDstFile; + FEEDBACK_FILEERROR ferr = { (PCTSTR)strFile, NULL, eCreateError, dwLastError }; + CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); + switch(frResult) + { + case CFeedbackHandler::eResult_Cancel: + throw new CProcessingException(E_CANCEL, pTask); + break; + case CFeedbackHandler::eResult_Retry: + continue; + break; + case CFeedbackHandler::eResult_Pause: + throw new CProcessingException(E_PAUSE, pTask); + break; + case CFeedbackHandler::eResult_Skip: + bRetry = false; + break; // just do nothing + default: + BOOST_ASSERT(FALSE); // unknown result + throw new CProcessingException(E_ERROR, pTask, 0, _t("Unknown feedback result type")); + } } pTask->IncreaseProcessedSize(fi.GetLength64()); Index: src/ch/task.h =================================================================== diff -u -r449a5b399ab21ca0d06050b47b264f2f704af966 -rf6706e71721e6828e4e3be894caec6808e27630b --- src/ch/task.h (.../task.h) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/task.h (.../task.h) (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -406,7 +406,7 @@ ull_t GetPosition(); ull_t GetRange(); - int GetPercent(); + int GetPercent(); UINT GetOperationsPending(); void SetLimitOperations(UINT uiLimit); Index: src/common/ErrorConstants.h =================================================================== diff -u --- src/common/ErrorConstants.h (revision 0) +++ src/common/ErrorConstants.h (revision f6706e71721e6828e4e3be894caec6808e27630b) @@ -0,0 +1,37 @@ +//****************************************************************************** +// Copyright (C) 2001-2008 by Jozef Starosczyk +// ixen@copyhandler.com +// +// This program is free software; you can redistribute it and/or modify +// it under the terms of the GNU Library General Public License +// (version 2) as published by the Free Software Foundation; +// +// This program is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +// GNU General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this program; if not, write to the +// Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. +// +//****************************************************************************** +/// @file ErrorConstants.h +/// @brief Contains error constants used throughout the project. +//****************************************************************************** +#ifndef __ERRORCONSTANTS_H__ +#define __ERRORCONSTANTS_H__ + +enum EFileError +{ + eDeleteError, ///< Problem occured when tried to delete the fs object + eSeekError, ///< Problem occured when tried to set file pointer + eResizeError, ///< Problem occured when tried to change size of the fs object + eReadError, ///< Problem occured when tried to read data from file + eWriteError, ///< Problem occured when tried to write data to a file + eFastMoveError, ///< Problem occured when tried to perform fast move operation (that does not involve copying contents) + eCreateError ///< Problem occured when tried to create the fs object +}; + +#endif