📄 sharedfile.cpp
字号:
//
// 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 + -