Index: ch/Structs.cpp =================================================================== diff -u -N --- ch/Structs.cpp (revision 6472716fec44f80b223922d89f269e365aeaba60) +++ ch/Structs.cpp (revision 0) @@ -1,1578 +0,0 @@ -/************************************************************************ - Copy Handler 1.x - program for copying data in Microsoft Windows - systems. - Copyright (C) 2001-2004 Ixen Gerthannes (copyhandler@o2.pl) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -*************************************************************************/ -#include "stdafx.h" -#include "structs.h" -#include "resource.h" -#include "StringHelpers.h" -#include "..\common\FileSupport.h" -#include "Copy Handler.h" - -#ifdef _DEBUG -#define new DEBUG_NEW -#endif - -// global -int PriorityToIndex(int nPriority) -{ - switch(nPriority) - { - case THREAD_PRIORITY_TIME_CRITICAL: - return 0; - case THREAD_PRIORITY_HIGHEST: - return 1; - case THREAD_PRIORITY_ABOVE_NORMAL: - return 2; - case THREAD_PRIORITY_NORMAL: - return 3; - case THREAD_PRIORITY_BELOW_NORMAL: - return 4; - case THREAD_PRIORITY_LOWEST: - return 5; - case THREAD_PRIORITY_IDLE: - return 6; - default: - return 3; - } -} - -int IndexToPriority(int nIndex) -{ - switch(nIndex) - { - case 0: - return THREAD_PRIORITY_TIME_CRITICAL; - case 1: - return THREAD_PRIORITY_HIGHEST; - case 2: - return THREAD_PRIORITY_ABOVE_NORMAL; - case 3: - return THREAD_PRIORITY_NORMAL; - case 4: - return THREAD_PRIORITY_BELOW_NORMAL; - case 5: - return THREAD_PRIORITY_LOWEST; - case 6: - return THREAD_PRIORITY_IDLE; - default: - return THREAD_PRIORITY_NORMAL; - } -} - -int IndexToPriorityClass(int iIndex) -{ - switch(iIndex) - { - case 0: - return IDLE_PRIORITY_CLASS; - case 1: - return NORMAL_PRIORITY_CLASS; - case 2: - return HIGH_PRIORITY_CLASS; - case 3: - return REALTIME_PRIORITY_CLASS; - default: - return NORMAL_PRIORITY_CLASS; - } -} - -int PriorityClassToIndex(int iPriority) -{ - switch(iPriority) - { - case IDLE_PRIORITY_CLASS: - return 0; - case NORMAL_PRIORITY_CLASS: - return 1; - case HIGH_PRIORITY_CLASS: - return 2; - case REALTIME_PRIORITY_CLASS: - return 3; - default: - return 1; - } -} - -//////////////////////////////////////////////////////////////////////////// -// CTask members - -CTask::CTask(const TASK_CREATE_DATA *pCreateData) : - m_log(false) -{ - m_nCurrentIndex=0; - m_iLastProcessedIndex=-1; - m_nStatus=ST_NULL_STATUS; - m_bsSizes.m_uiDefaultSize=65536; - m_bsSizes.m_uiOneDiskSize=4194304; - m_bsSizes.m_uiTwoDisksSize=262144; - m_bsSizes.m_uiCDSize=262144; - m_bsSizes.m_uiLANSize=65536; - m_pThread=NULL; - m_nPriority=THREAD_PRIORITY_NORMAL; - m_nProcessed=0; - m_nAll=0; - m_pnTasksProcessed=pCreateData->pTasksProcessed; - m_pnTasksAll=pCreateData->pTasksAll; - m_bKill=false; - m_bKilled=true; - m_pcs=pCreateData->pcs; - m_pfnTaskProc=pCreateData->pfnTaskProc; - m_lTimeElapsed=0; - m_lLastTime=-1; - m_puiOperationsPending=pCreateData->puiOperationsPending; - m_bQueued=false; - m_ucCopies=1; - m_ucCurrentCopy=0; - m_files.Init(&m_clipboard); - m_uiResumeInterval=0; - m_plFinished=pCreateData->plFinished; - m_bForce=false; - m_bContinue=false; - m_bSaved=false; - - m_iIdentical=-1; - m_iDestinationLess=-1; - m_iDestinationGreater=-1; - m_iMissingInput=-1; - m_iOutputError=-1; - m_iMoveFile=-1; - - TCHAR xx[16]; - _itot(time(NULL), xx, 10); - m_strUniqueName=xx; -} - -CTask::~CTask() -{ - KillThread(); -} - -// m_clipboard -int CTask::AddClipboardData(CClipboardEntry* pEntry) -{ - m_cs.Lock(); - int retval=m_clipboard.Add(pEntry); - m_cs.Unlock(); - - return retval; -} - -CClipboardEntry* CTask::GetClipboardData(int nIndex) -{ - m_cs.Lock(); - CClipboardEntry* pEntry=m_clipboard.GetAt(nIndex); - m_cs.Unlock(); - - return pEntry; -} - -int CTask::GetClipboardDataSize() -{ - m_cs.Lock(); - int rv=m_clipboard.GetSize(); - m_cs.Unlock(); - - return rv; -} - -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 (int i=0;iGetPath(); - strText.MakeLower(); - iOffset=strText.Find(strOld, 0); - if (iOffset != -1) - { - // found - strText=pEntry->GetPath(); - strText=strText.Left(iOffset)+strNew+strText.Mid(iOffset+strOld.GetLength()); - pEntry->SetPath(strText); - iCount++; - } - } - m_cs.Unlock(); - - return iCount; -} - -// m_files -int CTask::FilesAddDir(const CString strDirName, const CFiltersArray* pFilters, int iSrcIndex, - const bool bRecurse, const bool bIncludeDirs) -{ - // this uses much of memory, but resolves problem critical section hungs and m_bKill - CFileInfoArray fa; - fa.Init(&m_clipboard); - - fa.AddDir(strDirName, pFilters, iSrcIndex, bRecurse, bIncludeDirs, &m_bKill); - - m_cs.Lock(); - - m_files.Append(fa); - - m_cs.Unlock(); - - return 0; -} - -int CTask::FilesAdd(CFileInfo fi) -{ - int rv=-1; - m_cs.Lock(); - if (fi.IsDirectory() || m_afFilters.Match(fi)) - rv=m_files.Add(fi); - m_cs.Unlock(); - - return rv; -} - -CFileInfo CTask::FilesGetAt(int nIndex) -{ - m_cs.Lock(); - CFileInfo info=m_files.GetAt(nIndex); - m_cs.Unlock(); - - return info; -} - -CFileInfo CTask::FilesGetAtCurrentIndex() -{ - m_cs.Lock(); - CFileInfo info=m_files.GetAt(m_nCurrentIndex); - m_cs.Unlock(); - return info; -} - -void CTask::FilesRemoveAll() -{ - m_cs.Lock(); - m_files.RemoveAll(); - m_cs.Unlock(); -} - -int CTask::FilesGetSize() -{ - m_cs.Lock(); - int nSize=m_files.GetSize(); - m_cs.Unlock(); - - return nSize; -} - -// m_nCurrentIndex -void CTask::IncreaseCurrentIndex() -{ - m_cs.Lock(); - ++m_nCurrentIndex; - m_cs.Unlock(); -} - -int CTask::GetCurrentIndex() -{ - m_cs.Lock(); - int nIndex=m_nCurrentIndex; - m_cs.Unlock(); - - return nIndex; -} - -void CTask::SetCurrentIndex(int nIndex) -{ - m_cs.Lock(); - m_nCurrentIndex=nIndex; - m_cs.Unlock(); -} - -// m_strDestPath - adds '\\' -void CTask::SetDestPath(LPCTSTR lpszPath) -{ - m_dpDestPath.SetPath(lpszPath); -} - -// guaranteed '\\' -const CDestPath& CTask::GetDestPath() -{ - return m_dpDestPath; -} - -int CTask::GetDestDriveNumber() -{ - return m_dpDestPath.GetDriveNumber(); -} - -// m_nStatus -void CTask::SetStatus(UINT nStatus, UINT nMask) -{ - m_cs.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); -} - -// m_nBufferSize -void CTask::SetBufferSizes(const BUFFERSIZES* bsSizes) -{ - m_cs.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; -} - -int CTask::GetCurrentBufferIndex() -{ - int rv=0; - m_cs.Lock(); - int iSize=m_files.GetSize(); - if (iSize > 0 && m_nCurrentIndex != -1) - rv=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_nCurrentIndex < iSize) ? m_nCurrentIndex : 0).GetBufferIndex(); - m_cs.Unlock(); - - return rv; -} - -// m_pThread -// m_nPriority -int CTask::GetPriority() -{ - m_cs.Lock(); - int nPriority=m_nPriority; - m_cs.Unlock(); - return nPriority; -} - -void CTask::SetPriority(int nPriority) -{ - m_cs.Lock(); - m_nPriority=nPriority; - m_bSaved=false; - if (m_pThread != NULL) - { - TRACE("Changing thread priority"); - m_pThread->SuspendThread(); - m_pThread->SetThreadPriority(nPriority); - m_pThread->ResumeThread(); - } - m_cs.Unlock(); -} - -// m_nProcessed -void CTask::IncreaseProcessedSize(__int64 nSize) -{ - m_cs.Lock(); - m_nProcessed+=nSize; - m_cs.Unlock(); -} - -void CTask::SetProcessedSize(__int64 nSize) -{ - m_cs.Lock(); - m_nProcessed=nSize; - m_cs.Unlock(); -} - -__int64 CTask::GetProcessedSize() -{ - m_cs.Lock(); - __int64 nSize=m_nProcessed; - m_cs.Unlock(); - - return nSize; -} - -// m_nAll -void CTask::SetAllSize(__int64 nSize) -{ - m_cs.Lock(); - m_nAll=nSize; - m_cs.Unlock(); -} - -__int64 CTask::GetAllSize() -{ - m_cs.Lock(); - __int64 nAll=m_nAll; - m_cs.Unlock(); - - return nAll; -} - -void CTask::CalcAllSize() -{ - m_cs.Lock(); - m_nAll=0; - - int nSize=m_files.GetSize(); - CFileInfo* pFiles=m_files.GetData(); - - for (int i=0;iLock(); - (*m_pnTasksProcessed)+=nSize; - m_pcs->Unlock(); -// m_cs.Unlock(); -} - -void CTask::DecreaseProcessedTasksSize(__int64 nSize) -{ -// m_cs.Lock(); - m_pcs->Lock(); - (*m_pnTasksProcessed)-=nSize; - m_pcs->Unlock(); -// m_cs.Unlock(); -} - -// m_pnTasksAll -void CTask::IncreaseAllTasksSize(__int64 nSize) -{ -// m_cs.Lock(); - m_pcs->Lock(); - (*m_pnTasksAll)+=nSize; - m_pcs->Unlock(); -// m_cs.Unlock(); -} - -void CTask::DecreaseAllTasksSize(__int64 nSize) -{ -// m_cs.Lock(); - m_pcs->Lock(); - (*m_pnTasksAll)-=nSize; - m_pcs->Unlock(); -// m_cs.Unlock(); -} - -// m_bKill -/*inline*/ void CTask::SetKillFlag(bool bKill) -{ - m_cs.Lock(); - m_bKill=bKill; - m_cs.Unlock(); -} - -bool CTask::GetKillFlag() -{ - m_cs.Lock(); - bool bKill=m_bKill; - m_cs.Unlock(); - - return bKill; -} - -// m_bKilled -/*inline*/ void CTask::SetKilledFlag(bool bKilled) -{ - m_cs.Lock(); - m_bKilled=bKilled; - m_cs.Unlock(); -} - -/*inline*/ bool CTask::GetKilledFlag() -{ - m_cs.Lock(); - bool bKilled=m_bKilled; - m_cs.Unlock(); - - return bKilled; -} - -// m_strUniqueName - -CString CTask::GetUniqueName() -{ - m_cs.Lock(); - CString name=m_strUniqueName; - m_cs.Unlock(); - - return name; -} - -void CTask::Load(CArchive& ar, bool bData) -{ - m_cs.Lock(); - try - { - if (bData) - { - m_clipboard.Serialize(ar, bData); - - m_files.Load(ar); - m_dpDestPath.Serialize(ar); - ar>>m_strUniqueName; - m_afFilters.Serialize(ar); - ar>>m_ucCopies; - } - else - { - int data; - unsigned long part; - - ar>>data; - m_nCurrentIndex=data; - ar>>data; - m_nStatus=data; - ar>>m_lOsError; - ar>>m_strErrorDesc; - m_bsSizes.Serialize(ar); - ar>>m_nPriority; - - ar>>part; - m_nAll=(static_cast(part) << 32); - ar>>part; - m_nAll|=part; - // czas - ar>>m_lTimeElapsed; - - ar>>part; - m_nProcessed=(static_cast(part) << 32); - ar>>part; - m_nProcessed|=part; - - ar>>m_ucCurrentCopy; - - m_clipboard.Serialize(ar, bData); - - unsigned char ucTmp; - ar>>ucTmp; - m_bSaved=ucTmp != 0; - } - } - catch(CException*) - { - m_cs.Unlock(); - throw; - } - m_cs.Unlock(); -} - -void CTask::Store(LPCTSTR lpszDirectory, bool bData) -{ - m_cs.Lock(); - if (!bData && m_bSaved) - { - m_cs.Unlock(); - TRACE("Saving locked - file not saved\n"); - return; - } - - if (!bData && !m_bSaved && ( (m_nStatus & ST_STEP_MASK) == ST_FINISHED || (m_nStatus & ST_STEP_MASK) == ST_CANCELLED - || (m_nStatus & ST_WORKING_MASK) == ST_PAUSED )) - { - TRACE("Last save - saving blocked\n"); - m_bSaved=true; - } - - try - { - CFile file(lpszDirectory+GetUniqueName()+( (bData) ? _T(".atd") : _T(".atp") ), CFile::modeWrite | CFile::modeCreate); - CArchive ar(&file, CArchive::store); - - if (bData) - { - m_clipboard.Serialize(ar, bData); - - if (GetStatus(ST_STEP_MASK) > ST_SEARCHING) - m_files.Store(ar); - else - ar<(0); - - m_dpDestPath.Serialize(ar); - ar<((m_nAll & 0xffffffff00000000) >> 32); - ar<(m_nAll & 0x00000000ffffffff); - ar<((m_nProcessed & 0xffffffff00000000) >> 32); - ar<(m_nProcessed & 0x00000000ffffffff); - ar<Delete(); - m_cs.Unlock(); - return; - } - m_cs.Unlock(); -} - -/*inline*/ void CTask::KillThread() -{ - if (!GetKilledFlag()) // protection from recalling Cleanup - { - SetKillFlag(); - while (!GetKilledFlag()) - Sleep(10); - - // cleanup - CleanupAfterKill(); - } -} - -void CTask::BeginProcessing() -{ - m_cs.Lock(); - if (m_pThread != NULL) - { - m_cs.Unlock(); - return; - } - m_cs.Unlock(); - - // create new thread - m_uiResumeInterval=0; // just in case - m_bSaved=false; // save - SetKillFlag(false); - SetKilledFlag(false); - CWinThread* pThread=AfxBeginThread(m_pfnTaskProc, this, GetPriority()); - - m_cs.Lock(); - m_pThread=pThread; - m_cs.Unlock(); -} - -void CTask::ResumeProcessing() -{ - // the same as retry but less demanding - if ( (GetStatus(ST_WORKING_MASK) & ST_PAUSED) && GetStatus(ST_STEP_MASK) != ST_FINISHED - && GetStatus(ST_STEP_MASK) != ST_CANCELLED) - { - SetStatus(0, ST_ERROR); - BeginProcessing(); - } -} - -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)) - && GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) - { - if (uiInterval != 0) - { - m_uiResumeInterval+=uiInterval; - if (m_uiResumeInterval < (UINT)GetConfig()->GetIntValue(PP_CMAUTORETRYINTERVAL)) - return false; - else - m_uiResumeInterval=0; - } - - SetStatus(0, ST_ERROR); - BeginProcessing(); - return true; - } - return false; -} - -void CTask::RestartProcessing() -{ - KillThread(); - SetStatus(0, ST_ERROR); - SetStatus(ST_NULL_STATUS, ST_STEP_MASK); - m_lTimeElapsed=0; - SetCurrentIndex(0); - SetCurrentCopy(0); - BeginProcessing(); -} - -void CTask::PauseProcessing() -{ - if (GetStatus(ST_STEP_MASK) != ST_FINISHED && GetStatus(ST_STEP_MASK) != ST_CANCELLED) - { - KillThread(); - SetStatus(ST_PAUSED, ST_WORKING_MASK); - SetLastProcessedIndex(GetCurrentIndex()); - m_bSaved=false; - } -} - -void CTask::CancelProcessing() -{ - // change to ST_CANCELLED - if (GetStatus(ST_STEP_MASK) != ST_FINISHED) - { - KillThread(); - SetStatus(ST_CANCELLED, ST_STEP_MASK); - SetStatus(0, ST_ERROR); - m_bSaved=false; - } -} - -void CTask::GetMiniSnapshot(TASK_MINI_DISPLAY_DATA *pData) -{ - m_cs.Lock(); - if (m_nCurrentIndex >= 0 && m_nCurrentIndex < m_files.GetSize()) - pData->m_fi=m_files.GetAt(m_nCurrentIndex); - else - { - 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); - } - else - { - if (m_clipboard.GetSize() > 0) - { - pData->m_fi.SetFilePath(m_clipboard.GetAt(0)->GetPath()); - pData->m_fi.SetSrcIndex(-1); - } - else - { - pData->m_fi.SetFilePath(GetResManager()->LoadString(IDS_NONEINPUTFILE_STRING)); - pData->m_fi.SetSrcIndex(-1); - } - } - } - - pData->m_uiStatus=m_nStatus; - - // percents - int iSize=m_files.GetSize()*m_ucCopies; - int iIndex=m_nCurrentIndex+m_ucCurrentCopy*m_files.GetSize(); - 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 (iSize != 0) - pData->m_nPercent=static_cast( static_cast(iIndex)*100.0/static_cast(iSize) ); - else - pData->m_nPercent=0; - - m_cs.Unlock(); -} - -void CTask::GetSnapshot(TASK_DISPLAY_DATA *pData) -{ - m_cs.Lock(); - if (m_nCurrentIndex >= 0 && m_nCurrentIndex < m_files.GetSize()) - pData->m_fi=m_files.GetAt(m_nCurrentIndex); - else - { - 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); - } - else - { - if (m_clipboard.GetSize() > 0) - { - pData->m_fi.SetFilePath(m_clipboard.GetAt(0)->GetPath()); - pData->m_fi.SetSrcIndex(-1); - } - else - { - pData->m_fi.SetFilePath(GetResManager()->LoadString(IDS_NONEINPUTFILE_STRING)); - pData->m_fi.SetSrcIndex(-1); - } - } - } - - pData->m_pbsSizes=&m_bsSizes; - pData->m_nPriority=m_nPriority; - pData->m_pdpDestPath=&m_dpDestPath; - pData->m_pafFilters=&m_afFilters; - pData->m_dwOsErrorCode=m_lOsError; - pData->m_strErrorDesc=m_strErrorDesc; - pData->m_uiStatus=m_nStatus; - pData->m_iIndex=m_nCurrentIndex+m_ucCurrentCopy*m_files.GetSize(); - pData->m_iProcessedSize=m_nProcessed; - pData->m_iSize=m_files.GetSize()*m_ucCopies; - pData->m_iSizeAll=m_nAll; - pData->m_ucCurrentCopy=static_cast(m_ucCurrentCopy+1); // visual aspect - pData->m_ucCopies=m_ucCopies; - pData->m_pstrUniqueName=&m_strUniqueName; - - if (m_files.GetSize() > 0 && m_nCurrentIndex != -1) - pData->m_iCurrentBufferIndex=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_nCurrentIndex < m_files.GetSize()) ? m_nCurrentIndex : 0).GetBufferIndex(); - else - pData->m_iCurrentBufferIndex=0; - - // percents - 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_iSize != 0) - pData->m_nPercent=static_cast( static_cast(pData->m_iIndex)*100.0/static_cast(pData->m_iSize) ); - else - pData->m_nPercent=0; - - // status string - // first - 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 ) - { - 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 ) - { - 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 ) - { - 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 ) - { - GetResManager()->LoadStringCopy(IDS_STATUS0_STRING+8, pData->m_szStatusText, _MAX_PATH); - _tcscat(pData->m_szStatusText, _T("/")); - } - else - _tcscpy(pData->m_szStatusText, _T("")); - - // second part - 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 ) - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_STATUS0_STRING+0)); - else if ((m_nStatus & ST_OPERATION_MASK) == ST_COPY ) - { - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_STATUS0_STRING+1)); - if (m_afFilters.GetSize()) - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_FILTERING_STRING)); - } - else if ( (m_nStatus & ST_OPERATION_MASK) == ST_MOVE ) - { - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_STATUS0_STRING+2)); - if (m_afFilters.GetSize()) - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_FILTERING_STRING)); - } - else - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_STATUS0_STRING+7)); - - // third part - 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 ) - { - _tcscat(pData->m_szStatusText, _T("/")); - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_STATUS0_STRING+11)); - } - - // count of copies - 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) - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_COPYWORDLESSFIVE_STRING)); - else - _tcscat(pData->m_szStatusText, GetResManager()->LoadString(IDS_COPYWORDMOREFOUR_STRING)); - } - - // time - UpdateTime(); - 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(); -} - -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(); -} - -void CTask::SetOsErrorCode(DWORD dwError, LPCTSTR lpszErrDesc) -{ - m_cs.Lock(); - m_lOsError=dwError; - m_strErrorDesc=lpszErrDesc; - m_cs.Unlock(); -} - -void CTask::UpdateTime() -{ - m_cs.Lock(); - if (m_lLastTime != -1) - { - long lVal=time(NULL); - m_lTimeElapsed+=lVal-m_lLastTime; - m_lLastTime=lVal; - } - m_cs.Unlock(); -} - -void CTask::DecreaseOperationsPending(UINT uiBy) -{ - m_pcs->Lock(); - 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) - { - TRACE("Increasing operations pending by %lu\n", uiBy); - m_pcs->Lock(); - (*m_puiOperationsPending)+=uiBy; - m_pcs->Unlock(); - m_bQueued=true; - } -} - -const CFiltersArray* CTask::GetFilters() -{ - return &m_afFilters; -} - -void CTask::SetFilters(const CFiltersArray* pFilters) -{ - m_cs.Lock(); - m_afFilters.Copy(*pFilters); - m_cs.Unlock(); -} - -bool CTask::CanBegin() -{ - bool bRet=true; - m_cs.Lock(); - if (GetContinueFlag() || GetForceFlag()) - { - TRACE("New operation Begins... continue: %d, force: %d\n", GetContinueFlag(), GetForceFlag()); - IncreaseOperationsPending(); - SetForceFlag(false); - SetContinueFlag(false); - } - else - bRet=false; - m_cs.Unlock(); - - return bRet; -} - -void CTask::SetCopies(unsigned char ucCopies) -{ - m_cs.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; -} - -void CTask::SetCurrentCopy(unsigned char ucCopy) -{ - m_cs.Lock(); - m_ucCurrentCopy=ucCopy; - m_cs.Unlock(); -} - -unsigned char CTask::GetCurrentCopy() -{ - m_cs.Lock(); - unsigned char ucCopy=m_ucCurrentCopy; - m_cs.Unlock(); - - return ucCopy; -} - -void CTask::SetLastProcessedIndex(int iIndex) -{ - m_cs.Lock(); - m_iLastProcessedIndex=iIndex; - m_cs.Unlock(); -} - -int CTask::GetLastProcessedIndex() -{ - int iIndex; - m_cs.Lock(); - iIndex=m_iLastProcessedIndex; - m_cs.Unlock(); - - return iIndex; -} - -bool CTask::GetRequiredFreeSpace(__int64 *pi64Needed, __int64 *pi64Available) -{ - *pi64Needed=GetAllSize()-GetProcessedSize(); // it'd be nice to round up to take cluster size into consideration, - // but GetDiskFreeSpace returns flase values - - // get free space - if (!GetDynamicFreeSpace(GetDestPath().GetPath(), pi64Available, NULL)) - return true; - - return (*pi64Needed <= *pi64Available); -} - -void CTask::SetForceFlag(bool bFlag) -{ - m_cs.Lock(); - m_bForce=bFlag; - m_cs.Unlock(); -} - -bool CTask::GetForceFlag() -{ - return m_bForce; -} - -void CTask::SetContinueFlag(bool bFlag) -{ - m_cs.Lock(); - m_bContinue=bFlag; - m_cs.Unlock(); -} - -bool CTask::GetContinueFlag() -{ - return m_bContinue; -} - -CString CTask::GetLogName() -{ - TCHAR szPath[_MAX_PATH]; - GetConfig()->GetStringValue(PP_PAUTOSAVEDIRECTORY, szPath, _MAX_PATH); - return GetApp()->ExpandPath(szPath)+GetUniqueName()+_T(".log"); -} - -//////////////////////////////////////////////////////////////////////////////// -// CTaskArray members -void CTaskArray::Create(UINT (*pfnTaskProc)(LPVOID pParam)) -{ - m_tcd.pcs=&m_cs; - m_tcd.pfnTaskProc=pfnTaskProc; - m_tcd.pTasksAll=&m_uhRange; - m_tcd.pTasksProcessed=&m_uhPosition; - m_tcd.puiOperationsPending=&m_uiOperationsPending; - m_tcd.plFinished=&m_lFinished; -} - -CTaskArray::~CTaskArray() -{ -} - -int CTaskArray::GetSize( ) -{ - m_cs.Lock(); - int nSize=m_nSize; - m_cs.Unlock(); - - return nSize; -} - -int CTaskArray::GetUpperBound( ) -{ - m_cs.Lock(); - int upper=m_nSize; - m_cs.Unlock(); - - return upper-1; -} - -void CTaskArray::SetSize( int nNewSize, int nGrowBy ) -{ - m_cs.Lock(); - (static_cast*>(this))->SetSize(nNewSize, nGrowBy); - m_cs.Unlock(); -} - -CTask* CTaskArray::GetAt( int nIndex ) -{ - ASSERT(nIndex >= 0 && nIndex < m_nSize); - m_cs.Lock(); - CTask* pTask=m_pData[nIndex]; - m_cs.Unlock(); - - return pTask; -} - -void CTaskArray::SetAt( int nIndex, CTask* newElement ) -{ - m_cs.Lock(); - ASSERT(nIndex >= 0 && nIndex < m_nSize); - m_uhRange-=m_pData[nIndex]->GetAllSize(); // subtract old element - m_pData[nIndex]=newElement; - m_uhRange+=m_pData[nIndex]->GetAllSize(); // add new - m_cs.Unlock(); -} - -int CTaskArray::Add( CTask* newElement ) -{ - m_cs.Lock(); - m_uhRange+=newElement->GetAllSize(); - m_uhPosition+=newElement->GetProcessedSize(); - int pos=(static_cast*>(this))->Add(newElement); - m_cs.Unlock(); - - return pos; -} - -void CTaskArray::RemoveAt(int nIndex, int nCount) -{ - m_cs.Lock(); - for (int i=nIndex;iKillThread(); - - m_uhRange-=pTask->GetAllSize(); - m_uhPosition-=pTask->GetProcessedSize(); - - delete pTask; - } - - // remove elements from array - (static_cast*>(this))->RemoveAt(nIndex, nCount); - m_cs.Unlock(); -} - -void CTaskArray::RemoveAll() -{ - m_cs.Lock(); - CTask* pTask; - - for (int i=0;iSetKillFlag(); // send an info about finishing - - // wait for finishing and get rid of it - for (i=0;iGetKilledFlag()) - Sleep(10); - - pTask->CleanupAfterKill(); - - m_uhRange-=pTask->GetAllSize(); - m_uhPosition-=pTask->GetProcessedSize(); - - // delete data - delete pTask; - } - - (static_cast*>(this))->RemoveAll(); - m_cs.Unlock(); -} - -void CTaskArray::RemoveAllFinished() -{ - m_cs.Lock(); - int i=GetSize(); - - TCHAR szPath[_MAX_PATH]; - GetConfig()->GetStringValue(PP_PAUTOSAVEDIRECTORY, szPath, _MAX_PATH); - GetApp()->ExpandPath(szPath); - while (i) - { - CTask* pTask=GetAt(i-1); - - // delete only when the thread is finished - if ( (pTask->GetStatus(ST_STEP_MASK) == ST_FINISHED || pTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED) - && pTask->GetKilledFlag()) - { - m_uhRange-=pTask->GetAllSize(); - m_uhPosition-=pTask->GetProcessedSize(); - - // delete associated files - pTask->DeleteProgress(szPath); - - delete pTask; - - static_cast*>(this)->RemoveAt(i-1); - } - - --i; - } - - m_cs.Unlock(); -} - -void CTaskArray::RemoveFinished(CTask** pSelTask) -{ - m_cs.Lock(); - TCHAR szPath[_MAX_PATH]; - GetConfig()->GetStringValue(PP_PAUTOSAVEDIRECTORY, szPath, _MAX_PATH); - GetApp()->ExpandPath(szPath); - for (int i=0;iGetStatus(ST_STEP_MASK) == ST_FINISHED || pTask->GetStatus(ST_STEP_MASK) == ST_CANCELLED)) - { - // kill task if needed - pTask->KillThread(); - - m_uhRange-=pTask->GetAllSize(); - m_uhPosition-=pTask->GetProcessedSize(); - - // delete associated files - pTask->DeleteProgress(szPath); - - // delete data - delete pTask; - - static_cast*>(this)->RemoveAt(i); - - m_cs.Unlock(); - return; - } - } - m_cs.Unlock(); -} - -void CTaskArray::SaveData(LPCTSTR lpszDirectory) -{ - m_cs.Lock(); - for (int i=0;iStore(lpszDirectory, true); - m_cs.Unlock(); -} - -void CTaskArray::SaveProgress(LPCTSTR lpszDirectory) -{ - m_cs.Lock(); - for (int i=0;iStore(lpszDirectory, false); - m_cs.Unlock(); -} - -void CTaskArray::LoadDataProgress(LPCTSTR lpszDirectory) -{ - m_cs.Lock(); - CFileFind finder; - CTask* pTask; - - BOOL bWorking=finder.FindFile(CString(lpszDirectory)+_T("*.atd")); - while ( bWorking ) - { - bWorking=finder.FindNextFile(); - - // load data - pTask=new CTask(&m_tcd); - - try - { - CString strPath=finder.GetFilePath(); - - // load data file - CFile file(strPath, CFile::modeRead); - CArchive ar(&file, CArchive::load); - - pTask->Load(ar, true); - - ar.Close(); - file.Close(); - - // load progress file - strPath=strPath.Left(strPath.GetLength()-4); - strPath+=_T(".atp"); - CFile file2(strPath, CFile::modeRead); - CArchive ar2(&file2, CArchive::load); - - pTask->Load(ar2, false); - - ar2.Close(); - file2.Close(); - - // add read task to array - Add(pTask); - } - catch(CException* e) - { - e->Delete(); - delete pTask; - } - } - finder.Close(); - - m_cs.Unlock(); -} - -void CTaskArray::TasksBeginProcessing() -{ - for (int i=0;iBeginProcessing(); -} - -void CTaskArray::TasksPauseProcessing() -{ - for (int i=0;iPauseProcessing(); -} - -void CTaskArray::TasksResumeProcessing() -{ - for (int i=0;iResumeProcessing(); -} - -void CTaskArray::TasksRestartProcessing() -{ - for (int i=0;iRestartProcessing(); -} - -bool CTaskArray::TasksRetryProcessing(bool bOnlyErrors/*=false*/, UINT uiInterval) -{ - bool bChanged=false; - for (int i=0;iRetryProcessing(bOnlyErrors, uiInterval)) - bChanged=true; - } - - return bChanged; -} - -void CTaskArray::TasksCancelProcessing() -{ - for (int i=0;iCancelProcessing(); -} - -__int64 CTaskArray::GetPosition() -{ - m_cs.Lock(); - __int64 rv=m_uhPosition; - m_cs.Unlock(); - - return rv; -} - -__int64 CTaskArray::GetRange() -{ - m_cs.Lock(); - __int64 rv=m_uhRange; - m_cs.Unlock(); - - return rv; -} - -int CTaskArray::GetPercent() -{ - 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; -} - -UINT CTaskArray::GetOperationsPending() -{ - m_cs.Lock(); - UINT uiOP=m_uiOperationsPending; - m_cs.Unlock(); - return uiOP; -} - -bool CTaskArray::IsFinished() -{ - bool bFlag=true; - UINT uiStatus; - - m_cs.Lock(); - if (m_uiOperationsPending != 0) - bFlag=false; - else - { - for (int i=0;iGetStatus(); - 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()->GetBoolValue(PP_CMAUTORETRYONERROR))); - } - } - - m_cs.Unlock(); - return bFlag; -} - -/////////////////////////////////////////////////////////////////////// -// CProcessingException - -CProcessingException::CProcessingException(int iType, CTask* pTask, UINT uiFmtID, DWORD dwError, ...) -{ - // std values - m_iType=iType; - m_pTask=pTask; - m_dwError=dwError; - - // format some text - CString strFormat=GetResManager()->LoadString(uiFmtID); - ExpandFormatString(&strFormat, dwError); - - // get param list - va_list marker; - va_start(marker, dwError); - m_strErrorDesc.FormatV(strFormat, marker); - va_end(marker); -} - -void CProcessingException::Cleanup() -{ - TCHAR szPath[_MAX_PATH]; - switch (m_pTask->GetStatus(ST_STEP_MASK)) - { - case ST_NULL_STATUS: - case ST_SEARCHING: - // get rif of m_files contents - m_pTask->FilesRemoveAll(); - - // save state of a task - GetConfig()->GetStringValue(PP_PAUTOSAVEDIRECTORY, szPath, _MAX_PATH); - GetApp()->ExpandPath(szPath); - m_pTask->Store(szPath, true); - m_pTask->Store(szPath, false); - - m_pTask->SetKilledFlag(); - m_pTask->CleanupAfterKill(); - - break; - case ST_COPYING: - case ST_DELETING: - switch (m_iType) - { - case E_ERROR: - m_pTask->SetStatus(ST_ERROR, ST_WORKING_MASK); - m_pTask->SetOsErrorCode(m_dwError, this->m_strErrorDesc); - break; - case E_CANCEL: - m_pTask->SetStatus(ST_CANCELLED, ST_STEP_MASK); - break; - } - - GetConfig()->GetStringValue(PP_PAUTOSAVEDIRECTORY, szPath, _MAX_PATH); - GetApp()->ExpandPath(szPath); - m_pTask->Store(szPath, false); - - m_pTask->SetKilledFlag(); - m_pTask->CleanupAfterKill(); - - break; - } -}