|
|
//+---------------------------------------------------------------------------
//
// 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 <pch.cxx>
#pragma hdrstop
#include <cci.hxx>
#include <prcstob.hxx>
#include <glbconst.hxx>
#include <idxtab.hxx>
#include <enumstr.hxx>
#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<ICiCLangRes> 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<ICiCDocStore> 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<WCHAR> 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<IPropertyMapper> 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<CIndexNotificationTable> 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<ICiEnumWorkids> xEnumWorkids;
XPtr<CiStorage> 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<IEnumString> 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<CPidLookupTable> 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<PRcovStorageObj> 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<CiStorage> xStorage( new CiStorage( pwszNewFilesDir, _xAdviseStatus.GetReference(), _xFrameParams->GetMinDiskSpaceToLeave(), CURRENT_VERSION_STAMP) );
//
// Create the index table for the current storage location.
//
CTransaction xact; XPtr<CIndexTable> xCurrTable( new CIndexTable( _xStorage.GetReference(), xact ));
XPtr<CIndexTable> 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; }
}
|