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.

2192 lines
71 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1993 - 2002.
  5. //
  6. // File: cistore.cxx
  7. //
  8. // Contents: CI physical storage
  9. //
  10. // Classes: CiStorage
  11. //
  12. // History: 07-Jul-93 BartoszM Separated from physidx.cxx
  13. // 20-Nov-98 KLam Moved IsVolumeWriteProtected to CDriveInfo
  14. //
  15. //----------------------------------------------------------------------------
  16. #include <pch.cxx>
  17. #pragma hdrstop
  18. #include <mmstrm.hxx>
  19. #include <cidir.hxx>
  20. #include <cistore.hxx>
  21. #include <idxtab.hxx>
  22. #include <circstob.hxx>
  23. #include <fullpath.hxx>
  24. #include <enumstr.hxx>
  25. #include <pathpars.hxx>
  26. #include <propbkp.hxx>
  27. #include <ntopen.hxx>
  28. #define CAT_TESTLOG_HDR L"\\CiTstLog.000"
  29. #define CAT_TESTLOG_CP1 L"\\CiTstLog.001"
  30. #define CAT_TESTLOG_CP2 L"\\CiTstLog.002"
  31. #define CAT_IDXTABLE_HDR L"\\INDEX.000"
  32. #define CAT_IDXTABLE_CP1 L"\\INDEX.001"
  33. #define CAT_IDXTABLE_CP2 L"\\INDEX.002"
  34. #define MMLOG_PREFIX L"\\CiML"
  35. #define PROPSTORE_PREFIX L"\\CiPS"
  36. #define PROPSTORE1_PREFIX L"\\CiP1"
  37. #define PROPSTORE2_PREFIX L"\\CiP2"
  38. #define PRI_CHANGELOG_PREFIX L"\\CiCL"
  39. #define SEC_CHANGELOG_PREFIX L"\\CiSL"
  40. #define FRESHLOG_PREFIX L"\\CiFL"
  41. #define PIDTABLE_PREFIX L"\\CiPT"
  42. #define SCOPELIST_PREFIX L"\\CiSP"
  43. #define SECSTORE_PREFIX L"\\CiST"
  44. #define VSCOPELIST_PREFIX L"\\CiVP"
  45. // constant definitions moved here from cicat.cxx
  46. const WCHAR CAT_FILEID_MAP_FILE[] = L"\\cicat.fid"; // File id map table
  47. const WCHAR CAT_HASH_FILE[] = L"\\cicat.hsh"; // Strings table
  48. //+-------------------------------------------------------------------------
  49. //--------------------------------------------------------------------------
  50. SStorage::SStorage(PStorage * pObj ) : _pObj(pObj)
  51. {
  52. }
  53. //+-------------------------------------------------------------------------
  54. //--------------------------------------------------------------------------
  55. SStorage::~SStorage()
  56. {
  57. delete _pObj;
  58. }
  59. //+-------------------------------------------------------------------------
  60. //--------------------------------------------------------------------------
  61. PStorageObject::PStorageObject()
  62. {
  63. }
  64. //+-------------------------------------------------------------------------
  65. //--------------------------------------------------------------------------
  66. inline CiStorageObject& CI_OBJ ( PStorageObject& obj )
  67. {
  68. return( (CiStorageObject&)obj );
  69. }
  70. //+-------------------------------------------------------------------------
  71. //--------------------------------------------------------------------------
  72. CiStorageObject::CiStorageObject(WORKID objectId)
  73. : _objectId(objectId)
  74. {
  75. }
  76. //+-------------------------------------------------------------------------
  77. //--------------------------------------------------------------------------
  78. CiStorageObject::~CiStorageObject()
  79. {
  80. }
  81. //+-------------------------------------------------------------------------
  82. //--------------------------------------------------------------------------
  83. SStorageObject::SStorageObject ( PStorageObject* pObj )
  84. : _pObj(pObj)
  85. {
  86. }
  87. //+-------------------------------------------------------------------------
  88. //--------------------------------------------------------------------------
  89. SStorageObject::~SStorageObject()
  90. {
  91. delete _pObj;
  92. }
  93. //+-------------------------------------------------------------------------
  94. //
  95. // Function: DoesVolumeSupportShrinkFromFront
  96. //
  97. // Synopsis: Checks if the volume supports SFF, like NTFS5
  98. //
  99. // Arguments: [pwcPath] -- Path to physical storage.
  100. //
  101. // Returns: TRUE if the file system supports sparse files
  102. // FALSE otherwise
  103. //
  104. // History: 5-Nov-97 dlee Created
  105. //
  106. //--------------------------------------------------------------------------
  107. BOOL DoesVolumeSupportShrinkFromFront( WCHAR const * pwcPath )
  108. {
  109. SHandle xDir( CiNtOpen( pwcPath,
  110. FILE_READ_DATA | SYNCHRONIZE,
  111. FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
  112. FILE_DIRECTORY_FILE | FILE_SYNCHRONOUS_IO_NONALERT ) );
  113. BYTE aInfo[ sizeof FILE_FS_ATTRIBUTE_INFORMATION +
  114. MAX_PATH * sizeof WCHAR ];
  115. FILE_FS_ATTRIBUTE_INFORMATION *pAttributeInfo = (FILE_FS_ATTRIBUTE_INFORMATION *) aInfo;
  116. IO_STATUS_BLOCK IoStatus;
  117. NTSTATUS Status = NtQueryVolumeInformationFile( xDir.Get(),
  118. &IoStatus,
  119. pAttributeInfo,
  120. sizeof aInfo,
  121. FileFsAttributeInformation );
  122. if ( FAILED( Status ) )
  123. {
  124. ciDebugOut(( DEB_WARN, "can't get volume info %#x on '%ws'\n",
  125. Status, pwcPath ));
  126. THROW( CException( Status ) );
  127. }
  128. return 0 != ( FILE_SUPPORTS_SPARSE_FILES &
  129. pAttributeInfo->FileSystemAttributes );
  130. } //DoesVolumeSupportShrinkFromFront
  131. //+-------------------------------------------------------------------------
  132. //
  133. // Member: IsDirectoryWritable
  134. //
  135. // Synopsis: Checks if the directory is writable by trying to open
  136. // file "cicat.hsh" for write
  137. //
  138. // Arguments: [pwcPath] -- Path to physical storage.
  139. //
  140. // Returns: TRUE if the directory is writable
  141. // FALSE otherwise
  142. //
  143. // History: 17-Mar-98 KitmanH Created
  144. // 10-Jun-98 KitmanH Changed to only retrive file
  145. // attributes
  146. //
  147. // Note: Assume writable, if the file does not exist, caller needs
  148. // to check if the volume is writable
  149. //
  150. //--------------------------------------------------------------------------
  151. BOOL IsDirectoryWritable( WCHAR const * pwcPath )
  152. {
  153. WCHAR wcsPath [ MAX_PATH ];
  154. wcsncpy( wcsPath, pwcPath, sizeof wcsPath / sizeof WCHAR );
  155. wcsPath[ (sizeof wcsPath / sizeof WCHAR) - 1 ] = 0;
  156. wcsncat(wcsPath, CAT_HASH_FILE, (sizeof wcsPath / sizeof WCHAR) - wcslen(wcsPath) );
  157. ciDebugOut(( DEB_ITRACE, "wcsPath == %ws\n", wcsPath ));
  158. DWORD dwFileAttribute = GetFileAttributes( wcsPath );
  159. if ( 0xFFFFFFFF != dwFileAttribute)
  160. {
  161. Win4Assert( !(FILE_ATTRIBUTE_DIRECTORY & dwFileAttribute) );
  162. ciDebugOut(( DEB_ITRACE, "dwFileAttribute is %#x\n", dwFileAttribute ));
  163. if ( dwFileAttribute & FILE_ATTRIBUTE_READONLY )
  164. return FALSE;
  165. else
  166. return TRUE;
  167. }
  168. else
  169. return TRUE;
  170. } //IsDirectoryWritable
  171. //+-------------------------------------------------------------------------
  172. //
  173. // Member: CiStorage::CiStorage, public
  174. //
  175. // Effects: Saves path to physical storage.
  176. //
  177. // Arguments: [wcsPath] -- Path to physical storage.
  178. // [adviseStatus] -- advise status object
  179. // [cMegToLeaveOnDisk] -- number of megabytes to leave on disk
  180. // [ulVer] -- version [default: CURRENT_VERSION_STAMP]
  181. // [fReadOnly] -- is storage read-only [default: FALSE]
  182. //
  183. // History: 07-Mar-92 KyleP Created
  184. // 16-Feb-98 KitmanH Added fReadOnly argument
  185. // 20-Mar-98 KitmanH _fReadOnly is determined by both
  186. // IsDirectoryWritable() and
  187. // IsVolumeWriteProtected()
  188. // 27-Oct-98 KLam Added disk space to leave
  189. // 20-Nov-98 KLam Initialize _driveInfo
  190. //
  191. // Note: _fIsReadOnly value is set according whether the registry
  192. // value "IsReadOnly" is set OR the volume is WriteProtected
  193. // OR the directory is not writable
  194. //--------------------------------------------------------------------------
  195. CiStorage::CiStorage( WCHAR const * wcsPath,
  196. ICiCAdviseStatus & adviseStatus,
  197. ULONG cMegToLeaveOnDisk,
  198. ULONG ulVer,
  199. BOOL fReadOnly )
  200. :_widFreshLog( widInvalid ),
  201. _adviseStatus( adviseStatus ),
  202. _fCorruptionReported(FALSE),
  203. _ulVer( ulVer ),
  204. _fSupportsShrinkFromFront( FALSE ),
  205. _fIsReadOnly( fReadOnly ),
  206. _fFavorReadAhead( FALSE ), // optimize for queries, not merges
  207. _cMegToLeaveOnDisk ( cMegToLeaveOnDisk ),
  208. _driveInfo ( wcsPath, cMegToLeaveOnDisk )
  209. {
  210. // The constructor is extended to take a version parameter
  211. // to set the FSCI versioning apart from framework CI versioning.
  212. // When the content framework version changes, all framework clients should reindex.
  213. // However, if only the FSCI version changes, only FSCI should reindex.
  214. // The default value for the property store is the content index version.
  215. //
  216. // ulVer defaults to the framework's version stamp, so when FSCI alone changes,
  217. // others don't have to change (unless they are using a feature of FSCI.)
  218. CIndexId iid( itFreshLog, partidFresh2 );
  219. _widFreshLog = iid;
  220. //
  221. // Squirrel away the path.
  222. //
  223. _xPath.Set( new WCHAR [ wcslen( wcsPath ) + 1 ] );
  224. wcscpy( _xPath.GetPointer(), wcsPath );
  225. ciDebugOut(( DEB_ITRACE, "Content index physical storage: %ws\n", wcsPath ));
  226. // Is the volume writable?
  227. BOOL fAbsolutelyUnWritable = ( _driveInfo.IsWriteProtected() ) || !( IsDirectoryWritable( wcsPath ) );
  228. ciDebugOut(( DEB_ITRACE, "CiStorage::CiStorage.. fAbsolutelyUnWritable == %d\n", fAbsolutelyUnWritable ));
  229. _fIsReadOnly = fReadOnly || fAbsolutelyUnWritable;
  230. //
  231. // Determine whether this volume supports shrink from front (ntfs5)
  232. //
  233. _fSupportsShrinkFromFront = DoesVolumeSupportShrinkFromFront( wcsPath );
  234. ciDebugOut(( DEB_ITRACE, "supports SFF: %d\n", _fSupportsShrinkFromFront ));
  235. } //CiStorage
  236. //+-------------------------------------------------------------------------
  237. //
  238. // Member: CiStorage::~CiStorage, public
  239. //
  240. // Synopsis: Destroys physical storage.
  241. //
  242. // Effects: Has *no* effect on open indexes.
  243. //
  244. // History: 07-Mar-92 KyleP Created
  245. //
  246. //--------------------------------------------------------------------------
  247. CiStorage::~CiStorage()
  248. {
  249. }
  250. const WCHAR CiStorage::_aHexDigit[] = L"0123456789ABCDEF";
  251. //+-------------------------------------------------------------------------
  252. //
  253. // Member: CiStorage::MakePath, private
  254. //
  255. // Synopsis: Creates an index, dir, hash or prop path.
  256. //
  257. // Arguments: [type] -- Index, dir, etc.
  258. // [iid] -- Index ID.
  259. // [wcsIndex] -- Output path
  260. //
  261. // History: 07-Mar-92 KyleP Created
  262. // 28-Dec-95 KyleP Collapsed four routines into one
  263. //
  264. //--------------------------------------------------------------------------
  265. void CiStorage::MakePath( CiStorage::EPathType type, WORKID iid, WCHAR * wcsIndex )
  266. {
  267. //
  268. // Construct a path for the new index.
  269. //
  270. wcscpy( wcsIndex, _xPath.GetPointer() );
  271. int len = wcslen( wcsIndex );
  272. wcsIndex[len++] = L'\\';
  273. for ( int i = 7; i >= 0; i-- )
  274. {
  275. wcsIndex[len++] = _aHexDigit[ (iid >> (4 * i)) & 0xF ];
  276. }
  277. wcsIndex[len] = 0;
  278. Win4Assert( len < MAX_PATH );
  279. switch ( type )
  280. {
  281. case CiStorage::eIndexPath:
  282. wcscat( wcsIndex, L".ci" );
  283. break;
  284. case CiStorage::eHashPath:
  285. wcscat( wcsIndex, L".hsh" );
  286. break;
  287. case CiStorage::ePrimaryPropPath:
  288. wcscat( wcsIndex, L".ps1" );
  289. break;
  290. case CiStorage::eSecondaryPropPath:
  291. wcscat( wcsIndex, L".ps2" );
  292. break;
  293. case CiStorage::eDirPath:
  294. wcscat( wcsIndex, L".dir" );
  295. break;
  296. }
  297. ciDebugOut(( DEB_ITRACE, "Physical index name: %ws\n", wcsIndex ));
  298. }
  299. PStorageObject* CiStorage::QueryObject( WORKID objectId )
  300. {
  301. return new CiStorageObject(objectId);
  302. }
  303. //+---------------------------------------------------------------------------
  304. //
  305. // Function: QueryIdxTableObject
  306. //
  307. // Synopsis: Returns an "Index Table" as a "Recoverable Storage Object"
  308. //
  309. // Returns: Pointer to a recoverable storage object allocated from the
  310. // heap. It is the responsibiity of the caller to destroy the
  311. // object.
  312. //
  313. // History: 2-25-94 srikants Created
  314. // 27-Oct-98 KLam Pass cMegToLeaveOnDisk to CiRcovStorageObj
  315. //
  316. //----------------------------------------------------------------------------
  317. PRcovStorageObj * CiStorage::QueryIdxTableObject()
  318. {
  319. WCHAR wcsHdr[MAX_PATH];
  320. WCHAR wcsCopy1[MAX_PATH];
  321. WCHAR wcsCopy2[MAX_PATH];
  322. MakeLogPath( CAT_IDXTABLE_HDR, wcsHdr );
  323. MakeLogPath( CAT_IDXTABLE_CP1, wcsCopy1 );
  324. MakeLogPath( CAT_IDXTABLE_CP2, wcsCopy2 );
  325. return new CiRcovStorageObj( *this,
  326. wcsHdr,
  327. wcsCopy1,
  328. wcsCopy2,
  329. _cMegToLeaveOnDisk,
  330. _fIsReadOnly);
  331. }
  332. //+-------------------------------------------------------------------------
  333. //--------------------------------------------------------------------------
  334. PIndexTable* CiStorage::QueryIndexTable ( CTransaction& xact )
  335. {
  336. return new CIndexTable ( *this, xact );
  337. }
  338. //+-------------------------------------------------------------------------
  339. //--------------------------------------------------------------------------
  340. PMmStream* CiStorage::QueryNewIndexStream( PStorageObject& obj,
  341. BOOL isSparse )
  342. {
  343. WCHAR wcsIndex [ MAX_PATH ];
  344. MakePath( eIndexPath, CI_OBJ(obj).ObjectId(), wcsIndex );
  345. XPtr<PMmStream> xStream;
  346. //
  347. // If it's a master index and the storage supports sparse streams, make
  348. // the stream sparse.
  349. //
  350. BOOL fSparse = ( isSparse && _fSupportsShrinkFromFront );
  351. ciDebugOut(( DEB_ITRACE, "opening new %s stream '%ws'\n",
  352. isSparse ? "master" : "shadow",
  353. wcsIndex ));
  354. if ( fSparse )
  355. {
  356. CLockingMmStream * pLockingMmStream = new CLockingMmStream( _cMegToLeaveOnDisk );
  357. xStream.Set( pLockingMmStream );
  358. pLockingMmStream->Open( wcsIndex,
  359. GENERIC_READ | GENERIC_WRITE,
  360. FILE_SHARE_READ|FILE_SHARE_WRITE,
  361. CREATE_NEW, // File cannot already exist.
  362. FILE_ATTRIBUTE_NORMAL,
  363. TRUE ); // sparse file
  364. }
  365. else
  366. {
  367. CMmStream * pMmStream = new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly );
  368. xStream.Set( pMmStream );
  369. pMmStream->Open( wcsIndex,
  370. GENERIC_READ | GENERIC_WRITE,
  371. FILE_SHARE_READ|FILE_SHARE_WRITE,
  372. CREATE_NEW, // File cannot already exist.
  373. FILE_ATTRIBUTE_NORMAL,
  374. FALSE ); // non-sparse file
  375. }
  376. return xStream.Acquire();
  377. }
  378. //+---------------------------------------------------------------------------
  379. //
  380. // Function: QueryExistingIndexStream
  381. //
  382. // Synopsis: Returns an "existing" index stream as a memory mapped
  383. // stream.
  384. //
  385. // Arguments: [obj] -- The storage object associated with the main
  386. // object containing the stream.
  387. // [mode] -- The open mode: read/write
  388. //
  389. // History: 4-20-94 srikants Added fWrite parameter.
  390. // 2-18-98 kitmanh Ignore fWrite for readOnly catalogs
  391. //
  392. // Notes: The fWrite parameter was used for supporting a restartable
  393. // master merge for which an existing index stream must be
  394. // opened for write access. Otherwise, all existing streams are
  395. // normally opened for read access only.
  396. //
  397. //----------------------------------------------------------------------------
  398. PMmStream* CiStorage::QueryExistingIndexStream ( PStorageObject& obj,
  399. PStorage::EOpenMode mode )
  400. {
  401. WCHAR wcsIndex [ MAX_PATH ];
  402. MakePath( eIndexPath, CI_OBJ(obj).ObjectId(), wcsIndex );
  403. BOOL fWrite = _fIsReadOnly ? FALSE : (PStorage::eOpenForWrite == mode);
  404. DWORD dwAccess = fWrite ? (GENERIC_READ | GENERIC_WRITE) : (GENERIC_READ);
  405. ciDebugOut(( DEB_ITRACE, "opening existing %s stream '%ws'\n",
  406. fWrite ? "write" : "read",
  407. wcsIndex ));
  408. XPtr<PMmStream> xStream;
  409. if ( fWrite )
  410. {
  411. CLockingMmStream * pLockingMmStream = new CLockingMmStream( _cMegToLeaveOnDisk );
  412. xStream.Set( pLockingMmStream );
  413. pLockingMmStream->Open( wcsIndex,
  414. dwAccess, // Access flags
  415. FILE_SHARE_READ | FILE_SHARE_WRITE,
  416. OPEN_EXISTING, // File must already exist.
  417. FILE_ATTRIBUTE_NORMAL,
  418. fWrite && _fSupportsShrinkFromFront ); // sparse
  419. }
  420. else
  421. {
  422. dwAccess = _fIsReadOnly ? GENERIC_READ : dwAccess;
  423. CMmStream * pMmStream = new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly );
  424. xStream.Set( pMmStream );
  425. pMmStream->Open( wcsIndex,
  426. dwAccess, // Access flags
  427. FILE_SHARE_READ | FILE_SHARE_WRITE,
  428. OPEN_EXISTING, // File must already exist.
  429. FILE_ATTRIBUTE_NORMAL,
  430. FALSE ); // sparse
  431. }
  432. return xStream.Acquire();
  433. }
  434. //+-------------------------------------------------------------------------
  435. //--------------------------------------------------------------------------
  436. PMmStream * CiStorage::DupExistingIndexStream( PStorageObject& obj,
  437. PMmStream & mmStream,
  438. EOpenMode mode )
  439. {
  440. return new CDupStream( (CLockingMmStream &) mmStream );
  441. }
  442. //+-------------------------------------------------------------------------
  443. //
  444. // Method: CiStorage::QueryNewHashStream
  445. //
  446. // Synopsis: Creates hash stream
  447. //
  448. // Arguments: [obj] -- Object holding stream
  449. //
  450. // Returns: Stream
  451. //
  452. // History: 17-Feb-1994 KyleP Created
  453. //
  454. //--------------------------------------------------------------------------
  455. PMmStream* CiStorage::QueryNewHashStream ( PStorageObject& obj )
  456. {
  457. WCHAR wcsIndex [ MAX_PATH ];
  458. MakePath( eHashPath, CI_OBJ(obj).ObjectId(), wcsIndex );
  459. XPtr<CMmStream> xStream( new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly ) );
  460. xStream->Open( wcsIndex,
  461. GENERIC_READ | GENERIC_WRITE, // Access flags
  462. 0, // Sharing flags
  463. CREATE_NEW, // File cannot already exist.
  464. FILE_ATTRIBUTE_NORMAL );
  465. return xStream.Acquire();
  466. }
  467. //+-------------------------------------------------------------------------
  468. //
  469. // Method: CiStorage::QueryExistingHashStream
  470. //
  471. // Synopsis: Opens existing hash stream
  472. //
  473. // Arguments: [obj] -- Object holding stream
  474. // [fWrite] -- Flag indicating if the stream must be opened
  475. // for write access; set to TRUE during a restarted
  476. // master merge.
  477. //
  478. // Returns: Stream
  479. //
  480. // History: 17-Feb-1994 KyleP Created
  481. //
  482. //--------------------------------------------------------------------------
  483. PMmStream* CiStorage::QueryExistingHashStream ( PStorageObject& obj,
  484. PStorage::EOpenMode mode )
  485. {
  486. WCHAR wcsIndex [ MAX_PATH ];
  487. MakePath( eHashPath, CI_OBJ(obj).ObjectId(), wcsIndex );
  488. XPtr<CMmStream> xStream( new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly ) );
  489. BOOL fWrite = PStorage::eOpenForWrite == mode;
  490. DWORD dwAccess = fWrite ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ;
  491. xStream->Open( wcsIndex,
  492. dwAccess, // Access flags
  493. FILE_SHARE_READ | FILE_SHARE_WRITE, // Sharing flags
  494. OPEN_EXISTING ); // File must already exist.
  495. return xStream.Acquire();
  496. }
  497. //+-------------------------------------------------------------------------
  498. //
  499. // Method: CiStorage::QueryNewPropStream
  500. //
  501. // Synopsis: Creates prop stream
  502. //
  503. // Arguments: [obj] -- Object holding stream
  504. //
  505. // Returns: Stream
  506. //
  507. // History: 17-Feb-1994 KyleP Created
  508. //
  509. //--------------------------------------------------------------------------
  510. PMmStream* CiStorage::QueryNewPropStream ( PStorageObject& obj, DWORD dwStoreLevel )
  511. {
  512. WCHAR wcsIndex [ MAX_PATH ];
  513. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  514. MakePath( (PRIMARY_STORE == dwStoreLevel) ? ePrimaryPropPath : eSecondaryPropPath,
  515. CI_OBJ(obj).ObjectId(), wcsIndex );
  516. XPtr<CMmStream> xStream( new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly ) );
  517. xStream->Open ( wcsIndex,
  518. GENERIC_READ | GENERIC_WRITE, // Access flags
  519. FILE_SHARE_READ | FILE_SHARE_WRITE, // Sharing flags
  520. CREATE_NEW, // File cannot already exist.
  521. FILE_ATTRIBUTE_NORMAL );
  522. return xStream.Acquire();
  523. }
  524. //+-------------------------------------------------------------------------
  525. //
  526. // Method: CiStorage::QueryExistingPropStream
  527. //
  528. // Synopsis: Opens existing prop stream
  529. //
  530. // Arguments: [obj] -- Object holding stream
  531. // [fWrite] -- Flag indicating if the stream must be opened
  532. // for write access; set to TRUE during a restarted
  533. // master merge.
  534. //
  535. // Returns: Stream
  536. //
  537. // History: 17-Feb-1994 KyleP Created
  538. //
  539. //--------------------------------------------------------------------------
  540. PMmStream* CiStorage::QueryExistingPropStream ( PStorageObject& obj,
  541. PStorage::EOpenMode mode,
  542. DWORD dwStoreLevel )
  543. {
  544. WCHAR wcsIndex [ MAX_PATH ];
  545. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  546. MakePath( (PRIMARY_STORE == dwStoreLevel) ? ePrimaryPropPath : eSecondaryPropPath,
  547. CI_OBJ(obj).ObjectId(), wcsIndex );
  548. XPtr<CMmStream> xStream( new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly ) );
  549. BOOL fWrite = PStorage::eOpenForWrite == mode;
  550. DWORD dwAccess = fWrite ? GENERIC_READ | GENERIC_WRITE : GENERIC_READ;
  551. xStream->Open ( wcsIndex,
  552. dwAccess, // Access flags
  553. FILE_SHARE_READ | FILE_SHARE_WRITE, // Sharing flags
  554. OPEN_EXISTING); // File must already exist.
  555. return xStream.Acquire();
  556. }
  557. //+-------------------------------------------------------------------------
  558. //
  559. // Method: CiStorage::QueryNewPSBkpStream, public
  560. //
  561. // Synopsis: Creates property store backup stream.
  562. //
  563. // Arguments: [obj] -- Object holding stream
  564. // [ulMaxPages] -- Max pages to backup
  565. //
  566. // Returns: Property store backup stream
  567. //
  568. // History: 30-May-97 KrishnaN Created
  569. // 29-Oct-98 KLam Pass _cMegToLeaveOnDisk to
  570. // CPropStoreBackupStream
  571. //
  572. // Notes: This method can be called either to create a backup file when a
  573. // catalog is being created for the first time or when a catalog is
  574. // being opened at CI startup. In the latter case it will be called
  575. // after the existing backup file is already used, if necessary. Once
  576. // the backup file is used, it can be run over.
  577. //
  578. //--------------------------------------------------------------------------
  579. CPropStoreBackupStream* CiStorage::QueryNewPSBkpStream( PStorageObject& obj,
  580. ULONG ulMaxPages,
  581. DWORD dwStoreLevel )
  582. {
  583. Win4Assert( wcslen( PROP_BKP_FILE1 ) == wcslen( PROP_BKP_FILE2 ) );
  584. unsigned cwc = wcslen( _xPath.GetPointer() ) + wcslen( PROP_BKP_FILE1 );
  585. if ( cwc >= MAX_PATH )
  586. THROW( CException( STATUS_INVALID_PARAMETER ) );
  587. WCHAR wcsIndex [ MAX_PATH ];
  588. wcscpy(wcsIndex, _xPath.GetPointer() );
  589. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  590. wcscat(wcsIndex, (PRIMARY_STORE == dwStoreLevel) ? PROP_BKP_FILE1 : PROP_BKP_FILE2 );
  591. XPtr<CPropStoreBackupStream> xStream( new CPropStoreBackupStream( _cMegToLeaveOnDisk ) );
  592. xStream->OpenForBackup ( wcsIndex,
  593. FILE_SHARE_READ | FILE_SHARE_WRITE, // Sharing flags
  594. CREATE_ALWAYS, // File may already exist, but we'll run over it.
  595. ulMaxPages);
  596. Win4Assert(xStream.GetPointer());
  597. return xStream.Acquire();
  598. }
  599. //+-------------------------------------------------------------------------
  600. //
  601. // Method: CiStorage::OpenExistingPSBkpStreamForRecovery, public
  602. //
  603. // Synopsis: Opens existing property store backup stream for recovery.
  604. //
  605. // Arguments: [obj] -- Object holding stream
  606. //
  607. // Returns: Property store backup stream
  608. //
  609. // History: 30-May-97 KrishnaN Created
  610. // 29-Oct-98 KLam Pass _cMegToLeaveOnDisk to
  611. // CPropStoreBackupStream
  612. //
  613. //--------------------------------------------------------------------------
  614. CPropStoreBackupStream* CiStorage::OpenExistingPSBkpStreamForRecovery(PStorageObject& obj,
  615. DWORD dwStoreLevel)
  616. {
  617. Win4Assert( wcslen( PROP_BKP_FILE1 ) == wcslen( PROP_BKP_FILE2 ) );
  618. unsigned cwc = wcslen( _xPath.GetPointer() ) + wcslen( PROP_BKP_FILE1 );
  619. if ( cwc >= MAX_PATH )
  620. THROW( CException( STATUS_INVALID_PARAMETER ) );
  621. WCHAR wcsIndex [ MAX_PATH ];
  622. wcscpy(wcsIndex, _xPath.GetPointer() );
  623. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  624. wcscat(wcsIndex, (PRIMARY_STORE == dwStoreLevel) ? PROP_BKP_FILE1 : PROP_BKP_FILE2 );
  625. XPtr<CPropStoreBackupStream> xStream( new CPropStoreBackupStream( _cMegToLeaveOnDisk ) );
  626. xStream->OpenForRecovery( wcsIndex, FILE_SHARE_READ); // Sharing flags
  627. Win4Assert(xStream.GetPointer());
  628. return xStream.Acquire();
  629. }
  630. //+-------------------------------------------------------------------------
  631. //--------------------------------------------------------------------------
  632. PDirectory* CiStorage::QueryNewDirectory( PStorageObject& obj )
  633. {
  634. return new CiDirectory( *this,
  635. CI_OBJ(obj).ObjectId(),
  636. PStorage::eCreate );
  637. }
  638. //+---------------------------------------------------------------------------
  639. //
  640. // Function: QueryExistingDirectory
  641. //
  642. // Synopsis: Returns an existing directory stream for an index.
  643. //
  644. // Arguments: [obj] -- Storage object.
  645. // [fWrite] -- Flag indicating if the stream must be opened
  646. // for write access or for read access.
  647. //
  648. // History: 4-20-94 srikants Added fWrite parameter
  649. //
  650. // Notes: fWrite parameter was added to support restartable master
  651. // merge.
  652. //
  653. //----------------------------------------------------------------------------
  654. PDirectory* CiStorage::QueryExistingDirectory( PStorageObject& obj,
  655. PStorage::EOpenMode mode )
  656. {
  657. return new CiDirectory ( *this, CI_OBJ(obj).ObjectId(), mode );
  658. }
  659. //+-------------------------------------------------------------------------
  660. //--------------------------------------------------------------------------
  661. PMmStream* CiStorage::QueryNewDirStream ( WORKID iid )
  662. {
  663. WCHAR wcsDir [ MAX_PATH ];
  664. MakePath( eDirPath, iid, wcsDir );
  665. XPtr<CMmStream> xStream( new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly ) );
  666. xStream->Open ( wcsDir,
  667. GENERIC_READ | GENERIC_WRITE, // Access flags
  668. FILE_SHARE_READ, // Sharing flags
  669. CREATE_NEW, // File cannot already exist.
  670. FILE_ATTRIBUTE_NORMAL );
  671. return xStream.Acquire();
  672. }
  673. //+-------------------------------------------------------------------------
  674. //--------------------------------------------------------------------------
  675. PMmStream* CiStorage::QueryExistingDirStream ( WORKID iid, BOOL fWrite )
  676. {
  677. WCHAR wcsDir [ MAX_PATH ];
  678. MakePath( eDirPath, iid, wcsDir );
  679. XPtr<CMmStream> xStream( new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly ) );
  680. if ( _fIsReadOnly )
  681. fWrite = FALSE;
  682. DWORD dwAccess = fWrite ? (GENERIC_READ | GENERIC_WRITE) : GENERIC_READ;
  683. xStream->Open( wcsDir,
  684. dwAccess, // Access flags
  685. FILE_SHARE_READ | FILE_SHARE_WRITE, // Sharing flags
  686. OPEN_EXISTING ); // File must already exist.
  687. return xStream.Acquire();
  688. }
  689. //+-------------------------------------------------------------------------
  690. //--------------------------------------------------------------------------
  691. BOOL CiStorage::RemoveObject( WORKID iid )
  692. {
  693. WCHAR wcsIndex [ MAX_PATH ];
  694. //
  695. // Delete index
  696. //
  697. MakePath( eIndexPath, iid, wcsIndex );
  698. BOOL fSuccess = DeleteFile( wcsIndex );
  699. //
  700. // and directory
  701. //
  702. MakePath( eDirPath, iid, wcsIndex );
  703. fSuccess = fSuccess && DeleteFile( wcsIndex );
  704. //
  705. // and maybe hash
  706. //
  707. MakePath( eHashPath, iid, wcsIndex );
  708. if ( !DeleteFile( wcsIndex ) )
  709. fSuccess = fSuccess && (GetLastError() == ERROR_FILE_NOT_FOUND);
  710. //
  711. // and maybe prop
  712. //
  713. MakePath( ePrimaryPropPath, iid, wcsIndex );
  714. if ( !DeleteFile( wcsIndex ) )
  715. fSuccess = fSuccess && (GetLastError() == ERROR_FILE_NOT_FOUND);
  716. MakePath( eSecondaryPropPath, iid, wcsIndex );
  717. if ( !DeleteFile( wcsIndex ) )
  718. fSuccess = fSuccess && (GetLastError() == ERROR_FILE_NOT_FOUND);
  719. return fSuccess;
  720. }
  721. //+-------------------------------------------------------------------------
  722. //
  723. // Member: CiStorage::MakeLogPath, private
  724. //
  725. // Synopsis: Create a fully qualified path for which to store the
  726. // persistent log.
  727. //
  728. // Arguments: [wcsName] -- name of logfile to append to path
  729. // [wcsPath] -- (out) resulting fully qualified name
  730. //
  731. // Notes: It is assumed that wcsPath is large enough to hold the
  732. // name + path
  733. //
  734. // History: 18-Nov-93 DwightKr Created
  735. //
  736. //--------------------------------------------------------------------------
  737. void CiStorage::MakeLogPath(WCHAR * wcsName, WCHAR * wcsPath)
  738. {
  739. wcscpy(wcsPath, _xPath.GetPointer());
  740. wcscat(wcsPath, wcsName);
  741. Win4Assert( wcslen(wcsPath) < MAX_PATH );
  742. }
  743. //+-------------------------------------------------------------------------
  744. //
  745. // Member: CiStorage::QueryFreshLog, public
  746. //
  747. // Synopsis: Builds a new persistent freshlog, using the specified name
  748. //
  749. // Arguments: [wcsName] -- name to use for new stream
  750. //
  751. // Returns: a new CPersStream * object
  752. //
  753. // History: 19-Nov-93 DwightKr Created
  754. // 27-Oct-98 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  755. //
  756. //--------------------------------------------------------------------------
  757. PRcovStorageObj * CiStorage::QueryFreshLog(WORKID wid)
  758. {
  759. WCHAR wcsHdr[MAX_PATH];
  760. WCHAR wcsCopy1[MAX_PATH];
  761. WCHAR wcsCopy2[MAX_PATH];
  762. FormRcovObjNames( wid, FRESHLOG_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  763. return new CiRcovStorageObj( *this,
  764. wcsHdr,
  765. wcsCopy1,
  766. wcsCopy2,
  767. _cMegToLeaveOnDisk,
  768. _fIsReadOnly);
  769. }
  770. //+---------------------------------------------------------------------------
  771. //----------------------------------------------------------------------------
  772. BOOL CiStorage::RemoveFreshLog(WORKID wid)
  773. {
  774. WCHAR wcsHdr[MAX_PATH];
  775. WCHAR wcsCopy1[MAX_PATH];
  776. WCHAR wcsCopy2[MAX_PATH];
  777. FormRcovObjNames( wid, FRESHLOG_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  778. DeleteFile( wcsHdr );
  779. DeleteFile( wcsCopy1 );
  780. DeleteFile( wcsCopy2 );
  781. return(TRUE);
  782. }
  783. //+---------------------------------------------------------------------------
  784. //
  785. // Function: QueryChangeLog
  786. //
  787. // Synopsis: Creates a recoverable storage object for testing.
  788. //
  789. // History: 2-08-94 DwightKr Created
  790. // 4-20-94 SrikantS Modified to use the common
  791. // FormRcovObjNames method.
  792. // 27-Oct-98 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  793. //
  794. // Notes: For down level storage, the WID is really the partition ID.
  795. //
  796. //----------------------------------------------------------------------------
  797. PRcovStorageObj * CiStorage::QueryChangeLog( WORKID wid, EChangeLogType type )
  798. {
  799. WCHAR wcsHdr[MAX_PATH];
  800. WCHAR wcsCopy1[MAX_PATH];
  801. WCHAR wcsCopy2[MAX_PATH];
  802. if ( ePrimChangeLog == type )
  803. {
  804. FormRcovObjNames( wid, PRI_CHANGELOG_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  805. }
  806. else
  807. {
  808. FormRcovObjNames( wid, SEC_CHANGELOG_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  809. }
  810. return new CiRcovStorageObj( *this,
  811. wcsHdr,
  812. wcsCopy1,
  813. wcsCopy2,
  814. _cMegToLeaveOnDisk,
  815. _fIsReadOnly );
  816. }
  817. //+-------------------------------------------------------------------------
  818. //--------------------------------------------------------------------------
  819. PRcovStorageObj * CiStorage::QueryRecoverableLog(WORKID wid)
  820. {
  821. Win4Assert(!"QueryRecoverableLog() not supported in class CiStorage");
  822. PRcovStorageObj *a = 0;
  823. return a;
  824. }
  825. //+-------------------------------------------------------------------------
  826. //
  827. // Member: CiStorage::QueryPidLookupTable, public
  828. //
  829. // Synopsis: Builds a new persistent storage object for PID mapping.
  830. //
  831. // Arguments: [wid] -- WorkId of the object. For downlevel, only
  832. // the upper 4 bytes are used as the "partition id" that the
  833. // object belongs to. It is assumed that the upper 4 bytes of
  834. // the wid contain the partition id.
  835. //
  836. // Returns: a new CPersStream * object
  837. //
  838. // History: 05 Jan 1996 Alanw Created
  839. // 27 Oct 1998 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  840. //
  841. //--------------------------------------------------------------------------
  842. PRcovStorageObj * CiStorage::QueryPidLookupTable(WORKID wid)
  843. {
  844. WCHAR wcsHdr[MAX_PATH];
  845. WCHAR wcsCopy1[MAX_PATH];
  846. WCHAR wcsCopy2[MAX_PATH];
  847. FormRcovObjNames( wid, PIDTABLE_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  848. return new CiRcovStorageObj( *this,
  849. wcsHdr,
  850. wcsCopy1,
  851. wcsCopy2,
  852. _cMegToLeaveOnDisk,
  853. _fIsReadOnly );
  854. }
  855. //+-------------------------------------------------------------------------
  856. //
  857. // Member: CiStorage::QuerySdidLookupTable, public
  858. //
  859. // Synopsis: Builds a new persistent storage object for SDID mapping.
  860. //
  861. // Arguments: [wid] -- WorkId of the object. For downlevel, only
  862. // the upper 4 bytes are used as the "partition id" that the
  863. // object belongs to. It is assumed that the upper 4 bytes of
  864. // the wid contain the partition id.
  865. //
  866. // Returns: a new CPersStream * object
  867. //
  868. // History: 29 Jan 1996 Alanw Created
  869. // 27 Oct 1998 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  870. //
  871. //--------------------------------------------------------------------------
  872. PRcovStorageObj * CiStorage::QuerySdidLookupTable(WORKID wid)
  873. {
  874. WCHAR wcsHdr[MAX_PATH];
  875. WCHAR wcsCopy1[MAX_PATH];
  876. WCHAR wcsCopy2[MAX_PATH];
  877. FormRcovObjNames( wid, SECSTORE_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  878. return new CiRcovStorageObj( *this,
  879. wcsHdr,
  880. wcsCopy1,
  881. wcsCopy2,
  882. _cMegToLeaveOnDisk,
  883. _fIsReadOnly );
  884. }
  885. //+---------------------------------------------------------------------------
  886. //
  887. // Function: FormRcovObjNames
  888. //
  889. // Synopsis: Forms the down-level names for the three streams that make up
  890. // a recoverable object. This method can be used for creating
  891. // names for objects that exist on a "per partition" basis.
  892. //
  893. // Arguments: [wid] -- WorkId of the object. For downlevel, only
  894. // the upper 4 bytes are used as the "partition id" that the
  895. // object belongs to. It is assumed that the upper 4 bytes of
  896. // the wid contain the partition id.
  897. // [wcsPrefix] -- A 5 character prefix for the object name.
  898. // Must begin with a "\\". (That will leave 4 chars for name.)
  899. // [wcsHdr] -- On output will contain the file name for the
  900. // atomic header.
  901. // [wcsCopy1] -- On output will contain the name of the first
  902. // copy.
  903. // [wcsCopy2] -- On output, will contain the name of the
  904. // second copy.
  905. //
  906. // History: 4-20-94 srikants Created
  907. //
  908. // Notes:
  909. //
  910. //----------------------------------------------------------------------------
  911. void CiStorage::FormRcovObjNames( WORKID wid, WCHAR * wcsPrefix,
  912. WCHAR * wcsHdr, WCHAR * wcsCopy1,
  913. WCHAR * wcsCopy2 )
  914. {
  915. Win4Assert( wcslen(wcsPrefix) == 5 ); // extra char is for "\\"
  916. WCHAR wcsTemp[_MAX_FNAME+1];
  917. CIndexId iid(wid);
  918. Win4Assert( iid.PartId() <= 0x0000FFFF );
  919. swprintf(wcsTemp, L"%5s%4.4x.000", wcsPrefix, iid.PartId() );
  920. MakeLogPath( wcsTemp, wcsHdr );
  921. swprintf(wcsTemp, L"%5s%4.4x.001", wcsPrefix, iid.PartId() );
  922. MakeLogPath( wcsTemp, wcsCopy1 );
  923. swprintf(wcsTemp, L"%5s%4.4x.002", wcsPrefix, iid.PartId() );
  924. MakeLogPath( wcsTemp, wcsCopy2 );
  925. }
  926. //+---------------------------------------------------------------------------
  927. //
  928. // Function: QueryMMergeLog
  929. //
  930. // Synopsis: Returns a Master Merge Log object created on the heap.
  931. //
  932. // Arguments: [wid] -- WorkId of the master merge log. Only the upper
  933. // 4 bytes are used as the partition id.
  934. //
  935. // History: 4-20-94 srikants Created
  936. // 27-Oct-98 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  937. //
  938. // Notes:
  939. //
  940. //----------------------------------------------------------------------------
  941. PRcovStorageObj * CiStorage::QueryMMergeLog( WORKID wid )
  942. {
  943. WCHAR wcsHdr[MAX_PATH];
  944. WCHAR wcsCopy1[MAX_PATH];
  945. WCHAR wcsCopy2[MAX_PATH];
  946. FormRcovObjNames( wid, MMLOG_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  947. return new CiRcovStorageObj( *this,
  948. wcsHdr,
  949. wcsCopy1,
  950. wcsCopy2,
  951. _cMegToLeaveOnDisk,
  952. _fIsReadOnly );
  953. }
  954. //+---------------------------------------------------------------------------
  955. //
  956. // Function: QueryPropStore
  957. //
  958. // Synopsis: Returns a property store table
  959. //
  960. // Arguments: [wid] -- WorkId of the property store table. Only the upper
  961. // 4 bytes are used as the partition id.
  962. //
  963. // History: 27-Dec-94 KyleP Created
  964. // 27-Oct-98 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  965. //
  966. //----------------------------------------------------------------------------
  967. PRcovStorageObj * CiStorage::QueryPropStore( WORKID wid, DWORD dwStoreLevel )
  968. {
  969. WCHAR wcsHdr[MAX_PATH];
  970. WCHAR wcsCopy1[MAX_PATH];
  971. WCHAR wcsCopy2[MAX_PATH];
  972. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  973. FormRcovObjNames( wid,
  974. (PRIMARY_STORE == dwStoreLevel) ? PROPSTORE1_PREFIX : PROPSTORE2_PREFIX,
  975. wcsHdr, wcsCopy1, wcsCopy2 );
  976. return new CiRcovStorageObj( *this,
  977. wcsHdr,
  978. wcsCopy1,
  979. wcsCopy2,
  980. _cMegToLeaveOnDisk,
  981. _fIsReadOnly );
  982. }
  983. //+---------------------------------------------------------------------------
  984. //
  985. // Member: CiStorage::RemovePropStore
  986. //
  987. // Synopsis: Removes the PropStore header files.
  988. //
  989. // Arguments: [wid] -- WorkId of the property store table. Only the upper
  990. // 4 bytes are used as the partition id.
  991. //
  992. // History: 3-26-97 srikants Created
  993. //
  994. //----------------------------------------------------------------------------
  995. void CiStorage::RemovePropStore( WORKID wid, DWORD dwStoreLevel )
  996. {
  997. WCHAR wcsHdr[MAX_PATH];
  998. WCHAR wcsCopy1[MAX_PATH];
  999. WCHAR wcsCopy2[MAX_PATH];
  1000. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  1001. FormRcovObjNames( wid,
  1002. (PRIMARY_STORE == dwStoreLevel) ? PROPSTORE1_PREFIX : PROPSTORE2_PREFIX,
  1003. wcsHdr, wcsCopy1, wcsCopy2 );
  1004. DeleteFile( wcsHdr );
  1005. DeleteFile( wcsCopy1);
  1006. DeleteFile( wcsCopy2 );
  1007. }
  1008. //+---------------------------------------------------------------------------
  1009. //
  1010. // Member: CiStorage::RemoveSecStore
  1011. //
  1012. // Synopsis: Removes the security store files.
  1013. //
  1014. // Arguments: [wid] -- Workid of the security store table.
  1015. //
  1016. // History: 7-14-97 srikants Created
  1017. //
  1018. //----------------------------------------------------------------------------
  1019. void CiStorage::RemoveSecStore( WORKID wid )
  1020. {
  1021. WCHAR wcsHdr[MAX_PATH];
  1022. WCHAR wcsCopy1[MAX_PATH];
  1023. WCHAR wcsCopy2[MAX_PATH];
  1024. FormRcovObjNames( wid, SECSTORE_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  1025. DeleteFile( wcsHdr );
  1026. DeleteFile( wcsCopy1);
  1027. DeleteFile( wcsCopy2 );
  1028. }
  1029. //+---------------------------------------------------------------------------
  1030. //
  1031. // Member: CiStorage::QueryScopeList
  1032. //
  1033. // Synopsis: Returns CI scopes list table
  1034. //
  1035. // Arguments: [wid] - Workid of the scopes list table.
  1036. //
  1037. // History: 1-19-96 srikants Created
  1038. // 27-Oct-98 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  1039. //
  1040. // Notes:
  1041. //
  1042. //----------------------------------------------------------------------------
  1043. PRcovStorageObj * CiStorage::QueryScopeList( WORKID wid )
  1044. {
  1045. WCHAR wcsHdr[MAX_PATH];
  1046. WCHAR wcsCopy1[MAX_PATH];
  1047. WCHAR wcsCopy2[MAX_PATH];
  1048. FormRcovObjNames( wid, SCOPELIST_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  1049. return new CiRcovStorageObj( *this,
  1050. wcsHdr,
  1051. wcsCopy1,
  1052. wcsCopy2,
  1053. _cMegToLeaveOnDisk,
  1054. _fIsReadOnly );
  1055. }
  1056. //+---------------------------------------------------------------------------
  1057. //
  1058. // Member: CiStorage::QueryVirtualScopeList
  1059. //
  1060. // Synopsis: Returns CI virtual scopes list table
  1061. //
  1062. // Arguments: [wid] - Workid of the virtual scopes list table.
  1063. //
  1064. // History: 2-05-96 KyleP Created
  1065. // 27-Oct-98 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  1066. //
  1067. //----------------------------------------------------------------------------
  1068. PRcovStorageObj * CiStorage::QueryVirtualScopeList( WORKID wid )
  1069. {
  1070. WCHAR wcsHdr[MAX_PATH];
  1071. WCHAR wcsCopy1[MAX_PATH];
  1072. WCHAR wcsCopy2[MAX_PATH];
  1073. FormRcovObjNames( wid, VSCOPELIST_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  1074. return new CiRcovStorageObj( *this,
  1075. wcsHdr,
  1076. wcsCopy1,
  1077. wcsCopy2,
  1078. _cMegToLeaveOnDisk,
  1079. _fIsReadOnly );
  1080. }
  1081. //+---------------------------------------------------------------------------
  1082. //
  1083. // Function: RemoveMMLog
  1084. //
  1085. // Synopsis: Deletes the specified master log object.
  1086. //
  1087. // Arguments: [wid] -- WorkId of the master merge log. Only the upper
  1088. // 4 bytes are used as the partition id.
  1089. //
  1090. // History: 4-20-94 srikants Created
  1091. //
  1092. //----------------------------------------------------------------------------
  1093. BOOL CiStorage::RemoveMMLog( WORKID wid )
  1094. {
  1095. WCHAR wcsHdr[MAX_PATH];
  1096. WCHAR wcsCopy1[MAX_PATH];
  1097. WCHAR wcsCopy2[MAX_PATH];
  1098. FormRcovObjNames( wid, MMLOG_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  1099. DeleteFile( wcsHdr );
  1100. DeleteFile( wcsCopy1 );
  1101. DeleteFile( wcsCopy2 );
  1102. return(TRUE);
  1103. }
  1104. //+---------------------------------------------------------------------------
  1105. //
  1106. // Function: QueryTestLog
  1107. //
  1108. // Synopsis: Creates a recoverable storage object for testing.
  1109. //
  1110. // History: 2-08-94 srikants Created
  1111. // 27-Oct-98 KLam Pass _cMegToLeaveOnDisk to CiRcovStorageObj
  1112. //
  1113. //----------------------------------------------------------------------------
  1114. PRcovStorageObj * CiStorage::QueryTestLog()
  1115. {
  1116. WCHAR wcsHdr[MAX_PATH];
  1117. WCHAR wcsCopy1[MAX_PATH];
  1118. WCHAR wcsCopy2[MAX_PATH];
  1119. MakeLogPath( CAT_TESTLOG_HDR, wcsHdr );
  1120. MakeLogPath( CAT_TESTLOG_CP1, wcsCopy1 );
  1121. MakeLogPath( CAT_TESTLOG_CP2, wcsCopy2 );
  1122. return new CiRcovStorageObj( *this,
  1123. wcsHdr,
  1124. wcsCopy1,
  1125. wcsCopy2,
  1126. _cMegToLeaveOnDisk,
  1127. _fIsReadOnly );
  1128. }
  1129. //+---------------------------------------------------------------------------
  1130. //
  1131. // Function: GetDiskSpace
  1132. //
  1133. // Synopsis: Returns the disk size & space remaining, in bytes
  1134. // Takes into consideration the space to leave on disk
  1135. //
  1136. // History: 31-Jul-94 DwightKr Created
  1137. // 27-Oct-98 KLam Compensates for DiskSpaceToLeave
  1138. // Forwards call to drive info
  1139. //
  1140. //----------------------------------------------------------------------------
  1141. void CiStorage::GetDiskSpace( __int64 & diskTotal,
  1142. __int64 & diskRemaining )
  1143. {
  1144. _driveInfo.GetDiskSpace ( diskTotal, diskRemaining );
  1145. }
  1146. //+---------------------------------------------------------------------------
  1147. //
  1148. // Member: CiStorage::ReportCorruptComponent, public
  1149. //
  1150. // Synopsis: Generates meaningful error message on storage corruption.
  1151. //
  1152. // Arguments: [pwszString] -- Error message
  1153. //
  1154. // History: 21-Jul-97 KyleP Move from header
  1155. //
  1156. //----------------------------------------------------------------------------
  1157. void CiStorage::ReportCorruptComponent( WCHAR const * pwszString )
  1158. {
  1159. if ( !_fCorruptionReported )
  1160. {
  1161. CFwCorruptionEvent event( GetVolumeName(), pwszString, _adviseStatus );
  1162. _fCorruptionReported = TRUE;
  1163. }
  1164. }
  1165. //+---------------------------------------------------------------------------
  1166. //
  1167. // Function: GetNewObjectIdForFreshLog
  1168. //
  1169. // Synopsis: Forms a new object id for the fresh log. It uses a pool of
  1170. // two ids and returns the one that is currently not in use.
  1171. //
  1172. // Returns: ObjectId for a new fresh log.
  1173. //
  1174. // History: 10-05-94 srikants Created
  1175. //
  1176. // Notes:
  1177. //
  1178. //----------------------------------------------------------------------------
  1179. WORKID CiStorage::GetNewObjectIdForFreshLog()
  1180. {
  1181. CIndexId iidCurr( _widFreshLog );
  1182. PARTITIONID partIdNew = partidFresh1 == iidCurr.PartId() ?
  1183. partidFresh2 : partidFresh1;
  1184. CIndexId iidNew( itFreshLog, partIdNew );
  1185. return( CreateObjectId( iidNew, PStorage::eRcovHdr ) );
  1186. }
  1187. //+---------------------------------------------------------------------------
  1188. //
  1189. // Function: SetSpecialItObjectId
  1190. //
  1191. // Synopsis: Sets the object id of the special index type.
  1192. //
  1193. // Arguments: [it] -- Index Type
  1194. // [wid] -- WorkId for this index type.
  1195. //
  1196. // History: 10-05-94 srikants Created
  1197. //
  1198. // Notes: As of now, only the itFreshLog is of interest to CiStorage.
  1199. //
  1200. //----------------------------------------------------------------------------
  1201. void CiStorage::SetSpecialItObjectId( IndexType it, WORKID wid )
  1202. {
  1203. switch ( it )
  1204. {
  1205. case itFreshLog:
  1206. #if CIDBG==1
  1207. CIndexId iid( wid );
  1208. Win4Assert( it == iid.PersId() );
  1209. Win4Assert( partidFresh1 == iid.PartId() ||
  1210. partidFresh2 == iid.PartId() );
  1211. #endif // CIDBG
  1212. _widFreshLog = wid;
  1213. break;
  1214. }
  1215. return;
  1216. }
  1217. //+---------------------------------------------------------------------------
  1218. //
  1219. // Function: GetSpecialItObjectId
  1220. //
  1221. // Synopsis: Returns the current object id of a special index type.
  1222. //
  1223. // Arguments: [it] -- Index Type
  1224. //
  1225. // History: 10-05-94 srikants Created
  1226. //
  1227. // Notes: As of now, only the itFreshLog is of interest.
  1228. //
  1229. //----------------------------------------------------------------------------
  1230. WORKID CiStorage::GetSpecialItObjectId( IndexType it ) const
  1231. {
  1232. switch ( it )
  1233. {
  1234. case itFreshLog:
  1235. return(_widFreshLog);
  1236. default:
  1237. return(0);
  1238. }
  1239. }
  1240. //+---------------------------------------------------------------------------
  1241. //
  1242. // Function: DeleteObject, public
  1243. //
  1244. // Synopsis: Deletes the file specified
  1245. //
  1246. // Arguments: [objectId] -- Object to delete
  1247. //
  1248. // History: Nov-16-94 DwightKr Added this header
  1249. //
  1250. //----------------------------------------------------------------------------
  1251. void CiStorage::DeleteObject( WORKID objectId )
  1252. {
  1253. RemoveObject( objectId );
  1254. }
  1255. //+---------------------------------------------------------------------------
  1256. //
  1257. // Function: EmptyIndexList, public
  1258. //
  1259. // Synopsis: Empties the index list
  1260. //
  1261. // History: Nov-16-94 DwightKr Created
  1262. //
  1263. //----------------------------------------------------------------------------
  1264. void CiStorage::EmptyIndexList()
  1265. {
  1266. WCHAR wcsHdr[MAX_PATH];
  1267. WCHAR wcsCopy1[MAX_PATH];
  1268. WCHAR wcsCopy2[MAX_PATH];
  1269. MakeLogPath( CAT_IDXTABLE_HDR, wcsHdr );
  1270. MakeLogPath( CAT_IDXTABLE_CP1, wcsCopy1 );
  1271. MakeLogPath( CAT_IDXTABLE_CP2, wcsCopy2 );
  1272. HANDLE hFile = CreateFile( wcsHdr, GENERIC_WRITE, 0,
  1273. NULL, TRUNCATE_EXISTING,
  1274. FILE_ATTRIBUTE_NORMAL,
  1275. NULL );
  1276. if ( INVALID_HANDLE_VALUE != hFile )
  1277. CloseHandle( hFile );
  1278. hFile = CreateFile( wcsCopy1, GENERIC_WRITE, 0,
  1279. NULL, TRUNCATE_EXISTING,
  1280. FILE_ATTRIBUTE_NORMAL,
  1281. NULL );
  1282. if ( INVALID_HANDLE_VALUE != hFile )
  1283. CloseHandle( hFile );
  1284. hFile = CreateFile( wcsCopy2, GENERIC_WRITE, 0,
  1285. NULL, TRUNCATE_EXISTING,
  1286. FILE_ATTRIBUTE_NORMAL,
  1287. NULL );
  1288. if ( INVALID_HANDLE_VALUE != hFile )
  1289. CloseHandle( hFile );
  1290. }
  1291. //+---------------------------------------------------------------------------
  1292. //
  1293. // Member: CiStorage::ListPropStoreFileNames, public
  1294. //
  1295. // Synopsis: Lists property store related files in the ci directory.
  1296. //
  1297. // Arguments: [enumStr] - String enumerator to which to add filenames to.
  1298. // [wid] - WORKID of the property store.
  1299. //
  1300. // History: 11-Apr-97 KrishnaN Created
  1301. // 30-May-97 KrishnaN Enumerate the backup file
  1302. // 24-Oct-97 KyleP Backup file is ephemeral and thus not
  1303. // part of the list.
  1304. //
  1305. //----------------------------------------------------------------------------
  1306. void CiStorage::ListPropStoreFileNames( CEnumString & enumStr, WORKID wid,
  1307. DWORD dwStoreLevel )
  1308. {
  1309. WCHAR wcsHdr[MAX_PATH];
  1310. WCHAR wcsCopy1[MAX_PATH];
  1311. WCHAR wcsCopy2[MAX_PATH];
  1312. //
  1313. // Get the recoverable storage object files
  1314. //
  1315. Win4Assert(PRIMARY_STORE == dwStoreLevel || SECONDARY_STORE == dwStoreLevel);
  1316. FormRcovObjNames( wid,
  1317. (PRIMARY_STORE == dwStoreLevel) ? PROPSTORE1_PREFIX:PROPSTORE2_PREFIX,
  1318. wcsHdr, wcsCopy1, wcsCopy2 );
  1319. enumStr.Append(wcsHdr);
  1320. enumStr.Append(wcsCopy1);
  1321. enumStr.Append(wcsCopy2);
  1322. //
  1323. // Get the property store and prop store backup file names
  1324. //
  1325. // Reuse wcsCopy1
  1326. PStorageObject *pObj = QueryObject(wid);
  1327. XPtr<PStorageObject> xObj(pObj);
  1328. MakePath( (PRIMARY_STORE == dwStoreLevel) ? ePrimaryPropPath:eSecondaryPropPath,
  1329. CI_OBJ(*pObj).ObjectId(), wcsCopy1);
  1330. enumStr.Append(wcsCopy1);
  1331. }
  1332. //+---------------------------------------------------------------------------
  1333. //
  1334. // Member: CiStorage::ListSecStoreFileNames
  1335. //
  1336. // Synopsis: Lists the names of the files that constitute the recoverable
  1337. // stoage object for the security store.
  1338. //
  1339. // Arguments: [enumStr] -- Output object to append the names of the
  1340. // security store.
  1341. // [wid] -- Workid
  1342. //
  1343. // History: 7-14-97 srikants Created
  1344. //
  1345. //----------------------------------------------------------------------------
  1346. void CiStorage::ListSecStoreFileNames( CEnumString & enumStr, WORKID wid )
  1347. {
  1348. WCHAR wcsHdr[MAX_PATH];
  1349. WCHAR wcsCopy1[MAX_PATH];
  1350. WCHAR wcsCopy2[MAX_PATH];
  1351. //
  1352. // Get the recoverable storage object files
  1353. //
  1354. FormRcovObjNames( wid, SECSTORE_PREFIX, wcsHdr, wcsCopy1, wcsCopy2 );
  1355. enumStr.Append(wcsHdr);
  1356. enumStr.Append(wcsCopy1);
  1357. enumStr.Append(wcsCopy2);
  1358. }
  1359. //+---------------------------------------------------------------------------
  1360. //
  1361. // Member: CiStorage::DeleteFilesInCiDir
  1362. //
  1363. // Synopsis: Deletes files in the ci directory which match the given
  1364. // pattern.
  1365. //
  1366. // Arguments: [pwszPattern] - Pattern of files to search.
  1367. //
  1368. // History: 1-31-97 srikants Created
  1369. //
  1370. //----------------------------------------------------------------------------
  1371. void CiStorage::DeleteFilesInCiDir( WCHAR const * pwszPattern )
  1372. {
  1373. CFullPath fullPath( _xPath.GetPointer() );
  1374. WCHAR wszFullPattern[MAX_PATH];
  1375. swprintf( wszFullPattern, L"%s%s", fullPath.GetBuf(), pwszPattern );
  1376. WIN32_FIND_DATA fileData;
  1377. HANDLE hFile = FindFirstFile( wszFullPattern, &fileData );
  1378. if ( INVALID_HANDLE_VALUE == hFile )
  1379. {
  1380. ciDebugOut(( DEB_ITRACE, "Did not find files for (%ws)\n",
  1381. wszFullPattern ));
  1382. return;
  1383. }
  1384. do
  1385. {
  1386. if ( !(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  1387. {
  1388. fullPath.MakePath( fileData.cFileName );
  1389. BOOL fSuccess = DeleteFile( fullPath.GetBuf() );
  1390. if ( !fSuccess )
  1391. {
  1392. DWORD dwError = GetLastError();
  1393. ciDebugOut(( DEB_ITRACE,
  1394. "Failed to delete file (%ws) due to error (%d)\n",
  1395. fullPath.GetBuf(), dwError ));
  1396. }
  1397. else
  1398. {
  1399. ciDebugOut(( DEB_ITRACE,
  1400. "Deleted file (%ws)\n", fullPath.GetBuf() ));
  1401. }
  1402. }
  1403. else
  1404. {
  1405. ciDebugOut(( DEB_ITRACE,
  1406. "Not deleting directory (%ws) \n", fullPath.GetBuf() ));
  1407. }
  1408. }
  1409. while ( FindNextFile( hFile, &fileData ) );
  1410. FindClose( hFile );
  1411. }
  1412. //+---------------------------------------------------------------------------
  1413. //
  1414. // Member: CiStorage::DeleteAllFiles
  1415. //
  1416. // Synopsis: Deletes all the files in the Ci directory.
  1417. //
  1418. // History: 3-21-97 srikants Created
  1419. //
  1420. //----------------------------------------------------------------------------
  1421. void CiStorage::DeleteAllFiles()
  1422. {
  1423. WCHAR wszPattern[32];
  1424. swprintf( wszPattern, L"*.*" );
  1425. DeleteFilesInCiDir( wszPattern );
  1426. }
  1427. //+---------------------------------------------------------------------------
  1428. //
  1429. // Member: CiStorage::DeleteAllCiFiles
  1430. //
  1431. // Synopsis: Deletes files that belong to the CI engine.
  1432. //
  1433. // History: 1-31-97 srikants Created
  1434. //
  1435. //----------------------------------------------------------------------------
  1436. void CiStorage::DeleteAllCiFiles()
  1437. {
  1438. //
  1439. // Delete the following types of files.
  1440. //
  1441. WCHAR wszPattern[32];
  1442. swprintf( wszPattern, L"*.ci" );
  1443. DeleteFilesInCiDir( wszPattern );
  1444. swprintf( wszPattern, L"*.dir" );
  1445. DeleteFilesInCiDir( wszPattern );
  1446. swprintf( wszPattern, L"%s*", MMLOG_PREFIX );
  1447. DeleteFilesInCiDir( wszPattern );
  1448. swprintf( wszPattern, L"%s*", PRI_CHANGELOG_PREFIX );
  1449. DeleteFilesInCiDir( wszPattern );
  1450. swprintf( wszPattern, L"%s*", SEC_CHANGELOG_PREFIX );
  1451. DeleteFilesInCiDir( wszPattern );
  1452. swprintf( wszPattern, L"%s*", FRESHLOG_PREFIX );
  1453. DeleteFilesInCiDir( wszPattern );
  1454. swprintf( wszPattern, L"INDEX.*" );
  1455. DeleteFilesInCiDir( wszPattern );
  1456. }
  1457. //+---------------------------------------------------------------------------
  1458. //
  1459. // Member: CiStorage::DeleteAllPersistentIndexes
  1460. //
  1461. // Synopsis: Deletes all the persistent indexes in the ci directory.
  1462. //
  1463. // History: 3-25-97 srikants Created
  1464. //
  1465. //----------------------------------------------------------------------------
  1466. void CiStorage::DeleteAllPersIndexes()
  1467. {
  1468. //
  1469. // Delete the following types of files.
  1470. //
  1471. WCHAR wszPattern[32];
  1472. swprintf( wszPattern, L"*.ci" );
  1473. DeleteFilesInCiDir( wszPattern );
  1474. swprintf( wszPattern, L"*.dir" );
  1475. DeleteFilesInCiDir( wszPattern );
  1476. }
  1477. //+---------------------------------------------------------------------------
  1478. //
  1479. // Member: CiStorage::DeleteUnUsedPersIndexes
  1480. //
  1481. // Synopsis: Deletes any .ci and .dir files that are not referenced in
  1482. // the given iid list.
  1483. //
  1484. // Arguments: [iidStk] - List of in-use iids.
  1485. //
  1486. // History: 3-25-97 srikants Created
  1487. //
  1488. //----------------------------------------------------------------------------
  1489. void CiStorage::DeleteUnUsedPersIndexes( BOOL fIsCi,
  1490. CIndexIdList const & iidsInUse )
  1491. {
  1492. WCHAR wszPattern[32];
  1493. if ( fIsCi )
  1494. swprintf( wszPattern, L"*.ci" );
  1495. else
  1496. swprintf( wszPattern, L"*.dir" );
  1497. CFullPath fullPath( _xPath.GetPointer() );
  1498. WCHAR wszFullPattern[MAX_PATH];
  1499. swprintf( wszFullPattern, L"%s%s", fullPath.GetBuf(), wszPattern );
  1500. WIN32_FIND_DATA fileData;
  1501. HANDLE hFile = FindFirstFile( wszFullPattern, &fileData );
  1502. if ( INVALID_HANDLE_VALUE == hFile )
  1503. {
  1504. ciDebugOut(( DEB_ITRACE, "Did not find files for (%ws)\n",
  1505. wszFullPattern ));
  1506. return;
  1507. }
  1508. do
  1509. {
  1510. if ( !(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  1511. {
  1512. if ( !IsInUse( fileData.cFileName, iidsInUse ) )
  1513. {
  1514. fullPath.MakePath( fileData.cFileName );
  1515. ciDebugOut(( DEB_ITRACE, "Deleting UnUsed Index (%ws) \n",
  1516. fullPath.GetBuf() ));
  1517. BOOL fSuccess = DeleteFile( fullPath.GetBuf() );
  1518. if ( !fSuccess )
  1519. {
  1520. DWORD dwError = GetLastError();
  1521. ciDebugOut(( DEB_ITRACE,
  1522. "Failed to delete file (%ws) due to error (%d)\n",
  1523. fullPath.GetBuf(), dwError ));
  1524. }
  1525. else
  1526. {
  1527. ciDebugOut(( DEB_ITRACE,
  1528. "Deleted file (%ws)\n", fullPath.GetBuf() ));
  1529. }
  1530. }
  1531. }
  1532. else
  1533. {
  1534. ciDebugOut(( DEB_ITRACE,
  1535. "Not deleting directory (%ws) \n", fullPath.GetBuf() ));
  1536. }
  1537. }
  1538. while ( FindNextFile( hFile, &fileData ) );
  1539. FindClose( hFile );
  1540. }
  1541. //+---------------------------------------------------------------------------
  1542. //
  1543. // Member: CiStorage::IsInUse
  1544. //
  1545. // Synopsis: Tests if the given file is in use.
  1546. //
  1547. // Arguments: [pwszFile] -
  1548. // [iidStk] -
  1549. //
  1550. // Returns: TRUE if it is in use. FALSE o/w
  1551. //
  1552. // History: 3-25-97 srikants Created
  1553. //
  1554. //----------------------------------------------------------------------------
  1555. BOOL CiStorage::IsInUse( WCHAR const * pwszFile,
  1556. CIndexIdList const & iidsInUse ) const
  1557. {
  1558. //
  1559. // Determine the iid and see if it is in the list.
  1560. //
  1561. WCHAR * pwszEnd;
  1562. INDEXID iid = (INDEXID) wcstol( pwszFile, &pwszEnd, 16 );
  1563. for ( ULONG i = 0; i < iidsInUse.Count(); i++ )
  1564. {
  1565. if ( iid == iidsInUse.Get(i) )
  1566. return TRUE;
  1567. }
  1568. return FALSE;
  1569. }
  1570. //+---------------------------------------------------------------------------
  1571. //
  1572. // Member: CiStorage::DeleteUnUsedPersIndexes
  1573. //
  1574. // Synopsis: Deletes the persistent .ci and .dir files that are not
  1575. // in the list of in-use iids.
  1576. //
  1577. // Arguments: [iidStk] - The list of in-use iids.
  1578. //
  1579. // History: 3-25-97 srikants Created
  1580. //
  1581. //----------------------------------------------------------------------------
  1582. void CiStorage::DeleteUnUsedPersIndexes( CIndexIdList const & iidsInUse )
  1583. {
  1584. DeleteUnUsedPersIndexes( TRUE, iidsInUse ); // delete the unused .ci files
  1585. DeleteUnUsedPersIndexes( FALSE, iidsInUse ); // delete the unused .dir files
  1586. }
  1587. //+---------------------------------------------------------------------------
  1588. //
  1589. // Member: CiStorage::DeleteAllFsCiFiles
  1590. //
  1591. // Synopsis: Deletes all the files belonging to the FileSystem CI client.
  1592. //
  1593. // History: 2-10-97 srikants Created
  1594. //
  1595. //----------------------------------------------------------------------------
  1596. void CiStorage::DeleteAllFsCiFiles()
  1597. {
  1598. //
  1599. // Delete the following types of files.
  1600. //
  1601. WCHAR wszPattern[32];
  1602. swprintf( wszPattern, L"cicat.hsh" );
  1603. DeleteFilesInCiDir( wszPattern );
  1604. swprintf( wszPattern, L"cicat.fid" );
  1605. DeleteFilesInCiDir( wszPattern );
  1606. swprintf( wszPattern, L"deletion.log" );
  1607. DeleteFilesInCiDir( wszPattern );
  1608. swprintf( wszPattern, PROP_BKP_FILE);
  1609. DeleteFilesInCiDir( wszPattern );
  1610. swprintf( wszPattern, PROP_BKP_FILE1);
  1611. DeleteFilesInCiDir( wszPattern );
  1612. swprintf( wszPattern, PROP_BKP_FILE2);
  1613. DeleteFilesInCiDir( wszPattern );
  1614. swprintf( wszPattern, L"*.prp" );
  1615. DeleteFilesInCiDir( wszPattern );
  1616. swprintf( wszPattern, L"*.ps1" );
  1617. DeleteFilesInCiDir( wszPattern );
  1618. swprintf( wszPattern, L"*.ps2" );
  1619. DeleteFilesInCiDir( wszPattern );
  1620. swprintf( wszPattern, L"%s*", PIDTABLE_PREFIX );
  1621. DeleteFilesInCiDir( wszPattern );
  1622. swprintf( wszPattern, L"%s*", SCOPELIST_PREFIX );
  1623. DeleteFilesInCiDir( wszPattern );
  1624. swprintf( wszPattern, L"%s*", SECSTORE_PREFIX );
  1625. DeleteFilesInCiDir( wszPattern );
  1626. swprintf( wszPattern, L"%s*", PROPSTORE_PREFIX );
  1627. DeleteFilesInCiDir( wszPattern );
  1628. swprintf( wszPattern, L"%s*", PROPSTORE1_PREFIX );
  1629. DeleteFilesInCiDir( wszPattern );
  1630. swprintf( wszPattern, L"%s*", PROPSTORE2_PREFIX );
  1631. DeleteFilesInCiDir( wszPattern );
  1632. swprintf( wszPattern, L"%s*", VSCOPELIST_PREFIX );
  1633. DeleteFilesInCiDir( wszPattern );
  1634. }
  1635. //+---------------------------------------------------------------------------
  1636. //
  1637. // Function: EnumerateFilesInDir
  1638. //
  1639. // Synopsis: Enumerates files in a directory. Does not include directories
  1640. // and there is no recursive traversal.
  1641. //
  1642. // Arguments: [pwszDir] - Directory to enumerate.
  1643. // [enumStr] - Place to add the enumerated files.
  1644. //
  1645. // History: 3-19-97 srikants Created
  1646. //
  1647. //----------------------------------------------------------------------------
  1648. void CiStorage::EnumerateFilesInDir( WCHAR const * pwszDir,
  1649. CEnumString & enumStr )
  1650. {
  1651. CFullPath fullPath( (WCHAR *) pwszDir );
  1652. fullPath.MakePath( L"*.*" );
  1653. WIN32_FIND_DATA fileData;
  1654. HANDLE hFile = FindFirstFile( fullPath.GetBuf(), &fileData );
  1655. if ( INVALID_HANDLE_VALUE == hFile )
  1656. {
  1657. ciDebugOut(( DEB_ITRACE, "Did not find files for (%ws)\n",
  1658. fullPath.GetBuf() ));
  1659. return;
  1660. }
  1661. do
  1662. {
  1663. if ( !(fileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) )
  1664. {
  1665. fullPath.MakePath( fileData.cFileName );
  1666. enumStr.Append( fullPath.GetBuf() );
  1667. ciDebugOut(( DEB_ITRACE,
  1668. "EnumerateFiles - Adding File (%ws) \n", fullPath.GetBuf() ));
  1669. }
  1670. else
  1671. {
  1672. ciDebugOut(( DEB_ITRACE,
  1673. "EnumerateFiles - Skipping directory (%ws) \n", fileData.cFileName ));
  1674. }
  1675. }
  1676. while ( FindNextFile( hFile, &fileData ) );
  1677. FindClose( hFile );
  1678. }
  1679. //+---------------------------------------------------------------------------
  1680. //
  1681. // Function: IsValidFile
  1682. //
  1683. // Synopsis: Verifies that the given file is a valid file.
  1684. //
  1685. // Arguments: [pwszFile] - File name
  1686. //
  1687. // History: 3-21-97 srikants Created
  1688. //
  1689. //----------------------------------------------------------------------------
  1690. BOOL CiStorage::IsValidFile( WCHAR const * pwszFile )
  1691. {
  1692. DWORD dwFileAttributes = GetFileAttributes( pwszFile );
  1693. if ( 0xFFFFFFFF == dwFileAttributes )
  1694. {
  1695. DWORD dwError = GetLastError();
  1696. ciDebugOut(( DEB_ITRACE, "GetFileAttributes failed with error %d\n", dwError ));
  1697. return FALSE;
  1698. }
  1699. return 0 == (dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) ;
  1700. }
  1701. //+---------------------------------------------------------------------------
  1702. //
  1703. // Function: CheckHasIndexTable
  1704. //
  1705. // Synopsis: Verifies that the given directory is a valid one. Also checks
  1706. // that files INDEX.000, INDEX.001, INDEX.002 are present in the
  1707. // directory.
  1708. //
  1709. // Arguments: [pwszPath] - Path of the directory.
  1710. //
  1711. // Returns: TRUE if valid; FALSE o/w
  1712. //
  1713. // History: 3-21-97 srikants Created
  1714. //
  1715. //----------------------------------------------------------------------------
  1716. BOOL CiStorage::CheckHasIndexTable( WCHAR const * pwszPath )
  1717. {
  1718. CFullPath fullPath( pwszPath );
  1719. fullPath.MakePath( CAT_IDXTABLE_HDR );
  1720. if ( !IsValidFile( fullPath.GetBuf() ) )
  1721. return FALSE;
  1722. fullPath.MakePath( CAT_IDXTABLE_CP1 );
  1723. if ( !IsValidFile( fullPath.GetBuf() ) )
  1724. return FALSE;
  1725. fullPath.MakePath( CAT_IDXTABLE_CP2 );
  1726. if ( !IsValidFile( fullPath.GetBuf() ) )
  1727. return FALSE;
  1728. return TRUE;
  1729. }
  1730. //+---------------------------------------------------------------------------
  1731. //
  1732. // Function: DetermineDriveType
  1733. //
  1734. // Synopsis: Determines the type of drive on which the given path is.
  1735. //
  1736. // Arguments: [pwszPath] - Path of the file.
  1737. //
  1738. // Returns: WIN32 drive type ( values returned by GetDriveType() )
  1739. //
  1740. // History: 3-24-97 srikants Created
  1741. //
  1742. //----------------------------------------------------------------------------
  1743. UINT CiStorage::DetermineDriveType( WCHAR const * pwszPath )
  1744. {
  1745. CPathParser pathParser( pwszPath );
  1746. if ( pathParser.IsUNCName() )
  1747. return DRIVE_REMOTE;
  1748. WCHAR wDrive[MAX_PATH];
  1749. ULONG cc=sizeof(wDrive)/sizeof(WCHAR);
  1750. pathParser.GetFileName( wDrive, cc );
  1751. UINT uType = GetDriveType( wDrive );
  1752. return uType;
  1753. }
  1754. //+-------------------------------------------------------------------------
  1755. //
  1756. // Method: CiStorage::QueryStream, Private
  1757. //
  1758. // Synopsis: Opens a mmstream of name specified
  1759. //
  1760. // Arguments: [wcsFileName] - Name of the file.
  1761. //
  1762. // Returns: CMmStream
  1763. //
  1764. // History: 17-Mar-1998 KitmanH Created
  1765. //
  1766. //--------------------------------------------------------------------------
  1767. PMmStream* CiStorage::QueryStream (WCHAR const * wcsFileName)
  1768. {
  1769. XPtr<CMmStream> xStrm( new CMmStream( _cMegToLeaveOnDisk, _fIsReadOnly ) );
  1770. DWORD dwAccess = _fIsReadOnly ? GENERIC_READ : ( GENERIC_READ | GENERIC_WRITE );
  1771. DWORD sharing = _fIsReadOnly ? ( FILE_SHARE_READ | FILE_SHARE_WRITE ) : FILE_SHARE_READ;
  1772. DWORD openMode = _fIsReadOnly ? OPEN_EXISTING : OPEN_ALWAYS;
  1773. WCHAR wcsFilePath[MAX_PATH];
  1774. if ( ( wcslen( _xPath.GetPointer() ) + wcslen( wcsFileName ) ) >= MAX_PATH )
  1775. THROW( CException( STATUS_INVALID_PARAMETER ) );
  1776. wcscpy( wcsFilePath, _xPath.GetPointer() );
  1777. wcscat( wcsFilePath, wcsFileName );
  1778. xStrm->Open( wcsFilePath,
  1779. dwAccess, // Access flags
  1780. sharing,
  1781. openMode,
  1782. FILE_ATTRIBUTE_NORMAL,
  1783. FALSE );
  1784. return xStrm.Acquire();
  1785. }
  1786. //+-------------------------------------------------------------------------
  1787. //
  1788. // Method: CiStorage::QueryStringHash
  1789. //
  1790. // Synopsis: Opens a mmstream by calling private function QueryStream
  1791. // with the appropriate filename
  1792. //
  1793. // Arguments: [wcsFileName] - Name of the file.
  1794. //
  1795. // Returns: CMmStream
  1796. //
  1797. // History: 17-Mar-1998 KitmanH Created
  1798. //
  1799. //--------------------------------------------------------------------------
  1800. PMmStream* CiStorage::QueryStringHash()
  1801. {
  1802. return QueryStream( CAT_HASH_FILE );
  1803. }
  1804. //+-------------------------------------------------------------------------
  1805. //
  1806. // Method: CiStorage::QueryFileIdMap
  1807. //
  1808. // Synopsis: Opens a mmstream by calling private function QueryStream
  1809. // with the appropriate filename
  1810. //
  1811. // Arguments: [wcsFileName] - Name of the file.
  1812. //
  1813. // Returns: CMmStream
  1814. //
  1815. // History: 17-Mar-1998 KitmanH Created
  1816. //
  1817. //--------------------------------------------------------------------------
  1818. PMmStream* CiStorage::QueryFileIdMap()
  1819. {
  1820. return QueryStream( CAT_FILEID_MAP_FILE );
  1821. }
  1822. //+-------------------------------------------------------------------------
  1823. //
  1824. // Method: CiStorage::QueryDeletionLog
  1825. //
  1826. // Synopsis: Opens a mmstream by calling private function QueryStream
  1827. // with the appropriate filename
  1828. //
  1829. // Arguments: [wcsFileName] - Name of the file.
  1830. //
  1831. // Returns: CMmStream
  1832. //
  1833. // History: 17-Mar-1998 KitmanH Created
  1834. //
  1835. //--------------------------------------------------------------------------
  1836. PMmStream* CiStorage::QueryDeletionLog()
  1837. {
  1838. Win4Assert( FALSE );
  1839. return 0;
  1840. }