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