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.

344 lines
9.5 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 2000.
  5. //
  6. // File: CIRCSTOB.CXX
  7. //
  8. // Contents: Down-Level Recoverable Storage Object
  9. //
  10. // Classes: CiRcovStorageObj
  11. //
  12. // History: 04-Feb-1994 SrikantS Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #include <pch.cxx>
  16. #pragma hdrstop
  17. #include <circstob.hxx>
  18. #include <eventlog.hxx>
  19. //+---------------------------------------------------------------------------
  20. //
  21. // Function: CiRcovStorageObj::CiRcovStorageObj
  22. //
  23. // Synopsis: Constructor for CiRcovStorageObj.
  24. //
  25. // Effects: Results in the initialization of the header information
  26. // of the recoverable storage object.
  27. //
  28. // Arguments: [storage] -- Storage object for content index.
  29. // [wcsHdr] -- Full path name of the header file.
  30. // [wcsCopy1] -- Full path name of the copy 1.
  31. // [wcsCopy2] -- Full path name of the copy 2.
  32. // [cbDiskSpaceToLeave] -- Megabytes to leave on disk
  33. // [fReadOnly] -- Read only?
  34. //
  35. // Modifies:
  36. //
  37. // Algorithm:
  38. //
  39. // History: 2-05-94 srikants Created
  40. // 11-30-94 srikants Modified to deal with version
  41. // initialization.
  42. // 02-12-98 kitmanh Adding a readOnly parameter to the
  43. // constructor and changes to deal with
  44. // read-only catalogs
  45. // 03-18-98 kitmanh Init the embedded CMmStream with
  46. // value of _fIsReadOnly
  47. // 27-Oct-98 KLam Added cbDiskSpaceToLeave
  48. //
  49. //
  50. // Notes: The constructor initializes the header information but
  51. // does not open the copy 1 or copy 2. That is does in the
  52. // QueryMmStream() method.
  53. //
  54. //----------------------------------------------------------------------------
  55. CiRcovStorageObj::CiRcovStorageObj( CiStorage & storage,
  56. WCHAR * wcsHdr,
  57. WCHAR * wcsCopy1,
  58. WCHAR * wcsCopy2,
  59. ULONG cbDiskSpaceToLeave,
  60. BOOL fReadOnly)
  61. : PRcovStorageObj( storage ),
  62. _storage(storage),
  63. _wcsCopy1(NULL),
  64. _wcsCopy2(NULL),
  65. _cbDiskSpaceToLeave(cbDiskSpaceToLeave),
  66. _hdrStrm(cbDiskSpaceToLeave),
  67. _fIsReadOnly(fReadOnly)
  68. {
  69. Win4Assert( wcsHdr );
  70. Win4Assert( wcsCopy1 );
  71. Win4Assert( wcsCopy2 );
  72. _apMmStrm[0] = _apMmStrm[1] = NULL;
  73. //
  74. // Initialize the header stream (to reset value of CMmStrem::_fIsReadOnly)
  75. //
  76. InithdrStrm();
  77. //
  78. // Open the header stream.
  79. //
  80. _hdrStrm.OpenExclusive( wcsHdr, _fIsReadOnly );
  81. if ( !_hdrStrm.Ok() )
  82. {
  83. THROW( CException() );
  84. }
  85. //
  86. // Check if this is the first time the recoverable object is being
  87. // constructed.
  88. //
  89. BOOL fVirgin = _hdrStrm.SizeLow() == 0 && _hdrStrm.SizeHigh() == 0;
  90. if ( fVirgin )
  91. {
  92. if ( !fReadOnly )
  93. {
  94. //
  95. // There is no data on disk.
  96. //
  97. _hdrStrm.SetSize( _storage, sizeof(CRcovStorageHdr), 0 );
  98. _hdrStrm.MapAll( _hdrSbuf );
  99. //
  100. // Make sure the new header makes it to disk.
  101. //
  102. WriteHeader();
  103. }
  104. }
  105. else
  106. {
  107. //
  108. // By default, the size of the mm stream is always set to the large
  109. // page. Here, we don't need it to be that big.
  110. //
  111. _hdrStrm.MapAll( _hdrSbuf );
  112. const BYTE * pbuf = (const BYTE *)_hdrSbuf.Get();
  113. _hdr.Init( (const void *) pbuf, sizeof(CRcovStorageHdr) );
  114. if ( _hdr.GetVersion() != _storage.GetStorageVersion() )
  115. {
  116. ciDebugOut(( DEB_ERROR,
  117. "Ci Version Mismatch - OnDisk 0x%X Binaries 0x%X\n",
  118. _hdr.GetVersion(), _storage.GetStorageVersion() ));
  119. #if 0
  120. //
  121. // Disabled because general NT user does not want to be bothered by
  122. // the version change assert.
  123. //
  124. Win4Assert( !"The on disk catalog version and that of the binaries"
  125. " are different\n. Catalog will be reindexed. Hit OK." );
  126. #endif
  127. _storage.ReportCorruptComponent( L"CI-RcovStorageObj1" );
  128. THROW( CException( CI_INCORRECT_VERSION ) );
  129. }
  130. }
  131. Win4Assert( _hdr.GetVersion() == _storage.GetStorageVersion() );
  132. TRY
  133. {
  134. _wcsCopy1 = new WCHAR [wcslen(wcsCopy1)+1];
  135. _wcsCopy2 = new WCHAR [wcslen(wcsCopy2)+1];
  136. wcscpy( _wcsCopy1, wcsCopy1 );
  137. wcscpy( _wcsCopy2, wcsCopy2 );
  138. VerifyConsistency();
  139. }
  140. CATCH( CException, e )
  141. {
  142. delete [] _wcsCopy1;
  143. delete [] _wcsCopy2;
  144. RETHROW();
  145. }
  146. END_CATCH
  147. }
  148. CiRcovStorageObj::~CiRcovStorageObj()
  149. {
  150. //
  151. // If the header stream is still mapped, then unmap it.
  152. //
  153. if ( _hdrSbuf.Get() ) {
  154. _hdrStrm.Unmap( _hdrSbuf );
  155. }
  156. _hdrStrm.Close();
  157. delete [] _wcsCopy1;
  158. delete [] _wcsCopy2;
  159. Close( CRcovStorageHdr::idxOne );
  160. Close( CRcovStorageHdr::idxTwo );
  161. }
  162. //+---------------------------------------------------------------------------
  163. //
  164. // Function: Open
  165. //
  166. // Synopsis: Opens the specified stream with the specified access.
  167. //
  168. // Arguments: [n] -- Stream copy to open.
  169. // [fWrite] -- Flag indicating if open in write mode.
  170. //
  171. // History: 2-05-94 srikants Created
  172. //
  173. // Notes:
  174. //
  175. //----------------------------------------------------------------------------
  176. void CiRcovStorageObj::Open( CRcovStorageHdr::DataCopyNum n, BOOL fWrite )
  177. {
  178. AssertValidIndex(n);
  179. Win4Assert( !IsOpen(n) );
  180. //
  181. // Create the memory mapped stream with the specified open mode.
  182. //
  183. _apMmStrm[n] = QueryMmStream( n, fWrite );
  184. }
  185. //+---------------------------------------------------------------------------
  186. //
  187. // Function: Close
  188. //
  189. // Synopsis: Closes the specified stream if it is open. Also, if the
  190. // stream buffer associated with this stream is mapped, it
  191. // will be unmapped before closing.
  192. //
  193. // Arguments: [n] -- the stream copy to close.
  194. //
  195. // History: 2-05-94 srikants Created
  196. //
  197. // Notes:
  198. //
  199. //----------------------------------------------------------------------------
  200. void CiRcovStorageObj::Close( CRcovStorageHdr::DataCopyNum n )
  201. {
  202. AssertValidIndex(n);
  203. if ( IsOpen(n) )
  204. {
  205. //
  206. // If the stream is still mapped, then it must be
  207. // unmapped first.
  208. //
  209. if ( IsMapped(n) )
  210. {
  211. _apMmStrm[n]->Unmap( GetMmStreamBuf( n ) );
  212. }
  213. //
  214. // Closing the stream automatically flushes the contents.
  215. //
  216. _apMmStrm[n]->Close();
  217. delete _apMmStrm[n];
  218. _apMmStrm[n] = NULL;
  219. }
  220. }
  221. void CiRcovStorageObj::ReadHeader()
  222. {
  223. const BYTE * pbHdr;
  224. Win4Assert( _hdrStrm.SizeLow() >= sizeof(CRcovStorageHdr) );
  225. pbHdr = (const BYTE *) _hdrSbuf.Get();
  226. Win4Assert( pbHdr );
  227. memcpy( &_hdr, pbHdr, sizeof(CRcovStorageHdr) );
  228. }
  229. void CiRcovStorageObj::WriteHeader()
  230. {
  231. BYTE * pbHdr;
  232. Win4Assert( _hdrStrm.SizeLow() >= sizeof(CRcovStorageHdr) );
  233. Win4Assert( _hdrStrm.isWritable() );
  234. pbHdr = (BYTE *) _hdrSbuf.Get();
  235. Win4Assert( pbHdr );
  236. memcpy( pbHdr, &_hdr , sizeof(CRcovStorageHdr) );
  237. _hdrStrm.Flush( _hdrSbuf, sizeof(CRcovStorageHdr) );
  238. }
  239. //+---------------------------------------------------------------------------
  240. //
  241. // Function: QueryMmStream
  242. //
  243. // Synopsis: Creates a Memory Mapped Stream for the specified copy.
  244. // If one doesn't exist already, a new one will be created.
  245. //
  246. // Arguments: [n] -- Copy number of the stream.
  247. // [fWritable] -- Set to TRUE if the stream is writable.
  248. //
  249. // Returns: Pointer to the memory mapped stream.
  250. //
  251. // History: 2-05-94 srikants Created
  252. // 3-03-98 kitmanh Added code to deal with read-only catalogs
  253. // 27-Oct-98 KLam Pass _cbDiskSpaceToLeave to CMmStream
  254. //
  255. // Notes: It is upto the caller to free up the object created.
  256. //
  257. //----------------------------------------------------------------------------
  258. PMmStream *
  259. CiRcovStorageObj::QueryMmStream( CRcovStorageHdr::DataCopyNum n,
  260. BOOL fWritable )
  261. {
  262. WCHAR * wcsName = ( n == CRcovStorageHdr::idxOne ) ? _wcsCopy1 :
  263. _wcsCopy2;
  264. CMmStream * pMmStrm = new CMmStream( _cbDiskSpaceToLeave, _fIsReadOnly );
  265. ULONG modeShare = 0; // No sharing
  266. ULONG modeCreate = _fIsReadOnly ? OPEN_EXISTING : OPEN_ALWAYS;
  267. ULONG modeAccess = GENERIC_READ;
  268. if ( fWritable && !_fIsReadOnly )
  269. {
  270. modeAccess |= GENERIC_WRITE;
  271. }
  272. //
  273. // A Safe Pointer is needed because the open can fail.
  274. //
  275. XPtr<PMmStream> sMmStrm( pMmStrm );
  276. pMmStrm->Open( wcsName,
  277. modeAccess,
  278. modeShare,
  279. modeCreate,
  280. FILE_ATTRIBUTE_NORMAL | FILE_ATTRIBUTE_NOT_CONTENT_INDEXED );
  281. if ( !pMmStrm->Ok() )
  282. {
  283. ciDebugOut(( DEB_ERROR, "querymmstrm failed due to %#x\n",
  284. pMmStrm->GetStatus() ));
  285. THROW( CException(STATUS_OBJECT_PATH_INVALID) );
  286. }
  287. sMmStrm.Acquire();
  288. return pMmStrm;
  289. }