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

LibraryMaps.cpp

Go to the documentation of this file.
00001 //
00002 // LibraryMaps.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 "Library.h"
00025 #include "LibraryMaps.h"
00026 #include "SharedFile.h"
00027 
00028 #include "Application.h"
00029 #include "QuerySearch.h"
00030 
00031 #include "SHA.h"
00032 #include "MD5.h"
00033 #include "ED2K.h"
00034 #include "TigerTree.h"
00035 
00036 IMPLEMENT_DYNAMIC(CLibraryMaps, CComObject)
00037 
00038 BEGIN_INTERFACE_MAP(CLibraryMaps, CComObject)
00039         INTERFACE_PART(CLibraryMaps, IID_ILibraryFiles, LibraryFiles)
00040 END_INTERFACE_MAP()
00041 
00042 #define HASH_SIZE       512
00043 #define HASH_MASK       0x1FF
00044 
00045 CLibraryMaps LibraryMaps;
00046 
00047 
00049 // CLibraryMaps construction
00050 
00051 CLibraryMaps::CLibraryMaps()
00052 {
00053         EnableDispatch( IID_ILibraryFiles );
00054         
00055         m_pSHA1Map              = new CLibraryFile*[HASH_SIZE];
00056         m_pTigerMap             = new CLibraryFile*[HASH_SIZE];
00057         m_pED2KMap              = new CLibraryFile*[HASH_SIZE];
00058         
00059         ZeroMemory( m_pSHA1Map, HASH_SIZE * 4 );
00060         ZeroMemory( m_pTigerMap, HASH_SIZE * 4 );
00061         ZeroMemory( m_pED2KMap, HASH_SIZE * 4 );
00062         
00063         m_nNextIndex    = 4;
00064         m_nFiles                = 0;
00065         m_nVolume               = 0;
00066 }
00067 
00068 CLibraryMaps::~CLibraryMaps()
00069 {
00070         delete [] m_pED2KMap;
00071         delete [] m_pTigerMap;
00072         delete [] m_pSHA1Map;
00073 }
00074 
00076 // CLibraryMaps file list
00077 
00078 POSITION CLibraryMaps::GetFileIterator() const
00079 {
00080         return m_pIndexMap.GetStartPosition();
00081 }
00082 
00083 CLibraryFile* CLibraryMaps::GetNextFile(POSITION& pos) const
00084 {
00085         LPVOID pIndex;
00086         CLibraryFile* pFile = NULL;
00087         m_pIndexMap.GetNextAssoc( pos, pIndex, (void*&)pFile );
00088         return pFile;
00089 }
00090 
00091 int CLibraryMaps::GetFileCount() const
00092 {
00093         return m_pIndexMap.GetCount();
00094 }
00095 
00096 void CLibraryMaps::GetStatistics(DWORD* pnFiles, QWORD* pnVolume)
00097 {
00098         if ( pnFiles ) *pnFiles = m_nFiles;
00099         if ( pnVolume ) *pnVolume = m_nVolume;
00100 }
00101 
00103 // CLibraryMaps lookup file by index
00104 
00105 CLibraryFile* CLibraryMaps::LookupFile(DWORD nIndex, BOOL bSharedOnly, BOOL bAvailableOnly)
00106 {
00107         if ( ! nIndex ) return NULL;
00108         
00109         CLibraryFile* pFile = NULL;
00110         
00111         CQuickLock oLock( Library.m_pSection );
00112         
00113         if ( m_pIndexMap.Lookup( (LPVOID)nIndex, (void*&)pFile ) && ( ! bSharedOnly || pFile->IsShared() ) && ( ! bAvailableOnly || pFile->IsAvailable() ) )
00114         {
00115                 return pFile;
00116         }
00117         
00118         return NULL;
00119 }
00120 
00122 // CLibraryMaps lookup file by name and/or path
00123 
00124 CLibraryFile* CLibraryMaps::LookupFileByName(LPCTSTR pszName, BOOL bSharedOnly, BOOL bAvailableOnly)
00125 {
00126         CLibraryFile* pFile = NULL;
00127         CString strName( pszName );
00128         
00129         CQuickLock oLock( Library.m_pSection );
00130         CharLower( strName.GetBuffer() );
00131         strName.ReleaseBuffer();
00132         
00133         if ( m_pNameMap.Lookup( strName, (CObject*&)pFile ) && ( ! bSharedOnly || pFile->IsShared() ) && ( ! bAvailableOnly || pFile->IsAvailable() ) )
00134         {
00135                 return pFile;
00136         }
00137         
00138         return NULL;
00139 }
00140 
00141 CLibraryFile* CLibraryMaps::LookupFileByPath(LPCTSTR pszPath, BOOL bSharedOnly, BOOL bAvailableOnly)
00142 {
00143         CLibraryFile* pFile = NULL;
00144         
00145         CQuickLock oLock( Library.m_pSection );
00146         
00147         if ( m_pPathMap.Lookup( pszPath, (CObject*&)pFile ) && ( ! bSharedOnly || pFile->IsShared() ) && ( ! bAvailableOnly || pFile->IsAvailable() ) )
00148         {
00149                 return pFile;
00150         }
00151         
00152         return NULL;
00153 }
00154 
00156 // CLibraryMaps lookup file by URN
00157 
00158 CLibraryFile* CLibraryMaps::LookupFileByURN(LPCTSTR pszURN, BOOL bSharedOnly, BOOL bAvailableOnly)
00159 {
00160         CLibraryFile* pFile;
00161         TIGEROOT pTiger;
00162         SHA1 pSHA1;
00163         MD4 pED2K;
00164         
00165         if ( CSHA::HashFromURN( pszURN, &pSHA1 ) )
00166         {
00167                 if ( pFile = LookupFileBySHA1( &pSHA1, bSharedOnly ) ) return pFile;
00168         }
00169         
00170         if ( CTigerNode::HashFromURN( pszURN, &pTiger ) )
00171         {
00172                 if ( pFile = LookupFileByTiger( &pTiger, bSharedOnly ) ) return pFile;
00173         }
00174         
00175         if ( CED2K::HashFromURN( pszURN, &pED2K ) )
00176         {
00177                 if ( pFile = LookupFileByED2K( &pED2K, bSharedOnly ) ) return pFile;
00178         }
00179         
00180         return NULL;
00181 }
00182 
00184 // CLibraryMaps lookup file by individual hash types
00185 
00186 CLibraryFile* CLibraryMaps::LookupFileBySHA1(const SHA1* pSHA1,BOOL bSharedOnly, BOOL bAvailableOnly)
00187 {
00188         CQuickLock oLock( Library.m_pSection );
00189         
00190         CLibraryFile* pFile = m_pSHA1Map[ *(WORD*)pSHA1 & HASH_MASK ];
00191         
00192         for ( ; pFile ; pFile = pFile->m_pNextSHA1 )
00193         {
00194                 if ( *pSHA1 == pFile->m_pSHA1 )
00195                 {
00196                         if ( ( ! bSharedOnly || pFile->IsShared() ) && ( ! bAvailableOnly || pFile->IsAvailable() ) )
00197                         {
00198                                 return pFile;
00199                         }
00200                         else
00201                         {
00202                                 return NULL;
00203                         }
00204                 }
00205         }
00206         
00207         return NULL;
00208 }
00209 
00210 CLibraryFile* CLibraryMaps::LookupFileByTiger(const TIGEROOT* pTiger, BOOL bSharedOnly, BOOL bAvailableOnly)
00211 {
00212         CQuickLock oLock( Library.m_pSection );
00213         
00214         CLibraryFile* pFile = m_pTigerMap[ *(WORD*)pTiger & HASH_MASK ];
00215         
00216         for ( ; pFile ; pFile = pFile->m_pNextTiger )
00217         {
00218                 if ( *pTiger == pFile->m_pTiger )
00219                 {
00220                         if ( ( ! bSharedOnly || pFile->IsShared() ) && ( ! bAvailableOnly || pFile->IsAvailable() ) )
00221                         {
00222                                 return pFile;
00223                         }
00224                         else
00225                         {
00226                                 return NULL;
00227                         }
00228                 }
00229         }
00230         
00231         return NULL;
00232 }
00233 
00234 CLibraryFile* CLibraryMaps::LookupFileByED2K(const MD4* pED2K, BOOL bSharedOnly, BOOL bAvailableOnly)
00235 {
00236         CQuickLock oLock( Library.m_pSection );
00237         
00238         CLibraryFile* pFile = m_pED2KMap[ *(WORD*)pED2K & HASH_MASK ];
00239         
00240         for ( ; pFile ; pFile = pFile->m_pNextED2K )
00241         {
00242                 if ( *pED2K == pFile->m_pED2K )
00243                 {
00244                         if ( ( ! bSharedOnly || pFile->IsShared() ) && ( ! bAvailableOnly || pFile->IsAvailable() ) )
00245                         {
00246                                 return pFile;
00247                         }
00248                         else
00249                         {
00250                                 return NULL;
00251                         }
00252                 }
00253         }
00254         
00255         return NULL;
00256 }
00257 
00259 // CLibraryMaps clear
00260 
00261 void CLibraryMaps::Clear()
00262 {
00263         for ( POSITION pos = GetFileIterator() ; pos ; ) delete GetNextFile( pos );
00264         
00265         ASSERT( m_pIndexMap.GetCount() == 0 );
00266         ASSERT( m_pNameMap.GetCount() == 0 );
00267         ASSERT( m_pPathMap.GetCount() == 0 );
00268         
00269         ZeroMemory( m_pSHA1Map, HASH_SIZE * 4 );
00270         ZeroMemory( m_pTigerMap, HASH_SIZE * 4 );
00271         ZeroMemory( m_pED2KMap, HASH_SIZE * 4 );
00272         
00273         m_nFiles  = 0;
00274         m_nVolume = 0;
00275 }
00276 
00278 // CLibraryMaps index manager
00279 
00280 DWORD CLibraryMaps::AllocateIndex()
00281 {
00282         while ( ( m_nNextIndex & 3 ) == 0 || LookupFile( m_nNextIndex ) ) m_nNextIndex++;
00283         return m_nNextIndex;
00284 }
00285 
00287 // CLibraryMaps add a file to the maps
00288 
00289 void CLibraryMaps::OnFileAdd(CLibraryFile* pFile)
00290 {
00291         BOOL bSkipStats = FALSE;
00292         if ( pFile->m_nIndex )
00293         {
00294                 if ( CLibraryFile* pOld = LookupFile( pFile->m_nIndex ) )
00295                 {
00296                         if ( pOld != pFile )
00297                         {
00298                                 pFile->m_nIndex = AllocateIndex();
00299                                 m_pIndexMap.SetAt( (LPVOID)pFile->m_nIndex, pFile );
00300                         }
00301                         else
00302                         {
00303                                 bSkipStats = TRUE;
00304                         }
00305                 }
00306                 else
00307                 {
00308                         m_pIndexMap.SetAt( (LPVOID)pFile->m_nIndex, pFile );
00309                 }
00310         }
00311         else
00312         {
00313                 pFile->m_nIndex = AllocateIndex();
00314                 m_pIndexMap.SetAt( (LPVOID)pFile->m_nIndex, pFile );
00315         }
00316 
00317         if ( ( pFile->m_pFolder != NULL ) && ( ! bSkipStats ) )
00318         {
00319                 m_nVolume += ( pFile->m_nSize >> 10 );
00320                 m_nFiles ++;
00321         }
00322         
00323         m_pNameMap.SetAt( pFile->GetNameLC(), pFile );
00324         
00325         if ( pFile->m_pFolder != NULL )
00326         {
00327                 m_pPathMap.SetAt( pFile->GetPath(), pFile );
00328         }
00329         else if ( m_pDeleted.Find( pFile ) == NULL )
00330         {
00331                 m_pDeleted.AddTail( pFile );
00332         }
00333         
00334         if ( pFile->m_bSHA1 )
00335         {
00336                 CLibraryFile** pHash = &m_pSHA1Map[ *(WORD*)&pFile->m_pSHA1 & HASH_MASK ];
00337                 pFile->m_pNextSHA1 = *pHash;
00338                 *pHash = pFile;
00339         }
00340         
00341         if ( pFile->m_bTiger )
00342         {
00343                 CLibraryFile** pHash = &m_pTigerMap[ *(WORD*)&pFile->m_pTiger & HASH_MASK ];
00344                 pFile->m_pNextTiger = *pHash;
00345                 *pHash = pFile;
00346         }
00347         
00348         if ( pFile->m_bED2K )
00349         {
00350                 CLibraryFile** pHash = &m_pED2KMap[ *(WORD*)&pFile->m_pED2K & HASH_MASK ];
00351                 pFile->m_pNextED2K = *pHash;
00352                 *pHash = pFile;
00353         }
00354 }
00355 
00357 // CLibraryMaps remove a file from the maps
00358 
00359 void CLibraryMaps::OnFileRemove(CLibraryFile* pFile)
00360 {
00361         CLibraryFile* pOld;
00362         
00363         if ( pFile->m_nIndex )
00364         {
00365                 pOld = LookupFile( pFile->m_nIndex );
00366                 
00367                 if ( pOld == pFile )
00368                 {
00369                         m_pIndexMap.RemoveKey( (LPVOID)pFile->m_nIndex );
00370                         
00371                         if ( pOld->m_pFolder != NULL )
00372                         {
00373                                 m_nFiles --;
00374                                 m_nVolume -= ( pFile->m_nSize >> 10 );
00375                         }
00376                 }
00377         }
00378         
00379         pOld = LookupFileByName( pFile->GetNameLC() );
00380         if ( pOld == pFile ) m_pNameMap.RemoveKey( pFile->GetNameLC() );
00381         
00382         if ( pFile->m_pFolder != NULL )
00383         {
00384                 pOld = LookupFileByPath( pFile->GetPath() );
00385                 if ( pOld == pFile ) m_pPathMap.RemoveKey( pFile->GetPath() );
00386         }
00387         
00388         if ( POSITION pos = m_pDeleted.Find( pFile ) )
00389                 m_pDeleted.RemoveAt( pos );
00390         
00391         if ( pFile->m_bSHA1 )
00392         {
00393                 CLibraryFile** pPrev = &m_pSHA1Map[ *(WORD*)&pFile->m_pSHA1 & HASH_MASK ];
00394                 
00395                 for ( CLibraryFile* pOther = *pPrev ; pOther ; pOther = pOther->m_pNextSHA1 )
00396                 {
00397                         if ( pOther == pFile )
00398                         {
00399                                 *pPrev = pOther->m_pNextSHA1;
00400                                 break;
00401                         }
00402                         pPrev = &pOther->m_pNextSHA1;
00403                 }
00404                 
00405                 pFile->m_pNextSHA1 = NULL;
00406         }
00407         
00408         if ( pFile->m_bTiger )
00409         {
00410                 CLibraryFile** pPrev = &m_pTigerMap[ *(WORD*)&pFile->m_pTiger & HASH_MASK ];
00411                 
00412                 for ( CLibraryFile* pOther = *pPrev ; pOther ; pOther = pOther->m_pNextTiger )
00413                 {
00414                         if ( pOther == pFile )
00415                         {
00416                                 *pPrev = pOther->m_pNextTiger;
00417                                 break;
00418                         }
00419                         pPrev = &pOther->m_pNextTiger;
00420                 }
00421                 
00422                 pFile->m_pNextTiger = NULL;
00423         }
00424         
00425         if ( pFile->m_bED2K )
00426         {
00427                 CLibraryFile** pPrev = &m_pED2KMap[ *(WORD*)&pFile->m_pED2K & HASH_MASK ];
00428                 
00429                 for ( CLibraryFile* pOther = *pPrev ; pOther ; pOther = pOther->m_pNextED2K )
00430                 {
00431                         if ( pOther == pFile )
00432                         {
00433                                 *pPrev = pOther->m_pNextED2K;
00434                                 break;
00435                         }
00436                         pPrev = &pOther->m_pNextED2K;
00437                 }
00438                 
00439                 pFile->m_pNextED2K = NULL;
00440         }
00441 }
00442 
00444 // CLibraryMaps cull deleted files
00445 
00446 void CLibraryMaps::CullDeletedFiles(CLibraryFile* pMatch)
00447 {
00448         CSingleLock oLock( &Library.m_pSection );
00449         if ( !oLock.Lock( 100 ) ) return;
00450         CLibraryFile* pFile;
00451         
00452         if ( pMatch->m_bSHA1 )
00453         {
00454                 if ( pFile = LookupFileBySHA1( &pMatch->m_pSHA1 ) )
00455                 {
00456                         if ( ! pFile->IsAvailable() ) pFile->Delete();
00457                 }
00458         }
00459         
00460         if ( pMatch->m_bTiger )
00461         {
00462                 if ( pFile = LookupFileByTiger( &pMatch->m_pTiger ) )
00463                 {
00464                         if ( ! pFile->IsAvailable() ) pFile->Delete();
00465                 }
00466         }
00467         
00468         if ( pMatch->m_bED2K )
00469         {
00470                 if ( pFile = LookupFileByED2K( &pMatch->m_pED2K ) )
00471                 {
00472                         if ( ! pFile->IsAvailable() ) pFile->Delete();
00473                 }
00474         }
00475         
00476 }
00477 
00479 // CLibraryMaps search
00480 
00481 CPtrList* CLibraryMaps::Search(CQuerySearch* pSearch, int nMaximum, BOOL bLocal)
00482 {
00483         CPtrList* pHits = NULL;
00484         
00485         if ( pSearch == NULL )
00486         {
00487                 for ( POSITION pos = GetFileIterator() ; pos ; )
00488                 {
00489                         CLibraryFile* pFile = GetNextFile( pos );
00490                         
00491                         if ( pFile->IsAvailable() )
00492                         {
00493                                 if ( bLocal || ( pFile->IsShared() && pFile->m_bSHA1 ) )
00494                                 {
00495                                         if ( ! pHits ) pHits = new CPtrList( 64 );
00496                                         pHits->AddTail( pFile );
00497                                 }
00498                         }
00499                 }
00500         }
00501         else if ( pSearch->m_bSHA1 )
00502         {
00503                 if ( CLibraryFile* pFile = LookupFileBySHA1( &pSearch->m_pSHA1 ) )
00504                 {
00505                         if ( bLocal || pFile->IsShared() )
00506                         {
00507                                 pHits = new CPtrList();
00508                                 pHits->AddTail( pFile );
00509                                 
00510                                 if ( ! bLocal )
00511                                 {
00512                                         pFile->m_nHitsToday++;
00513                                         pFile->m_nHitsTotal++;
00514                                 }
00515                         }
00516                 }
00517         }
00518         else if ( pSearch->m_bTiger )
00519         {
00520                 if ( CLibraryFile* pFile = LookupFileByTiger( &pSearch->m_pTiger ) )
00521                 {
00522                         if ( bLocal || pFile->IsShared() )
00523                         {
00524                                 pHits = new CPtrList();
00525                                 pHits->AddTail( pFile );
00526                                 
00527                                 if ( ! bLocal )
00528                                 {
00529                                         pFile->m_nHitsToday++;
00530                                         pFile->m_nHitsTotal++;
00531                                 }
00532                         }
00533                 }
00534         }
00535         else if ( pSearch->m_bED2K )
00536         {
00537                 for ( POSITION pos = GetFileIterator() ; pos ; )
00538                 {
00539                         CLibraryFile* pFile = GetNextFile( pos );
00540                         
00541                         if ( pFile->m_bED2K && pFile->m_pED2K == pSearch->m_pED2K )
00542                         {
00543                                 if ( bLocal || ( pFile->IsShared() && pFile->m_bSHA1 ) )
00544                                 {
00545                                         if ( ! pHits ) pHits = new CPtrList( 64 );
00546                                         pHits->AddTail( pFile );
00547                                 }
00548                         }
00549                 }
00550         }
00551         
00552         return pHits;
00553 }
00554 
00556 // CLibraryMaps serialize
00557 
00558 void CLibraryMaps::Serialize1(CArchive& ar, int nVersion)
00559 {
00560         if ( ar.IsStoring() )
00561         {
00562                 ar << m_nNextIndex;
00563         }
00564         else
00565         {
00566                 ar >> m_nNextIndex;
00567         }
00568 }
00569 
00570 void CLibraryMaps::Serialize2(CArchive& ar, int nVersion)
00571 {
00572         if ( nVersion < 18 ) return;
00573         
00574         if ( ar.IsStoring() )
00575         {
00576                 ar.WriteCount( m_pDeleted.GetCount() );
00577                 
00578                 for ( POSITION pos = m_pDeleted.GetHeadPosition() ; pos ; )
00579                 {
00580                         CLibraryFile* pFile = (CLibraryFile*)m_pDeleted.GetNext( pos );
00581                         pFile->Serialize( ar, nVersion );
00582                 }
00583         }
00584         else
00585         {
00586                 for ( int nCount = ar.ReadCount() ; nCount > 0 ; nCount-- )
00587                 {
00588                         CLibraryFile* pFile = new CLibraryFile( NULL );
00589                         pFile->Serialize( ar, nVersion );
00590                 }
00591         }
00592 }
00593 
00595 // CLibrary ILibraryFiles
00596 
00597 IMPLEMENT_DISPATCH(CLibraryMaps, LibraryFiles)
00598 
00599 STDMETHODIMP CLibraryMaps::XLibraryFiles::get_Application(IApplication FAR* FAR* ppApplication)
00600 {
00601         METHOD_PROLOGUE( CLibraryMaps, LibraryFiles )
00602         *ppApplication = Application.GetApp();
00603         return S_OK;
00604 }
00605 
00606 STDMETHODIMP CLibraryMaps::XLibraryFiles::get_Library(ILibrary FAR* FAR* ppLibrary)
00607 {
00608         METHOD_PROLOGUE( CLibraryMaps, LibraryFiles )
00609         *ppLibrary = (ILibrary*)Library.GetInterface( IID_ILibrary, TRUE );
00610         return S_OK;
00611 }
00612 
00613 STDMETHODIMP CLibraryMaps::XLibraryFiles::get__NewEnum(IUnknown FAR* FAR* ppEnum)
00614 {
00615         METHOD_PROLOGUE( CLibraryMaps, LibraryFiles )
00616         return E_NOTIMPL;
00617 }
00618 
00619 STDMETHODIMP CLibraryMaps::XLibraryFiles::get_Item(VARIANT vIndex, ILibraryFile FAR* FAR* ppFile)
00620 {
00621         METHOD_PROLOGUE( CLibraryMaps, LibraryFiles )
00622 
00623         CLibraryFile* pFile = NULL;
00624         *ppFile = NULL;
00625         
00626         if ( vIndex.vt == VT_BSTR )
00627         {
00628                 CString strName( vIndex.bstrVal );
00629                 if ( strName.Find( '\\' ) >= 0 )
00630                         pFile = pThis->LookupFileByPath( strName );
00631                 else
00632                         pFile = pThis->LookupFileByName( strName );
00633         }
00634         else
00635         {
00636                 VARIANT va;
00637                 VariantInit( &va );
00638 
00639                 if ( FAILED( VariantChangeType( &va, (VARIANT FAR*)&vIndex, 0, VT_I4 ) ) )
00640                         return E_INVALIDARG;
00641                 if ( va.lVal < 0 || va.lVal >= pThis->GetFileCount() )
00642                         return E_INVALIDARG;
00643                 
00644                 for ( POSITION pos = pThis->GetFileIterator() ; pos ; )
00645                 {
00646                         pFile = pThis->GetNextFile( pos );
00647                         if ( va.lVal-- == 0 ) break;
00648                         pFile = NULL;
00649                 }
00650         }
00651         
00652         *ppFile = pFile ? (ILibraryFile*)pFile->GetInterface( IID_ILibraryFile, TRUE ) : NULL;
00653         
00654         return S_OK;
00655 }
00656 
00657 STDMETHODIMP CLibraryMaps::XLibraryFiles::get_Count(LONG FAR* pnCount)
00658 {
00659         METHOD_PROLOGUE( CLibraryMaps, LibraryFiles )
00660         *pnCount = pThis->GetFileCount();
00661         return S_OK;
00662 }

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