Windows2003-3790/inetsrv/query/cicat/cinulcat.cxx

387 lines
11 KiB
C++

//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation, 1997 - 2001.
//
// File: CiNulCat.CXX
//
// Contents: Content index null catalog.
//
// Classes:
//
// History: 09-Jul-1997 KrishnaN Created
//
//----------------------------------------------------------------------------
#include <pch.cxx>
#pragma hdrstop
#include <regacc.hxx>
#include <cicat.hxx>
#include <cinulcat.hxx>
#include <update.hxx>
#include <pstore.hxx>
#include <pidremap.hxx>
#include <imprsnat.hxx>
#include <docstore.hxx>
#include <cievtmsg.h>
#include <cifailte.hxx>
#include <regscp.hxx>
#include <cifrmcom.hxx>
#include <glbconst.hxx>
#include <cimbmgr.hxx>
#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<ICiAdminParams> xICiAdminParams;
ICiAdmin *pICiAdmin = 0;
XInterface<ICiAdmin> 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