Index: src/ch/ClipboardMonitor.cpp
===================================================================
diff -u -r44c811ed2e152c83d92aa7d0b41497a90a177209 -r012e8c96dde85616cf4ecbd594afa91517d81a0d
--- src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision 44c811ed2e152c83d92aa7d0b41497a90a177209)
+++ src/ch/ClipboardMonitor.cpp	(.../ClipboardMonitor.cpp)	(revision 012e8c96dde85616cf4ecbd594afa91517d81a0d)
@@ -209,12 +209,6 @@
 				dlg.GetPath(strData);
 				spTask->SetDestPath(strData);
 
-				// get the relationship between src and dst paths
-				for (size_t stIndex = 0; stIndex < spTask->GetClipboard()->GetSize(); ++stIndex)
-				{
-					spTask->GetClipboard()->GetAt(stIndex)->CalcBufferIndex(spTask->GetDestPath());
-				}
-
 				// add task to a list of tasks and start
 				pData->m_pTasks->Add(spTask);
 
Index: src/ch/FileInfo.cpp
===================================================================
diff -u -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 -r012e8c96dde85616cf4ecbd594afa91517d81a0d
--- src/ch/FileInfo.cpp	(.../FileInfo.cpp)	(revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987)
+++ src/ch/FileInfo.cpp	(.../FileInfo.cpp)	(revision 012e8c96dde85616cf4ecbd594afa91517d81a0d)
@@ -46,48 +46,25 @@
 CClipboardEntry::CClipboardEntry() :
 	m_bMove(true),
 	m_iDriveNumber(-1),
-	m_uiDriveType(static_cast<UINT>(-1)),
-	m_iBufferIndex(0)
+	m_iBufferIndex(-1)
 {
 }
 
 CClipboardEntry::CClipboardEntry(const CClipboardEntry& rEntry) :
 	m_strPath(rEntry.m_strPath),
 	m_bMove(rEntry.m_bMove),
 	m_iDriveNumber(rEntry.m_iDriveNumber),
-	m_uiDriveType(rEntry.m_uiDriveType),
 	m_strDstPath(rEntry.m_strDstPath)
 {
 }
 
 void CClipboardEntry::SetPath(const CString& strPath)
 {
-	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)
-{
-	// what kind of buffer
-	if (m_uiDriveType == DRIVE_REMOTE || dpDestPath.GetDriveType() == DRIVE_REMOTE)
-		m_iBufferIndex=BI_LAN;
-	else if (m_uiDriveType == DRIVE_CDROM || dpDestPath.GetDriveType() == DRIVE_CDROM)
-		m_iBufferIndex=BI_CD;
-	else if (m_uiDriveType == DRIVE_FIXED && dpDestPath.GetDriveType() == DRIVE_FIXED)
-	{
-		// two hdd's - is this the same physical disk ?
-		if (m_iDriveNumber == dpDestPath.GetDriveNumber() || IsSamePhysicalDisk(m_iDriveNumber, dpDestPath.GetDriveNumber()))
-			m_iBufferIndex=BI_ONEDISK;
-		else
-			m_iBufferIndex=BI_TWODISKS;
-	}
-	else
-		m_iBufferIndex=BI_DEFAULT;
-}
-
 CString CClipboardEntry::GetFileName() const
 {
 	TCHAR szName[_MAX_FNAME];
@@ -96,6 +73,42 @@
 	return CString(szName) + szExt;
 }
 
