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.

293 lines
7.8 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1991 - 1992.
  5. //
  6. // File: Borrow.hxx
  7. //
  8. // Contents: Smart encapsulation of buffer
  9. //
  10. // Classes: CBorrowed
  11. //
  12. // History: 27-Dec-19 KyleP Created
  13. //
  14. //----------------------------------------------------------------------------
  15. #pragma once
  16. #include <propstor.hxx>
  17. #include <proprec.hxx>
  18. //+-------------------------------------------------------------------------
  19. //
  20. // Class: CBorrowed
  21. //
  22. // Purpose: Smart wrapper for bowwowing (and returning!) buffer.
  23. //
  24. // History: 27-Dec-95 KyleP Created
  25. //
  26. //--------------------------------------------------------------------------
  27. class CBorrowed
  28. {
  29. public:
  30. inline CBorrowed( CPhysPropertyStore & store,
  31. ULONG cRecPerPage,
  32. ULONG culRec );
  33. inline CBorrowed( CPhysPropertyStore & store,
  34. WORKID wid,
  35. ULONG cRecPerPage,
  36. ULONG culRec,
  37. BOOL fIntentToWrite = TRUE );
  38. inline CBorrowed( CBorrowed & src );
  39. inline ~CBorrowed();
  40. inline CBorrowed & operator=( CBorrowed & src );
  41. inline void Set( WORKID wid, BOOL fIntentToWrite = TRUE );
  42. inline void SetMaybeNew( WORKID wid );
  43. inline void Release();
  44. inline COnDiskPropertyRecord * Get();
  45. private:
  46. COnDiskPropertyRecord * _prec;
  47. ULONG _nLargePage;
  48. ULONG _cRecPerPage;
  49. ULONG _culRec;
  50. CPhysPropertyStore & _store;
  51. };
  52. #if CIDBG == 1
  53. //+-------------------------------------------------------------------------
  54. //
  55. // Class: XBorrowExisting
  56. //
  57. // Purpose: Smart wrapper for borrowing (and returning!) buffer.
  58. //
  59. // History: 16-Oct-97 KyleP Created
  60. //
  61. //--------------------------------------------------------------------------
  62. class XBorrowExisting
  63. {
  64. public:
  65. XBorrowExisting( CPhysPropertyStore & store, ULONG nLargePage, BOOL fWrite = FALSE )
  66. : _store( store ),
  67. _nLargePage( nLargePage ),
  68. _pulPage( _store.BorrowLargeBuffer( nLargePage, fWrite ) )
  69. {
  70. }
  71. ~XBorrowExisting()
  72. {
  73. _store.ReturnLargeBuffer( _nLargePage );
  74. }
  75. BYTE * Get() { return (BYTE *)_pulPage; }
  76. private:
  77. CPhysStorage & _store;
  78. ULONG _nLargePage;
  79. ULONG * _pulPage;
  80. };
  81. #endif
  82. inline CBorrowed::CBorrowed( CPhysPropertyStore & store,
  83. ULONG cRecPerPage,
  84. ULONG culRec )
  85. : _store( store ),
  86. _prec( 0 ),
  87. _nLargePage( 0xFFFFFFFF ),
  88. _cRecPerPage( cRecPerPage ),
  89. _culRec( culRec )
  90. {
  91. }
  92. inline CBorrowed::CBorrowed( CPhysPropertyStore & store,
  93. WORKID wid,
  94. ULONG cRecPerPage,
  95. ULONG culRec,
  96. BOOL fIntentToWrite )
  97. : _store( store ),
  98. _prec( 0 ),
  99. _nLargePage( 0xFFFFFFFF ),
  100. _cRecPerPage( cRecPerPage ),
  101. _culRec( culRec )
  102. {
  103. Set( wid, fIntentToWrite );
  104. }
  105. inline CBorrowed::CBorrowed( CBorrowed & src )
  106. : _store( src._store ),
  107. _prec( 0 ),
  108. _nLargePage( 0xFFFFFFFF ),
  109. _cRecPerPage( src._cRecPerPage ),
  110. _culRec( src._culRec )
  111. {
  112. *this = src;
  113. }
  114. inline CBorrowed::~CBorrowed()
  115. {
  116. Release();
  117. }
  118. inline CBorrowed & CBorrowed::operator=( CBorrowed & src )
  119. {
  120. Win4Assert( &_store == &src._store );
  121. Win4Assert( _cRecPerPage == src._cRecPerPage );
  122. Win4Assert( 0xFFFFFFFF == _nLargePage );
  123. _nLargePage = src._nLargePage;
  124. src._nLargePage = 0xFFFFFFFF;
  125. _prec = src._prec;
  126. src._prec = 0;
  127. return *this;
  128. }
  129. inline void CBorrowed::Set( WORKID wid, BOOL fIntentToWrite )
  130. {
  131. Win4Assert( 0xFFFFFFFF == _nLargePage && "Borrow buffer not released" );
  132. Win4Assert( 0 == _prec );
  133. if (widInvalid == wid || 0 == wid)
  134. {
  135. ciDebugOut((DEB_PROPSTORE, "CBorrowed::Set: Attempted to set wid 0x%x!\n", wid));
  136. }
  137. else
  138. {
  139. WORKID widInRec = wid % _cRecPerPage;
  140. ULONG nLargePage = wid / _cRecPerPage;
  141. // Borrow the buffer for write and pass the intent to write flag
  142. #if 0 // compiler bug 3/27/02 in Windows Server 2003 tree 13.01.2035
  143. _prec = new( widInRec,
  144. (BYTE *)_store.BorrowLargeBuffer( nLargePage,
  145. TRUE,
  146. fIntentToWrite ),
  147. _culRec ) COnDiskPropertyRecord();
  148. #else
  149. BYTE * pb = (BYTE *) _store.BorrowLargeBuffer( nLargePage,
  150. TRUE,
  151. fIntentToWrite );
  152. _prec = (COnDiskPropertyRecord *) ( pb + ( widInRec * _culRec * 4 ) );
  153. #endif
  154. _nLargePage = nLargePage;
  155. ciDebugOut(( DEB_PROPSTORE, "Wid %u (0x%x) --> wid %u of %u on %uK page %u. p = 0x%x\n",
  156. wid, wid,
  157. widInRec,
  158. _cRecPerPage,
  159. COMMON_PAGE_SIZE / 1024,
  160. _nLargePage,
  161. _prec ));
  162. }
  163. }
  164. inline void CBorrowed::SetMaybeNew( WORKID wid )
  165. {
  166. Win4Assert( 0xFFFFFFFF == _nLargePage );
  167. Win4Assert( 0 != wid );
  168. WORKID widInRec = wid % _cRecPerPage;
  169. ULONG nLargePage = wid / _cRecPerPage;
  170. // The first valid wid is 1, so when we are writing the first
  171. // record, we need to borrow a new large buffer.
  172. if ( 1 == wid || 0 == widInRec )
  173. {
  174. #if 0 // compiler bug 3/27/02 in Windows Server 2003 tree 13.01.2035
  175. _prec = new( (1 == wid) ? 1 : 0,
  176. (BYTE *)_store.BorrowNewLargeBuffer( nLargePage ),
  177. _culRec ) COnDiskPropertyRecord();
  178. #else
  179. BYTE * pb = (BYTE *) _store.BorrowNewLargeBuffer( nLargePage );
  180. WORKID wir = (1 == wid) ? 1 : 0;
  181. _prec = (COnDiskPropertyRecord *) ( pb + ( wir * _culRec * 4 ) );
  182. #endif
  183. #if CIDBG == 1
  184. // verify that we are always getting zero filled pages. We rely on that
  185. ULONG ulLen = COMMON_PAGE_SIZE/sizeof(ULONG);
  186. // Start from the first record in page. Most times it is record 0, but
  187. // it could be 1 on occassion.
  188. if (1 == wid)
  189. ulLen -= _culRec;
  190. for (ULONG i = 0; i < ulLen ; i++)
  191. Win4Assert(0 == ((ULONG *)_prec)[i]);
  192. #endif
  193. }
  194. else
  195. {
  196. #if 0 // compiler bug 3/27/02 in Windows Server 2003 tree 13.01.2035
  197. _prec = new( widInRec,
  198. (BYTE *)_store.BorrowLargeBuffer( nLargePage ),
  199. _culRec ) COnDiskPropertyRecord();
  200. #else
  201. BYTE * pb = (BYTE *) _store.BorrowLargeBuffer( nLargePage );
  202. _prec = (COnDiskPropertyRecord *) ( pb + ( widInRec * _culRec * 4 ) );
  203. #endif
  204. }
  205. _nLargePage = nLargePage;
  206. ciDebugOut(( DEB_PROPSTORE, "Wid %u (0x%x) --> wid %u of %u on %uK page %u. p = 0x%x\n",
  207. wid, wid,
  208. widInRec,
  209. _cRecPerPage,
  210. COMMON_PAGE_SIZE / 1024,
  211. _nLargePage,
  212. _prec ));
  213. }
  214. inline void CBorrowed::Release()
  215. {
  216. if ( 0xFFFFFFFF != _nLargePage )
  217. {
  218. _store.ReturnLargeBuffer( _nLargePage );
  219. _nLargePage = 0xFFFFFFFF;
  220. _prec = 0;
  221. }
  222. }
  223. inline COnDiskPropertyRecord * CBorrowed::Get()
  224. {
  225. return _prec;
  226. }