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

📄 sharedfile.cpp

📁 著名的下载软件核心Shareaza
💻 CPP
📖 第 1 页 / 共 3 页
字号:
//
// SharedFile.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 "SharedFile.h"
#include "SharedFolder.h"
#include "Library.h"
#include "HashDatabase.h"

#include "Network.h"
#include "Uploads.h"
#include "Downloads.h"
#include "SourceURL.h"
#include "FileExecutor.h"
#include "Buffer.h"

#include "XML.h"
#include "XMLCOM.h"
#include "Schema.h"
#include "SchemaCache.h"

#include "SHA.h"
#include "MD5.h"
#include "ED2K.h"
#include "TigerTree.h"

#include "Application.h"
#include "VersionChecker.h"
#include "DlgFolderScan.h"

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

IMPLEMENT_DYNAMIC(CLibraryFile, CComObject)

BEGIN_INTERFACE_MAP(CLibraryFile, CComObject)
	INTERFACE_PART(CLibraryFile, IID_ILibraryFile, LibraryFile)
END_INTERFACE_MAP()


//////////////////////////////////////////////////////////////////////
// CLibraryFile construction

CLibraryFile::CLibraryFile(CLibraryFolder* pFolder, LPCTSTR pszName)
{
	EnableDispatch( IID_ILibraryFile );
	
	m_pFolder		= pFolder;
	m_pNextSHA1		= NULL;
	m_pNextTiger	= NULL;
	m_pNextED2K		= NULL;
	m_nScanCookie	= 0;
	m_nUpdateCookie	= 0;
	m_nSelectCookie	= 0;
	
	m_nIndex		= 0;
	m_nSize			= 0;
	m_bShared		= TS_UNKNOWN;
	m_nVirtualBase	= 0;
	m_nVirtualSize	= 0;
	
	m_bSHA1			= FALSE;
	m_bTiger		= FALSE;
	m_bMD5			= FALSE;
	m_bED2K			= FALSE;
	m_bVerify		= TS_UNKNOWN;
	
	m_pSchema		= NULL;
	m_pMetadata		= NULL;
	m_bMetadataAuto	= FALSE;
	m_nRating		= 0;
	
	m_nHitsToday		= 0;
	m_nHitsTotal		= 0;
	m_nUploadsToday		= 0;
	m_nUploadsTotal		= 0;
	m_bCachedPreview	= FALSE;
	m_bBogus			= FALSE;
	
	m_nSearchCookie	= 0;
	m_nSearchWords	= 0;
	m_nCollIndex	= 0;
	m_nIcon16		= -1;
	
	if ( pszName != NULL ) m_sName = pszName;
}

