UINT __cdecl CopyThread(void* pParam)
{
ProgressArguments* pArgs = (ProgressArguments*)pParam;
CString strDir, strFileName, strExt, strCopyFrom, strCopyTo, strTemp;
UINT64 nNumOfFiles = 0, unAdd = 0;
bool bError = false;
pArgs->punAdd = &unAdd;
pArgs->pbError = &bError;
//for (size_t i = 0; i < pArgs->pCopyClass->strFilesToCopy->size(); i++)
//{
// _wsplitpath_s(pArgs->pCopyClass->strFilesToCopy->at(i), NULL, 0, strDir.GetBuffer(5000), 5000, NULL, 0, NULL, 0);
// strDir.ReleaseBuffer();
// strCopyTo = pArgs->pCopyClass->strFolderCopyTo + strDir + strFileName;
// strCopyTo.Replace(pArgs->pCopyClass->strFolderCopyFrom, L"");
// SHCreateDirectoryEx(NULL, strCopyTo, NULL);
//}
for (size_t i = 0; i < pArgs->pCopyClass->strFilesToCopy->size(); i++)
{
nPrevious = 0;
//pArgs->pProgressDlg->nPreviousByteCountAll = 0;
strCopyFrom = pArgs->pCopyClass->strFilesToCopy->at(i);
_wsplitpath_s(strCopyFrom, NULL, 0, strDir.GetBuffer(5000), 5000, strFileName.GetBuffer(500), 500, strExt.GetBuffer(500), 500);
strDir.ReleaseBuffer();
strFileName.ReleaseBuffer();
strExt.ReleaseBuffer();
strFileName += strExt;
strCopyTo = pArgs->pCopyClass->strFolderCopyTo + strDir;
strCopyTo.Replace(pArgs->pCopyClass->strFolderCopyFrom, L"");
SHCreateDirectoryEx(NULL, strCopyTo, NULL);
strCopyTo += strFileName;
pArgs->pProgressDlg->m_NowCopying = L"Now copying file " + strFileName + L"...";
strTemp.Format(L"Copying file %I64u ", ++nNumOfFiles);
if (bThreadReady)
strTemp.AppendFormat(L"out of %I64u file(s)...", nTotalFiles);
else
strTemp.AppendFormat(L"...");
pArgs->pProgressDlg->m_CopyFileOfFiles = strTemp;
if (hEstimateTime) SetEvent(hEstimateTime);
BOOL bSuccess = CopyFileEx(strCopyFrom, strCopyTo, &CopyProgressRoutine, pArgs, NULL, COPY_FILE_FAIL_IF_EXISTS);
if (pArgs->pProgressDlg->bCancel) break;
if (!bSuccess)
{
if (GetLastError() != ERROR_FILE_EXISTS)
pArgs->pErrorDlg->m_Errors.AppendFormat(L"Unable to copy file %s (%s)...\r\n", strFileName, LastError( GetLastError() ));
// Add the files size to the copied amount
FILE* f;
_wfopen_s(&f, pArgs->pCopyClass->strFilesToCopy->at(i), L"rb");
if (f == NULL) continue;
_fseeki64(f, 0, SEEK_END);
unAdd += _ftelli64(f);
fclose(f);
// Recalculate the estimate time. The reason for calling the thread again is to rule out the case when the copy operations fails and it skips files. When it does,
// it will calculate faulty data. Therefore, we restart this thread again.
bError = true;
//bAbortThread = true; // This will hinder any estimation threads from setting the dwBytesPerSecond variable.
dwBytesPerSecond = 0; // If some / any threads has already set this variable, then disable it so that faulty estimation time won't appear.
TerminateThread(hEstTimeThread, 0); // Kill the estimation time thread
hEstTimeThread = NULL;
pArgs->pProgressDlg->m_EstimatedTimeAll = "Calculating...";
}
else;
//{
// WaitForSingleObject(hEvent, INFINITE);
// ResetEvent(hEvent);
//}
}
FILE* f;
_wfopen_s(&f, pArgs->pCopyClass->strFilesToCopy->at( pArgs->pCopyClass->strFilesToCopy->size() - 1 ), L"rb");
if (f != NULL)
{
_fseeki64(f, 0, SEEK_END);
unAdd = _ftelli64(f);
fclose(f);
}
if (!pArgs->pProgressDlg->bCancel)
{
pArgs->pProgressDlg->GetDlgItem(IDC_CANCEL)->SetWindowText(L"OK");
pArgs->pProgressDlg->m_ProgressAll.SetPos(100);
pArgs->pProgressDlg->m_ProgressCurrent.SetPos(100);
pArgs->pProgressDlg->m_CopyFileOfFiles.Format(L"Copying file %I64u ", nNumOfFiles++);
if (bThreadReady)
pArgs->pProgressDlg->m_CopyFileOfFiles.AppendFormat(L"out of %I64u file(s)...", nTotalFiles);
else
pArgs->pProgressDlg->m_CopyFileOfFiles.AppendFormat(L"...");
pArgs->pProgressDlg->m_EstimatedTimeAll = L"Estimated time reamining: 00:00:00";
pArgs->pProgressDlg->m_EstimatedTimeCurrent = L"Estimated time reamining: 00:00:00";
CString strUnit = GetSize(nTotalSize);
pArgs->pProgressDlg->m_DataCopiedAll.Format(L"Copied %I64u %s ", nTotalSize, strUnit);
if (bThreadReady)
pArgs->pProgressDlg->m_DataCopiedAll.AppendFormat(L"of %I64u %s (%i%%)...", nTotalSize, strUnit, 100);
else
pArgs->pProgressDlg->m_DataCopiedAll += L"so far...";
strUnit = GetSize(unAdd);
if (unAdd != 0)
{
pArgs->pProgressDlg->m_DataCopiedCurrent.Format(L"Copied %I64u %s ", unAdd, strUnit);
if (bThreadReady)
pArgs->pProgressDlg->m_DataCopiedCurrent.AppendFormat(L"of %I64u %s (%i%%)...", unAdd, strUnit, 100);
else
pArgs->pProgressDlg->m_DataCopiedCurrent += L"so far...";
}
else
pArgs->pProgressDlg->m_DataCopiedCurrent = L"Copied an unknown amount of data...";
}
return S_OK;
}