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 "SharedFolder.h"
00026 #include "SharedFile.h"
00027 #include "Library.h"
00028 #include "Application.h"
00029
00030 #ifdef _DEBUG
00031 #undef THIS_FILE
00032 static char THIS_FILE[]=__FILE__;
00033 #define new DEBUG_NEW
00034 #endif
00035
00036 IMPLEMENT_DYNAMIC(CLibraryFolder, CComObject)
00037
00038 BEGIN_INTERFACE_MAP(CLibraryFolder, CComObject)
00039 INTERFACE_PART(CLibraryFolder, IID_ILibraryFolder, LibraryFolder)
00040 INTERFACE_PART(CLibraryFolder, IID_ILibraryFolders, LibraryFolders)
00041 INTERFACE_PART(CLibraryFolder, IID_ILibraryFiles, LibraryFiles)
00042 END_INTERFACE_MAP()
00043
00044
00046
00047
00048 CLibraryFolder::CLibraryFolder(CLibraryFolder* pParent, LPCTSTR pszPath)
00049 {
00050 EnableDispatch( IID_ILibraryFolder );
00051 EnableDispatch( IID_ILibraryFolders );
00052 EnableDispatch( IID_ILibraryFiles );
00053
00054 m_pParent = pParent;
00055
00056 m_nFiles = 0;
00057 m_nVolume = 0;
00058 m_bShared = pParent ? TS_UNKNOWN : TS_TRUE;
00059 m_bExpanded = pParent ? FALSE : TRUE;
00060
00061 m_nScanCookie = 0;
00062 m_nUpdateCookie = 0;
00063 m_nSelectCookie = 0;
00064
00065 m_hMonitor = INVALID_HANDLE_VALUE;
00066 m_bMonitor = FALSE;
00067
00068 if ( pszPath )
00069 {
00070 m_sPath = pszPath;
00071 PathToName();
00072 }
00073 }
00074
00075 CLibraryFolder::~CLibraryFolder()
00076 {
00077 if ( m_hMonitor != INVALID_HANDLE_VALUE ) FindCloseChangeNotification( m_hMonitor );
00078
00079 Clear();
00080 }
00081
00083
00084
00085 POSITION CLibraryFolder::GetFolderIterator() const
00086 {
00087 return m_pFolders.GetStartPosition();
00088 }
00089
00090 CLibraryFolder* CLibraryFolder::GetNextFolder(POSITION& pos) const
00091 {
00092 CLibraryFolder* pOutput = NULL;
00093 CString strName;
00094 m_pFolders.GetNextAssoc( pos, strName, (CObject*&)pOutput );
00095 return pOutput;
00096 }
00097
00098 CLibraryFolder* CLibraryFolder::GetFolderByName(LPCTSTR pszName) const
00099 {
00100 CLibraryFolder* pOutput = NULL;
00101 CString strName( pszName );
00102 CharLower( strName.GetBuffer() );
00103 strName.ReleaseBuffer();
00104 return ( m_pFolders.Lookup( strName, (CObject*&)pOutput ) ) ? pOutput : NULL;
00105 }
00106
00107 CLibraryFolder* CLibraryFolder::GetFolderByPath(LPCTSTR pszPath) const
00108 {
00109 if ( m_sPath.CompareNoCase( pszPath ) == 0 ) return (CLibraryFolder*)this;
00110
00111 for ( POSITION pos = GetFolderIterator() ; pos ; )
00112 {
00113 CLibraryFolder* pFolder = GetNextFolder( pos )->GetFolderByPath( pszPath );
00114 if ( pFolder ) return pFolder;
00115 }
00116
00117 return NULL;
00118 }
00119
00120 BOOL CLibraryFolder::CheckFolder(CLibraryFolder* pFolder, BOOL bRecursive) const
00121 {
00122 for ( POSITION pos = GetFolderIterator() ; pos ; )
00123 {
00124 CLibraryFolder* pCheck = GetNextFolder( pos );
00125 if ( pCheck == pFolder ) return TRUE;
00126 if ( bRecursive && pCheck->CheckFolder( pFolder, TRUE ) ) return TRUE;
00127 }
00128
00129 return FALSE;
00130 }
00131
00132 int CLibraryFolder::GetFolderCount() const
00133 {
00134 return m_pFolders.GetCount();
00135 }
00136
00138
00139
00140 POSITION CLibraryFolder::GetFileIterator() const
00141 {
00142 return m_pFiles.GetStartPosition();
00143 }
00144
00145 CLibraryFile* CLibraryFolder::GetNextFile(POSITION& pos) const
00146 {
00147 CLibraryFile* pOutput = NULL;
00148 CString strName;
00149 m_pFiles.GetNextAssoc( pos, strName, (CObject*&)pOutput );
00150 return pOutput;
00151 }
00152
00153 CLibraryFile* CLibraryFolder::GetFile(LPCTSTR pszName) const
00154 {
00155 CLibraryFile* pOutput = NULL;
00156 CString strName( pszName );
00157 CharLower( strName.GetBuffer() );
00158 strName.ReleaseBuffer();
00159 return ( m_pFiles.Lookup( strName, (CObject*&)pOutput ) ) ? pOutput : NULL;
00160 }
00161
00162 int CLibraryFolder::GetFileCount() const
00163 {
00164 return m_pFiles.GetCount();
00165 }
00166
00167 int CLibraryFolder::GetFileList(CLibraryList* pList, BOOL bRecursive) const
00168 {
00169 int nCount = 0;
00170
00171 for ( POSITION pos = GetFileIterator() ; pos ; )
00172 {
00173 pList->CheckAndAdd( GetNextFile( pos )->m_nIndex );
00174 nCount++;
00175 }
00176
00177 if ( bRecursive )
00178 {
00179 for ( POSITION pos = GetFolderIterator() ; pos ; )
00180 {
00181 GetNextFolder( pos )->GetFileList( pList, bRecursive );
00182 }
00183 }
00184
00185 return nCount;
00186 }
00187
00188 int CLibraryFolder::GetSharedCount() const
00189 {
00190 int nCount = 0;
00191
00192 for ( POSITION pos = GetFileIterator() ; pos ; )
00193 {
00194 CLibraryFile* pFile = GetNextFile( pos );
00195 if ( pFile->IsShared() ) nCount++;
00196 }
00197
00198 for ( POSITION pos = GetFolderIterator() ; pos ; )
00199 {
00200 nCount += GetNextFolder( pos )->GetSharedCount();
00201 }
00202
00203 return nCount;
00204 }
00205
00207
00208
00209 void CLibraryFolder::Clear()
00210 {
00211 for ( POSITION pos = GetFolderIterator() ; pos ; )
00212 {
00213 delete GetNextFolder( pos );
00214 }
00215
00216 for ( POSITION pos = GetFileIterator() ; pos ; )
00217 {
00218 delete GetNextFile( pos );
00219 }
00220
00221 m_pFolders.RemoveAll();
00222 m_pFiles.RemoveAll();
00223
00224 m_nFiles = 0;
00225 m_nVolume = 0;
00226 }
00227
00229
00230
00231 void CLibraryFolder::Serialize(CArchive& ar, int nVersion)
00232 {
00233 if ( ar.IsStoring() )
00234 {
00235 ar << m_sPath;
00236 ar << m_bShared;
00237 ar << m_bExpanded;
00238
00239 ar.WriteCount( GetFolderCount() );
00240
00241 for ( POSITION pos = GetFolderIterator() ; pos ; )
00242 {
00243 GetNextFolder( pos )->Serialize( ar, nVersion );
00244 }
00245
00246 ar.WriteCount( GetFileCount() );
00247
00248 for ( POSITION pos = GetFileIterator() ; pos ; )
00249 {
00250 GetNextFile( pos )->Serialize( ar, nVersion );
00251 }
00252 }
00253 else
00254 {
00255 Clear();
00256
00257 ar >> m_sPath;
00258
00259 if ( nVersion >= 5 )
00260 {
00261 ar >> m_bShared;
00262 }
00263 else
00264 {
00265 BYTE bShared;
00266 ar >> bShared;
00267 m_bShared = bShared ? TS_UNKNOWN : TS_FALSE;
00268 }
00269
00270 if ( nVersion >= 3 ) ar >> m_bExpanded;
00271
00272 PathToName();
00273
00274 for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
00275 {
00276 CLibraryFolder* pFolder = new CLibraryFolder( this );
00277 pFolder->Serialize( ar, nVersion );
00278
00279 m_pFolders.SetAt( pFolder->m_sNameLC, pFolder );
00280
00281 m_nFiles += pFolder->m_nFiles;
00282 m_nVolume += pFolder->m_nVolume;
00283 }
00284
00285 for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
00286 {
00287 CLibraryFile* pFile = new CLibraryFile( this );
00288 pFile->Serialize( ar, nVersion );
00289
00290 m_pFiles.SetAt( pFile->GetNameLC(), pFile );
00291
00292 m_nFiles ++;
00293 m_nVolume += pFile->m_nSize / 1024;
00294 }
00295 }
00296 }
00297
00298 void CLibraryFolder::PathToName()
00299 {
00300 m_sName = m_sPath;
00301 int nPos = m_sName.ReverseFind( '\\' );
00302 if ( nPos >= 0 && nPos < m_sName.GetLength() - 1 ) m_sName = m_sName.Mid( nPos + 1 );
00303 m_sNameLC = m_sName;
00304 CharLower( m_sNameLC.GetBuffer() );
00305 m_sNameLC.ReleaseBuffer();
00306 }
00307
00309
00310
00311 BOOL CLibraryFolder::ThreadScan(DWORD nScanCookie)
00312 {
00313 CSingleLock pLock( &Library.m_pSection );
00314 CString strPath, strMetaData;
00315 LPCTSTR pszMetaData = NULL;
00316 WIN32_FIND_DATA pFind;
00317 HANDLE hSearch;
00318
00319 if ( m_pParent == NULL )
00320 theApp.Message( MSG_DEBUG, _T("Library scanning: %s"), (LPCTSTR)m_sPath );
00321
00322 if ( m_sPath.CompareNoCase( Settings.Downloads.IncompletePath ) == 0 ) return FALSE;
00323
00324 strMetaData = m_sPath + _T("\\Metadata");
00325
00326 hSearch = FindFirstFile( strMetaData + _T("\\*.*"), &pFind );
00327
00328 if ( hSearch != INVALID_HANDLE_VALUE )
00329 {
00330 FindClose( hSearch );
00331 strMetaData += '\\';
00332 pszMetaData = strMetaData;
00333 }
00334
00335 hSearch = FindFirstFile( m_sPath + _T("\\*.*"), &pFind );
00336
00337 pLock.Lock();
00338 m_nScanCookie = nScanCookie;
00339 nScanCookie = ++Library.m_nScanCookie;
00340 pLock.Unlock();
00341
00342 BOOL bKazaaFolder = _tcsistr( m_sPath, _T("kazaa") ) != NULL;
00343 BOOL bChanged = FALSE;
00344
00345 if ( hSearch != INVALID_HANDLE_VALUE )
00346 {
00347 do
00348 {
00349 strPath.Format( _T("%s\\%s"), (LPCTSTR)m_sPath, pFind.cFileName );
00350
00351 if ( pFind.cFileName[0] == '.' ) continue;
00352 if ( pFind.dwFileAttributes & (FILE_ATTRIBUTE_HIDDEN|FILE_ATTRIBUTE_SYSTEM) ) continue;
00353 if ( _tcsicmp( pFind.cFileName, _T("Metadata") ) == 0 ) continue;
00354 if ( _tcsicmp( pFind.cFileName, _T("SThumbs.dat") ) == 0 ) continue;
00355
00356 if ( pFind.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY )
00357 {
00358 CLibraryFolder* pFolder = GetFolderByName( pFind.cFileName );
00359
00360 if ( pFolder != NULL )
00361 {
00362 m_nFiles -= pFolder->m_nFiles;
00363 m_nVolume -= pFolder->m_nVolume;
00364
00365 if ( pFolder->m_sName != pFind.cFileName )
00366 {
00367 pFolder->m_sPath = strPath;
00368 pFolder->PathToName();
00369 pFolder->m_nUpdateCookie++;
00370 bChanged = TRUE;
00371 }
00372 }
00373 else
00374 {
00375 pLock.Lock();
00376 pFolder = new CLibraryFolder( this, strPath );
00377 m_pFolders.SetAt( pFolder->m_sNameLC, pFolder );
00378 bChanged = TRUE;
00379 m_nUpdateCookie++;
00380 pLock.Unlock();
00381 }
00382
00383 bChanged |= pFolder->ThreadScan( nScanCookie );
00384
00385 m_nFiles += pFolder->m_nFiles;
00386 m_nVolume += pFolder->m_nVolume;
00387 }
00388 else
00389 {
00390 if ( pFind.dwFileAttributes & (FILE_ATTRIBUTE_ENCRYPTED) ) continue;
00391
00392 CLibraryFile* pFile = GetFile( pFind.cFileName );
00393
00394 if ( pFile != NULL )
00395 {
00396 m_nVolume -= pFile->m_nSize / 1024;
00397
00398 if ( pFile->m_sName != pFind.cFileName )
00399 {
00400 pFile->m_sName = pFind.cFileName;
00401 bChanged = TRUE;
00402 }
00403 }
00404 else if ( bKazaaFolder && _tcsistr( pFind.cFileName, _T(".dat") ) != NULL )
00405 {
00406
00407 continue;
00408 }
00409 else if ( _tcsnicmp( pFind.cFileName, _T("__INCOMPLETE___"), 15 ) == 0 )
00410 {
00411
00412 continue;
00413 }
00414 else
00415 {
00416 pLock.Lock();
00417 pFile = new CLibraryFile( this, pFind.cFileName );
00418 m_pFiles.SetAt( pFile->GetNameLC(), pFile );
00419 m_nFiles++;
00420 bChanged = TRUE;
00421 pLock.Unlock();
00422 }
00423
00424 QWORD nLongSize = (QWORD)pFind.nFileSizeLow | ( (QWORD)pFind.nFileSizeHigh << 32 );
00425
00426 bChanged |= pFile->ThreadScan( pLock, nScanCookie, nLongSize,
00427 &pFind.ftLastWriteTime, pszMetaData );
00428
00429 m_nVolume += pFile->m_nSize / 1024;
00430 }
00431 }
00432 while ( Library.m_bThread && FindNextFile( hSearch, &pFind ) );
00433
00434 FindClose( hSearch );
00435 }
00436
00437 if ( ! Library.m_bThread ) return FALSE;
00438
00439 for ( POSITION pos = GetFolderIterator() ; pos ; )
00440 {
00441 CLibraryFolder* pFolder = GetNextFolder( pos );
00442
00443 if ( pFolder->m_nScanCookie != nScanCookie )
00444 {
00445 CString strNameLC( pFolder->m_sName );
00446 CharLower( strNameLC.GetBuffer() );
00447 strNameLC.ReleaseBuffer();
00448
00449 m_nFiles -= pFolder->m_nFiles;
00450 m_nVolume -= pFolder->m_nVolume;
00451
00452 if ( ! pLock.IsLocked() ) pLock.Lock();
00453
00454 m_pFolders.RemoveKey( strNameLC );
00455 pFolder->OnDelete();
00456
00457 bChanged = TRUE;
00458 m_nUpdateCookie++;
00459 }
00460 }
00461
00462 for ( POSITION pos = GetFileIterator() ; pos ; )
00463 {
00464 CLibraryFile* pFile = GetNextFile( pos );
00465
00466 if ( pFile->m_nScanCookie != nScanCookie )
00467 {
00468 CString strNameLC( pFile->m_sName );
00469 CharLower( strNameLC.GetBuffer() );
00470 strNameLC.ReleaseBuffer();
00471
00472 m_nFiles --;
00473 m_nVolume -= pFile->m_nSize / 1024;
00474
00475 if ( ! pLock.IsLocked() ) pLock.Lock();
00476
00477 pFile->OnDelete();
00478 m_pFiles.RemoveKey( strNameLC );
00479
00480 bChanged = TRUE;
00481 }
00482 }
00483
00484 if ( m_pParent == NULL )
00485 theApp.Message( MSG_DEBUG, _T("Finished scanning (%i)"), bChanged );
00486
00487 return bChanged;
00488 }
00489
00491
00492
00493 BOOL CLibraryFolder::SetMonitor()
00494 {
00495 if ( ! m_bMonitor )
00496 {
00497 m_bMonitor = TRUE;
00498
00499 if ( m_hMonitor != INVALID_HANDLE_VALUE ) FindCloseChangeNotification( m_hMonitor );
00500 m_hMonitor = INVALID_HANDLE_VALUE;
00501
00502 if ( ! Settings.Library.WatchFolders ) return FALSE;
00503
00504 m_hMonitor = FindFirstChangeNotification( m_sPath, TRUE,
00505 FILE_NOTIFY_CHANGE_FILE_NAME|FILE_NOTIFY_CHANGE_DIR_NAME|
00506 FILE_NOTIFY_CHANGE_LAST_WRITE );
00507 }
00508
00509 return ( m_hMonitor != INVALID_HANDLE_VALUE );
00510 }
00511
00512 BOOL CLibraryFolder::CheckMonitor()
00513 {
00514 if ( ! m_bMonitor ) return TRUE;
00515
00516 if ( m_hMonitor == INVALID_HANDLE_VALUE ) return FALSE;
00517
00518 if ( WaitForSingleObject( m_hMonitor, 0 ) != WAIT_OBJECT_0 ) return FALSE;
00519
00520 if ( ! FindNextChangeNotification( m_hMonitor ) )
00521 {
00522 FindCloseChangeNotification( m_hMonitor );
00523 m_hMonitor = INVALID_HANDLE_VALUE;
00524 }
00525
00526 return TRUE;
00527 }
00528
00530
00531
00532 void CLibraryFolder::Scan()
00533 {
00534 CLibraryFolder* pFolder = this;
00535 for ( ; pFolder->m_pParent ; pFolder = pFolder->m_pParent );
00536 if ( pFolder ) pFolder->m_bMonitor = FALSE;
00537 Library.m_pWakeup.SetEvent();
00538 }
00539
00541
00542
00543 BOOL CLibraryFolder::IsShared()
00544 {
00545 for ( CLibraryFolder* pFolder = this ; pFolder ; pFolder = pFolder->m_pParent )
00546 {
00547 if ( pFolder->m_bShared )
00548 {
00549 if ( pFolder->m_bShared == TS_TRUE ) return TRUE;
00550 if ( pFolder->m_bShared == TS_FALSE ) return FALSE;
00551 }
00552 }
00553
00554 return TRUE;
00555 }
00556
00558
00559
00560 void CLibraryFolder::OnDelete()
00561 {
00562 for ( POSITION pos = GetFolderIterator() ; pos ; )
00563 {
00564 GetNextFolder( pos )->OnDelete();
00565 }
00566
00567 for ( POSITION pos = GetFileIterator() ; pos ; )
00568 {
00569 GetNextFile( pos )->OnDelete();
00570 }
00571
00572 m_pFolders.RemoveAll();
00573 m_pFiles.RemoveAll();
00574
00575 delete this;
00576 }
00577
00578 void CLibraryFolder::OnFileRename(CLibraryFile* pFile)
00579 {
00580 for ( POSITION pos = m_pFiles.GetStartPosition() ; pos ; )
00581 {
00582 CLibraryFile* pOld = NULL;
00583 CString strName;
00584
00585 m_pFiles.GetNextAssoc( pos, strName, (CObject*&)pOld );
00586
00587 if ( pFile == pOld )
00588 {
00589 m_pFiles.RemoveKey( strName );
00590 m_pFiles.SetAt( pFile->GetNameLC(), pFile );
00591 break;
00592 }
00593 }
00594 }
00595
00597
00598
00599 IMPLEMENT_DISPATCH(CLibraryFolder, LibraryFolder)
00600
00601 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Application(IApplication FAR* FAR* ppApplication)
00602 {
00603 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00604 *ppApplication = Application.GetApp();
00605 return S_OK;
00606 }
00607
00608 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Library(ILibrary FAR* FAR* ppLibrary)
00609 {
00610 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00611 *ppLibrary = (ILibrary*)Library.GetInterface( IID_ILibrary, TRUE );
00612 return S_OK;
00613 }
00614
00615 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Parent(ILibraryFolder FAR* FAR* ppFolder)
00616 {
00617 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00618 if ( pThis->m_pParent )
00619 *ppFolder = (ILibraryFolder*)pThis->m_pParent->GetInterface( IID_ILibraryFolder, TRUE );
00620 else
00621 *ppFolder = NULL;
00622 return S_OK;
00623 }
00624
00625 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Path(BSTR FAR* psPath)
00626 {
00627 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00628 pThis->m_sPath.SetSysString( psPath );
00629 return S_OK;
00630 }
00631
00632 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Name(BSTR FAR* psPath)
00633 {
00634 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00635 pThis->m_sName.SetSysString( psPath );
00636 return S_OK;
00637 }
00638
00639 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Shared(STRISTATE FAR* pnValue)
00640 {
00641 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00642 *pnValue = (STRISTATE)pThis->m_bShared;
00643 return S_OK;
00644 }
00645
00646 STDMETHODIMP CLibraryFolder::XLibraryFolder::put_Shared(STRISTATE nValue)
00647 {
00648 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00649 pThis->m_bShared = nValue;
00650 return S_OK;
00651 }
00652
00653 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_EffectiveShared(VARIANT_BOOL FAR* pbValue)
00654 {
00655 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00656 *pbValue = pThis->IsShared() ? VARIANT_TRUE : VARIANT_FALSE;
00657 return S_OK;
00658 }
00659
00660 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Folders(ILibraryFolders FAR* FAR* ppFolders)
00661 {
00662 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00663 *ppFolders = (ILibraryFolders*)pThis->GetInterface( IID_ILibraryFolders, TRUE );
00664 return S_OK;
00665 }
00666
00667 STDMETHODIMP CLibraryFolder::XLibraryFolder::get_Files(ILibraryFiles FAR* FAR* ppFiles)
00668 {
00669 METHOD_PROLOGUE( CLibraryFolder, LibraryFolder )
00670 *ppFiles = (ILibraryFiles*)pThis->GetInterface( IID_ILibraryFiles, TRUE );
00671 return S_OK;
00672 }
00673
00675
00676
00677 IMPLEMENT_DISPATCH(CLibraryFolder, LibraryFolders)
00678
00679 STDMETHODIMP CLibraryFolder::XLibraryFolders::get_Application(IApplication FAR* FAR* ppApplication)
00680 {
00681 METHOD_PROLOGUE( CLibraryFolder, LibraryFolders )
00682 *ppApplication = Application.GetApp();
00683 return S_OK;
00684 }
00685
00686 STDMETHODIMP CLibraryFolder::XLibraryFolders::get_Library(ILibrary FAR* FAR* ppLibrary)
00687 {
00688 METHOD_PROLOGUE( CLibraryFolder, LibraryFolders )
00689 *ppLibrary = (ILibrary*)Library.GetInterface( IID_ILibrary, TRUE );
00690 return S_OK;
00691 }
00692
00693 STDMETHODIMP CLibraryFolder::XLibraryFolders::get__NewEnum(IUnknown FAR* FAR* ppEnum)
00694 {
00695 METHOD_PROLOGUE( CLibraryFolder, LibraryFolders )
00696 return E_NOTIMPL;
00697 }
00698
00699 STDMETHODIMP CLibraryFolder::XLibraryFolders::get_Item(VARIANT vIndex, ILibraryFolder FAR* FAR* ppFolder)
00700 {
00701 METHOD_PROLOGUE( CLibraryFolder, LibraryFolders )
00702
00703 CLibraryFolder* pFolder = NULL;
00704 *ppFolder = NULL;
00705
00706 if ( vIndex.vt == VT_BSTR )
00707 {
00708 CString strName( vIndex.bstrVal );
00709 if ( strName.Find( '\\' ) >= 0 )
00710 pFolder = pThis->GetFolderByPath( strName );
00711 else
00712 pFolder = pThis->GetFolderByName( strName );
00713 }
00714 else
00715 {
00716 VARIANT va;
00717 VariantInit( &va );
00718
00719 if ( FAILED( VariantChangeType( &va, (VARIANT FAR*)&vIndex, 0, VT_I4 ) ) )
00720 return E_INVALIDARG;
00721 if ( va.lVal < 0 || va.lVal >= pThis->GetFolderCount() )
00722 return E_INVALIDARG;
00723
00724 for ( POSITION pos = pThis->GetFolderIterator() ; pos ; )
00725 {
00726 pFolder = pThis->GetNextFolder( pos );
00727 if ( va.lVal-- == 0 ) break;
00728 pFolder = NULL;
00729 }
00730 }
00731
00732 *ppFolder = pFolder ? (ILibraryFolder*)pFolder->GetInterface( IID_ILibraryFolder, TRUE ) : NULL;
00733
00734 return S_OK;
00735 }
00736
00737 STDMETHODIMP CLibraryFolder::XLibraryFolders::get_Count(LONG FAR* pnCount)
00738 {
00739 METHOD_PROLOGUE( CLibraryFolder, LibraryFolders )
00740 *pnCount = pThis->GetFolderCount();
00741 return S_OK;
00742 }
00743
00745
00746
00747 IMPLEMENT_DISPATCH(CLibraryFolder, LibraryFiles)
00748
00749 STDMETHODIMP CLibraryFolder::XLibraryFiles::get_Application(IApplication FAR* FAR* ppApplication)
00750 {
00751 METHOD_PROLOGUE( CLibraryFolder, LibraryFiles )
00752 *ppApplication = Application.GetApp();
00753 return S_OK;
00754 }
00755
00756 STDMETHODIMP CLibraryFolder::XLibraryFiles::get_Library(ILibrary FAR* FAR* ppLibrary)
00757 {
00758 METHOD_PROLOGUE( CLibraryFolder, LibraryFiles )
00759 *ppLibrary = (ILibrary*)Library.GetInterface( IID_ILibrary, TRUE );
00760 return S_OK;
00761 }
00762
00763 STDMETHODIMP CLibraryFolder::XLibraryFiles::get__NewEnum(IUnknown FAR* FAR* ppEnum)
00764 {
00765 METHOD_PROLOGUE( CLibraryFolder, LibraryFiles )
00766 return E_NOTIMPL;
00767 }
00768
00769 STDMETHODIMP CLibraryFolder::XLibraryFiles::get_Item(VARIANT vIndex, ILibraryFile FAR* FAR* ppFile)
00770 {
00771 METHOD_PROLOGUE( CLibraryFolder, LibraryFiles )
00772
00773 CLibraryFile* pFile = NULL;
00774 *ppFile = NULL;
00775
00776 if ( vIndex.vt == VT_BSTR )
00777 {
00778 CString strName( vIndex.bstrVal );
00779 pFile = pThis->GetFile( strName );
00780 }
00781 else
00782 {
00783 VARIANT va;
00784 VariantInit( &va );
00785
00786 if ( FAILED( VariantChangeType( &va, (VARIANT FAR*)&vIndex, 0, VT_I4 ) ) )
00787 return E_INVALIDARG;
00788 if ( va.lVal < 0 || va.lVal >= pThis->GetFileCount() )
00789 return E_INVALIDARG;
00790
00791 for ( POSITION pos = pThis->GetFileIterator() ; pos ; )
00792 {
00793 pFile = pThis->GetNextFile( pos );
00794 if ( va.lVal-- == 0 ) break;
00795 pFile = NULL;
00796 }
00797 }
00798
00799 *ppFile = pFile ? (ILibraryFile*)pFile->GetInterface( IID_ILibraryFile, TRUE ) : NULL;
00800
00801 return S_OK;
00802 }
00803
00804 STDMETHODIMP CLibraryFolder::XLibraryFiles::get_Count(LONG FAR* pnCount)
00805 {
00806 METHOD_PROLOGUE( CLibraryFolder, LibraryFiles )
00807 *pnCount = pThis->GetFileCount();
00808 return S_OK;
00809 }
00810