Leaked source code of windows server 2003
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.

1518 lines
51 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2002.
  5. //
  6. // File: PrpStMgr.cxx
  7. //
  8. // Contents: A two-level property store.
  9. //
  10. // Classes: CPropStoreManager
  11. //
  12. // History: 24-Oct-1997 KrishnaN Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <prpstmgr.hxx>
  18. #include <propobj.hxx>
  19. #include <eventlog.hxx>
  20. #include <catalog.hxx>
  21. #include <imprsnat.hxx>
  22. #include <propiter.hxx>
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Member: CPropStoreManager::CPropStoreManager, public
  26. //
  27. // Synopsis: Constructs the class.
  28. //
  29. // History: 24-Oct-97 KrishnaN Created.
  30. // 01-Nov-98 KLam Added cMegToLeaveOnDisk to constructor
  31. //
  32. //----------------------------------------------------------------------------
  33. CPropStoreManager::CPropStoreManager( ULONG cMegToLeaveOnDisk )
  34. : _pStorage( 0 ),
  35. _xPrimaryStore( 0 ),
  36. _xSecondaryStore( 0 ),
  37. _dwXctionStoreLevel( INVALID_STORE_LEVEL ),
  38. _cMegToLeaveOnDisk( cMegToLeaveOnDisk )
  39. {
  40. _xPrimaryStore.Set(new CPropertyStore(*this, PRIMARY_STORE));
  41. _xSecondaryStore.Set(new CPropertyStore(*this, SECONDARY_STORE));
  42. }
  43. //+---------------------------------------------------------------------------
  44. //
  45. // Member: CPropStoreManager::CPropStoreManager, public
  46. //
  47. // Synopsis: Constructs the class.
  48. //
  49. // History: 24-Oct-97 KrishnaN Created.
  50. // 01-Nov-98 KLam Added cMegToLeaveOnDisk to constructor
  51. //
  52. //----------------------------------------------------------------------------
  53. CPropStoreManager::CPropStoreManager(CiStorage * pStorage,
  54. CPropertyStore *pPrimaryStore,
  55. CPropertyStore *pSecondaryStore,
  56. ULONG cMegToLeaveOnDisk )
  57. : _pStorage( pStorage ),
  58. _dwXctionStoreLevel( INVALID_STORE_LEVEL ),
  59. _cMegToLeaveOnDisk( cMegToLeaveOnDisk )
  60. {
  61. _xPrimaryStore.Set( pPrimaryStore );
  62. _xSecondaryStore.Set( pSecondaryStore );
  63. }
  64. //+---------------------------------------------------------------------------
  65. //
  66. // Member: CPropStoreManager::~CPropStoreManager, public
  67. //
  68. // Synopsis: Destructs the class.
  69. //
  70. // History: 24-Oct-97 KrishnaN Created.
  71. //
  72. //----------------------------------------------------------------------------
  73. CPropStoreManager::~CPropStoreManager()
  74. {
  75. if ( !_xpsNew.IsNull() )
  76. {
  77. //
  78. // The property stores in xpsnew are owned by the property stores
  79. // in this instance (the one being destructed) of the property
  80. // stores. They're in smart pointers but you can't delete them.
  81. //
  82. _xpsNew->_xPrimaryStore.Acquire();
  83. _xpsNew->_xSecondaryStore.Acquire();
  84. _xpsNew.Free();
  85. }
  86. }
  87. //+---------------------------------------------------------------------------
  88. //
  89. // Member: CPropStoreManager::Empty
  90. //
  91. // Synopsis: Empties out the intitialized members and prepares for a
  92. // re-init.
  93. //
  94. // History: 22-Oct-97 KrishnaN Created
  95. //
  96. //----------------------------------------------------------------------------
  97. void CPropStoreManager::Empty()
  98. {
  99. _xPrimaryStore->Empty();
  100. _xSecondaryStore->Empty();
  101. _pStorage = 0;
  102. }
  103. //+---------------------------------------------------------------------------
  104. //
  105. // Member: CPropStoreManager::FastInit, public
  106. //
  107. // Synopsis: Initialize property store (two-phase construction)
  108. //
  109. // Arguments: [pStorage] -- Storage object.
  110. //
  111. // History: 22-Oct-97 KrishnaN Created
  112. //
  113. //----------------------------------------------------------------------------
  114. void CPropStoreManager::FastInit( CiStorage * pStorage )
  115. {
  116. _pStorage = pStorage;
  117. _xPrimaryStore->FastInit(pStorage);
  118. _xSecondaryStore->FastInit(pStorage);
  119. }
  120. //+---------------------------------------------------------------------------
  121. //
  122. // Member: CPropStoreManager::LongInit
  123. //
  124. // Synopsis: If the propstore was dirty when shut down, run the recovery
  125. // operation.
  126. //
  127. // Arguments: [fWasDirty] -- dirty flag is returned here
  128. // [cInconsistencies] -- returns number of inconsistencies found
  129. // [pfnUpdateCallback]-- Callback to be called to update docs during
  130. // recovery. the prop store has no knowledge of
  131. // doc store, so this callback is needed.
  132. // [pUserData] -- will be echoed back through callback.
  133. //
  134. // Returns:
  135. //
  136. // History: 22-Oct-97 KrishnaN Created
  137. //
  138. // Notes: The propstore is locked for write during recovery, but
  139. // reads are still permitted.
  140. //
  141. //----------------------------------------------------------------------------
  142. void CPropStoreManager::LongInit( BOOL & fWasDirty, ULONG & cInconsistencies,
  143. T_UpdateDoc pfnUpdateCallback, void const *pUserData )
  144. {
  145. //
  146. // If at least one of the two stores is dirty, consider both to be dirty
  147. // and recover from both.
  148. //
  149. ciDebugOut(( DEB_ITRACE, "is primary dirty: %d, is secondary dirty %d\n",
  150. _xPrimaryStore->IsDirty(), _xSecondaryStore->IsDirty() ));
  151. ciDebugOut(( DEB_ITRACE, "is backedup mode: %d\n", IsBackedUpMode() ));
  152. if (IsDirty())
  153. {
  154. _xPrimaryStore->_PropStoreInfo.MarkDirty();
  155. _xSecondaryStore->_PropStoreInfo.MarkDirty();
  156. }
  157. //
  158. // If at least one of them recovered with inconsistencies, both should be
  159. // considered to be corrupt!
  160. //
  161. _xPrimaryStore->LongInit(fWasDirty, cInconsistencies, pfnUpdateCallback, pUserData);
  162. ciDebugOut(( DEB_ITRACE, "fWas, cIncon: %d, %d\n", fWasDirty, cInconsistencies ));
  163. if (fWasDirty && cInconsistencies)
  164. {
  165. // Propstore is considered corrupt. No point attempting recovery on
  166. // secondary.
  167. return;
  168. }
  169. _xSecondaryStore->LongInit(fWasDirty, cInconsistencies, pfnUpdateCallback, pUserData);
  170. ciDebugOut(( DEB_ITRACE, "2nd: fWas, cIncon: %d, %d\n", fWasDirty, cInconsistencies ));
  171. if (fWasDirty && cInconsistencies)
  172. {
  173. // Propstore is still corrupt.
  174. return;
  175. }
  176. // Are both the stores in sync
  177. // First line defense
  178. if (_xPrimaryStore->CountRecordsInUse() != _xSecondaryStore->CountRecordsInUse())
  179. {
  180. Win4Assert(fWasDirty);
  181. cInconsistencies = abs((LONG)_xPrimaryStore->CountRecordsInUse() -
  182. (LONG)_xSecondaryStore->CountRecordsInUse());
  183. return;
  184. }
  185. // We have done our best to recover from a dirty shutdown. However, in at least one
  186. // case (bug 132655), it was detected that there was an inconsistency between the
  187. // two stores. Ensure that we catch such inconsistencies.
  188. if (IsDirty())
  189. {
  190. CPropertyStoreWids iter(*this);
  191. ULONG iRec = 0;
  192. const ULONG cTotal = _xPrimaryStore->CountRecordsInUse();
  193. for ( WORKID wid = iter.WorkId();
  194. !cInconsistencies && wid != widInvalid;
  195. wid = iter.LokNextWorkId() )
  196. {
  197. iRec++;
  198. // get the physical store pointed to by the primary top-level record
  199. CBorrowed BorrowedTopLevel( *(_xSecondaryStore->PhysStore()),
  200. GetSecondaryTopLevelWid(wid),
  201. _xSecondaryStore->RecordsPerPage(),
  202. _xSecondaryStore->RecordSize() );
  203. COnDiskPropertyRecord * prec = BorrowedTopLevel.Get();
  204. if (!prec->IsInUse())
  205. cInconsistencies++;
  206. }
  207. if (cInconsistencies)
  208. return;
  209. }
  210. #if 0 // this is really expensive... CIDBG == 1
  211. else
  212. {
  213. ULONG iRec = 0;
  214. const ULONG cTotal = _xPrimaryStore->CountRecordsInUse();
  215. CPropertyStoreWids iter(*this);
  216. for ( WORKID wid = iter.WorkId(); wid != widInvalid; wid = iter.LokNextWorkId() )
  217. {
  218. iRec++;
  219. // get the physical store pointed to by the primary top-level record
  220. CBorrowed BorrowedTopLevel( *(_xSecondaryStore->PhysStore()),
  221. GetSecondaryTopLevelWid(wid),
  222. _xSecondaryStore->RecordsPerPage(),
  223. _xSecondaryStore->RecordSize() );
  224. COnDiskPropertyRecord * prec = BorrowedTopLevel.Get();
  225. Win4Assert(prec->IsInUse());
  226. }
  227. }
  228. #endif // CIDBG
  229. // All is well. Flush and get on with the business of indexing and searching
  230. Flush();
  231. } //LongInit
  232. //+---------------------------------------------------------------------------
  233. //
  234. // Member: CPropStoreManager::BeginTransaction, public
  235. //
  236. // Synopsis: Begins a schema transaction. Any existing transaction will be
  237. // aborted.
  238. //
  239. // Returns: Token representing transaction.
  240. //
  241. // History: 24-Oct-97 KrishnaN Created.
  242. // 02-Nov-98 KLam Passed _cMegToLeaveOnDisk to
  243. // CPropStoreManager
  244. //
  245. //----------------------------------------------------------------------------
  246. ULONG_PTR CPropStoreManager::BeginTransaction()
  247. {
  248. CLock lock( _mtxWrite );
  249. // we are not committing, so the fixed pids are ignored.
  250. if ( !_xpsNew.IsNull() )
  251. EndTransaction( (ULONG_PTR)_xpsNew.Acquire(), FALSE, pidInvalid, pidInvalid);
  252. ULONG_PTR ulPrimaryXctionToken = _xPrimaryStore->BeginTransaction();
  253. ULONG_PTR ulSecondaryXctionToken = _xSecondaryStore->BeginTransaction();
  254. _xpsNew.Set( new CPropStoreManager( _pStorage,
  255. (CPropertyStore *)ulPrimaryXctionToken,
  256. (CPropertyStore *)ulSecondaryXctionToken,
  257. _cMegToLeaveOnDisk ) );
  258. // init storelevel used in transaction to unknown.
  259. _dwXctionStoreLevel = INVALID_STORE_LEVEL;
  260. return (ULONG_PTR)_xpsNew.GetPointer();
  261. }
  262. //+---------------------------------------------------------------------------
  263. //
  264. // Member: CPropStoreManager::Setup, public
  265. //
  266. // Synopsis: Setup a property description. Property may already exist
  267. // in the cache.
  268. //
  269. // Arguments: [pid] -- Propid
  270. // [vt] -- Datatype of property. VT_VARIANT if unknown.
  271. // [cbMaxLen] -- Soft-maximum length for variable length
  272. // properties. This much space is pre-allocated
  273. // in original record.
  274. // [ulToken] -- Token of transaction
  275. // [fCanBeModified]-- Can the prop meta info be modified once set?
  276. //
  277. // History: 22-Oct-97 KrishnaN Created.
  278. //
  279. //----------------------------------------------------------------------------
  280. void CPropStoreManager::Setup( PROPID pid,
  281. ULONG vt,
  282. DWORD cbMaxLen,
  283. ULONG_PTR ulToken,
  284. BOOL fCanBeModified,
  285. DWORD dwStoreLevel )
  286. {
  287. if ( ulToken != (ULONG_PTR)_xpsNew.GetPointer() )
  288. {
  289. ciDebugOut(( DEB_ERROR, "Transaction mismatch: 0x%x vs. 0x%x\n", ulToken, _xpsNew.GetPointer() ));
  290. THROW( CException( STATUS_TRANSACTION_NO_MATCH ) );
  291. }
  292. //
  293. // Currently we only allow operations on one store during a transaction.
  294. // Remember that or enforce that, as appropriate.
  295. //
  296. if (INVALID_STORE_LEVEL == _dwXctionStoreLevel)
  297. _dwXctionStoreLevel = dwStoreLevel;
  298. else
  299. {
  300. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  301. // should be primary or secondary
  302. if (PRIMARY_STORE != dwStoreLevel && SECONDARY_STORE != dwStoreLevel)
  303. {
  304. THROW( CException( STATUS_TRANSACTION_INVALID_TYPE ) );
  305. }
  306. // should be the same as the first store used in the transaction
  307. if (_dwXctionStoreLevel != dwStoreLevel)
  308. {
  309. THROW( CException( STATUS_TRANSACTION_NO_MATCH ) );
  310. }
  311. }
  312. // Before placing the pid in a store, assert that it doesn't
  313. // exist in the other store.
  314. CLock lock( _mtxWrite );
  315. CPropStoreManager *pStoreMgr = (CPropStoreManager *)ulToken;
  316. if (PRIMARY_STORE == dwStoreLevel)
  317. {
  318. Win4Assert(_xSecondaryStore->CanStore(pid) == FALSE);
  319. if (_xSecondaryStore->CanStore(pid))
  320. {
  321. THROW( CException( STATUS_TRANSACTION_NO_MATCH ) );
  322. }
  323. _xPrimaryStore->Setup(pid, vt, cbMaxLen,
  324. (ULONG_PTR)pStoreMgr->_xPrimaryStore.GetPointer(),
  325. fCanBeModified);
  326. }
  327. else
  328. {
  329. Win4Assert(_xPrimaryStore->CanStore(pid) == FALSE);
  330. if (_xPrimaryStore->CanStore(pid))
  331. {
  332. THROW( CException( STATUS_TRANSACTION_NO_MATCH ) );
  333. }
  334. _xSecondaryStore->Setup(pid, vt, cbMaxLen,
  335. (ULONG_PTR)pStoreMgr->_xSecondaryStore.GetPointer(),
  336. fCanBeModified);
  337. }
  338. }
  339. //+---------------------------------------------------------------------------
  340. //
  341. // Member: CPropStoreManager::EndTransaction, public
  342. //
  343. // Synopsis: End property transaction, and maybe commit changes.
  344. //
  345. // Arguments: [ulToken] -- Token of transaction
  346. // [fCommit] -- TRUE --> Commit transaction
  347. // [pidFixedPrimary] -- Every workid with this pid will move to the
  348. // same workid in the new property cache.
  349. // [pidFixedSecondary] -- Every workid with this pid will move to the
  350. // same workid in the new property cache.
  351. //
  352. // History: 22-Oct-97 KrishnaN Created.
  353. //
  354. //----------------------------------------------------------------------------
  355. void CPropStoreManager::EndTransaction( ULONG_PTR ulToken, BOOL fCommit,
  356. PROPID pidFixedPrimary,
  357. PROPID pidFixedSecondary )
  358. {
  359. Win4Assert(ulToken);
  360. CLock lock( _mtxWrite );
  361. if ( ulToken != (ULONG_PTR)_xpsNew.GetPointer() )
  362. {
  363. ciDebugOut(( DEB_ERROR,
  364. "PropStMgr: Transaction mismatch: 0x%x vs. 0x%x\n",
  365. ulToken, _xpsNew.GetPointer() ));
  366. THROW( CException( STATUS_TRANSACTION_NO_MATCH ) );
  367. }
  368. _xPrimaryStore->EndTransaction((ULONG_PTR)_xpsNew->_xPrimaryStore.GetPointer(),
  369. fCommit, pidFixedPrimary);
  370. _xSecondaryStore->EndTransaction((ULONG_PTR)_xpsNew->_xSecondaryStore.GetPointer(),
  371. fCommit, pidFixedSecondary);
  372. // The primary and secondary ptrs are already deleted in EndTransaction
  373. // calls. Cleanup to reflect them prior to deleting _xpsNew.
  374. _xpsNew->_xPrimaryStore.Acquire();
  375. _xpsNew->_xSecondaryStore.Acquire();
  376. _xpsNew.Free();
  377. } //EndTransaction
  378. //+---------------------------------------------------------------------------
  379. //
  380. // Member: CPropStoreManager::MakeBackupCopy
  381. //
  382. // Synopsis: Makes a backup copy of the property storage. It makes a
  383. // full copy if the pIEnumWorkids is NULL. Otherwise, it makes
  384. // a copy of only the changed workids.
  385. //
  386. // Arguments: [pIProgressEnum] - Progress indication
  387. // [pfAbort] - Caller initiated abort flag
  388. // [dstStorage] - Destination storage to use
  389. // [pIEnumWorkids] - List of workids to copy. If null, all the
  390. // workids are copied.
  391. // [ppFileList] - List of propstore files copied.
  392. //
  393. // History: 22-Oct-97 KrishnaN Created
  394. //
  395. // Notes: Incremental not implemented yet
  396. //
  397. //----------------------------------------------------------------------------
  398. void CPropStoreManager::MakeBackupCopy( IProgressNotify * pIProgressEnum,
  399. BOOL & fAbort,
  400. CiStorage & dstStorage,
  401. ICiEnumWorkids * pIEnumWorkids,
  402. IEnumString **ppFileList )
  403. {
  404. CLock lock( _mtxWrite );
  405. Flush();
  406. // fill in an array of sizes to pass into CCompositeProgressNotifier
  407. DWORD *pdwStoreSizes = new DWORD[2];
  408. pdwStoreSizes[0] = _xPrimaryStore->GetTotalSizeInKB();
  409. pdwStoreSizes[1] = _xSecondaryStore->GetTotalSizeInKB();
  410. CCompositeProgressNotifier ProgressNotifier( pIProgressEnum, pdwStoreSizes );
  411. _xPrimaryStore->MakeBackupCopy(&ProgressNotifier, fAbort, dstStorage,
  412. pIEnumWorkids, ppFileList);
  413. ProgressNotifier.IncrementFinishedComponents();
  414. ICiEnumWorkids *pIEnumSecondaryWorkids = pIEnumWorkids;
  415. _xSecondaryStore->MakeBackupCopy(&ProgressNotifier, fAbort, dstStorage,
  416. pIEnumSecondaryWorkids, ppFileList);
  417. }
  418. //+---------------------------------------------------------------------------
  419. //
  420. // Member: CPropStoreManager::WriteProperty, public
  421. //
  422. // Synopsis: Write a property to the cache.
  423. //
  424. // Arguments: [wid] -- Workid
  425. // [pid] -- Propid
  426. // [var] -- Value
  427. //
  428. // Returns: Scode propagated from underlying store.
  429. //
  430. // History: 24-Oct-97 KrishnaN Created.
  431. //
  432. //----------------------------------------------------------------------------
  433. SCODE CPropStoreManager::WriteProperty( WORKID wid,
  434. PROPID pid,
  435. CStorageVariant const & var )
  436. {
  437. if ( _xPrimaryStore->CanStore( pid ) )
  438. {
  439. return WritePrimaryProperty( wid, pid, var );
  440. }
  441. else
  442. {
  443. CCompositePropRecordForWrites PropRecord( wid, *this, _mtxWrite );
  444. return _xSecondaryStore->WriteProperty( PropRecord.GetSecondaryPropRecord(),
  445. pid,
  446. var,
  447. IsBackedUpMode() );
  448. }
  449. } //WriteProperty
  450. //+---------------------------------------------------------------------------
  451. //
  452. // Member: CPropStoreManager::WriteProperty, public
  453. //
  454. // Synopsis: Write a property to the specified cache.
  455. //
  456. // Arguments: [dwStoreLevle] -- level of the property store to write to
  457. // [PropRecord] -- Previously opened property record.
  458. // [pid] -- Propid
  459. // [var] -- Value
  460. //
  461. // Returns: SCODE propagated from underlying store.
  462. //
  463. // History: 23-Oct-2000 KitmanH Created.
  464. //
  465. //----------------------------------------------------------------------------
  466. SCODE CPropStoreManager::WriteProperty( DWORD dwStoreLevel,
  467. CCompositePropRecordForWrites & PropRecord,
  468. PROPID pid,
  469. CStorageVariant const & var )
  470. {
  471. Win4Assert( PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel );
  472. if ( PRIMARY_STORE == dwStoreLevel )
  473. {
  474. if ( _xPrimaryStore->CanStore( pid ) )
  475. return WritePrimaryProperty( PropRecord, pid, var );
  476. }
  477. else
  478. {
  479. if ( _xSecondaryStore->CanStore( pid ) )
  480. return WriteSecondaryProperty( PropRecord, pid, var );
  481. }
  482. return E_INVALIDARG;
  483. } //WriteProperty
  484. //+---------------------------------------------------------------------------
  485. //
  486. // Member: CPropStoreManager::WritePrimaryProperty, public
  487. //
  488. // Synopsis: Write a property from the cache. Triggers CoTaskMemAlloc
  489. //
  490. // Arguments: [wid] -- Workid
  491. // [pid] -- Propid
  492. // [var] -- Place to return the value
  493. //
  494. // History: 22-Oct-97 KrishnaN Created.
  495. //
  496. //----------------------------------------------------------------------------
  497. SCODE CPropStoreManager::WritePrimaryProperty( WORKID wid,
  498. PROPID pid,
  499. CStorageVariant const & var )
  500. {
  501. CPrimaryPropRecordForWrites PropRecord( wid, *this, _mtxWrite );
  502. return WritePrimaryProperty( PropRecord, pid, var );
  503. }
  504. //+---------------------------------------------------------------------------
  505. //
  506. // Member: CPropStoreManager::WriteProperty, public
  507. //
  508. // Synopsis: Write a property to the cache.
  509. //
  510. // Arguments: [PropRecord] -- Previously opened property record.
  511. // [pid] -- Propid
  512. // [var] -- Value
  513. //
  514. // Returns: Scode propagated from underlying store.
  515. //
  516. // History: 24-Oct-97 KrishnaN Created.
  517. //
  518. //----------------------------------------------------------------------------
  519. SCODE CPropStoreManager::WriteProperty( CCompositePropRecordForWrites & PropRecord,
  520. PROPID pid, CStorageVariant const & var )
  521. {
  522. ciDebugOut(( DEB_PROPSTORE, "WRITE: proprecord = 0x%x, pid = 0x%x, type = %d\n", &PropRecord, pid, var.Type() ));
  523. if (_xPrimaryStore->CanStore(pid))
  524. return _xPrimaryStore->WriteProperty(PropRecord.GetPrimaryPropRecord(), pid, var, IsBackedUpMode() );
  525. else
  526. return _xSecondaryStore->WriteProperty(PropRecord.GetSecondaryPropRecord(), pid, var, IsBackedUpMode() );
  527. }
  528. //+---------------------------------------------------------------------------
  529. //
  530. // Member: CPropStoreManager::WritePrimaryProperty, public
  531. //
  532. // Synopsis: Write a property from the cache. Triggers CoTaskMemAlloc
  533. //
  534. // Arguments: [PropRecord] -- Previously opened property record
  535. // [pid] -- Propid
  536. // [var] -- Place to return the value
  537. //
  538. // History: 17-Mar-98 KrishnaN Created.
  539. //
  540. //----------------------------------------------------------------------------
  541. SCODE CPropStoreManager::WritePrimaryProperty( CCompositePropRecordForWrites & PropRecord,
  542. PROPID pid, CStorageVariant const & var )
  543. {
  544. // Has to be used only to Write pids in the primary store.
  545. Win4Assert(_xPrimaryStore->CanStore(pid) == TRUE);
  546. return _xPrimaryStore->WriteProperty( PropRecord.GetPrimaryPropRecord(), pid, var, IsBackedUpMode() );
  547. }
  548. //+---------------------------------------------------------------------------
  549. //
  550. // Member: CPropStoreManager::WritePrimaryProperty, public
  551. //
  552. // Synopsis: Write a property from the cache. Triggers CoTaskMemAlloc
  553. //
  554. // Arguments: [PropRecord] -- Previously opened property record
  555. // [pid] -- Propid
  556. // [var] -- Place to return the value
  557. //
  558. // History: 17-Mar-98 KrishnaN Created.
  559. //
  560. //----------------------------------------------------------------------------
  561. SCODE CPropStoreManager::WritePrimaryProperty( CPrimaryPropRecordForWrites & PropRecord,
  562. PROPID pid,
  563. CStorageVariant const & var )
  564. {
  565. // Has to be used only to Write pids in the primary store.
  566. Win4Assert(_xPrimaryStore->CanStore(pid) == TRUE);
  567. return _xPrimaryStore->WriteProperty( PropRecord.GetPrimaryPropRecord(), pid, var, IsBackedUpMode() );
  568. }
  569. //+---------------------------------------------------------------------------
  570. //
  571. // Member: CPropStoreManager::WriteSecondaryProperty, public
  572. //
  573. // Synopsis: Write a property from the cache. Triggers CoTaskMemAlloc
  574. //
  575. // Arguments: [PropRecord] -- Previously opened property record
  576. // [pid] -- Propid
  577. // [var] -- Place to return the value
  578. //
  579. // History: 23-Oct-2000 KitmanH Created.
  580. //
  581. //----------------------------------------------------------------------------
  582. SCODE CPropStoreManager::WriteSecondaryProperty( CCompositePropRecordForWrites & PropRecord,
  583. PROPID pid, CStorageVariant const & var )
  584. {
  585. Win4Assert(_xSecondaryStore->CanStore(pid) == TRUE);
  586. return _xSecondaryStore->WriteProperty( PropRecord.GetSecondaryPropRecord(), pid, var, IsBackedUpMode() );
  587. }
  588. //+---------------------------------------------------------------------------
  589. //
  590. // Member: CPropStoreManager::ReadProperty, public
  591. //
  592. // Synopsis: Read a property from the cache.
  593. //
  594. // Arguments: [wid] -- Workid
  595. // [pid] -- Propid
  596. // [pbData] -- Place to return the value
  597. // [pcb] -- On input, the maximum number of bytes to
  598. // write at pbData. On output, the number of
  599. // bytes written if the call was successful,
  600. // else the number of bytes required.
  601. //
  602. // History: 22-Oct-97 KrishnaN Created.
  603. //
  604. //----------------------------------------------------------------------------
  605. BOOL CPropStoreManager::ReadProperty( WORKID wid, PROPID pid,
  606. PROPVARIANT * pbData, unsigned * pcb )
  607. {
  608. unsigned cb = *pcb - sizeof (PROPVARIANT);
  609. BOOL fOk = ReadProperty( wid, pid, *pbData, (BYTE *)(pbData + 1), &cb );
  610. *pcb = cb + sizeof (PROPVARIANT);
  611. return fOk;
  612. }
  613. //+---------------------------------------------------------------------------
  614. //
  615. // Member: CPropStoreManager::ReadProperty, public
  616. //
  617. // Synopsis: Read a property from the cache. Version which uses property
  618. // record.
  619. //
  620. // Arguments: [PropRec] -- Pre-opened property record
  621. // [pid] -- Propid
  622. // [pbData] -- Place to return the value
  623. // [pcb] -- On input, the maximum number of bytes to
  624. // write at pbData. On output, the number of
  625. // bytes written if the call was successful,
  626. // else the number of bytes required.
  627. //
  628. // History: 22-Oct-97 KrishnaN Created.
  629. //
  630. //----------------------------------------------------------------------------
  631. BOOL CPropStoreManager::ReadProperty( CCompositePropRecord & PropRec,
  632. PROPID pid,
  633. PROPVARIANT * pbData,
  634. unsigned * pcb )
  635. {
  636. unsigned cb = *pcb - sizeof (PROPVARIANT);
  637. BOOL fOk = ReadProperty( PropRec, pid, *pbData, (BYTE *)(pbData + 1), &cb );
  638. *pcb = cb + sizeof (PROPVARIANT);
  639. return fOk;
  640. }
  641. //+---------------------------------------------------------------------------
  642. //
  643. // Member: CPropStoreManager::ReadProperty, public
  644. //
  645. // Synopsis: Read a property from the cache. Version which uses property
  646. // record.
  647. //
  648. // Arguments: [PropRec] -- Pre-opened property record
  649. // [pid] -- Propid
  650. // [var] -- Place to return the value
  651. //
  652. // History: 19-Dec-97 dlee Created.
  653. //
  654. //----------------------------------------------------------------------------
  655. BOOL CPropStoreManager::ReadProperty(
  656. CCompositePropRecord & PropRec,
  657. PROPID pid,
  658. PROPVARIANT & var )
  659. {
  660. unsigned cb = 0xFFFFFFFF;
  661. return ReadProperty( PropRec, pid, var, 0, &cb );
  662. }
  663. //+---------------------------------------------------------------------------
  664. //
  665. // Member: CPropStoreManager::ReadProperty, public
  666. //
  667. // Synopsis: Read a property from the cache. Version which uses property
  668. // record.
  669. //
  670. // Arguments: [PropRec] -- Pre-opened property record
  671. // [pid] -- Propid
  672. // [var] -- Place to return the value
  673. //
  674. // History: 19-Dec-97 dlee Created.
  675. //
  676. //----------------------------------------------------------------------------
  677. BOOL CPropStoreManager::ReadProperty(
  678. CPrimaryPropRecord & PropRec,
  679. PROPID pid,
  680. PROPVARIANT & var )
  681. {
  682. unsigned cb = 0xFFFFFFFF;
  683. return ReadProperty( PropRec, pid, var, 0, &cb );
  684. }
  685. //+---------------------------------------------------------------------------
  686. //
  687. // Member: CPropStoreManager::ReadProperty, public
  688. //
  689. // Synopsis: Read a property from the cache. Triggers CoTaskMemAlloc
  690. //
  691. // Arguments: [wid] -- Workid
  692. // [pid] -- Propid
  693. // [var] -- Place to return the value
  694. //
  695. // History: 22-Oct-97 KrishnaN Created.
  696. //
  697. //----------------------------------------------------------------------------
  698. BOOL CPropStoreManager::ReadProperty(
  699. WORKID wid,
  700. PROPID pid,
  701. PROPVARIANT & var )
  702. {
  703. unsigned cb = 0xFFFFFFFF;
  704. return ReadProperty( wid, pid, var, 0, &cb );
  705. }
  706. //+---------------------------------------------------------------------------
  707. //
  708. // Member: CPropStoreManager::ReadProperty, public
  709. //
  710. // Synopsis: Read a property from the cache. Triggers CoTaskMemAlloc
  711. //
  712. // Arguments: [wid] -- Workid
  713. // [pid] -- Propid
  714. // [var] -- Place to return the value
  715. //
  716. // History: 22-Oct-97 KrishnaN Created.
  717. //
  718. //----------------------------------------------------------------------------
  719. BOOL CPropStoreManager::ReadPrimaryProperty( WORKID wid, PROPID pid, PROPVARIANT & var )
  720. {
  721. // Has to be used only to read pids in the primary store.
  722. Win4Assert(_xPrimaryStore->CanStore(pid) == TRUE);
  723. unsigned cb = 0xFFFFFFFF;
  724. BOOL fOk = _xPrimaryStore->ReadProperty( wid, pid, var, 0, &cb );
  725. return fOk;
  726. }
  727. //+---------------------------------------------------------------------------
  728. //
  729. // Member: CPropStoreManager::ReadProperty, public
  730. //
  731. // Synopsis: Read a property from the cache. Separate variable buffer.
  732. //
  733. // Arguments: [wid] -- Workid
  734. // [pid] -- Propid
  735. // [var] -- Variant written here
  736. // [pbExtra] -- Place to store additional pointer(s).
  737. // [pcbExtra] -- On input, the maximum number of bytes to
  738. // write at pbExtra. On output, the number of
  739. // bytes written if the call was successful,
  740. // else the number of bytes required.
  741. //
  742. // History: 24-Oct-97 KrishnaN Created.
  743. //
  744. //----------------------------------------------------------------------------
  745. BOOL CPropStoreManager::ReadProperty( WORKID wid,
  746. PROPID pid,
  747. PROPVARIANT & var,
  748. BYTE * pbExtra,
  749. unsigned * pcbExtra )
  750. {
  751. if ( _xPrimaryStore->CanStore( pid ) )
  752. {
  753. CPrimaryPropRecord PropRecord( wid, *this );
  754. return ReadProperty( PropRecord, pid, var, pbExtra, pcbExtra );
  755. }
  756. else
  757. {
  758. // the constructor seeds the constituent proprecords
  759. // with the right wid, based on the wid we pass in.
  760. CCompositePropRecord PropRecord( wid, *this );
  761. return _xSecondaryStore->ReadProperty( PropRecord.GetSecondaryPropRecord(),
  762. pid, var, pbExtra, pcbExtra);
  763. }
  764. } //ReadProperty
  765. //+---------------------------------------------------------------------------
  766. //
  767. // Member: CPropStoreManager::ReadProperty, public
  768. //
  769. // Synopsis: Read a property from the cache. Separate variable buffer.
  770. // Uses pre-opened property record.
  771. //
  772. // Arguments: [PropRec] -- Pre-opened property record.
  773. // [pid] -- Propid
  774. // [var] -- Variant written here
  775. // [pbExtra] -- Place to store additional pointer(s).
  776. // [pcbExtra] -- On input, the maximum number of bytes to
  777. // write at pbExtra. On output, the number of
  778. // bytes written if the call was successful,
  779. // else the number of bytes required.
  780. //
  781. // History: 03-Apr-96 KyleP Created.
  782. //
  783. //----------------------------------------------------------------------------
  784. BOOL CPropStoreManager::ReadProperty( CCompositePropRecord & PropRecord,
  785. PROPID pid,
  786. PROPVARIANT & var,
  787. BYTE * pbExtra,
  788. unsigned * pcbExtra )
  789. {
  790. if (_xPrimaryStore->CanStore(pid))
  791. {
  792. return _xPrimaryStore->ReadProperty(PropRecord.GetPrimaryPropRecord(),
  793. pid, var, pbExtra, pcbExtra);
  794. }
  795. else
  796. {
  797. return _xSecondaryStore->ReadProperty(PropRecord.GetSecondaryPropRecord(),
  798. pid, var, pbExtra, pcbExtra);
  799. }
  800. }
  801. //+---------------------------------------------------------------------------
  802. //
  803. // Member: CPropStoreManager::ReadProperty, public
  804. //
  805. // Synopsis: Read a property from the cache. Separate variable buffer.
  806. // Uses pre-opened property record.
  807. //
  808. // Arguments: [PropRec] -- Pre-opened property record.
  809. // [pid] -- Propid
  810. // [var] -- Variant written here
  811. // [pbExtra] -- Place to store additional pointer(s).
  812. // [pcbExtra] -- On input, the maximum number of bytes to
  813. // write at pbExtra. On output, the number of
  814. // bytes written if the call was successful,
  815. // else the number of bytes required.
  816. //
  817. // History: 03-Apr-96 KyleP Created.
  818. //
  819. //----------------------------------------------------------------------------
  820. BOOL CPropStoreManager::ReadProperty( CPrimaryPropRecord & PropRecord,
  821. PROPID pid,
  822. PROPVARIANT & var,
  823. BYTE * pbExtra,
  824. unsigned * pcbExtra )
  825. {
  826. Win4Assert( _xPrimaryStore->CanStore(pid) );
  827. return _xPrimaryStore->ReadProperty(PropRecord.GetPrimaryPropRecord(),
  828. pid, var, pbExtra, pcbExtra);
  829. }
  830. //+---------------------------------------------------------------------------
  831. //
  832. // Member: CPropStoreManager::OpenRecord, public
  833. //
  834. // Synopsis: Opens record (for multiple reads)
  835. //
  836. // Arguments: [wid] -- Workid
  837. // [pb] -- Storage for record
  838. //
  839. // Returns: Pointer to open property record. Owned by caller.
  840. //
  841. // History: 03-Apr-96 KyleP Created.
  842. //
  843. //----------------------------------------------------------------------------
  844. CCompositePropRecord * CPropStoreManager::OpenRecord( WORKID wid, BYTE * pb )
  845. {
  846. Win4Assert( sizeof(CCompositePropRecord) <= sizeof_CCompositePropRecord );
  847. return new( pb ) CCompositePropRecord( wid, *this );
  848. }
  849. //+---------------------------------------------------------------------------
  850. //
  851. // Member: CPropStoreManager::CloseRecord, public
  852. //
  853. // Synopsis: Closes record.
  854. //
  855. // Arguments: [pRec] -- Property record
  856. //
  857. // History: 03-Apr-96 KyleP Created.
  858. //
  859. //----------------------------------------------------------------------------
  860. void CPropStoreManager::CloseRecord( CCompositePropRecord * pRec )
  861. {
  862. delete pRec;
  863. }
  864. //+---------------------------------------------------------------------------
  865. //
  866. // Member: CPropStoreManager::OpenPrimaryRecord, public
  867. //
  868. // Synopsis: Opens record (for multiple reads)
  869. //
  870. // Arguments: [wid] -- Workid
  871. // [pb] -- Storage for record
  872. //
  873. // Returns: Pointer to open property record. Owned by caller.
  874. //
  875. // History: 03-Apr-96 KyleP Created.
  876. //
  877. //----------------------------------------------------------------------------
  878. CPrimaryPropRecord * CPropStoreManager::OpenPrimaryRecord( WORKID wid, BYTE * pb )
  879. {
  880. Win4Assert( sizeof(CPrimaryPropRecord) <= sizeof_CPropRecord );
  881. return new( pb ) CPrimaryPropRecord( wid, *this );
  882. }
  883. //+---------------------------------------------------------------------------
  884. //
  885. // Member: CPropStoreManager::CloseRecord, public
  886. //
  887. // Synopsis: Closes record.
  888. //
  889. // Arguments: [pRec] -- Property record
  890. //
  891. // History: 03-Apr-96 KyleP Created.
  892. //
  893. //----------------------------------------------------------------------------
  894. void CPropStoreManager::CloseRecord( CPrimaryPropRecord * pRec )
  895. {
  896. delete pRec;
  897. }
  898. //+---------------------------------------------------------------------------
  899. //
  900. // Member: CPropStoreManager::OpenRecordForWrites, public
  901. //
  902. // Synopsis: Opens record (for multiple writes)
  903. //
  904. // Arguments: [wid] -- Workid
  905. // [pb] -- Storage for record
  906. //
  907. // Returns: Pointer to open property record. Owned by caller.
  908. //
  909. // History: 17-Mar-98 KrishnaN Created.
  910. //
  911. //----------------------------------------------------------------------------
  912. CCompositePropRecordForWrites * CPropStoreManager::OpenRecordForWrites( WORKID wid, BYTE * pb )
  913. {
  914. Win4Assert( sizeof(CCompositePropRecordForWrites) <= sizeof_CCompositePropRecord );
  915. return new( pb ) CCompositePropRecordForWrites( wid, *this, _mtxWrite );
  916. }
  917. //+---------------------------------------------------------------------------
  918. //
  919. // Member: CPropStoreManager::OpenPrimaryRecordForWrites, public
  920. //
  921. // Synopsis: Opens record (for multiple writes)
  922. //
  923. // Arguments: [wid] -- Workid
  924. // [pb] -- Storage for record
  925. //
  926. // Returns: Pointer to open property record. Owned by caller.
  927. //
  928. // History: 17-Mar-98 KrishnaN Created.
  929. //
  930. //----------------------------------------------------------------------------
  931. CPrimaryPropRecordForWrites * CPropStoreManager::OpenPrimaryRecordForWrites( WORKID wid, BYTE * pb )
  932. {
  933. Win4Assert( sizeof(CPrimaryPropRecordForWrites) <= sizeof_CPropRecord );
  934. return new( pb ) CPrimaryPropRecordForWrites( wid, *this, _mtxWrite );
  935. }
  936. //+---------------------------------------------------------------------------
  937. //
  938. // Member: CPropStoreManager::CloseRecord, public
  939. //
  940. // Synopsis: Closes record.
  941. //
  942. // Arguments: [pRec] -- Property record
  943. //
  944. // History: 17-Mar-98 KrishnaN Created.
  945. //
  946. //----------------------------------------------------------------------------
  947. void CPropStoreManager::CloseRecord( CCompositePropRecordForWrites * pRec )
  948. {
  949. delete pRec;
  950. }
  951. //+---------------------------------------------------------------------------
  952. //
  953. // Member: CPropStoreManager::CloseRecord, public
  954. //
  955. // Synopsis: Closes record.
  956. //
  957. // Arguments: [pRec] -- Property record
  958. //
  959. // History: 17-Mar-98 KrishnaN Created.
  960. //
  961. //----------------------------------------------------------------------------
  962. void CPropStoreManager::CloseRecord( CPrimaryPropRecordForWrites * pRec )
  963. {
  964. delete pRec;
  965. }
  966. //+---------------------------------------------------------------------------
  967. //
  968. // Member: CPropStoreManager::DeleteRecord, public
  969. //
  970. // Synopsis: Free a record and any records chained off it.
  971. //
  972. // Arguments: [wid] -- Workid
  973. //
  974. // History: 24-Oct-97 KrishnaN Created.
  975. //
  976. //----------------------------------------------------------------------------
  977. void CPropStoreManager::DeleteRecord( WORKID wid )
  978. {
  979. CLock lock( _mtxWrite );
  980. ciDebugOut(( DEB_PROPSTORE, "DELETE: wid = 0x%x\n", wid ));
  981. //
  982. // Get the secondary store's top-level wid before getting rid
  983. // of the wid in the primary store.
  984. //
  985. //
  986. // The secondary wid can certainly be bogus if we couldn't write
  987. // it to the primary store after allocating it when creating the
  988. // records.
  989. //
  990. WORKID widSec = GetSecondaryTopLevelWid(wid);
  991. if ( widInvalid != widSec && 0 != widSec )
  992. _xSecondaryStore->DeleteRecord( widSec,
  993. IsBackedUpMode() );
  994. _xPrimaryStore->DeleteRecord( wid, IsBackedUpMode() );
  995. }
  996. //+---------------------------------------------------------------------------
  997. //
  998. // Member: CPropStoreManager::Flush
  999. //
  1000. // Synopsis: Flushes the data in the property store and marks it clean.
  1001. //
  1002. // History: 3-20-96 srikants Created
  1003. //
  1004. //----------------------------------------------------------------------------
  1005. void CPropStoreManager::Flush()
  1006. {
  1007. CLock mtxLock( _mtxWrite );
  1008. // Flush both the stores. Only when both are successful
  1009. // do we consider the entire flush to be successful.
  1010. // Don't reset the backup streams until the flush is
  1011. // completely successful.
  1012. BOOL fFlushOK = _xPrimaryStore->Flush();
  1013. if (fFlushOK)
  1014. fFlushOK = _xSecondaryStore->Flush();
  1015. // Reset the primary and the secondary backup stores
  1016. if (fFlushOK)
  1017. {
  1018. if (_xPrimaryStore->BackupStream())
  1019. _xPrimaryStore->BackupStream()->Reset(_xPrimaryStore->GetDesiredBackupSize());
  1020. if (_xSecondaryStore->BackupStream())
  1021. _xSecondaryStore->BackupStream()->Reset(_xSecondaryStore->GetDesiredBackupSize());
  1022. }
  1023. }
  1024. //+---------------------------------------------------------------------------
  1025. //
  1026. // Member: CPropStoreManager::WritePropertyInNewRecord, public
  1027. //
  1028. // Synopsis: Like WriteProperty, but also allocates record.
  1029. //
  1030. // Arguments: [pid] -- Propid to write.
  1031. // [var] -- Property value
  1032. //
  1033. // Returns: Workid of new record.
  1034. //
  1035. // History: 22-Oct-97 KrishnaN Created.
  1036. //
  1037. //----------------------------------------------------------------------------
  1038. WORKID CPropStoreManager::WritePropertyInNewRecord( PROPID pid,
  1039. CStorageVariant const & var )
  1040. {
  1041. CLock lock( _mtxWrite );
  1042. //
  1043. // Get new wids from the primary and the secondary store.
  1044. // Write the property.
  1045. // Increment records in use for both the stores.
  1046. //
  1047. WORKID widPrimary = widInvalid;
  1048. WORKID widSecondary = widInvalid;
  1049. TRY
  1050. {
  1051. widPrimary = _xPrimaryStore->NewWorkId( 1, IsBackedUpMode() );
  1052. widSecondary = _xSecondaryStore->NewWorkId( 1, IsBackedUpMode() );
  1053. }
  1054. CATCH(CException, e)
  1055. {
  1056. // cleanup if widSecondary is invalid
  1057. if (widInvalid == widSecondary && widInvalid != widPrimary)
  1058. _xPrimaryStore->DeleteRecord( widPrimary, IsBackedUpMode() );
  1059. // Let the caller do what it normally does to handle exceptions
  1060. RETHROW();
  1061. }
  1062. END_CATCH
  1063. ciDebugOut(( DEB_PROPSTORE, "New record at primary: %d, secondary: %d\n",
  1064. widPrimary, widSecondary ));
  1065. //
  1066. // The primary's top-level record has a pointer to the
  1067. // top-level record in the secondary store. Fill that now!
  1068. //
  1069. VARIANT newVar;
  1070. newVar.vt = VT_UI4;
  1071. newVar.ulVal = widSecondary;
  1072. CStorageVariant *pVar = CastToStorageVariant(newVar);
  1073. SCODE sc;
  1074. sc = WritePrimaryProperty( widPrimary, pidSecondaryStorage, *pVar );
  1075. if (FAILED(sc))
  1076. THROW(CException(sc));
  1077. sc = WriteProperty( widPrimary, pid, var );
  1078. //
  1079. // DLee add this assert to find out why this is failing sometimes.
  1080. // Did the caller pass a bogus variant?
  1081. //
  1082. Win4Assert( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) != sc );
  1083. if (FAILED(sc))
  1084. THROW(CException(sc));
  1085. _xPrimaryStore->IncRecordsInUse();
  1086. _xSecondaryStore->IncRecordsInUse();
  1087. // To the outside world, the primary wid is the one that matters.
  1088. return widPrimary;
  1089. }
  1090. //
  1091. // get and set parameters
  1092. // If incorrect parameter, default to the primary store.
  1093. //
  1094. //+---------------------------------------------------------------------------
  1095. //
  1096. // Member: CPropStoreManager::SetBackupSize, public
  1097. //
  1098. // Synopsis: Sets backup size for a given property store.
  1099. //
  1100. // Arguments: [ulBackupSizeInPages] -- Size of the backup file.
  1101. // [dwStoreLevel] -- Primary or secondary store?
  1102. //
  1103. // History: 22-Oct-97 KrishnaN Created.
  1104. //
  1105. //----------------------------------------------------------------------------
  1106. void CPropStoreManager::SetBackupSize(ULONG ulBackupSizeInPages,
  1107. DWORD dwStoreLevel)
  1108. {
  1109. if (SECONDARY_STORE == dwStoreLevel)
  1110. _xSecondaryStore->SetBackupSize(ulBackupSizeInPages);
  1111. else
  1112. {
  1113. Win4Assert(PRIMARY_STORE == dwStoreLevel);
  1114. _xPrimaryStore->SetBackupSize(ulBackupSizeInPages);
  1115. }
  1116. }
  1117. //+---------------------------------------------------------------------------
  1118. //
  1119. // Member: CPropStoreManager::GetBackupSize, public
  1120. //
  1121. // Synopsis: Gets backup size of a given property store.
  1122. //
  1123. // Arguments: [dwStoreLevel] -- Primary or secondary store?
  1124. //
  1125. // History: 22-Oct-97 KrishnaN Created.
  1126. //
  1127. //----------------------------------------------------------------------------
  1128. ULONG CPropStoreManager::GetBackupSize(DWORD dwStoreLevel)
  1129. {
  1130. if ( SECONDARY_STORE == dwStoreLevel)
  1131. return _xSecondaryStore->GetActualBackupSize();
  1132. else
  1133. {
  1134. Win4Assert( PRIMARY_STORE == dwStoreLevel);
  1135. return _xPrimaryStore->GetActualBackupSize();
  1136. }
  1137. }
  1138. //+---------------------------------------------------------------------------
  1139. //
  1140. // Member: CPropStoreManager::SetMappedCacheSize, public
  1141. //
  1142. // Synopsis: Gets backup size of a given property store.
  1143. //
  1144. // Arguments: [dwStoreLevel] -- Primary or secondary store?
  1145. //
  1146. // History: 22-Oct-97 KrishnaN Created.
  1147. //
  1148. //----------------------------------------------------------------------------
  1149. void CPropStoreManager::SetMappedCacheSize(ULONG ulPSMappedCache,
  1150. DWORD dwStoreLevel)
  1151. {
  1152. if ( SECONDARY_STORE == dwStoreLevel)
  1153. _xSecondaryStore->SetMappedCacheSize(ulPSMappedCache);
  1154. else
  1155. {
  1156. Win4Assert( PRIMARY_STORE== dwStoreLevel);
  1157. _xPrimaryStore->SetMappedCacheSize(ulPSMappedCache);
  1158. }
  1159. }
  1160. //+---------------------------------------------------------------------------
  1161. //
  1162. // Member: CPropStoreManager::GetMappedCacheSize, public
  1163. //
  1164. // Synopsis: Gets mapped cache size of a given property store.
  1165. //
  1166. // Arguments: [dwStoreLevel] -- Primary or secondary store?
  1167. //
  1168. // History: 22-Oct-97 KrishnaN Created.
  1169. //
  1170. //----------------------------------------------------------------------------
  1171. ULONG CPropStoreManager::GetMappedCacheSize(DWORD dwStoreLevel)
  1172. {
  1173. if (SECONDARY_STORE == dwStoreLevel)
  1174. return _xSecondaryStore->GetMappedCacheSize();
  1175. else
  1176. {
  1177. Win4Assert(PRIMARY_STORE == dwStoreLevel);
  1178. return _xPrimaryStore->GetMappedCacheSize();
  1179. }
  1180. }
  1181. //+---------------------------------------------------------------------------
  1182. //
  1183. // Member: CPropStoreManager::GetTotalSizeInKB, public
  1184. //
  1185. // Synopsis: Gets total size of the property store.
  1186. //
  1187. // Arguments:
  1188. //
  1189. // History: 22-Oct-97 KrishnaN Created.
  1190. //
  1191. //----------------------------------------------------------------------------
  1192. ULONG CPropStoreManager::GetTotalSizeInKB()
  1193. {
  1194. return _xPrimaryStore->GetTotalSizeInKB() +
  1195. _xSecondaryStore->GetTotalSizeInKB();
  1196. }
  1197. PStorage& CPropStoreManager::GetStorage(DWORD dwStoreLevel)
  1198. {
  1199. Win4Assert(&(_xPrimaryStore->GetStorage()) == _pStorage);
  1200. Win4Assert(&(_xSecondaryStore->GetStorage()) == _pStorage);
  1201. return *_pStorage;
  1202. }
  1203. void CPropStoreManager::Shutdown()
  1204. {
  1205. Flush();
  1206. _xPrimaryStore->Shutdown();
  1207. _xSecondaryStore->Shutdown();
  1208. }
  1209. void CPropStoreManager::ClearNonStorageProperties( CCompositePropRecordForWrites & rec )
  1210. {
  1211. _xPrimaryStore->ClearNonStorageProperties( rec );
  1212. _xSecondaryStore->ClearNonStorageProperties( rec );
  1213. }
  1214. // CSvcQuery methods
  1215. //+-------------------------------------------------------------------------
  1216. //
  1217. // Member: CCompositeProgressNotifier::QueryInterface, public
  1218. //
  1219. // Arguments: [ifid] -- Interface id
  1220. // [ppiuk] -- Interface return pointer
  1221. //
  1222. // Returns: Error. No rebind from this class is supported.
  1223. //
  1224. // History: Nov-14-97 KrishnaN Created
  1225. //
  1226. //--------------------------------------------------------------------------
  1227. STDMETHODIMP CCompositeProgressNotifier::QueryInterface(
  1228. REFIID ifid,
  1229. void ** ppiuk )
  1230. {
  1231. if ( IID_IUnknown == ifid )
  1232. {
  1233. AddRef();
  1234. *ppiuk = (void *)((IUnknown *)this);
  1235. return S_OK;
  1236. }
  1237. else
  1238. {
  1239. *ppiuk = 0;
  1240. return E_NOINTERFACE;
  1241. }
  1242. } //QueryInterface
  1243. //+-------------------------------------------------------------------------
  1244. //
  1245. // Member: CCompositeProgressNotifier::AddRef, public
  1246. //
  1247. // Synopsis: Reference the virtual table.
  1248. //
  1249. // History: Nov-14-97 KrishnaN Created
  1250. //
  1251. //--------------------------------------------------------------------------
  1252. STDMETHODIMP_(ULONG) CCompositeProgressNotifier::AddRef()
  1253. {
  1254. InterlockedIncrement( &_ref );
  1255. return (ULONG)_ref;
  1256. } //AddRef
  1257. //+-------------------------------------------------------------------------
  1258. //
  1259. // Member: CCompositeProgressNotifier::Release, public
  1260. //
  1261. // Synopsis: De-Reference the virtual table.
  1262. //
  1263. // Effects: If the ref count goes to 0 then the table is deleted.
  1264. //
  1265. // History: Nov-14-97 KrishnaN Created
  1266. //
  1267. //--------------------------------------------------------------------------
  1268. STDMETHODIMP_(ULONG) CCompositeProgressNotifier::Release()
  1269. {
  1270. unsigned long uTmp = InterlockedDecrement( &_ref );
  1271. if ( 0 == uTmp )
  1272. delete this;
  1273. return(uTmp);
  1274. } //Release
  1275. //+-------------------------------------------------------------------------
  1276. //
  1277. // Member: CCompositeProgressNotifier::OnProgress, public
  1278. //
  1279. // Synopsis: Report progress.
  1280. //
  1281. // Effects: Progress reporting accounts for the presence of multiple
  1282. // independently operating constituents in the property store.
  1283. //
  1284. // History: Nov-14-97 KrishnaN Created
  1285. //
  1286. //--------------------------------------------------------------------------
  1287. STDMETHODIMP CCompositeProgressNotifier::OnProgress
  1288. (
  1289. DWORD dwProgressCurrent,
  1290. DWORD dwProgressMaximum,
  1291. BOOL fAccurate,
  1292. BOOL fOwner
  1293. )
  1294. {
  1295. if (0 == _xComponentProgressNotifier.GetPointer())
  1296. return S_OK;
  1297. Win4Assert(_cFinishedComponents < _cComponents);
  1298. Win4Assert(dwProgressMaximum == _aulMaxSizes[_cFinishedComponents]);
  1299. //
  1300. // Present a unified view of progress reports. The composite progress
  1301. // report is 100% done only when all components are 100% done.
  1302. //
  1303. return _xComponentProgressNotifier->OnProgress
  1304. (dwProgressCurrent*1000/dwProgressMaximum + _dwCumMaxSize,
  1305. _dwTotalMaxSize,
  1306. fAccurate,
  1307. fOwner);
  1308. } //OnProgress