//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1992 - 2002. // // File: cimanger.cxx // // Contents: The Content Index manager object implementing the // ICiManager interface. // // History: 12-03-96 srikants Created // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include #include #include #include "cimanger.hxx" #include "dmnslave.hxx" CCiManager::CCiManager( ICiCDocStore * pICiCDocStore ) :_sigCiManger(sigCiManger), _refCount(1), _state(STARTING), _reason(INVALID_REASON), _pcci(0), _startupFlags(0), _fInProc(FALSE), _pFilterDaemon(0), _pPidLookupTable(0), _fNullContentIndex( FALSE ) { Win4Assert( pICiCDocStore ); pICiCDocStore->AddRef(); _xDocStore.Set( pICiCDocStore ); ICiCAdviseStatus *pAdviseStatus = 0; SCODE sc = _xDocStore->QueryInterface( IID_ICiCAdviseStatus, (void **) &pAdviseStatus); if ( S_OK != sc ) { Win4Assert( 0 != pAdviseStatus ); THROW(CException(sc) ); } _xAdviseStatus.Set(pAdviseStatus); ICiCLangRes *pICiCLangRes; sc = pICiCDocStore->QueryInterface(IID_ICiCLangRes, (void **) &pICiCLangRes); if ( FAILED(sc) ) { Win4Assert( !"QI on ICiCLangRes failed" ); THROW (CException(sc)); } XInterface xCiCLangRes(pICiCLangRes); _xLangList.Set( new CLangList(pICiCLangRes) ); CCiAdminParams * pAdminParams = new CCiAdminParams( _xLangList.GetPointer() ); _xAdminParams.Set( pAdminParams ); CCiFrameworkParams * pFrameParams = new CCiFrameworkParams( pAdminParams ); _xFrameParams.Set( pFrameParams ); } CCiManager::~CCiManager() { Win4Assert( 0 == _refCount ); delete _pFilterDaemon; delete _pcci; } //+--------------------------------------------------------------------------- // // Member: CCiManager::QueryInterface // // Synopsis: Returns interfaces to IID_IUknown, IID_ICiManager, // IID_ICiStartup, IID_ICiAdmin, IID_ICiFrameworkQuery, // IID_ISimpleCommandCreator // // History: 11-27-96 srikants Created // 2-14-97 mohamedn ICiAdmin and ICiFrameworkQuery // 04-23-97 KrishnaN Exposed IID_ISimpleCommandCreator // 04-23-97 KrishnaN Replaced RtlEqualMemory with == // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::QueryInterface( REFIID riid, void **ppvObject) { Win4Assert( 0 != ppvObject ); if ( IID_ISimpleCommandCreator == riid ) *ppvObject = (void *)((ISimpleCommandCreator *)this); else if ( IID_ICiManager == riid ) *ppvObject = (void *)((ICiManager *)this); else if ( IID_ICiStartup == riid ) *ppvObject = (void *)((ICiStartup *)this); else if ( IID_ICiAdmin == riid ) *ppvObject = (void *)((ICiAdmin *)this); else if ( IID_ICiFrameworkQuery == riid ) *ppvObject = (void *)((ICiFrameworkQuery *)this); else if ( IID_ICiPersistIncrFile == riid ) *ppvObject = (void *)((ICiPersistIncrFile *)this); else if ( (IID_ICiIndexNotification == riid ) && !_xIndexNotifTable.IsNull() ) { return _xIndexNotifTable->QueryInterface( riid, ppvObject ); } else if ( IID_IUnknown == riid ) *ppvObject = (void *)((IUnknown *) (ICiManager *) this); else { *ppvObject = 0; return E_NOINTERFACE; } AddRef(); return S_OK; } //QueryInterface //+--------------------------------------------------------------------------- // // Member: CCiManager::AddRef // // History: 11-22-96 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CCiManager::AddRef() { return InterlockedIncrement(&_refCount); } //AddRef //+--------------------------------------------------------------------------- // // Member: CCiManager::Release // // History: 11-22-96 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP_(ULONG) CCiManager::Release() { Win4Assert( _refCount > 0 ); LONG refCount = InterlockedDecrement(&_refCount); if ( refCount <= 0 ) delete this; return (ULONG) refCount; } //Release //+--------------------------------------------------------------------------- // // Member: CCiManager::GetStatus // // Synopsis: Retrieves the Content Index status // // Arguments: [pCiState] - // // History: 1-08-97 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::GetStatus(CIF_STATE *pCiState) { Win4Assert( 0 != pCiState ); SCODE sc = S_OK; if ( 0 != _pcci ) _pcci->CiState( *pCiState ); else sc = CI_E_NOT_INITIALIZED; return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::Empty // // Synopsis: Empties all the contents of the Content Index. // // History: 1-08-97 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::Empty() { SCODE sc = S_OK; if ( 0 != _pcci ) _pcci->Empty(); else sc = CI_E_NOT_INITIALIZED; return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::Shutdown // // Synopsis: Shuts down Content Index. Cannot initiate any more queries after // this. // // Returns: SCODE of the operation. // // History: 12-09-96 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::Shutdown() { SCODE sc = S_OK; // ======================================= { CLock lock(_mutex); if ( IsShutdown() ) return CI_E_SHUTDOWN; _state = SHUTDOWN; } // ======================================= _saveTracker.SetAbort(); if ( _pFilterDaemon ) _pFilterDaemon->InitiateShutdown(); if ( _pcci ) _pcci->Dismount(); // // Wait for the death of the filter daemon thread. // if ( _pFilterDaemon ) _pFilterDaemon->WaitForDeath(); _saveTracker.WaitForCompletion(); // // Shutdown buffered notifications in push filtering, // _after_ the filter thread has terminated. // if ( !_xIndexNotifTable.IsNull() ) _xIndexNotifTable->Shutdown(); _xPropMapper.Free(); _xDocStore.Free(); return S_OK; } //+--------------------------------------------------------------------------- // // Member: CCiManager::UpdateDocument // // Synopsis: Schedules a document for update and filtering. // // Arguments: [pInfo] - Information about the document to be updated. // // History: 12-09-96 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::UpdateDocument( const CI_DOCUMENT_UPDATE_INFO * pInfo ) { if ( _xIndexNotifTable.IsNull() ) return UpdDocumentNoThrow( pInfo ); else { // Win4Assert( !"UpdateDocument is not available in push filtering" ); ciDebugOut ((DEB_ERROR, "UpdateDocument is not available in push filtering, wid = 0x%x\n", pInfo->workId )); return E_FAIL; } } //+--------------------------------------------------------------------------- // // Member: CCiManager::StartupNullContentIndex // // Synopsis: Starts up the NULL content index. // // Arguments: [pwszCiDirectory] - Starting directory for storing CI data. // [pStartupInfo] - Startup information. // [pIProgressNotify] - Progress notification i/f // [pfAbort] - Ptr to flag controlling abort. // // History: Jul-09-97 KrishnaN Created // // Notes: The thread calling this MUST be in the SYSTEM/ADMINISTRATIVE // context, ie, have the highest privilege needed for Content Index. // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::StartupNullContentIndex( CI_STARTUP_INFO * pStartupInfo, IProgressNotify *pIProgressNotify, BOOL * pfAbort ) { // Anything but null for the second param... return StartupContentIndex(TRUE, CINULLCATALOG, pStartupInfo, pIProgressNotify, pfAbort); } //+--------------------------------------------------------------------------- // // Member: CCiManager::StartupContentIndex // // Synopsis: Starts up the content index using the startup parameters // provided. // // Arguments: [pwszCiDirectory] - Starting directory for storing CI data. // [pStartupInfo] - Startup information. // [pIProgressNotify] - Progress notification i/f // [pfAbort] - Ptr to flag controlling abort. // // History: 12-09-96 srikants Created // // Notes: The thread calling this MUST be in the SYSTEM/ADMINISTRATIVE // context, ie, have the highest privilege needed for Content Index. // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::StartupContentIndex( const WCHAR * pwszCiDirectory, CI_STARTUP_INFO * pStartupInfo, IProgressNotify *pIProgressNotify, BOOL * pfAbort ) { return StartupContentIndex(FALSE, pwszCiDirectory, pStartupInfo, pIProgressNotify, pfAbort); } //+--------------------------------------------------------------------------- // // Member: CCiManager::StartupContentIndex // // Synopsis: Starts up the content index using the startup parameters // provided. // // Arguments: [fNullContentIndex] - Null content index? // [pwszCiDirectory] - Starting directory for storing CI data. // [pStartupInfo] - Startup information. // [pIProgressNotify] - Progress notification i/f // [pfAbort] - Ptr to flag controlling abort. // // History: 12-09-96 srikants Created // 02-17-98 kitmanh Passed fReadOnly into CiStorage // constructor // 01-Nov-98 KLam Passed DiskSpaceToLeave to CiStorage // // Notes: The thread calling this MUST be in the SYSTEM/ADMINISTRATIVE // context, ie, have the highest privilege needed for Content Index. // //---------------------------------------------------------------------------- SCODE CCiManager::StartupContentIndex( BOOL fNullContentIndex, const WCHAR * pwszCiDirectory, CI_STARTUP_INFO * pStartupInfo, IProgressNotify *pIProgressNotify, BOOL * pfAbort ) { Win4Assert( !CImpersonateSystem::IsImpersonated() ); Win4Assert( 0 != pwszCiDirectory && 0 != pStartupInfo ); _fNullContentIndex = fNullContentIndex; CLock lock(_mutex); if ( STARTING != _state ) { return CI_E_INVALID_STATE; } _startupFlags = pStartupInfo->startupFlags; BOOL fPushFiltering = FALSE; if (!fNullContentIndex) { _fInProc = pStartupInfo->startupFlags & CI_CONFIG_INPROCESS_FILTERING; fPushFiltering = pStartupInfo->startupFlags & CI_CONFIG_PUSH_FILTERING; if ( fPushFiltering && !_fInProc ) { Win4Assert( !"Simple filtering is supported only with in process filtering" ); return E_INVALIDARG; } } SCODE sc = S_OK; TRY { if ( !fNullContentIndex && fPushFiltering ) { XInterface xDocStore( _xDocStore.GetPointer() ); xDocStore->AddRef(); _xIndexNotifTable.Set( new CIndexNotificationTable( this, xDocStore ) ); } BOOL fEnableFiltering = pStartupInfo->startupFlags & CI_CONFIG_ENABLE_INDEXING; // If this is a null content index, filtering should be disabled. Win4Assert( (fNullContentIndex && !fEnableFiltering) || !fNullContentIndex); if ( 0 == _pcci ) { CLowcaseBuf lcaseDir( pwszCiDirectory ); // // Make a copy to be acquired by CCiManager. // XArray xDirCopy( lcaseDir.Length()+1 ); if (!fNullContentIndex) { RtlCopyMemory( xDirCopy.GetPointer(), lcaseDir.Get(), xDirCopy.SizeOf() ); // // Create a PStorage object for CI framework data. // if ( 0 == _xStorage.GetPointer() ) { BOOL fReadOnly = (pStartupInfo->startupFlags & CI_CONFIG_READONLY) ? TRUE : FALSE; CiStorage * pStorage = new CiStorage( lcaseDir.Get(), _xAdviseStatus.GetReference(), _xFrameParams->GetMinDiskSpaceToLeave(), CURRENT_VERSION_STAMP, fReadOnly ); _xStorage.Set( pStorage ); } } // // Try to obtain a property mapper from the docstore. If successful, // we don't have to create one. O/W, we create a property mapper. // XInterface xPropMapper; IPropertyMapper * pPropMapper = 0; if ( pStartupInfo->startupFlags & CI_CONFIG_PROVIDE_PROPERTY_MAPPER ) { xPropMapper.Set( _LokCreatePropertyMapper() ); } else { SCODE scPropMapper = _xDocStore->GetPropertyMapper( &pPropMapper ); if ( !SUCCEEDED(scPropMapper) ) { ciDebugOut(( DEB_ERROR, "DocStore Is not providing property mapper. Error 0x%X\n", scPropMapper )); THROW( CException( E_INVALIDARG ) ); } xPropMapper.Set( pPropMapper ); } // // Update the worker queue registry settings. // _UpdateQueryWorkerQueueParams(); // // Save the CLSID of the client manager in daemon process. // _clsidDmnClientMgr = pStartupInfo->clsidDaemonClientMgr; if (!fNullContentIndex) { if ( !_xIndexNotifTable.IsNull() ) _xIndexNotifTable->AddRef(); XInterface xNotifTable( _xIndexNotifTable.GetPointer() ); _pcci = new CCI( _xStorage.GetReference(), _xFrameParams.GetReference(), _xDocStore.GetPointer(), *pStartupInfo, xPropMapper.GetPointer(), xNotifTable ); _xCiDir.Set( xDirCopy.Count(), xDirCopy.Get() ); xDirCopy.Acquire(); } _xPropMapper.Set( xPropMapper.Acquire() ); // // Move to the next state depending upon the startup options. // if ( fEnableFiltering ) { // // Check the disk free space situation. // _state = READY_TO_FILTER; } else { _state = FILTERING_DISABLED; _reason = DISABLED_ON_STARTUP; } } else { sc = CI_E_ALREADY_INITIALIZED; } } CATCH( CException, e ) { sc = e.GetErrorCode(); } END_CATCH return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::_LokGetStartFilteringError // // Synopsis: Determines the error code to be returned in the // StartFiltering() method based upon the current state. // // Returns: // // History: 12-10-96 srikants Created // //---------------------------------------------------------------------------- SCODE CCiManager::_LokGetStartFilteringError() const { Win4Assert( READY_TO_FILTER != _state ); if ( FILTERING_DISABLED == _state ) { Win4Assert( INVALID_REASON != _reason ); if ( DISABLED_ON_STARTUP == _state ) { return CI_E_FILTERING_DISABLED; } else if ( DISABLED_FOR_DISK_FULL == _reason ) { return CI_E_DISK_FULL; } else { return CI_E_INVALID_STATE; } } else if ( FILTERING_ENABLED == _state ) { return S_OK; // already enabled. } else { return CI_E_INVALID_STATE; } } //+--------------------------------------------------------------------------- // // Member: CCiManager::StartFiltering // // Synopsis: Start the filtering process // // Arguments: [cbData] - Count of bytes in startup data // [pbData] - Pointer to startup data // // Returns: CI_E_DISK_FULL if the disk is full and so filtering cannot be // started. // // CI_E_FILTERING_DISABLED if filtering was disabled in the startup // options. // // CI_E_INVALID_STATE if this is not a valid call in this state. // Usually signifies that shutdown is in progress. // // History: 12-09-96 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::StartFiltering( ULONG cbData, BYTE const * pbData ) { SCODE sc = S_OK; // ============================================================== { CLock lock(_mutex); if ( READY_TO_FILTER != _state ) { return _LokGetStartFilteringError(); } TRY { if ( 0 == _pFilterDaemon ) { CSharedNameGen nameGen( _xCiDir.Get() ); _pFilterDaemon = new CDaemonSlave( *this, _pcci, _xCiDir.Get(), nameGen, _clsidDmnClientMgr ); } _pFilterDaemon->StartFiltering( pbData, cbData); _state = FILTERING_ENABLED; } CATCH( CException, e ) { sc = e.GetErrorCode(); } END_CATCH } // ============================================================== return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::FlushUpdates // // Synopsis: Flushes all update notifications to disk // // Returns: S_OK if successful; error code otherwise. // // History: 27-Jun-97 SitaramR Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::FlushUpdates() { SCODE sc = S_OK; TRY { if ( IsShutdown() ) sc = CI_E_SHUTDOWN; else _pcci->FlushUpdates(); } CATCH( CException, e ) { sc = e.GetErrorCode(); ciDebugOut(( DEB_ERROR, "FlushUpdates - caught exception 0x%x\n", sc )); } END_CATCH return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::ForceMerge // // Synopsis: Forces a master merge on the content index. // // Arguments: [mt] -- Merge type (shadow, master, etc.) // // Returns: S_OK if successfully forced; error code otherwise. // // History: 12-11-96 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::ForceMerge( CI_MERGE_TYPE mt ) { SCODE sc = S_OK; if ( 0 != _pcci ) { Win4Assert( STARTING != _state ); sc = _pcci->ForceMerge( partidDefault, mt ); } else { sc = CI_E_NOT_INITIALIZED; } return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::AbortMerge // // Synopsis: Aborts any in progress merge on the content index. // // Returns: S_OK if successfully forced; error code otherwise. // // History: 12-11-96 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::AbortMerge() { SCODE sc = S_OK; if ( 0 != _pcci ) { Win4Assert( STARTING != _state ); sc = _pcci->AbortMerge( partidDefault ); } else { sc = CI_E_NOT_INITIALIZED; } return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::IsQuiesced // // Synopsis: Tests if Content Index is quiesced (no activity). ContentIndex // is considered quiesced if there are no outstanding documents // to filter, there is only one index and there are no wordlists. // // Arguments: [pfState] - Set to TRUE if it CI is quiesced; FALSE o/w // // History: 1-08-97 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::IsQuiesced( BOOL * pfState ) { Win4Assert( 0 != pfState ); CIF_STATE ciState; ciState.cbStruct = sizeof ciState; SCODE sc = GetStatus( &ciState ); if ( S_OK == sc ) { *pfState = 0 == ciState.eState && 0 == ciState.cWordList && 0 == ciState.cDocuments && 0 == ciState.cFreshTest && ciState.cPersistentIndex <= 1; } return sc; } // // ICiPersistIncrFile methods // //+--------------------------------------------------------------------------- // // Member: CCiManager::Save // // Synopsis: Saves the Content Index data in the directory provided. // An incremental save for the first time will actually be a full // save. // // Arguments: [pwszSaveDirectory] - The directory in which to save the backup // data. This directory MUST be on a local drive and security protected. // It is recommended that this directory has the same security set as the // current content index directory. Also, it MUST be on a local drive. // [fFull] - Set to TRUE if a full save is being requested. // [pIProgressNotify] - Interface to give progress notification. // [pfAbort] - This flag will be set to TRUE by the caller if // the caller wants the operation to be aborted before completion. // [ppWorkidList] - On output, will have the list of changed workids. // On a full save, this list may be empty in which case the caller must // assume that all the know workids have changed. // [ppFileList] - On output, will be set to the filelist enumerator. // [pfFull] - Set to TRUE if a FULL save was done. // [pfCallerOwnsFiles] - Set to TRUE if the caller has the responsibility to // clean up the files. // // Returns: S_OK if successful // Other error code as appropriate. // // History: 3-20-97 srikants Created // 01-Nov-98 KLam Added DiskSpaceToLeave to CiStorage constructor // // Notes: Handle DISK_FULL as a special case. // Right now there is no restartability - if an operation fails in // the middle due to any problem, the whole operation is aborted // and the partially created files are deleted. We should do some // logging to indicate the progress made so far and have a notion of // restartability. The time I have does not permit doing the // restartability - SriKants - 3-20-97 // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::Save( const WCHAR *pwszSaveDirectory, BOOL fFull, IProgressNotify *pIProgressNotify, BOOL *pfAbort, ICiEnumWorkids ** ppWorkidList, IEnumString ** ppFileList, BOOL * pfFull, BOOL * pfCallerOwnsFiles) { Win4Assert( !CImpersonateSystem::IsImpersonated() ); if ( !_IsIncrIndexingEnabled() ) return CI_E_INVALID_STATE; if ( 0 == _pcci ) return CI_E_INVALID_STATE; if ( IsShutdown() ) return CI_E_SHUTDOWN; //===================================== { // // There can be only one instance of "Save()" running at // any time. // CLock lock(_mutex); if ( !_saveTracker.LokIsTracking() ) { _saveTracker.LokStartTracking( pIProgressNotify, pfAbort ); } else { return CI_E_INVALID_STATE; } } //===================================== SCODE sc = S_OK; TRY { if ( !_IsValidSaveDirectory( pwszSaveDirectory ) ) { ciDebugOut(( DEB_ERROR, "Invalid Save Directory (%ws)\n", pwszSaveDirectory )); THROW( CException( E_INVALIDARG ) ); } XInterface xEnumWorkids; XPtr xStorage( new CiStorage( pwszSaveDirectory, _xAdviseStatus.GetReference(), _xFrameParams->GetMinDiskSpaceToLeave(), CURRENT_VERSION_STAMP )); // // Until we have a restartable save, nuke all the files in the specified // directory. // xStorage->DeleteAllFiles(); BOOL fIsFull = fFull; SCODE sc = _pcci->BackupCiData( xStorage.GetReference(), fIsFull, // in-out parameter xEnumWorkids, _saveTracker ); if ( !SUCCEEDED(sc) ) { THROW( CException(sc) ); } // // If we provided the property mapper, we must copy that too. // if ( 0 != _pPidLookupTable ) _CreateBackupOfPidTable( xStorage.GetReference(), _saveTracker ); // // Create an enumerated list of the files created in this save. // CEnumString * pEnumStr = new CEnumString; XInterface xEnumStr( pEnumStr ); CiStorage::EnumerateFilesInDir( pwszSaveDirectory, *pEnumStr ); // // Setup the return parameter values. // *ppWorkidList = xEnumWorkids.Acquire(); *ppFileList = xEnumStr.Acquire(); *pfFull = fIsFull; *pfCallerOwnsFiles = TRUE; } CATCH( CException,e ) { ciDebugOut(( DEB_ERROR, "Error in CCiManager::Save. (0x%X)\n", e.GetErrorCode() )); sc = e.GetErrorCode(); } END_CATCH //===================================== { CLock lock(_mutex); _saveTracker.LokStopTracking(); } //===================================== return sc; } // ICiFrameWorkQuery interface - interface that is internal to the // framework indexing and querying only. // //+--------------------------------------------------------------------------- // // Member: CCiManager::ProcessError // // Synopsis: Processes the error code. Only the corruption error is of // interest to notify the content index which in turn will // notify the client. // // Arguments: [lErrorCode] - // // History: 1-08-97 srikants Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::ProcessError( long lErrorCode ) { if ( IsCiCorruptStatus( lErrorCode ) && 0 != _pcci ) _pcci->MarkCorruptIndex(); return S_OK; } // // ISimpleCommandCreator methods // //+--------------------------------------------------------------------------- // // Member: CCiManager::CreateICommand, public // // Synopsis: Exposes an ICommand from the framework. // // Arguments: [ppiCommand] - Transports back an instance of the ICommand // // History: 04-22-97 KrishnaN Created // //---------------------------------------------------------------------------- STDMETHODIMP CCiManager::CreateICommand (IUnknown ** ppIUnknown, IUnknown * pOuterUnk) { if (0 == ppIUnknown) { ciDebugOut((DEB_ERROR, "Invalid ppICommand passed to CCiManager::CreateICommand")); return E_INVALIDARG; } *ppIUnknown = 0; if ( 0 ==_xDocStore.GetPointer() ) return E_NOINTERFACE; return MakeLocalICommand(ppIUnknown, _xDocStore.GetPointer(), pOuterUnk); } //+--------------------------------------------------------------------------- // // Member: CCiManager::VerifyCatalog, public // // Synopsis: Validate catalog location // // Arguments: [pwszMachine] -- Machine on which catalog exists // [pwszCatalogName] -- Catalog Name // // Returns: S_OK for now... // // History: 22-Jul-97 KyleP Created // //---------------------------------------------------------------------------- SCODE STDMETHODCALLTYPE CCiManager::VerifyCatalog( WCHAR const * pwszMachine, WCHAR const * pwszCatalogName ) { return S_OK; } //+--------------------------------------------------------------------------- // // Member: CCiManager::GetDefaultCatalog, public // // Synopsis: Determine 'default' catalog for system // // Arguments: [pwszCatalogName] -- Catalog Name // [cwcIn] -- Size in characters of [pwszCatalogName] // [pcwcOut] -- Size of catalog name // // Returns: E_NOTIMPL // // History: 22-Jul-97 KyleP Created // //---------------------------------------------------------------------------- SCODE STDMETHODCALLTYPE CCiManager::GetDefaultCatalog( WCHAR * pwszCatalogName, ULONG cwcIn, ULONG * pcwcOut ) { return E_NOTIMPL; } // // Non-Interface methods // void CCiManager::ProcessCiDaemonTermination( SCODE sc ) { CLock lock(_mutex); if ( _xDocStore.GetPointer() ) { _state = READY_TO_FILTER; sc = _xDocStore->ProcessCiDaemonTermination(sc); if ( !SUCCEEDED(sc) ) { ciDebugOut(( DEB_ERROR, "ICiCDocStore::ProcessCiDaemonTermination returned 0x%X\n", sc )); THROW( CException( sc ) ); } } } //+--------------------------------------------------------------------------- // // Member: CCiManager::_LokCreatePropertyMapper // // Synopsis: Creates a property mapper object. // // History: 1-31-97 srikants Created // //---------------------------------------------------------------------------- IPropertyMapper * CCiManager::_LokCreatePropertyMapper() { Win4Assert( 0 == _xPropMapper.GetPointer() ); Win4Assert( 0 == _pPidLookupTable ); XPtr xPidTable( new CPidLookupTable ); PRcovStorageObj * pObj = _xStorage->QueryPidLookupTable(0); // Init takes ownership regardless of whether it succeeds. if ( !xPidTable->Init( pObj ) ) { ciDebugOut ((DEB_ERROR, "Failed init of PidTable\n")); THROW (CException(CI_CORRUPT_CATALOG)); } IPropertyMapper * pMapper = new CFwPropertyMapper( xPidTable.GetReference(), _fNullContentIndex, // map std props only? TRUE // Own the pid table ); _pPidLookupTable = xPidTable.Acquire(); return pMapper; } //+--------------------------------------------------------------------------- // // Member: CCiManager::_CreateBackupOfPidTable // // Synopsis: Creates a copy of the pid table. // // Arguments: [storage] - Storage to use // [tracker] - Progress Tracker // // History: 3-20-97 srikants Created // //---------------------------------------------------------------------------- void CCiManager::_CreateBackupOfPidTable( CiStorage & storage, PSaveProgressTracker & tracker ) { Win4Assert( 0 != _pPidLookupTable ); PRcovStorageObj * pObj = storage.QueryPidLookupTable(0); XPtr xObj(pObj); _pPidLookupTable->MakeBackupCopy( *pObj, tracker ); } //+--------------------------------------------------------------------------- // // Member: CCiManager::_UpdateQueryWorkerQueueParams // // Synopsis: Updates the worker queue parameters // // History: 1-03-97 srikants Created // //---------------------------------------------------------------------------- void CCiManager::_UpdateQueryWorkerQueueParams() { // // Getting these from the registry is fine for Indexing Service, // but will be fixed in the PKM codebase. // ULONG cMaxActiveThreads, cMinIdleThreads; TheWorkQueue.GetWorkQueueRegParams( cMaxActiveThreads, cMinIdleThreads ); TheWorkQueue.RefreshParams( cMaxActiveThreads, cMinIdleThreads ); } //+--------------------------------------------------------------------------- // // Member: CCiManager::UpdDocumentNoThrow // // Synopsis: Real worker function that schedules a document for update // and filtering. This is called directly in push filtering. // // Arguments: [pInfo] - Information about the document to be updated. // // History: 15-Mar-97 SitaramR Created // // Notes: Does not throw because this is simply a worker function // for UpdateDocument // //---------------------------------------------------------------------------- SCODE CCiManager::UpdDocumentNoThrow( const CI_DOCUMENT_UPDATE_INFO * pInfo ) { Win4Assert( 0 != pInfo ); SCODE sc = S_OK; TRY { if ( 0 == _pcci ) sc = CI_E_NOT_INITIALIZED; else { ULONG hint = _pcci->ReserveUpdate( pInfo->workId ); ULONG action = CI_UPDATE_OBJ; if ( CI_UPDATE_DELETE == pInfo->change ) action = CI_DELETE_OBJ; sc = _pcci->Update( hint, pInfo->workId, partidDefault, pInfo->usn, pInfo->volumeId, action ); } } CATCH( CException,e ) { ciDebugOut(( DEB_ERROR, "CCiManager::UpdDocument - Error 0x%X\n", e.GetErrorCode() )); sc = e.GetErrorCode(); } END_CATCH return sc; } //+--------------------------------------------------------------------------- // // Member: CCiManager::_IsValidLoadDirectory // // Synopsis: Verifies that the given directory is a valid directory. // It ensures that files INDEX.000, INDEX.001, INDEX.002 // are in the directory. // // Arguments: [pwszDirPath] - Directory path to verify. // // Returns: TRUE if valid; FALSE o/w; May throw exceptions. // // History: 3-21-97 srikants Created // //---------------------------------------------------------------------------- BOOL CCiManager::_IsValidSaveDirectory( WCHAR const * pwszDirPath ) { // // Confirm that it is a local drive. // UINT driveType = CiStorage::DetermineDriveType( pwszDirPath ); if ( DRIVE_FIXED != driveType ) { ciDebugOut(( DEB_ERROR, "The given path (%ws) is not a local fixed disk\n", pwszDirPath )); THROW( CException( E_INVALIDARG ) ); } const MAX_DIR_PATH = MAX_PATH - 13; // Leave room for "\\8.3" DWORD dwFileAttributes = GetFileAttributes( pwszDirPath ); if ( 0xFFFFFFFF == dwFileAttributes ) return FALSE; return dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY; } //+--------------------------------------------------------------------------- // // Member: CCiManager::_CompareIncrDataSequence // // Synopsis: Compares the sequence number information stored in the // current catalog and the information in the new files. // // Arguments: [pwszNewFilesDir] - Directory where the new INDEX.* files // are located. // // Returns: TRUE if they match. FALSE o/w // // History: 3-19-97 srikants Created // 01-Nov-98 KLam Added DiskSpaceToLeave to CiStorage constructor // //---------------------------------------------------------------------------- BOOL CCiManager::_CompareIncrDataSequence( WCHAR const * pwszNewFilesDir ) { Win4Assert( !_xStorage.IsNull() ); // // Create a new CiStorage for the target directory. // XPtr xStorage( new CiStorage( pwszNewFilesDir, _xAdviseStatus.GetReference(), _xFrameParams->GetMinDiskSpaceToLeave(), CURRENT_VERSION_STAMP) ); // // Create the index table for the current storage location. // CTransaction xact; XPtr xCurrTable( new CIndexTable( _xStorage.GetReference(), xact )); XPtr xNewTable( new CIndexTable( xStorage.GetReference(), xact )); unsigned currVersion, newVersion; BOOL fFullSave; xCurrTable->GetUserHdrInfo( currVersion, fFullSave ); // fFullSave is ignored xNewTable->GetUserHdrInfo( newVersion, fFullSave ); ciDebugOut(( DEB_WARN, "%s\nCurrent Version = %d\n New Version = %d\n", fFullSave ? "FullSave" : "Incr. Save", currVersion, newVersion )); if ( fFullSave ) { // // For FULL save, any version is fine. return TRUE; } else { // // For an incremental save, the seqnums in the source and // destination must match. Otherwise, it should be ignored. // return currVersion == newVersion; } }