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.

445 lines
11 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1998.
  5. //
  6. // File: RCSTXACT.HXX
  7. //
  8. // Contents: Recoverable Stream Transactions.
  9. //
  10. // Classes: CRcovStrmTrans
  11. // CRcovStrmReadTrans
  12. // CRcovStrmWriteTrans
  13. // CRcovStrmAppendTrans
  14. // CRcovStrmMDTrans
  15. //
  16. //
  17. // History: 25-Jan-94 SrikantS Created.
  18. //
  19. //----------------------------------------------------------------------------
  20. #pragma once
  21. #include <prcstob.hxx>
  22. #include <xact.hxx>
  23. //+---------------------------------------------------------------------------
  24. //
  25. // Class: SOpenRcovObj
  26. //
  27. // Purpose: An unwindable object to guarantee that the open streams in a
  28. // recoverable object are closed.
  29. //
  30. // History: 1-16-95 srikants Created
  31. //
  32. // Notes:
  33. //
  34. //----------------------------------------------------------------------------
  35. class SOpenRcovObj
  36. {
  37. public:
  38. SOpenRcovObj( PRcovStorageObj & obj ) : _obj(obj)
  39. {
  40. }
  41. ~SOpenRcovObj()
  42. {
  43. //
  44. // None of these methods on PRcovStorageObj can throw
  45. //
  46. if ( _obj.IsOpen(CRcovStorageHdr::idxOne) )
  47. {
  48. _obj.Close(CRcovStorageHdr::idxOne);
  49. }
  50. if ( _obj.IsOpen(CRcovStorageHdr::idxTwo) )
  51. {
  52. _obj.Close(CRcovStorageHdr::idxTwo);
  53. }
  54. }
  55. private:
  56. PRcovStorageObj & _obj;
  57. };
  58. //+---------------------------------------------------------------------------
  59. //
  60. // Class: CRcovStrmTrans ()
  61. //
  62. // Purpose: Base class for the Recoverable Stream transactions.
  63. //
  64. // History: 2-02-94 srikants Created
  65. //
  66. // Notes: This object must not be created directly. Classes for
  67. // read transaction, write transaction, etc must be
  68. // derived from this class.
  69. //
  70. //----------------------------------------------------------------------------
  71. const DWORD ENDOFSTRM = 0xFFFFFFFF;
  72. class CRcovStrmTrans : public CTransaction
  73. {
  74. public:
  75. BOOL Seek( ULONG offset );
  76. void Advance( ULONG cb );
  77. void Backup( ULONG cb );
  78. ULONG Read( void *pvBuf, ULONG cbToRead );
  79. BOOL AtEnd();
  80. protected:
  81. CRcovStrmTrans( PRcovStorageObj &obj , RcovOpType op );
  82. void CommitPh1();
  83. void CommitPh2();
  84. void Write( const void *pvBuf, ULONG cbToWrite );
  85. void Unmap( CRcovStorageHdr::DataCopyNum nCopy );
  86. void SetStrmSize( CRcovStorageHdr::DataCopyNum nCopy, ULONG cbNew );
  87. void Grow( CRcovStorageHdr::DataCopyNum nCopy, ULONG cbDelta );
  88. void CopyToBack( ULONG oSrc, ULONG oDst, ULONG cbToCopy );
  89. void CleanupAndSynchronize();
  90. void _Seek( ULONG offset );
  91. ULONG _GetCommittedStrmSize( PMmStream & strm,
  92. CRcovStorageHdr::DataCopyNum nCopy );
  93. ULONG _GetCommittedStrmSize( CRcovStorageHdr::DataCopyNum nCopy );
  94. PRcovStorageObj & GetRcovObj() { return _obj; }
  95. CRcovStorageHdr & GetStorageHdr() { return _hdr; }
  96. void EmptyBackupStream();
  97. CRcovStorageHdr::DataCopyNum _iPrim, _iBack, _iCurr;
  98. private:
  99. PRcovStorageObj & _obj;
  100. CRcovStorageHdr & _hdr;
  101. SOpenRcovObj _sObj; // Safe pointer to always close the
  102. // streams on a failure (even in the
  103. // constructor).
  104. //
  105. // This keeps track of the range of bytes mapped in memory and the
  106. // current offset for both the primary copy and the backup copy.
  107. //
  108. class CStrmInfo
  109. {
  110. public:
  111. CStrmInfo()
  112. {
  113. Reset();
  114. _oCurrent = 0;
  115. }
  116. void Reset()
  117. {
  118. _oMapLow = _oMapHigh = ENDOFSTRM;
  119. }
  120. //
  121. // All of the offsets below are WRT to the beginning of the
  122. // "committed" region, ie, after the "hole" in the front.
  123. //
  124. ULONG _oMapLow; // Offset of the lowest mapped byte.
  125. ULONG _oMapHigh; // Offset of the highest mapped byte.
  126. ULONG _oCurrent; // Current offset.
  127. } _aStrmInfo[2];
  128. void SetCurrentStrm( CRcovStorageHdr::DataCopyNum nCopy )
  129. {
  130. _iCurr = nCopy;
  131. }
  132. BOOL IsMapped( ULONG offset );
  133. };
  134. //+---------------------------------------------------------------------------
  135. //
  136. // Function: IsMapped
  137. //
  138. // Synopsis: Checks whether the specified offset is mapped in the
  139. // current stream or not.
  140. //
  141. // Arguments: [offset] -- Byte offset to check for mapping.
  142. //
  143. // Returns: TRUE if that byte is mapped; FALSE otherwise.
  144. //
  145. // History: 2-02-94 srikants Created
  146. //
  147. // Notes:
  148. //
  149. //----------------------------------------------------------------------------
  150. inline BOOL CRcovStrmTrans::IsMapped( ULONG offset )
  151. {
  152. return ( ENDOFSTRM != _aStrmInfo[_iCurr]._oMapLow &&
  153. offset >= _aStrmInfo[_iCurr]._oMapLow &&
  154. offset <= _aStrmInfo[_iCurr]._oMapHigh ) ;
  155. }
  156. //+---------------------------------------------------------------------------
  157. //
  158. // Member: CRcovStrmTrans::AtEnd
  159. //
  160. // Synopsis: Checks if the data access is at the end of the stream.
  161. //
  162. // Returns: TRUE if at end; FALSE o/w
  163. //
  164. // History: 2-02-94 srikants Created
  165. //
  166. // Notes:
  167. //
  168. //----------------------------------------------------------------------------
  169. inline BOOL CRcovStrmTrans::AtEnd()
  170. {
  171. return (_aStrmInfo[_iCurr]._oCurrent == ENDOFSTRM) ||
  172. (_aStrmInfo[_iCurr]._oCurrent >= _hdr.GetFullSize(_iCurr));
  173. }
  174. inline ULONG CRcovStrmTrans::_GetCommittedStrmSize( PMmStream & strm,
  175. CRcovStorageHdr::DataCopyNum nCopy )
  176. {
  177. return lltoul( strm.Size() - _hdr.GetHoleLength( nCopy ) );
  178. }
  179. inline ULONG CRcovStrmTrans::_GetCommittedStrmSize( CRcovStorageHdr::DataCopyNum nCopy )
  180. {
  181. PMmStream & strm = _obj.GetMmStream( nCopy );
  182. return _GetCommittedStrmSize( strm, nCopy );
  183. }
  184. //+---------------------------------------------------------------------------
  185. //
  186. // Class: CRcovStrmReadTrans ()
  187. //
  188. // Purpose: Read Transaction for a Recoverable Stream.
  189. //
  190. // History: 2-02-94 srikants Created
  191. //
  192. // Notes:
  193. //
  194. //----------------------------------------------------------------------------
  195. class CRcovStrmReadTrans : public CRcovStrmTrans
  196. {
  197. public:
  198. CRcovStrmReadTrans( PRcovStorageObj &obj );
  199. ~CRcovStrmReadTrans();
  200. };
  201. inline CRcovStrmReadTrans::CRcovStrmReadTrans( PRcovStorageObj & obj )
  202. : CRcovStrmTrans( obj, opRead )
  203. {
  204. Commit();
  205. }
  206. inline CRcovStrmReadTrans::~CRcovStrmReadTrans()
  207. {
  208. if ( XActCommit == CTransaction::_status )
  209. {
  210. CTransaction::_status = XActAbort;
  211. Unmap( _iPrim );
  212. GetRcovObj().Close(_iPrim);
  213. CTransaction::Commit();
  214. }
  215. }
  216. //+---------------------------------------------------------------------------
  217. //
  218. // Class: CRcovStrmWriteTrans ()
  219. //
  220. // Purpose: Write transaction for a Recoverable Stream. This
  221. // is a expensive transaction mode which allows any
  222. // kind of writing on the stream.
  223. //
  224. // History: 2-02-94 srikants Created
  225. //
  226. // Notes: This transaction must be used only when there is a
  227. // need to modify something in the middle of a stream.
  228. // For appending to the stream, use the CRcovStrmAppendTrans
  229. //
  230. //----------------------------------------------------------------------------
  231. class CRcovStrmWriteTrans : public CRcovStrmTrans
  232. {
  233. public:
  234. CRcovStrmWriteTrans( PRcovStorageObj &obj );
  235. void Empty();
  236. void Append( const void *pvBuf, ULONG cbToAppend );
  237. void Write( const void *pvBuf, ULONG cbToWrite )
  238. {
  239. CRcovStrmTrans::Write( pvBuf, cbToWrite );
  240. }
  241. void Commit();
  242. };
  243. inline CRcovStrmWriteTrans::CRcovStrmWriteTrans( PRcovStorageObj & obj )
  244. : CRcovStrmTrans( obj, opModify )
  245. {
  246. }
  247. inline
  248. void CRcovStrmWriteTrans::Append( const void *pvBuf, ULONG cbToAppend )
  249. {
  250. Seek( ENDOFSTRM );
  251. Write( pvBuf, cbToAppend );
  252. }
  253. //+---------------------------------------------------------------------------
  254. //
  255. // Class: CRcovStrmAppendTrans ()
  256. //
  257. // Purpose: Append transaction for a Recoverable Stream.
  258. // Allows reading any where in the stream but writing
  259. // is only to the end of the stream ( appending ).
  260. // Optimized for append operation.
  261. //
  262. // History: 2-02-94 srikants Created
  263. //
  264. // Notes: Even though we don't want all the methods of CRcovStrmTrans
  265. // be available to CRcovStrmAppendTrans users, we cannot
  266. // selectively grant access to methods eg. declaring
  267. // CRcovStrm::Read() say in the public section because
  268. // of compiler limitations.
  269. //
  270. //----------------------------------------------------------------------------
  271. class CRcovStrmAppendTrans : public CRcovStrmTrans
  272. {
  273. public:
  274. CRcovStrmAppendTrans( PRcovStorageObj &obj );
  275. void Append( const void *pvBuf, ULONG cbToAppend, BOOL fIncrementCount = TRUE );
  276. void Commit();
  277. };
  278. inline
  279. void CRcovStrmAppendTrans::Append( const void *pvBuf, ULONG cbToAppend, BOOL fIncrementCount )
  280. {
  281. Seek( ENDOFSTRM );
  282. Write( pvBuf, cbToAppend );
  283. if ( fIncrementCount )
  284. GetStorageHdr().IncrementCount(_iBack);
  285. }
  286. //+---------------------------------------------------------------------------
  287. //
  288. // Class: CRcovStrmMDTrans ()
  289. //
  290. // Purpose: Transaced operations on Meta Data for a recoverable
  291. // stream.
  292. //
  293. // History: 2-02-94 srikants Created
  294. //
  295. // Notes:
  296. //
  297. //----------------------------------------------------------------------------
  298. class CRcovStrmMDTrans : public CRcovStrmTrans
  299. {
  300. public:
  301. enum MDOp { mdopSetSize, mdopGrow, mdopFrontShrink, mdopBackCompact };
  302. CRcovStrmMDTrans( PRcovStorageObj &obj, MDOp op, ULONG cb );
  303. void Commit();
  304. private:
  305. void SetSize( ULONG cbNew );
  306. void Grow( ULONG cbDelta );
  307. void ShrinkFromFront( ULONG cbDelta );
  308. void CompactFromEnd( ULONG cbDelta );
  309. void IncreaseBytesToSkip( ULONG cbDelta );
  310. void CopyShrinkFromFront( ULONG cbNew, ULONG cbDelta );
  311. MDOp _op;
  312. ULONG _cbOp;
  313. };
  314. //+---------------------------------------------------------------------------
  315. //
  316. // Class: CCopyRcovObject
  317. //
  318. // Purpose: Copies the given source recoverable object's data to the
  319. // destination source object.
  320. //
  321. // History: 3-17-97 srikants Created
  322. //
  323. //----------------------------------------------------------------------------
  324. class CCopyRcovObject
  325. {
  326. public:
  327. CCopyRcovObject( PRcovStorageObj & dst, PRcovStorageObj & src )
  328. : _dst(dst),
  329. _src(src),
  330. _dstHdr(dst.GetHeader()),
  331. _srcHdr(src.GetHeader())
  332. {
  333. _cbSrc = _srcHdr.GetUserDataSize( _srcHdr.GetPrimary() );
  334. }
  335. NTSTATUS DoIt();
  336. private:
  337. void _SetDstSize();
  338. void _CopyData();
  339. PRcovStorageObj & _dst;
  340. PRcovStorageObj & _src;
  341. CRcovStorageHdr & _dstHdr;
  342. CRcovStorageHdr const & _srcHdr;
  343. ULONG _cbSrc;
  344. };