+int CClipboardEntry::GetDriveNumber()
+{
+	if(m_iDriveNumber == -1)
+		GetDriveData(m_strPath, &m_iDriveNumber, NULL);
+
+	return m_iDriveNumber;
+}
+
+int CClipboardEntry::GetBufferIndex(const CDestPath& dpDestPath)
+{
+	if(m_iBufferIndex == -1)
+	{
+		UINT uiDriveType = 0;
+		GetDriveData(m_strPath, NULL, &uiDriveType);
+
+		// what kind of buffer
+		if(uiDriveType == DRIVE_REMOTE || dpDestPath.GetDriveType() == DRIVE_REMOTE)
+			m_iBufferIndex = BI_LAN;
+		else if(uiDriveType == DRIVE_CDROM || dpDestPath.GetDriveType() == DRIVE_CDROM)
+			m_iBufferIndex = BI_CD;
+		else if(uiDriveType == DRIVE_FIXED && dpDestPath.GetDriveType() == DRIVE_FIXED)
+		{
+			int iDriveNumber = GetDriveNumber();
+			// two hdd's - is this the same physical disk ?
+			if(iDriveNumber == dpDestPath.GetDriveNumber() || IsSamePhysicalDisk(iDriveNumber, dpDestPath.GetDriveNumber()))
+				m_iBufferIndex = BI_ONEDISK;
+			else
+				m_iBufferIndex = BI_TWODISKS;
+		}
+		else
+			m_iBufferIndex = BI_DEFAULT;
+	}
+
+	return m_iBufferIndex;
+}
+
 void CClipboardEntry::SetDestinationPath(const CString& strPath)
 {
 	m_strDstPath = strPath;
@@ -342,17 +355,21 @@
 
 CString CFileInfo::GetFileDrive() const
 {
-	ASSERT(m_pClipboard);
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
 
 	CString strPath=(m_stSrcIndex != std::numeric_limits<size_t>::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath() + m_strFilePath : m_strFilePath;
 	TCHAR szDrive[_MAX_DRIVE];
 	_tsplitpath(strPath, szDrive, NULL, NULL, NULL);
 	return CString(szDrive);
 }
 
-int CFileInfo::GetDriveNumber() const
+int CFileInfo::GetDriveNumber()
 {
-	ASSERT(m_pClipboard);
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
 
 	if(m_stSrcIndex != std::numeric_limits<size_t>::max())
 	{
@@ -362,33 +379,17 @@
 	else
 	{
 		// manually
-		int iNum;
+		int iNum = 0;
 		GetDriveData(m_strFilePath, &iNum, NULL);
 		return iNum;
 	}
 }
 
-UINT CFileInfo::GetDriveType() const
-{
-	ASSERT(m_pClipboard);
-
-	if(m_stSrcIndex != std::numeric_limits<size_t>::max())
-	{
-		// read data contained in CClipboardEntry
-		return m_pClipboard->GetAt(m_stSrcIndex)->GetDriveType();
-	}
-	else
-	{
-		// manually
-		UINT uiType;
-		GetDriveData(m_strFilePath, NULL, &uiType);
-		return uiType;
-	}
-}
-
 CString CFileInfo::GetFileDir() const
 { 
-	ASSERT(m_pClipboard);
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
 
 	CString strPath=(m_stSrcIndex != std::numeric_limits<size_t>::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath()+m_strFilePath : m_strFilePath;
 	TCHAR szDir[_MAX_DIR];
@@ -398,7 +399,9 @@
 
 CString CFileInfo::GetFileTitle() const
 {
-	ASSERT(m_pClipboard);
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
 
 	CString strPath=(m_stSrcIndex != std::numeric_limits<size_t>::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath()+m_strFilePath : m_strFilePath;
 	TCHAR szName[_MAX_FNAME];
@@ -409,6 +412,9 @@
 CString CFileInfo::GetFileExt() const
 {
 	ASSERT(m_pClipboard);
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
 
 	CString strPath=(m_stSrcIndex != std::numeric_limits<size_t>::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath()+m_strFilePath : m_strFilePath;
 	TCHAR szExt[_MAX_EXT];
@@ -419,6 +425,9 @@
 CString CFileInfo::GetFileRoot() const
 {
 	ASSERT(m_pClipboard);
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
 
 	CString strPath=(m_stSrcIndex != std::numeric_limits<size_t>::max()) ? m_pClipboard->GetAt(m_stSrcIndex)->GetPath()+m_strFilePath : m_strFilePath;
 
@@ -430,13 +439,18 @@
 
 CString CFileInfo::GetFileName() const
 {
-	ASSERT(m_pClipboard || m_stSrcIndex == std::numeric_limits<size_t>::max());
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
 
 	CString strPath;
 	if(m_pClipboard && m_stSrcIndex != std::numeric_limits<size_t>::max())
 		strPath = m_pClipboard->GetAt(m_stSrcIndex)->GetPath() + m_strFilePath;
 	else
+	{
+		ASSERT(m_stSrcIndex == std::numeric_limits<size_t>::max());
 		strPath = m_strFilePath;
+	}
 
 	TCHAR szName[_MAX_FNAME];
 	TCHAR szExt[_MAX_EXT];
@@ -493,6 +507,10 @@
 
 CString CFileInfo::GetFullFilePath() const
 {
+	BOOST_ASSERT(m_pClipboard);
+	if(!m_pClipboard)
+		THROW(_T("Invalid pointer"), 0, 0, 0);
+
 	CString strPath;
 	if(m_stSrcIndex != std::numeric_limits<size_t>::max())
 	{
@@ -504,10 +522,10 @@
 	return strPath;
 }
 
-int CFileInfo::GetBufferIndex() const
+int CFileInfo::GetBufferIndex(const CDestPath& dpDestPath)
 {
-	if (m_stSrcIndex != std::numeric_limits<size_t>::max())
-		return m_pClipboard->GetAt(m_stSrcIndex)->GetBufferIndex();
+	if(m_stSrcIndex != std::numeric_limits<size_t>::max())
+		return m_pClipboard->GetAt(m_stSrcIndex)->GetBufferIndex(dpDestPath);
 	else
 		return BI_DEFAULT;
 }
Index: src/ch/FileInfo.h
===================================================================
diff -u -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 -r012e8c96dde85616cf4ecbd594afa91517d81a0d
--- src/ch/FileInfo.h	(.../FileInfo.h)	(revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987)
+++ src/ch/FileInfo.h	(.../FileInfo.h)	(revision 012e8c96dde85616cf4ecbd594afa91517d81a0d)
@@ -43,17 +43,15 @@
 	CClipboardEntry(const CClipboardEntry& rEntry);
 
 	void SetPath(const CString& strPath);
-	void CalcBufferIndex(const CDestPath& dpDestPath);
 	const CString& GetPath() const { return m_strPath; }
 	CString GetFileName() const;
 
-	void SetMove(bool bValue) { m_bMove=bValue; }
+	//void SetMove(bool bValue) { m_bMove=bValue; }
 	bool GetMove() { return m_bMove; }
 
-	int GetDriveNumber() const { return m_iDriveNumber; }
-	UINT GetDriveType() const { return m_uiDriveType; }
+	int GetDriveNumber();
 
-	int GetBufferIndex() const { return m_iBufferIndex; }
+	int GetBufferIndex(const CDestPath& dpDestPath);
 
 	template<class Archive>
 	void Serialize(Archive& ar, unsigned int /*uiVersion*/, bool bData)
@@ -62,9 +60,6 @@
 		{
 			ar & m_strPath;
 			ar & m_bMove;
-			ar & m_iDriveNumber;
-			ar & m_uiDriveType;
-			ar & m_iBufferIndex;
 		}
 		else
 			ar & m_strDstPath;
@@ -79,7 +74,6 @@
 	bool m_bMove;					// specifies if we can use MoveFile (if will be moved)
 
 	int m_iDriveNumber;		// disk number (-1 - none)
-	UINT m_uiDriveType;		// path type
 
 	int m_iBufferIndex;		// buffer number, with which we'll copy this data
 
@@ -174,8 +168,7 @@
 
 	// disk - path and disk number (-1 if none - ie. net disk)
 	CString GetFileDrive(void) const;		// returns string with src disk
-	int GetDriveNumber() const;				// disk number A - 0, b-1, c-2, ...
-	UINT GetDriveType() const;				// drive type
+	int GetDriveNumber();				// disk number A - 0, b-1, c-2, ...
 
 	CString GetFileDir() const;	// @rdesc Returns \WINDOWS\ for C:\WINDOWS\WIN.INI 
 	CString GetFileTitle() const;	// @cmember returns WIN for C:\WINDOWS\WIN.INI
@@ -215,7 +208,7 @@
 
 	bool GetMove() { if (m_stSrcIndex != std::numeric_limits<size_t>::max()) return m_pClipboard->GetAt(m_stSrcIndex)->GetMove(); else return true; };
 
-	int GetBufferIndex() const;
+	int GetBufferIndex(const CDestPath& dpDestPath);
 
 	// operators
 	bool operator==(const CFileInfo& rInfo);
Index: src/ch/MainWnd.cpp
===================================================================
diff -u -r4ec3aef62d14193e3021e6bc3f8bcdf11770c7d5 -r012e8c96dde85616cf4ecbd594afa91517d81a0d
--- src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 4ec3aef62d14193e3021e6bc3f8bcdf11770c7d5)
+++ src/ch/MainWnd.cpp	(.../MainWnd.cpp)	(revision 012e8c96dde85616cf4ecbd594afa91517d81a0d)
@@ -514,7 +514,6 @@
 	{
 		spEntry.reset(new CClipboardEntry);
 		spEntry->SetPath(astrFiles.GetAt(i));
-		spEntry->CalcBufferIndex(spTask->GetDestPath());
 		spTask->AddClipboardData(spEntry);
 	}
 
@@ -595,7 +594,6 @@
 		{
 			spEntry.reset(new CClipboardEntry);
 			spEntry->SetPath(dlg.m_ccData.m_astrPaths.GetAt(i));
-			spEntry->CalcBufferIndex(spTask->GetDestPath());
 			spTask->AddClipboardData(spEntry);
 		}
 		
Index: src/ch/task.cpp
===================================================================
diff -u -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 -r012e8c96dde85616cf4ecbd594afa91517d81a0d
--- src/ch/task.cpp	(.../task.cpp)	(revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987)
+++ src/ch/task.cpp	(.../task.cpp)	(revision 012e8c96dde85616cf4ecbd594afa91517d81a0d)
@@ -609,7 +609,7 @@
 
 	size_t stSize = m_files.GetSize();
 	if(stSize > 0 && m_stCurrentIndex != std::numeric_limits<size_t>::max())
-		rv = m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < stSize) ? m_stCurrentIndex : 0)->GetBufferIndex();
+		rv = m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < stSize) ? m_stCurrentIndex : 0)->GetBufferIndex(m_dpDestPath);
 
 	return rv;
 }
@@ -906,7 +906,7 @@
 	pData->m_pstrUniqueName=&m_strUniqueName;
 
 	if(m_files.GetSize() > 0 && m_stCurrentIndex != std::numeric_limits<size_t>::max())
-		pData->m_iCurrentBufferIndex=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < m_files.GetSize()) ? m_stCurrentIndex : 0)->GetBufferIndex();
+		pData->m_iCurrentBufferIndex=m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < m_files.GetSize()) ? m_stCurrentIndex : 0)->GetBufferIndex(m_dpDestPath);
 	else
 		pData->m_iCurrentBufferIndex=0;
 
@@ -1147,7 +1147,7 @@
 
 	size_t stSize = m_files.GetSize();
 	if(stSize > 0 && m_stCurrentIndex != std::numeric_limits<size_t>::max())
-		rv = m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < stSize) ? m_stCurrentIndex : 0)->GetBufferIndex();
+		rv = m_bsSizes.m_bOnlyDefault ? 0 : m_files.GetAt((m_stCurrentIndex < stSize) ? m_stCurrentIndex : 0)->GetBufferIndex(m_dpDestPath);
 
 	return rv;
 }
