⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sharedfolder.cpp

📁 p2p软件
💻 CPP
📖 第 1 页 / 共 2 页
字号:
//
// SharedFolder.cpp
//
// Copyright (c) Shareaza Development Team, 2002-2004.
// This file is part of SHAREAZA (www.shareaza.com)
//
// Shareaza 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.
//
// Shareaza 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 Shareaza; if not, write to the Free Software
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
//

#include "StdAfx.h"
#include "Shareaza.h"
#include "Settings.h"
#include "SharedFolder.h"
#include "SharedFile.h"
#include "Library.h"
#include "Application.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

IMPLEMENT_DYNAMIC(CLibraryFolder, CComObject)

BEGIN_INTERFACE_MAP(CLibraryFolder, CComObject)
	INTERFACE_PART(CLibraryFolder, IID_ILibraryFolder, LibraryFolder)
	INTERFACE_PART(CLibraryFolder, IID_ILibraryFolders, LibraryFolders)
	INTERFACE_PART(CLibraryFolder, IID_ILibraryFiles, LibraryFiles)
END_INTERFACE_MAP()


//////////////////////////////////////////////////////////////////////
// CLibraryFolder construction

CLibraryFolder::CLibraryFolder(CLibraryFolder* pParent, LPCTSTR pszPath)
{
	EnableDispatch( IID_ILibraryFolder );
	EnableDispatch( IID_ILibraryFolders );
	EnableDispatch( IID_ILibraryFiles );
	
	m_pParent	= pParent;
	
	m_nFiles	= 0;
	m_nVolume	= 0;
	m_bShared	= pParent ? TS_UNKNOWN : TS_TRUE;
	m_bExpanded	= pParent ? FALSE : TRUE;
	
	m_nScanCookie	= 0;
	m_nUpdateCookie	= 0;
	m_nSelectCookie	= 0;
	
	m_hMonitor		= INVALID_HANDLE_VALUE;
	m_bMonitor		= FALSE;

	if ( pszPath )
	{
		m_sPath = pszPath;
		PathToName();
	}
}

CLibraryFolder::~CLibraryFolder()
{
	if ( m_hMonitor != INVALID_HANDLE_VALUE ) FindCloseChangeNotification( m_hMonitor );

	Clear();
}

//////////////////////////////////////////////////////////////////////
// CLibraryFolder folder list

POSITION CLibraryFolder::GetFolderIterator() const
{
	return m_pFolders.GetStartPosition();
}

CLibraryFolder* CLibraryFolder::GetNextFolder(POSITION& pos) const
{
	CLibraryFolder* pOutput = NULL;
	CString strName;
	m_pFolders.GetNextAssoc( pos, strName, (CObject*&)pOutput );
	return pOutput;
}

CLibraryFolder* CLibraryFolder::GetFolderByName(LPCTSTR pszName) const
{
	CLibraryFolder* pOutput = NULL;
	CString strName( pszName );
	strName.MakeLower();
	return ( m_pFolders.Lookup( strName, (CObject*&)pOutput ) ) ? pOutput : NULL;
}

CLibraryFolder* CLibraryFolder::GetFolderByPath(LPCTSTR pszPath) const
{
	if ( m_sPath.CompareNoCase( pszPath ) == 0 ) return (CLibraryFolder*)this;

	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		CLibraryFolder* pFolder = GetNextFolder( pos )->GetFolderByPath( pszPath );
		if ( pFolder ) return pFolder;
	}

	return NULL;
}

BOOL CLibraryFolder::CheckFolder(CLibraryFolder* pFolder, BOOL bRecursive) const
{
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		CLibraryFolder* pCheck = GetNextFolder( pos );
		if ( pCheck == pFolder ) return TRUE;
		if ( bRecursive && pCheck->CheckFolder( pFolder, TRUE ) ) return TRUE;
	}

	return FALSE;
}

int CLibraryFolder::GetFolderCount() const
{
	return m_pFolders.GetCount();
}

//////////////////////////////////////////////////////////////////////
// CLibraryFolder file list

POSITION CLibraryFolder::GetFileIterator() const
{
	return m_pFiles.GetStartPosition();
}

CLibraryFile* CLibraryFolder::GetNextFile(POSITION& pos) const
{
	CLibraryFile* pOutput = NULL;
	CString strName;
	m_pFiles.GetNextAssoc( pos, strName, (CObject*&)pOutput );
	return pOutput;
}

CLibraryFile* CLibraryFolder::GetFile(LPCTSTR pszName) const
{
	CLibraryFile* pOutput = NULL;
	CString strName( pszName );
	strName.MakeLower();
	return ( m_pFiles.Lookup( strName, (CObject*&)pOutput ) ) ? pOutput : NULL;
}

int CLibraryFolder::GetFileCount() const
{
	return m_pFiles.GetCount();
}

int CLibraryFolder::GetFileList(CLibraryList* pList, BOOL bRecursive) const
{
	int nCount = 0;
	
	for ( POSITION pos = GetFileIterator() ; pos ; )
	{
		pList->CheckAndAdd( GetNextFile( pos )->m_nIndex );
		nCount++;
	}
	
	if ( bRecursive )
	{
		for ( pos = GetFolderIterator() ; pos ; )
		{
			GetNextFolder( pos )->GetFileList( pList, bRecursive );
		}
	}
	
	return nCount;
}

