Source code of Windows XP (NT5)
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

2877 lines
80 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 2002.
  5. //
  6. // File: docstore.cxx
  7. //
  8. // Contents: Deals with the client side document store implementation.
  9. //
  10. // Classes: CClientDocStore
  11. //
  12. // History: 12-03-96 srikants Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. // for definition of CRequestQueue
  18. #include <query.hxx>
  19. #include <srequest.hxx>
  20. #include <regacc.hxx>
  21. #include <docstore.hxx>
  22. #include <docname.hxx>
  23. #include <qsession.hxx>
  24. #include <cicat.hxx>
  25. #include <cinulcat.hxx>
  26. #include <seccache.hxx>
  27. #include <dmnstart.hxx>
  28. #include <propmap.hxx>
  29. #include <notifyev.hxx>
  30. #include <catalog.hxx>
  31. #include <catarray.hxx>
  32. #include <glbconst.hxx>
  33. #include <cisvcex.hxx>
  34. #include <cisvcfrm.hxx>
  35. #include <cistore.hxx>
  36. #include <enumstr.hxx>
  37. #include <filterob.hxx>
  38. #include <catadmin.hxx>
  39. #include <fsci.hxx>
  40. extern CCatArray Catalogs;
  41. CRequestQueue * g_pFSCIRequestQueue = 0;
  42. extern "C" const GUID clsidStorageFilterObject =
  43. { 0xaa205a4d, 0x681f, 0x11d0, { 0xa2, 0x43, 0x8, 0x0, 0x2b, 0x36, 0xfc, 0xa4 } };
  44. extern "C" const GUID guidStorageDocStoreLocatorObject;
  45. //+---------------------------------------------------------------------------
  46. //
  47. // Member: CClientDocStore::QueryInterface
  48. //
  49. // Synopsis: Supports IID_IUnknown
  50. // IID_ICiCDocStore
  51. // IID_ICiCDocStoreEx
  52. // IID_ICiCPropertyStorage
  53. // IID_ICiCDocNameToWorkidTranslator
  54. // IID_ICiCDocNameToWorkidTranslatorEx
  55. // IID_ICiCAdviseStatus
  56. // IID_IFsCiAdmin
  57. // IID_ICiCLangRes
  58. //
  59. // History: 12-03-96 srikants Created
  60. // 2-14-97 mohamedn ICiCLangRes
  61. //
  62. //----------------------------------------------------------------------------
  63. STDMETHODIMP CClientDocStore::QueryInterface( REFIID riid, void **ppvObject )
  64. {
  65. Win4Assert( 0 != ppvObject );
  66. if ( IID_ICiCDocStore == riid )
  67. *ppvObject = (void *)((ICiCDocStore *)this);
  68. else if ( IID_ICiCPropertyStorage == riid )
  69. *ppvObject = (void *)((ICiCPropertyStorage *)this);
  70. else if ( IID_ICiCDocNameToWorkidTranslator == riid )
  71. *ppvObject = (void *)((ICiCDocNameToWorkidTranslator *)this);
  72. else if ( IID_ICiCDocNameToWorkidTranslatorEx == riid )
  73. *ppvObject = (void *)((ICiCDocNameToWorkidTranslatorEx *)this);
  74. else if ( IID_ICiCAdviseStatus == riid )
  75. *ppvObject = (void *)((ICiCAdviseStatus *)this);
  76. else if ( IID_IFsCiAdmin == riid )
  77. *ppvObject = (void *)((IFsCiAdmin *)this);
  78. else if ( IID_ICiCLangRes == riid )
  79. *ppvObject = (void *) ((ICiCLangRes *)this);
  80. else if ( IID_ICiCDocStoreEx == riid )
  81. *ppvObject = (void *)((IUnknown *) (ICiCDocStoreEx *)this);
  82. else if ( IID_ICiCResourceMonitor == riid )
  83. *ppvObject = (void *)((IUnknown *) (ICiCResourceMonitor *)this);
  84. else if ( IID_IUnknown == riid )
  85. *ppvObject = (void *)((IUnknown *) (ICiCDocStore *)this);
  86. else
  87. {
  88. *ppvObject = 0;
  89. return E_NOINTERFACE;
  90. }
  91. AddRef();
  92. return S_OK;
  93. } //QueryInterface
  94. //+---------------------------------------------------------------------------
  95. //
  96. // Member: CClientDocStore::AddRef
  97. //
  98. // History: 12-03-96 srikants Created
  99. //
  100. //----------------------------------------------------------------------------
  101. STDMETHODIMP_(ULONG) CClientDocStore::AddRef()
  102. {
  103. return InterlockedIncrement(&_refCount);
  104. } //AddRef
  105. //+---------------------------------------------------------------------------
  106. //
  107. // Member: CClientDocStore::Release
  108. //
  109. // History: 12-03-96 srikants Created
  110. //
  111. //----------------------------------------------------------------------------
  112. STDMETHODIMP_(ULONG) CClientDocStore::Release()
  113. {
  114. Win4Assert( _refCount > 0 );
  115. LONG refCount = InterlockedDecrement(&_refCount);
  116. if ( refCount <= 0 )
  117. delete this;
  118. return (ULONG) refCount;
  119. } //Release
  120. //+---------------------------------------------------------------------------
  121. //
  122. // Member: CClientDocStore::CClientDocStore
  123. //
  124. // Synopsis: Constructor of the NULL CiCDocStore object.
  125. //
  126. // Arguments: None
  127. //
  128. // History: Jul-09-97 KrishnaN Created
  129. // 01-Nov-98 KLam Need to instantiate a CDiskFreeStatus
  130. //
  131. //----------------------------------------------------------------------------
  132. CClientDocStore::CClientDocStore()
  133. : _sigClientDocStore(eSigClientDocStore),
  134. _refCount(1),
  135. _fNoQuery( FALSE ),
  136. _state(eUpdatesDisabled),
  137. _pCiCat(0),
  138. _pCiNullCat(0)
  139. {
  140. // Create the CiNullCat object.
  141. _pCiNullCat = new CiNullCat( *this );
  142. XPtr<CiNullCat> xCat( _pCiNullCat );
  143. // Map std props only (second param)
  144. _xPropMapper.Set( new CFwPropertyMapper( _pCiNullCat->GetPidLookupTable(), TRUE ) );
  145. // Create CI Manager object.
  146. _CreateCiManager();
  147. _pCiNullCat->StartupCiFrameWork( _xCiManager.GetPointer() );
  148. //
  149. // Startup content index.
  150. //
  151. ICiStartup * pCiStartup;
  152. SCODE sc = _xCiManager->QueryInterface( IID_ICiStartup, (void **) &pCiStartup );
  153. XInterface<ICiStartup> xStartup( pCiStartup );
  154. if ( S_OK != sc )
  155. {
  156. THROW( CException(sc) );
  157. }
  158. CI_STARTUP_INFO startupInfo;
  159. RtlZeroMemory( &startupInfo, sizeof(startupInfo) );
  160. startupInfo.clsidDaemonClientMgr = clsidStorageFilterObject;
  161. startupInfo.startupFlags = CI_CONFIG_ENABLE_QUERYING ;
  162. BOOL fAbort = FALSE;
  163. sc = pCiStartup->StartupNullContentIndex( &startupInfo,0, &fAbort );
  164. if ( FAILED(sc) )
  165. {
  166. THROW( CException(sc) );
  167. }
  168. xCat->SetAdviseStatus();
  169. xCat.Acquire();
  170. }
  171. //+---------------------------------------------------------------------------
  172. //
  173. // Member: CClientDocStore::CClientDocStore
  174. //
  175. // Synopsis: Constructor of the CiCDocStore object.
  176. //
  177. // Arguments: [pwszPath] - Path of the directory where the files must be
  178. // created.
  179. // [pwszName] - Name of the Content Index.
  180. //
  181. // History: 12-03-96 srikants Created
  182. // 02-17-98 kitmanh Added code to deal with read-only
  183. // catalogs (the readOnly flag is
  184. // passed down from CiCat to startupInfo)
  185. // 07-Jan-99 klam Logged and event that initialization failed
  186. //
  187. //----------------------------------------------------------------------------
  188. CClientDocStore::CClientDocStore( WCHAR const * pwszPath,
  189. BOOL fOpenForReadOnly,
  190. CDrvNotifArray & DrvNotifArray,
  191. WCHAR const * pwszName )
  192. : _sigClientDocStore(eSigClientDocStore),
  193. _refCount(1),
  194. _state(eUpdatesDisabled),
  195. _pCiCat(0),
  196. _pCiNullCat(0),
  197. _fNoQuery( FALSE ),
  198. _pDrvNotifArray( &DrvNotifArray )
  199. {
  200. ciDebugOut(( DEB_ITRACE, "CClientDocStore::CClinetDocStore.. fOpenForReadOnly == %d\n", fOpenForReadOnly ));
  201. ciDebugOut(( DEB_ITRACE, "CClientDocStore::CClinetDocStore.. pwszPath == %ws\n", pwszPath ));
  202. ciDebugOut(( DEB_ITRACE, "CClientDocStore::CClinetDocStore.. pwszName == %ws\n", pwszName ));
  203. // Check if the catalog directory exists
  204. if ( ( wcslen( pwszPath ) + wcslen( CAT_DIR ) ) >= MAX_PATH )
  205. THROW( CException( STATUS_INVALID_PARAMETER ) );
  206. WCHAR awcCatDir[ MAX_PATH ];
  207. wcscpy( awcCatDir, pwszPath );
  208. wcscat( awcCatDir, CAT_DIR );
  209. WIN32_FILE_ATTRIBUTE_DATA fData;
  210. if ( GetFileAttributesEx( awcCatDir, GetFileExInfoStandard, &fData ) )
  211. {
  212. // Is the catalog path a file or a directory?
  213. if ( 0 == ( fData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY ) )
  214. THROW( CException( HRESULT_FROM_WIN32( ERROR_PATH_NOT_FOUND ) ) );
  215. }
  216. else
  217. {
  218. //
  219. // You can get back both errors depending on what parts of the
  220. // directory tree currently exist.
  221. //
  222. if ( ( ERROR_FILE_NOT_FOUND == GetLastError() ) ||
  223. ( ERROR_PATH_NOT_FOUND == GetLastError() ) )
  224. {
  225. // create the catalog directory with proper acls
  226. CMachineAdmin admin;
  227. admin.CreateSubdirs( pwszPath );
  228. }
  229. else
  230. THROW( CException() );
  231. }
  232. BOOL fLeaveCorruptCatalog;
  233. {
  234. // By default, delete corrupt catalogs.
  235. CRegAccess reg( RTL_REGISTRY_CONTROL, wcsRegAdmin );
  236. fLeaveCorruptCatalog = reg.Read( wcsLeaveCorruptCatalog, (ULONG) FALSE );
  237. }
  238. //
  239. // Create the CiCat object.
  240. //
  241. BOOL fVersionChange = FALSE;
  242. _pCiCat = new CiCat( *this,
  243. _workMan,
  244. pwszPath,
  245. fVersionChange,
  246. fOpenForReadOnly,
  247. *_pDrvNotifArray,
  248. pwszName,
  249. fLeaveCorruptCatalog );
  250. XPtr<CiCat> xCat( _pCiCat );
  251. // Create a CDiskFreeStatus object
  252. _xDiskStatus.Set( new CDiskFreeStatus( pwszPath,
  253. xCat->GetRegParams()->GetMinDiskSpaceToLeave() ) );
  254. // Map std props AND others (second param set to false)
  255. _xPropMapper.Set( new CFwPropertyMapper( xCat->GetPidLookupTable(), FALSE ) );
  256. //
  257. // Create the perform counters object. This must be done before
  258. // starting up rest of the content index.
  259. //
  260. Win4Assert( 0 != xCat->GetCatalogName() );
  261. CPerfMon * pPerfMon = new CPerfMon( xCat->GetCatalogName() );
  262. _xPerfMon.Set( pPerfMon );
  263. //
  264. // Create CI Manager object.
  265. //
  266. _CreateCiManager();
  267. xCat->StartupCiFrameWork( _xCiManager.GetPointer() );
  268. //
  269. // Startup content index.
  270. //
  271. ICiStartup * pCiStartup;
  272. SCODE sc = _xCiManager->QueryInterface( IID_ICiStartup,
  273. (void **) &pCiStartup );
  274. XInterface<ICiStartup> xStartup( pCiStartup );
  275. if ( S_OK != sc )
  276. THROW( CException(sc) );
  277. BOOL fFullScanNeeded = FALSE;
  278. CI_STARTUP_INFO startupInfo;
  279. RtlZeroMemory( &startupInfo, sizeof(startupInfo) );
  280. startupInfo.clsidDaemonClientMgr = clsidStorageFilterObject;
  281. startupInfo.startupFlags = CI_CONFIG_ENABLE_INDEXING |
  282. CI_CONFIG_ENABLE_QUERYING ;
  283. if ( xCat->IsReadOnly() )
  284. startupInfo.startupFlags |= CI_CONFIG_READONLY;
  285. if ( xCat->IsCiDataCorrupt() || xCat->IsFsCiDataCorrupt() || fVersionChange )
  286. {
  287. if ( fLeaveCorruptCatalog )
  288. {
  289. Win4Assert( !"leaving corrupt catalog" );
  290. THROW( CException( CI_CORRUPT_CATALOG ) );
  291. }
  292. if ( xCat->IsCiDataCorrupt() ||
  293. xCat->IsFsCiDataCorrupt() )
  294. {
  295. ciDebugOut(( DEB_ERROR, "Persistent CI/FSCI Data Corruption. It will be emptied \n" ));
  296. //Win4Assert( !"Persistent CI/FSCI Data Corruption" );
  297. }
  298. startupInfo.startupFlags |= (ULONG) CI_CONFIG_EMPTY_DATA;
  299. xCat->LogEvent( CCiStatusMonitor::eCiRemoved );
  300. fFullScanNeeded = TRUE;
  301. }
  302. BOOL fAbort = FALSE;
  303. #if CIDBG==1
  304. #if 0
  305. _FillLoadFilesInfo( startupInfo );
  306. #endif // 0
  307. #endif // CIDBG==1
  308. sc = pCiStartup->StartupContentIndex( xCat->GetCatDir(), &startupInfo,0, &fAbort );
  309. #if CIDBG==1
  310. #if 0
  311. if ( SUCCEEDED(sc) )
  312. {
  313. WCHAR wszBackupPath[MAX_PATH];
  314. wcscpy( wszBackupPath, xCat->GetCatDir() );
  315. wcscat( wszBackupPath, L"\\backup");
  316. ICiPersistIncrFile * pIPersist = 0;
  317. sc = _xCiManager->QueryInterface( IID_ICiPersistIncrFile,
  318. (void **) &pIPersist );
  319. Win4Assert( SUCCEEDED(sc) );
  320. _xSaveTest.Set( new CCiSaveTest( wszBackupPath,
  321. pIPersist,
  322. xCat.GetReference() ) );
  323. pIPersist->Release();
  324. }
  325. _ClearLoadFilesInfo( startupInfo );
  326. #endif // 0
  327. #endif // CIDBG==1
  328. if ( FAILED(sc) )
  329. {
  330. if ( !IsCiCorruptStatus( sc ) && sc != CI_INCORRECT_VERSION )
  331. {
  332. ciDebugOut(( DEB_ERROR, "Failed to startupci. Error 0x%X\n", sc ));
  333. xCat->LogEvent ( CCiStatusMonitor::eCiError, sc );
  334. THROW( CException(sc) );
  335. }
  336. if ( fLeaveCorruptCatalog )
  337. {
  338. Win4Assert( !"leaving corrupt catalog" );
  339. THROW( CException( sc ) );
  340. }
  341. ciDebugOut(( DEB_ERROR, "ContentIndex is corrupt. It will be emptied\n" ));
  342. //Win4Assert( !"Startup CI Data Corruption" );
  343. xCat->LogEvent( CCiStatusMonitor::eCiRemoved );
  344. //
  345. // Content Index is corrupt. Ask CI to delete the contentIndex and
  346. // start afresh.
  347. //
  348. startupInfo.startupFlags |= CI_CONFIG_EMPTY_DATA;
  349. sc = pCiStartup->StartupContentIndex( xCat->GetCatDir(),
  350. &startupInfo,
  351. 0,
  352. &fAbort );
  353. if ( FAILED(sc) )
  354. {
  355. THROW( CException(sc) );
  356. }
  357. fFullScanNeeded = TRUE;
  358. }
  359. xCat->ClearCiDataCorrupt();
  360. xCat->InitIf( fLeaveCorruptCatalog );
  361. //
  362. // Optimization - we may want to just force an "add" of the documents in the
  363. // property store rather than a full scan of the corpus.
  364. //
  365. if ( fFullScanNeeded )
  366. xCat->MarkFullScanNeeded();
  367. xCat.Acquire();
  368. }
  369. //+---------------------------------------------------------------------------
  370. //
  371. // Member: CClientDocStore::_CreateCiManager
  372. //
  373. // Synopsis: Creates the CI manager by doing a CoCreateInstance of the
  374. // ICiControl.
  375. //
  376. // History: 1-31-97 srikants Created
  377. //
  378. //----------------------------------------------------------------------------
  379. void CClientDocStore::_CreateCiManager()
  380. {
  381. //
  382. // We have to create the ICiManager also now.
  383. //
  384. ICiControl * pICiControl = 0;
  385. GUID clsIdCiControl = CLSID_CiControl;
  386. SCODE sc = CoCreateInstance( clsIdCiControl,
  387. NULL,
  388. CLSCTX_INPROC_SERVER,
  389. IID_ICiControl,
  390. (void **) &pICiControl );
  391. if ( 0 == pICiControl )
  392. {
  393. ciDebugOut(( DEB_ERROR, "Cannot CoCreateInstance IID_ICiControl. Error (0x%X)\n",
  394. sc ));
  395. THROW( CException(sc) );
  396. }
  397. XInterface<ICiControl> xCiControl( pICiControl );
  398. ICiManager * pICiManager = 0;
  399. sc = xCiControl->CreateContentIndex( this, &pICiManager );
  400. if ( 0 == pICiManager )
  401. {
  402. ciDebugOut(( DEB_ERROR, "Cannot Get ContentIndex. Error 0x%X\n",
  403. sc ));
  404. THROW( CException(sc) );
  405. }
  406. _xCiManager.Set( pICiManager );
  407. } //_CreateCiManager
  408. //+---------------------------------------------------------------------------
  409. //
  410. // Member: CClientDocStore::~CClientDocStore
  411. //
  412. // Synopsis: Destructor of the client document store.
  413. //
  414. // History: 12-03-96 srikants Created
  415. //
  416. //----------------------------------------------------------------------------
  417. CClientDocStore::~CClientDocStore()
  418. {
  419. delete _pCiCat;
  420. delete _pCiNullCat;
  421. }
  422. //+---------------------------------------------------------------------------
  423. //
  424. // Member: CClientDocStore::IsPropertyCached
  425. //
  426. // Synopsis: Tests if the given property is cached in the property
  427. // store or not.
  428. //
  429. // Arguments: [pPropSpec] - Property to test.
  430. // [pfValue] - Set to TRUE if cached; FALSE o/w
  431. //
  432. // Returns: S_OK if successful;
  433. // Some other error code if not in a valid state.
  434. //
  435. // History: 12-03-96 srikants Created
  436. //
  437. //----------------------------------------------------------------------------
  438. STDMETHODIMP CClientDocStore::IsPropertyCached(
  439. const FULLPROPSPEC * pPropSpec,
  440. BOOL * pfValue )
  441. {
  442. Win4Assert( 0 != pfValue );
  443. Win4Assert( 0 != pPropSpec );
  444. Win4Assert( 0 != _pCiCat );
  445. CFullPropSpec const & ps = *((CFullPropSpec const *) pPropSpec);
  446. SCODE sc = S_OK;
  447. TRY
  448. {
  449. *pfValue = _pCiCat->IsPropertyCached( ps );
  450. }
  451. CATCH( CException, e )
  452. {
  453. sc = e.GetErrorCode();
  454. }
  455. END_CATCH
  456. return sc;
  457. }
  458. //+---------------------------------------------------------------------------
  459. //
  460. // Function: StoreProperty
  461. //
  462. // Synopsis: Stores the given property for the workid.
  463. //
  464. // Arguments: [workid] - WorkId of the document
  465. // [pPropSpec] - Property to be stored
  466. // [pPropVariant] - Value of the property
  467. //
  468. // Returns: S_OK if successful
  469. // CI_E_PROPERTY_NOT_CACHED if it is not a cached property.
  470. // Other error code
  471. //
  472. // History: 12-03-96 srikants Created
  473. //
  474. //----------------------------------------------------------------------------
  475. STDMETHODIMP CClientDocStore::StoreProperty(
  476. WORKID workid,
  477. const FULLPROPSPEC * pPropSpec,
  478. const PROPVARIANT * pPropVariant )
  479. {
  480. Win4Assert( 0 != pPropSpec );
  481. Win4Assert( 0 != pPropVariant );
  482. Win4Assert( 0 != _pCiCat );
  483. CFullPropSpec const & ps = *((CFullPropSpec const *) pPropSpec);
  484. CStorageVariant const & var = *(ConvertToStgVariant( pPropVariant ));
  485. SCODE sc = S_OK;
  486. TRY
  487. {
  488. BOOL fStored = _pCiCat->StoreValue( workid, ps, var );
  489. if ( !fStored )
  490. sc = CI_E_PROPERTY_NOT_CACHED;
  491. }
  492. CATCH( CException, e )
  493. {
  494. sc = e.GetErrorCode();
  495. }
  496. END_CATCH
  497. return sc;
  498. }
  499. //+---------------------------------------------------------------------------
  500. //
  501. // Member: CClientDocStore::FlushPropertyStore
  502. //
  503. // Synopsis: Causes the property store to flush.
  504. //
  505. // History: 06-30-97 KrishnaN Created
  506. //
  507. //----------------------------------------------------------------------------
  508. STDMETHODIMP CClientDocStore::FlushPropertyStore (void)
  509. {
  510. SCODE sc = S_OK;
  511. Win4Assert(_pCiCat);
  512. TRY
  513. {
  514. //
  515. // Flushing the property store at this point (just before a shadow
  516. // merge) is necessary for Push model filtering, but not for clients
  517. // like fsci that do Pull model filtering. The changelog,
  518. // scopetable, and property store are already tightly linked and
  519. // flushed appropriately.
  520. //
  521. // _pCiCat->FlushPropertyStore();
  522. }
  523. CATCH( CException, e)
  524. {
  525. sc = e.GetErrorCode();
  526. }
  527. END_CATCH
  528. return sc;
  529. }
  530. //+---------------------------------------------------------------------------
  531. //
  532. // Member: CClientDocStore::GetClientStatus
  533. //
  534. // Synopsis: Retrieves the client status information
  535. //
  536. // Arguments: [pStatus] - Will have the status information on output.
  537. //
  538. // History: 12-05-96 srikants Created
  539. //
  540. //----------------------------------------------------------------------------
  541. STDMETHODIMP CClientDocStore::GetClientStatus(
  542. CI_CLIENT_STATUS * pStatus )
  543. {
  544. Win4Assert( 0 != pStatus );
  545. SCODE sc = S_OK;
  546. TRY
  547. {
  548. ULONG cPendingScans, state;
  549. if (_pCiNullCat)
  550. _pCiNullCat->CatalogState( pStatus->cDocuments,
  551. cPendingScans,
  552. state );
  553. else
  554. _pCiCat->CatalogState( pStatus->cDocuments,
  555. cPendingScans,
  556. state );
  557. }
  558. CATCH( CException,e )
  559. {
  560. sc = e.GetErrorCode();
  561. }
  562. END_CATCH
  563. return sc;
  564. }
  565. //+---------------------------------------------------------------------------
  566. //
  567. // Member: CClientDocStore::GetContentIndex
  568. //
  569. // Synopsis: Returns the ICiManager if there is one and we are not
  570. // in a shutdown sequence.
  571. //
  572. // Arguments: [ppICiManager] - ICiManager pointer
  573. //
  574. //
  575. // Returns: S_OK if successful
  576. // CI_E_SHUTDOWN if shutdown
  577. // CI_E_NOT_INITIALIZED if not yet initialized
  578. //
  579. // History: 12-10-96 srikants Created
  580. //
  581. //----------------------------------------------------------------------------
  582. STDMETHODIMP CClientDocStore::GetContentIndex(
  583. ICiManager ** ppICiManager)
  584. {
  585. Win4Assert( 0 != ppICiManager );
  586. SCODE sc = S_OK;
  587. CLock lock(_mutex);
  588. if ( !_IsShutdown() && _xCiManager.GetPointer() )
  589. {
  590. _xCiManager->AddRef();
  591. *ppICiManager = _xCiManager.GetPointer();
  592. }
  593. else
  594. {
  595. *ppICiManager = 0;
  596. if ( _IsShutdown() )
  597. sc = CI_E_SHUTDOWN;
  598. else sc = CI_E_NOT_INITIALIZED;
  599. }
  600. return sc;
  601. }
  602. //+---------------------------------------------------------------------------
  603. //
  604. // Member: CClientDocStore::EnableUpdates
  605. //
  606. // Synopsis: Enables updates from document store.
  607. //
  608. // History: 12-09-96 srikants Created
  609. //
  610. //----------------------------------------------------------------------------
  611. STDMETHODIMP CClientDocStore::EnableUpdates()
  612. {
  613. SCODE sc = S_OK;
  614. Win4Assert(_pCiCat);
  615. BOOL fEnableUpdateNotifies = FALSE;
  616. TRY
  617. {
  618. // =============================================================
  619. {
  620. CLock lock(_mutex);
  621. if ( _IsShutdown() )
  622. {
  623. ciDebugOut(( DEB_ERROR,
  624. "CClientDocStore::EnableUpdates called after shutdown\n" ));
  625. THROW( CException( CI_E_SHUTDOWN ) );
  626. }
  627. fEnableUpdateNotifies = _AreUpdatesDisabled();
  628. _state = eUpdatesEnabled;
  629. }
  630. // =============================================================
  631. //
  632. // Notifications are not disabled on DisableUpdates and so only scans/usns
  633. // need to be scheduled, which is done by NoLokClearDiskFull
  634. //
  635. if ( fEnableUpdateNotifies )
  636. _pCiCat->NoLokClearDiskFull();
  637. }
  638. CATCH( CException, e )
  639. {
  640. ciDebugOut(( DEB_ERROR,
  641. "CClientDocStore::EnableUpdates caught error (0x%X)\n",
  642. e.GetErrorCode() ));
  643. sc = e.GetErrorCode();
  644. }
  645. END_CATCH
  646. if ( S_OK != sc && fEnableUpdateNotifies )
  647. {
  648. //
  649. // There was a failure while enabling udpates. We must set
  650. // the state back to indicate that updates are not enabled.
  651. //
  652. CLock lock(_mutex);
  653. _LokDisableUpdates();
  654. }
  655. return sc;
  656. }
  657. //+---------------------------------------------------------------------------
  658. //
  659. // Member: CClientDocStore::DisableUpdates
  660. //
  661. // Synopsis: Disables further updates and prevents update notifications
  662. // until enabled via the "EnableUpdates" call.
  663. //
  664. // History: 12-31-96 srikants Created
  665. //
  666. //----------------------------------------------------------------------------
  667. STDMETHODIMP
  668. CClientDocStore::DisableUpdates( BOOL fIncremental,
  669. CI_DISABLE_UPDATE_REASON dwReason )
  670. {
  671. Win4Assert(_pCiCat);
  672. if ( _IsShutdown() )
  673. return CI_E_SHUTDOWN;
  674. SCODE sc = S_OK;
  675. TRY
  676. {
  677. {
  678. CLock lock(_mutex);
  679. _LokDisableUpdates();
  680. }
  681. if ( fIncremental )
  682. {
  683. _pCiCat->MarkIncrScanNeeded();
  684. _pCiCat->NoLokProcessDiskFull();
  685. }
  686. else
  687. {
  688. if ( dwReason == CI_CORRUPT_INDEX )
  689. _pCiCat->HandleError( CI_CORRUPT_DATABASE );
  690. else
  691. {
  692. _pCiCat->MarkFullScanNeeded();
  693. _pCiCat->NoLokProcessDiskFull();
  694. }
  695. }
  696. }
  697. CATCH( CException, e )
  698. {
  699. sc = e.GetErrorCode();
  700. ciDebugOut(( DEB_ERROR,
  701. "Error (0x%X) while disabling updates\n",
  702. sc ));
  703. }
  704. END_CATCH
  705. return sc;
  706. }
  707. //+---------------------------------------------------------------------------
  708. //
  709. // Member: CClientDocStore::ProcessCiDaemonTermination
  710. //
  711. // Synopsis: Processes the death of CiDaemon. Creates a work item to
  712. // restart the filter daemon.
  713. //
  714. // History: 12-23-96 srikants Created
  715. //
  716. //----------------------------------------------------------------------------
  717. STDMETHODIMP CClientDocStore::ProcessCiDaemonTermination( DWORD dwStatus )
  718. {
  719. //
  720. // The CiDaemon process is dead; Just start filtering again.
  721. //
  722. SCODE sc = S_OK;
  723. TRY
  724. {
  725. CStartFilterDaemon * pWorkItem = new CStartFilterDaemon( *this, _workMan );
  726. _workMan.AddToWorkList( pWorkItem );
  727. pWorkItem->AddToWorkQueue();
  728. pWorkItem->Release();
  729. }
  730. CATCH( CException, e)
  731. {
  732. ciDebugOut(( DEB_ERROR,
  733. "Failed to create a work item for start filter daemon. Error 0x%X\n",
  734. e.GetErrorCode() ));
  735. sc = e.GetErrorCode();
  736. }
  737. END_CATCH
  738. return sc;
  739. }
  740. //+---------------------------------------------------------------------------
  741. //
  742. // Member: CClientDocStore::CheckPointChangesFlushed
  743. //
  744. // Synopsis: Processes a changelog flush.
  745. //
  746. // History: 12-23-96 srikants Created
  747. //
  748. //----------------------------------------------------------------------------
  749. STDMETHODIMP CClientDocStore::CheckPointChangesFlushed(
  750. FILETIME ftFlushed,
  751. ULONG cEntries,
  752. USN_FLUSH_INFO const * const *ppUsnEntries)
  753. {
  754. SCODE sc = S_OK;
  755. Win4Assert(_pCiCat);
  756. TRY
  757. {
  758. _pCiCat->ProcessChangesFlush( ftFlushed, cEntries, ppUsnEntries );
  759. }
  760. CATCH( CException,e )
  761. {
  762. ciDebugOut(( DEB_ERROR,
  763. "CheckPointChangesFlushed failed. Error 0x%X\n",
  764. e.GetErrorCode() ));
  765. sc = e.GetErrorCode();
  766. }
  767. END_CATCH
  768. return sc;
  769. }
  770. //+---------------------------------------------------------------------------
  771. //
  772. // Member: CClientDocStore::MarkDocUnReachable
  773. //
  774. // Synopsis: Marks that the document was not reachable when an attempt
  775. // was made to filter it.
  776. //
  777. // Arguments: [wid] - The WORKID which could not be reached.
  778. //
  779. // History: 12-10-96 srikants Created
  780. //
  781. //----------------------------------------------------------------------------
  782. STDMETHODIMP CClientDocStore::MarkDocUnReachable(
  783. WORKID wid )
  784. {
  785. SCODE sc = S_OK;
  786. Win4Assert(_pCiCat);
  787. TRY
  788. {
  789. _pCiCat->MarkUnReachable( wid );
  790. }
  791. CATCH( CException, e )
  792. {
  793. ciDebugOut(( DEB_ERROR,
  794. "CClientDocStore::MarkDocUnReachable caught exception (0x%X)\n",
  795. e.GetErrorCode() ));
  796. sc = e.GetErrorCode();
  797. }
  798. END_CATCH
  799. return sc;
  800. }
  801. //+---------------------------------------------------------------------------
  802. //
  803. // Member: CClientDocStore::StoreSecurity
  804. //
  805. // Synopsis: Stores the given security data for the workid.
  806. //
  807. // Arguments: [wid] - WorkId of the document
  808. // [pbData] - Security data buffer
  809. // [cbData] - NUmber of bytes in the security data buffer
  810. //
  811. // History: 1-15-97 srikants Created
  812. //
  813. // Notes: We may want to eliminate this call and instead have the
  814. // security be stored as a special property.
  815. //
  816. //----------------------------------------------------------------------------
  817. STDMETHODIMP CClientDocStore::StoreSecurity(
  818. WORKID wid,
  819. BYTE const * pbData,
  820. ULONG cbData )
  821. {
  822. SCODE sc = S_OK;
  823. Win4Assert(_pCiCat);
  824. TRY
  825. {
  826. _pCiCat->StoreSecurity( wid, (PSECURITY_DESCRIPTOR) pbData, cbData );
  827. }
  828. CATCH( CException, e )
  829. {
  830. ciDebugOut(( DEB_ERROR,
  831. "CClientDocStore::MarkDocUnReachable caught exception (0x%X)\n",
  832. e.GetErrorCode() ));
  833. sc = e.GetErrorCode();
  834. }
  835. END_CATCH
  836. return sc;
  837. }
  838. //+---------------------------------------------------------------------------
  839. //
  840. // Member: CClientDocStore::IsNoQuery
  841. //
  842. // Synopsis: Check if the docstore is set to NoQuery
  843. //
  844. // Arguments: [fNoQuery] - Output
  845. //
  846. // History: 05-26-98 kitmanh Created
  847. //
  848. //----------------------------------------------------------------------------
  849. STDMETHODIMP CClientDocStore::IsNoQuery(
  850. BOOL * fNoQuery )
  851. {
  852. SCODE sc = S_OK;
  853. if ( !fNoQuery )
  854. sc = STATUS_INVALID_PARAMETER;
  855. else
  856. *fNoQuery = _fNoQuery;
  857. return sc;
  858. }
  859. //+---------------------------------------------------------------------------
  860. //
  861. // Member: CClientDocStore::GetPropertyMapper
  862. //
  863. // Synopsis: Retrieves the interface to IPropertyMapper.
  864. //
  865. // Arguments: [ppIPropertyMapper] - On output, will have the IPropertyMapper.
  866. //
  867. // Returns: S_OK if successful;
  868. // E_NOTIMPL if property mapper is not supported by doc store.
  869. // Other error code if there is a failure.
  870. // Modifies:
  871. //
  872. // History: 12-31-96 srikants Created
  873. //
  874. //----------------------------------------------------------------------------
  875. STDMETHODIMP CClientDocStore::GetPropertyMapper(
  876. IPropertyMapper ** ppIPropertyMapper)
  877. {
  878. SCODE sc = S_OK;
  879. TRY
  880. {
  881. Win4Assert( 0 != _xPropMapper.GetPointer() );
  882. *ppIPropertyMapper = _xPropMapper.GetPointer();
  883. _xPropMapper->AddRef();
  884. }
  885. CATCH( CException, e )
  886. {
  887. ciDebugOut(( DEB_ERROR,
  888. "CClientDocStore::MarkDocUnReachable caught exception (0x%X)\n",
  889. e.GetErrorCode() ));
  890. sc = e.GetErrorCode();
  891. }
  892. END_CATCH
  893. return sc;
  894. }
  895. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  896. // ICiCDocNameToWorkidTranslatorEx methods.
  897. // ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  898. //+---------------------------------------------------------------------------
  899. //
  900. // Member: CClientDocStore::QueryDocName
  901. //
  902. // Synopsis: Creates a new doc name object and returns its interface.
  903. //
  904. // Arguments: [ppICiCDocName] - [out] Will have a pointer to the
  905. // ICiCDocName object filled in.
  906. //
  907. // History: 12-05-96 srikants Created
  908. //
  909. //----------------------------------------------------------------------------
  910. STDMETHODIMP CClientDocStore::QueryDocName(
  911. ICiCDocName ** ppICiCDocName )
  912. {
  913. Win4Assert( 0 != ppICiCDocName );
  914. SCODE sc = S_OK;
  915. TRY
  916. {
  917. *ppICiCDocName = new CCiCDocName;
  918. }
  919. CATCH( CException,e )
  920. {
  921. sc = e.GetErrorCode();
  922. }
  923. END_CATCH
  924. return sc;
  925. }
  926. //+---------------------------------------------------------------------------
  927. //
  928. // Member: CClientDocStore::WorkIdToDocName
  929. //
  930. // Synopsis: Translates a WorkId to a document name.
  931. //
  932. // Arguments: [workid] - [in] WorkId to translate
  933. // [pICiCDocName] - [out] Will be filled in with the document
  934. // name on output.
  935. //
  936. // Returns: S_OK if successfully converted.
  937. // CI_E_BUFFERTOOSMALL if the buffer is not big enough
  938. // Other error code.
  939. //
  940. // History: 12-05-96 srikants Created
  941. //
  942. // Notes: This method may be one of the most frequently called methods.
  943. // Look for optimizations (esp. can the TRY/CATCH be avoided?)
  944. //
  945. //----------------------------------------------------------------------------
  946. STDMETHODIMP CClientDocStore::WorkIdToDocName(
  947. WORKID workid,
  948. ICiCDocName * pICiCDocName )
  949. {
  950. return InternalWorkIdToDocName( workid, pICiCDocName, FALSE );
  951. }
  952. //+---------------------------------------------------------------------------
  953. //
  954. // Member: CClientDocStore::DocNameToWorkId
  955. //
  956. // Synopsis: Converts a document name to a WorkId.
  957. //
  958. // Arguments: [pICiCDocName] - Document Name
  959. // [pWorkid] - [out] Will have the workid on output.
  960. //
  961. // Returns: S_OK if successful; Error code otherwise.
  962. //
  963. // History: 12-05-96 srikants Created
  964. //
  965. //----------------------------------------------------------------------------
  966. STDMETHODIMP CClientDocStore::DocNameToWorkId(
  967. ICiCDocName const * pICiCDocName,
  968. WORKID * pWorkid )
  969. {
  970. SCODE sc = S_OK;
  971. Win4Assert( 0 != pICiCDocName );
  972. Win4Assert( 0 != pWorkid );
  973. TRY
  974. {
  975. CCiCDocName const * pDocName = (CCiCDocName const *) pICiCDocName;
  976. *pWorkid = _pCiCat->PathToWorkId( pDocName->GetPath(), TRUE );
  977. }
  978. CATCH( CException, e )
  979. {
  980. sc = e.GetErrorCode();
  981. }
  982. END_CATCH
  983. return sc;
  984. }
  985. //+---------------------------------------------------------------------------
  986. //
  987. // Member: CClientDocStore::WorkIdToAccurateDocName
  988. //
  989. // Synopsis: Translates a WorkId 'accurately' to a document name.
  990. //
  991. // Arguments: [workid] - [in] WorkId to translate
  992. // [pICiCDocName] - [out] Will be filled in with the document
  993. // name on output.
  994. //
  995. // Returns: S_OK if successfully converted.
  996. // CI_E_BUFFERTOOSMALL if the buffer is not big enough
  997. // Other error code.
  998. //
  999. // History: 31-Dec-1998 KyleP Created
  1000. //
  1001. //----------------------------------------------------------------------------
  1002. STDMETHODIMP CClientDocStore::WorkIdToAccurateDocName(
  1003. WORKID workid,
  1004. ICiCDocName * pICiCDocName )
  1005. {
  1006. return InternalWorkIdToDocName( workid, pICiCDocName, TRUE );
  1007. }
  1008. //+---------------------------------------------------------------------------
  1009. //
  1010. // Member: CClientDocStore::_GetPerfIndex
  1011. //
  1012. // Synopsis: An internal helper function to get the offset of the perfmon
  1013. // counter in the perfmon shared memory.
  1014. //
  1015. // Arguments: [name] - Name of the counter.
  1016. // [index] - Index of the name
  1017. //
  1018. // Returns: TRUE if successfully looked up; FALSE on failure.
  1019. //
  1020. // History: 12-06-96 srikants Created
  1021. //
  1022. //----------------------------------------------------------------------------
  1023. BOOL CClientDocStore::_GetPerfIndex( CI_PERF_COUNTER_NAME name, ULONG & index )
  1024. {
  1025. BOOL fOk= TRUE;
  1026. ULONG offset = 0;
  1027. switch ( name )
  1028. {
  1029. case CI_PERF_NUM_WORDLIST:
  1030. offset = NUM_WORDLIST;
  1031. break;
  1032. case CI_PERF_NUM_PERSISTENT_INDEXES:
  1033. offset = NUM_PERSISTENT_INDEX;
  1034. break;
  1035. case CI_PERF_INDEX_SIZE:
  1036. offset = INDEX_SIZE;
  1037. break;
  1038. case CI_PERF_FILES_TO_BE_FILTERED:
  1039. offset = FILES_TO_BE_FILTERED;
  1040. break;
  1041. case CI_PERF_NUM_UNIQUE_KEY:
  1042. offset = NUM_UNIQUE_KEY;
  1043. break;
  1044. case CI_PERF_RUNNING_QUERIES:
  1045. offset = RUNNING_QUERIES;
  1046. break;
  1047. case CI_PERF_MERGE_PROGRESS:
  1048. offset = MERGE_PROGRESS;
  1049. break;
  1050. case CI_PERF_DOCUMENTS_FILTERED:
  1051. offset = DOCUMENTS_FILTERED;
  1052. break;
  1053. case CI_PERF_NUM_DOCUMENTS:
  1054. offset = NUM_DOCUMENTS;
  1055. break;
  1056. case CI_PERF_TOTAL_QUERIES:
  1057. offset = TOTAL_QUERIES;
  1058. break;
  1059. case CI_PERF_DEFERRED_FILTER_FILES:
  1060. offset = DEFERRED_FILTER_FILES;
  1061. break;
  1062. default:
  1063. fOk = FALSE;
  1064. }
  1065. if ( fOk )
  1066. index = offset + KERNEL_USER_INDEX;
  1067. return fOk;
  1068. }
  1069. //+---------------------------------------------------------------------------
  1070. //
  1071. // Member: CClientDocStore::SetPerfCounterValue
  1072. //
  1073. // Synopsis: Sets the value of the perfmon counter.
  1074. //
  1075. // Arguments: [name] - Name of the counter
  1076. // [value] - Value to be set.
  1077. //
  1078. // Returns: S_OK if a valid perfmon name; E_INVALIDARG if the perfmon
  1079. // name is not correct.
  1080. //
  1081. // History: 12-06-96 srikants Created
  1082. //
  1083. //----------------------------------------------------------------------------
  1084. STDMETHODIMP CClientDocStore::SetPerfCounterValue(
  1085. CI_PERF_COUNTER_NAME name,
  1086. long value )
  1087. {
  1088. // true for the NULL catalog
  1089. if ( _xPerfMon.IsNull() )
  1090. return S_OK;
  1091. SCODE sc = S_OK;
  1092. ULONG index;
  1093. //
  1094. // CPerfMon::Update must not throw.
  1095. //
  1096. if ( _GetPerfIndex( name, index ) )
  1097. _xPerfMon->Update( index, value );
  1098. else
  1099. sc = E_INVALIDARG;
  1100. return sc;
  1101. }
  1102. //+---------------------------------------------------------------------------
  1103. //
  1104. // Member: CClientDocStore::IncrementPerfCounterValue
  1105. //
  1106. // Synopsis: Increments the value of the perfmon counter.
  1107. //
  1108. // Arguments: [name] - Name of the counter
  1109. //
  1110. // Returns: S_OK if a valid perfmon name; E_INVALIDARG if the perfmon
  1111. // name is not correct.
  1112. //
  1113. // History: 1-15-97 dlee Created
  1114. //
  1115. //----------------------------------------------------------------------------
  1116. STDMETHODIMP CClientDocStore::IncrementPerfCounterValue(
  1117. CI_PERF_COUNTER_NAME name )
  1118. {
  1119. // true for the NULL catalog
  1120. if ( _xPerfMon.IsNull() )
  1121. return S_OK;
  1122. SCODE sc = S_OK;
  1123. ULONG index;
  1124. //
  1125. // CPerfMon::Update must not throw.
  1126. //
  1127. if ( _GetPerfIndex( name, index ) )
  1128. _xPerfMon->Increment( index );
  1129. else
  1130. sc = E_INVALIDARG;
  1131. return sc;
  1132. }
  1133. //+---------------------------------------------------------------------------
  1134. //
  1135. // Member: CClientDocStore::DecrementPerfCounterValue
  1136. //
  1137. // Synopsis: Decrements the value of the perfmon counter.
  1138. //
  1139. // Arguments: [name] - Name of the counter
  1140. //
  1141. // Returns: S_OK if a valid perfmon name; E_INVALIDARG if the perfmon
  1142. // name is not correct.
  1143. //
  1144. // History: 1-15-97 dlee Created
  1145. //
  1146. //----------------------------------------------------------------------------
  1147. STDMETHODIMP CClientDocStore::DecrementPerfCounterValue(
  1148. CI_PERF_COUNTER_NAME name )
  1149. {
  1150. // true for the NULL catalog
  1151. if ( _xPerfMon.IsNull() )
  1152. return S_OK;
  1153. SCODE sc = S_OK;
  1154. ULONG index;
  1155. //
  1156. // CPerfMon::Update must not throw.
  1157. //
  1158. if ( _GetPerfIndex( name, index ) )
  1159. _xPerfMon->Decrement( index );
  1160. else
  1161. sc = E_INVALIDARG;
  1162. return sc;
  1163. } //DecrementPerfCounterValue
  1164. //+---------------------------------------------------------------------------
  1165. //
  1166. // Member: CClientDocStore::GetPerfCounterValue
  1167. //
  1168. // Synopsis: Retrieves the value of the perfmon counter.
  1169. //
  1170. // Arguments: [name] - [see SetPerfCounterValue]
  1171. // [pValue] - "
  1172. //
  1173. // History: 12-06-96 srikants Created
  1174. //
  1175. //----------------------------------------------------------------------------
  1176. STDMETHODIMP CClientDocStore::GetPerfCounterValue(
  1177. CI_PERF_COUNTER_NAME name,
  1178. long * pValue )
  1179. {
  1180. // true for the NULL catalog
  1181. if ( _xPerfMon.IsNull() )
  1182. return S_OK;
  1183. Win4Assert( pValue );
  1184. ULONG index;
  1185. SCODE sc = S_OK;
  1186. if ( _GetPerfIndex( name, index ) )
  1187. *pValue = _xPerfMon->GetCurrValue( index );
  1188. else
  1189. sc = E_INVALIDARG;
  1190. return sc;
  1191. }
  1192. //+------------------------------------------------------
  1193. //
  1194. // Member: CClientDocStore::NotifyEvent
  1195. //
  1196. // Synopsis: Reports the passed in event and arguments to eventlog
  1197. //
  1198. // Arguments: [fType ] - Type of event
  1199. // [eventId] - Message file event identifier
  1200. // [nParams] - Number of substitution arguments being passed
  1201. // [aParams] - pointer to PROPVARIANT array of substitution args.
  1202. // [cbData ] - number of bytes in supplemental raw data.
  1203. // [data ] - pointer to block of supplemental data.
  1204. //
  1205. // Returns: S_OK upon success, value of the exception if an exception
  1206. // is thrown.
  1207. //
  1208. // History: 12-30-96 mohamedn Created
  1209. //
  1210. //----------------------------------------------------------------------------
  1211. STDMETHODIMP CClientDocStore::NotifyEvent( WORD fType,
  1212. DWORD eventId,
  1213. ULONG nParams,
  1214. const PROPVARIANT *aParams,
  1215. ULONG cbData,
  1216. void* data)
  1217. {
  1218. SCODE sc = S_OK;
  1219. TRY
  1220. {
  1221. CClientNotifyEvent notifyEvent(fType,eventId,nParams,aParams,cbData,data);
  1222. }
  1223. CATCH( CException,e )
  1224. {
  1225. ciDebugOut(( DEB_ERROR, "Exception 0x%X in CClientDocStore::NotifyEvent()\n",
  1226. e.GetErrorCode() ));
  1227. sc = e.GetErrorCode();
  1228. }
  1229. END_CATCH
  1230. return sc;
  1231. }
  1232. //+---------------------------------------------------------------------------
  1233. //
  1234. // Member: CClientDocStore::NotifyStatus
  1235. //
  1236. // Synopsis: When a special status is being notified.
  1237. //
  1238. // Returns: S_OK always.
  1239. //
  1240. // History: 12-05-96 srikants Created
  1241. //
  1242. //----------------------------------------------------------------------------
  1243. STDMETHODIMP CClientDocStore::NotifyStatus(
  1244. CI_NOTIFY_STATUS_VALUE status,
  1245. ULONG nParams,
  1246. const PROPVARIANT * aParams )
  1247. {
  1248. SCODE sc = S_OK;
  1249. switch ( status )
  1250. {
  1251. case CI_NOTIFY_FILTERING_FAILURE:
  1252. Win4Assert( nParams == 1 );
  1253. Win4Assert( aParams[0].vt == VT_I4 || aParams[0].vt == VT_UI4 );
  1254. if ( 1 == nParams )
  1255. _ReportFilteringFailure( aParams[0].ulVal );
  1256. break;
  1257. case CI_NOTIFY_FILTER_TOO_MANY_BLOCKS:
  1258. case CI_NOTIFY_FILTER_EMBEDDING_FAILURE:
  1259. //
  1260. // This is possible in the in-proc filtering because
  1261. // the advise status is provided by docstore for filtering
  1262. // also.
  1263. //
  1264. {
  1265. CStorageFilterObjNotifyStatus notify( this );
  1266. sc = notify.NotifyStatus( status, nParams, aParams );
  1267. }
  1268. break;
  1269. default:
  1270. Win4Assert( !"Invalid Case Stmt" );
  1271. break;
  1272. };
  1273. return sc;
  1274. }
  1275. //
  1276. // IFsCiAdmin methods.
  1277. //
  1278. //+---------------------------------------------------------------------------
  1279. //
  1280. // Member: CClientDocStore::ForceMerge
  1281. //
  1282. // Synopsis: Forces a master merge on the given partition id.
  1283. //
  1284. // History: 2-12-97 srikants Created
  1285. //
  1286. //----------------------------------------------------------------------------
  1287. STDMETHODIMP CClientDocStore::ForceMerge( PARTITIONID partId )
  1288. {
  1289. SCODE sc = S_OK;
  1290. TRY
  1291. {
  1292. if ( 0 == _pCiCat )
  1293. THROW( CException( E_INVALIDARG ) );
  1294. sc = _pCiCat->ForceMerge( partId );
  1295. }
  1296. CATCH( CException,e )
  1297. {
  1298. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::ForceMerge\n",
  1299. e.GetErrorCode() ));
  1300. sc = e.GetErrorCode();
  1301. }
  1302. END_CATCH
  1303. return sc;
  1304. }
  1305. //+---------------------------------------------------------------------------
  1306. //
  1307. // Member: CClientDocStore::AbortMerge
  1308. //
  1309. // Synopsis: Aborts any in-progress merge on the given partition id.
  1310. //
  1311. // History: 2-12-97 srikants Created
  1312. //
  1313. //----------------------------------------------------------------------------
  1314. STDMETHODIMP CClientDocStore::AbortMerge( PARTITIONID partId )
  1315. {
  1316. SCODE sc = S_OK;
  1317. TRY
  1318. {
  1319. if ( 0 == _pCiCat )
  1320. THROW( CException( E_INVALIDARG ) );
  1321. sc = _pCiCat->AbortMerge( partId );
  1322. }
  1323. CATCH( CException,e )
  1324. {
  1325. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::AbortMerge\n",
  1326. e.GetErrorCode() ));
  1327. sc = e.GetErrorCode();
  1328. }
  1329. END_CATCH
  1330. return sc;
  1331. }
  1332. //+---------------------------------------------------------------------------
  1333. //
  1334. // Member: CClientDocStore::CiState
  1335. //
  1336. // Synopsis: Retrieves the CI_STATE information.
  1337. //
  1338. // Arguments: [pCiState] - On output, will contain the cistate data.
  1339. //
  1340. // History: 2-12-97 srikants Created
  1341. //
  1342. //----------------------------------------------------------------------------
  1343. STDMETHODIMP CClientDocStore::CiState( CI_STATE * pCiState )
  1344. {
  1345. SCODE sc = S_OK;
  1346. TRY
  1347. {
  1348. if (_pCiNullCat)
  1349. sc = _pCiNullCat->CiState( *pCiState );
  1350. else
  1351. sc = _pCiCat->CiState( *pCiState );
  1352. }
  1353. CATCH( CException,e )
  1354. {
  1355. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::CiState\n",
  1356. e.GetErrorCode() ));
  1357. sc = e.GetErrorCode();
  1358. }
  1359. END_CATCH
  1360. return sc;
  1361. }
  1362. //+---------------------------------------------------------------------------
  1363. //
  1364. // Member: CClientDocStore::UpdateDocuments
  1365. //
  1366. // Synopsis: Forces a scan on the given root.
  1367. //
  1368. // Arguments: [rootPath] - Root to force a scan on.
  1369. // [flag] - Indicating if this is a full scan or a partial
  1370. // scan.
  1371. //
  1372. // History: 2-12-97 srikants Created
  1373. //
  1374. //----------------------------------------------------------------------------
  1375. STDMETHODIMP CClientDocStore::UpdateDocuments(
  1376. const WCHAR *rootPath,
  1377. ULONG flag )
  1378. {
  1379. SCODE sc = S_OK;
  1380. TRY
  1381. {
  1382. if ( 0 == _pCiCat )
  1383. THROW( CException( E_INVALIDARG ) );
  1384. _pCiCat->UpdateDocuments( rootPath, flag);
  1385. }
  1386. CATCH( CException,e )
  1387. {
  1388. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::UpdateDocuments\n",
  1389. e.GetErrorCode() ));
  1390. sc = e.GetErrorCode();
  1391. }
  1392. END_CATCH
  1393. return sc;
  1394. }
  1395. //+---------------------------------------------------------------------------
  1396. //
  1397. // Member: CClientDocStore::AddScopeToCI
  1398. //
  1399. // Synopsis: Adds the given scope to ContentIndex for indexing.
  1400. //
  1401. // Arguments: [rootPath] - Path to add
  1402. //
  1403. // History: 2-12-97 srikants Created
  1404. //
  1405. //----------------------------------------------------------------------------
  1406. STDMETHODIMP CClientDocStore::AddScopeToCI(
  1407. const WCHAR *rootPath )
  1408. {
  1409. SCODE sc = S_OK;
  1410. TRY
  1411. {
  1412. if ( 0 == _pCiCat )
  1413. THROW( CException( E_INVALIDARG ) );
  1414. _pCiCat->AddScopeToCI( rootPath );
  1415. }
  1416. CATCH( CException,e )
  1417. {
  1418. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::AddScopeToCI\n",
  1419. e.GetErrorCode() ));
  1420. sc = e.GetErrorCode();
  1421. }
  1422. END_CATCH
  1423. return sc;
  1424. }
  1425. //+---------------------------------------------------------------------------
  1426. //
  1427. // Member: CClientDocStore::RemoveScopeFromCI
  1428. //
  1429. // Synopsis: Removes the given scope from CI.
  1430. //
  1431. // Arguments: [rootPath] - Scope to remove.
  1432. //
  1433. // History: 2-12-97 srikants Created
  1434. //
  1435. //----------------------------------------------------------------------------
  1436. STDMETHODIMP CClientDocStore::RemoveScopeFromCI(
  1437. const WCHAR *rootPath )
  1438. {
  1439. SCODE sc = S_OK;
  1440. TRY
  1441. {
  1442. if ( 0 == _pCiCat )
  1443. THROW( CException( E_INVALIDARG ) );
  1444. _pCiCat->RemoveScopeFromCI( rootPath, FALSE );
  1445. }
  1446. CATCH( CException,e )
  1447. {
  1448. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::RemoveScopeFromCI\n",
  1449. e.GetErrorCode() ));
  1450. sc = e.GetErrorCode();
  1451. }
  1452. END_CATCH
  1453. return sc;
  1454. }
  1455. //+---------------------------------------------------------------------------
  1456. //
  1457. // Member: CClientDocStore::BeginCacheTransaction
  1458. //
  1459. // Synopsis: Begins a property cache transaction.
  1460. //
  1461. // Arguments: [pulToken] - Output - Transaction "cookie".
  1462. //
  1463. // History: 2-12-97 srikants Created
  1464. //
  1465. //----------------------------------------------------------------------------
  1466. STDMETHODIMP CClientDocStore::BeginCacheTransaction(
  1467. ULONG_PTR * pulToken )
  1468. {
  1469. SCODE sc = S_OK;
  1470. TRY
  1471. {
  1472. if ( 0 == _pCiCat )
  1473. THROW( CException( E_INVALIDARG ) );
  1474. *pulToken = _pCiCat->BeginCacheTransaction();
  1475. }
  1476. CATCH( CException,e )
  1477. {
  1478. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::BeginCacheTransaction\n",
  1479. e.GetErrorCode() ));
  1480. sc = e.GetErrorCode();
  1481. }
  1482. END_CATCH
  1483. return sc;
  1484. }
  1485. //+---------------------------------------------------------------------------
  1486. //
  1487. // Member: CClientDocStore::SetupCache
  1488. //
  1489. // Synopsis: Sets up the property for storing the property cache.
  1490. //
  1491. // Arguments: [ps] -
  1492. // [vt] -
  1493. // [cbMaxLen] -
  1494. // [ulToken] -
  1495. //
  1496. // History: 2-12-97 srikants Created
  1497. //
  1498. //----------------------------------------------------------------------------
  1499. STDMETHODIMP CClientDocStore::SetupCache(
  1500. const FULLPROPSPEC *ps,
  1501. ULONG vt,
  1502. ULONG cbMaxLen,
  1503. ULONG_PTR ulToken,
  1504. BOOL fCanBeModified,
  1505. DWORD dwStoreLevel)
  1506. {
  1507. Win4Assert(PRIMARY_STORE == dwStoreLevel ||
  1508. SECONDARY_STORE == dwStoreLevel);
  1509. SCODE sc = S_OK;
  1510. TRY
  1511. {
  1512. if ( 0 == _pCiCat )
  1513. THROW( CException( E_INVALIDARG ) );
  1514. CFullPropSpec * pFullPropSpec = (CFullPropSpec *)ps;
  1515. _pCiCat->SetupCache( *pFullPropSpec,
  1516. vt,
  1517. cbMaxLen,
  1518. ulToken,
  1519. fCanBeModified,
  1520. dwStoreLevel );
  1521. }
  1522. CATCH( CException,e )
  1523. {
  1524. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::RemoveVirtualScope\n",
  1525. e.GetErrorCode() ));
  1526. sc = e.GetErrorCode();
  1527. }
  1528. END_CATCH
  1529. return sc;
  1530. }
  1531. //+---------------------------------------------------------------------------
  1532. //
  1533. // Member: CClientDocStore::EndCacheTransaction
  1534. //
  1535. // Synopsis: Ends the property cache transaction.
  1536. //
  1537. // Arguments: [ulToken] -
  1538. // [fCommit] -
  1539. //
  1540. // History: 2-12-97 srikants Created
  1541. //
  1542. //----------------------------------------------------------------------------
  1543. STDMETHODIMP CClientDocStore::EndCacheTransaction(
  1544. ULONG_PTR ulToken,
  1545. BOOL fCommit )
  1546. {
  1547. SCODE sc = S_OK;
  1548. TRY
  1549. {
  1550. if ( 0 == _pCiCat )
  1551. THROW( CException( E_INVALIDARG ) );
  1552. _pCiCat->EndCacheTransaction( ulToken, fCommit );
  1553. }
  1554. CATCH( CException,e )
  1555. {
  1556. ciDebugOut(( DEB_ERROR, "Error 0x%X in CClientDocStore::RemoveVirtualScope\n",
  1557. e.GetErrorCode() ));
  1558. sc = e.GetErrorCode();
  1559. }
  1560. END_CATCH
  1561. return sc;
  1562. }
  1563. //+-------------------------------------------------------------------------
  1564. //
  1565. // Method: CClientDocStore::IsIoHigh, public
  1566. //
  1567. // Returns: S_OK if system is in a high i/o state, S_FALSE if it is not.
  1568. //
  1569. // History: 21-Jul-1998 KyleP Created
  1570. //
  1571. //--------------------------------------------------------------------------
  1572. SCODE CClientDocStore::IsIoHigh( BOOL * pfAbort )
  1573. {
  1574. // Windows XP removed support for the IOCTL we used to measure disk
  1575. // usage.
  1576. return S_FALSE;
  1577. } //IsIoHigh
  1578. //
  1579. // Non-Interface methods.
  1580. //
  1581. //+---------------------------------------------------------------------------
  1582. //
  1583. // Member: CClientDocStore::_StartFiltering
  1584. //
  1585. // Synopsis: Asks the CiManager to start filter daemon and resume
  1586. // filtering.
  1587. //
  1588. // History: 12-09-96 srikants Created
  1589. //
  1590. //----------------------------------------------------------------------------
  1591. void CClientDocStore::_StartFiltering()
  1592. {
  1593. XInterface<ICiManager> xManager;
  1594. // =============================================
  1595. {
  1596. CLock lock(_mutex);
  1597. if ( !_IsShutdown() && _xCiManager.GetPointer() )
  1598. {
  1599. _xCiManager->AddRef();
  1600. xManager.Set( _xCiManager.GetPointer() );
  1601. }
  1602. else
  1603. {
  1604. ciDebugOut(( DEB_WARN,
  1605. "Already Shutdown or CI not started. Cannot start filtering\n" ));
  1606. return;
  1607. }
  1608. }
  1609. // =============================================
  1610. //
  1611. // Get the startup data and serialize it.
  1612. //
  1613. WCHAR const * pwszName = _pCiCat->GetName();
  1614. WCHAR const * pwszCatDir = _pCiCat->GetDriveName();
  1615. CDaemonStartupData startupData( pwszCatDir,
  1616. pwszName );
  1617. ULONG cbData;
  1618. BYTE * pbData = startupData.Serialize( cbData );
  1619. XArray<BYTE> xBuf;
  1620. xBuf.Set(cbData,pbData);
  1621. xManager->StartFiltering( cbData, pbData );
  1622. //
  1623. // Note: Should we be worried about StartFiltering failing ??
  1624. //
  1625. }
  1626. //+---------------------------------------------------------------------------
  1627. //
  1628. // Member: CClientDocStore::Shutdown
  1629. //
  1630. // Synopsis: Intiates a shutdown of the document store and the
  1631. // CiManager associated with the document store.
  1632. //
  1633. // History: 12-05-96 srikants Created
  1634. //
  1635. //----------------------------------------------------------------------------
  1636. void CClientDocStore::Shutdown()
  1637. {
  1638. TRY
  1639. {
  1640. Win4Assert( !_IsShutdown() );
  1641. // =============================================
  1642. {
  1643. CLock lock(_mutex);
  1644. _LokMarkShutdown();
  1645. }
  1646. // =============================================
  1647. #if CIDBG==1
  1648. if ( !_xSaveTest.IsNull() )
  1649. _xSaveTest->InitiateShutdown();
  1650. #endif // CIDBG==1
  1651. if (_pCiNullCat)
  1652. _pCiNullCat->ShutdownPhase1();
  1653. else
  1654. _pCiCat->ShutdownPhase1();
  1655. if ( _xCiManager.GetPointer() )
  1656. {
  1657. _xCiManager->Shutdown();
  1658. _xCiManager.Free();
  1659. }
  1660. #if CIDBG==1
  1661. if ( !_xSaveTest.IsNull() )
  1662. _xSaveTest->WaitForDeath();
  1663. #endif //CIDBG==1
  1664. if (_pCiNullCat)
  1665. _pCiNullCat->ShutdownPhase2();
  1666. else
  1667. _pCiCat->ShutdownPhase2();
  1668. }
  1669. CATCH( CException, e)
  1670. {
  1671. ciDebugOut(( DEB_ERROR, "Error (0x%X) in CClientDocStore::Shutdown\n",
  1672. e.GetErrorCode() ));
  1673. }
  1674. END_CATCH
  1675. }
  1676. //+---------------------------------------------------------------------------
  1677. //
  1678. // Member: CClientDocStore::GetName
  1679. //
  1680. // Synopsis: Gets the catalog name (if any)
  1681. //
  1682. // History: 12-05-96 srikants Created
  1683. //
  1684. //----------------------------------------------------------------------------
  1685. WCHAR const * CClientDocStore::GetName()
  1686. {
  1687. if (_pCiNullCat)
  1688. return _pCiNullCat->GetName();
  1689. else
  1690. return _pCiCat->GetName();
  1691. }
  1692. //+---------------------------------------------------------------------------
  1693. //
  1694. // Member: CClientDocStore::_SetCiCatRecovered
  1695. //
  1696. // Synopsis: Sets that the CiCat is recovered and if updates were
  1697. // enabled by Content Index, it asks CiCat to start scans
  1698. // and notifications.
  1699. //
  1700. // History: 12-09-96 srikants Created
  1701. // 02-25-98 kitmanh if catalog is read-only, don't filter
  1702. //
  1703. // Notes: This method MUST be called in SYSTEM context only. This
  1704. // starts filtering which in turn creates the filter daemon
  1705. // proxy thread and that must be in SYSTEM context.
  1706. //
  1707. //----------------------------------------------------------------------------
  1708. void CClientDocStore::_SetCiCatRecovered()
  1709. {
  1710. Win4Assert( 0 != _pCiCat );
  1711. Win4Assert( !CImpersonateSystem::IsImpersonated() );
  1712. BOOL fEnableFilering = FALSE;
  1713. //don't start filtering if catalog is read-only
  1714. if ( !_pCiCat->IsReadOnly() )
  1715. {
  1716. // ==================================================
  1717. {
  1718. CLock lock(_mutex);
  1719. fEnableFilering = _AreUpdatesEnabled();
  1720. }
  1721. // ==================================================
  1722. //
  1723. // Since CiCat has been recovered fully, filtering can be started
  1724. // if we are running with "indexing" enabled.
  1725. //
  1726. _StartFiltering();
  1727. if ( fEnableFilering )
  1728. _pCiCat->EnableUpdateNotifies();
  1729. }
  1730. }
  1731. //+---------------------------------------------------------------------------
  1732. //
  1733. // Member: CClientDocStore::IsLowOnDiskSpace
  1734. //
  1735. // Synopsis: Returns the status of free space on the disk used by
  1736. // docstore (client) based on the last check.
  1737. //
  1738. // Returns: TRUE if low on free disk space; FALSE o/w
  1739. //
  1740. // History: 12-10-96 srikants Created
  1741. //
  1742. // Notes: This does not actually make an I/O. Just returns an in-memory
  1743. // status.
  1744. //
  1745. //----------------------------------------------------------------------------
  1746. BOOL CClientDocStore::IsLowOnDiskSpace() const
  1747. {
  1748. Win4Assert ( !_xDiskStatus.IsNull() );
  1749. return _xDiskStatus->IsLow();
  1750. }
  1751. //+---------------------------------------------------------------------------
  1752. //
  1753. // Member: CClientDocStore::VerifyIfLowOnDiskSpace
  1754. //
  1755. // Synopsis: Verifies the free disk space situation by making an I/O call
  1756. // to the O/S.
  1757. //
  1758. // Returns: TRUE if disk is getting to be full; FALSE o/w
  1759. //
  1760. // History: 12-10-96 srikants Created
  1761. //
  1762. //----------------------------------------------------------------------------
  1763. BOOL CClientDocStore::VerifyIfLowOnDiskSpace()
  1764. {
  1765. Win4Assert ( !_xDiskStatus.IsNull() );
  1766. _xDiskStatus->UpdateDiskLowInfo();
  1767. return _xDiskStatus->IsLow();
  1768. }
  1769. //+---------------------------------------------------------------------------
  1770. //
  1771. // Member: CClientDocStore::_ReportFilteringFailure
  1772. //
  1773. // Synopsis: Reports that there was filtering failure on the given wid.
  1774. //
  1775. // Arguments: [wid] - Workid which failed to filter.
  1776. //
  1777. // History: 1-24-97 srikants Created
  1778. //
  1779. //----------------------------------------------------------------------------
  1780. void CClientDocStore::_ReportFilteringFailure( WORKID wid )
  1781. {
  1782. ciDebugOut(( DEB_IWARN,
  1783. "Warning: unsuccessful attempts to filter workid 0x%X; "
  1784. "cancelling\n", wid ));
  1785. }
  1786. //+---------------------------------------------------------------------------
  1787. //
  1788. // Member: CClientDocStore::GetQuerySession
  1789. //
  1790. // Synopsis: Returns a query session object
  1791. //
  1792. // Returns: [ppICiCQuerySession] -- Session object is returned here
  1793. //
  1794. // History: 22-Jan-97 SitaramR Created
  1795. //
  1796. //----------------------------------------------------------------------------
  1797. SCODE STDMETHODCALLTYPE CClientDocStore::GetQuerySession( ICiCQuerySession **ppICiCQuerySession)
  1798. {
  1799. SCODE sc = S_OK;
  1800. TRY
  1801. {
  1802. CQuerySession *pQuerySession = _pCiNullCat ? new CQuerySession(*_pCiNullCat) :
  1803. new CQuerySession(*_pCiCat );
  1804. XInterface<CQuerySession> xSession( pQuerySession );
  1805. sc = pQuerySession->QueryInterface( IID_ICiCQuerySession, (void **) ppICiCQuerySession );
  1806. if ( FAILED(sc) ) {
  1807. vqDebugOut(( DEB_ERROR, "GetQuerySession - QI failed 0x%x\n", sc ));
  1808. }
  1809. }
  1810. CATCH( CException,e )
  1811. {
  1812. sc = e.GetErrorCode();
  1813. vqDebugOut(( DEB_ERROR,
  1814. "CClientDocStore::GetQuerySession - Exception caught 0x%x\n",
  1815. sc ));
  1816. }
  1817. END_CATCH
  1818. return sc;
  1819. } //GetQuerySession
  1820. //+-------------------------------------------------------------------------
  1821. //
  1822. // Function: RegisterDLL
  1823. //
  1824. // Synopsis: Calls DllRegisterServer on the fully qualified path
  1825. //
  1826. // History: 19-Jun-97
  1827. //
  1828. //--------------------------------------------------------------------------
  1829. DWORD RegisterDLL( WCHAR const * pwcDLL )
  1830. {
  1831. // All Index Server dlls are currently in system32
  1832. DWORD dwErr = NO_ERROR;
  1833. HINSTANCE hDll = LoadLibraryEx( pwcDLL,
  1834. 0,
  1835. LOAD_WITH_ALTERED_SEARCH_PATH );
  1836. if( 0 != hDll )
  1837. {
  1838. SCODE (STDAPICALLTYPE *pfnDllRegisterServer)();
  1839. pfnDllRegisterServer = (HRESULT (STDAPICALLTYPE *)())
  1840. GetProcAddress(hDll, "DllRegisterServer");
  1841. if ( 0 != pfnDllRegisterServer )
  1842. {
  1843. TRY
  1844. {
  1845. SCODE sc = (*pfnDllRegisterServer)();
  1846. if ( S_OK != sc )
  1847. {
  1848. // no way to map a scode to a win32 error
  1849. dwErr = ERROR_INVALID_FUNCTION;
  1850. }
  1851. }
  1852. CATCH( CException, e )
  1853. {
  1854. Win4Assert( !"DllRegisterServer threw an exception" );
  1855. ciDebugOut(( DEB_ERROR, "caught 0x%x registering '%ws'\n",
  1856. e.GetErrorCode(), pwcDLL ));
  1857. }
  1858. END_CATCH;
  1859. }
  1860. else
  1861. dwErr = GetLastError();
  1862. FreeLibrary( hDll );
  1863. }
  1864. else
  1865. {
  1866. dwErr = GetLastError();
  1867. }
  1868. return dwErr;
  1869. } //RegisterDll
  1870. //+-------------------------------------------------------------------------
  1871. //
  1872. // Function: RegisterKnownDlls
  1873. //
  1874. // Synopsis: Gets the value of the DLL's from the registry and then
  1875. // registers all of them if not done so already.
  1876. //
  1877. // History: 19-Jun-97 t-elainc Created
  1878. //
  1879. //--------------------------------------------------------------------------
  1880. void RegisterKnownDlls()
  1881. {
  1882. static fKnownDllsRegistered = FALSE;
  1883. if ( fKnownDllsRegistered )
  1884. return;
  1885. fKnownDllsRegistered = TRUE;
  1886. TRY
  1887. {
  1888. // get registry value
  1889. HKEY hkey;
  1890. int errorcode = RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1891. wcsRegAdminSubKey,
  1892. 0,
  1893. KEY_QUERY_VALUE |
  1894. KEY_ENUMERATE_SUB_KEYS,
  1895. &hkey );
  1896. if (NO_ERROR == errorcode)
  1897. {
  1898. SRegKey xKey( hkey );
  1899. WCHAR awcPath[4000];
  1900. DWORD cwcPath = sizeof awcPath / sizeof WCHAR;
  1901. int anothererrorcode = RegQueryValueEx( hkey,
  1902. L"DLLsToRegister",
  1903. 0,
  1904. 0,
  1905. (BYTE *)awcPath,
  1906. &cwcPath );
  1907. if (NO_ERROR == anothererrorcode)
  1908. {
  1909. // parse the string
  1910. WCHAR* pwcCurrFile = awcPath;
  1911. //for each file call RegisterDLL
  1912. while ( 0 != *pwcCurrFile )
  1913. {
  1914. RegisterDLL(pwcCurrFile);
  1915. pwcCurrFile += wcslen( pwcCurrFile) + 1;
  1916. }
  1917. }
  1918. }
  1919. }
  1920. CATCH( CException, ex )
  1921. {
  1922. ciDebugOut(( DEB_FORCE, "exception %#x registering dlls\n",
  1923. ex.GetErrorCode() ));
  1924. }
  1925. END_CATCH;
  1926. } //RegisterKnownDlls
  1927. //+-------------------------------------------------------------------------
  1928. //
  1929. // Function: OpenCatalogsOnRemovableDrives
  1930. //
  1931. // Synopsis: Opens the catalogs found on the roots of removable drives
  1932. // that are not yet opened.
  1933. //
  1934. // History: 28-Apr-99 dlee Created.
  1935. //
  1936. //--------------------------------------------------------------------------
  1937. void OpenCatalogsOnRemovableDrives()
  1938. {
  1939. CRegAccess reg( RTL_REGISTRY_CONTROL, wcsRegAdmin );
  1940. if ( 0 == reg.Read( wcsMountRemovableCatalogs,
  1941. CI_AUTO_MOUNT_CATALOGS_DEFAULT ) )
  1942. return;
  1943. // Determine which drives exist in this bitmask
  1944. DWORD dwDriveMask = GetLogicalDrives();
  1945. dwDriveMask >>= 2;
  1946. WCHAR awcPath[5];
  1947. wcscpy( awcPath, L"c:\\" );
  1948. // loop through all the drives c-z
  1949. for ( WCHAR wc = L'C'; wc <= L'Z'; wc++ )
  1950. {
  1951. DWORD dwTemp = ( dwDriveMask & 1 );
  1952. dwDriveMask >>= 1;
  1953. if ( 0 != dwTemp )
  1954. {
  1955. if ( IsRemovableDrive( wc ) )
  1956. {
  1957. awcPath[0] = wc;
  1958. if ( 0 == Catalogs.GetDocStore( awcPath ) )
  1959. Catalogs.TryToStartCatalogOnRemovableVol( wc, g_pFSCIRequestQueue );
  1960. }
  1961. }
  1962. }
  1963. } //OpenCatalogsOnRemovableDrives
  1964. //+-------------------------------------------------------------------------
  1965. //
  1966. // Function: OpenCatalogsInRegistry
  1967. //
  1968. // Synopsis: Opens the catalogs listed in the registry. If there are
  1969. // problems opening a catalog, it is skipped -- no sense
  1970. // bringing down the service over a messed-up registry entry.
  1971. //
  1972. // History: 10-Oct-96 dlee Created.
  1973. //
  1974. //--------------------------------------------------------------------------
  1975. void OpenCatalogsInRegistry( BOOL fOpenForReadOnly = FALSE )
  1976. {
  1977. //
  1978. // Side effect of starting up -- register dlls
  1979. //
  1980. RegisterKnownDlls();
  1981. ciDebugOut(( DEB_ITRACE, "OpenCatalogsInRegistry: fOpenForReadOnly == %d\n",
  1982. fOpenForReadOnly ));
  1983. HKEY hKey;
  1984. if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  1985. wcsRegCatalogsSubKey,
  1986. 0,
  1987. KEY_QUERY_VALUE |
  1988. KEY_ENUMERATE_SUB_KEYS,
  1989. &hKey ) )
  1990. {
  1991. SRegKey xKey( hKey );
  1992. DWORD iSubKey = 0;
  1993. do
  1994. {
  1995. FILETIME ft;
  1996. WCHAR awcName[MAX_PATH];
  1997. DWORD cwcName = sizeof awcName / sizeof WCHAR;
  1998. LONG err = RegEnumKeyEx( hKey,
  1999. iSubKey,
  2000. awcName,
  2001. &cwcName,
  2002. 0, 0, 0, &ft );
  2003. // either error or end of enumeration
  2004. if ( ERROR_SUCCESS != err )
  2005. break;
  2006. iSubKey++;
  2007. HKEY hCatName;
  2008. if ( ERROR_SUCCESS == RegOpenKeyEx( hKey,
  2009. awcName,
  2010. 0,
  2011. KEY_QUERY_VALUE,
  2012. &hCatName ) )
  2013. {
  2014. SRegKey xCatNameKey( hCatName );
  2015. WCHAR awcPath[MAX_PATH];
  2016. DWORD cbPath = sizeof awcPath;
  2017. if ( ERROR_SUCCESS == RegQueryValueEx( hCatName,
  2018. wcsCatalogLocation,
  2019. 0,
  2020. 0,
  2021. (BYTE *)awcPath,
  2022. &cbPath ) )
  2023. {
  2024. Catalogs.GetNamedOne( awcPath, awcName, fOpenForReadOnly );
  2025. }
  2026. }
  2027. } while ( TRUE );
  2028. }
  2029. OpenCatalogsOnRemovableDrives();
  2030. } //OpenCatalogsInRegistry
  2031. //+-------------------------------------------------------------------------
  2032. //
  2033. // Function: OpenOneCatalog
  2034. //
  2035. // Synopsis: Opens the catalog specified for R/W or R/O.
  2036. // set the fNoQuery flag in the docstore if fNoQuery (passed in)
  2037. // is TRUE
  2038. //
  2039. // Arguments: [wcCatName] -- name of the catalog
  2040. // [fReadOnly] -- opening for readOnly
  2041. // [fNoQuery] -- opening the catalog as NoQuery
  2042. //
  2043. // History: 27-Apr-98 kitmanh Created.
  2044. // 12-May-98 kitmanh Added fNoQuery
  2045. //
  2046. //--------------------------------------------------------------------------
  2047. void OpenOneCatalog( WCHAR const * wcCatName, BOOL fReadOnly, BOOL fNoQuery = FALSE )
  2048. {
  2049. ciDebugOut(( DEB_ITRACE, "OpenOneCatalog\n" ));
  2050. ciDebugOut(( DEB_ITRACE, "fNoQuery is %d\n", fNoQuery ));
  2051. HKEY hKey;
  2052. WCHAR wcsKey[MAX_PATH];
  2053. if ( ( wcslen( wcsRegCatalogsSubKey ) + wcslen( wcCatName ) + 1 ) >= MAX_PATH )
  2054. THROW( CException( STATUS_INVALID_PARAMETER ) );
  2055. wcscpy( wcsKey, wcsRegCatalogsSubKey );
  2056. wcscat( wcsKey, L"\\" );
  2057. wcscat( wcsKey, wcCatName );
  2058. if ( ERROR_SUCCESS == RegOpenKeyEx( HKEY_LOCAL_MACHINE,
  2059. wcsKey,
  2060. 0,
  2061. KEY_QUERY_VALUE,
  2062. &hKey ) )
  2063. {
  2064. SRegKey xKey( hKey );
  2065. WCHAR awcPath[MAX_PATH];
  2066. DWORD cwcPath = sizeof awcPath / sizeof WCHAR;
  2067. if ( ERROR_SUCCESS == RegQueryValueEx( hKey,
  2068. wcsCatalogLocation,
  2069. 0,
  2070. 0,
  2071. (BYTE *)awcPath,
  2072. &cwcPath ) )
  2073. {
  2074. Catalogs.GetNamedOne( awcPath, wcCatName, fReadOnly, fNoQuery );
  2075. }
  2076. }
  2077. } //OpenOneCatalog
  2078. // Mutex and Event to synchronize start, stop, pause and continue
  2079. CStaticMutexSem g_mtxStartStop;
  2080. CEventSem * g_pevtPauseContinue = 0;
  2081. //+-------------------------------------------------------------------------
  2082. //
  2083. // Function: StartCiSvcWork
  2084. //
  2085. // Synopsis: Entry point for doing the CI service work. The thread does
  2086. // not exit until StopCiSvcWork is called.
  2087. //
  2088. // Argument: [DrvNotifArray] -- reference to the only one
  2089. // DriveNotificationArray
  2090. //
  2091. // History: 16-Sep-96 dlee Created.
  2092. // 16-Sep-98 kitmanh Added parameter DrvNotifArray
  2093. //
  2094. //--------------------------------------------------------------------------
  2095. void StartCiSvcWork( CDrvNotifArray & DrvNotifArray )
  2096. {
  2097. TRY
  2098. {
  2099. //
  2100. // This lock is released when cisvc is initialized enough that
  2101. // StopCiSvcWork can safely be called.
  2102. //
  2103. CReleasableLock lock( g_mtxStartStop );
  2104. ciDebugOut(( DEB_ITRACE, "StartCiSvcWork got the lock\n" ));
  2105. Catalogs.Init();
  2106. TheFrameworkClientWorkQueue.Init();
  2107. XCom xcom;
  2108. // Create the CRequestQueue here, so it'll stay around for
  2109. // the whole time
  2110. ULONG cMaxCachedServerItems, cMaxSimultaneousRequests,
  2111. cmsDefaultClientTimeout, cMinClientIdleTime, cmsStartupDelay;
  2112. BOOL fMinimizeWorkingSet;
  2113. {
  2114. CRegAccess reg( RTL_REGISTRY_CONTROL, wcsRegAdmin );
  2115. cMaxCachedServerItems = reg.Read( wcsMaxCachedPipes,
  2116. CI_MAX_CACHED_PIPES_DEFAULT,
  2117. CI_MAX_CACHED_PIPES_MIN,
  2118. CI_MAX_CACHED_PIPES_MAX );
  2119. cMaxSimultaneousRequests = reg.Read( wcsMaxSimultaneousRequests,
  2120. CI_MAX_SIMULTANEOUS_REQUESTS_DEFAULT,
  2121. CI_MAX_SIMULTANEOUS_REQUESTS_MIN,
  2122. CI_MAX_SIMULTANEOUS_REQUESTS_MAX );
  2123. cmsDefaultClientTimeout = reg.Read( wcsRequestTimeout,
  2124. CI_REQUEST_TIMEOUT_DEFAULT,
  2125. CI_REQUEST_TIMEOUT_MIN,
  2126. CI_REQUEST_TIMEOUT_MAX );
  2127. fMinimizeWorkingSet = reg.Read( wcsMinimizeWorkingSet,
  2128. (DWORD)CI_MINIMIZE_WORKINGSET_DEFAULT );
  2129. // convert seconds to milliseconds
  2130. cMinClientIdleTime = 1000 * reg.Read( wcsMinClientIdleTime,
  2131. CI_MIN_CLIENT_IDLE_TIME );
  2132. cmsStartupDelay = reg.Read( wcsStartupDelay,
  2133. CI_STARTUP_DELAY_DEFAULT,
  2134. CI_STARTUP_DELAY_MIN,
  2135. CI_STARTUP_DELAY_MAX );
  2136. }
  2137. Catalogs.SetDrvNotifArray( &DrvNotifArray );
  2138. // Create the CRequestQueue here, so it'll stay around for the
  2139. // whole time.
  2140. CRequestQueue queue( cMaxCachedServerItems,
  2141. cMaxSimultaneousRequests,
  2142. cmsDefaultClientTimeout,
  2143. fMinimizeWorkingSet,
  2144. cMinClientIdleTime,
  2145. cmsStartupDelay,
  2146. guidStorageDocStoreLocatorObject );
  2147. g_pFSCIRequestQueue = &queue;
  2148. while ( TRUE )
  2149. {
  2150. // request lock to prevent problems of sequence of
  2151. // net pause, net stop and net start (in any order
  2152. // and combo.)
  2153. if ( !lock.IsHeld() )
  2154. lock.Request();
  2155. ciDebugOut(( DEB_ITRACE, "About to call StartFWCiSvcWork\n" ));
  2156. StartFWCiSvcWork( lock, &queue, *g_pevtPauseContinue);
  2157. ciDebugOut(( DEB_ITRACE, "StartCiSvcWork:: fell out from StartFWCiSvcWork\n" ));
  2158. // In the case where a net pause happened
  2159. // instead of checking IsNetPause and IsNetcontinue, loop thru the
  2160. // dynarray to reopen docstores. and clear the SCarry when done
  2161. // note if array.count == 0, work as normal.
  2162. SCWorkItem * WorkItem;
  2163. WCHAR wcCatName[MAX_PATH];
  2164. if ( !queue.IsShutdown() )
  2165. {
  2166. // something is on the _stateChangeArray to be handled
  2167. for ( unsigned i = 0; i < queue.SCArrayCount(); i++ )
  2168. {
  2169. WorkItem = queue.GetSCItem(i);
  2170. if ( WorkItem->StoppedCat ) {
  2171. wcsncpy( wcCatName, WorkItem->StoppedCat, sizeof wcCatName / sizeof WCHAR );
  2172. wcCatName[ (sizeof wcCatName / sizeof WCHAR) - 1 ] = 0;
  2173. }
  2174. else if ( eNoCatWork != WorkItem->type ) {
  2175. wcsncpy( wcCatName, ( (CClientDocStore *)(WorkItem->pDocStore) )->GetName(), sizeof wcCatName / sizeof WCHAR );
  2176. wcCatName[ (sizeof wcCatName / sizeof WCHAR) - 1 ] = 0;
  2177. }
  2178. switch ( WorkItem->type )
  2179. {
  2180. case eCatRO:
  2181. //flush cat
  2182. if ( !WorkItem->StoppedCat )
  2183. Catalogs.FlushOne( WorkItem->pDocStore );
  2184. else
  2185. Catalogs.RmFromStopArray( wcCatName );
  2186. OpenOneCatalog( wcCatName, TRUE );
  2187. break;
  2188. case eCatW:
  2189. if ( !WorkItem->StoppedCat )
  2190. Catalogs.FlushOne( WorkItem->pDocStore );
  2191. else
  2192. Catalogs.RmFromStopArray( wcCatName );
  2193. OpenOneCatalog( wcCatName, FALSE );
  2194. break;
  2195. case eStopCat:
  2196. if ( !WorkItem->StoppedCat )
  2197. {
  2198. Catalogs.FlushOne( WorkItem->pDocStore );
  2199. ciDebugOut(( DEB_ITRACE, "Catalogs.IsCatStopped( %ws ) == %d\n",
  2200. wcCatName, Catalogs.IsCatStopped( wcCatName ) ));
  2201. }
  2202. break;
  2203. case eNoQuery:
  2204. if ( !WorkItem->StoppedCat )
  2205. Catalogs.FlushOne( WorkItem->pDocStore );
  2206. else
  2207. Catalogs.RmFromStopArray( wcCatName );
  2208. OpenOneCatalog( wcCatName, !(WorkItem->fNoQueryRW), TRUE );
  2209. break;
  2210. case eNetPause:
  2211. case eNetContinue:
  2212. case eNetStop:
  2213. case eNoCatWork:
  2214. // These cases are handled later
  2215. break;
  2216. default:
  2217. Win4Assert( !"The eCisvcActionType specified is unknown" );
  2218. }
  2219. }
  2220. }
  2221. if ( queue.IsNetPause() )
  2222. {
  2223. Win4Assert( !queue.IsNetContinue() );
  2224. Catalogs.ClearStopArray();
  2225. // reset the queue
  2226. queue.ReStart();
  2227. //closecatalog
  2228. Catalogs.Flush();
  2229. OpenCatalogsInRegistry( TRUE ); //reopen catalogs for r/o
  2230. //Win4Assert( !"Done Pausing" );
  2231. }
  2232. // a net continue happened
  2233. else if ( queue.IsNetContinue() )
  2234. {
  2235. Win4Assert( !queue.IsNetPause() );
  2236. Catalogs.ClearStopArray();
  2237. // reset the queue
  2238. queue.ReStart();
  2239. ciDebugOut(( DEB_ITRACE, "YES, net continued*********\n" ));
  2240. ciDebugOut(( DEB_ITRACE, "About to flush catalogs.\n" ));
  2241. //closecatalog
  2242. Catalogs.Flush();
  2243. ciDebugOut(( DEB_ITRACE, "About to OpenCatalogsInRegistry for r/w \n" ));
  2244. OpenCatalogsInRegistry( FALSE ); //reopen catalogs for r/w
  2245. ciDebugOut(( DEB_ITRACE, "Done opening catalogs in registry\n" ));
  2246. //Win4Assert( !"Done Continuing" );
  2247. }
  2248. else
  2249. {
  2250. if ( !( queue.IsShutdown() || queue.IsNetStop() ) )
  2251. queue.ReStart();
  2252. else
  2253. {
  2254. ciDebugOut(( DEB_ITRACE, "StartCisvcWork: Breaking out of the loop and ready to shutdown the service\n" ));
  2255. Catalogs.ClearStopArray();
  2256. break;
  2257. }
  2258. }
  2259. }
  2260. }
  2261. CATCH( CException, ex )
  2262. {
  2263. ciDebugOut(( DEB_WARN, "StartCiSvcWork2 exception error 0x%x\n",
  2264. ex.GetErrorCode() ));
  2265. }
  2266. END_CATCH;
  2267. } //StartCiSvcWork
  2268. //+-------------------------------------------------------------------------
  2269. //
  2270. // Function: StopCiSvcWork
  2271. //
  2272. // Synopsis: Entry point for stopping the CI service work.
  2273. //
  2274. // Arguments: [type] -- type of work to do
  2275. // [wcVol] -- volume letter (for eLockVol only)
  2276. //
  2277. // History: 16-Sep-96 dlee Created.
  2278. // 12-Aug-98 kitmanh Returned an SCODE
  2279. //
  2280. //--------------------------------------------------------------------------
  2281. SCODE StopCiSvcWork( ECiSvcActionType type, WCHAR wcVol )
  2282. {
  2283. ciDebugOut(( DEB_ITRACE, "StopCiSvcWork is trying to get the lock\n" ));
  2284. CReleasableLock lock( g_mtxStartStop );
  2285. ciDebugOut(( DEB_ITRACE, "StopCiSvcWork got the lock\n" ));
  2286. // If the main SCM thread didn't get very far, this will be the case.
  2287. if ( 0 == g_pevtPauseContinue )
  2288. return S_OK;
  2289. g_pevtPauseContinue->Reset();
  2290. SCODE sc = StopFWCiSvcWork( type, &lock, g_pevtPauseContinue, wcVol );
  2291. lock.Release();
  2292. ciDebugOut(( DEB_ITRACE, "StopCiSvcWork.. After StopFwCiSvcWork has returned. type == %d\n", type ));
  2293. // Do not block if shutdown has intialized
  2294. if ( STATUS_TOO_LATE == sc )
  2295. return S_OK;
  2296. // block if pausing or continuing
  2297. if ( eNetStop != type )
  2298. {
  2299. ciDebugOut(( DEB_ITRACE, "StopCiSvcWork.. After StopFwCiSvcWork has returned. Block on g_pevtPauseContinue\n" ));
  2300. g_pevtPauseContinue->Wait();
  2301. lock.Request();
  2302. g_pevtPauseContinue->Reset();
  2303. lock.Release();
  2304. ciDebugOut(( DEB_ITRACE, "StopCiSvcWork.. After StopFwCiSvcWork has returned. Reusme on g_pevtPauseContinue\n" ));
  2305. }
  2306. return sc;
  2307. } //StopCiSvcWork
  2308. //+---------------------------------------------------------------------------
  2309. //
  2310. // Member: CClientDocStore::InternalWorkIdToDocName
  2311. //
  2312. // Synopsis: Translates a WorkId to a document name.
  2313. //
  2314. // Arguments: [workid] - [in] WorkId to translate
  2315. // [pICiCDocName] - [out] Will be filled in with the document
  2316. // name on output.
  2317. // [fAccurate] - Use the slow and accurate call
  2318. //
  2319. // Returns: S_OK if successfully converted.
  2320. // CI_E_BUFFERTOOSMALL if the buffer is not big enough
  2321. // Other error code.
  2322. //
  2323. // History: 31-Dec-1998 KyleP Created
  2324. //
  2325. //----------------------------------------------------------------------------
  2326. SCODE CClientDocStore::InternalWorkIdToDocName( WORKID workid,
  2327. ICiCDocName * pICiCDocName,
  2328. BOOL fAccurate )
  2329. {
  2330. Win4Assert( 0 != pICiCDocName );
  2331. Win4Assert(_pCiCat);
  2332. CCiCDocName * pDocName = (CCiCDocName *) pICiCDocName;
  2333. CLowerFunnyPath funnyPath;
  2334. SCODE sc = S_OK;
  2335. TRY
  2336. {
  2337. //
  2338. // We should avoid a memory copy here. Copy into the CCiCDocName
  2339. // directly. If this turns out to be a performance problem fix
  2340. // it. It isn't now.
  2341. //
  2342. unsigned cwc;
  2343. if ( fAccurate )
  2344. cwc = _pCiCat->WorkIdToAccuratePath( workid, funnyPath );
  2345. else
  2346. cwc = _pCiCat->WorkIdToPath( workid, funnyPath );
  2347. //
  2348. // CiCat::WorkIdToPath makes an EMPTY string when a doc
  2349. // is deleted.
  2350. //
  2351. if ( cwc > 1 )
  2352. {
  2353. // this is not a deleted file.
  2354. pDocName->SetPath( funnyPath.GetActualPath(), cwc );
  2355. }
  2356. else
  2357. {
  2358. // this is a deleted file.
  2359. sc = CI_S_WORKID_DELETED;
  2360. }
  2361. }
  2362. CATCH( CException, e )
  2363. {
  2364. sc = e.GetErrorCode();
  2365. }
  2366. END_CATCH
  2367. return sc;
  2368. }
  2369. //+---------------------------------------------------------------------------
  2370. //
  2371. // Member: CClientDocStore::ClearNonStoragePropertiesForWid
  2372. //
  2373. // Synopsis: Clear non-storage properties from the property storage for wid
  2374. //
  2375. // Arguments: [wid] - workid
  2376. //
  2377. // Returns: S_OK if successful;
  2378. //
  2379. // History: 10-06-2000 kitmanh Created
  2380. //
  2381. //----------------------------------------------------------------------------
  2382. STDMETHODIMP CClientDocStore::ClearNonStoragePropertiesForWid( WORKID wid )
  2383. {
  2384. SCODE sc = S_OK;
  2385. TRY
  2386. {
  2387. _pCiCat->ClearNonStoragePropertiesForWid( wid );
  2388. }
  2389. CATCH( CException, e )
  2390. {
  2391. sc = e.GetErrorCode();
  2392. }
  2393. END_CATCH
  2394. return sc;
  2395. }