@@ -1218,7 +1218,6 @@
 	FilesRemoveAll();
 
 	// enter some data to m_files
-	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;
@@ -1229,6 +1228,7 @@
 	bool bRetry = true;
 	bool bSkipInputPath = false;
 
+	size_t stSize = GetClipboardDataSize();
 	for(size_t stIndex = 0; stIndex < stSize ; stIndex++)
 	{
 		CFileInfoPtr spFileInfo;
@@ -1360,9 +1360,6 @@
 	// calc size of all files
 	CalculateTotalSize();
 
-	// update *m_pnTasksAll;
-//	m_rtGlobalStats.IncreaseGlobalTotalSize(GetAllSize());
-
 	// change state to ST_COPYING - finished searching for files
 	SetStatus(ST_COPYING, ST_STEP_MASK);
 
@@ -1797,7 +1794,11 @@
 				}
 
 				// establish count of data to read
-				iBufferIndex=GetBufferSizes()->m_bOnlyDefault ? 0 : pData->spSrcFile->GetBufferIndex();
+				if(GetBufferSizes()->m_bOnlyDefault)
+					iBufferIndex = BI_DEFAULT;
+				else
+					iBufferIndex = pData->spSrcFile->GetBufferIndex(m_dpDestPath);
+
 				ulToRead=bNoBuffer ? ROUNDUP(pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex], MAXSECTORSIZE) : pData->dbBuffer.GetSizes()->m_auiSizes[iBufferIndex];
 
 				// read
