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.

1566 lines
51 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  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::Load
  421. //
  422. // Synopsis: Copies/moves the listed files to the specified directory.
  423. //
  424. // Arguments: [pwszDestinationDirectory] - Destination dir for files
  425. // [pFileList] - Files to be moved/copied
  426. // [pProgressNotify] - Progress notification
  427. // [fCallerOwnsFiles] - If TRUE, should copy; else move
  428. // [pfAbort] - Causes abort when set.
  429. //
  430. // History: 22-Oct-97 KrishnaN Created
  431. // 01-Nov-98 KLam Passed _cMegToLeaveOnDisk to CiStorage
  432. //
  433. // Notes:
  434. //
  435. //----------------------------------------------------------------------------
  436. void CPropStoreManager::Load( WCHAR const * pwszDestDir,
  437. ICiCAdviseStatus * pAdviseStatus,
  438. IEnumString * pFileList,
  439. IProgressNotify * pProgressNotify,
  440. BOOL fCallerOwnsFiles,
  441. BOOL * pfAbort )
  442. {
  443. CLock lock( _mtxWrite );
  444. // This is identical to the CPropertyStore::Load. They both simply copy files.
  445. Win4Assert(pwszDestDir);
  446. Win4Assert(pFileList);
  447. Win4Assert(pfAbort);
  448. ULONG ulFetched;
  449. XPtr<CiStorage> xStorage( new CiStorage( pwszDestDir,
  450. *pAdviseStatus,
  451. _cMegToLeaveOnDisk,
  452. FSCI_VERSION_STAMP ) );
  453. WCHAR * pwszFilePath;
  454. while ( !(*pfAbort) && (S_OK == pFileList->Next(1, &pwszFilePath, &ulFetched)) )
  455. {
  456. xStorage->CopyGivenFile( pwszFilePath, !fCallerOwnsFiles );
  457. }
  458. }
  459. //+---------------------------------------------------------------------------
  460. //
  461. // Member: CPropStoreManager::WriteProperty, public
  462. //
  463. // Synopsis: Write a property to the cache.
  464. //
  465. // Arguments: [wid] -- Workid
  466. // [pid] -- Propid
  467. // [var] -- Value
  468. //
  469. // Returns: Scode propagated from underlying store.
  470. //
  471. // History: 24-Oct-97 KrishnaN Created.
  472. //
  473. //----------------------------------------------------------------------------
  474. SCODE CPropStoreManager::WriteProperty( WORKID wid,
  475. PROPID pid,
  476. CStorageVariant const & var )
  477. {
  478. if ( _xPrimaryStore->CanStore( pid ) )
  479. {
  480. return WritePrimaryProperty( wid, pid, var );
  481. }
  482. else
  483. {
  484. CCompositePropRecordForWrites PropRecord( wid, *this, _mtxWrite );
  485. return _xSecondaryStore->WriteProperty( PropRecord.GetSecondaryPropRecord(),
  486. pid,
  487. var,
  488. IsBackedUpMode() );
  489. }
  490. } //WriteProperty
  491. //+---------------------------------------------------------------------------
  492. //
  493. // Member: CPropStoreManager::WriteProperty, public
  494. //
  495. // Synopsis: Write a property to the specified cache.
  496. //
  497. // Arguments: [dwStoreLevle] -- level of the property store to write to
  498. // [PropRecord] -- Previously opened property record.
  499. // [pid] -- Propid
  500. // [var] -- Value
  501. //
  502. // Returns: SCODE propagated from underlying store.
  503. //
  504. // History: 23-Oct-2000 KitmanH Created.
  505. //
  506. //----------------------------------------------------------------------------
  507. SCODE CPropStoreManager::WriteProperty( DWORD dwStoreLevel,
  508. CCompositePropRecordForWrites & PropRecord,
  509. PROPID pid,
  510. CStorageVariant const & var )
  511. {
  512. Win4Assert( PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel );
  513. if ( PRIMARY_STORE == dwStoreLevel )
  514. {
  515. if ( _xPrimaryStore->CanStore( pid ) )
  516. return WritePrimaryProperty( PropRecord, pid, var );
  517. }
  518. else
  519. {
  520. if ( _xSecondaryStore->CanStore( pid ) )
  521. return WriteSecondaryProperty( PropRecord, pid, var );
  522. }
  523. return E_INVALIDARG;
  524. } //WriteProperty
  525. //+---------------------------------------------------------------------------
  526. //
  527. // Member: CPropStoreManager::WritePrimaryProperty, public
  528. //
  529. // Synopsis: Write a property from the cache. Triggers CoTaskMemAlloc
  530. //
  531. // Arguments: [wid] -- Workid
  532. // [pid] -- Propid
  533. // [var] -- Place to return the value
  534. //
  535. // History: 22-Oct-97 KrishnaN Created.
  536. //
  537. //----------------------------------------------------------------------------
  538. SCODE CPropStoreManager::WritePrimaryProperty( WORKID wid,
  539. PROPID pid,
  540. CStorageVariant const & var )
  541. {
  542. CPrimaryPropRecordForWrites PropRecord( wid, *this, _mtxWrite );
  543. return WritePrimaryProperty( PropRecord, pid, var );
  544. }
  545. //+---------------------------------------------------------------------------
  546. //
  547. // Member: CPropStoreManager::WriteProperty, public
  548. //
  549. // Synopsis: Write a property to the cache.
  550. //
  551. // Arguments: [PropRecord] -- Previously opened property record.
  552. // [pid] -- Propid
  553. // [var] -- Value
  554. //
  555. // Returns: Scode propagated from underlying store.
  556. //
  557. // History: 24-Oct-97 KrishnaN Created.
  558. //
  559. //----------------------------------------------------------------------------
  560. SCODE CPropStoreManager::WriteProperty( CCompositePropRecordForWrites & PropRecord,
  561. PROPID pid, CStorageVariant const & var )
  562. {
  563. ciDebugOut(( DEB_PROPSTORE, "WRITE: proprecord = 0x%x, pid = 0x%x, type = %d\n", &PropRecord, pid, var.Type() ));
  564. if (_xPrimaryStore->CanStore(pid))
  565. return _xPrimaryStore->WriteProperty(PropRecord.GetPrimaryPropRecord(), pid, var, IsBackedUpMode() );
  566. else
  567. return _xSecondaryStore->WriteProperty(PropRecord.GetSecondaryPropRecord(), pid, var, IsBackedUpMode() );
  568. }
  569. //+---------------------------------------------------------------------------
  570. //
  571. // Member: CPropStoreManager::WritePrimaryProperty, 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: 17-Mar-98 KrishnaN Created.
  580. //
  581. //----------------------------------------------------------------------------
  582. SCODE CPropStoreManager::WritePrimaryProperty( CCompositePropRecordForWrites & PropRecord,
  583. PROPID pid, CStorageVariant const & var )
  584. {
  585. // Has to be used only to Write pids in the primary store.
  586. Win4Assert(_xPrimaryStore->CanStore(pid) == TRUE);
  587. return _xPrimaryStore->WriteProperty( PropRecord.GetPrimaryPropRecord(), pid, var, IsBackedUpMode() );
  588. }
  589. //+---------------------------------------------------------------------------
  590. //
  591. // Member: CPropStoreManager::WritePrimaryProperty, public
  592. //
  593. // Synopsis: Write a property from the cache. Triggers CoTaskMemAlloc
  594. //
  595. // Arguments: [PropRecord] -- Previously opened property record
  596. // [pid] -- Propid
  597. // [var] -- Place to return the value
  598. //
  599. // History: 17-Mar-98 KrishnaN Created.
  600. //
  601. //----------------------------------------------------------------------------
  602. SCODE CPropStoreManager::WritePrimaryProperty( CPrimaryPropRecordForWrites & PropRecord,
  603. PROPID pid,
  604. CStorageVariant const & var )
  605. {
  606. // Has to be used only to Write pids in the primary store.
  607. Win4Assert(_xPrimaryStore->CanStore(pid) == TRUE);
  608. return _xPrimaryStore->WriteProperty( PropRecord.GetPrimaryPropRecord(), pid, var, IsBackedUpMode() );
  609. }
  610. //+---------------------------------------------------------------------------
  611. //
  612. // Member: CPropStoreManager::WriteSecondaryProperty, public
  613. //
  614. // Synopsis: Write a property from the cache. Triggers CoTaskMemAlloc
  615. //
  616. // Arguments: [PropRecord] -- Previously opened property record
  617. // [pid] -- Propid
  618. // [var] -- Place to return the value
  619. //
  620. // History: 23-Oct-2000 KitmanH Created.
  621. //
  622. //----------------------------------------------------------------------------
  623. SCODE CPropStoreManager::WriteSecondaryProperty( CCompositePropRecordForWrites & PropRecord,
  624. PROPID pid, CStorageVariant const & var )
  625. {
  626. Win4Assert(_xSecondaryStore->CanStore(pid) == TRUE);
  627. return _xSecondaryStore->WriteProperty( PropRecord.GetSecondaryPropRecord(), pid, var, IsBackedUpMode() );
  628. }
  629. //+---------------------------------------------------------------------------
  630. //
  631. // Member: CPropStoreManager::ReadProperty, public
  632. //
  633. // Synopsis: Read a property from the cache.
  634. //
  635. // Arguments: [wid] -- Workid
  636. // [pid] -- Propid
  637. // [pbData] -- Place to return the value
  638. // [pcb] -- On input, the maximum number of bytes to
  639. // write at pbData. On output, the number of
  640. // bytes written if the call was successful,
  641. // else the number of bytes required.
  642. //
  643. // History: 22-Oct-97 KrishnaN Created.
  644. //
  645. //----------------------------------------------------------------------------
  646. BOOL CPropStoreManager::ReadProperty( WORKID wid, PROPID pid,
  647. PROPVARIANT * pbData, unsigned * pcb )
  648. {
  649. unsigned cb = *pcb - sizeof (PROPVARIANT);
  650. BOOL fOk = ReadProperty( wid, pid, *pbData, (BYTE *)(pbData + 1), &cb );
  651. *pcb = cb + sizeof (PROPVARIANT);
  652. return fOk;
  653. }
  654. //+---------------------------------------------------------------------------
  655. //
  656. // Member: CPropStoreManager::ReadProperty, public
  657. //
  658. // Synopsis: Read a property from the cache. Version which uses property
  659. // record.
  660. //
  661. // Arguments: [PropRec] -- Pre-opened property record
  662. // [pid] -- Propid
  663. // [pbData] -- Place to return the value
  664. // [pcb] -- On input, the maximum number of bytes to
  665. // write at pbData. On output, the number of
  666. // bytes written if the call was successful,
  667. // else the number of bytes required.
  668. //
  669. // History: 22-Oct-97 KrishnaN Created.
  670. //
  671. //----------------------------------------------------------------------------
  672. BOOL CPropStoreManager::ReadProperty( CCompositePropRecord & PropRec,
  673. PROPID pid,
  674. PROPVARIANT * pbData,
  675. unsigned * pcb )
  676. {
  677. unsigned cb = *pcb - sizeof (PROPVARIANT);
  678. BOOL fOk = ReadProperty( PropRec, pid, *pbData, (BYTE *)(pbData + 1), &cb );
  679. *pcb = cb + sizeof (PROPVARIANT);
  680. return fOk;
  681. }
  682. //+---------------------------------------------------------------------------
  683. //
  684. // Member: CPropStoreManager::ReadProperty, public
  685. //
  686. // Synopsis: Read a property from the cache. Version which uses property
  687. // record.
  688. //
  689. // Arguments: [PropRec] -- Pre-opened property record
  690. // [pid] -- Propid
  691. // [var] -- Place to return the value
  692. //
  693. // History: 19-Dec-97 dlee Created.
  694. //
  695. //----------------------------------------------------------------------------
  696. BOOL CPropStoreManager::ReadProperty(
  697. CCompositePropRecord & PropRec,
  698. PROPID pid,
  699. PROPVARIANT & var )
  700. {
  701. unsigned cb = 0xFFFFFFFF;
  702. return ReadProperty( PropRec, pid, var, 0, &cb );
  703. }
  704. //+---------------------------------------------------------------------------
  705. //
  706. // Member: CPropStoreManager::ReadProperty, public
  707. //
  708. // Synopsis: Read a property from the cache. Version which uses property
  709. // record.
  710. //
  711. // Arguments: [PropRec] -- Pre-opened property record
  712. // [pid] -- Propid
  713. // [var] -- Place to return the value
  714. //
  715. // History: 19-Dec-97 dlee Created.
  716. //
  717. //----------------------------------------------------------------------------
  718. BOOL CPropStoreManager::ReadProperty(
  719. CPrimaryPropRecord & PropRec,
  720. PROPID pid,
  721. PROPVARIANT & var )
  722. {
  723. unsigned cb = 0xFFFFFFFF;
  724. return ReadProperty( PropRec, pid, var, 0, &cb );
  725. }
  726. //+---------------------------------------------------------------------------
  727. //
  728. // Member: CPropStoreManager::ReadProperty, public
  729. //
  730. // Synopsis: Read a property from the cache. Triggers CoTaskMemAlloc
  731. //
  732. // Arguments: [wid] -- Workid
  733. // [pid] -- Propid
  734. // [var] -- Place to return the value
  735. //
  736. // History: 22-Oct-97 KrishnaN Created.
  737. //
  738. //----------------------------------------------------------------------------
  739. BOOL CPropStoreManager::ReadProperty(
  740. WORKID wid,
  741. PROPID pid,
  742. PROPVARIANT & var )
  743. {
  744. unsigned cb = 0xFFFFFFFF;
  745. return ReadProperty( wid, pid, var, 0, &cb );
  746. }
  747. //+---------------------------------------------------------------------------
  748. //
  749. // Member: CPropStoreManager::ReadProperty, public
  750. //
  751. // Synopsis: Read a property from the cache. Triggers CoTaskMemAlloc
  752. //
  753. // Arguments: [wid] -- Workid
  754. // [pid] -- Propid
  755. // [var] -- Place to return the value
  756. //
  757. // History: 22-Oct-97 KrishnaN Created.
  758. //
  759. //----------------------------------------------------------------------------
  760. BOOL CPropStoreManager::ReadPrimaryProperty( WORKID wid, PROPID pid, PROPVARIANT & var )
  761. {
  762. // Has to be used only to read pids in the primary store.
  763. Win4Assert(_xPrimaryStore->CanStore(pid) == TRUE);
  764. unsigned cb = 0xFFFFFFFF;
  765. BOOL fOk = _xPrimaryStore->ReadProperty( wid, pid, var, 0, &cb );
  766. return fOk;
  767. }
  768. //+---------------------------------------------------------------------------
  769. //
  770. // Member: CPropStoreManager::ReadProperty, public
  771. //
  772. // Synopsis: Read a property from the cache. Separate variable buffer.
  773. //
  774. // Arguments: [wid] -- Workid
  775. // [pid] -- Propid
  776. // [var] -- Variant written here
  777. // [pbExtra] -- Place to store additional pointer(s).
  778. // [pcbExtra] -- On input, the maximum number of bytes to
  779. // write at pbExtra. On output, the number of
  780. // bytes written if the call was successful,
  781. // else the number of bytes required.
  782. //
  783. // History: 24-Oct-97 KrishnaN Created.
  784. //
  785. //----------------------------------------------------------------------------
  786. BOOL CPropStoreManager::ReadProperty( WORKID wid,
  787. PROPID pid,
  788. PROPVARIANT & var,
  789. BYTE * pbExtra,
  790. unsigned * pcbExtra )
  791. {
  792. if ( _xPrimaryStore->CanStore( pid ) )
  793. {
  794. CPrimaryPropRecord PropRecord( wid, *this );
  795. return ReadProperty( PropRecord, pid, var, pbExtra, pcbExtra );
  796. }
  797. else
  798. {
  799. // the constructor seeds the constituent proprecords
  800. // with the right wid, based on the wid we pass in.
  801. CCompositePropRecord PropRecord( wid, *this );
  802. return _xSecondaryStore->ReadProperty( PropRecord.GetSecondaryPropRecord(),
  803. pid, var, pbExtra, pcbExtra);
  804. }
  805. } //ReadProperty
  806. //+---------------------------------------------------------------------------
  807. //
  808. // Member: CPropStoreManager::ReadProperty, public
  809. //
  810. // Synopsis: Read a property from the cache. Separate variable buffer.
  811. // Uses pre-opened property record.
  812. //
  813. // Arguments: [PropRec] -- Pre-opened property record.
  814. // [pid] -- Propid
  815. // [var] -- Variant written here
  816. // [pbExtra] -- Place to store additional pointer(s).
  817. // [pcbExtra] -- On input, the maximum number of bytes to
  818. // write at pbExtra. On output, the number of
  819. // bytes written if the call was successful,
  820. // else the number of bytes required.
  821. //
  822. // History: 03-Apr-96 KyleP Created.
  823. //
  824. //----------------------------------------------------------------------------
  825. BOOL CPropStoreManager::ReadProperty( CCompositePropRecord & PropRecord,
  826. PROPID pid,
  827. PROPVARIANT & var,
  828. BYTE * pbExtra,
  829. unsigned * pcbExtra )
  830. {
  831. if (_xPrimaryStore->CanStore(pid))
  832. {
  833. return _xPrimaryStore->ReadProperty(PropRecord.GetPrimaryPropRecord(),
  834. pid, var, pbExtra, pcbExtra);
  835. }
  836. else
  837. {
  838. return _xSecondaryStore->ReadProperty(PropRecord.GetSecondaryPropRecord(),
  839. pid, var, pbExtra, pcbExtra);
  840. }
  841. }
  842. //+---------------------------------------------------------------------------
  843. //
  844. // Member: CPropStoreManager::ReadProperty, public
  845. //
  846. // Synopsis: Read a property from the cache. Separate variable buffer.
  847. // Uses pre-opened property record.
  848. //
  849. // Arguments: [PropRec] -- Pre-opened property record.
  850. // [pid] -- Propid
  851. // [var] -- Variant written here
  852. // [pbExtra] -- Place to store additional pointer(s).
  853. // [pcbExtra] -- On input, the maximum number of bytes to
  854. // write at pbExtra. On output, the number of
  855. // bytes written if the call was successful,
  856. // else the number of bytes required.
  857. //
  858. // History: 03-Apr-96 KyleP Created.
  859. //
  860. //----------------------------------------------------------------------------
  861. BOOL CPropStoreManager::ReadProperty( CPrimaryPropRecord & PropRecord,
  862. PROPID pid,
  863. PROPVARIANT & var,
  864. BYTE * pbExtra,
  865. unsigned * pcbExtra )
  866. {
  867. Win4Assert( _xPrimaryStore->CanStore(pid) );
  868. return _xPrimaryStore->ReadProperty(PropRecord.GetPrimaryPropRecord(),
  869. pid, var, pbExtra, pcbExtra);
  870. }
  871. //+---------------------------------------------------------------------------
  872. //
  873. // Member: CPropStoreManager::OpenRecord, public
  874. //
  875. // Synopsis: Opens record (for multiple reads)
  876. //
  877. // Arguments: [wid] -- Workid
  878. // [pb] -- Storage for record
  879. //
  880. // Returns: Pointer to open property record. Owned by caller.
  881. //
  882. // History: 03-Apr-96 KyleP Created.
  883. //
  884. //----------------------------------------------------------------------------
  885. CCompositePropRecord * CPropStoreManager::OpenRecord( WORKID wid, BYTE * pb )
  886. {
  887. Win4Assert( sizeof(CCompositePropRecord) <= sizeof_CCompositePropRecord );
  888. return new( pb ) CCompositePropRecord( wid, *this );
  889. }
  890. //+---------------------------------------------------------------------------
  891. //
  892. // Member: CPropStoreManager::CloseRecord, public
  893. //
  894. // Synopsis: Closes record.
  895. //
  896. // Arguments: [pRec] -- Property record
  897. //
  898. // History: 03-Apr-96 KyleP Created.
  899. //
  900. //----------------------------------------------------------------------------
  901. void CPropStoreManager::CloseRecord( CCompositePropRecord * pRec )
  902. {
  903. delete pRec;
  904. }
  905. //+---------------------------------------------------------------------------
  906. //
  907. // Member: CPropStoreManager::OpenPrimaryRecord, public
  908. //
  909. // Synopsis: Opens record (for multiple reads)
  910. //
  911. // Arguments: [wid] -- Workid
  912. // [pb] -- Storage for record
  913. //
  914. // Returns: Pointer to open property record. Owned by caller.
  915. //
  916. // History: 03-Apr-96 KyleP Created.
  917. //
  918. //----------------------------------------------------------------------------
  919. CPrimaryPropRecord * CPropStoreManager::OpenPrimaryRecord( WORKID wid, BYTE * pb )
  920. {
  921. Win4Assert( sizeof(CPrimaryPropRecord) <= sizeof_CPropRecord );
  922. return new( pb ) CPrimaryPropRecord( wid, *this );
  923. }
  924. //+---------------------------------------------------------------------------
  925. //
  926. // Member: CPropStoreManager::CloseRecord, public
  927. //
  928. // Synopsis: Closes record.
  929. //
  930. // Arguments: [pRec] -- Property record
  931. //
  932. // History: 03-Apr-96 KyleP Created.
  933. //
  934. //----------------------------------------------------------------------------
  935. void CPropStoreManager::CloseRecord( CPrimaryPropRecord * pRec )
  936. {
  937. delete pRec;
  938. }
  939. //+---------------------------------------------------------------------------
  940. //
  941. // Member: CPropStoreManager::OpenRecordForWrites, public
  942. //
  943. // Synopsis: Opens record (for multiple writes)
  944. //
  945. // Arguments: [wid] -- Workid
  946. // [pb] -- Storage for record
  947. //
  948. // Returns: Pointer to open property record. Owned by caller.
  949. //
  950. // History: 17-Mar-98 KrishnaN Created.
  951. //
  952. //----------------------------------------------------------------------------
  953. CCompositePropRecordForWrites * CPropStoreManager::OpenRecordForWrites( WORKID wid, BYTE * pb )
  954. {
  955. Win4Assert( sizeof(CCompositePropRecordForWrites) <= sizeof_CCompositePropRecord );
  956. return new( pb ) CCompositePropRecordForWrites( wid, *this, _mtxWrite );
  957. }
  958. //+---------------------------------------------------------------------------
  959. //
  960. // Member: CPropStoreManager::OpenPrimaryRecordForWrites, public
  961. //
  962. // Synopsis: Opens record (for multiple writes)
  963. //
  964. // Arguments: [wid] -- Workid
  965. // [pb] -- Storage for record
  966. //
  967. // Returns: Pointer to open property record. Owned by caller.
  968. //
  969. // History: 17-Mar-98 KrishnaN Created.
  970. //
  971. //----------------------------------------------------------------------------
  972. CPrimaryPropRecordForWrites * CPropStoreManager::OpenPrimaryRecordForWrites( WORKID wid, BYTE * pb )
  973. {
  974. Win4Assert( sizeof(CPrimaryPropRecordForWrites) <= sizeof_CPropRecord );
  975. return new( pb ) CPrimaryPropRecordForWrites( wid, *this, _mtxWrite );
  976. }
  977. //+---------------------------------------------------------------------------
  978. //
  979. // Member: CPropStoreManager::CloseRecord, public
  980. //
  981. // Synopsis: Closes record.
  982. //
  983. // Arguments: [pRec] -- Property record
  984. //
  985. // History: 17-Mar-98 KrishnaN Created.
  986. //
  987. //----------------------------------------------------------------------------
  988. void CPropStoreManager::CloseRecord( CCompositePropRecordForWrites * pRec )
  989. {
  990. delete pRec;
  991. }
  992. //+---------------------------------------------------------------------------
  993. //
  994. // Member: CPropStoreManager::CloseRecord, public
  995. //
  996. // Synopsis: Closes record.
  997. //
  998. // Arguments: [pRec] -- Property record
  999. //
  1000. // History: 17-Mar-98 KrishnaN Created.
  1001. //
  1002. //----------------------------------------------------------------------------
  1003. void CPropStoreManager::CloseRecord( CPrimaryPropRecordForWrites * pRec )
  1004. {
  1005. delete pRec;
  1006. }
  1007. //+---------------------------------------------------------------------------
  1008. //
  1009. // Member: CPropStoreManager::DeleteRecord, public
  1010. //
  1011. // Synopsis: Free a record and any records chained off it.
  1012. //
  1013. // Arguments: [wid] -- Workid
  1014. //
  1015. // History: 24-Oct-97 KrishnaN Created.
  1016. //
  1017. //----------------------------------------------------------------------------
  1018. void CPropStoreManager::DeleteRecord( WORKID wid )
  1019. {
  1020. CLock lock( _mtxWrite );
  1021. ciDebugOut(( DEB_PROPSTORE, "DELETE: wid = 0x%x\n", wid ));
  1022. //
  1023. // Get the secondary store's top-level wid before getting rid
  1024. // of the wid in the primary store.
  1025. //
  1026. //
  1027. // The secondary wid can certainly be bogus if we couldn't write
  1028. // it to the primary store after allocating it when creating the
  1029. // records.
  1030. //
  1031. WORKID widSec = GetSecondaryTopLevelWid(wid);
  1032. if ( widInvalid != widSec && 0 != widSec )
  1033. _xSecondaryStore->DeleteRecord( widSec,
  1034. IsBackedUpMode() );
  1035. _xPrimaryStore->DeleteRecord( wid, IsBackedUpMode() );
  1036. }
  1037. //+---------------------------------------------------------------------------
  1038. //
  1039. // Member: CPropStoreManager::Flush
  1040. //
  1041. // Synopsis: Flushes the data in the property store and marks it clean.
  1042. //
  1043. // History: 3-20-96 srikants Created
  1044. //
  1045. //----------------------------------------------------------------------------
  1046. void CPropStoreManager::Flush()
  1047. {
  1048. CLock mtxLock( _mtxWrite );
  1049. // Flush both the stores. Only when both are successful
  1050. // do we consider the entire flush to be successful.
  1051. // Don't reset the backup streams until the flush is
  1052. // completely successful.
  1053. BOOL fFlushOK = _xPrimaryStore->Flush();
  1054. if (fFlushOK)
  1055. fFlushOK = _xSecondaryStore->Flush();
  1056. // Reset the primary and the secondary backup stores
  1057. if (fFlushOK)
  1058. {
  1059. if (_xPrimaryStore->BackupStream())
  1060. _xPrimaryStore->BackupStream()->Reset(_xPrimaryStore->GetDesiredBackupSize());
  1061. if (_xSecondaryStore->BackupStream())
  1062. _xSecondaryStore->BackupStream()->Reset(_xSecondaryStore->GetDesiredBackupSize());
  1063. }
  1064. }
  1065. //+---------------------------------------------------------------------------
  1066. //
  1067. // Member: CPropStoreManager::WritePropertyInNewRecord, public
  1068. //
  1069. // Synopsis: Like WriteProperty, but also allocates record.
  1070. //
  1071. // Arguments: [pid] -- Propid to write.
  1072. // [var] -- Property value
  1073. //
  1074. // Returns: Workid of new record.
  1075. //
  1076. // History: 22-Oct-97 KrishnaN Created.
  1077. //
  1078. //----------------------------------------------------------------------------
  1079. WORKID CPropStoreManager::WritePropertyInNewRecord( PROPID pid,
  1080. CStorageVariant const & var )
  1081. {
  1082. CLock lock( _mtxWrite );
  1083. //
  1084. // Get new wids from the primary and the secondary store.
  1085. // Write the property.
  1086. // Increment records in use for both the stores.
  1087. //
  1088. WORKID widPrimary = widInvalid;
  1089. WORKID widSecondary = widInvalid;
  1090. TRY
  1091. {
  1092. widPrimary = _xPrimaryStore->NewWorkId( 1, IsBackedUpMode() );
  1093. widSecondary = _xSecondaryStore->NewWorkId( 1, IsBackedUpMode() );
  1094. }
  1095. CATCH(CException, e)
  1096. {
  1097. // cleanup if widSecondary is invalid
  1098. if (widInvalid == widSecondary && widInvalid != widPrimary)
  1099. _xPrimaryStore->DeleteRecord( widPrimary, IsBackedUpMode() );
  1100. // Let the caller do what it normally does to handle exceptions
  1101. RETHROW();
  1102. }
  1103. END_CATCH
  1104. ciDebugOut(( DEB_PROPSTORE, "New record at primary: %d, secondary: %d\n",
  1105. widPrimary, widSecondary ));
  1106. //
  1107. // The primary's top-level record has a pointer to the
  1108. // top-level record in the secondary store. Fill that now!
  1109. //
  1110. VARIANT newVar;
  1111. newVar.vt = VT_UI4;
  1112. newVar.ulVal = widSecondary;
  1113. CStorageVariant *pVar = CastToStorageVariant(newVar);
  1114. SCODE sc;
  1115. sc = WritePrimaryProperty( widPrimary, pidSecondaryStorage, *pVar );
  1116. if (FAILED(sc))
  1117. THROW(CException(sc));
  1118. sc = WriteProperty( widPrimary, pid, var );
  1119. //
  1120. // DLee add this assert to find out why this is failing sometimes.
  1121. // Did the caller pass a bogus variant?
  1122. //
  1123. Win4Assert( HRESULT_FROM_WIN32( ERROR_INVALID_PARAMETER ) != sc );
  1124. if (FAILED(sc))
  1125. THROW(CException(sc));
  1126. _xPrimaryStore->IncRecordsInUse();
  1127. _xSecondaryStore->IncRecordsInUse();
  1128. // To the outside world, the primary wid is the one that matters.
  1129. return widPrimary;
  1130. }
  1131. //
  1132. // get and set parameters
  1133. // If incorrect parameter, default to the primary store.
  1134. //
  1135. //+---------------------------------------------------------------------------
  1136. //
  1137. // Member: CPropStoreManager::SetBackupSize, public
  1138. //
  1139. // Synopsis: Sets backup size for a given property store.
  1140. //
  1141. // Arguments: [ulBackupSizeInPages] -- Size of the backup file.
  1142. // [dwStoreLevel] -- Primary or secondary store?
  1143. //
  1144. // History: 22-Oct-97 KrishnaN Created.
  1145. //
  1146. //----------------------------------------------------------------------------
  1147. void CPropStoreManager::SetBackupSize(ULONG ulBackupSizeInPages,
  1148. DWORD dwStoreLevel)
  1149. {
  1150. if (SECONDARY_STORE == dwStoreLevel)
  1151. _xSecondaryStore->SetBackupSize(ulBackupSizeInPages);
  1152. else
  1153. {
  1154. Win4Assert(PRIMARY_STORE == dwStoreLevel);
  1155. _xPrimaryStore->SetBackupSize(ulBackupSizeInPages);
  1156. }
  1157. }
  1158. //+---------------------------------------------------------------------------
  1159. //
  1160. // Member: CPropStoreManager::GetBackupSize, public
  1161. //
  1162. // Synopsis: Gets backup size of a given property store.
  1163. //
  1164. // Arguments: [dwStoreLevel] -- Primary or secondary store?
  1165. //
  1166. // History: 22-Oct-97 KrishnaN Created.
  1167. //
  1168. //----------------------------------------------------------------------------
  1169. ULONG CPropStoreManager::GetBackupSize(DWORD dwStoreLevel)
  1170. {
  1171. if ( SECONDARY_STORE == dwStoreLevel)
  1172. return _xSecondaryStore->GetActualBackupSize();
  1173. else
  1174. {
  1175. Win4Assert( PRIMARY_STORE == dwStoreLevel);
  1176. return _xPrimaryStore->GetActualBackupSize();
  1177. }
  1178. }
  1179. //+---------------------------------------------------------------------------
  1180. //
  1181. // Member: CPropStoreManager::SetMappedCacheSize, public
  1182. //
  1183. // Synopsis: Gets backup size of a given property store.
  1184. //
  1185. // Arguments: [dwStoreLevel] -- Primary or secondary store?
  1186. //
  1187. // History: 22-Oct-97 KrishnaN Created.
  1188. //
  1189. //----------------------------------------------------------------------------
  1190. void CPropStoreManager::SetMappedCacheSize(ULONG ulPSMappedCache,
  1191. DWORD dwStoreLevel)
  1192. {
  1193. if ( SECONDARY_STORE == dwStoreLevel)
  1194. _xSecondaryStore->SetMappedCacheSize(ulPSMappedCache);
  1195. else
  1196. {
  1197. Win4Assert( PRIMARY_STORE== dwStoreLevel);
  1198. _xPrimaryStore->SetMappedCacheSize(ulPSMappedCache);
  1199. }
  1200. }
  1201. //+---------------------------------------------------------------------------
  1202. //
  1203. // Member: CPropStoreManager::GetMappedCacheSize, public
  1204. //
  1205. // Synopsis: Gets mapped cache size of a given property store.
  1206. //
  1207. // Arguments: [dwStoreLevel] -- Primary or secondary store?
  1208. //
  1209. // History: 22-Oct-97 KrishnaN Created.
  1210. //
  1211. //----------------------------------------------------------------------------
  1212. ULONG CPropStoreManager::GetMappedCacheSize(DWORD dwStoreLevel)
  1213. {
  1214. if (SECONDARY_STORE == dwStoreLevel)
  1215. return _xSecondaryStore->GetMappedCacheSize();
  1216. else
  1217. {
  1218. Win4Assert(PRIMARY_STORE == dwStoreLevel);
  1219. return _xPrimaryStore->GetMappedCacheSize();
  1220. }
  1221. }
  1222. //+---------------------------------------------------------------------------
  1223. //
  1224. // Member: CPropStoreManager::GetTotalSizeInKB, public
  1225. //
  1226. // Synopsis: Gets total size of the property store.
  1227. //
  1228. // Arguments:
  1229. //
  1230. // History: 22-Oct-97 KrishnaN Created.
  1231. //
  1232. //----------------------------------------------------------------------------
  1233. ULONG CPropStoreManager::GetTotalSizeInKB()
  1234. {
  1235. return _xPrimaryStore->GetTotalSizeInKB() +
  1236. _xSecondaryStore->GetTotalSizeInKB();
  1237. }
  1238. PStorage& CPropStoreManager::GetStorage(DWORD dwStoreLevel)
  1239. {
  1240. Win4Assert(&(_xPrimaryStore->GetStorage()) == _pStorage);
  1241. Win4Assert(&(_xSecondaryStore->GetStorage()) == _pStorage);
  1242. return *_pStorage;
  1243. }
  1244. void CPropStoreManager::Shutdown()
  1245. {
  1246. Flush();
  1247. _xPrimaryStore->Shutdown();
  1248. _xSecondaryStore->Shutdown();
  1249. }
  1250. void CPropStoreManager::ClearNonStorageProperties( CCompositePropRecordForWrites & rec )
  1251. {
  1252. _xPrimaryStore->ClearNonStorageProperties( rec );
  1253. _xSecondaryStore->ClearNonStorageProperties( rec );
  1254. }
  1255. // CSvcQuery methods
  1256. //+-------------------------------------------------------------------------
  1257. //
  1258. // Member: CCompositeProgressNotifier::QueryInterface, public
  1259. //
  1260. // Arguments: [ifid] -- Interface id
  1261. // [ppiuk] -- Interface return pointer
  1262. //
  1263. // Returns: Error. No rebind from this class is supported.
  1264. //
  1265. // History: Nov-14-97 KrishnaN Created
  1266. //
  1267. //--------------------------------------------------------------------------
  1268. STDMETHODIMP CCompositeProgressNotifier::QueryInterface(
  1269. REFIID ifid,
  1270. void ** ppiuk )
  1271. {
  1272. if ( IID_IUnknown == ifid )
  1273. {
  1274. AddRef();
  1275. *ppiuk = (void *)((IUnknown *)this);
  1276. return S_OK;
  1277. }
  1278. else
  1279. {
  1280. *ppiuk = 0;
  1281. return E_NOINTERFACE;
  1282. }
  1283. } //QueryInterface
  1284. //+-------------------------------------------------------------------------
  1285. //
  1286. // Member: CCompositeProgressNotifier::AddRef, public
  1287. //
  1288. // Synopsis: Reference the virtual table.
  1289. //
  1290. // History: Nov-14-97 KrishnaN Created
  1291. //
  1292. //--------------------------------------------------------------------------
  1293. STDMETHODIMP_(ULONG) CCompositeProgressNotifier::AddRef()
  1294. {
  1295. InterlockedIncrement( &_ref );
  1296. return (ULONG)_ref;
  1297. } //AddRef
  1298. //+-------------------------------------------------------------------------
  1299. //
  1300. // Member: CCompositeProgressNotifier::Release, public
  1301. //
  1302. // Synopsis: De-Reference the virtual table.
  1303. //
  1304. // Effects: If the ref count goes to 0 then the table is deleted.
  1305. //
  1306. // History: Nov-14-97 KrishnaN Created
  1307. //
  1308. //--------------------------------------------------------------------------
  1309. STDMETHODIMP_(ULONG) CCompositeProgressNotifier::Release()
  1310. {
  1311. unsigned long uTmp = InterlockedDecrement( &_ref );
  1312. if ( 0 == uTmp )
  1313. delete this;
  1314. return(uTmp);
  1315. } //Release
  1316. //+-------------------------------------------------------------------------
  1317. //
  1318. // Member: CCompositeProgressNotifier::OnProgress, public
  1319. //
  1320. // Synopsis: Report progress.
  1321. //
  1322. // Effects: Progress reporting accounts for the presence of multiple
  1323. // independently operating constituents in the property store.
  1324. //
  1325. // History: Nov-14-97 KrishnaN Created
  1326. //
  1327. //--------------------------------------------------------------------------
  1328. STDMETHODIMP CCompositeProgressNotifier::OnProgress
  1329. (
  1330. DWORD dwProgressCurrent,
  1331. DWORD dwProgressMaximum,
  1332. BOOL fAccurate,
  1333. BOOL fOwner
  1334. )
  1335. {
  1336. if (0 == _xComponentProgressNotifier.GetPointer())
  1337. return S_OK;
  1338. Win4Assert(_cFinishedComponents < _cComponents);
  1339. Win4Assert(dwProgressMaximum == _aulMaxSizes[_cFinishedComponents]);
  1340. //
  1341. // Present a unified view of progress reports. The composite progress
  1342. // report is 100% done only when all components are 100% done.
  1343. //
  1344. return _xComponentProgressNotifier->OnProgress
  1345. (dwProgressCurrent*1000/dwProgressMaximum + _dwCumMaxSize,
  1346. _dwTotalMaxSize,
  1347. fAccurate,
  1348. fOwner);
  1349. } //OnProgress