📄 sharedfile.cpp
字号:
if ( strURLs[ nScan ] == '\"' )
{
bQuote = ! bQuote;
strURLs.SetAt( nScan, ' ' );
}
else if ( strURLs[ nScan ] == ',' && bQuote )
{
strURLs.SetAt( nScan, '`' );
}
}
strURLs += ',';
for ( int nCount = 0 ; ; )
{
int nPos = strURLs.Find( ',' );
if ( nPos < 0 ) break;
CString strURL = strURLs.Left( nPos );
strURLs = strURLs.Mid( nPos + 1 );
strURL.TrimLeft();
if ( _tcsistr( strURL, _T("://") ) != NULL )
{
for ( int nScan = 0 ; nScan < strURL.GetLength() ; nScan++ )
{
if ( strURL[ nScan ] == '`' ) strURL.SetAt( nScan, ',' );
}
}
else
{
nPos = strURL.Find( ':' );
if ( nPos < 1 ) continue;
int nPort = 0;
_stscanf( strURL.Mid( nPos + 1 ), _T("%i"), &nPort );
strURL.Truncate( nPos );
USES_CONVERSION;
DWORD nAddress = inet_addr( T2CA( strURL ) );
strURL.Empty();
if ( ! Network.IsFirewalledAddress( &nAddress, TRUE ) && nPort != 0 && nAddress != INADDR_NONE )
{
if ( m_bSHA1 )
{
strURL.Format( _T("http://%s:%i/uri-res/N2R?%s"),
(LPCTSTR)CString( inet_ntoa( *(IN_ADDR*)&nAddress ) ),
nPort, (LPCTSTR)CSHA::HashToString( &m_pSHA1, TRUE ) );
}
}
}
if ( CSharedSource* pSource = AddAlternateSource( strURL, FALSE ) )
{
pFirst = pSource;
nCount++;
}
}
return pFirst;
}
CSharedSource* CLibraryFile::AddAlternateSource(LPCTSTR pszURL, BOOL bForce)
{
if ( pszURL == NULL ) return NULL;
if ( *pszURL == 0 ) return NULL;
CString strURL( pszURL );
CSourceURL pURL;
FILETIME tSeen = { 0, 0 };
BOOL bSeen = FALSE;
int nPos = strURL.ReverseFind( ' ' );
if ( nPos > 0 )
{
CString strTime = strURL.Mid( nPos + 1 );
strURL = strURL.Left( nPos );
strURL.TrimRight();
bSeen = TimeFromString( strTime, &tSeen );
}
// if ( ! bSeen && ! bForce ) return NULL;
if ( ! pURL.Parse( strURL ) ) return NULL;
if ( memcmp( &pURL.m_pAddress, &Network.m_pHost.sin_addr,
sizeof(IN_ADDR) ) == 0 ) return NULL;
if ( Network.IsFirewalledAddress( &pURL.m_pAddress, TRUE ) ) return FALSE;
if ( pURL.m_bSHA1 && m_bSHA1 && pURL.m_pSHA1 != m_pSHA1 ) return NULL;
for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
{
CSharedSource* pSource = (CSharedSource*)m_pSources.GetNext( pos );
if ( pSource->m_sURL.CompareNoCase( strURL ) == 0 )
{
pSource->Freshen( bSeen ? &tSeen : NULL );
return pSource;
}
}
CSharedSource* pSource = new CSharedSource( strURL, bSeen ? &tSeen : NULL );
m_pSources.AddTail( pSource );
return pSource;
}
CString CLibraryFile::GetAlternateSources(CStringList* pState, int nMaximum, BOOL bHTTP)
{
CString strSources;
SYSTEMTIME stNow;
FILETIME ftNow;
GetSystemTime( &stNow );
SystemTimeToFileTime( &stNow, &ftNow );
for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
{
CSharedSource* pSource = (CSharedSource*)m_pSources.GetNext( pos );
if ( ! pSource->IsExpired( ftNow ) &&
( pState == NULL || pState->Find( pSource->m_sURL ) == NULL ) )
{
if ( pState != NULL ) pState->AddTail( pSource->m_sURL );
if ( bHTTP && _tcsncmp( pSource->m_sURL, _T("http://"), 7 ) != 0 ) continue;
CString strURL = pSource->m_sURL;
Replace( strURL, _T(","), _T("%2C") );
if ( strSources.GetLength() ) strSources += _T(", ");
strSources += strURL;
strSources += ' ';
strSources += TimeToString( &pSource->m_pTime );
if ( nMaximum == 1 ) break;
else if ( nMaximum > 1 ) nMaximum --;
}
}
if ( strSources.Find( _T("Zhttp://") ) >= 0 ) strSources.Empty();
return strSources;
}
//////////////////////////////////////////////////////////////////////
// CLibraryFile serialize
void CLibraryFile::Serialize(CArchive& ar, int nVersion)
{
if ( ar.IsStoring() )
{
ar << m_sName;
ar << m_nIndex;
ar << m_nSize;
ar.Write( &m_pTime, sizeof(m_pTime) );
ar << m_bShared;
ar << m_nVirtualSize;
if ( m_nVirtualSize > 0 ) ar << m_nVirtualBase;
ar << m_bSHA1;
if ( m_bSHA1 ) ar.Write( &m_pSHA1, sizeof(SHA1) );
ar << m_bTiger;
if ( m_bTiger ) ar.Write( &m_pTiger, sizeof(TIGEROOT) );
ar << m_bMD5;
if ( m_bMD5 ) ar.Write( &m_pMD5, sizeof(MD5) );
ar << m_bED2K;
if ( m_bED2K ) ar.Write( &m_pED2K, sizeof(MD4) );
ar << m_bVerify;
if ( m_pSchema != NULL && m_pMetadata != NULL )
{
ar << m_pSchema->m_sURI;
ar << m_bMetadataAuto;
if ( ! m_bMetadataAuto ) ar.Write( &m_pMetadataTime, sizeof(m_pMetadataTime) );
m_pMetadata->Serialize( ar );
}
else
{
CString strURI;
ar << strURI;
}
ar << m_nRating;
ar << m_sComments;
ar << m_sShareTags;
if ( m_bMetadataAuto && ( m_nRating || m_sComments.GetLength() ) )
{
ar.Write( &m_pMetadataTime, sizeof(m_pMetadataTime) );
}
ar << m_nHitsTotal;
ar << m_nUploadsTotal;
ar << m_bCachedPreview;
ar << m_bBogus;
ar.WriteCount( m_pSources.GetCount() );
for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
{
CSharedSource* pSource = (CSharedSource*)m_pSources.GetNext( pos );
pSource->Serialize( ar, nVersion );
}
}
else
{
ar >> m_sName;
ar >> m_nIndex;
if ( nVersion >= 17 )
{
ar >> m_nSize;
}
else
{
DWORD nSize;
ar >> nSize;
m_nSize = nSize;
}
ar.Read( &m_pTime, sizeof(m_pTime) );
if ( nVersion >= 5 )
{
ar >> m_bShared;
}
else
{
BYTE bShared;
ar >> bShared;
m_bShared = bShared ? TS_UNKNOWN : TS_FALSE;
}
if ( nVersion >= 21 )
{
ar >> m_nVirtualSize;
if ( m_nVirtualSize > 0 ) ar >> m_nVirtualBase;
}
ar >> m_bSHA1;
if ( m_bSHA1 ) ar.Read( &m_pSHA1, sizeof(SHA1) );
if ( nVersion >= 8 ) ar >> m_bTiger; else m_bSHA1 = FALSE;
if ( m_bTiger ) ar.Read( &m_pTiger, sizeof(TIGEROOT) );
if ( nVersion >= 11 ) ar >> m_bMD5; else m_bMD5 = FALSE;
if ( m_bMD5 ) ar.Read( &m_pMD5, sizeof(MD5) );
if ( nVersion >= 11 ) ar >> m_bED2K; else m_bED2K = FALSE;
if ( m_bED2K ) ar.Read( &m_pED2K, sizeof(MD4) );
if ( nVersion >= 4 ) ar >> m_bVerify;
CString strURI;
ar >> strURI;
if ( strURI.GetLength() )
{
ar >> m_bMetadataAuto;
if ( ! m_bMetadataAuto ) ar.Read( &m_pMetadataTime, sizeof(m_pMetadataTime) );
m_pMetadata = new CXMLElement();
m_pMetadata->Serialize( ar );
m_pSchema = SchemaCache.Get( strURI );
if ( m_pSchema == NULL )
{
delete m_pMetadata;
m_pMetadata = NULL;
}
}
if ( nVersion >= 13 )
{
ar >> m_nRating;
ar >> m_sComments;
if ( nVersion >= 16 ) ar >> m_sShareTags;
if ( m_bMetadataAuto && ( m_nRating || m_sComments.GetLength() ) )
{
ar.Read( &m_pMetadataTime, sizeof(m_pMetadataTime) );
}
}
ar >> m_nHitsTotal;
ar >> m_nUploadsTotal;
if ( nVersion >= 14 ) ar >> m_bCachedPreview;
if ( nVersion >= 20 ) ar >> m_bBogus;
if ( nVersion >= 2 )
{
SYSTEMTIME stNow;
FILETIME ftNow;
GetSystemTime( &stNow );
SystemTimeToFileTime( &stNow, &ftNow );
for ( int nSources = ar.ReadCount() ; nSources > 0 ; nSources-- )
{
CSharedSource* pSource = new CSharedSource();
pSource->Serialize( ar, nVersion );
if ( pSource->IsExpired( ftNow ) )
delete pSource;
else
m_pSources.AddTail( pSource );
}
}
// Rehash pre-version-22 audio files
if ( nVersion < 22 && m_pSchema != NULL && m_pSchema->m_sURI.CompareNoCase( CSchema::uriAudio ) == 0 )
{
m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
}
Library.AddFile( this );
}
}
//////////////////////////////////////////////////////////////////////
// CLibraryFile threaded scan
BOOL CLibraryFile::ThreadScan(CSingleLock& pLock, DWORD nScanCookie, QWORD nSize, FILETIME* pTime, LPCTSTR pszMetaData)
{
BOOL bChanged = FALSE;
ASSERT( m_pFolder != NULL );
m_nScanCookie = nScanCookie;
if ( m_nSize != nSize || CompareFileTime( &m_pTime, pTime ) != 0 )
{
bChanged = TRUE;
pLock.Lock();
Library.RemoveFile( this );
CopyMemory( &m_pTime, pTime, sizeof(FILETIME) );
m_nSize = nSize;
m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
if ( m_pMetadata != NULL && m_bMetadataAuto )
{
delete m_pMetadata;
m_pSchema = NULL;
m_pMetadata = NULL;
m_bMetadataAuto = FALSE;
}
}
HANDLE hFile = INVALID_HANDLE_VALUE;
BOOL bMetaData = FALSE;
FILETIME pMetaDataTime;
if ( pszMetaData != NULL )
{
CString strMetaData = pszMetaData + m_sName + _T(".xml");
if ( Library.m_pfnGFAEW != NULL && theApp.m_bNT )
{
USES_CONVERSION;
WIN32_FILE_ATTRIBUTE_DATA pInfo;
bMetaData = (*Library.m_pfnGFAEW)( T2CW( (LPCTSTR)strMetaData ), GetFileExInfoStandard, &pInfo );
pMetaDataTime = pInfo.ftLastWriteTime;
}
else if ( Library.m_pfnGFAEA != NULL )
{
USES_CONVERSION;
WIN32_FILE_ATTRIBUTE_DATA pInfo;
bMetaData = (*Library.m_pfnGFAEA)( T2CA( (LPCTSTR)strMetaData ), GetFileExInfoStandard, &pInfo );
pMetaDataTime = pInfo.ftLastWriteTime;
}
else
{
hFile = CreateFile( strMetaData, GENERIC_READ, FILE_SHARE_READ,
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
if ( hFile != INVALID_HANDLE_VALUE )
{
bMetaData = TRUE;
GetFileTime( hFile, NULL, NULL, &pMetaDataTime );
}
}
}
if ( bMetaData )
{
if ( CompareFileTime( &m_pMetadataTime, &pMetaDataTime ) != 0 )
{
CopyMemory( &m_pMetadataTime, &pMetaDataTime, sizeof(FILETIME) );
if ( hFile == INVALID_HANDLE_VALUE )
{
hFile = CreateFile( pszMetaData + m_sName + _T(".xml"),
GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
FILE_ATTRIBUTE_NORMAL, NULL );
}
if ( hFile != INVALID_HANDLE_VALUE )
{
if ( ! bChanged )
{
bChanged = TRUE;
pLock.Lock();
Library.RemoveFile( this );
}
LoadMetadata( hFile );
}
}
if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile );
}
else if ( m_pMetadata != NULL && ! m_bMetadataAuto )
{
BOOL bLocked = ! bChanged;
if ( bLocked ) pLock.Lock();
if ( m_pMetadata != NULL && ! m_bMetadataAuto )
{
if ( ! bChanged )
{
bChanged = TRUE;
bLocked = FALSE;
Library.RemoveFile( this );
}
ZeroMemory( &m_pMetadataTime, sizeof(FILETIME) );
LoadMetadata( INVALID_HANDLE_VALUE );
m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
}
if ( bLocked ) pLock.Unlock();
}
if ( bChanged )
{
Library.AddFile( this );
CFolderScanDlg::Update( m_sName, (DWORD)( m_nSize / 1024 ), FALSE );
pLock.Unlock();
m_nUpdateCookie++;
}
else
{
CFolderScanDlg::Update( m_sName, (DWORD)( m_nSize / 1024 ), TRUE );
}
return bChanged;
}
//////////////////////////////////////////////////////////////////////
// CLibraryFile metadata file I/O
BOOL CLibraryFile::LoadMetadata(HANDLE hFile)
{
ASSERT( m_pFolder != NULL );
if ( m_bMetadataAuto == FALSE )
{
if ( m_pMetadata != NULL ) delete m_pMetadata;
m_pSchema = NULL;
m_pMetadata = NULL;
}
if ( hFile == INVALID_HANDLE_VALUE ) return FALSE;
CXMLElement* pXML = CXMLElement::FromFile( hFile );
if ( pXML == NULL ) return FALSE;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -