Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

SharedFile.cpp

Go to the documentation of this file.
00001 //
00002 // SharedFile.cpp
00003 //
00004 // Copyright (c) Shareaza Development Team, 2002-2005.
00005 // This file is part of SHAREAZA (www.shareaza.com)
00006 //
00007 // Shareaza is free software; you can redistribute it
00008 // and/or modify it under the terms of the GNU General Public License
00009 // as published by the Free Software Foundation; either version 2 of
00010 // the License, or (at your option) any later version.
00011 //
00012 // Shareaza is distributed in the hope that it will be useful,
00013 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015 // GNU General Public License for more details.
00016 //
00017 // You should have received a copy of the GNU General Public License
00018 // along with Shareaza; if not, write to the Free Software
00019 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 //
00021 
00022 #include "StdAfx.h"
00023 #include "Shareaza.h"
00024 #include "Settings.h"
00025 #include "SharedFile.h"
00026 #include "SharedFolder.h"
00027 #include "Library.h"
00028 #include "HashDatabase.h"
00029 
00030 #include "Network.h"
00031 #include "Uploads.h"
00032 #include "Downloads.h"
00033 #include "SourceURL.h"
00034 #include "FileExecutor.h"
00035 #include "Buffer.h"
00036 
00037 #include "XML.h"
00038 #include "XMLCOM.h"
00039 #include "Schema.h"
00040 #include "SchemaCache.h"
00041 
00042 #include "SHA.h"
00043 #include "MD5.h"
00044 #include "ED2K.h"
00045 #include "TigerTree.h"
00046 
00047 #include "Application.h"
00048 #include "VersionChecker.h"
00049 #include "DlgFolderScan.h"
00050 
00051 #ifdef _DEBUG
00052 #undef THIS_FILE
00053 static char THIS_FILE[]=__FILE__;
00054 #define new DEBUG_NEW
00055 #endif
00056 
00057 IMPLEMENT_DYNAMIC(CLibraryFile, CComObject)
00058 
00059 BEGIN_INTERFACE_MAP(CLibraryFile, CComObject)
00060         INTERFACE_PART(CLibraryFile, IID_ILibraryFile, LibraryFile)
00061 END_INTERFACE_MAP()
00062 
00063 
00065 // CLibraryFile construction
00066 
00067 CLibraryFile::CLibraryFile(CLibraryFolder* pFolder, LPCTSTR pszName)
00068 {
00069         EnableDispatch( IID_ILibraryFile );
00070         
00071         m_pFolder               = pFolder;
00072         m_pNextSHA1             = NULL;
00073         m_pNextTiger    = NULL;
00074         m_pNextED2K             = NULL;
00075         m_nScanCookie   = 0;
00076         m_nUpdateCookie = 0;
00077         m_nSelectCookie = 0;
00078         
00079         m_nIndex                = 0;
00080         m_nSize                 = 0;
00081         m_bShared               = TS_UNKNOWN;
00082         m_nVirtualBase  = 0;
00083         m_nVirtualSize  = 0;
00084         
00085         m_bSHA1                 = FALSE;
00086         m_bTiger                = FALSE;
00087         m_bMD5                  = FALSE;
00088         m_bED2K                 = FALSE;
00089         m_bVerify               = TS_UNKNOWN;
00090         
00091         m_pSchema               = NULL;
00092         m_pMetadata             = NULL;
00093         m_bMetadataAuto = FALSE;
00094         m_nRating               = 0;
00095         
00096         m_nHitsToday            = 0;
00097         m_nHitsTotal            = 0;
00098         m_nUploadsToday         = 0;
00099         m_nUploadsTotal         = 0;
00100         m_bCachedPreview        = FALSE;
00101         m_bBogus                        = FALSE;
00102         
00103         m_nSearchCookie = 0;
00104         m_nSearchWords  = 0;
00105         m_nCollIndex    = 0;
00106         m_nIcon16               = -1;
00107         
00108         if ( pszName != NULL ) m_sName = pszName;
00109 }
00110 
00111 CLibraryFile::~CLibraryFile()
00112 {
00113         Library.RemoveFile( this );
00114         
00115         if ( m_pMetadata != NULL ) delete m_pMetadata;
00116         
00117         for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
00118         {
00119                 delete (CSharedSource*)m_pSources.GetNext( pos );
00120         }
00121 }
00122 
00124 // CLibraryFile path computation
00125 
00126 CString CLibraryFile::GetPath() const
00127 {
00128         if ( m_pFolder != NULL )
00129                 return m_pFolder->m_sPath + '\\' + m_sName;
00130         else
00131                 return CString();
00132 }
00133 
00134 CString CLibraryFile::GetSearchName() const
00135 {
00136         int nBase = 0;
00137         CString str;
00138         
00139         if ( m_pFolder != NULL && m_pFolder->m_pParent != NULL )
00140         {
00141                 for ( CLibraryFolder* pFolder = m_pFolder ; ; pFolder = pFolder->m_pParent )
00142                 {
00143                         if ( pFolder->m_pParent == NULL )
00144                         {
00145                                 nBase = pFolder->m_sPath.GetLength();
00146                                 break;
00147                         }
00148                 }
00149         }
00150         
00151         if ( nBase <= 0 )
00152         {
00153                 str = m_sName;
00154         }
00155         else
00156         {
00157                 ASSERT( m_pFolder->m_sPath.GetLength() > nBase );
00158                 str = m_pFolder->m_sPath.Mid( nBase + 1 ) + '\\' + m_sName;
00159         }
00160         
00161         ToLower( str );
00162         return str;
00163 }
00164 
00166 // CLibraryFile shared check
00167 
00168 BOOL CLibraryFile::IsShared() const
00169 {
00170         if ( LPCTSTR pszExt = _tcsrchr( m_sName, '.' ) )
00171         {
00172                 pszExt++;
00173                 
00174                 if ( LPCTSTR pszFind = _tcsistr( Settings.Library.PrivateTypes, pszExt ) )
00175                 {
00176                         if ( pszFind[ _tcslen( pszExt ) ] == 0 ||
00177                                  pszFind[ _tcslen( pszExt ) ] == '|' )
00178                         {
00179                                 if ( pszFind == Settings.Library.PrivateTypes ||
00180                                          pszFind[-1] == '|' )
00181                                 {
00182                                         return FALSE;
00183                                 }
00184                         }
00185                 }
00186         }
00187         
00188         if ( m_bShared )
00189         {
00190                 if ( m_bShared == TS_TRUE ) return TRUE;
00191                 if ( m_bShared == TS_FALSE ) return FALSE;
00192         }
00193         
00194         for ( CLibraryFolder* pFolder = m_pFolder ; pFolder ; pFolder = pFolder->m_pParent )
00195         {
00196                 if ( pFolder->m_bShared )
00197                 {
00198                         if ( pFolder->m_bShared == TS_TRUE ) return TRUE;
00199                         if ( pFolder->m_bShared == TS_FALSE ) return FALSE;
00200                 }
00201         }
00202         
00203         return TRUE;
00204 }
00205 
00207 // CLibraryFile schema URI test
00208 
00209 BOOL CLibraryFile::IsSchemaURI(LPCTSTR pszURI) const
00210 {
00211         if ( m_pSchema == NULL )
00212         {
00213                 return ( pszURI == NULL || *pszURI == NULL );
00214         }
00215         else
00216         {
00217                 return m_pSchema->CheckURI( pszURI );
00218         }
00219 }
00220 
00222 // CLibraryFile rebuild hashes and metadata
00223 
00224 BOOL CLibraryFile::Rebuild()
00225 {
00226         if ( m_pFolder == NULL ) return FALSE;
00227         
00228         Library.RemoveFile( this );
00229         
00230         m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
00231         m_nVirtualBase = m_nVirtualSize = 0;
00232         
00233         if ( m_pMetadata != NULL && m_bMetadataAuto )
00234         {
00235                 delete m_pMetadata;
00236                 m_pSchema       = NULL;
00237                 m_pMetadata     = NULL;
00238         }
00239         
00240         Library.AddFile( this );
00241         
00242         return TRUE;
00243 }
00244 
00246 // CLibraryFile rename
00247 
00248 BOOL CLibraryFile::Rename(LPCTSTR pszName)
00249 {
00250         if ( m_pFolder == NULL ) return FALSE;
00251         if ( ! pszName || ! *pszName ) return FALSE;
00252         if ( _tcschr( pszName, '\\' ) ) return FALSE;
00253         
00254         CString strNew = m_pFolder->m_sPath + '\\' + pszName;
00255         
00256         Uploads.OnRename( GetPath() );
00257         
00258         if ( MoveFile( GetPath(), strNew ) )
00259         {
00260                 Uploads.OnRename( GetPath(), strNew );
00261         }
00262         else
00263         {
00264                 Uploads.OnRename( GetPath(), GetPath() );
00265                 return FALSE;
00266         }
00267         
00268         if ( m_pMetadata != NULL )
00269         {
00270                 CString strMetaFolder   = m_pFolder->m_sPath + _T("\\Metadata");
00271                 CString strMetaOld              = strMetaFolder + '\\' + m_sName + _T(".xml");
00272                 CString strMetaNew              = strMetaFolder + '\\' + pszName + _T(".xml");
00273                 
00274                 MoveFile( strMetaOld, strMetaNew );
00275         }
00276         
00277         Library.RemoveFile( this );
00278         
00279         m_sName = pszName;
00280         
00281         m_pFolder->OnFileRename( this );
00282         
00283         Library.AddFile( this );
00284         
00285         return TRUE;
00286 }
00287 
00289 // CLibraryFile delete
00290 
00291 BOOL CLibraryFile::Delete()
00292 {
00293         if ( m_pFolder != NULL )
00294         {
00295                 Uploads.OnRename( GetPath(), NULL );
00296                 
00297                 LPTSTR pszPath = new TCHAR[ GetPath().GetLength() + 2 ];
00298                 _tcscpy( pszPath, GetPath() );
00299                 pszPath[ GetPath().GetLength() + 1 ] = 0;
00300                 
00301                 SHFILEOPSTRUCT pOp;
00302                 ZeroMemory( &pOp, sizeof(pOp) );
00303                 pOp.wFunc       = FO_DELETE;
00304                 pOp.pFrom       = pszPath;
00305                 pOp.fFlags      = FOF_ALLOWUNDO|FOF_NOCONFIRMATION;
00306                 
00307                 if ( GetAsyncKeyState( VK_SHIFT ) & 0x8000 ) pOp.fFlags &= ~FOF_ALLOWUNDO;
00308                 
00309                 int nReturn = SHFileOperation( &pOp );
00310                 
00311                 delete [] pszPath;
00312 
00313                 if ( nReturn != 0 )
00314                 {
00315                         Uploads.OnRename( GetPath(), GetPath() );
00316                         return FALSE;
00317                 }
00318                 
00319                 if ( m_pMetadata != NULL || m_sComments.GetLength() || m_nRating > 0 )
00320                 {
00321                         CString strMetaFolder   = m_pFolder->m_sPath + _T("\\Metadata");
00322                         CString strMetaFile             = strMetaFolder + '\\' + m_sName + _T(".xml");
00323                         
00324                         if ( DeleteFile( strMetaFile ) )
00325                         {
00326                                 RemoveDirectory( strMetaFolder );
00327                         }
00328                 }
00329         }
00330         else
00331         {
00332                 OnDelete();
00333         }
00334         
00335         return TRUE;
00336 }
00337 
00339 // CLibraryFile metadata access
00340 
00341 BOOL CLibraryFile::SetMetadata(CXMLElement* pXML)
00342 {
00343         if ( m_pFolder == NULL ) return FALSE;
00344         if ( m_pMetadata == NULL && pXML == NULL ) return TRUE;
00345         
00346         CSchema* pSchema = NULL;
00347         
00348         if ( pXML != NULL )
00349         {
00350                 pSchema = SchemaCache.Get( pXML->GetAttributeValue( CXMLAttribute::schemaName ) );
00351                 if ( pSchema == NULL ) return FALSE;
00352                 if ( ! pSchema->Validate( pXML, TRUE ) ) return FALSE;
00353                 
00354                 if ( m_pMetadata != NULL && m_pSchema == pSchema )
00355                 {
00356                         if ( m_pMetadata->Equals( pXML->GetFirstElement() ) ) return TRUE;
00357                 }
00358         }
00359         
00360         Library.RemoveFile( this );
00361         
00362         if ( m_pMetadata != NULL )
00363         {
00364                 delete m_pMetadata;
00365                 m_pSchema               = NULL;
00366                 m_pMetadata             = NULL;
00367                 m_bMetadataAuto = FALSE;
00368         }
00369         
00370         m_pSchema               = pSchema;
00371         m_pMetadata             = pXML ? pXML->GetFirstElement()->Detach() : NULL;
00372         m_bMetadataAuto = FALSE;
00373         
00374         if ( m_pMetadata == NULL )
00375         {
00376                 m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = NULL;
00377         }
00378         
00379         Library.AddFile( this );
00380         
00381         SaveMetadata();
00382         
00383         return TRUE;
00384 }
00385 
00386 CString CLibraryFile::GetMetadataWords() const
00387 {
00388         if ( m_pSchema != NULL && m_pMetadata != NULL )
00389         {
00390                 return m_pSchema->GetIndexedWords( m_pMetadata );
00391         }
00392         else
00393         {
00394                 return CString();
00395         }
00396 }
00397 
00399 // CLibraryFile hash volume lookups
00400 
00401 CTigerTree* CLibraryFile::GetTigerTree()
00402 {
00403         if ( m_bTiger == FALSE ) return NULL;
00404         if ( m_pFolder == NULL ) return NULL;
00405         
00406         CTigerTree* pTiger = new CTigerTree();
00407         
00408         if ( LibraryHashDB.GetTiger( m_nIndex, pTiger ) )
00409         {
00410                 TIGEROOT pRoot;
00411                 pTiger->GetRoot( &pRoot );
00412                 if ( ! m_bTiger || m_pTiger == pRoot ) return pTiger;
00413                 
00414                 LibraryHashDB.DeleteTiger( m_nIndex );
00415                 
00416                 Library.RemoveFile( this );
00417                 m_bTiger = FALSE;
00418                 Library.AddFile( this );
00419         }
00420         
00421         delete pTiger;
00422         return NULL;
00423 }
00424 
00425 CED2K* CLibraryFile::GetED2K()
00426 {
00427         if ( m_bED2K == FALSE ) return NULL;
00428         if ( m_pFolder == NULL ) return NULL;
00429         
00430         CED2K* pED2K = new CED2K();
00431         
00432         if ( LibraryHashDB.GetED2K( m_nIndex, pED2K ) )
00433         {
00434                 MD4 pRoot;
00435                 pED2K->GetRoot( &pRoot );
00436                 if ( m_pED2K == pRoot ) return pED2K;
00437                 
00438                 LibraryHashDB.DeleteED2K( m_nIndex );
00439         }
00440         
00441         delete pED2K;
00442         Library.RemoveFile( this );
00443         m_bED2K = FALSE;
00444         Library.AddFile( this );
00445         
00446         return NULL;
00447 }
00448 
00450 // CLibraryFile alternate sources
00451 
00452 CSharedSource* CLibraryFile::AddAlternateSources(LPCTSTR pszURL)
00453 {
00454         CString strURLs( pszURL );
00455         CSharedSource* pFirst = NULL;
00456         BOOL bQuote = FALSE;
00457         
00458         for ( int nScan = 0 ; nScan < strURLs.GetLength() ; nScan++ )
00459         {
00460                 if ( strURLs[ nScan ] == '\"' )
00461                 {
00462                         bQuote = ! bQuote;
00463                         strURLs.SetAt( nScan, ' ' );
00464                 }
00465                 else if ( strURLs[ nScan ] == ',' && bQuote )
00466                 {
00467                         strURLs.SetAt( nScan, '`' );
00468                 }
00469         }
00470         
00471         strURLs += ',';
00472         
00473         for ( int nCount = 0 ; ; )
00474         {
00475                 int nPos = strURLs.Find( ',' );
00476                 if ( nPos < 0 ) break;
00477                 
00478                 CString strURL  = strURLs.Left( nPos );
00479                 strURLs                 = strURLs.Mid( nPos + 1 );
00480                 strURL.TrimLeft();
00481                 
00482                 if ( _tcsistr( strURL, _T("://") ) != NULL )
00483                 {
00484                         for ( int nScan = 0 ; nScan < strURL.GetLength() ; nScan++ )
00485                         {
00486                                 if ( strURL[ nScan ] == '`' ) strURL.SetAt( nScan, ',' );
00487                         }
00488                 }
00489                 else
00490                 {
00491                         nPos = strURL.Find( ':' );
00492                         if ( nPos < 1 ) continue;
00493                         
00494                         int nPort = 0;
00495                         _stscanf( strURL.Mid( nPos + 1 ), _T("%i"), &nPort );
00496                         strURL.Truncate( nPos );
00497                         USES_CONVERSION;
00498                         DWORD nAddress = inet_addr( T2CA( strURL ) );
00499                         strURL.Empty();
00500                         
00501                         if ( ! Network.IsFirewalledAddress( &nAddress, TRUE ) && nPort != 0 && nAddress != INADDR_NONE )
00502                         {
00503                                 if ( m_bSHA1 )
00504                                 {
00505                                         strURL.Format( _T("http://%s:%i/uri-res/N2R?%s"),
00506                                                 (LPCTSTR)CString( inet_ntoa( *(IN_ADDR*)&nAddress ) ),
00507                                                 nPort, (LPCTSTR)CSHA::HashToString( &m_pSHA1, TRUE ) );
00508                                 }
00509                         }
00510                 }
00511                 
00512                 if ( CSharedSource* pSource = AddAlternateSource( strURL, FALSE ) )
00513                 {
00514                         pFirst = pSource;
00515                         nCount++;
00516                 }
00517         }
00518         
00519         return pFirst;
00520 }
00521 
00522 CSharedSource* CLibraryFile::AddAlternateSource(LPCTSTR pszURL, BOOL bForce)
00523 {
00524         if ( pszURL == NULL ) return NULL;
00525         if ( *pszURL == 0 ) return NULL;
00526         
00527         CString strURL( pszURL );
00528         CSourceURL pURL;
00529         
00530         FILETIME tSeen = { 0, 0 };
00531         BOOL bSeen = FALSE;
00532         
00533         int nPos = strURL.ReverseFind( ' ' );
00534         
00535         if ( nPos > 0 )
00536         {
00537                 CString strTime = strURL.Mid( nPos + 1 );
00538                 strURL = strURL.Left( nPos );
00539                 strURL.TrimRight();
00540                 bSeen = TimeFromString( strTime, &tSeen );
00541         }
00542         
00543         // if ( ! bSeen && ! bForce ) return NULL;
00544         if ( ! pURL.Parse( strURL ) ) return NULL;
00545         
00546         if ( memcmp( &pURL.m_pAddress, &Network.m_pHost.sin_addr,
00547                  sizeof(IN_ADDR) ) == 0 ) return NULL;
00548         
00549         if ( Network.IsFirewalledAddress( &pURL.m_pAddress, TRUE ) ) return FALSE;
00550         
00551         if ( pURL.m_bSHA1 && m_bSHA1 && pURL.m_pSHA1 != m_pSHA1 ) return NULL;
00552         
00553         for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
00554         {
00555                 CSharedSource* pSource = (CSharedSource*)m_pSources.GetNext( pos );
00556                 
00557                 if ( pSource->m_sURL.CompareNoCase( strURL ) == 0 )
00558                 {
00559                         pSource->Freshen( bSeen ? &tSeen : NULL );
00560                         return pSource;
00561                 }
00562         }
00563         
00564         CSharedSource* pSource = new CSharedSource( strURL, bSeen ? &tSeen : NULL );
00565         m_pSources.AddTail( pSource );
00566         
00567         return pSource;
00568 }
00569 
00570 CString CLibraryFile::GetAlternateSources(CStringList* pState, int nMaximum, PROTOCOLID nProtocol)
00571 {
00572         CString strSources;
00573         SYSTEMTIME stNow;
00574         FILETIME ftNow;
00575         
00576         GetSystemTime( &stNow );
00577         SystemTimeToFileTime( &stNow, &ftNow );
00578         
00579         for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
00580         {
00581                 CSharedSource* pSource = (CSharedSource*)m_pSources.GetNext( pos );
00582                 
00583                 if ( ! pSource->IsExpired( ftNow ) &&
00584                          ( pState == NULL || pState->Find( pSource->m_sURL ) == NULL ) )
00585                 {
00586                         if ( pState != NULL ) pState->AddTail( pSource->m_sURL );
00587                         
00588                         if ( ( nProtocol == PROTOCOL_HTTP ) && ( _tcsncmp( pSource->m_sURL, _T("http://"), 7 ) != 0 ) )
00589                                 continue;
00590                         
00591                         CString strURL = pSource->m_sURL;
00592                         Replace( strURL, _T(","), _T("%2C") );
00593 
00594                         if ( strSources.GetLength() ) strSources += _T(", ");
00595                         strSources += strURL;
00596                         strSources += ' ';
00597                         strSources += TimeToString( &pSource->m_pTime );
00598 
00599                         if ( nMaximum == 1 ) break;
00600                         else if ( nMaximum > 1 ) nMaximum --;
00601                 }
00602         }
00603         
00604         if ( strSources.Find( _T("Zhttp://") ) >= 0 ) strSources.Empty();
00605         
00606         return strSources;
00607 }
00608 
00610 // CLibraryFile serialize
00611 
00612 void CLibraryFile::Serialize(CArchive& ar, int nVersion)
00613 {
00614         if ( ar.IsStoring() )
00615         {
00616                 ar << m_sName;
00617                 ar << m_nIndex;
00618                 ar << m_nSize;
00619                 ar.Write( &m_pTime, sizeof(m_pTime) );
00620                 ar << m_bShared;
00621                 
00622                 ar << m_nVirtualSize;
00623                 if ( m_nVirtualSize > 0 ) ar << m_nVirtualBase;
00624                 
00625                 ar << m_bSHA1;
00626                 if ( m_bSHA1 ) ar.Write( &m_pSHA1, sizeof(SHA1) );
00627                 ar << m_bTiger;
00628                 if ( m_bTiger ) ar.Write( &m_pTiger, sizeof(TIGEROOT) );
00629                 ar << m_bMD5;
00630                 if ( m_bMD5 ) ar.Write( &m_pMD5, sizeof(MD5) );
00631                 ar << m_bED2K;
00632                 if ( m_bED2K ) ar.Write( &m_pED2K, sizeof(MD4) );
00633                 ar << m_bVerify;
00634                 
00635                 if ( m_pSchema != NULL && m_pMetadata != NULL )
00636                 {
00637                         ar << m_pSchema->m_sURI;
00638                         ar << m_bMetadataAuto;
00639                         if ( ! m_bMetadataAuto ) ar.Write( &m_pMetadataTime, sizeof(m_pMetadataTime) );
00640                         m_pMetadata->Serialize( ar );
00641                 }
00642                 else
00643                 {
00644                         CString strURI;
00645                         ar << strURI;
00646                 }
00647                 
00648                 ar << m_nRating;
00649                 ar << m_sComments;
00650                 ar << m_sShareTags;
00651                 
00652                 if ( m_bMetadataAuto && ( m_nRating || m_sComments.GetLength() ) )
00653                 {
00654                         ar.Write( &m_pMetadataTime, sizeof(m_pMetadataTime) );
00655                 }
00656                 
00657                 ar << m_nHitsTotal;
00658                 ar << m_nUploadsTotal;
00659                 ar << m_bCachedPreview;
00660                 ar << m_bBogus;
00661                 
00662                 ar.WriteCount( m_pSources.GetCount() );
00663                 
00664                 for ( POSITION pos = m_pSources.GetHeadPosition() ; pos ; )
00665                 {
00666                         CSharedSource* pSource = (CSharedSource*)m_pSources.GetNext( pos );
00667                         pSource->Serialize( ar, nVersion );
00668                 }
00669         }
00670         else
00671         {
00672                 ar >> m_sName;
00673                 ar >> m_nIndex;
00674                 
00675                 if ( nVersion >= 17 )
00676                 {
00677             ar >> m_nSize;
00678                 }
00679                 else
00680                 {
00681                         DWORD nSize;
00682                         ar >> nSize;
00683                         m_nSize = nSize;
00684                 }
00685                 
00686                 ar.Read( &m_pTime, sizeof(m_pTime) );
00687                 
00688                 if ( nVersion >= 5 )
00689                 {
00690                         ar >> m_bShared;
00691                 }
00692                 else
00693                 {
00694                         BYTE bShared;
00695                         ar >> bShared;
00696                         m_bShared = bShared ? TS_UNKNOWN : TS_FALSE;
00697                 }
00698                 
00699                 if ( nVersion >= 21 )
00700                 {
00701                         ar >> m_nVirtualSize;
00702                         if ( m_nVirtualSize > 0 ) ar >> m_nVirtualBase;
00703                 }
00704                 
00705                 ar >> m_bSHA1;
00706                 if ( m_bSHA1 ) ar.Read( &m_pSHA1, sizeof(SHA1) );
00707                 if ( nVersion >= 8 ) ar >> m_bTiger; else m_bTiger = FALSE;
00708                 if ( m_bTiger ) ar.Read( &m_pTiger, sizeof(TIGEROOT) );
00709                 if ( nVersion >= 11 ) ar >> m_bMD5; else m_bMD5 = FALSE;
00710                 if ( m_bMD5 ) ar.Read( &m_pMD5, sizeof(MD5) );
00711                 if ( nVersion >= 11 ) ar >> m_bED2K; else m_bED2K = FALSE;
00712                 if ( m_bED2K ) ar.Read( &m_pED2K, sizeof(MD4) );
00713                 
00714                 if ( nVersion >= 4 ) ar >> m_bVerify;
00715                 
00716                 CString strURI;
00717                 ar >> strURI;
00718                 
00719                 if ( strURI.GetLength() )
00720                 {
00721                         ar >> m_bMetadataAuto;
00722                         if ( ! m_bMetadataAuto ) ar.Read( &m_pMetadataTime, sizeof(m_pMetadataTime) );
00723                         
00724                         m_pMetadata = new CXMLElement();
00725                         m_pMetadata->Serialize( ar );
00726                         m_pSchema = SchemaCache.Get( strURI );
00727                         
00728                         if ( m_pSchema == NULL )
00729                         {
00730                                 delete m_pMetadata;
00731                                 m_pMetadata = NULL;
00732                         }
00733                 }
00734                 
00735                 if ( nVersion >= 13 )
00736                 {
00737                         ar >> m_nRating;
00738                         ar >> m_sComments;
00739                         if ( nVersion >= 16 ) ar >> m_sShareTags;
00740                         
00741                         if ( m_bMetadataAuto && ( m_nRating || m_sComments.GetLength() ) )
00742                         {
00743                                 ar.Read( &m_pMetadataTime, sizeof(m_pMetadataTime) );
00744                         }
00745                 }
00746                 
00747                 ar >> m_nHitsTotal;
00748                 ar >> m_nUploadsTotal;
00749                 if ( nVersion >= 14 ) ar >> m_bCachedPreview;
00750                 if ( nVersion >= 20 ) ar >> m_bBogus;
00751                 
00752                 if ( nVersion >= 2 )
00753                 {
00754                         SYSTEMTIME stNow;
00755                         FILETIME ftNow;
00756                         
00757                         GetSystemTime( &stNow );
00758                         SystemTimeToFileTime( &stNow, &ftNow );
00759                         
00760                         for ( int nSources = ar.ReadCount() ; nSources > 0 ; nSources-- )
00761                         {
00762                                 CSharedSource* pSource = new CSharedSource();
00763                                 pSource->Serialize( ar, nVersion );
00764                                 
00765                                 if ( pSource->IsExpired( ftNow ) )
00766                                         delete pSource;
00767                                 else
00768                                         m_pSources.AddTail( pSource );
00769                         }
00770                 }
00771                 
00772                 // Rehash pre-version-22 audio files
00773                 
00774                 if ( nVersion < 22 && m_pSchema != NULL && m_pSchema->m_sURI.CompareNoCase( CSchema::uriAudio ) == 0 )
00775                 {
00776                         m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
00777                 }
00778                 
00779                 Library.AddFile( this );
00780         }
00781 }
00782 
00784 // CLibraryFile threaded scan
00785 
00786 BOOL CLibraryFile::ThreadScan(CSingleLock& pLock, DWORD nScanCookie, QWORD nSize, FILETIME* pTime, LPCTSTR pszMetaData)
00787 {
00788         BOOL bChanged = FALSE;
00789         
00790         ASSERT( m_pFolder != NULL );
00791         m_nScanCookie = nScanCookie;
00792         
00793         if ( m_nSize != nSize || CompareFileTime( &m_pTime, pTime ) != 0 )
00794         {
00795                 bChanged = TRUE;
00796                 pLock.Lock();
00797                 Library.RemoveFile( this );
00798                 
00799                 CopyMemory( &m_pTime, pTime, sizeof(FILETIME) );
00800                 m_nSize = nSize;
00801                 
00802                 m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
00803                 
00804                 if ( m_pMetadata != NULL && m_bMetadataAuto )
00805                 {
00806                         delete m_pMetadata;
00807                         m_pSchema               = NULL;
00808                         m_pMetadata             = NULL;
00809                         m_bMetadataAuto = FALSE;
00810                 }
00811         }
00812         
00813         HANDLE hFile    = INVALID_HANDLE_VALUE;
00814         BOOL bMetaData  = FALSE;
00815         FILETIME pMetaDataTime;
00816         
00817         if ( pszMetaData != NULL )
00818         {
00819                 CString strMetaData = pszMetaData + m_sName + _T(".xml");
00820                 
00821                 if ( Library.m_pfnGFAEW != NULL && theApp.m_bNT )
00822                 {
00823                         USES_CONVERSION;
00824                         WIN32_FILE_ATTRIBUTE_DATA pInfo;
00825                         bMetaData = (*Library.m_pfnGFAEW)( T2CW( (LPCTSTR)strMetaData ), GetFileExInfoStandard, &pInfo );
00826                         pMetaDataTime = pInfo.ftLastWriteTime;
00827                 }
00828                 else if ( Library.m_pfnGFAEA != NULL )
00829                 {
00830                         USES_CONVERSION;
00831                         WIN32_FILE_ATTRIBUTE_DATA pInfo;
00832                         bMetaData = (*Library.m_pfnGFAEA)( T2CA( (LPCTSTR)strMetaData ), GetFileExInfoStandard, &pInfo );
00833                         pMetaDataTime = pInfo.ftLastWriteTime;
00834                 }
00835                 else
00836                 {
00837                         hFile = CreateFile( strMetaData, GENERIC_READ, FILE_SHARE_READ,
00838                                 NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL );
00839                         
00840                         if ( hFile != INVALID_HANDLE_VALUE )
00841                         {
00842                                 bMetaData = TRUE;
00843                                 GetFileTime( hFile, NULL, NULL, &pMetaDataTime );
00844                         }
00845                 }
00846         }
00847         
00848         if ( bMetaData )
00849         {
00850                 if ( CompareFileTime( &m_pMetadataTime, &pMetaDataTime ) != 0 )
00851                 {
00852                         CopyMemory( &m_pMetadataTime, &pMetaDataTime, sizeof(FILETIME) );
00853                         
00854                         if ( hFile == INVALID_HANDLE_VALUE )
00855                         {
00856                                 hFile = CreateFile( pszMetaData + m_sName + _T(".xml"),
00857                                         GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING,
00858                                         FILE_ATTRIBUTE_NORMAL, NULL );
00859                         }
00860                         
00861                         if ( hFile != INVALID_HANDLE_VALUE )
00862                         {
00863                                 if ( ! bChanged )
00864                                 {
00865                                         bChanged = TRUE;
00866                                         pLock.Lock();
00867                                         Library.RemoveFile( this );
00868                                 }
00869                                 
00870                                 LoadMetadata( hFile );
00871                         }
00872                 }
00873                 
00874                 if ( hFile != INVALID_HANDLE_VALUE ) CloseHandle( hFile );
00875         }
00876         else if ( m_pMetadata != NULL && ! m_bMetadataAuto )
00877         {
00878                 BOOL bLocked = ! bChanged;
00879                 if ( bLocked ) pLock.Lock();
00880                 
00881                 if ( m_pMetadata != NULL && ! m_bMetadataAuto )
00882                 {
00883                         if ( ! bChanged )
00884                         {
00885                                 bChanged = TRUE;
00886                                 bLocked = FALSE;
00887                                 Library.RemoveFile( this );
00888                         }
00889                         
00890                         ZeroMemory( &m_pMetadataTime, sizeof(FILETIME) );
00891                         LoadMetadata( INVALID_HANDLE_VALUE );
00892                         
00893                         m_bSHA1 = m_bTiger = m_bMD5 = m_bED2K = FALSE;
00894                 }
00895                 
00896                 if ( bLocked ) pLock.Unlock();
00897         }
00898         
00899         if ( bChanged )
00900         {
00901                 Library.AddFile( this );
00902                 CFolderScanDlg::Update( m_sName, (DWORD)( m_nSize / 1024 ) );
00903                 pLock.Unlock();
00904                 m_nUpdateCookie++;
00905         }
00906         else
00907         {
00908                 CFolderScanDlg::Update( m_sName, (DWORD)( m_nSize / 1024 ) );
00909         }
00910         
00911         return bChanged;
00912 }
00913 
00915 // CLibraryFile metadata file I/O
00916 
00917 BOOL CLibraryFile::LoadMetadata(HANDLE hFile)
00918 {
00919         ASSERT( m_pFolder != NULL );
00920         
00921         if ( m_bMetadataAuto == FALSE )
00922         {
00923                 if ( m_pMetadata != NULL ) delete m_pMetadata;
00924                 m_pSchema       = NULL;
00925                 m_pMetadata     = NULL;
00926         }
00927         
00928         if ( hFile == INVALID_HANDLE_VALUE ) return FALSE;
00929         
00930         CXMLElement* pXML = CXMLElement::FromFile( hFile );
00931         if ( pXML == NULL ) return FALSE;
00932         
00933         if ( CXMLElement* pComment = pXML->GetElementByName( _T("comment") ) )
00934         {
00935                 m_nRating = -1;
00936                 CString strRating = pComment->GetAttributeValue( _T("rating") );
00937                 _stscanf( strRating, _T("%i"), &m_nRating );
00938                 m_nRating       = max( 0, min( 6, m_nRating + 1 ) );
00939                 m_sComments     = pComment->GetValue();
00940                 Replace( m_sComments, _T("{n}"), _T("\r\n") );
00941                 pComment->Delete();
00942         }
00943         
00944         CSchema* pSchema = SchemaCache.Get( pXML->GetAttributeValue( CXMLAttribute::schemaName, _T("") ) );
00945         
00946         if ( pSchema == NULL || pXML->GetFirstElement() == NULL )
00947         {
00948                 delete pXML;
00949                 return FALSE;
00950         }
00951         
00952         pSchema->Validate( pXML, TRUE );
00953         
00954         if ( m_pMetadata != NULL ) delete m_pMetadata;
00955         
00956         m_pSchema               = pSchema;
00957         m_pMetadata             = pXML->GetFirstElement()->Detach();
00958         m_bMetadataAuto = FALSE;
00959         
00960         delete pXML;
00961         
00962         return TRUE;
00963 }
00964 
00965 BOOL CLibraryFile::SaveMetadata()
00966 {
00967         CXMLElement* pXML = NULL;
00968         
00969         m_nUpdateCookie++;
00970         
00971         if ( m_pFolder == NULL ) return TRUE;
00972         
00973         if ( m_pSchema != NULL && m_pMetadata != NULL && ! m_bMetadataAuto )
00974         {
00975                 pXML = m_pSchema->Instantiate( TRUE );
00976                 pXML->AddElement( m_pMetadata->Clone() );
00977         }
00978         
00979         if ( m_nRating > 0 || m_sComments.GetLength() > 0 )
00980         {
00981                 if ( pXML == NULL )
00982                 {
00983                         pXML = new CXMLElement( NULL, _T("comments") );
00984                 }
00985                 
00986                 CXMLElement* pComment = pXML->AddElement( _T("comment") );
00987                 
00988                 if ( m_nRating > 0 )
00989                 {
00990                         CString strRating;
00991                         strRating.Format( _T("%i"), m_nRating - 1 );
00992                         pComment->AddAttribute( _T("rating"), strRating );
00993                 }
00994                 
00995                 if ( m_sComments.GetLength() > 0 )
00996                 {
00997                         CString strComments( m_sComments );
00998                         Replace( strComments, _T("\r\n"), _T("{n}") );
00999                         pComment->SetValue( strComments );
01000                 }
01001         }
01002         
01003         CString strMetaFolder   = m_pFolder->m_sPath + _T("\\Metadata");
01004         CString strMetaFile             = strMetaFolder + _T("\\") + m_sName + _T(".xml");
01005         
01006         if ( pXML != NULL )
01007         {
01008                 pXML->AddAttribute( _T("xmlns:xsi"), CXMLAttribute::xmlnsInstance );
01009                 
01010                 HANDLE hFile = CreateFile( strMetaFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
01011                         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
01012                 
01013                 if ( hFile == INVALID_HANDLE_VALUE )
01014                 {
01015                         CreateDirectory( strMetaFolder, NULL );
01016                         SetFileAttributes( strMetaFolder, FILE_ATTRIBUTE_HIDDEN );
01017                         
01018                         hFile = CreateFile( strMetaFile, GENERIC_WRITE, FILE_SHARE_READ, NULL,
01019                                 CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL );
01020                         
01021                         if ( hFile == INVALID_HANDLE_VALUE ) return FALSE;
01022                 }
01023                 
01024                 CString strXML = pXML->ToString( TRUE, TRUE );
01025                 DWORD nWritten;
01026                 delete pXML;
01027                 
01028                 int nASCII = WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), NULL, 0, NULL, NULL );
01029                 LPSTR pszASCII = new CHAR[ nASCII ];
01030                 WideCharToMultiByte( CP_UTF8, 0, strXML, strXML.GetLength(), pszASCII, nASCII, NULL, NULL );
01031                 WriteFile( hFile, pszASCII, nASCII, &nWritten, NULL );
01032                 delete [] pszASCII;
01033                 
01034                 GetFileTime( hFile, NULL, NULL, &m_pMetadataTime );
01035                 CloseHandle( hFile );
01036         }
01037         else
01038         {
01039                 DeleteFile( strMetaFile );
01040                 RemoveDirectory( strMetaFolder );
01041                 ZeroMemory( &m_pMetadataTime, sizeof(FILETIME) );
01042         }
01043         
01044         return TRUE;
01045 }
01046 
01048 // CLibraryFile delete handler
01049 
01050 void CLibraryFile::OnDelete()
01051 {
01052         if ( m_pFolder != NULL )
01053         {
01054                 if ( m_nRating > 0 || m_sComments.GetLength() > 0 )
01055                 {
01056                         Ghost();
01057                         return;
01058                 }
01059         }
01060         
01061         Library.OnFileDelete( this );
01062         
01063         delete this;
01064 }
01065 
01066 void CLibraryFile::Ghost()
01067 {
01068         SYSTEMTIME pTime;
01069         GetSystemTime( &pTime );
01070         SystemTimeToFileTime( &pTime, &m_pTime );
01071         Library.RemoveFile( this );
01072         m_pFolder = NULL;
01073         Library.AddFile( this );
01074         Library.OnFileDelete( this );
01075 }
01076 
01078 // CLibraryFile download verification
01079 
01080 BOOL CLibraryFile::OnVerifyDownload(const SHA1* pSHA1, const MD4* pED2K, LPCTSTR pszSources)
01081 {
01082         if ( m_pFolder == NULL ) return FALSE;
01083         
01084         if ( Settings.Downloads.VerifyFiles && m_bVerify == TS_UNKNOWN && m_nVirtualSize == 0 )
01085         {
01086                 if ( m_bSHA1 && pSHA1 != NULL )
01087                 {
01088                         m_bVerify = ( m_pSHA1 == *pSHA1 ) ? TS_TRUE : TS_FALSE;
01089                 }
01090                 else if ( m_bED2K && pED2K != NULL )
01091                 {
01092                         m_bVerify = ( m_pED2K == *pED2K ) ? TS_TRUE : TS_FALSE;
01093                 }
01094                 
01095                 if ( m_bVerify == TS_TRUE )
01096                 {
01097                         theApp.Message( MSG_SYSTEM, IDS_DOWNLOAD_VERIFY_SUCCESS, (LPCTSTR)m_sName );
01098                         Downloads.OnVerify( GetPath(), TRUE );
01099                 }
01100                 else if ( m_bVerify == TS_FALSE )
01101                 {
01102                         m_bShared = TS_FALSE;
01103                         
01104                         theApp.Message( MSG_ERROR, IDS_DOWNLOAD_VERIFY_FAIL, (LPCTSTR)m_sName );
01105                         Downloads.OnVerify( GetPath(), FALSE );
01106                         
01107                         return FALSE;
01108                 }
01109         }
01110         
01111         if ( m_bSHA1 && m_nVirtualSize == 0 && VersionChecker.m_bUpgrade )
01112         {
01113                 VersionChecker.CheckUpgradeHash( &m_pSHA1, GetPath() );
01114         }
01115         
01116         if ( pszSources != NULL && *pszSources != 0 )
01117         {
01118                 AddAlternateSources( pszSources );
01119         }
01120         return TRUE;
01121 }
01122 
01123 
01125 // CSharedSource construction
01126 
01127 CSharedSource::CSharedSource(LPCTSTR pszURL, FILETIME* pTime)
01128 {
01129         if ( pszURL != NULL )
01130         {
01131                 m_sURL = pszURL;
01132                 Freshen( pTime );
01133         }
01134 }
01135 
01136 void CSharedSource::Serialize(CArchive& ar, int nVersion)
01137 {
01138         if ( ar.IsStoring() )
01139         {
01140                 ar << m_sURL;
01141                 ar.Write( &m_pTime, sizeof(FILETIME) );
01142         }
01143         else
01144         {
01145                 ar >> m_sURL;
01146 
01147                 if ( nVersion >= 10 )
01148                 {
01149                         ar.Read( &m_pTime, sizeof(FILETIME) );
01150                 }
01151                 else
01152                 {
01153                         DWORD nTemp;
01154                         ar >> nTemp;
01155                         Freshen();
01156                 }
01157         }
01158 }
01159 
01160 void CSharedSource::Freshen(FILETIME* pTime)
01161 {
01162         SYSTEMTIME tNow1;
01163         GetSystemTime( &tNow1 );
01164         
01165         if ( pTime != NULL )
01166         {
01167                 FILETIME tNow2;
01168                 
01169                 SystemTimeToFileTime( &tNow1, &tNow2 );
01170                 (LONGLONG&)tNow2 += 10000000;
01171                 
01172                 if ( CompareFileTime( pTime, &tNow2 ) <= 0 )
01173                 {
01174                         m_pTime = *pTime;
01175                 }
01176                 else
01177                 {
01178                         SystemTimeToFileTime( &tNow1, &m_pTime );
01179                 }
01180         }
01181         else
01182         {
01183                 SystemTimeToFileTime( &tNow1, &m_pTime );
01184         }
01185 }
01186 
01187 BOOL CSharedSource::IsExpired(FILETIME& tNow)
01188 {
01189         LONGLONG nElapse = *((LONGLONG*)&tNow) - *((LONGLONG*)&m_pTime);
01190         return nElapse > (LONGLONG)Settings.Library.SourceExpire * 10000000;
01191 }
01192 
01194 // CLibraryFile automation
01195 
01196 IMPLEMENT_DISPATCH(CLibraryFile, LibraryFile)
01197 
01198 STDMETHODIMP CLibraryFile::XLibraryFile::get_Application(IApplication FAR* FAR* ppApplication)
01199 {
01200         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01201         *ppApplication = Application.GetApp();
01202         return S_OK;
01203 }
01204 
01205 STDMETHODIMP CLibraryFile::XLibraryFile::get_Library(ILibrary FAR* FAR* ppLibrary)
01206 {
01207         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01208         *ppLibrary = (ILibrary*)Library.GetInterface( IID_ILibrary, TRUE );
01209         return S_OK;
01210 }
01211 
01212 STDMETHODIMP CLibraryFile::XLibraryFile::get_Folder(ILibraryFolder FAR* FAR* ppFolder)
01213 {
01214         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01215         if ( pThis->m_pFolder == NULL )
01216                 *ppFolder = NULL;
01217         else
01218                 *ppFolder = (ILibraryFolder*)pThis->m_pFolder->GetInterface( IID_ILibraryFolder, TRUE );
01219         return *ppFolder != NULL ? S_OK : S_FALSE;
01220 }
01221 
01222 STDMETHODIMP CLibraryFile::XLibraryFile::get_Path(BSTR FAR* psPath)
01223 {
01224         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01225         pThis->GetPath().SetSysString( psPath );
01226         return S_OK;
01227 }
01228 
01229 STDMETHODIMP CLibraryFile::XLibraryFile::get_Name(BSTR FAR* psPath)
01230 {
01231         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01232         pThis->m_sName.SetSysString( psPath );
01233         return S_OK;
01234 }
01235 
01236 STDMETHODIMP CLibraryFile::XLibraryFile::get_Shared(STRISTATE FAR* pnValue)
01237 {
01238         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01239         *pnValue = (STRISTATE)pThis->m_bShared;
01240         return S_OK;
01241 }
01242 
01243 STDMETHODIMP CLibraryFile::XLibraryFile::put_Shared(STRISTATE nValue)
01244 {
01245         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01246         pThis->m_bShared = nValue;
01247         return S_OK;
01248 }
01249 
01250 STDMETHODIMP CLibraryFile::XLibraryFile::get_EffectiveShared(VARIANT_BOOL FAR* pbValue)
01251 {
01252         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01253         *pbValue = pThis->IsShared() ? VARIANT_TRUE : VARIANT_FALSE;
01254         return S_OK;
01255 }
01256 
01257 STDMETHODIMP CLibraryFile::XLibraryFile::get_Size(LONG FAR* pnSize)
01258 {
01259         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01260         *pnSize = (LONG)pThis->GetSize();
01261         return S_OK;
01262 }
01263 
01264 STDMETHODIMP CLibraryFile::XLibraryFile::get_Index(LONG FAR* pnIndex)
01265 {
01266         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01267         *pnIndex = (LONG)pThis->m_nIndex;
01268         return S_OK;
01269 }
01270 
01271 STDMETHODIMP CLibraryFile::XLibraryFile::get_URN(BSTR sURN, BSTR FAR* psURN)
01272 {
01273         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01274         CString strURN( sURN );
01275         
01276         if ( strURN.IsEmpty() )
01277         {
01278                 if ( pThis->m_bTiger && pThis->m_bSHA1 )
01279                         strURN = _T("urn:bitprint");
01280                 else if ( pThis->m_bTiger )
01281                         strURN = _T("urn:tree:tiger/");
01282                 else if ( pThis->m_bSHA1 )
01283                         strURN = _T("urn:sha1");
01284                 else
01285                         return E_FAIL;
01286         }
01287         
01288         if ( strURN.CompareNoCase( _T("urn:bitprint") ) == 0 )
01289         {
01290                 if ( ! pThis->m_bSHA1 || ! pThis->m_bTiger ) return E_FAIL;
01291                 strURN  = _T("urn:bitprint:")
01292                                 + CSHA::HashToString( &pThis->m_pSHA1 ) + '.'
01293                                 + CTigerNode::HashToString( &pThis->m_pTiger );
01294         }
01295         else if ( strURN.CompareNoCase( _T("urn:sha1") ) == 0 )
01296         {
01297                 if ( ! pThis->m_bSHA1 ) return E_FAIL;
01298                 strURN = CSHA::HashToString( &pThis->m_pSHA1, TRUE );
01299         }
01300         else if ( strURN.CompareNoCase( _T("urn:tree:tiger/") ) == 0 )
01301         {
01302                 if ( ! pThis->m_bTiger ) return E_FAIL;
01303                 strURN = CTigerNode::HashToString( &pThis->m_pTiger, TRUE );
01304         }
01305         else if ( strURN.CompareNoCase( _T("urn:md5") ) == 0 )
01306         {
01307                 if ( ! pThis->m_bMD5 ) return E_FAIL;
01308                 strURN = CMD5::HashToString( &pThis->m_pMD5, TRUE );
01309         }
01310         else if ( strURN.CompareNoCase( _T("urn:ed2k") ) == 0 )
01311         {
01312                 if ( ! pThis->m_bED2K ) return E_FAIL;
01313                 strURN = CED2K::HashToString( &pThis->m_pED2K, TRUE );
01314         }
01315         else
01316         {
01317                 return E_FAIL;
01318         }
01319         
01320         strURN.SetSysString( psURN );
01321         
01322         return S_OK;
01323 }
01324 
01325 STDMETHODIMP CLibraryFile::XLibraryFile::get_MetadataAuto(VARIANT_BOOL FAR* pbValue)
01326 {
01327         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01328         *pbValue = pThis->m_bMetadataAuto ? VARIANT_TRUE : VARIANT_FALSE;
01329         return S_OK;
01330 }
01331 
01332 STDMETHODIMP CLibraryFile::XLibraryFile::get_Metadata(ISXMLElement FAR* FAR* ppXML)
01333 {
01334         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01335         *ppXML = NULL;
01336 
01337         if ( pThis->m_pSchema == NULL || pThis->m_pMetadata == NULL ) return S_OK;
01338         
01339         CXMLElement* pXML       = pThis->m_pSchema->Instantiate( TRUE );
01340         *ppXML                          = (ISXMLElement*)CXMLCOM::Wrap( pXML, IID_ISXMLElement );
01341         
01342         pXML->AddElement( pThis->m_pMetadata->Clone() );
01343         
01344         return S_OK;
01345 }
01346 
01347 STDMETHODIMP CLibraryFile::XLibraryFile::put_Metadata(ISXMLElement FAR* pXML)
01348 {
01349         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01350         
01351         if ( CXMLElement* pReal = CXMLCOM::Unwrap( pXML ) )
01352         {
01353                 return pThis->SetMetadata( pReal ) ? S_OK : E_FAIL;
01354         }
01355         else
01356         {
01357                 pThis->SetMetadata( NULL );
01358                 return S_OK;
01359         }
01360 }
01361 
01362 STDMETHODIMP CLibraryFile::XLibraryFile::Execute()
01363 {
01364         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01365         return CFileExecutor::Execute( pThis->GetPath(), TRUE ) ? S_OK : E_FAIL;
01366 }
01367 
01368 STDMETHODIMP CLibraryFile::XLibraryFile::SmartExecute()
01369 {
01370         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01371         return CFileExecutor::Execute( pThis->GetPath(), FALSE ) ? S_OK : E_FAIL;
01372 }
01373 
01374 STDMETHODIMP CLibraryFile::XLibraryFile::Delete()
01375 {
01376         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01377         return pThis->Delete() ? S_OK : E_FAIL;
01378 }
01379 
01380 STDMETHODIMP CLibraryFile::XLibraryFile::Rename(BSTR sNewName)
01381 {
01382         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01383         return pThis->Rename( CString( sNewName ) ) ? S_OK : E_FAIL;
01384 }
01385 
01386 STDMETHODIMP CLibraryFile::XLibraryFile::Copy(BSTR sNewPath)
01387 {
01388         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01389         return E_NOTIMPL;
01390 }
01391 
01392 STDMETHODIMP CLibraryFile::XLibraryFile::Move(BSTR sNewPath)
01393 {
01394         METHOD_PROLOGUE( CLibraryFile, LibraryFile )
01395         return E_NOTIMPL;
01396 }
01397 

Generated on Thu Dec 15 10:39:49 2005 for Shareaza 2.2.1.0 by  doxygen 1.4.2