int CLibraryFolder::GetSharedCount() const
{
	int nCount = 0;
	
	for ( POSITION pos = GetFileIterator() ; pos ; )
	{
		CLibraryFile* pFile = GetNextFile( pos );
		if ( pFile->IsShared() ) nCount++;
	}
	
	for ( pos = GetFolderIterator() ; pos ; )
	{
		nCount += GetNextFolder( pos )->GetSharedCount();
	}
	
	return nCount;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFolder clear

void CLibraryFolder::Clear()
{
	for ( POSITION pos = GetFolderIterator() ; pos ; )
	{
		delete GetNextFolder( pos );
	}
	
	for ( pos = GetFileIterator() ; pos ; )
	{
		delete GetNextFile( pos );
	}
	
	m_pFolders.RemoveAll();
	m_pFiles.RemoveAll();
	
	m_nFiles	= 0;
	m_nVolume	= 0;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFolder serialize

void CLibraryFolder::Serialize(CArchive& ar, int nVersion)
{
	if ( ar.IsStoring() )
	{
		ar << m_sPath;
		ar << m_bShared;
		ar << m_bExpanded;

		ar.WriteCount( GetFolderCount() );

		for ( POSITION pos = GetFolderIterator() ; pos ; )
		{
			GetNextFolder( pos )->Serialize( ar, nVersion );
		}
		
		ar.WriteCount( GetFileCount() );

		for ( pos = GetFileIterator() ; pos ; )
		{
			GetNextFile( pos )->Serialize( ar, nVersion );
		}
	}
	else
	{
		Clear();

		ar >> m_sPath;

		if ( nVersion >= 5 )
		{
			ar >> m_bShared;
		}
		else
		{
			BYTE bShared;
			ar >> bShared;
			m_bShared = bShared ? TS_UNKNOWN : TS_FALSE;
		}
		
		if ( nVersion >= 3 ) ar >> m_bExpanded;

		PathToName();

		for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
		{
			CLibraryFolder* pFolder = new CLibraryFolder( this );
			pFolder->Serialize( ar, nVersion );

			m_pFolders.SetAt( pFolder->m_sNameLC, pFolder );

			m_nFiles	+= pFolder->m_nFiles;
			m_nVolume	+= pFolder->m_nVolume;
		}

		for ( nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
		{
			CLibraryFile* pFile = new CLibraryFile( this );
			pFile->Serialize( ar, nVersion );

			m_pFiles.SetAt( pFile->GetNameLC(), pFile );

			m_nFiles	++;
			m_nVolume	+= pFile->m_nSize / 1024;
		}
	}
}

void CLibraryFolder::PathToName()
{
	m_sName = m_sPath;
	int nPos = m_sName.ReverseFind( '\\' );
	if ( nPos >= 0 && nPos < m_sName.GetLength() - 1 ) m_sName = m_sName.Mid( nPos + 1 );
	m_sNameLC = m_sName;
	m_sNameLC.MakeLower();
}

//////////////////////////////////////////////////////////////////////
// CLibraryFolder threaded scan

BOOL CLibraryFolder::ThreadScan(DWORD nScanCookie)
{
	CSingleLock pLock( &Library.m_pSection );
	CString strPath, strMetaData;
	LPCTSTR pszMetaData = NULL;
	WIN32_FIND_DATA pFind;
	HANDLE hSearch;
	
	if ( m_pParent == NULL )
		theApp.Message( MSG_DEBUG, _T("Library scanning: %s"), (LPCTSTR)m_sPath );
	
	if ( m_sPath.CompareNoCase( Settings.Downloads.IncompletePath ) == 0 ) return FALSE;
	
	strMetaData = m_sPath + _T("\\Metadata");
	
	hSearch = FindFirstFile( strMetaData + _T("\\*.*"), &pFind );
	
	if ( hSearch != INVALID_HANDLE_VALUE )
	{
		FindClose( hSearch );
		strMetaData += '\\';
		pszMetaData = strMetaData;
	}
	
	hSearch = FindFirstFile( m_sPath + _T("\\*.*"), &pFind );
	
	pLock.Lock();
	m_nScanCookie	= nScanCookie;
	nScanCookie		= ++Library.m_nScanCookie;
	pLock.Unlock();
	
	BOOL bKazaaFolder = _tcsistr( m_sPath, _T("kazaa") ) != NULL;
	BOOL bChanged = FALSE;
	
	if ( hSearch != INVALID_HANDLE_VALUE )
	{
		do
		{
			strPath.Format( _T("%s\\%s"), (LPCTSTR)m_sPath, pFind.cFileName );
			
			if ( pFind.cFileName[0] == '.' ) continue;
			if ( pFind.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) ) continue;
			if ( _tcsicmp( pFind.cFileName, _T("Metadata") ) == 0 ) continue;
			if ( _tcsicmp( pFind.cFileName, _T("SThumbs.dat") ) == 0 ) continue;
			
			if ( pFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
			{
				CLibraryFolder* pFolder = GetFolderByName( pFind.cFileName );
				
				if ( pFolder != NULL )
				{
					m_nFiles	-= pFolder->m_nFiles;
					m_nVolume	-= pFolder->m_nVolume;
					
					if ( pFolder->m_sName != pFind.cFileName )
					{
						pFolder->m_sPath = strPath;
						pFolder->PathToName();
						pFolder->m_nUpdateCookie++;
						bChanged = TRUE;
					}
				}
				else
				{
					pLock.Lock();
					pFolder = new CLibraryFolder( this, strPath );
					m_pFolders.SetAt( pFolder->m_sNameLC, pFolder );
					bChanged = TRUE;
					m_nUpdateCookie++;
					pLock.Unlock();
				}
				
				bChanged |= pFolder->ThreadScan( nScanCookie );
				
				m_nFiles	+= pFolder->m_nFiles;
				m_nVolume	+= pFolder->m_nVolume;
			}
			else
			{
				CLibraryFile* pFile = GetFile( pFind.cFileName );
				
				if ( pFile != NULL )
				{
					m_nVolume -= pFile->m_nSize / 1024;
					
					if ( pFile->m_sName != pFind.cFileName )
					{
						pFile->m_sName = pFind.cFileName;
						bChanged = TRUE;
					}
				}
				else if ( bKazaaFolder && _tcsistr( pFind.cFileName, _T(".dat") ) != NULL )
				{
					// Ignore .dat files in Kazaa folder
					continue;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -