Index: src/ch/CustomCopyDlg.cpp =================================================================== diff -u -N -r9352ed0c4fe447a36bc728640c307be6d41455fd -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/CustomCopyDlg.cpp (.../CustomCopyDlg.cpp) (revision 9352ed0c4fe447a36bc728640c307be6d41455fd) +++ src/ch/CustomCopyDlg.cpp (.../CustomCopyDlg.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -18,6 +18,7 @@ ***************************************************************************/ #include "stdafx.h" #include "resource.h" +#include "FileInfo.h" #include "CustomCopyDlg.h" #include "structs.h" #include "dialogs.h" Index: src/ch/FeedbackFileErrorDlg.cpp =================================================================== diff -u -N -r17059054c69cd5726f4c7d35357f3b9556471783 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FeedbackFileErrorDlg.cpp (.../FeedbackFileErrorDlg.cpp) (revision 17059054c69cd5726f4c7d35357f3b9556471783) +++ src/ch/FeedbackFileErrorDlg.cpp (.../FeedbackFileErrorDlg.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -3,6 +3,7 @@ #include "stdafx.h" #include "ch.h" +#include "FileInfo.h" #include "FeedbackFileErrorDlg.h" #include "FeedbackHandler.h" Index: src/ch/FeedbackHandler.cpp =================================================================== diff -u -N -rf6706e71721e6828e4e3be894caec6808e27630b -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FeedbackHandler.cpp (.../FeedbackHandler.cpp) (revision f6706e71721e6828e4e3be894caec6808e27630b) +++ src/ch/FeedbackHandler.cpp (.../FeedbackHandler.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -17,13 +17,13 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "stdafx.h" +#include "FileInfo.h" #include "FeedbackHandler.h" #include "FeedbackReplaceDlg.h" #include "FeedbackFileErrorDlg.h" #include "FeedbackNotEnoughSpaceDlg.h" #include "ch.h" #include "mmsystem.h" -#include "FileInfo.h" CFeedbackHandler::CFeedbackHandler() : chcore::IFeedbackHandler() @@ -58,7 +58,7 @@ return eResult_Unknown; FEEDBACK_ALREADYEXISTS* pData = (FEEDBACK_ALREADYEXISTS*)pFeedbackParam; - CFeedbackReplaceDlg dlg(pData->pfiSrc, pData->pfiDst); + CFeedbackReplaceDlg dlg(pData->spSrcFileInfo, pData->spDstFileInfo); eFeedbackResult = (EFeedbackResult)dlg.DoModal(); bUseForAllItems = dlg.m_bAllItems; Index: src/ch/FeedbackHandler.h =================================================================== diff -u -N -rf6706e71721e6828e4e3be894caec6808e27630b -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FeedbackHandler.h (.../FeedbackHandler.h) (revision f6706e71721e6828e4e3be894caec6808e27630b) +++ src/ch/FeedbackHandler.h (.../FeedbackHandler.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2001-2008 by J�zef Starosczyk * + * Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -21,13 +21,10 @@ #include "../libchcore/FeedbackHandlerBase.h" -class CFileInfo; -enum EFileError; - struct FEEDBACK_ALREADYEXISTS { - CFileInfo* pfiSrc; - CFileInfo* pfiDst; + CFileInfoPtr spSrcFileInfo; + CFileInfoPtr spDstFileInfo; }; struct FEEDBACK_FILEERROR Index: src/ch/FeedbackNotEnoughSpaceDlg.cpp =================================================================== diff -u -N -r17059054c69cd5726f4c7d35357f3b9556471783 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FeedbackNotEnoughSpaceDlg.cpp (.../FeedbackNotEnoughSpaceDlg.cpp) (revision 17059054c69cd5726f4c7d35357f3b9556471783) +++ src/ch/FeedbackNotEnoughSpaceDlg.cpp (.../FeedbackNotEnoughSpaceDlg.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -18,11 +18,13 @@ ***************************************************************************/ #include "stdafx.h" #include "ch.h" +#include "FileInfo.h" #include "FeedbackNotEnoughSpaceDlg.h" #include "btnIDs.h" #include "StringHelpers.h" #include "..\Common\FileSupport.h" #include "FeedbackHandler.h" + #ifdef _DEBUG #define new DEBUG_NEW #undef THIS_FILE Index: src/ch/FeedbackReplaceDlg.cpp =================================================================== diff -u -N -r5057e08b0cc064972abeb94a488e5f12d9db14a0 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FeedbackReplaceDlg.cpp (.../FeedbackReplaceDlg.cpp) (revision 5057e08b0cc064972abeb94a488e5f12d9db14a0) +++ src/ch/FeedbackReplaceDlg.cpp (.../FeedbackReplaceDlg.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -3,6 +3,7 @@ #include "stdafx.h" #include "ch.h" +#include "FileInfo.h" #include "FeedbackReplaceDlg.h" #include "../libictranslate/ResourceManager.h" #include "FileInfo.h" @@ -12,13 +13,12 @@ IMPLEMENT_DYNAMIC(CFeedbackReplaceDlg, ictranslate::CLanguageDialog) -CFeedbackReplaceDlg::CFeedbackReplaceDlg(const CFileInfo* pfiSrcFile, const CFileInfo* pfiDstFile, CWnd* pParent /*=NULL*/) +CFeedbackReplaceDlg::CFeedbackReplaceDlg(const CFileInfoPtr& spSrcFile, const CFileInfoPtr& spDstFile, CWnd* pParent /*=NULL*/) : ictranslate::CLanguageDialog(IDD_FEEDBACK_REPLACE_DIALOG, pParent), - m_pfiSrcFile(pfiSrcFile), - m_pfiDstFile(pfiDstFile) - , m_bAllItems(FALSE) + m_spSrcFile(spSrcFile), + m_spDstFile(spDstFile), + m_bAllItems(FALSE) { - } CFeedbackReplaceDlg::~CFeedbackReplaceDlg() @@ -81,8 +81,8 @@ void CFeedbackReplaceDlg::RefreshFilesInfo() { - BOOST_ASSERT(m_pfiSrcFile && m_pfiDstFile); - if(!m_pfiSrcFile || !m_pfiDstFile) + BOOST_ASSERT(m_spSrcFile && m_spDstFile); + if(!m_spSrcFile || !m_spDstFile) return; // load template @@ -96,35 +96,35 @@ strTemplate += rManager.LoadString(IDS_INFO_MODIFIED_STRING); ictranslate::CFormat fmt(strTemplate); - fmt.SetParam(_T("%filename"), m_pfiSrcFile->GetFullFilePath()); - fmt.SetParam(_T("%size"), m_pfiSrcFile->GetLength64()); + fmt.SetParam(_T("%filename"), m_spSrcFile->GetFullFilePath()); + fmt.SetParam(_T("%size"), m_spSrcFile->GetLength64()); - COleDateTime dtTemp = m_pfiSrcFile->GetLastWriteTime(); + COleDateTime dtTemp = m_spSrcFile->GetLastWriteTime(); fmt.SetParam(_T("%datemod"), dtTemp.Format(LOCALE_NOUSEROVERRIDE, LANG_USER_DEFAULT)); m_ctlSrcInfo.SetWindowText(fmt); fmt.SetFormat(strTemplate); - fmt.SetParam(_T("%filename"), m_pfiDstFile->GetFullFilePath()); - fmt.SetParam(_T("%size"), m_pfiDstFile->GetLength64()); - dtTemp = m_pfiDstFile->GetLastWriteTime(); + fmt.SetParam(_T("%filename"), m_spDstFile->GetFullFilePath()); + fmt.SetParam(_T("%size"), m_spDstFile->GetLength64()); + dtTemp = m_spDstFile->GetLastWriteTime(); fmt.SetParam(_T("%datemod"), dtTemp.Format(LOCALE_NOUSEROVERRIDE, LANG_USER_DEFAULT)); m_ctlDstInfo.SetWindowText(fmt); } void CFeedbackReplaceDlg::RefreshImages() { - BOOST_ASSERT(m_pfiSrcFile && m_pfiDstFile); - if(!m_pfiSrcFile || !m_pfiDstFile) + BOOST_ASSERT(m_spSrcFile && m_spDstFile); + if(!m_spSrcFile || !m_spDstFile) return; SHFILEINFO shfi; - DWORD_PTR dwRes = SHGetFileInfo(m_pfiSrcFile->GetFullFilePath(), 0, &shfi, sizeof(shfi), SHGFI_ICON); + DWORD_PTR dwRes = SHGetFileInfo(m_spSrcFile->GetFullFilePath(), 0, &shfi, sizeof(shfi), SHGFI_ICON); if(dwRes) m_ctlSrcIcon.SetIcon(shfi.hIcon); - dwRes = SHGetFileInfo(m_pfiDstFile->GetFullFilePath(), 0, &shfi, sizeof(shfi), SHGFI_ICON); + dwRes = SHGetFileInfo(m_spDstFile->GetFullFilePath(), 0, &shfi, sizeof(shfi), SHGFI_ICON); if(dwRes) m_ctlDstIcon.SetIcon(shfi.hIcon); } Index: src/ch/FeedbackReplaceDlg.h =================================================================== diff -u -N -r449a5b399ab21ca0d06050b47b264f2f704af966 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FeedbackReplaceDlg.h (.../FeedbackReplaceDlg.h) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/FeedbackReplaceDlg.h (.../FeedbackReplaceDlg.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2001-2008 by J�zef Starosczyk * + * Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -19,14 +19,12 @@ #ifndef __FEEDBACKREPLACEDLG_H__ #define __FEEDBACKREPLACEDLG_H__ -class CFileInfo; - class CFeedbackReplaceDlg : public ictranslate::CLanguageDialog { DECLARE_DYNAMIC(CFeedbackReplaceDlg) public: - CFeedbackReplaceDlg(const CFileInfo* pfiSrcFile, const CFileInfo* pfiDstFile, CWnd* pParent = NULL); // standard constructor + CFeedbackReplaceDlg(const CFileInfoPtr& spSrcFile, const CFileInfoPtr& spDstFile, CWnd* pParent = NULL); // standard constructor virtual ~CFeedbackReplaceDlg(); virtual BOOL OnInitDialog(); @@ -38,16 +36,18 @@ void RefreshImages(); DECLARE_MESSAGE_MAP() -public: + + public: CStatic m_ctlSrcIcon; CStatic m_ctlDstIcon; CStatic m_ctlSrcInfo; CStatic m_ctlDstInfo; BOOL m_bAllItems; protected: - const CFileInfo* m_pfiSrcFile; - const CFileInfo* m_pfiDstFile; + const CFileInfoPtr m_spSrcFile; + const CFileInfoPtr m_spDstFile; + public: afx_msg void OnBnClickedReplaceButton(); afx_msg void OnBnClickedCopyRestButton(); Index: src/ch/FileFilter.cpp =================================================================== diff -u -N -r5057e08b0cc064972abeb94a488e5f12d9db14a0 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FileFilter.cpp (.../FileFilter.cpp) (revision 5057e08b0cc064972abeb94a488e5f12d9db14a0) +++ src/ch/FileFilter.cpp (.../FileFilter.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2001-2008 by J�zef Starosczyk * + * Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -184,15 +184,15 @@ delete [] pszData; } -bool CFileFilter::Match(const CFileInfo& rInfo) const +bool CFileFilter::Match(const CFileInfoPtr& spInfo) const { // check by mask if(m_bUseMask) { bool bRes=false; for(std::vector::const_iterator iterMask = m_astrMask.begin(); iterMask != m_astrMask.end(); ++iterMask) { - if(MatchMask(*iterMask, rInfo.GetFileName())) + if(MatchMask(*iterMask, spInfo->GetFileName())) bRes = true; } if(!bRes) @@ -204,7 +204,7 @@ { for(std::vector::const_iterator iterExcludeMask = m_astrExcludeMask.begin(); iterExcludeMask != m_astrExcludeMask.end(); ++iterExcludeMask) { - if(MatchMask(*iterExcludeMask, rInfo.GetFileName())) + if(MatchMask(*iterExcludeMask, spInfo->GetFileName())) return false; } } @@ -215,23 +215,23 @@ switch (m_iSizeType1) { case LT: - if (m_ullSize1 <= rInfo.GetLength64()) + if (m_ullSize1 <= spInfo->GetLength64()) return false; break; case LE: - if (m_ullSize1 < rInfo.GetLength64()) + if (m_ullSize1 < spInfo->GetLength64()) return false; break; case EQ: - if (m_ullSize1 != rInfo.GetLength64()) + if (m_ullSize1 != spInfo->GetLength64()) return false; break; case GE: - if (m_ullSize1 > rInfo.GetLength64()) + if (m_ullSize1 > spInfo->GetLength64()) return false; break; case GT: - if (m_ullSize1 >= rInfo.GetLength64()) + if (m_ullSize1 >= spInfo->GetLength64()) return false; break; } @@ -242,23 +242,23 @@ switch (m_iSizeType2) { case LT: - if (m_ullSize2 <= rInfo.GetLength64()) + if (m_ullSize2 <= spInfo->GetLength64()) return false; break; case LE: - if (m_ullSize2 < rInfo.GetLength64()) + if (m_ullSize2 < spInfo->GetLength64()) return false; break; case EQ: - if (m_ullSize2 != rInfo.GetLength64()) + if (m_ullSize2 != spInfo->GetLength64()) return false; break; case GE: - if (m_ullSize2 > rInfo.GetLength64()) + if (m_ullSize2 > spInfo->GetLength64()) return false; break; case GT: - if (m_ullSize2 >= rInfo.GetLength64()) + if (m_ullSize2 >= spInfo->GetLength64()) return false; break; } @@ -272,13 +272,13 @@ switch (m_iDateType) { case DATE_CREATED: - tm=rInfo.GetCreationTime(); + tm=spInfo->GetCreationTime(); break; case DATE_MODIFIED: - tm=rInfo.GetLastWriteTime(); + tm=spInfo->GetLastWriteTime(); break; case DATE_LASTACCESSED: - tm=rInfo.GetLastAccessTime(); + tm=spInfo->GetLastAccessTime(); break; } @@ -367,15 +367,15 @@ // attributes if (m_bUseAttributes) { - if ( (m_iArchive == 1 && !rInfo.IsArchived()) || (m_iArchive == 0 && rInfo.IsArchived())) + if ( (m_iArchive == 1 && !spInfo->IsArchived()) || (m_iArchive == 0 && spInfo->IsArchived())) return false; - if ( (m_iReadOnly == 1 && !rInfo.IsReadOnly()) || (m_iReadOnly == 0 && rInfo.IsReadOnly())) + if ( (m_iReadOnly == 1 && !spInfo->IsReadOnly()) || (m_iReadOnly == 0 && spInfo->IsReadOnly())) return false; - if ( (m_iHidden == 1 && !rInfo.IsHidden()) || (m_iHidden == 0 && rInfo.IsHidden())) + if ( (m_iHidden == 1 && !spInfo->IsHidden()) || (m_iHidden == 0 && spInfo->IsHidden())) return false; - if ( (m_iSystem == 1 && !rInfo.IsSystem()) || (m_iSystem == 0 && rInfo.IsSystem())) + if ( (m_iSystem == 1 && !spInfo->IsSystem()) || (m_iSystem == 0 && spInfo->IsSystem())) return false; - if ( (m_iDirectory == 1 && !rInfo.IsDirectory()) || (m_iDirectory == 0 && rInfo.IsDirectory())) + if ( (m_iDirectory == 1 && !spInfo->IsDirectory()) || (m_iDirectory == 0 && spInfo->IsDirectory())) return false; } @@ -452,15 +452,15 @@ return *this; } -bool CFiltersArray::Match(const CFileInfo& rInfo) const +bool CFiltersArray::Match(const CFileInfoPtr& spInfo) const { if(m_vFilters.empty()) return true; // if only one of the filters matches - return true for(std::vector::const_iterator iterFilter = m_vFilters.begin(); iterFilter != m_vFilters.end(); iterFilter++) { - if((*iterFilter).Match(rInfo)) + if((*iterFilter).Match(spInfo)) return true; } Index: src/ch/FileFilter.h =================================================================== diff -u -N -r5057e08b0cc064972abeb94a488e5f12d9db14a0 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FileFilter.h (.../FileFilter.h) (revision 5057e08b0cc064972abeb94a488e5f12d9db14a0) +++ src/ch/FileFilter.h (.../FileFilter.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** - * Copyright (C) 2001-2008 by J�zef Starosczyk * + * Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -31,16 +31,14 @@ #define DATE_MODIFIED 1 #define DATE_LASTACCESSED 2 -class CFileInfo; - class CFileFilter { public: CFileFilter(); CFileFilter(const CFileFilter& rFilter); CFileFilter& operator=(const CFileFilter& rFilter); - bool Match(const CFileInfo& rInfo) const; + bool Match(const CFileInfoPtr& spInfo) const; CString& GetCombinedMask(CString& pMask) const; void SetCombinedMask(const CString& pMask); @@ -140,7 +138,7 @@ ~CFiltersArray() {} CFiltersArray& operator=(const CFiltersArray& rSrc); - bool Match(const CFileInfo& rInfo) const; + bool Match(const CFileInfoPtr& spInfo) const; template void serialize(Archive& ar, unsigned int /*uiVersion*/) Index: src/ch/FileInfo.cpp =================================================================== diff -u -N -r5057e08b0cc064972abeb94a488e5f12d9db14a0 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision 5057e08b0cc064972abeb94a488e5f12d9db14a0) +++ src/ch/FileInfo.cpp (.../FileInfo.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * +* Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -41,14 +41,6 @@ #endif ////////////////////////////////////////////////////////////////////////////// -// CClipboardArray - -CClipboardArray::~CClipboardArray() -{ - RemoveAll(); -} - -////////////////////////////////////////////////////////////////////////////// // CClipboardEntry CClipboardEntry::CClipboardEntry() : @@ -68,46 +60,13 @@ { } -CClipboardEntryPtr CClipboardArray::GetAt(size_t iPos) -{ - return m_vEntries.at(iPos); -} - -void CClipboardArray::SetAt(size_t nIndex, const CClipboardEntryPtr& spEntry) -{ - m_vEntries[nIndex] = spEntry; -} - -void CClipboardArray::Add(const CClipboardEntryPtr& spEntry) -{ - m_vEntries.push_back(spEntry); -} - -void CClipboardArray::RemoveAt(size_t nIndex, size_t nCount) -{ - m_vEntries.erase(m_vEntries.begin() + nIndex, m_vEntries.begin() + nIndex + nCount); -} - -void CClipboardArray::RemoveAll() -{ - m_vEntries.clear(); -} - -size_t CClipboardArray::GetSize() const -{ - return m_vEntries.size(); -} - -///////////////////////////////////////////////////////////////////////////// -// CClipboardEntry - void CClipboardEntry::SetPath(const CString& strPath) { - m_strPath=strPath; // guaranteed without ending '\\' - if (m_strPath.Right(1) == _T('\\')) - m_strPath=m_strPath.Left(m_strPath.GetLength()-1); - GetDriveData(m_strPath, &m_iDriveNumber, &m_uiDriveType); + + m_strPath = strPath; // guaranteed without ending '\\' + if(m_strPath.Right(1) == _T('\\')) + m_strPath = m_strPath.Left(m_strPath.GetLength() - 1); } void CClipboardEntry::CalcBufferIndex(const CDestPath& dpDestPath) @@ -144,6 +103,91 @@ return m_vDstPaths.at(stIndex); } +////////////////////////////////////////////////////////////////////////////// +// CClipboardArray + +CClipboardArray::~CClipboardArray() +{ + RemoveAll(); +} + +CClipboardEntryPtr CClipboardArray::GetAt(size_t stPos) const +{ + boost::shared_lock lock(m_lock); + + if(stPos >= m_vEntries.size()) + THROW(_T("Out of range"), 0, 0, 0); + + return m_vEntries.at(stPos); +} + +void CClipboardArray::SetAt(size_t stIndex, const CClipboardEntryPtr& spEntry) +{ + if(!spEntry) + THROW(_T("Invalid argument"), 0, 0, 0); + + boost::unique_lock lock(m_lock); + + if(stIndex >= m_vEntries.size()) + THROW(_T("Out of range"), 0, 0, 0); + + m_vEntries[stIndex] = spEntry; +} + +void CClipboardArray::Add(const CClipboardEntryPtr& spEntry) +{ + boost::unique_lock lock(m_lock); + m_vEntries.push_back(spEntry); +} + +void CClipboardArray::RemoveAt(size_t nIndex, size_t nCount) +{ + boost::unique_lock lock(m_lock); + m_vEntries.erase(m_vEntries.begin() + nIndex, m_vEntries.begin() + nIndex + nCount); +} + +void CClipboardArray::RemoveAll() +{ + boost::unique_lock lock(m_lock); + m_vEntries.clear(); +} + +size_t CClipboardArray::GetSize() const +{ + boost::shared_lock lock(m_lock); + return m_vEntries.size(); +} + +int CClipboardArray::ReplacePathsPrefix(CString strOld, CString strNew) +{ + // small chars to make comparing case insensitive + strOld.MakeLower(); + + CString strText; + int iOffset = 0; + int iCount = 0; + + boost::unique_lock lock(m_lock); + + BOOST_FOREACH(CClipboardEntryPtr& spEntry, m_vEntries) + { + strText = spEntry->GetPath(); + strText.MakeLower(); + iOffset = strText.Find(strOld, 0); + if(iOffset != -1) + { + // found + strText = spEntry->GetPath(); + strText = strText.Left(iOffset) + strNew + strText.Mid(iOffset + strOld.GetLength()); + spEntry->SetPath(strText); + + ++iCount; + } + } + + return iCount; +} + ////////////////////////////////////////////////////////////////////// // Construction/Destruction ////////////////////////////////////////////////////////////////////// @@ -251,7 +295,7 @@ // if proper index has been passed - reduce the path if(m_pClipboard && stSrcIndex >= 0) - m_strFilePath=m_strFilePath.Mid(m_pClipboard->GetAt(stSrcIndex)->GetPath().GetLength()); // wytnij �cie�k� z clipboarda + m_strFilePath=m_strFilePath.Mid(m_pClipboard->GetAt(stSrcIndex)->GetPath().GetLength()); // cut path from clipboard m_stSrcIndex = stSrcIndex; m_dwAttributes = pwfd->dwFileAttributes; @@ -293,7 +337,7 @@ } } -CString CFileInfo::GetFileDrive(void) const +CString CFileInfo::GetFileDrive() const { ASSERT(m_pClipboard); @@ -325,7 +369,7 @@ { ASSERT(m_pClipboard); - if (m_stSrcIndex != std::numeric_limits::max()) + if(m_stSrcIndex != std::numeric_limits::max()) { // read data contained in CClipboardEntry return m_pClipboard->GetAt(m_stSrcIndex)->GetDriveType(); @@ -339,17 +383,17 @@ } } -CString CFileInfo::GetFileDir(void) const +CString CFileInfo::GetFileDir() const { ASSERT(m_pClipboard); CString strPath=(m_stSrcIndex != std::numeric_limits::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath()+m_strFilePath : m_strFilePath; TCHAR szDir[_MAX_DIR]; - _tsplitpath(strPath, NULL, szDir,NULL, NULL); + _tsplitpath(strPath, NULL, szDir, NULL, NULL); return CString(szDir); } -CString CFileInfo::GetFileTitle(void) const +CString CFileInfo::GetFileTitle() const { ASSERT(m_pClipboard); @@ -359,7 +403,7 @@ return CString(szName); } -CString CFileInfo::GetFileExt(void) const +CString CFileInfo::GetFileExt() const { ASSERT(m_pClipboard); @@ -369,7 +413,7 @@ return CString(szExt); } -CString CFileInfo::GetFileRoot(void) const +CString CFileInfo::GetFileRoot() const { ASSERT(m_pClipboard); @@ -381,7 +425,7 @@ return CString(szDrive)+szDir; } -CString CFileInfo::GetFileName(void) const +CString CFileInfo::GetFileName() const { ASSERT(m_pClipboard || m_stSrcIndex == std::numeric_limits::max()); @@ -452,9 +496,9 @@ if(m_stSrcIndex != std::numeric_limits::max()) { ASSERT(m_pClipboard); - strPath+=m_pClipboard->GetAt(m_stSrcIndex)->GetPath(); + strPath += m_pClipboard->GetAt(m_stSrcIndex)->GetPath(); } - strPath+=m_strFilePath; + strPath += m_strFilePath; return strPath; } @@ -469,90 +513,43 @@ /////////////////////////////////////////////////////////////////////// // Array - -void CFileInfoArray::AddDir(CString strDirName, const CFiltersArray* pFilters, size_t stSrcIndex, - const bool bRecurse, const bool bIncludeDirs, - const volatile bool* pbAbort) -{ - WIN32_FIND_DATA wfd; - CString strText; - - // init CFileInfo - CFileInfo finf; - finf.SetClipboard(&m_rClipboard); // this is the link table (CClipboardArray) - - // append '\\' at the end of path if needed - if (strDirName.Right(1) != _T("\\")) - strDirName+=_T("\\"); - - strText = strDirName + _T("*"); - // Iterate through dirs & files - HANDLE hFind = FindFirstFile(strText, &wfd); - if (hFind != INVALID_HANDLE_VALUE) - { - do - { - if ( !(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ) - { - finf.Create(&wfd, strDirName, stSrcIndex); - if (pFilters->Match(finf)) - m_vFiles.push_back(finf); - } - else if ( _tcscmp(wfd.cFileName, _T(".")) != 0 && _tcscmp(wfd.cFileName, _T("..")) != 0) - { - if (bIncludeDirs) - { - // Add directory itself - finf.Create(&wfd, strDirName, stSrcIndex); - m_vFiles.push_back(finf); - } - if (bRecurse) - { - strText = strDirName + wfd.cFileName+_T("\\"); - // Recurse Dirs - AddDir(strText, pFilters, stSrcIndex, bRecurse, bIncludeDirs, pbAbort); - } - } - } - while (((pbAbort == NULL) || (!*pbAbort)) && (FindNextFile(hFind, &wfd))); - - FindClose(hFind); - } -} - -void CFileInfoArray::AddFile(CString strFilePath, size_t stSrcIndex) +void CFileInfoArray::AddFileInfo(const CFileInfoPtr& spFileInfo) { - CFileInfo finf; - - // CUSTOMIZATION3 - cut '\\' at the end of strFilePath, set relative path - if(strFilePath.Right(1) == _T("\\")) - strFilePath = strFilePath.Left(strFilePath.GetLength()-1); - - finf.Create(strFilePath, stSrcIndex); - return m_vFiles.push_back(finf); + boost::unique_lock lock(m_lock); + m_vFiles.push_back(spFileInfo); } -void CFileInfoArray::AddFileInfo(const CFileInfo& rFileInfo) +size_t CFileInfoArray::GetSize() const { - m_vFiles.push_back(rFileInfo); + boost::shared_lock lock(m_lock); + return m_vFiles.size(); } -void CFileInfoArray::AppendArray(const CFileInfoArray& arrFiles) +CFileInfoPtr CFileInfoArray::GetAt(size_t stIndex) const { - m_vFiles.insert(m_vFiles.end(), arrFiles.m_vFiles.begin(), arrFiles.m_vFiles.end()); + boost::shared_lock lock(m_lock); + + if(stIndex >= m_vFiles.size()) + THROW(_T("Out of bounds"), 0, 0, 0); + + return m_vFiles.at(stIndex); } -size_t CFileInfoArray::GetSize() const +CFileInfo CFileInfoArray::GetCopyAt(size_t stIndex) const { - return m_vFiles.size(); -} + boost::shared_lock lock(m_lock); + + if(stIndex >= m_vFiles.size()) + THROW(_T("Out of bounds"), 0, 0, 0); + const CFileInfoPtr& spInfo = m_vFiles.at(stIndex); + if(!spInfo) + THROW(_T("Invalid pointer"), 0, 0, 0); -CFileInfo& CFileInfoArray::GetAt(size_t stIndex) -{ - return m_vFiles.at(stIndex); + return *spInfo; } void CFileInfoArray::Clear() { + boost::unique_lock lock(m_lock); m_vFiles.clear(); } Index: src/ch/FileInfo.h =================================================================== diff -u -N -r5057e08b0cc064972abeb94a488e5f12d9db14a0 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FileInfo.h (.../FileInfo.h) (revision 5057e08b0cc064972abeb94a488e5f12d9db14a0) +++ src/ch/FileInfo.h (.../FileInfo.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * +* Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -30,7 +30,7 @@ extern void GetDriveData(LPCTSTR lpszPath, int *piDrvNum, UINT *puiDrvType); // CFileInfo flags -// flag stating that file has been processed (used to determine if file can be deleted at the end of copying) +// flag stating that file has been processed (used to determine if file can be deleted at the end of copying) #define FIF_PROCESSED 0x00000001 class CFiltersArray; @@ -96,13 +96,14 @@ ~CClipboardArray(); template - void Store(Archive& ar, unsigned int /*uiVersion*/, bool bData) + void Store(Archive& ar, unsigned int /*uiVersion*/, bool bData) const { + boost::shared_lock lock(m_lock); // write data size_t stCount = m_vEntries.size(); ar << stCount; - BOOST_FOREACH(CClipboardEntryPtr& spEntry, m_vEntries) + BOOST_FOREACH(const CClipboardEntryPtr& spEntry, m_vEntries) { spEntry->Serialize(ar, 0, bData); } @@ -114,6 +115,8 @@ size_t stCount; ar >> stCount; + boost::unique_lock lock(m_lock); + if(!bData && m_vEntries.size() != stCount) THROW(_T("Count of entries with data differs from the count of state entries"), 0, 0, 0); @@ -137,16 +140,19 @@ } } - CClipboardEntryPtr GetAt(size_t iPos); + CClipboardEntryPtr GetAt(size_t iPos) const; size_t GetSize() const; void Add(const CClipboardEntryPtr& pEntry); void SetAt(size_t nIndex, const CClipboardEntryPtr& pEntry); void RemoveAt(size_t nIndex, size_t nCount = 1); void RemoveAll(); + int ReplacePathsPrefix(CString strOld, CString strNew); + protected: std::vector m_vEntries; + mutable boost::shared_mutex m_lock; }; class CFileInfo @@ -186,15 +192,15 @@ const FILETIME& GetLastWriteTime() const { return m_ftLastWrite; }; /* Get File attributes info (equivalent to CFindFile members) */ - DWORD GetAttributes(void) const { return m_dwAttributes; } - bool IsDirectory(void) const { return (m_dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } - bool IsArchived(void) const { return (m_dwAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0; } - bool IsReadOnly(void) const { return (m_dwAttributes & FILE_ATTRIBUTE_READONLY) != 0; } - bool IsCompressed(void) const { return (m_dwAttributes & FILE_ATTRIBUTE_COMPRESSED) != 0; } - bool IsSystem(void) const { return (m_dwAttributes & FILE_ATTRIBUTE_SYSTEM) != 0; } - bool IsHidden(void) const { return (m_dwAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; } - bool IsTemporary(void) const { return (m_dwAttributes & FILE_ATTRIBUTE_TEMPORARY) != 0; } - bool IsNormal(void) const { return m_dwAttributes == 0; } + DWORD GetAttributes() const { return m_dwAttributes; } + bool IsDirectory() const { return (m_dwAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0; } + bool IsArchived() const { return (m_dwAttributes & FILE_ATTRIBUTE_ARCHIVE) != 0; } + bool IsReadOnly() const { return (m_dwAttributes & FILE_ATTRIBUTE_READONLY) != 0; } + bool IsCompressed() const { return (m_dwAttributes & FILE_ATTRIBUTE_COMPRESSED) != 0; } + bool IsSystem() const { return (m_dwAttributes & FILE_ATTRIBUTE_SYSTEM) != 0; } + bool IsHidden() const { return (m_dwAttributes & FILE_ATTRIBUTE_HIDDEN) != 0; } + bool IsTemporary() const { return (m_dwAttributes & FILE_ATTRIBUTE_TEMPORARY) != 0; } + bool IsNormal() const { return m_dwAttributes == 0; } uint_t GetFlags() const { return m_uiFlags; } void SetFlags(uint_t uiFlags, uint_t uiMask = 0xffffffff) { m_uiFlags = (m_uiFlags & ~(uiFlags & uiMask)) | (uiFlags & uiMask); } @@ -240,33 +246,27 @@ FILETIME m_ftLastWrite; uint_t m_uiFlags; + // ptrs to elements providing data CClipboardArray* m_pClipboard; -}; +}; -/** -* @class Allows to retrieve s from files/directories in a directory -*/ +typedef boost::shared_ptr CFileInfoPtr; + class CFileInfoArray { public: CFileInfoArray(CClipboardArray& A_rClipboardArray) : - m_rClipboard(A_rClipboardArray) + m_rClipboard(A_rClipboardArray) { } - void AddDir(CString strDirName, const CFiltersArray* pFilters, size_t stSrcIndex, - const bool bRecurse, const bool bIncludeDirs, const volatile bool* pbAbort=NULL); + void AddFileInfo(const CFileInfoPtr& spFileInfo); - void AddFile(CString strFilePath, size_t stSrcIndex); - - void AddFileInfo(const CFileInfo& rFileInfo); - - void AppendArray(const CFileInfoArray& arrFiles); - size_t GetSize() const; - CFileInfo& GetAt(size_t stIndex); - + CFileInfoPtr GetAt(size_t stIndex) const; + CFileInfo GetCopyAt(size_t stIndex) const; + void Clear(); // store/restore @@ -275,15 +275,15 @@ { size_t stCount = m_vFiles.size(); ar << stCount; - for(std::vector::iterator iterFile = m_vFiles.begin(); iterFile != m_vFiles.end(); ++iterFile) + for(std::vector::iterator iterFile = m_vFiles.begin(); iterFile != m_vFiles.end(); ++iterFile) { if(bOnlyFlags) { - uint_t uiFlags = (*iterFile).GetFlags(); + uint_t uiFlags = (*iterFile)->GetFlags(); ar << uiFlags; } else - ar << (*iterFile); + ar << *(*iterFile); } } @@ -301,28 +301,31 @@ else if(stCount != m_vFiles.size()) THROW(_T("Invalid count of flags received"), 0, 0, 0); - CFileInfo fi; - fi.SetClipboard(&m_rClipboard); + CFileInfoPtr spFileInfo; + uint_t uiFlags = 0; for(size_t stIndex = 0; stIndex < stCount; stIndex++) { if(bOnlyFlags) { - CFileInfo& rInfo = m_vFiles.at(stIndex); + CFileInfoPtr& spFileInfo = m_vFiles.at(stIndex); ar >> uiFlags; - rInfo.SetFlags(uiFlags); + spFileInfo->SetFlags(uiFlags); } else { - ar >> fi; - m_vFiles.push_back(fi); + spFileInfo.reset(new CFileInfo); + spFileInfo->SetClipboard(&m_rClipboard); + ar >> *spFileInfo; + m_vFiles.push_back(spFileInfo); } } } protected: CClipboardArray& m_rClipboard; - std::vector m_vFiles; + std::vector m_vFiles; + mutable boost::shared_mutex m_lock; }; #endif Index: src/ch/FilterDlg.cpp =================================================================== diff -u -N -raa6bff57279b9f9cfc276e9adab2763e2900878d -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FilterDlg.cpp (.../FilterDlg.cpp) (revision aa6bff57279b9f9cfc276e9adab2763e2900878d) +++ src/ch/FilterDlg.cpp (.../FilterDlg.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -17,6 +17,8 @@ * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * ***************************************************************************/ #include "stdafx.h" +#include "FileInfo.h" +#include "FileFilter.h" #include "ch.h" #include "FilterDlg.h" Index: src/ch/FilterDlg.h =================================================================== diff -u -N -r449a5b399ab21ca0d06050b47b264f2f704af966 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/FilterDlg.h (.../FilterDlg.h) (revision 449a5b399ab21ca0d06050b47b264f2f704af966) +++ src/ch/FilterDlg.h (.../FilterDlg.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -19,8 +19,6 @@ #ifndef __FILTERDLG_H__ #define __FILTERDLG_H__ -#include "FileFilter.h" - ///////////////////////////////////////////////////////////////////////////// // CFilterDlg dialog Index: src/ch/MainWnd.cpp =================================================================== diff -u -N -rf703b71b8c856e2538283555e9fdbc84918677c3 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision f703b71b8c856e2538283555e9fdbc84918677c3) +++ src/ch/MainWnd.cpp (.../MainWnd.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * +* Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -402,22 +402,7 @@ case 8743: { // wait state handling section - CTaskPtr spTask; - if (GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS) == 0 || m_tasks.GetOperationsPending() < (UINT)GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS)) - { - for(size_t stIndex = 0; stIndex < m_tasks.GetSize(); ++stIndex) - { - spTask = m_tasks.GetAt(stIndex); - // turn on some thread - find something with wait state - if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING && (GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS) == 0 || m_tasks.GetOperationsPending() < (UINT)GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS))) - { - TRACE("Enabling task %ld\n", stIndex); - spTask->SetContinueFlag(true); - spTask->IncreaseOperationsPending(); - spTask->SetStatus(0, ST_WAITING); // turn off wait state - } - } - } + m_tasks.ResumeWaitingTasks((size_t)GetConfig().get_signed_num(PP_CMLIMITMAXOPERATIONS)); break; } } Index: src/ch/MiniViewDlg.cpp =================================================================== diff -u -N -rf703b71b8c856e2538283555e9fdbc84918677c3 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/MiniViewDlg.cpp (.../MiniViewDlg.cpp) (revision f703b71b8c856e2538283555e9fdbc84918677c3) +++ src/ch/MiniViewDlg.cpp (.../MiniViewDlg.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * +* Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -200,7 +200,7 @@ else pItem->m_crColor=RGB(0, 255, 0); - pItem->m_strText=dd.m_fi.GetFileName(); + pItem->m_strText = dd.m_spFileInfo->GetFileName(); pItem->m_uiPos=dd.m_nPercent; pItem->m_spTask = spTask; } @@ -712,7 +712,7 @@ if (m_iIndex != -1) { - // popraw wsp�rz�dne punktu + // popraw wsp��rz�dne punktu point.x+=GetSystemMetrics(SM_CYDLGFRAME); point.y+=GetSystemMetrics(SM_CYSMCAPTION)+GetSystemMetrics(SM_CYDLGFRAME); if (m_bdButtons[m_iIndex].rcButton.PtInRect(point)) Index: src/ch/StatusDlg.cpp =================================================================== diff -u -N -rf703b71b8c856e2538283555e9fdbc84918677c3 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/StatusDlg.cpp (.../StatusDlg.cpp) (revision f703b71b8c856e2538283555e9fdbc84918677c3) +++ src/ch/StatusDlg.cpp (.../StatusDlg.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * +* Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -250,9 +250,9 @@ m_ctlStatusList.InsertItem(&lvi); // status subitem - lvi.mask=LVIF_TEXT; // zmie� mask� + lvi.mask=LVIF_TEXT; lvi.iSubItem=1; - m_strTemp=td.m_fi.GetFileName(); + m_strTemp=td.m_spFileInfo->GetFileName(); lvi.pszText=m_strTemp.GetBuffer(0); m_strTemp.ReleaseBuffer(); lvi.cchTextMax=lstrlen(lvi.pszText); @@ -279,7 +279,7 @@ { // data that can be changed by a thread GetDlgItem(IDC_OPERATION_STATIC)->SetWindowText(td.m_szStatusText); // operation - GetDlgItem(IDC_SOURCE_STATIC)->SetWindowText(td.m_fi.GetFullFilePath()); // src object + GetDlgItem(IDC_SOURCE_STATIC)->SetWindowText(td.m_spFileInfo->GetFullFilePath()); // src object // error message if ( (td.m_uiStatus & ST_WORKING_MASK) == ST_ERROR ) Index: src/ch/Stdafx.h =================================================================== diff -u -N -r9352ed0c4fe447a36bc728640c307be6d41455fd -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/Stdafx.h (.../Stdafx.h) (revision 9352ed0c4fe447a36bc728640c307be6d41455fd) +++ src/ch/Stdafx.h (.../Stdafx.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -35,6 +35,8 @@ #include #include +#include +#include #pragma warning (disable: 4711) #include "debug.h" Index: src/ch/task.cpp =================================================================== diff -u -N -rf703b71b8c856e2538283555e9fdbc84918677c3 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/task.cpp (.../task.cpp) (revision f703b71b8c856e2538283555e9fdbc84918677c3) +++ src/ch/task.cpp (.../task.cpp) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * +* Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -34,11 +34,10 @@ /////////////////////////////////////////////////////////////////////// // CProcessingException -CProcessingException::CProcessingException(int iType, CTask* pTask, UINT uiFmtID, DWORD dwError, ...) +CProcessingException::CProcessingException(int iType, UINT uiFmtID, DWORD dwError, ...) { // std values m_iType=iType; - m_pTask=pTask; m_dwError=dwError; // format some text @@ -52,11 +51,10 @@ va_end(marker); } -CProcessingException::CProcessingException(int iType, CTask* pTask, DWORD dwError, const tchar_t* pszDesc) +CProcessingException::CProcessingException(int iType, DWORD dwError, const tchar_t* pszDesc) { // std values m_iType=iType; - m_pTask=pTask; m_dwError=dwError; // format some text @@ -80,7 +78,7 @@ m_pnTasksAll(pCreateData->pTasksAll), m_bKill(false), m_bKilled(true), - m_pcs(pCreateData->pcs), + m_pLock(pCreateData->pLock), m_lTimeElapsed(0), m_lLastTime(-1), m_puiOperationsPending(pCreateData->puiOperationsPending), @@ -93,7 +91,7 @@ m_bContinue(false), m_bSaved(false), m_lOsError(0), - m_stSessionUniqueID(stSessionUniqueID) + m_stSessionUniqueID(stSessionUniqueID) { BOOST_ASSERT(piFeedbackHandler); @@ -117,202 +115,186 @@ // m_clipboard void CTask::AddClipboardData(const CClipboardEntryPtr& spEntry) { - m_cs.Lock(); m_clipboard.Add(spEntry); - m_cs.Unlock(); } CClipboardEntryPtr CTask::GetClipboardData(size_t stIndex) { - m_cs.Lock(); - CClipboardEntryPtr spEntry = m_clipboard.GetAt(stIndex); - m_cs.Unlock(); - - return spEntry; + return m_clipboard.GetAt(stIndex); } size_t CTask::GetClipboardDataSize() { - m_cs.Lock(); - size_t rv=m_clipboard.GetSize(); - m_cs.Unlock(); - - return rv; + return m_clipboard.GetSize(); } int CTask::ReplaceClipboardStrings(CString strOld, CString strNew) { - // small chars to make comparing case insensitive - strOld.MakeLower(); - - CString strText; - int iOffset; - int iCount=0; - m_cs.Lock(); - for (size_t stIndex = 0; stIndex < m_clipboard.GetSize(); ++stIndex) - { - CClipboardEntryPtr spEntry = m_clipboard.GetAt(stIndex); - strText = spEntry->GetPath(); - strText.MakeLower(); - iOffset=strText.Find(strOld, 0); - if (iOffset != -1) - { - // found - strText = spEntry->GetPath(); - strText = strText.Left(iOffset)+strNew+strText.Mid(iOffset+strOld.GetLength()); - spEntry->SetPath(strText); - iCount++; - } - } - m_cs.Unlock(); - - return iCount; + return m_clipboard.ReplacePathsPrefix(strOld, strNew); } // m_files -int CTask::FilesAddDir(const CString strDirName, const CFiltersArray* pFilters, size_t stSrcIndex, - const bool bRecurse, const bool bIncludeDirs) +int CTask::FilesAddDir(CString strDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs) { - // this uses much of memory, but resolves problem critical section hungs and m_bKill - CFileInfoArray fa(m_clipboard); + WIN32_FIND_DATA wfd; + CString strText; - fa.AddDir(strDirName, pFilters, stSrcIndex, bRecurse, bIncludeDirs, &m_bKill); + // append '\\' at the end of path if needed + if(strDirName.Right(1) != _T("\\")) + strDirName += _T("\\"); - m_cs.Lock(); + strText = strDirName + _T("*"); - m_files.AppendArray(fa); + // Iterate through dirs & files + HANDLE hFind = FindFirstFile(strText, &wfd); + if(hFind != INVALID_HANDLE_VALUE) + { + do + { + if(!(wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)) + { + CFileInfoPtr spFileInfo(boost::make_shared()); + spFileInfo->SetClipboard(&m_clipboard); // this is the link table (CClipboardArray) + + spFileInfo->Create(&wfd, strDirName, stSrcIndex); + if(m_afFilters.Match(spFileInfo)) + m_files.AddFileInfo(spFileInfo); + } + else if(_tcscmp(wfd.cFileName, _T(".")) != 0 && _tcscmp(wfd.cFileName, _T("..")) != 0) + { + if(bIncludeDirs) + { + CFileInfoPtr spFileInfo(boost::make_shared()); + spFileInfo->SetClipboard(&m_clipboard); // this is the link table (CClipboardArray) - m_cs.Unlock(); + // Add directory itself + spFileInfo->Create(&wfd, strDirName, stSrcIndex); + m_files.AddFileInfo(spFileInfo); + } + if(bRecurse) + { + strText = strDirName + wfd.cFileName + _T("\\"); + // Recurse Dirs + FilesAddDir(strText, stSrcIndex, bRecurse, bIncludeDirs); + } + } + } + while(!m_bKill && (FindNextFile(hFind, &wfd))); + + FindClose(hFind); + } return 0; } -void CTask::FilesAdd(CFileInfo fi) +void CTask::FilesAdd(const CFileInfoPtr& spFileInfo) { - m_cs.Lock(); - if (fi.IsDirectory() || m_afFilters.Match(fi)) - m_files.AddFileInfo(fi); - m_cs.Unlock(); -} + if(spFileInfo->IsDirectory() || m_afFilters.Match(spFileInfo)) + m_files.AddFileInfo(spFileInfo); +} -CFileInfo CTask::FilesGetAt(size_t stIndex) +CFileInfoPtr CTask::FilesGetAt(size_t stIndex) { - m_cs.Lock(); - CFileInfo info = m_files.GetAt(stIndex); - m_cs.Unlock(); - - return info; + return m_files.GetAt(stIndex); } -CFileInfo& CTask::FilesGetAtCurrentIndex() +CFileInfoPtr CTask::FilesGetAtCurrentIndex() { - m_cs.Lock(); - CFileInfo& info = m_files.GetAt(m_stCurrentIndex); - m_cs.Unlock(); - return info; + size_t stCurrentIndex = 0; + + m_lock.lock_shared(); + stCurrentIndex = m_stCurrentIndex; + m_lock.unlock_shared(); + + return m_files.GetAt(m_stCurrentIndex); } void CTask::FilesRemoveAll() { - m_cs.Lock(); m_files.Clear(); - m_cs.Unlock(); } size_t CTask::FilesGetSize() { - m_cs.Lock(); - size_t nSize=m_files.GetSize(); - m_cs.Unlock(); - - return nSize; + return m_files.GetSize(); } // m_stCurrentIndex void CTask::IncreaseCurrentIndex() { - m_cs.Lock(); + boost::unique_lock lock(m_lock); ++m_stCurrentIndex; - m_cs.Unlock(); } size_t CTask::GetCurrentIndex() { - m_cs.Lock(); - size_t stIndex = m_stCurrentIndex; - m_cs.Unlock(); - - return stIndex; + boost::shared_lock lock(m_lock); + return m_stCurrentIndex; } void CTask::SetCurrentIndex(size_t stIndex) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_stCurrentIndex = stIndex; - m_cs.Unlock(); } // m_strDestPath - adds '\\' void CTask::SetDestPath(LPCTSTR lpszPath) { + boost::unique_lock lock(m_lock); m_dpDestPath.SetPath(lpszPath); } // guaranteed '\\' const CDestPath& CTask::GetDestPath() { + boost::shared_lock lock(m_lock); return m_dpDestPath; } int CTask::GetDestDriveNumber() { + boost::shared_lock lock(m_lock); return m_dpDestPath.GetDriveNumber(); } // m_nStatus void CTask::SetStatus(UINT nStatus, UINT nMask) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_nStatus &= ~nMask; m_nStatus |= nStatus; - m_cs.Unlock(); } UINT CTask::GetStatus(UINT nMask) { - m_cs.Lock(); - UINT nStatus=m_nStatus; - m_cs.Unlock(); - - return (nStatus & nMask); + boost::shared_lock lock(m_lock); + return m_nStatus & nMask; } // m_nBufferSize void CTask::SetBufferSizes(const BUFFERSIZES* bsSizes) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_bsSizes=*bsSizes; m_bSaved=false; - m_cs.Unlock(); } const BUFFERSIZES* CTask::GetBufferSizes() { - m_cs.Lock(); - const BUFFERSIZES* pbsSizes=&m_bsSizes; - m_cs.Unlock(); - - return pbsSizes; + boost::shared_lock lock(m_lock); + return &m_bsSizes; } int CTask::GetCurrentBufferIndex() { - int rv=0; - m_cs.Lock(); + int rv = 0; + + boost::shared_lock lock(m_lock); + size_t stSize = m_files.GetSize(); - if (stSize > 0 && m_stCurrentIndex != -1) - rv=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < stSize) ? m_stCurrentIndex : 0).GetBufferIndex(); - m_cs.Unlock(); + if(stSize > 0 && m_stCurrentIndex != -1) + rv = m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < stSize) ? m_stCurrentIndex : 0)->GetBufferIndex(); return rv; } @@ -321,254 +303,204 @@ // m_nPriority int CTask::GetPriority() { - m_cs.Lock(); - int nPriority=m_nPriority; - m_cs.Unlock(); - return nPriority; + boost::shared_lock lock(m_lock); + + return m_nPriority; } void CTask::SetPriority(int nPriority) { - m_cs.Lock(); - m_nPriority=nPriority; - m_bSaved=false; - if (m_pThread != NULL) + if(m_pThread != NULL) { - TRACE("Changing thread priority"); m_pThread->SuspendThread(); m_pThread->SetThreadPriority(nPriority); m_pThread->ResumeThread(); } - m_cs.Unlock(); + + boost::unique_lock lock(m_lock); + m_nPriority = nPriority; + m_bSaved = false; } // m_nProcessed void CTask::IncreaseProcessedSize(__int64 nSize) { - m_cs.Lock(); - m_nProcessed+=nSize; - m_cs.Unlock(); + boost::unique_lock lock(m_lock); + m_nProcessed += nSize; } void CTask::SetProcessedSize(__int64 nSize) { - m_cs.Lock(); - m_nProcessed=nSize; - m_cs.Unlock(); + boost::unique_lock lock(m_lock); + m_nProcessed = nSize; } __int64 CTask::GetProcessedSize() { - m_cs.Lock(); - __int64 nSize=m_nProcessed; - m_cs.Unlock(); - - return nSize; + boost::shared_lock lock(m_lock); + return m_nProcessed; } // m_nAll void CTask::SetAllSize(__int64 nSize) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_nAll=nSize; - m_cs.Unlock(); } __int64 CTask::GetAllSize() { - m_cs.Lock(); - __int64 nAll=m_nAll; - m_cs.Unlock(); - - return nAll; + boost::shared_lock lock(m_lock); + return m_nAll; } void CTask::CalcAllSize() { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_nAll=0; size_t nSize = m_files.GetSize(); for (size_t i = 0; i < nSize; i++) { - m_nAll += m_files.GetAt(i).GetLength64(); + m_nAll += m_files.GetAt(i)->GetLength64(); } - m_nAll*=m_ucCopies; - - m_cs.Unlock(); + m_nAll *= m_ucCopies; } void CTask::CalcProcessedSize() { - m_cs.Lock(); - m_nProcessed=0; + boost::unique_lock lock(m_lock); + m_nProcessed = 0; // count all from previous passes if(m_ucCopies) - m_nProcessed+=m_ucCurrentCopy*(m_nAll/m_ucCopies); + m_nProcessed += m_ucCurrentCopy*(m_nAll/m_ucCopies); else - m_nProcessed+=m_ucCurrentCopy*m_nAll; + m_nProcessed += m_ucCurrentCopy*m_nAll; for(size_t stIndex = 0; stIndex < m_stCurrentIndex; ++stIndex) { - m_nProcessed += m_files.GetAt(stIndex).GetLength64(); + m_nProcessed += m_files.GetAt(stIndex)->GetLength64(); } IncreaseProcessedTasksSize(m_nProcessed); - - m_cs.Unlock(); } // m_pnTasksProcessed void CTask::IncreaseProcessedTasksSize(__int64 nSize) { - // m_cs.Lock(); - m_pcs->Lock(); - (*m_pnTasksProcessed)+=nSize; - m_pcs->Unlock(); - // m_cs.Unlock(); + boost::unique_lock lock(*m_pLock); + (*m_pnTasksProcessed) += nSize; } void CTask::DecreaseProcessedTasksSize(__int64 nSize) { - // m_cs.Lock(); - m_pcs->Lock(); - (*m_pnTasksProcessed)-=nSize; - m_pcs->Unlock(); - // m_cs.Unlock(); + boost::unique_lock lock(*m_pLock); + (*m_pnTasksProcessed) -= nSize; } // m_pnTasksAll void CTask::IncreaseAllTasksSize(__int64 nSize) { - // m_cs.Lock(); - m_pcs->Lock(); - (*m_pnTasksAll)+=nSize; - m_pcs->Unlock(); - // m_cs.Unlock(); + boost::unique_lock lock(*m_pLock); + (*m_pnTasksAll) += nSize; } void CTask::DecreaseAllTasksSize(__int64 nSize) { - // m_cs.Lock(); - m_pcs->Lock(); - (*m_pnTasksAll)-=nSize; - m_pcs->Unlock(); - // m_cs.Unlock(); + boost::unique_lock lock(*m_pLock); + (*m_pnTasksAll) -= nSize; } // m_bKill -/*inline*/ void CTask::SetKillFlag(bool bKill) +void CTask::SetKillFlag(bool bKill) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_bKill=bKill; - m_cs.Unlock(); } bool CTask::GetKillFlag() { - m_cs.Lock(); - bool bKill=m_bKill; - m_cs.Unlock(); - - return bKill; + boost::shared_lock lock(m_lock); + return m_bKill; } // m_bKilled -/*inline*/ void CTask::SetKilledFlag(bool bKilled) +void CTask::SetKilledFlag(bool bKilled) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_bKilled=bKilled; - m_cs.Unlock(); } -/*inline*/ bool CTask::GetKilledFlag() +bool CTask::GetKilledFlag() { - m_cs.Lock(); - bool bKilled=m_bKilled; - m_cs.Unlock(); - - return bKilled; + boost::shared_lock lock(m_lock); + return m_bKilled; } // m_strUniqueName CString CTask::GetUniqueName() { - m_cs.Lock(); - CString name=m_strUniqueName; - m_cs.Unlock(); - - return name; + boost::shared_lock lock(m_lock); + return m_strUniqueName; } void CTask::Load(const CString& strPath, bool bData) { std::ifstream ifs(strPath, ios_base::in | ios_base::binary); boost::archive::binary_iarchive ar(ifs); - m_cs.Lock(); - try + boost::unique_lock lock(m_lock); + if(bData) { - if(bData) - { - m_clipboard.Load(ar, 0, bData); + m_clipboard.Load(ar, 0, bData); - m_files.Load(ar, 0, false); + m_files.Load(ar, 0, false); - ar >> m_dpDestPath; + ar >> m_dpDestPath; - ar >> m_strUniqueName; - ar >> m_afFilters; - ar >> m_ucCopies; - } - else - { - size_t stData = 0; - UINT uiData = 0; + ar >> m_strUniqueName; + ar >> m_afFilters; + ar >> m_ucCopies; + } + else + { + size_t stData = 0; + UINT uiData = 0; - ar >> stData; - m_stCurrentIndex = stData; - ar >> uiData; - m_nStatus = uiData; - ar >> m_lOsError; + ar >> stData; + m_stCurrentIndex = stData; + ar >> uiData; + m_nStatus = uiData; + ar >> m_lOsError; - ar >> m_strErrorDesc; + ar >> m_strErrorDesc; - ar >> m_bsSizes; - ar >> m_nPriority; - ar >> m_nAll; - ar >> m_lTimeElapsed; + ar >> m_bsSizes; + ar >> m_nPriority; + ar >> m_nAll; + ar >> m_lTimeElapsed; - ar >> m_nProcessed; - ar >> m_ucCurrentCopy; + ar >> m_nProcessed; + ar >> m_ucCurrentCopy; - m_clipboard.Load(ar, 0, bData); - m_files.Load(ar, 0, true); + m_clipboard.Load(ar, 0, bData); + m_files.Load(ar, 0, true); - ar >> m_bSaved; - } + ar >> m_bSaved; } - catch(...) - { - m_cs.Unlock(); - throw; - } - m_cs.Unlock(); } void CTask::Store(bool bData) { - m_cs.Lock(); + boost::shared_lock lock(m_lock); BOOST_ASSERT(!m_strTaskBasePath.empty()); if(m_strTaskBasePath.empty()) - { - m_cs.Unlock(); THROW(_t("Missing task path."), 0, 0, 0); - } - if (!bData && m_bSaved) + + if(!bData && m_bSaved) { - m_cs.Unlock(); TRACE("Saving locked - file not saved\n"); return; } @@ -580,73 +512,64 @@ m_bSaved = true; } - try - { - CString strPath = m_strTaskBasePath.c_str() + GetUniqueName() + (bData ? _T(".atd") : _T(".atp")); + CString strPath = m_strTaskBasePath.c_str() + GetUniqueNameNL() + (bData ? _T(".atd") : _T(".atp")); - std::ofstream ofs(strPath, ios_base::out | ios_base::binary); - boost::archive::binary_oarchive ar(ofs); + std::ofstream ofs(strPath, ios_base::out | ios_base::binary); + boost::archive::binary_oarchive ar(ofs); - if(bData) - { - m_clipboard.Store(ar, 0, bData); + if(bData) + { + m_clipboard.Store(ar, 0, bData); - if(GetStatus(ST_STEP_MASK) > ST_SEARCHING) - m_files.Store(ar, 0, false); - else - { - size_t st(0); - ar << st; - } - - ar << m_dpDestPath; - ar << m_strUniqueName; - ar << m_afFilters; - ar << m_ucCopies; - } + if(GetStatusNL(ST_STEP_MASK) > ST_SEARCHING) + m_files.Store(ar, 0, false); else { - size_t stCurrentIndex = m_stCurrentIndex; - ar << stCurrentIndex; - UINT uiStatus = (m_nStatus & ST_WRITE_MASK); - ar << uiStatus; - ar << m_lOsError; + size_t st(0); + ar << st; + } - ar << m_strErrorDesc; + ar << m_dpDestPath; + ar << m_strUniqueName; + ar << m_afFilters; + ar << m_ucCopies; + } + else + { + size_t stCurrentIndex = m_stCurrentIndex; + ar << stCurrentIndex; + UINT uiStatus = (m_nStatus & ST_WRITE_MASK); + ar << uiStatus; + ar << m_lOsError; - ar << m_bsSizes; - ar << m_nPriority; - ar << m_nAll; - ar << m_lTimeElapsed; + ar << m_strErrorDesc; - ar << m_nProcessed; - ar << m_ucCurrentCopy; + ar << m_bsSizes; + ar << m_nPriority; + ar << m_nAll; + ar << m_lTimeElapsed; - m_clipboard.Store(ar, 0, bData); - if(GetStatus(ST_STEP_MASK) > ST_SEARCHING) - m_files.Store(ar, 0, true); - else - { - size_t st(0); - ar << st; - } - ar << m_bSaved; + ar << m_nProcessed; + ar << m_ucCurrentCopy; + + m_clipboard.Store(ar, 0, bData); + if(GetStatusNL(ST_STEP_MASK) > ST_SEARCHING) + m_files.Store(ar, 0, true); + else + { + size_t st(0); + ar << st; } + ar << m_bSaved; } - catch(...) - { - m_cs.Unlock(); - return; - } - m_cs.Unlock(); } -/*inline*/ void CTask::KillThread() +void CTask::KillThread() { - if (!GetKilledFlag()) // protection from recalling Cleanup + if(!GetKilledFlag()) // protection from recalling Cleanup { SetKillFlag(); - while (!GetKilledFlag()) + while(!GetKilledFlag()) Sleep(10); // cleanup @@ -656,30 +579,22 @@ void CTask::BeginProcessing() { - m_cs.Lock(); - if (m_pThread != NULL) - { - m_cs.Unlock(); + boost::unique_lock lock(m_lock); + if(m_pThread != NULL) return; - } - m_cs.Unlock(); // create new thread m_uiResumeInterval=0; // just in case m_bSaved=false; // save - SetKillFlag(false); - SetKilledFlag(false); - CWinThread* pThread=AfxBeginThread(ThrdProc, this, GetPriority()); - - m_cs.Lock(); - m_pThread=pThread; - m_cs.Unlock(); + SetKillFlagNL(false); + SetKilledFlagNL(false); + m_pThread = AfxBeginThread(ThrdProc, this, GetPriorityNL()); } void CTask::ResumeProcessing() { // the same as retry but less demanding - if ( (GetStatus(ST_WORKING_MASK) & ST_PAUSED) && GetStatus(ST_STEP_MASK) != ST_FINISHED + if( (GetStatus(ST_WORKING_MASK) & ST_PAUSED) && GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) { SetStatus(0, ST_ERROR); @@ -690,13 +605,13 @@ bool CTask::RetryProcessing(bool bOnlyErrors/*=false*/, UINT uiInterval) { // retry used to auto-resume, after loading - if ( (GetStatus(ST_WORKING_MASK) == ST_ERROR || (!bOnlyErrors && GetStatus(ST_WORKING_MASK) != ST_PAUSED)) + if( (GetStatus(ST_WORKING_MASK) == ST_ERROR || (!bOnlyErrors && GetStatus(ST_WORKING_MASK) != ST_PAUSED)) && GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) { - if (uiInterval != 0) + if(uiInterval != 0) { m_uiResumeInterval+=uiInterval; - if (m_uiResumeInterval < (UINT)GetConfig().get_signed_num(PP_CMAUTORETRYINTERVAL)) + if(m_uiResumeInterval < (UINT)GetConfig().get_signed_num(PP_CMAUTORETRYINTERVAL)) return false; else m_uiResumeInterval=0; @@ -722,7 +637,7 @@ void CTask::PauseProcessing() { - if (GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) + if(GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) { KillThread(); SetStatus(ST_PAUSED, ST_WORKING_MASK); @@ -734,7 +649,7 @@ void CTask::CancelProcessing() { // change to ST_CANCELLED - if (GetStatus(ST_STEP_MASK) != ST_FINISHED) + if(GetStatus(ST_STEP_MASK) != ST_FINISHED) { KillThread(); SetStatus(ST_CANCELLED, ST_STEP_MASK); @@ -745,28 +660,28 @@ void CTask::GetMiniSnapshot(TASK_MINI_DISPLAY_DATA *pData) { - m_cs.Lock(); - if (m_stCurrentIndex >= 0 && m_stCurrentIndex < m_files.GetSize()) - pData->m_fi=m_files.GetAt(m_stCurrentIndex); + boost::shared_lock lock(m_lock); + if(m_stCurrentIndex >= 0 && m_stCurrentIndex < m_files.GetSize()) + pData->m_spFileInfo = m_files.GetAt(m_stCurrentIndex); else { - if (m_files.GetSize() > 0) + if(m_files.GetSize() > 0) { - pData->m_fi=m_files.GetAt(0); - pData->m_fi.SetFilePath(pData->m_fi.GetFullFilePath()); - pData->m_fi.SetSrcIndex(-1); + pData->m_spFileInfo = m_files.GetAt(0); + pData->m_spFileInfo->SetFilePath(pData->m_spFileInfo->GetFullFilePath()); + pData->m_spFileInfo->SetSrcIndex(-1); } else { - if (m_clipboard.GetSize() > 0) + if(m_clipboard.GetSize() > 0) { - pData->m_fi.SetFilePath(m_clipboard.GetAt(0)->GetPath()); - pData->m_fi.SetSrcIndex(-1); + pData->m_spFileInfo->SetFilePath(m_clipboard.GetAt(0)->GetPath()); + pData->m_spFileInfo->SetSrcIndex(-1); } else { - pData->m_fi.SetFilePath(GetResManager().LoadString(IDS_NONEINPUTFILE_STRING)); - pData->m_fi.SetSrcIndex(-1); + pData->m_spFileInfo->SetFilePath(GetResManager().LoadString(IDS_NONEINPUTFILE_STRING)); + pData->m_spFileInfo->SetSrcIndex(-1); } } } @@ -776,41 +691,42 @@ // percents size_t stSize = m_files.GetSize() * m_ucCopies; size_t stIndex = m_stCurrentIndex + m_ucCurrentCopy * m_files.GetSize(); - if (m_nAll != 0 && !((m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_CONTENT)) + if(m_nAll != 0 && !((m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_CONTENT)) pData->m_nPercent=static_cast( (static_cast(m_nProcessed)*100.0)/static_cast(m_nAll) ); else - if (stSize != 0) - pData->m_nPercent=static_cast( static_cast(stIndex)*100.0/static_cast(stSize) ); - else - pData->m_nPercent=0; - - m_cs.Unlock(); + { + if(stSize != 0) + pData->m_nPercent=static_cast( static_cast(stIndex)*100.0/static_cast(stSize) ); + else + pData->m_nPercent=0; + } } void CTask::GetSnapshot(TASK_DISPLAY_DATA *pData) { - m_cs.Lock(); - if (m_stCurrentIndex >= 0 && m_stCurrentIndex < m_files.GetSize()) - pData->m_fi=m_files.GetAt(m_stCurrentIndex); + boost::unique_lock lock(m_lock); + + if(m_stCurrentIndex >= 0 && m_stCurrentIndex < m_files.GetSize()) + pData->m_spFileInfo = m_files.GetAt(m_stCurrentIndex); else { - if (m_files.GetSize() > 0) + if(m_files.GetSize() > 0) { - pData->m_fi=m_files.GetAt(0); - pData->m_fi.SetFilePath(pData->m_fi.GetFullFilePath()); - pData->m_fi.SetSrcIndex(-1); + pData->m_spFileInfo = m_files.GetAt(0); + pData->m_spFileInfo->SetFilePath(pData->m_spFileInfo->GetFullFilePath()); + pData->m_spFileInfo->SetSrcIndex(-1); } else { - if (m_clipboard.GetSize() > 0) + if(m_clipboard.GetSize() > 0) { - pData->m_fi.SetFilePath(m_clipboard.GetAt(0)->GetPath()); - pData->m_fi.SetSrcIndex(-1); + pData->m_spFileInfo->SetFilePath(m_clipboard.GetAt(0)->GetPath()); + pData->m_spFileInfo->SetSrcIndex(-1); } else { - pData->m_fi.SetFilePath(GetResManager().LoadString(IDS_NONEINPUTFILE_STRING)); - pData->m_fi.SetSrcIndex(-1); + pData->m_spFileInfo->SetFilePath(GetResManager().LoadString(IDS_NONEINPUTFILE_STRING)); + pData->m_spFileInfo->SetSrcIndex(-1); } } } @@ -830,43 +746,43 @@ pData->m_ucCopies=m_ucCopies; pData->m_pstrUniqueName=&m_strUniqueName; - if (m_files.GetSize() > 0 && m_stCurrentIndex != -1) - pData->m_iCurrentBufferIndex=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < m_files.GetSize()) ? m_stCurrentIndex : 0).GetBufferIndex(); + if(m_files.GetSize() > 0 && m_stCurrentIndex != -1) + pData->m_iCurrentBufferIndex=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < m_files.GetSize()) ? m_stCurrentIndex : 0)->GetBufferIndex(); else pData->m_iCurrentBufferIndex=0; // percents - if (m_nAll != 0 && !((m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_CONTENT)) + if(m_nAll != 0 && !((m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_CONTENT)) pData->m_nPercent=static_cast( (static_cast(m_nProcessed)*100.0)/static_cast(m_nAll) ); else - if (pData->m_stSize != 0) + if(pData->m_stSize != 0) pData->m_nPercent=static_cast( static_cast(pData->m_stIndex)*100.0/static_cast(pData->m_stSize) ); else pData->m_nPercent=0; // status string // first - if ( (m_nStatus & ST_WORKING_MASK) == ST_ERROR ) + if( (m_nStatus & ST_WORKING_MASK) == ST_ERROR ) { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+4, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); } - else if ( (m_nStatus & ST_WORKING_MASK) == ST_PAUSED ) + else if( (m_nStatus & ST_WORKING_MASK) == ST_PAUSED ) { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+5, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); } - else if ( (m_nStatus & ST_STEP_MASK) == ST_FINISHED ) + else if( (m_nStatus & ST_STEP_MASK) == ST_FINISHED ) { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+3, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); } - else if ( (m_nStatus & ST_WAITING_MASK) == ST_WAITING ) + else if( (m_nStatus & ST_WAITING_MASK) == ST_WAITING ) { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+9, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); } - else if ( (m_nStatus & ST_STEP_MASK) == ST_CANCELLED ) + else if( (m_nStatus & ST_STEP_MASK) == ST_CANCELLED ) { GetResManager().LoadStringCopy(IDS_STATUS0_STRING+8, pData->m_szStatusText, _MAX_PATH); _tcscat(pData->m_szStatusText, _T("/")); @@ -875,17 +791,17 @@ _tcscpy(pData->m_szStatusText, _T("")); // second part - if ( (m_nStatus & ST_STEP_MASK) == ST_DELETING ) + if( (m_nStatus & ST_STEP_MASK) == ST_DELETING ) _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_STATUS0_STRING+6)); - else if ( (m_nStatus & ST_STEP_MASK) == ST_SEARCHING ) + else if( (m_nStatus & ST_STEP_MASK) == ST_SEARCHING ) _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_STATUS0_STRING+0)); - else if ((m_nStatus & ST_OPERATION_MASK) == ST_COPY ) + else if((m_nStatus & ST_OPERATION_MASK) == ST_COPY ) { _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_STATUS0_STRING+1)); if(!m_afFilters.IsEmpty()) _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_FILTERING_STRING)); } - else if ( (m_nStatus & ST_OPERATION_MASK) == ST_MOVE ) + else if( (m_nStatus & ST_OPERATION_MASK) == ST_MOVE ) { _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_STATUS0_STRING+2)); if(!m_afFilters.IsEmpty()) @@ -895,181 +811,156 @@ _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_STATUS0_STRING+7)); // third part - if ( (m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_DIRS ) + if( (m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_DIRS ) { _tcscat(pData->m_szStatusText, _T("/")); _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_STATUS0_STRING+10)); } - if ( (m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_CONTENT ) + if( (m_nStatus & ST_SPECIAL_MASK) & ST_IGNORE_CONTENT ) { _tcscat(pData->m_szStatusText, _T("/")); _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_STATUS0_STRING+11)); } // count of copies - if (m_ucCopies > 1) + if(m_ucCopies > 1) { _tcscat(pData->m_szStatusText, _T("/")); TCHAR xx[4]; _tcscat(pData->m_szStatusText, _itot(m_ucCopies, xx, 10)); - if (m_ucCopies < 5) + if(m_ucCopies < 5) _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_COPYWORDLESSFIVE_STRING)); else _tcscat(pData->m_szStatusText, GetResManager().LoadString(IDS_COPYWORDMOREFOUR_STRING)); } // time - UpdateTime(); + UpdateTimeNL(); pData->m_lTimeElapsed=m_lTimeElapsed; - - m_cs.Unlock(); } /*inline*/ void CTask::CleanupAfterKill() { - m_cs.Lock(); - m_pThread=NULL; - UpdateTime(); - m_lLastTime=-1; - m_cs.Unlock(); + boost::unique_lock lock(m_lock); + + CleanupAfterKillNL(); } void CTask::DeleteProgress(LPCTSTR lpszDirectory) { - m_cs.Lock(); - DeleteFile(lpszDirectory+m_strUniqueName+_T(".atd")); - DeleteFile(lpszDirectory+m_strUniqueName+_T(".atp")); - DeleteFile(lpszDirectory+m_strUniqueName+_T(".log")); - m_cs.Unlock(); + m_lock.lock_shared(); + + CString strDel1 = lpszDirectory+m_strUniqueName+_T(".atd"); + CString strDel2 = lpszDirectory+m_strUniqueName+_T(".atp"); + CString strDel3 = lpszDirectory+m_strUniqueName+_T(".log"); + + m_lock.unlock_shared(); + + DeleteFile(strDel1); + DeleteFile(strDel2); + DeleteFile(strDel3); } void CTask::SetOsErrorCode(DWORD dwError, LPCTSTR lpszErrDesc) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_lOsError=dwError; m_strErrorDesc=lpszErrDesc; - m_cs.Unlock(); } void CTask::UpdateTime() { - m_cs.Lock(); - if (m_lLastTime != -1) - { - long lVal=(long)time(NULL); - m_lTimeElapsed+=lVal-m_lLastTime; - m_lLastTime=lVal; - } - m_cs.Unlock(); + boost::unique_lock lock(m_lock); + + UpdateTimeNL(); } void CTask::DecreaseOperationsPending(UINT uiBy) { - m_pcs->Lock(); - if (m_bQueued) + boost::unique_lock lock(*m_pLock); + if(m_bQueued) { TRACE("Decreasing operations pending by %lu\n", uiBy); (*m_puiOperationsPending)-=uiBy; m_bQueued=false; } - m_pcs->Unlock(); } void CTask::IncreaseOperationsPending(UINT uiBy) { TRACE("Trying to increase operations pending...\n"); - if (!m_bQueued) + if(!m_bQueued) { TRACE("Increasing operations pending by %lu\n", uiBy); - m_pcs->Lock(); - (*m_puiOperationsPending)+=uiBy; - m_pcs->Unlock(); - m_bQueued=true; + + boost::unique_lock lock(*m_pLock); + (*m_puiOperationsPending) += uiBy; + + m_bQueued = true; } } -const CFiltersArray* CTask::GetFilters() -{ - return &m_afFilters; -} - void CTask::SetFilters(const CFiltersArray* pFilters) { BOOST_ASSERT(pFilters); if(!pFilters) - return; + THROW(_T("Invalid argument"), 0, 0, 0); - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_afFilters = *pFilters; - m_cs.Unlock(); } bool CTask::CanBegin() { bool bRet=true; - m_cs.Lock(); - if (GetContinueFlag() || GetForceFlag()) + boost::unique_lock lock(m_lock); + + if(GetContinueFlagNL() || GetForceFlagNL()) { - TRACE("New operation Begins... continue: %d, force: %d\n", GetContinueFlag(), GetForceFlag()); IncreaseOperationsPending(); - SetForceFlag(false); - SetContinueFlag(false); + SetForceFlagNL(false); + SetContinueFlagNL(false); } else - bRet=false; - m_cs.Unlock(); + bRet = false; return bRet; } void CTask::SetCopies(unsigned char ucCopies) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_ucCopies=ucCopies; - m_cs.Unlock(); } unsigned char CTask::GetCopies() { - unsigned char ucCopies; - m_cs.Lock(); - ucCopies=m_ucCopies; - m_cs.Unlock(); - - return ucCopies; + boost::shared_lock lock(m_lock); + return m_ucCopies; } void CTask::SetCurrentCopy(unsigned char ucCopy) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_ucCurrentCopy=ucCopy; - m_cs.Unlock(); } unsigned char CTask::GetCurrentCopy() { - m_cs.Lock(); - unsigned char ucCopy=m_ucCurrentCopy; - m_cs.Unlock(); - - return ucCopy; + boost::shared_lock lock(m_lock); + return m_ucCurrentCopy; } void CTask::SetLastProcessedIndex(size_t stIndex) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_stLastProcessedIndex = stIndex; - m_cs.Unlock(); } size_t CTask::GetLastProcessedIndex() { - size_t stIndex = 0; - m_cs.Lock(); - stIndex = m_stLastProcessedIndex; - m_cs.Unlock(); - - return stIndex; + boost::shared_lock lock(m_lock); + return m_stLastProcessedIndex; } bool CTask::GetRequiredFreeSpace(ull_t *pullNeeded, ull_t *pullAvailable) @@ -1078,493 +969,272 @@ // but GetDiskFreeSpace returns flase values // get free space - if (!GetDynamicFreeSpace(GetDestPath().GetPath(), pullAvailable, NULL)) + if(!GetDynamicFreeSpace(GetDestPath().GetPath(), pullAvailable, NULL)) return true; return (*pullNeeded <= *pullAvailable); } void CTask::SetTaskPath(const tchar_t* pszDir) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_strTaskBasePath = pszDir; - m_cs.Unlock(); } const tchar_t* CTask::GetTaskPath() const { - const tchar_t* pszText = NULL; - m_cs.Lock(); - pszText = m_strTaskBasePath.c_str(); - m_cs.Unlock(); - - return pszText; + boost::shared_lock lock(m_lock); + return m_strTaskBasePath.c_str(); } void CTask::SetForceFlag(bool bFlag) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_bForce=bFlag; - m_cs.Unlock(); } bool CTask::GetForceFlag() { + boost::shared_lock lock(m_lock); return m_bForce; } void CTask::SetContinueFlag(bool bFlag) { - m_cs.Lock(); + boost::unique_lock lock(m_lock); m_bContinue=bFlag; - m_cs.Unlock(); } bool CTask::GetContinueFlag() { + boost::shared_lock lock(m_lock); return m_bContinue; } -//////////////////////////////////////////////////////////////////////////////// -// CTaskArray members -CTaskArray::CTaskArray() : - m_uhRange(0), - m_uhPosition(0), - m_uiOperationsPending(0), - m_lFinished(0), - m_piFeedbackFactory(NULL), - m_stNextSessionUniqueID(0) +///////////////////////////////////////////////////////////////////////////////////////////////////////////// +bool CTask::SetFileDirectoryTime(LPCTSTR lpszName, const CFileInfoPtr& spFileInfo) { -} + TAutoFileHandle hFile = CreateFile(lpszName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | (spFileInfo->IsDirectory() ? FILE_FLAG_BACKUP_SEMANTICS : 0), NULL); + if(hFile == INVALID_HANDLE_VALUE) + return false; -CTaskArray::~CTaskArray() -{ - // NOTE: do not delete the feedback factory, since we are not responsible for releasing it -} + BOOL bResult = (!SetFileTime(hFile, &spFileInfo->GetCreationTime(), &spFileInfo->GetLastAccessTime(), &spFileInfo->GetLastWriteTime())); -void CTaskArray::Create(chcore::IFeedbackHandlerFactory* piFeedbackHandlerFactory) -{ - BOOST_ASSERT(piFeedbackHandlerFactory); + if(!hFile.Close()) + return false; - m_tcd.pcs=&m_cs; - m_tcd.pTasksAll=&m_uhRange; - m_tcd.pTasksProcessed=&m_uhPosition; - m_tcd.puiOperationsPending=&m_uiOperationsPending; - m_tcd.plFinished=&m_lFinished; - m_piFeedbackFactory = piFeedbackHandlerFactory; + return bResult != 0; } -CTaskPtr CTaskArray::CreateTask() +// m_stCurrentIndex +void CTask::IncreaseCurrentIndexNL() { - BOOST_ASSERT(m_piFeedbackFactory); - if(!m_piFeedbackFactory) - return CTaskPtr(); - - chcore::IFeedbackHandler* piHandler = m_piFeedbackFactory->Create(); - if(!piHandler) - return CTaskPtr(); - - CTaskPtr spTask = boost::make_shared(piHandler, &m_tcd, m_stNextSessionUniqueID++); - return spTask; + ++m_stCurrentIndex; } -size_t CTaskArray::GetSize() +size_t CTask::GetCurrentIndexNL() { - m_cs.Lock(); - size_t stSize = m_vTasks.size(); - m_cs.Unlock(); - - return stSize; + return m_stCurrentIndex; } -CTaskPtr CTaskArray::GetAt(size_t nIndex) +void CTask::SetCurrentIndexNL(size_t stIndex) { - _ASSERTE(nIndex >= 0 && nIndex < (size_t)m_vTasks.size()); - if(nIndex >= m_vTasks.size()) - THROW(_t("Invalid argument"), 0, 0, 0); - - m_cs.Lock(); - CTaskPtr spTask = m_vTasks.at(nIndex); - m_cs.Unlock(); - - return spTask; + m_stCurrentIndex = stIndex; } -CTaskPtr CTaskArray::GetTaskBySessionUniqueID(size_t stSessionUniqueID) +// m_strDestPath - adds '\\' +void CTask::SetDestPathNL(LPCTSTR lpszPath) { - CTaskPtr spFoundTask; - - m_cs.Lock(); - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - if(spTask->GetSessionUniqueID() == stSessionUniqueID) - { - spFoundTask = spTask; - break; - } - } - m_cs.Unlock(); - - return spFoundTask; + m_dpDestPath.SetPath(lpszPath); } -size_t CTaskArray::Add(const CTaskPtr& spNewTask) +// guaranteed '\\' +const CDestPath& CTask::GetDestPathNL() { - if(!spNewTask) - THROW(_t("Invalid argument"), 0, 0, 0); - - m_cs.Lock(); - // here we know load succeeded - spNewTask->SetTaskPath(m_strTasksDir.c_str()); - - m_vTasks.push_back(spNewTask); - - m_uhRange += spNewTask->GetAllSize(); - m_uhPosition += spNewTask->GetProcessedSize(); - - size_t pos = m_vTasks.size() - 1; - m_cs.Unlock(); - - return pos; + return m_dpDestPath; } -void CTaskArray::RemoveAt(size_t stIndex, size_t stCount) +int CTask::GetDestDriveNumberNL() { - m_cs.Lock(); - try - { - _ASSERTE(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size()); - if(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size()) - THROW(_t("Invalid argument"), 0, 0, 0); - - for(std::vector::iterator iterTask = m_vTasks.begin() + stIndex; iterTask != m_vTasks.begin() + stIndex + stCount; ++iterTask) - { - CTaskPtr& spTask = *iterTask; - - // kill task if needed - spTask->KillThread(); - - m_uhRange -= spTask->GetAllSize(); - m_uhPosition -= spTask->GetProcessedSize(); - } - - // remove elements from array - m_vTasks.erase(m_vTasks.begin() + stIndex, m_vTasks.begin() + stIndex + stCount); - } - catch(...) - { - m_cs.Unlock(); - throw; - } - m_cs.Unlock(); + return m_dpDestPath.GetDriveNumber(); } -void CTaskArray::RemoveAll() +// m_nStatus +void CTask::SetStatusNL(UINT nStatus, UINT nMask) { - m_cs.Lock(); - - StopAllTasks(); - - m_vTasks.clear(); - - m_cs.Unlock(); + m_nStatus &= ~nMask; + m_nStatus |= nStatus; } -void CTaskArray::RemoveAllFinished() +UINT CTask::GetStatusNL(UINT nMask) { - m_cs.Lock(); - - size_t stIndex = m_vTasks.size(); - while(stIndex--) - { - CTaskPtr spTask = m_vTasks.at(stIndex); - - // delete only when the thread is finished - if((spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED) - && spTask->GetKilledFlag()) - { - m_uhRange -= spTask->GetAllSize(); - m_uhPosition -= spTask->GetProcessedSize(); - - // delete associated files - spTask->DeleteProgress(m_strTasksDir.c_str()); - - m_vTasks.erase(m_vTasks.begin() + stIndex); - } - } - - m_cs.Unlock(); + return m_nStatus & nMask; } -void CTaskArray::RemoveFinished(const CTaskPtr& spSelTask) +// m_nBufferSize +void CTask::SetBufferSizesNL(const BUFFERSIZES* bsSizes) { - m_cs.Lock(); - for(std::vector::iterator iterTask = m_vTasks.begin(); iterTask != m_vTasks.end(); ++iterTask) - { - CTaskPtr& spTask = *iterTask; + m_bsSizes = *bsSizes; + m_bSaved = false; +} - if(spTask == spSelTask && (spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED)) - { - // kill task if needed - spTask->KillThread(); - - m_uhRange -= spTask->GetAllSize(); - m_uhPosition -= spTask->GetProcessedSize(); - - // delete associated files - spTask->DeleteProgress(m_strTasksDir.c_str()); - - m_vTasks.erase(iterTask); - - m_cs.Unlock(); - return; - } - } - m_cs.Unlock(); +const BUFFERSIZES* CTask::GetBufferSizesNL() +{ + return &m_bsSizes; } -void CTaskArray::StopAllTasks() +int CTask::GetCurrentBufferIndexNL() { - m_cs.Lock(); + int rv = 0; - // kill all unfinished tasks - send kill request - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - spTask->SetKillFlag(); - } + size_t stSize = m_files.GetSize(); + if(stSize > 0 && m_stCurrentIndex != -1) + rv = m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < stSize) ? m_stCurrentIndex : 0)->GetBufferIndex(); - // wait for finishing - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - while(!spTask->GetKilledFlag()) - Sleep(10); - spTask->CleanupAfterKill(); - } - m_cs.Unlock(); + return rv; } -void CTaskArray::SaveData() +// m_pThread +// m_nPriority +int CTask::GetPriorityNL() { - m_cs.Lock(); - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - spTask->Store(true); - } - m_cs.Unlock(); + return m_nPriority; } -void CTaskArray::SaveProgress() +void CTask::SetPriorityNL(int nPriority) { - m_cs.Lock(); - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - spTask->Store(false); - } - m_cs.Unlock(); -} - -void CTaskArray::LoadDataProgress() -{ - m_cs.Lock(); - CFileFind finder; - CTaskPtr spTask; - CString strPath; - - BOOL bWorking=finder.FindFile(CString(m_strTasksDir.c_str())+_T("*.atd")); - while(bWorking) + if(m_pThread != NULL) { - bWorking = finder.FindNextFile(); - - // load data - spTask = CreateTask(); - try - { - strPath = finder.GetFilePath(); - - spTask->Load(strPath, true); - - strPath = strPath.Left(strPath.GetLength() - 4); - strPath += _T(".atp"); - - spTask->Load(strPath, false); - - // add read task to array - Add(spTask); - } - catch(std::exception& e) - { - CString strFmt; - strFmt.Format(_T("Cannot load task data: %s (reason: %S)"), strPath, e.what()); - LOG_ERROR(strFmt); - } + m_pThread->SuspendThread(); + m_pThread->SetThreadPriority(nPriority); + m_pThread->ResumeThread(); } - finder.Close(); - m_cs.Unlock(); + m_nPriority = nPriority; + m_bSaved = false; } -void CTaskArray::TasksBeginProcessing() +// m_nProcessed +void CTask::IncreaseProcessedSizeNL(__int64 nSize) { - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - spTask->BeginProcessing(); - } + m_nProcessed += nSize; } -void CTaskArray::TasksPauseProcessing() +void CTask::SetProcessedSizeNL(__int64 nSize) { - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - spTask->PauseProcessing(); - } + m_nProcessed = nSize; } -void CTaskArray::TasksResumeProcessing() +__int64 CTask::GetProcessedSizeNL() { - for(size_t stIndex = 0; stIndex < GetSize(); ++stIndex) - GetAt(stIndex)->ResumeProcessing(); + return m_nProcessed; } -void CTaskArray::TasksRestartProcessing() +// m_nAll +void CTask::SetAllSizeNL(__int64 nSize) { - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - spTask->RestartProcessing(); - } + m_nAll = nSize; } -bool CTaskArray::TasksRetryProcessing(bool bOnlyErrors/*=false*/, UINT uiInterval) +__int64 CTask::GetAllSizeNL() { - bool bChanged=false; - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + return m_nAll; +} + +void CTask::CalcAllSizeNL() +{ + m_nAll = 0; + + size_t nSize = m_files.GetSize(); + for (size_t i = 0; i < nSize; i++) { - if(spTask->RetryProcessing(bOnlyErrors, uiInterval)) - bChanged = true; + m_nAll += m_files.GetAt(i)->GetLength64(); } - return bChanged; + m_nAll *= m_ucCopies; } -void CTaskArray::TasksCancelProcessing() +void CTask::SetKillFlagNL(bool bKill) { - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - spTask->CancelProcessing(); - } + m_bKill = bKill; } -ull_t CTaskArray::GetPosition() +bool CTask::GetKillFlagNL() { - m_cs.Lock(); - ull_t rv = m_uhPosition; - m_cs.Unlock(); - - return rv; + return m_bKill; } -ull_t CTaskArray::GetRange() +void CTask::SetKilledFlagNL(bool bKilled) { - m_cs.Lock(); - ull_t rv=m_uhRange; - m_cs.Unlock(); - - return rv; + m_bKilled = bKilled; } -int CTaskArray::GetPercent() +bool CTask::GetKilledFlagNL() { - int pos; - m_cs.Lock(); - if (m_uhRange != 0) - pos=static_cast((static_cast(m_uhPosition)*100.0)/static_cast(m_uhRange)); - else - if (GetSize() != 0) // if anything is in an array, but size of it is 0 - pos=100; - else - pos=0; - m_cs.Unlock(); - - return pos; + return m_bKilled; } -UINT CTaskArray::GetOperationsPending() +void CTask::CleanupAfterKillNL() { - m_cs.Lock(); - UINT uiOP=m_uiOperationsPending; - m_cs.Unlock(); - return uiOP; + m_pThread = NULL; + UpdateTimeNL(); } -bool CTaskArray::IsFinished() +void CTask::UpdateTimeNL() { - bool bFlag=true; - UINT uiStatus; - - m_cs.Lock(); - if (m_uiOperationsPending != 0) - bFlag=false; - else + if(m_lLastTime != -1) { - BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) - { - uiStatus = spTask->GetStatus(); - bFlag=((uiStatus & ST_STEP_MASK) == ST_FINISHED || (uiStatus & ST_STEP_MASK) == ST_CANCELLED - || (uiStatus & ST_WORKING_MASK) == ST_PAUSED - || ((uiStatus & ST_WORKING_MASK) == ST_ERROR && !GetConfig().get_bool(PP_CMAUTORETRYONERROR))); - } + long lVal = (long)time(NULL); + m_lTimeElapsed += lVal - m_lLastTime; + m_lLastTime = lVal; } +} - m_cs.Unlock(); - return bFlag; +CString CTask::GetUniqueNameNL() +{ + return m_strUniqueName; } -void CTaskArray::SetTasksDir(const tchar_t* pszPath) +void CTask::SetForceFlagNL(bool bFlag) { - m_strTasksDir = pszPath; + m_bForce=bFlag; } -///////////////////////////////////////////////////////////////////////////////////////////////////////////// -bool CTask::SetFileDirectoryTime(LPCTSTR lpszName, CFileInfo* pSrcInfo) +bool CTask::GetForceFlagNL() { - HANDLE hFile = CreateFile(lpszName, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | (pSrcInfo->IsDirectory() ? FILE_FLAG_BACKUP_SEMANTICS : 0), NULL); - if(hFile == INVALID_HANDLE_VALUE) - return false; + return m_bForce; +} - if(!SetFileTime(hFile, &pSrcInfo->GetCreationTime(), &pSrcInfo->GetLastAccessTime(), &pSrcInfo->GetLastWriteTime())) - { - CloseHandle(hFile); - return false; - } +void CTask::SetContinueFlagNL(bool bFlag) +{ + m_bContinue=bFlag; +} - if(!CloseHandle(hFile)) - return false; - - return true; +bool CTask::GetContinueFlagNL() +{ + return m_bContinue; } // searching for files -void CTask::RecurseDirectories(CTask* pTask) +void CTask::RecurseDirectories() { - TRACE("Searching for files...\n"); - // log - pTask->m_log.logi(_T("Searching for files...")); + m_log.logi(_T("Searching for files...")); // update status - pTask->SetStatus(ST_SEARCHING, ST_STEP_MASK); + SetStatus(ST_SEARCHING, ST_STEP_MASK); // delete the content of m_files - pTask->FilesRemoveAll(); + FilesRemoveAll(); // enter some data to m_files - size_t stSize = pTask->GetClipboardDataSize(); // size of m_clipboard - const CFiltersArray* pFilters=pTask->GetFilters(); - int iDestDrvNumber=pTask->GetDestDriveNumber(); - bool bIgnoreDirs=(pTask->GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_DIRS) != 0; - bool bForceDirectories=(pTask->GetStatus(ST_SPECIAL_MASK) & ST_FORCE_DIRS) != 0; - bool bMove=pTask->GetStatus(ST_OPERATION_MASK) == ST_MOVE; - CFileInfo fi; - fi.SetClipboard(pTask->GetClipboard()); + size_t stSize = GetClipboardDataSize(); // size of m_clipboard + int iDestDrvNumber = GetDestDriveNumber(); + bool bIgnoreDirs = (GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_DIRS) != 0; + bool bForceDirectories = (GetStatus(ST_SPECIAL_MASK) & ST_FORCE_DIRS) != 0; + bool bMove = GetStatus(ST_OPERATION_MASK) == ST_MOVE; + CFileInfoPtr spFileInfo(boost::make_shared()); + spFileInfo->SetClipboard(GetClipboard()); // add everything ictranslate::CFormat fmt; @@ -1580,34 +1250,34 @@ do { // read attributes of src file/folder - bool bExists = fi.Create(pTask->GetClipboardData(i)->GetPath(), i); + bool bExists = spFileInfo->Create(GetClipboardData(i)->GetPath(), i); if(!bExists) { - chcore::IFeedbackHandler* piFeedbackHandler = pTask->GetFeedbackHandler(); + chcore::IFeedbackHandler* piFeedbackHandler = GetFeedbackHandler(); BOOST_ASSERT(piFeedbackHandler); - CString strSrcFile = pTask->GetClipboardData(i)->GetPath(); + CString strSrcFile = GetClipboardData(i)->GetPath(); FEEDBACK_FILEERROR ferr = { (PCTSTR)strSrcFile, NULL, eFastMoveError, ERROR_FILE_NOT_FOUND }; CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &ferr); switch(frResult) { case CFeedbackHandler::eResult_Cancel: - throw new CProcessingException(E_CANCEL, pTask); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: bRetry = true; continue; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pTask); + throw new CProcessingException(E_PAUSE); break; case CFeedbackHandler::eResult_Skip: bSkipInputPath = true; bRetry = false; break; // just do nothing default: BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } } @@ -1619,199 +1289,200 @@ // log fmt.SetFormat(_T("Adding file/folder (clipboard) : %path ...")); - fmt.SetParam(_t("%path"), pTask->GetClipboardData(i)->GetPath()); - pTask->m_log.logi(fmt); + fmt.SetParam(_t("%path"), GetClipboardData(i)->GetPath()); + m_log.logi(fmt); // found file/folder - check if the dest name has been generated - if (pTask->GetClipboardData(i)->GetDestinationPathsCount() == 0) + if(GetClipboardData(i)->GetDestinationPathsCount() == 0) { // generate something - if dest folder == src folder - search for copy - if (pTask->GetDestPath().GetPath() == fi.GetFileRoot()) + if(GetDestPath().GetPath() == spFileInfo->GetFileRoot()) { CString strSubst; - FindFreeSubstituteName(fi.GetFullFilePath(), pTask->GetDestPath().GetPath(), &strSubst); - pTask->GetClipboardData(i)->AddDestinationPath(strSubst); + FindFreeSubstituteName(spFileInfo->GetFullFilePath(), GetDestPath().GetPath(), &strSubst); + GetClipboardData(i)->AddDestinationPath(strSubst); } else - pTask->GetClipboardData(i)->AddDestinationPath(fi.GetFileName()); + GetClipboardData(i)->AddDestinationPath(spFileInfo->GetFileName()); } // add if needed - if (fi.IsDirectory()) + if(spFileInfo->IsDirectory()) { // add if folder's aren't ignored - if (!bIgnoreDirs && !bForceDirectories) + if(!bIgnoreDirs && !bForceDirectories) { - pTask->FilesAdd(fi); + FilesAdd(spFileInfo); // log fmt.SetFormat(_T("Added folder %path")); - fmt.SetParam(_t("%path"), fi.GetFullFilePath()); - pTask->m_log.logi(fmt); + fmt.SetParam(_t("%path"), spFileInfo->GetFullFilePath()); + m_log.logi(fmt); } // don't add folder contents when moving inside one disk boundary - if (bIgnoreDirs || !bMove || pTask->GetCopies() > 1 || iDestDrvNumber == -1 - || iDestDrvNumber != fi.GetDriveNumber() || CFileInfo::Exist(fi.GetDestinationPath(pTask->GetDestPath().GetPath(), 0, ((int)bForceDirectories) << 1)) ) + if(bIgnoreDirs || !bMove || GetCopies() > 1 || iDestDrvNumber == -1 + || iDestDrvNumber != spFileInfo->GetDriveNumber() || CFileInfo::Exist(spFileInfo->GetDestinationPath(GetDestPath().GetPath(), 0, ((int)bForceDirectories) << 1)) ) { // log fmt.SetFormat(_T("Recursing folder %path")); - fmt.SetParam(_t("%path"), fi.GetFullFilePath()); - pTask->m_log.logi(fmt); + fmt.SetParam(_t("%path"), spFileInfo->GetFullFilePath()); + m_log.logi(fmt); // no movefile possibility - use CustomCopyFile - pTask->GetClipboardData(i)->SetMove(false); + GetClipboardData(i)->SetMove(false); - pTask->FilesAddDir(fi.GetFullFilePath(), pFilters, i, true, !bIgnoreDirs || bForceDirectories); + FilesAddDir(spFileInfo->GetFullFilePath(), i, true, !bIgnoreDirs || bForceDirectories); } // check for kill need - if (pTask->GetKillFlag()) + if(GetKillFlag()) { // log - pTask->m_log.logi(_T("Kill request while adding data to files array (RecurseDirectories)")); - throw new CProcessingException(E_KILL_REQUEST, pTask); + m_log.logi(_T("Kill request while adding data to files array (RecurseDirectories)")); + throw new CProcessingException(E_KILL_REQUEST); } } else { - if (bMove && pTask->GetCopies() == 1 && iDestDrvNumber != -1 && iDestDrvNumber == fi.GetDriveNumber() && - !CFileInfo::Exist(fi.GetDestinationPath(pTask->GetDestPath().GetPath(), 0, ((int)bForceDirectories) << 1)) ) + if(bMove && GetCopies() == 1 && iDestDrvNumber != -1 && iDestDrvNumber == spFileInfo->GetDriveNumber() && + !CFileInfo::Exist(spFileInfo->GetDestinationPath(GetDestPath().GetPath(), 0, ((int)bForceDirectories) << 1)) ) { // if moving within one partition boundary set the file size to 0 so the overall size will // be ok - fi.SetLength64(0); + spFileInfo->SetLength64(0); } else - pTask->GetClipboardData(i)->SetMove(false); // no MoveFile + GetClipboardData(i)->SetMove(false); // no MoveFile - pTask->FilesAdd(fi); // file - add + FilesAdd(spFileInfo); // file - add // log fmt.SetFormat(_T("Added file %path")); - fmt.SetParam(_t("%path"), fi.GetFullFilePath()); - pTask->m_log.logi(fmt); + fmt.SetParam(_t("%path"), spFileInfo->GetFullFilePath()); + m_log.logi(fmt); } } // calc size of all files - pTask->CalcAllSize(); + CalcAllSize(); // update *m_pnTasksAll; - pTask->IncreaseAllTasksSize(pTask->GetAllSize()); + IncreaseAllTasksSize(GetAllSize()); // change state to ST_COPYING - finished searching for files - pTask->SetStatus(ST_COPYING, ST_STEP_MASK); + SetStatus(ST_COPYING, ST_STEP_MASK); // save task status - pTask->Store(true); - pTask->Store(false); + Store(true); + Store(false); // log - pTask->m_log.logi(_T("Searching for files finished")); + m_log.logi(_T("Searching for files finished")); } // delete files - after copying -void CTask::DeleteFiles(CTask* pTask) +void CTask::DeleteFiles() { // log - pTask->m_log.logi(_T("Deleting files (DeleteFiles)...")); + m_log.logi(_T("Deleting files (DeleteFiles)...")); - chcore::IFeedbackHandler* piFeedbackHandler = pTask->GetFeedbackHandler(); + chcore::IFeedbackHandler* piFeedbackHandler = GetFeedbackHandler(); BOOST_ASSERT(piFeedbackHandler); // current processed path BOOL bSuccess; - CFileInfo fi; + CFileInfoPtr spFileInfo; ictranslate::CFormat fmt; // index points to 0 or next item to process - size_t stIndex = pTask->GetCurrentIndex(); - while(stIndex < pTask->FilesGetSize()) + size_t stIndex = GetCurrentIndex(); + while(stIndex < FilesGetSize()) { // set index in pTask to currently deleted element - pTask->SetCurrentIndex(stIndex); + SetCurrentIndex(stIndex); // check for kill flag - if (pTask->GetKillFlag()) + if(GetKillFlag()) { // log - pTask->m_log.logi(_T("Kill request while deleting files (Delete Files)")); - throw new CProcessingException(E_KILL_REQUEST, pTask); + m_log.logi(_T("Kill request while deleting files (Delete Files)")); + throw new CProcessingException(E_KILL_REQUEST); } // current processed element - fi=pTask->FilesGetAt(pTask->FilesGetSize()-stIndex-1); - if(!(fi.GetFlags() & FIF_PROCESSED)) + spFileInfo = FilesGetAt(FilesGetSize() - stIndex - 1); + if(!(spFileInfo->GetFlags() & FIF_PROCESSED)) { ++stIndex; continue; } // delete data - if (fi.IsDirectory()) + if(spFileInfo->IsDirectory()) { - if (!GetConfig().get_bool(PP_CMPROTECTROFILES)) - SetFileAttributes(fi.GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); - bSuccess=RemoveDirectory(fi.GetFullFilePath()); + if(!GetConfig().get_bool(PP_CMPROTECTROFILES)) + SetFileAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_DIRECTORY); + bSuccess=RemoveDirectory(spFileInfo->GetFullFilePath()); } else { // set files attributes to normal - it'd slow processing a bit, but it's better. - if (!GetConfig().get_bool(PP_CMPROTECTROFILES)) - SetFileAttributes(fi.GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); - bSuccess=DeleteFile(fi.GetFullFilePath()); + if(!GetConfig().get_bool(PP_CMPROTECTROFILES)) + SetFileAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); + bSuccess=DeleteFile(spFileInfo->GetFullFilePath()); } // operation failed DWORD dwLastError=GetLastError(); - if (!bSuccess && dwLastError != ERROR_PATH_NOT_FOUND && dwLastError != ERROR_FILE_NOT_FOUND) + if(!bSuccess && dwLastError != ERROR_PATH_NOT_FOUND && dwLastError != ERROR_FILE_NOT_FOUND) { // log fmt.SetFormat(_T("Error #%errno while deleting file/folder %path")); fmt.SetParam(_t("%errno"), dwLastError); - fmt.SetParam(_t("%path"), fi.GetFullFilePath()); - pTask->m_log.loge(fmt); + fmt.SetParam(_t("%path"), spFileInfo->GetFullFilePath()); + m_log.loge(fmt); - CString strFile = fi.GetFullFilePath(); + CString strFile = spFileInfo->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); + m_log.logi(_T("Cancel request while deleting file.")); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: continue; // no stIndex bump, since we are trying again break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pTask); + throw new CProcessingException(E_PAUSE); 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")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } ++stIndex; }//while // change status to finished - pTask->SetStatus(ST_FINISHED, ST_STEP_MASK); + SetStatus(ST_FINISHED, ST_STEP_MASK); // add 1 to current index - looks better - pTask->IncreaseCurrentIndex(); + IncreaseCurrentIndex(); // log - pTask->m_log.logi(_T("Deleting files finished")); + m_log.logi(_T("Deleting files finished")); } void CTask::CustomCopyFile(CUSTOM_COPY_PARAMS* pData) { - TAutoFileHandle hSrc = INVALID_HANDLE_VALUE, hDst = INVALID_HANDLE_VALUE; + TAutoFileHandle hSrc = INVALID_HANDLE_VALUE, + hDst = INVALID_HANDLE_VALUE; ictranslate::CFormat fmt; bool bRetry = false; @@ -1821,19 +1492,19 @@ bool bCopyRest = false; // Data regarding dest file - CFileInfo fiDest; - bool bExist = fiDest.Create(pData->strDstFile, std::numeric_limits::max()); + CFileInfoPtr spDestFileInfo(boost::make_shared()); + bool bExist = spDestFileInfo->Create(pData->strDstFile, std::numeric_limits::max()); - chcore::IFeedbackHandler* piFeedbackHandler = pData->pTask->GetFeedbackHandler(); + chcore::IFeedbackHandler* piFeedbackHandler = GetFeedbackHandler(); BOOST_ASSERT(piFeedbackHandler); - pData->pTask->SetLastProcessedIndex(std::numeric_limits::max()); + SetLastProcessedIndex(std::numeric_limits::max()); // if dest file size >0 - we can do something more than usual if(bExist) { // src and dst files are the same - FEEDBACK_ALREADYEXISTS feedStruct = { pData->pfiSrcFile, &fiDest }; + FEEDBACK_ALREADYEXISTS feedStruct = { pData->spSrcFile, spDestFileInfo }; CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileAlreadyExists, &feedStruct); // check for dialog result switch(frResult) @@ -1850,32 +1521,32 @@ } case CFeedbackHandler::eResult_Skip: { - pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); - pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + IncreaseProcessedSize(pData->spSrcFile->GetLength64()); + IncreaseProcessedTasksSize(pData->spSrcFile->GetLength64()); pData->bProcessed = false; return; } case CFeedbackHandler::eResult_Cancel: { // log - if (GetConfig().get_bool(PP_CMCREATELOG)) + if(GetConfig().get_bool(PP_CMCREATELOG)) { fmt.SetFormat(_T("Cancel request while checking result of dialog before opening source file %path (CustomCopyFile)")); - fmt.SetParam(_t("%path"), pData->pfiSrcFile->GetFullFilePath()); - pData->pTask->m_log.logi(fmt); + fmt.SetParam(_t("%path"), pData->spSrcFile->GetFullFilePath()); + m_log.logi(fmt); } - throw new CProcessingException(E_CANCEL, pData->pTask); + throw new CProcessingException(E_CANCEL); break; } case CFeedbackHandler::eResult_Pause: { - throw new CProcessingException(E_PAUSE, pData->pTask); + throw new CProcessingException(E_PAUSE); break; } default: { BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); break; } } @@ -1886,60 +1557,60 @@ SetFileAttributes(pData->strDstFile, FILE_ATTRIBUTE_NORMAL); // first or second pass ? only for FFNB - bool bFirstPass=true; + bool bFirstPass = true; // check size of src file to know whether use flag FILE_FLAG_NOBUFFERING l_start: - bool bNoBuffer=(bFirstPass && GetConfig().get_bool(PP_BFUSENOBUFFERING) && pData->pfiSrcFile->GetLength64() >= (unsigned long long)GetConfig().get_signed_num(PP_BFBOUNDARYLIMIT)); + bool bNoBuffer=(bFirstPass && GetConfig().get_bool(PP_BFUSENOBUFFERING) && pData->spSrcFile->GetLength64() >= (unsigned long long)GetConfig().get_signed_num(PP_BFBOUNDARYLIMIT)); // refresh data about file - if (!bFirstPass) - bExist=fiDest.Create(pData->strDstFile, std::numeric_limits::max()); + if(!bFirstPass) + bExist = spDestFileInfo->Create(pData->strDstFile, std::numeric_limits::max()); // open src do { bRetry = false; - hSrc = CreateFile(pData->pfiSrcFile->GetFullFilePath(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffer ? FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH : 0), NULL); + hSrc = CreateFile(pData->spSrcFile->GetFullFilePath(), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffer ? FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH : 0), NULL); if(hSrc == INVALID_HANDLE_VALUE) { DWORD dwLastError=GetLastError(); - CString strFile = pData->pfiSrcFile->GetFullFilePath(); + CString strFile = pData->spSrcFile->GetFullFilePath(); FEEDBACK_FILEERROR feedStruct = { (PCTSTR)strFile, NULL, eCreateError, dwLastError }; CFeedbackHandler::EFeedbackResult frResult = (CFeedbackHandler::EFeedbackResult)piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_FileError, &feedStruct); switch (frResult) { case CFeedbackHandler::eResult_Skip: - pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); - pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + IncreaseProcessedSize(pData->spSrcFile->GetLength64()); + IncreaseProcessedTasksSize(pData->spSrcFile->GetLength64()); pData->bProcessed = false; return; break; case CFeedbackHandler::eResult_Cancel: // log fmt.SetFormat(_T("Cancel request [error %errno] while opening source file %path (CustomCopyFile)")); fmt.SetParam(_t("%errno"), dwLastError); - fmt.SetParam(_t("%path"), pData->pfiSrcFile->GetFullFilePath()); - pData->pTask->m_log.loge(fmt); - throw new CProcessingException(E_CANCEL, pData->pTask); + fmt.SetParam(_t("%path"), pData->spSrcFile->GetFullFilePath()); + m_log.loge(fmt); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pData->pTask); + throw new CProcessingException(E_PAUSE); break; case CFeedbackHandler::eResult_Retry: // log fmt.SetFormat(_T("Retrying [error %errno] to open source file %path (CustomCopyFile)")); fmt.SetParam(_t("%errno"), dwLastError); - fmt.SetParam(_t("%path"), pData->pfiSrcFile->GetFullFilePath()); - pData->pTask->m_log.loge(fmt); + fmt.SetParam(_t("%path"), pData->spSrcFile->GetFullFilePath()); + m_log.loge(fmt); bRetry = true; break; default: { BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); break; } } @@ -1953,7 +1624,7 @@ bRetry = false; hDst = CreateFile(pData->strDstFile, GENERIC_WRITE, FILE_SHARE_READ, NULL, OPEN_ALWAYS, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN | (bNoBuffer ? FILE_FLAG_NO_BUFFERING | FILE_FLAG_WRITE_THROUGH : 0), NULL); - if (hDst == INVALID_HANDLE_VALUE) + if(hDst == INVALID_HANDLE_VALUE) { DWORD dwLastError=GetLastError(); CString strFile = pData->strDstFile; @@ -1964,37 +1635,37 @@ { case CFeedbackHandler::eResult_Retry: // change attributes - if (!GetConfig().get_bool(PP_CMPROTECTROFILES)) + if(!GetConfig().get_bool(PP_CMPROTECTROFILES)) SetFileAttributes(pData->strDstFile, FILE_ATTRIBUTE_NORMAL); // log fmt.SetFormat(_T("Retrying [error %errno] to open destination file %path (CustomCopyFile)")); fmt.SetParam(_t("%errno"), dwLastError); fmt.SetParam(_t("%path"), pData->strDstFile); - pData->pTask->m_log.loge(fmt); + m_log.loge(fmt); bRetry = true; break; case CFeedbackHandler::eResult_Cancel: // log fmt.SetFormat(_T("Cancel request [error %errno] while opening destination file %path (CustomCopyFile)")); fmt.SetParam(_t("%errno"), dwLastError); fmt.SetParam(_t("%path"), pData->strDstFile); - pData->pTask->m_log.loge(fmt); - throw new CProcessingException(E_CANCEL, pData->pTask); + m_log.loge(fmt); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Skip: - pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); - pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + IncreaseProcessedSize(pData->spSrcFile->GetLength64()); + IncreaseProcessedTasksSize(pData->spSrcFile->GetLength64()); pData->bProcessed = false; return; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pData->pTask); + throw new CProcessingException(E_PAUSE); break; default: { BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); break; } } @@ -2008,10 +1679,10 @@ { if(bCopyRest) // if copy rest { - if(!bFirstPass || (bExist && fiDest.GetLength64() > 0)) + if(!bFirstPass || (bExist && spDestFileInfo->GetLength64() > 0)) { // try to move file pointers to the end - ULONGLONG ullMove = (bNoBuffer ? ROUNDDOWN(fiDest.GetLength64(), MAXSECTORSIZE) : fiDest.GetLength64()); + ULONGLONG ullMove = (bNoBuffer ? ROUNDDOWN(spDestFileInfo->GetLength64(), MAXSECTORSIZE) : spDestFileInfo->GetLength64()); bool bRetry = true; while(bRetry) { @@ -2021,45 +1692,45 @@ // log 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("%srcpath"), pData->spSrcFile->GetFullFilePath()); fmt.SetParam(_t("%dstpath"), pData->strDstFile); fmt.SetParam(_t("%pos"), ullMove); - pData->pTask->m_log.loge(fmt); + m_log.loge(fmt); - CString strSrcFile = pData->pfiSrcFile->GetFullFilePath(); + CString strSrcFile = pData->spSrcFile->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); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: continue; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pData->pTask); + throw new CProcessingException(E_PAUSE); break; case CFeedbackHandler::eResult_Skip: bRetry = false; - pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); - pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + IncreaseProcessedSize(pData->spSrcFile->GetLength64()); + IncreaseProcessedTasksSize(pData->spSrcFile->GetLength64()); pData->bProcessed = false; return; default: BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } else { bRetry = false; // file pointers moved - so we have skipped some work - update positions - if (bFirstPass) // przy drugim obiegu jest ju� uwzgl�dnione + if(bFirstPass) // przy drugim obiegu jest ju� uwzgl�dnione { - pData->pTask->IncreaseProcessedSize(ullMove); - pData->pTask->IncreaseProcessedTasksSize(ullMove); + IncreaseProcessedSize(ullMove); + IncreaseProcessedTasksSize(ullMove); } } } @@ -2075,27 +1746,27 @@ 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); + m_log.loge(fmt); FEEDBACK_FILEERROR ferr = { (PCTSTR)pData->strDstFile, NULL, eResizeError, 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); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: continue; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pData->pTask); + throw new CProcessingException(E_PAUSE); 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")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } } @@ -2106,21 +1777,21 @@ do { // kill flag checks - if(pData->pTask->GetKillFlag()) + if(GetKillFlag()) { // log fmt.SetFormat(_T("Kill request while main copying file %srcpath -> %dstpath")); - fmt.SetParam(_t("%srcpath"), pData->pfiSrcFile->GetFullFilePath()); + fmt.SetParam(_t("%srcpath"), pData->spSrcFile->GetFullFilePath()); fmt.SetParam(_t("%dstpath"), pData->strDstFile); - pData->pTask->m_log.logi(fmt); - throw new CProcessingException(E_KILL_REQUEST, pData->pTask); + m_log.logi(fmt); + throw new CProcessingException(E_KILL_REQUEST); } // recreate buffer if needed - if (!(*pData->dbBuffer.GetSizes() == *pData->pTask->GetBufferSizes())) + if(!(*pData->dbBuffer.GetSizes() == *GetBufferSizes())) { // log - const BUFFERSIZES *pbs1=pData->dbBuffer.GetSizes(), *pbs2=pData->pTask->GetBufferSizes(); + const BUFFERSIZES *pbs1=pData->dbBuffer.GetSizes(), *pbs2=GetBufferSizes(); 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)")); @@ -2134,15 +1805,15 @@ 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("%srcfile"), pData->spSrcFile->GetFullFilePath()); fmt.SetParam(_t("%dstfile"), pData->strDstFile); - pData->pTask->m_log.logi(fmt); - pData->pTask->SetBufferSizes(pData->dbBuffer.Create(pData->pTask->GetBufferSizes())); + m_log.logi(fmt); + SetBufferSizes(pData->dbBuffer.Create(GetBufferSizes())); } // establish count of data to read - iBufferIndex=pData->pTask->GetBufferSizes()->m_bOnlyDefault ? 0 : pData->pfiSrcFile->GetBufferIndex(); + iBufferIndex=GetBufferSizes()->m_bOnlyDefault ? 0 : pData->spSrcFile->GetBufferIndex(); ulToRead=bNoBuffer ? ROUNDUP(pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex], MAXSECTORSIZE) : pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex]; // read @@ -2154,38 +1825,38 @@ 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"), ulToRead); - fmt.SetParam(_t("%path"), pData->pfiSrcFile->GetFullFilePath()); - pData->pTask->m_log.loge(fmt); + fmt.SetParam(_t("%path"), pData->spSrcFile->GetFullFilePath()); + m_log.loge(fmt); - CString strFile = pData->pfiSrcFile->GetFullFilePath(); + CString strFile = pData->spSrcFile->GetFullFilePath(); FEEDBACK_FILEERROR ferr = { (PCTSTR)strFile, NULL, eReadError, 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); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: continue; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pData->pTask); + throw new CProcessingException(E_PAUSE); 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()); + IncreaseProcessedSize(pData->spSrcFile->GetLength64()); + IncreaseProcessedTasksSize(pData->spSrcFile->GetLength64()); pData->bProcessed = false; return; default: BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } // change count of stored data - if (bNoBuffer && (ROUNDUP(ulRead, MAXSECTORSIZE)) != ulRead) + if(bNoBuffer && (ROUNDUP(ulRead, MAXSECTORSIZE)) != ulRead) { // we need to copy rest so do the second pass // close files @@ -2209,47 +1880,47 @@ fmt.SetParam(_t("%errno"), dwLastError); fmt.SetParam(_t("%count"), ulRead); fmt.SetParam(_t("%path"), pData->strDstFile); - pData->pTask->m_log.loge(fmt); + 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) { case CFeedbackHandler::eResult_Cancel: - throw new CProcessingException(E_CANCEL, pData->pTask); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: continue; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pData->pTask); + throw new CProcessingException(E_PAUSE); 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()); + IncreaseProcessedSize(pData->spSrcFile->GetLength64()); + IncreaseProcessedTasksSize(pData->spSrcFile->GetLength64()); pData->bProcessed = false; return; default: BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pData->pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } // increase count of processed data - pData->pTask->IncreaseProcessedSize(ulRead); - pData->pTask->IncreaseProcessedTasksSize(ulRead); + IncreaseProcessedSize(ulRead); + IncreaseProcessedTasksSize(ulRead); // TRACE("Read: %d, Written: %d\n", rd, ulWritten); } while(ulRead != 0); } else { // we don't copy contents, but need to increase processed size - pData->pTask->IncreaseProcessedSize(pData->pfiSrcFile->GetLength64()); - pData->pTask->IncreaseProcessedTasksSize(pData->pfiSrcFile->GetLength64()); + IncreaseProcessedSize(pData->spSrcFile->GetLength64()); + IncreaseProcessedTasksSize(pData->spSrcFile->GetLength64()); } // close files @@ -2269,37 +1940,35 @@ } // function processes files/folders -void CTask::ProcessFiles(CTask* pTask) +void CTask::ProcessFiles() { - chcore::IFeedbackHandler* piFeedbackHandler = pTask->GetFeedbackHandler(); + chcore::IFeedbackHandler* piFeedbackHandler = GetFeedbackHandler(); BOOST_ASSERT(piFeedbackHandler); // log - pTask->m_log.logi(_T("Processing files/folders (ProcessFiles)")); + m_log.logi(_T("Processing files/folders (ProcessFiles)")); // count how much has been done (updates also a member in CTaskArray) - pTask->CalcProcessedSize(); + CalcProcessedSize(); - // create a buffer of size pTask->m_nBufferSize + // create a buffer of size m_nBufferSize CUSTOM_COPY_PARAMS ccp; ccp.bProcessed = false; - ccp.pTask=pTask; - ccp.bOnlyCreate=(pTask->GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_CONTENT) != 0; - ccp.dbBuffer.Create(pTask->GetBufferSizes()); + ccp.bOnlyCreate=(GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_CONTENT) != 0; + ccp.dbBuffer.Create(GetBufferSizes()); // helpers - //CFileInfo fi; // for currently processed element - DWORD dwLastError; + DWORD dwLastError = 0; // begin at index which wasn't processed previously - size_t stSize = 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(); + size_t stSize = FilesGetSize(); + int iCopiesCount = GetCopies(); + bool bIgnoreFolders = (GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_DIRS) != 0; + bool bForceDirectories = (GetStatus(ST_SPECIAL_MASK) & ST_FORCE_DIRS) != 0; + const CDestPath& dpDestPath = GetDestPath(); // log - const BUFFERSIZES* pbs=ccp.dbBuffer.GetSizes(); + const BUFFERSIZES* pbs = ccp.dbBuffer.GetSizes(); ictranslate::CFormat fmt; fmt.SetFormat(_T("Processing files/folders (ProcessFiles):\r\n\tOnlyCreate: %create\r\n\tBufferSize: [Def:%defsize, One:%onesize, Two:%twosize, CD:%cdsize, LAN:%lansize]\r\n\tFiles/folders count: %filecount\r\n\tCopies count: %copycount\r\n\tIgnore Folders: %ignorefolders\r\n\tDest path: %dstpath\r\n\tCurrent pass (0-based): %currpass\r\n\tCurrent index (0-based): %currindex")); @@ -2313,76 +1982,76 @@ fmt.SetParam(_t("%copycount"), iCopiesCount); fmt.SetParam(_t("%ignorefolders"), bIgnoreFolders); fmt.SetParam(_t("%dstpath"), dpDestPath.GetPath()); - fmt.SetParam(_t("%currpass"), pTask->GetCurrentCopy()); - fmt.SetParam(_t("%currindex"), pTask->GetCurrentIndex()); + fmt.SetParam(_t("%currpass"), GetCurrentCopy()); + fmt.SetParam(_t("%currindex"), GetCurrentIndex()); - pTask->m_log.logi(fmt); + m_log.logi(fmt); - for (unsigned char j=pTask->GetCurrentCopy();jSetCurrentCopy(j); - for (size_t i = pTask->GetCurrentIndex(); i < stSize; i++) + SetCurrentCopy(j); + for (size_t i = GetCurrentIndex(); i < stSize; i++) { // should we kill ? - if (pTask->GetKillFlag()) + if(GetKillFlag()) { // log - pTask->m_log.logi(_T("Kill request while processing file in ProcessFiles")); - throw new CProcessingException(E_KILL_REQUEST, pTask); + m_log.logi(_T("Kill request while processing file in ProcessFiles")); + throw new CProcessingException(E_KILL_REQUEST); } // update m_stCurrentIndex, getting current CFileInfo - pTask->SetCurrentIndex(i); - CFileInfo& fi=pTask->FilesGetAtCurrentIndex(); + SetCurrentIndex(i); + CFileInfoPtr spFileInfo = FilesGetAtCurrentIndex(); // set dest path with filename - ccp.strDstFile=fi.GetDestinationPath(dpDestPath.GetPath(), j, ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); + ccp.strDstFile = spFileInfo->GetDestinationPath(dpDestPath.GetPath(), j, ((int)bForceDirectories) << 1 | (int)bIgnoreFolders); // are the files/folders lie on the same partition ? - bool bMove=pTask->GetStatus(ST_OPERATION_MASK) == ST_MOVE; - if (bMove && dpDestPath.GetDriveNumber() != -1 && dpDestPath.GetDriveNumber() == fi.GetDriveNumber() && iCopiesCount == 1 && fi.GetMove()) + bool bMove=GetStatus(ST_OPERATION_MASK) == ST_MOVE; + if(bMove && dpDestPath.GetDriveNumber() != -1 && dpDestPath.GetDriveNumber() == spFileInfo->GetDriveNumber() && iCopiesCount == 1 && spFileInfo->GetMove()) { bool bRetry = true; - if(bRetry && !MoveFile(fi.GetFullFilePath(), ccp.strDstFile)) + if(bRetry && !MoveFile(spFileInfo->GetFullFilePath(), ccp.strDstFile)) { dwLastError=GetLastError(); //log fmt.SetFormat(_T("Error %errno while calling MoveFile %srcpath -> %dstpath (ProcessFiles)")); fmt.SetParam(_t("%errno"), dwLastError); - fmt.SetParam(_t("%srcpath"), fi.GetFullFilePath()); + fmt.SetParam(_t("%srcpath"), spFileInfo->GetFullFilePath()); fmt.SetParam(_t("%dstpath"), ccp.strDstFile); - pTask->m_log.loge(fmt); + m_log.loge(fmt); - CString strSrcFile = fi.GetFullFilePath(); + CString strSrcFile = spFileInfo->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); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: continue; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pTask); + throw new CProcessingException(E_PAUSE); 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")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } else - fi.SetFlags(FIF_PROCESSED, FIF_PROCESSED); + spFileInfo->SetFlags(FIF_PROCESSED, FIF_PROCESSED); } else { // if folder - create it - if ( fi.IsDirectory() ) + if(spFileInfo->IsDirectory()) { bool bRetry = true; if(bRetry && !CreateDirectory(ccp.strDstFile, NULL) && (dwLastError=GetLastError()) != ERROR_ALREADY_EXISTS ) @@ -2391,134 +2060,125 @@ 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); + m_log.loge(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); + throw new CProcessingException(E_CANCEL); break; case CFeedbackHandler::eResult_Retry: continue; break; case CFeedbackHandler::eResult_Pause: - throw new CProcessingException(E_PAUSE, pTask); + throw new CProcessingException(E_PAUSE); 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")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); } } - pTask->IncreaseProcessedSize(fi.GetLength64()); - pTask->IncreaseProcessedTasksSize(fi.GetLength64()); - fi.SetFlags(FIF_PROCESSED, FIF_PROCESSED); + IncreaseProcessedSize(spFileInfo->GetLength64()); + IncreaseProcessedTasksSize(spFileInfo->GetLength64()); + spFileInfo->SetFlags(FIF_PROCESSED, FIF_PROCESSED); } else { // start copying/moving file - ccp.pfiSrcFile=&fi; + ccp.spSrcFile = spFileInfo; ccp.bProcessed = false; // kopiuj dane CustomCopyFile(&ccp); - fi.SetFlags(ccp.bProcessed ? FIF_PROCESSED : 0, FIF_PROCESSED); + spFileInfo->SetFlags(ccp.bProcessed ? FIF_PROCESSED : 0, FIF_PROCESSED); // if moving - delete file (only if config flag is set) - if (bMove && fi.GetFlags() & FIF_PROCESSED && !GetConfig().get_bool(PP_CMDELETEAFTERFINISHED) && j == iCopiesCount-1) + if(bMove && spFileInfo->GetFlags() & FIF_PROCESSED && !GetConfig().get_bool(PP_CMDELETEAFTERFINISHED) && j == iCopiesCount-1) { - if (!GetConfig().get_bool(PP_CMPROTECTROFILES)) - SetFileAttributes(fi.GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); - DeleteFile(fi.GetFullFilePath()); // there will be another try later, so I don't check + if(!GetConfig().get_bool(PP_CMPROTECTROFILES)) + SetFileAttributes(spFileInfo->GetFullFilePath(), FILE_ATTRIBUTE_NORMAL); + DeleteFile(spFileInfo->GetFullFilePath()); // there will be another try later, so I don't check // if succeeded } } // set a time - if (GetConfig().get_bool(PP_CMSETDESTDATE)) - SetFileDirectoryTime(ccp.strDstFile, &fi); // no error check - ma�o istotne + if(GetConfig().get_bool(PP_CMSETDESTDATE)) + SetFileDirectoryTime(ccp.strDstFile, spFileInfo); // no error checking (but most probably it should be checked) // attributes - if (GetConfig().get_bool(PP_CMSETDESTATTRIBUTES)) - SetFileAttributes(ccp.strDstFile, fi.GetAttributes()); // j.w. + if(GetConfig().get_bool(PP_CMSETDESTATTRIBUTES)) + SetFileAttributes(ccp.strDstFile, spFileInfo->GetAttributes()); // as above } } - // current copy finished - change what's needed - pTask->SetCurrentIndex(0); + // current copy finished + SetCurrentIndex(0); } // delete buffer - it's not needed ccp.dbBuffer.Delete(); // change status - if (pTask->GetStatus(ST_OPERATION_MASK) == ST_MOVE) + if(GetStatus(ST_OPERATION_MASK) == ST_MOVE) { - pTask->SetStatus(ST_DELETING, ST_STEP_MASK); + SetStatus(ST_DELETING, ST_STEP_MASK); // set the index to 0 before deleting - pTask->SetCurrentIndex(0); + SetCurrentIndex(0); } else { - pTask->SetStatus(ST_FINISHED, ST_STEP_MASK); + SetStatus(ST_FINISHED, ST_STEP_MASK); // to look better - increase current index by 1 - pTask->SetCurrentIndex(stSize); + SetCurrentIndex(stSize); } // log - pTask->m_log.logi(_T("Finished processing in ProcessFiles")); + m_log.logi(_T("Finished processing in ProcessFiles")); } -void CTask::CheckForWaitState(CTask* pTask) +void CTask::CheckForWaitState() { // limiting operation count - pTask->SetStatus(ST_WAITING, ST_WAITING_MASK); + SetStatus(ST_WAITING, ST_WAITING_MASK); bool bContinue=false; - while (!bContinue) + while(!bContinue) { - if (pTask->CanBegin()) + if(CanBegin()) { TRACE("CAN BEGIN ALLOWED TO CONTINUE...\n"); - pTask->SetStatus(0, ST_WAITING); + SetStatus(0, ST_WAITING); bContinue=true; - pTask->m_log.logi(_T("Finished waiting for begin permission")); + m_log.logi(_T("Finished waiting for begin permission")); // return; // skips sleep and kill flag checking } Sleep(50); // not to make it too hard for processor - if (pTask->GetKillFlag()) + if(GetKillFlag()) { // log - pTask->m_log.logi(_T("Kill request while waiting for begin permission (wait state)")); - throw new CProcessingException(E_KILL_REQUEST, pTask); + m_log.logi(_T("Kill request while waiting for begin permission (wait state)")); + throw new CProcessingException(E_KILL_REQUEST); } } } -int CTask::OnBeginTask() -{ - return rand(); -} - -int CTask::OnEndTask(int i) -{ - return i + 2; -} - UINT CTask::ThrdProc(LPVOID pParam) { TRACE("\n\nENTERING ThrdProc (new task started)...\n"); - CTask* pTask=static_cast(pParam); - pTask->OnBeginTask(); + + CTask* pTask = static_cast(pParam); + chcore::IFeedbackHandler* piFeedbackHandler = pTask->GetFeedbackHandler(); tstring_t strPath = pTask->GetTaskPath(); @@ -2545,16 +2205,16 @@ try { // to make the value stable - bool bReadTasksSize=GetConfig().get_bool(PP_CMREADSIZEBEFOREBLOCKING); + bool bReadTasksSize = GetConfig().get_bool(PP_CMREADSIZEBEFOREBLOCKING); - if (!bReadTasksSize) - CheckForWaitState(pTask); // operation limiting + if(!bReadTasksSize) + pTask->CheckForWaitState(); // operation limiting // set what's needed pTask->m_lLastTime=(long)time(NULL); // last time (start counting) // search for files if needed - if ((pTask->GetStatus(ST_STEP_MASK) == ST_NULL_STATUS + if((pTask->GetStatus(ST_STEP_MASK) == ST_NULL_STATUS || pTask->GetStatus(ST_STEP_MASK) == ST_SEARCHING)) { // get rid of info about processed sizes @@ -2564,15 +2224,15 @@ pTask->SetAllSize(0); // start searching - RecurseDirectories(pTask); + pTask->RecurseDirectories(); } // check for free space ull_t ullNeededSize = 0, ullAvailableSize = 0; l_showfeedback: pTask->m_log.logi(_T("Checking for free space on destination disk...")); - if (!pTask->GetRequiredFreeSpace(&ullNeededSize, &ullAvailableSize)) + if(!pTask->GetRequiredFreeSpace(&ullNeededSize, &ullAvailableSize)) { fmt.SetFormat(_T("Not enough free space on disk - needed %needsize bytes for data, available: %availablesize bytes.")); fmt.SetParam(_t("%needsize"), ullNeededSize); @@ -2594,7 +2254,7 @@ case CFeedbackHandler::eResult_Cancel: { pTask->m_log.logi(_T("Cancel request while checking for free space on disk.")); - throw new CProcessingException(E_CANCEL, pTask); + throw new CProcessingException(E_CANCEL); break; } case CFeedbackHandler::eResult_Retry: @@ -2606,33 +2266,33 @@ break; default: BOOST_ASSERT(FALSE); // unknown result - throw new CProcessingException(E_ERROR, pTask, 0, _t("Unknown feedback result type")); + throw new CProcessingException(E_ERROR, 0, _t("Unknown feedback result type")); break; } } } - if (bReadTasksSize) + if(bReadTasksSize) { pTask->UpdateTime(); pTask->m_lLastTime=-1; - CheckForWaitState(pTask); + pTask->CheckForWaitState(); pTask->m_lLastTime=(long)time(NULL); } // Phase II - copying/moving - if (pTask->GetStatus(ST_STEP_MASK) == ST_COPYING) + if(pTask->GetStatus(ST_STEP_MASK) == ST_COPYING) { // decrease processed in ctaskarray - the rest will be done in ProcessFiles pTask->DecreaseProcessedTasksSize(pTask->GetProcessedSize()); - ProcessFiles(pTask); + pTask->ProcessFiles(); } // deleting data - III phase - if (pTask->GetStatus(ST_STEP_MASK) == ST_DELETING) - DeleteFiles(pTask); + if(pTask->GetStatus(ST_STEP_MASK) == ST_DELETING) + pTask->DeleteFiles(); // refresh time pTask->UpdateTime(); @@ -2675,7 +2335,7 @@ fmt.SetParam(_t("%type"), e->m_iType); pTask->m_log.loge(fmt); - if (e->m_iType == E_ERROR) + if(e->m_iType == E_ERROR) piFeedbackHandler->RequestFeedback(CFeedbackHandler::eFT_OperationError, NULL); // perform some adjustments depending on exception type @@ -2712,7 +2372,7 @@ break; } - if (pTask->GetStatus(ST_WAITING_MASK) & ST_WAITING) + if(pTask->GetStatus(ST_WAITING_MASK) & ST_WAITING) pTask->SetStatus(0, ST_WAITING); pTask->DecreaseOperationsPending(); @@ -2726,8 +2386,405 @@ return 0xffffffff; // almost like -1 } - pTask->OnEndTask(7); - TRACE("TASK FINISHED - exiting ThrdProc.\n"); return 0; } + +//////////////////////////////////////////////////////////////////////////////// +// CTaskArray members +CTaskArray::CTaskArray() : +m_uhRange(0), +m_uhPosition(0), +m_uiOperationsPending(0), +m_lFinished(0), +m_piFeedbackFactory(NULL), +m_stNextSessionUniqueID(0) +{ +} + +CTaskArray::~CTaskArray() +{ + // NOTE: do not delete the feedback factory, since we are not responsible for releasing it +} + +void CTaskArray::Create(chcore::IFeedbackHandlerFactory* piFeedbackHandlerFactory) +{ + BOOST_ASSERT(piFeedbackHandlerFactory); + + m_tcd.pLock=&m_lock; + m_tcd.pTasksAll=&m_uhRange; + m_tcd.pTasksProcessed=&m_uhPosition; + m_tcd.puiOperationsPending=&m_uiOperationsPending; + m_tcd.plFinished=&m_lFinished; + m_piFeedbackFactory = piFeedbackHandlerFactory; +} + +CTaskPtr CTaskArray::CreateTask() +{ + BOOST_ASSERT(m_piFeedbackFactory); + if(!m_piFeedbackFactory) + return CTaskPtr(); + + chcore::IFeedbackHandler* piHandler = m_piFeedbackFactory->Create(); + if(!piHandler) + return CTaskPtr(); + + CTaskPtr spTask = boost::make_shared(piHandler, &m_tcd, m_stNextSessionUniqueID++); + return spTask; +} + +size_t CTaskArray::GetSize() const +{ + boost::shared_lock lock(m_lock); + return m_vTasks.size(); +} + +CTaskPtr CTaskArray::GetAt(size_t nIndex) const +{ + boost::shared_lock lock(m_lock); + + _ASSERTE(nIndex >= 0 && nIndex < m_vTasks.size()); + if(nIndex >= m_vTasks.size()) + THROW(_t("Invalid argument"), 0, 0, 0); + + return m_vTasks.at(nIndex); +} + +CTaskPtr CTaskArray::GetTaskBySessionUniqueID(size_t stSessionUniqueID) const +{ + CTaskPtr spFoundTask; + + boost::shared_lock lock(m_lock); + BOOST_FOREACH(const CTaskPtr& spTask, m_vTasks) + { + if(spTask->GetSessionUniqueID() == stSessionUniqueID) + { + spFoundTask = spTask; + break; + } + } + + return spFoundTask; +} + +size_t CTaskArray::Add(const CTaskPtr& spNewTask) +{ + if(!spNewTask) + THROW(_t("Invalid argument"), 0, 0, 0); + + boost::unique_lock lock(m_lock); + // here we know load succeeded + spNewTask->SetTaskPath(m_strTasksDir.c_str()); + + m_vTasks.push_back(spNewTask); + + m_uhRange += spNewTask->GetAllSize(); + m_uhPosition += spNewTask->GetProcessedSize(); + + return m_vTasks.size() - 1; +} + +void CTaskArray::RemoveAt(size_t stIndex, size_t stCount) +{ + boost::unique_lock lock(m_lock); + + _ASSERTE(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size()); + if(stIndex >= m_vTasks.size() || stIndex + stCount > m_vTasks.size()) + THROW(_t("Invalid argument"), 0, 0, 0); + + for(std::vector::iterator iterTask = m_vTasks.begin() + stIndex; iterTask != m_vTasks.begin() + stIndex + stCount; ++iterTask) + { + CTaskPtr& spTask = *iterTask; + + // kill task if needed + spTask->KillThread(); + + m_uhRange -= spTask->GetAllSize(); + m_uhPosition -= spTask->GetProcessedSize(); + } + + // remove elements from array + m_vTasks.erase(m_vTasks.begin() + stIndex, m_vTasks.begin() + stIndex + stCount); +} + +void CTaskArray::RemoveAll() +{ + boost::unique_lock lock(m_lock); + + StopAllTasksNL(); + + m_vTasks.clear(); +} + +void CTaskArray::RemoveAllFinished() +{ + std::vector vTasksToRemove; + + m_lock.lock(); + + size_t stIndex = m_vTasks.size(); + while(stIndex--) + { + CTaskPtr spTask = m_vTasks.at(stIndex); + + // delete only when the thread is finished + if((spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED) + && spTask->GetKilledFlag()) + { + m_uhRange -= spTask->GetAllSize(); + m_uhPosition -= spTask->GetProcessedSize(); + + vTasksToRemove.push_back(spTask); + m_vTasks.erase(m_vTasks.begin() + stIndex); + } + } + + m_lock.unlock(); + + BOOST_FOREACH(CTaskPtr& spTask, vTasksToRemove) + { + // delete associated files + spTask->DeleteProgress(m_strTasksDir.c_str()); + } +} + +void CTaskArray::RemoveFinished(const CTaskPtr& spSelTask) +{ + boost::unique_lock lock(m_lock); + + // this might be optimized by copying tasks to a local table in critical section, and then deleting progress files outside of the critical section + for(std::vector::iterator iterTask = m_vTasks.begin(); iterTask != m_vTasks.end(); ++iterTask) + { + CTaskPtr& spTask = *iterTask; + + if(spTask == spSelTask && (spTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || spTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED)) + { + // kill task if needed + spTask->KillThread(); + + m_uhRange -= spTask->GetAllSize(); + m_uhPosition -= spTask->GetProcessedSize(); + + // delete associated files + spTask->DeleteProgress(m_strTasksDir.c_str()); + + m_vTasks.erase(iterTask); + + return; + } + } +} + +void CTaskArray::StopAllTasks() +{ + boost::unique_lock lock(m_lock); + + StopAllTasksNL(); +} + +void CTaskArray::ResumeWaitingTasks(size_t stMaxRunningTasks) +{ + boost::unique_lock lock(m_lock); + if(stMaxRunningTasks == 0 || m_uiOperationsPending < stMaxRunningTasks) + { + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + // turn on some thread - find something with wait state + if(spTask->GetStatus(ST_WAITING_MASK) & ST_WAITING && (stMaxRunningTasks == 0 || m_uiOperationsPending < stMaxRunningTasks)) + { + spTask->SetContinueFlag(true); + ++m_uiOperationsPending; + spTask->SetStatus(0, ST_WAITING); // turn off wait state + } + } + } +} + +void CTaskArray::SaveData() +{ + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->Store(true); + } +} + +void CTaskArray::SaveProgress() +{ + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->Store(false); + } +} + +void CTaskArray::LoadDataProgress() +{ + CFileFind finder; + CTaskPtr spTask; + CString strPath; + + BOOL bWorking=finder.FindFile(CString(m_strTasksDir.c_str())+_T("*.atd")); + while(bWorking) + { + bWorking = finder.FindNextFile(); + + // load data + spTask = CreateTask(); + try + { + strPath = finder.GetFilePath(); + + spTask->Load(strPath, true); + + strPath = strPath.Left(strPath.GetLength() - 4); + strPath += _T(".atp"); + + spTask->Load(strPath, false); + + // add read task to array + Add(spTask); + } + catch(std::exception& e) + { + CString strFmt; + strFmt.Format(_T("Cannot load task data: %s (reason: %S)"), strPath, e.what()); + LOG_ERROR(strFmt); + } + } + finder.Close(); +} + +void CTaskArray::TasksBeginProcessing() +{ + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->BeginProcessing(); + } +} + +void CTaskArray::TasksPauseProcessing() +{ + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->PauseProcessing(); + } +} + +void CTaskArray::TasksResumeProcessing() +{ + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->ResumeProcessing(); + } +} + +void CTaskArray::TasksRestartProcessing() +{ + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->RestartProcessing(); + } +} + +bool CTaskArray::TasksRetryProcessing(bool bOnlyErrors/*=false*/, UINT uiInterval) +{ + boost::shared_lock lock(m_lock); + bool bChanged=false; + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + if(spTask->RetryProcessing(bOnlyErrors, uiInterval)) + bChanged = true; + } + + return bChanged; +} + +void CTaskArray::TasksCancelProcessing() +{ + boost::shared_lock lock(m_lock); + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->CancelProcessing(); + } +} + +ull_t CTaskArray::GetPosition() +{ + boost::shared_lock lock(m_lock); + return m_uhPosition; +} + +ull_t CTaskArray::GetRange() +{ + boost::shared_lock lock(m_lock); + return m_uhRange; +} + +int CTaskArray::GetPercent() +{ + int pos = 0; + + boost::shared_lock lock(m_lock); + + if(m_uhRange != 0) + pos = static_cast((static_cast(m_uhPosition)*100.0)/static_cast(m_uhRange)); + else + { + if(GetSize() != 0) // if anything is in an array, but size of it is 0 + pos = 100; + else + pos = 0; + } + + return pos; +} + +bool CTaskArray::IsFinished() +{ + bool bFlag=true; + UINT uiStatus; + + boost::shared_lock lock(m_lock); + if(m_uiOperationsPending != 0) + bFlag = false; + else + { + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + uiStatus = spTask->GetStatus(); + bFlag = ((uiStatus & ST_STEP_MASK) == ST_FINISHED || (uiStatus & ST_STEP_MASK) == ST_CANCELLED + || (uiStatus & ST_WORKING_MASK) == ST_PAUSED + || ((uiStatus & ST_WORKING_MASK) == ST_ERROR && !GetConfig().get_bool(PP_CMAUTORETRYONERROR))); + } + } + + return bFlag; +} + +void CTaskArray::SetTasksDir(const tchar_t* pszPath) +{ + boost::unique_lock lock(m_lock); + m_strTasksDir = pszPath; +} + +void CTaskArray::StopAllTasksNL() +{ + // kill all unfinished tasks - send kill request + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + spTask->SetKillFlagNL(); + } + + // wait for finishing + BOOST_FOREACH(CTaskPtr& spTask, m_vTasks) + { + while(!spTask->GetKilledFlagNL()) + Sleep(10); + spTask->CleanupAfterKillNL(); + } +} Index: src/ch/task.h =================================================================== diff -u -N -rf703b71b8c856e2538283555e9fdbc84918677c3 -r22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1 --- src/ch/task.h (.../task.h) (revision f703b71b8c856e2538283555e9fdbc84918677c3) +++ src/ch/task.h (.../task.h) (revision 22bbc4a87fa0b249e1e02ba385f28da9d77a4aa1) @@ -1,5 +1,5 @@ /*************************************************************************** -* Copyright (C) 2001-2008 by J�zef Starosczyk * +* Copyright (C) 2001-2008 by Jozef Starosczyk * * ixen@copyhandler.com * * * * This program is free software; you can redistribute it and/or modify * @@ -82,13 +82,13 @@ UINT *puiOperationsPending; LONG *plFinished; - CCriticalSection* pcs; + boost::shared_mutex* pLock; }; // structure for gettings status of a task struct TASK_DISPLAY_DATA { - CFileInfo m_fi; // fi at CurrIndex + CFileInfoPtr m_spFileInfo; // fi at CurrIndex int m_iCurrentBufferIndex; size_t m_stIndex; size_t m_stSize; @@ -119,22 +119,20 @@ struct TASK_MINI_DISPLAY_DATA { - CFileInfo m_fi; // fi at CurrIndex + CFileInfoPtr m_spFileInfo; // fi at CurrIndex UINT m_uiStatus; int m_nPercent; }; struct CUSTOM_COPY_PARAMS { - CTask* pTask; // ptr to CTask object on which we do the operation + CFileInfoPtr spSrcFile; // CFileInfo - src file + CString strDstFile; // dest path with filename - CFileInfo* pfiSrcFile; // CFileInfo - src file - CString strDstFile; // dest path with filename - - CDataBuffer dbBuffer; // buffer handling - bool bOnlyCreate; // flag from configuration - skips real copying - only create - bool bProcessed; // has the element been processed ? (false if skipped) + CDataBuffer dbBuffer; // buffer handling + bool bOnlyCreate; // flag from configuration - skips real copying - only create + bool bProcessed; // has the element been processed ? (false if skipped) }; /// class encapsulates windows HANDLE, allowing automatic closing it in destructor. @@ -235,28 +233,23 @@ CTask(chcore::IFeedbackHandler* piFeedbackHandler, const TASK_CREATE_DATA *pCreateData, size_t stSessionUniqueID); ~CTask(); - int OnBeginTask(); - int OnEndTask(int i); - - // m_clipboard void AddClipboardData(const CClipboardEntryPtr& spEntry); CClipboardEntryPtr GetClipboardData(size_t stIndex); - size_t GetClipboardDataSize(); - int ReplaceClipboardStrings(CString strOld, CString strNew); + size_t GetClipboardDataSize(); + int ReplaceClipboardStrings(CString strOld, CString strNew); // m_files - int FilesAddDir(const CString strDirName, const CFiltersArray* pFilters, size_t stSrcIndex, - const bool bRecurse, const bool bIncludeDirs); - void FilesAdd(CFileInfo fi); - CFileInfo FilesGetAt(size_t stIndex); - CFileInfo& FilesGetAtCurrentIndex(); + int FilesAddDir(CString strDirName, size_t stSrcIndex, bool bRecurse, bool bIncludeDirs); + void FilesAdd(const CFileInfoPtr& spFileInfo); + CFileInfoPtr FilesGetAt(size_t stIndex); + CFileInfoPtr FilesGetAtCurrentIndex(); void FilesRemoveAll(); size_t FilesGetSize(); // m_stCurrentIndex void IncreaseCurrentIndex(); - size_t GetCurrentIndex(); + size_t GetCurrentIndex(); void SetCurrentIndex(size_t stIndex); // m_strDestPath @@ -266,7 +259,7 @@ // m_nStatus void SetStatus(UINT nStatus, UINT nMask); - UINT GetStatus(UINT nMask=0xffffffff); + UINT GetStatus(UINT nMask = 0xffffffff); // m_nBufferSize void SetBufferSizes(const BUFFERSIZES* bsSizes); @@ -279,29 +272,29 @@ void SetPriority(int nPriority); // m_nProcessed - void IncreaseProcessedSize(__int64 nSize); - void SetProcessedSize(__int64 nSize); + void IncreaseProcessedSize(__int64 nSize); + void SetProcessedSize(__int64 nSize); __int64 GetProcessedSize(); // m_nAll - void SetAllSize(__int64 nSize); + void SetAllSize(__int64 nSize); __int64 GetAllSize(); - void CalcAllSize(); + void CalcAllSize(); // m_pnTasksProcessed - void IncreaseProcessedTasksSize(__int64 nSize); - void DecreaseProcessedTasksSize(__int64 nSize); + void IncreaseProcessedTasksSize(__int64 nSize); + void DecreaseProcessedTasksSize(__int64 nSize); // m_pnTasksAll - void IncreaseAllTasksSize(__int64 nSize); - void DecreaseAllTasksSize(__int64 nSize); + void IncreaseAllTasksSize(__int64 nSize); + void DecreaseAllTasksSize(__int64 nSize); // m_bKill - void SetKillFlag(bool bKill=true); + void SetKillFlag(bool bKill = true); bool GetKillFlag(); // m_bKilled - void SetKilledFlag(bool bKilled=true); + void SetKilledFlag(bool bKilled = true); bool GetKilledFlag(); void KillThread(); @@ -329,15 +322,14 @@ void SetOsErrorCode(DWORD dwError, LPCTSTR lpszErrDesc); void CalcProcessedSize(); - void DecreaseOperationsPending(UINT uiBy=1); - void IncreaseOperationsPending(UINT uiBy=1); + void DecreaseOperationsPending(UINT uiBy = 1); + void IncreaseOperationsPending(UINT uiBy = 1); bool CanBegin(); void UpdateTime(); void SetFilters(const CFiltersArray* pFilters); - const CFiltersArray* GetFilters(); void SetCopies(unsigned char ucCopies); unsigned char GetCopies(); @@ -349,37 +341,84 @@ void SetLastProcessedIndex(size_t stIndex); size_t GetLastProcessedIndex(); - // CString GetLogName(); - bool GetRequiredFreeSpace(ull_t *pi64Needed, ull_t *pi64Available); void SetTaskPath(const tchar_t* pszDir); const tchar_t* GetTaskPath() const; chcore::IFeedbackHandler* GetFeedbackHandler() const { return m_piFeedbackHandler; } - void SetForceFlag(bool bFlag=true); + void SetForceFlag(bool bFlag = true); bool GetForceFlag(); - void SetContinueFlag(bool bFlag=true); + void SetContinueFlag(bool bFlag = true); bool GetContinueFlag(); - size_t GetSessionUniqueID() const { return m_stSessionUniqueID; } + size_t GetSessionUniqueID() const { return m_stSessionUniqueID; } protected: static UINT ThrdProc(LPVOID pParam); - static void CheckForWaitState(CTask* pTask); - static void ProcessFiles(CTask* pTask); - static void CustomCopyFile(CUSTOM_COPY_PARAMS* pData); - static void DeleteFiles(CTask* pTask); - static void RecurseDirectories(CTask* pTask); - static bool SetFileDirectoryTime(LPCTSTR lpszName, CFileInfo* pSrcInfo); + void CheckForWaitState(); + void ProcessFiles(); + void CustomCopyFile(CUSTOM_COPY_PARAMS* pData); + void DeleteFiles(); + void RecurseDirectories(); + static bool SetFileDirectoryTime(LPCTSTR lpszName, const CFileInfoPtr& spFileInfo); -public: - // CLogFile m_log; + void IncreaseCurrentIndexNL(); + size_t GetCurrentIndexNL(); + void SetCurrentIndexNL(size_t stIndex); + + // m_strDestPath + void SetDestPathNL(LPCTSTR lpszPath); + const CDestPath& GetDestPathNL(); + int GetDestDriveNumberNL(); + + // m_nStatus + void SetStatusNL(UINT nStatus, UINT nMask); + UINT GetStatusNL(UINT nMask = 0xffffffff); + + // m_nBufferSize + void SetBufferSizesNL(const BUFFERSIZES* bsSizes); + const BUFFERSIZES* GetBufferSizesNL(); + int GetCurrentBufferIndexNL(); + + // m_pThread + // m_nPriority + int GetPriorityNL(); + void SetPriorityNL(int nPriority); + + // m_nProcessed + void IncreaseProcessedSizeNL(__int64 nSize); + void SetProcessedSizeNL(__int64 nSize); + __int64 GetProcessedSizeNL(); + + // m_nAll + void SetAllSizeNL(__int64 nSize); + __int64 GetAllSizeNL(); + void CalcAllSizeNL(); + + void SetKillFlagNL(bool bKill = true); + bool GetKillFlagNL(); + + void SetKilledFlagNL(bool bKilled = true); + bool GetKilledFlagNL(); + + void CleanupAfterKillNL(); + void UpdateTimeNL(); + + CString GetUniqueNameNL(); + + void SetForceFlagNL(bool bFlag = true); + bool GetForceFlagNL(); + void SetContinueFlagNL(bool bFlag = true); + bool GetContinueFlagNL(); + +private: icpf::log_file m_log; - mutable CCriticalSection m_cs; // protection for this class + mutable boost::shared_mutex m_lock; // protection for this class UINT m_uiResumeInterval; // works only if the thread is off + // time long m_lTimeElapsed; // store long m_lLastTime; // not store @@ -392,7 +431,6 @@ bool m_bForce; // if the continuation of tasks should be independent of limitation bool m_bContinue; // used by ClipboardMonitorProc -protected: CClipboardArray m_clipboard; CFileInfoArray m_files; volatile size_t m_stCurrentIndex; @@ -437,9 +475,11 @@ tstring_t m_strTaskBasePath; // base path at which the files will be stored bool m_bSaved; // has the state been saved ('til next modification) - size_t m_stSessionUniqueID; + size_t m_stSessionUniqueID; - CCriticalSection* m_pcs; // protects *m_pnTasksProcessed & *m_pnTasksAll from external array + boost::shared_mutex* m_pLock; // protects *m_pnTasksProcessed & *m_pnTasksAll from external array + + friend class CTaskArray; }; typedef boost::shared_ptr CTaskPtr; @@ -450,14 +490,13 @@ class CProcessingException { public: - CProcessingException(int iType, CTask* pTask) { m_iType=iType; m_pTask=pTask; m_dwError=0; }; - CProcessingException(int iType, CTask* pTask, UINT uiFmtID, DWORD dwError, ...); - CProcessingException(int iType, CTask* pTask, DWORD dwError, const tchar_t* pszDesc); + CProcessingException(int iType) { m_iType=iType; m_dwError=0; }; + CProcessingException(int iType, UINT uiFmtID, DWORD dwError, ...); + CProcessingException(int iType, DWORD dwError, const tchar_t* pszDesc); // Implementation public: int m_iType; // kill request, error, ... - CTask* m_pTask; CString m_strErrorDesc; DWORD m_dwError; @@ -466,7 +505,7 @@ /////////////////////////////////////////////////////////////////////////// // CTaskArray -class CTaskArray// : public CArray +class CTaskArray { public: CTaskArray(); @@ -476,18 +515,20 @@ CTaskPtr CreateTask(); - size_t GetSize(); + size_t GetSize() const; - CTaskPtr GetAt(size_t stIndex); - CTaskPtr GetTaskBySessionUniqueID(size_t stSessionUniqueID); + CTaskPtr GetAt(size_t stIndex) const; + CTaskPtr GetTaskBySessionUniqueID(size_t stSessionUniqueID) const; + size_t Add(const CTaskPtr& spNewTask); void RemoveAt(size_t stIndex, size_t stCount = 1); void RemoveAll(); void RemoveAllFinished(); void RemoveFinished(const CTaskPtr& spSelTask); - void StopAllTasks(); + void ResumeWaitingTasks(size_t stMaxRunningTasks); + void StopAllTasks(); void SaveData(); void SaveProgress(); @@ -502,29 +543,28 @@ ull_t GetPosition(); ull_t GetRange(); - int GetPercent(); + int GetPercent(); - UINT GetOperationsPending(); - void SetLimitOperations(UINT uiLimit); - UINT GetLimitOperations(); - bool IsFinished(); void SetTasksDir(const tchar_t* pszPath); +protected: + void StopAllTasksNL(); + public: __int64 m_uhRange, m_uhPosition; tstring_t m_strTasksDir; UINT m_uiOperationsPending; // count of current operations LONG m_lFinished; // count of finished tasks - CCriticalSection m_cs; + mutable boost::shared_mutex m_lock; TASK_CREATE_DATA m_tcd; private: - std::vector m_vTasks; - size_t m_stNextSessionUniqueID; + std::vector m_vTasks; + size_t m_stNextSessionUniqueID; protected: chcore::IFeedbackHandlerFactory* m_piFeedbackFactory;