//+--------------------------------------------------------------------------- // // Microsoft Windows // Copyright (C) Microsoft Corporation, 1997 - 2001. // // File: CiNulCat.CXX // // Contents: Content index null catalog. // // Classes: // // History: 09-Jul-1997 KrishnaN Created // //---------------------------------------------------------------------------- #include #pragma hdrstop #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "catreg.hxx" // // Given a registry string like \Registry\Machine\System\CurrentControlSet\... // you skip the first 18 characters if using w/ HKEY_LOCAL_MACHINE. // unsigned const SKIP_TO_LM = 18; // ------------------------------------------------------------------------- // DO NOT VIOLATE THE FOLLOWING LOCK HIERARCHY // // 1. DocStore Lock // 2. CiNullCat Admin Lock // 3. CiNullCat Lock // 4. Resman Lock // 5. ScopeTable Lock // 6. NotifyMgr Lock // 7. ScanMgr Lock // 8. Propstore write lock // 9. Propstore lock record // // It is okay for a thread to acquire lock at level X and then acquire a lock // at a level >= X but not locks < X. This will avoid deadlock situations. // // SrikantS - April 25, 1996 // SrikantS _ Dec 31, 1996 - Added DocStore as the highest level lock // // ------------------------------------------------------------------------- //+------------------------------------------------------------------------- // // Member: CiNullCat::SetAdviseStatus, public // // Synopsis: Taken out of the CiNullCat constructor // // History: 11-May-2001 KitmanH Taken out from the CiNullCat constructor // // Note: The purpose of this function is to prevent circular deleteions // of CiNullCat and CClientDocStore. If CClientDocStore throws // after StartUpCiFrameWork, CiNullCat should not AddRef to // docstore // //-------------------------------------------------------------------------- void CiNullCat::SetAdviseStatus() { // obtain an ICiCAdviseStatus interface pointer to use ICiCAdviseStatus *pAdviseStatus = 0; SCODE sc = _docStore.QueryInterface( IID_ICiCAdviseStatus, (void **) &pAdviseStatus); if ( S_OK != sc ) { Win4Assert( 0 == pAdviseStatus ); THROW( CException(sc) ); } _xAdviseStatus.Set(pAdviseStatus); } //+------------------------------------------------------------------------- // // Member: CiNullCat::CiNullCat, public // // Synopsis: Creates a new 'content index catalog' // // Arguments: [wcsCatPath] - root path of catalog // [pwcName] - 0 or name of the catalog from the registry // // History: 10-Mar-92 BartoszM Created // 14-mar-92 KyleP Added Content index object. // //-------------------------------------------------------------------------- CiNullCat::CiNullCat ( CClientDocStore & docStore) : _ulSignature( LONGSIG( 'c', 'c', 'a', 't' ) ), _state(eStarting), _docStore(docStore), _fInitialized(FALSE), _impersonationTokenCache( CINULLCATALOG ) { CImpersonateSystem impersonate; BuildRegistryScopesKey( _xScopesKey, CINULLCATALOG ); _impersonationTokenCache.Initialize( CI_ACTIVEX_NAME, FALSE, FALSE, FALSE, 1, 1, 1 ); // These scopes will be used for query time (un)fixups SetupScopeFixups(); _state = eStarted; END_CONSTRUCTION( CiNullCat ); } //CiNullCat //+--------------------------------------------------------------------------- // // Member: CiNullCat::ShutdownPhase2, public // // Synopsis: Dismounts the catalog by stopping all activity. // // History: 1-30-96 srikants Created // // Notes: // //---------------------------------------------------------------------------- void CiNullCat::ShutdownPhase2() { CImpersonateSystem impersonate; TRY { // =================================================== { CLock lock(_mutex); _state = eShutdown; } // =================================================== CLock lock(_mutex); _xCiManager.Free(); } CATCH( CException, e ) { ciDebugOut(( DEB_ERROR, "CiNullCat::Shutdown failed with error 0x%X\n", e.GetErrorCode() )); } END_CATCH } //Shutdown //+------------------------------------------------------------------------- // // Member: CiNullCat::~CiNullCat, public // // Synopsis: Destructor // // History: 10-Mar-92 BartoszM Created // //-------------------------------------------------------------------------- CiNullCat::~CiNullCat () { if ( !IsShutdown() ) ShutdownPhase2(); } //+--------------------------------------------------------------------------- // // Member: CiNullCat::CiState, public // // Synopsis: Returns state of downlevel CI // // Arguments: [state] -- buffer to return state into // // History: 14-Dec-95 DwightKr Created // //---------------------------------------------------------------------------- #define setState( field, value ) \ if ( state.cbStruct >= ( offsetof( CI_STATE, field) + \ sizeof( state.field ) ) ) \ { \ state.field = ( value ); \ } SCODE CiNullCat::CiState( CI_STATE & state ) { SCODE sc = S_OK; if ( IsStarted() ) { state.cbStruct = min( state.cbStruct, sizeof(CI_STATE) ); RtlZeroMemory( &state, state.cbStruct ); setState( dwMergeProgress, 100 ); } else if ( IsShutdown() ) { sc = CI_E_SHUTDOWN; } else { sc = CI_E_NOT_INITIALIZED; } return sc; } //+--------------------------------------------------------------------------- // // Member: CiNullCat::HandleError // // Synopsis: Checks the status code passed and if it indicates corruption, // the index will be marked corrupt in-memory as well as on // disk. The recovery will happen on a subsequent restart. // // Arguments: [status] - The status code to check for corruption. // // History: 3-21-96 srikants Created // // Notes: MUST NOT THROW // //---------------------------------------------------------------------------- void CiNullCat::HandleError( NTSTATUS status ) { Win4Assert(CI_PROPSTORE_INCONSISTENCY != status); Win4Assert(!IsDiskLowError(status)); Win4Assert(!IsCiCorruptStatus(status)); // // We can't be corrupt, so nothing to do here. // } //HandleError // // Support for CI Frame Work // //+--------------------------------------------------------------------------- // // Member: CiNullCat::StartupCiFrameWork // // Synopsis: Takes the CiManager object pointer and refcounts it. // // Arguments: [pICiManager] - // // History: 12-05-96 srikants Created // // Note: Choose a better name. // //---------------------------------------------------------------------------- // void CiNullCat::StartupCiFrameWork( ICiManager * pICiManager ) { Win4Assert( 0 != pICiManager ); Win4Assert( 0 == _xCiManager.GetPointer() ); if ( 0 == _xCiManager.GetPointer() ) { pICiManager->AddRef(); _xCiManager.Set( pICiManager ); } RefreshRegistryParams(); } //+--------------------------------------------------------------------------- // // Member: CiNullCat::RefreshRegistryParams // // Synopsis: Refreshes CI registry parameters. // // History: 12-12-96 srikants Created // 1-25-97 mohamedn ICiAdminParams, ICiAdmin // Notes: // //---------------------------------------------------------------------------- void CiNullCat::RefreshRegistryParams() { ICiAdminParams *pICiAdminParams = 0; XInterface xICiAdminParams; ICiAdmin *pICiAdmin = 0; XInterface xICiAdmin; // ++++++++++++++++++++++++++++++++++++++++++++++++++++ { CLock lock(_mutex); if ( !IsShutdown() && 0 != _xCiManager.GetPointer() ) { // get pICiAdminParams SCODE sc = _xCiManager->GetAdminParams( &pICiAdminParams ); if ( FAILED(sc) ) { Win4Assert( 0 == pICiAdminParams ); THROW( CException(sc) ); } xICiAdminParams.Set(pICiAdminParams); // get pICiAdmin sc = _xCiManager->QueryInterface(IID_ICiAdmin,(void **)&pICiAdmin); if ( FAILED(sc) ) { Win4Assert( 0 == pICiAdmin ); THROW( CException(sc) ); } xICiAdmin.Set(pICiAdmin); } } // ----------------------------------------------------- SCODE sc = xICiAdmin->InvalidateLangResources(); if ( FAILED (sc) ) { Win4Assert( !"Failed to InvalidateLangResources\n" ); THROW( CException(sc) ); } _regParams.Refresh(pICiAdminParams); } //+------------------------------------------------------------------------- // // Member: CiNullCat::SetupScopeFixups, private // // Synopsis: Grovel registry looking for CI scopes and setup fixups // // History: 16-Oct-96 dlee Created // //-------------------------------------------------------------------------- void CiNullCat::SetupScopeFixups() { TRY { ciDebugOut(( DEB_ITRACE, "Reading scope fixups from '%ws'\n", GetScopesKey() )); CRegAccess regScopes( RTL_REGISTRY_ABSOLUTE, GetScopesKey() ); CRegistryScopesCallBackFixups callback( this ); regScopes.EnumerateValues( 0, callback ); } CATCH( CException, e ) { ciDebugOut(( DEB_WARN, "Exception 0x%x caught groveling ci registry fixups.\n", e.GetErrorCode() )); HandleError( e.GetErrorCode() ); } END_CATCH } //SetupScopeFixups