@@ -2305,21 +2306,22 @@
 	// count how much has been done (updates also a member in CTaskArray)
 	CalculateProcessedSize();
 
+	// begin at index which wasn't processed previously
+	size_t stSize = FilesGetSize();
+	bool bIgnoreFolders = (GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_DIRS) != 0;
+	bool bForceDirectories = (GetStatus(ST_SPECIAL_MASK) & ST_FORCE_DIRS) != 0;
+	const CDestPath& dpDestPath = GetDestPath();
+
 	// create a buffer of size m_nBufferSize
 	CUSTOM_COPY_PARAMS ccp;
 	ccp.bProcessed = false;
 	ccp.bOnlyCreate=(GetStatus(ST_SPECIAL_MASK) & ST_IGNORE_CONTENT) != 0;
 	ccp.dbBuffer.Create(GetBufferSizes());
+	ccp.pDestPath = &dpDestPath;
 
 	// helpers
 	DWORD dwLastError = 0;
 
-	// begin at index which wasn't processed previously
-	size_t stSize = FilesGetSize();
-	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();
 
Index: src/ch/task.h
===================================================================
diff -u -r860b25a7b72cd40f83d810f7c72a5e2a76f88987 -r012e8c96dde85616cf4ecbd594afa91517d81a0d
--- src/ch/task.h	(.../task.h)	(revision 860b25a7b72cd40f83d810f7c72a5e2a76f88987)
+++ src/ch/task.h	(.../task.h)	(revision 012e8c96dde85616cf4ecbd594afa91517d81a0d)
@@ -112,8 +112,9 @@
 
 struct CUSTOM_COPY_PARAMS
 {
-	CFileInfoPtr spSrcFile;	// CFileInfo - src file
+	CFileInfoPtr spSrcFile;		// CFileInfo - src file
 	CString strDstFile;			// dest path with filename
+	const CDestPath* pDestPath;
 
 	CDataBuffer dbBuffer;		// buffer handling
 	bool bOnlyCreate;			// flag from configuration - skips real copying - only create