CLibraryFile::~CLibraryFile()
{
	Library.RemoveFile( this );
	
	if ( m_pMetadata != NULL ) delete m_pMetadata;
	
	for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
	{
		delete (CSharedSource*)m_pSources.GetNext( pos );
	}
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile path computation

CString CLibraryFile::GetPath() const
{
	if ( m_pFolder != NULL )
		return m_pFolder->m_sPath + '\\' + m_sName;
	else
		return CString();
}

CString CLibraryFile::GetSearchName() const
{
	int nBase = 0;
	CString str;
	
	if ( m_pFolder != NULL && m_pFolder->m_pParent != NULL )
	{
		for ( CLibraryFolder* pFolder = m_pFolder ; ; pFolder = pFolder->m_pParent )
		{
			if ( pFolder->m_pParent == NULL )
			{
				nBase = pFolder->m_sPath.GetLength();
				break;
			}
		}
	}
	
	if ( nBase <= 0 )
	{
		str = m_sName;
	}
	else
	{
		ASSERT( m_pFolder->m_sPath.GetLength() > nBase );
		str = m_pFolder->m_sPath.Mid( nBase + 1 ) + '\\' + m_sName;
	}
	
	str.MakeLower();
	return str;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile shared check

BOOL CLibraryFile::IsShared() const
{
	if ( LPCTSTR pszExt = _tcsrchr( m_sName, '.' ) )
	{
		pszExt++;
		
		if ( LPCTSTR pszFind = _tcsistr( Settings.Library.PrivateTypes, pszExt ) )
		{
			if ( pszFind[ _tcslen( pszExt ) ] == 0 ||
				 pszFind[ _tcslen( pszExt ) ] == '|' )
			{
				if ( pszFind == Settings.Library.PrivateTypes ||
					 pszFind[-1] == '|' )
				{
					return FALSE;
				}
			}
		}
	}
	
	if ( m_bShared )
	{
		if ( m_bShared == TS_TRUE ) return TRUE;
		if ( m_bShared == TS_FALSE ) return FALSE;
	}
	
	for ( CLibraryFolder* pFolder = m_pFolder ; pFolder ; pFolder = pFolder->m_pParent )
	{
		if ( pFolder->m_bShared )
		{
			if ( pFolder->m_bShared == TS_TRUE ) return TRUE;
			if ( pFolder->m_bShared == TS_FALSE ) return FALSE;
		}
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile schema URI test

BOOL CLibraryFile::IsSchemaURI(LPCTSTR pszURI) const
{
	if ( m_pSchema == NULL )
	{
		return ( pszURI == NULL || *pszURI == NULL );
	}
	else
	{
		return m_pSchema->CheckURI( pszURI );
	}
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile rebuild hashes and metadata

BOOL CLibraryFile::Rebuild()
{
	if ( m_pFolder == NULL ) return FALSE;
	
	Library.RemoveFile( this );
	
	m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
	m_nVirtualBase = m_nVirtualSize = 0;
	
	if ( m_pMetadata != NULL && m_bMetadataAuto )
	{
		delete m_pMetadata;
		m_pSchema	= NULL;
		m_pMetadata	= NULL;
	}
	
	Library.AddFile( this );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile execute

BOOL CLibraryFile::Execute(BOOL bPrompt)
{
	if ( m_pFolder == NULL ) return FALSE;
	CString strPath = GetPath();
	Library.Unlock();
	BOOL bResult = CFileExecutor::Execute( strPath, ! bPrompt );
	Library.Lock();
	return bResult;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile rename

BOOL CLibraryFile::Rename(LPCTSTR pszName)
{
	if ( m_pFolder == NULL ) return FALSE;
	if ( ! pszName || ! *pszName ) return FALSE;
	if ( _tcschr( pszName, '\\' ) ) return FALSE;
	
	CString strNew = m_pFolder->m_sPath + '\\' + pszName;
	
	Uploads.OnRename( GetPath() );
	
	if ( MoveFile( GetPath(), strNew ) )
	{
		Uploads.OnRename( GetPath(), strNew );
	}
	else
	{
		Uploads.OnRename( GetPath(), GetPath() );
		return FALSE;
	}
	
	if ( m_pMetadata != NULL )
	{
		CString strMetaFolder	= m_pFolder->m_sPath + _T("\\Metadata");
		CString strMetaOld		= strMetaFolder + '\\' + m_sName + _T(".xml");
		CString strMetaNew		= strMetaFolder + '\\' + pszName + _T(".xml");
		
		MoveFile( strMetaOld, strMetaNew );
	}
	
	Library.RemoveFile( this );
	
	m_sName = pszName;
	
	m_pFolder->OnFileRename( this );
	
	Library.AddFile( this );
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile delete

BOOL CLibraryFile::Delete()
{
	if ( m_pFolder != NULL )
	{
		Uploads.OnRename( GetPath(), NULL );
		
		LPTSTR pszPath = new TCHAR[ GetPath().GetLength() + 2 ];
		_tcscpy( pszPath, GetPath() );
		pszPath[ GetPath().GetLength() + 1 ] = 0;
		
		SHFILEOPSTRUCT pOp;
		ZeroMemory( &pOp, sizeof(pOp) );
		pOp.wFunc	= FO_DELETE;
		pOp.pFrom	= pszPath;
		pOp.fFlags	= FOF_ALLOWUNDO|FOF_NOCONFIRMATION;
		
		if ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) pOp.fFlags &= ~FOF_ALLOWUNDO;
		
		int nReturn = SHFileOperation( &pOp );
		
		delete [] pszPath;
		
		if ( nReturn != 0 )
		{
			Uploads.OnRename( GetPath(), GetPath() );
			return FALSE;
		}
		
		if ( m_pMetadata != NULL || m_sComments.GetLength() || m_nRating > 0 )
		{
			CString strMetaFolder	= m_pFolder->m_sPath + _T("\\Metadata");
			CString strMetaFile		= strMetaFolder + '\\' + m_sName + _T(".xml");
			
			if ( DeleteFile( strMetaFile ) )
			{
				RemoveDirectory( strMetaFolder );
			}
		}
	}
	else
	{
		OnDelete();
	}
	
	return TRUE;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile metadata access

BOOL CLibraryFile::SetMetadata(CXMLElement* pXML)
{
	if ( m_pFolder == NULL ) return FALSE;
	if ( m_pMetadata == NULL && pXML == NULL ) return TRUE;
	
	CSchema* pSchema = NULL;
	
	if ( pXML != NULL )
	{
		pSchema = SchemaCache.Get( pXML->GetAttributeValue( CXMLAttribute::schemaName ) );
		if ( pSchema == NULL ) return FALSE;
		if ( ! pSchema->Validate( pXML, TRUE ) ) return FALSE;
		
		if ( m_pMetadata != NULL && m_pSchema == pSchema )
		{
			if ( m_pMetadata->Equals( pXML->GetFirstElement() ) ) return TRUE;
		}
	}
	
	Library.RemoveFile( this );
	
	if ( m_pMetadata != NULL )
	{
		delete m_pMetadata;
		m_pSchema		= NULL;
		m_pMetadata		= NULL;
		m_bMetadataAuto	= FALSE;
	}
	
	m_pSchema		= pSchema;
	m_pMetadata		= pXML ? pXML->GetFirstElement()->Detach() : NULL;
	m_bMetadataAuto	= FALSE;
	
	if ( m_pMetadata == NULL )
	{
		m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = NULL;
	}
	
	Library.AddFile( this );
	
	SaveMetadata();
	
	return TRUE;
}

CString CLibraryFile::GetMetadataWords() const
{
	if ( m_pSchema != NULL && m_pMetadata != NULL )
	{
		return m_pSchema->GetIndexedWords( m_pMetadata );
	}
	else
	{
		return CString();
	}
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile hash volume lookups

CTigerTree* CLibraryFile::GetTigerTree()
{
	if ( m_bTiger == FALSE ) return NULL;
	if ( m_pFolder == NULL ) return NULL;
	
	CTigerTree* pTiger = new CTigerTree();
	
	if ( LibraryHashDB.GetTiger( m_nIndex, pTiger ) )
	{
		TIGEROOT pRoot;
		pTiger->GetRoot( &pRoot );
		if ( ! m_bTiger || m_pTiger == pRoot ) return pTiger;
		
		LibraryHashDB.DeleteTiger( m_nIndex );
		
		Library.RemoveFile( this );
		m_bTiger = FALSE;
		Library.AddFile( this );
	}
	
	delete pTiger;
	return NULL;
}

CED2K* CLibraryFile::GetED2K()
{
	if ( m_bED2K == FALSE ) return NULL;
	if ( m_pFolder == NULL ) return NULL;
	
	CED2K* pED2K = new CED2K();
	
	if ( LibraryHashDB.GetED2K( m_nIndex, pED2K ) )
	{
		MD4 pRoot;
		pED2K->GetRoot( &pRoot );
		if ( m_pED2K == pRoot ) return pED2K;
		
		LibraryHashDB.DeleteED2K( m_nIndex );
	}
	
	delete pED2K;
	Library.RemoveFile( this );
	m_bED2K = FALSE;
	Library.AddFile( this );
	
	return NULL;
}

//////////////////////////////////////////////////////////////////////
// CLibraryFile alternate sources

CSharedSource* CLibraryFile::AddAlternateSources(LPCTSTR pszURL)
{
	CString strURLs( pszURL );
	CSharedSource* pFirst = NULL;
	BOOL bQuote = FALSE;
	
	for ( int nScan = 0 ; nScan < strURLs.GetLength() ; nScan++ )
	{

⌨️ 快捷键说明

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