00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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