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.

572 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1996.
  5. //
  6. // File: page.hxx
  7. //
  8. // Contents: Paging classes for MSF
  9. //
  10. // Classes: CMSFPage
  11. // CMSFPageTable
  12. //
  13. // Functions:
  14. //
  15. //----------------------------------------------------------------------------
  16. #ifndef __PAGE_HXX__
  17. #define __PAGE_HXX__
  18. #include "vect.hxx"
  19. class CPagedVector;
  20. #define STG_S_NEWPAGE \
  21. MAKE_SCODE(SEVERITY_SUCCESS, FACILITY_STORAGE, 0x2FF)
  22. #define FB_NONE 0x00000000
  23. #define FB_DIRTY 0x00000001
  24. #define FB_NEW 0x00000002
  25. #define FB_TOUCHED 0x10000000
  26. //+---------------------------------------------------------------------------
  27. //
  28. // Class: CMSFPage (mp)
  29. //
  30. // Purpose: Contain MSF data in a form that is swappable to disk
  31. //
  32. // Interface: See below.
  33. //
  34. // Notes:
  35. //
  36. //----------------------------------------------------------------------------
  37. class CMSFPage
  38. {
  39. public:
  40. void * operator new(size_t size, size_t sizeData);
  41. CMSFPage(CMSFPage *pmpNext);
  42. inline ~CMSFPage();
  43. inline void AddRef(void);
  44. inline void Release(void);
  45. inline CMSFPage *GetNext(void) const;
  46. inline CMSFPage *GetPrev(void) const;
  47. inline SID GetSid(void) const;
  48. inline ULONG GetOffset(void) const;
  49. inline SECT GetSect(void) const;
  50. inline void *GetData(void) const;
  51. inline DWORD GetFlags(void) const;
  52. inline CPagedVector * GetVector(void) const;
  53. inline void SetChain(CMSFPage *const pmpPrev,
  54. CMSFPage *const pmpNext);
  55. inline void SetPrev(CMSFPage *const pmpPrev);
  56. inline void SetNext(CMSFPage *const pmpNext);
  57. inline void SetSid(const SID sid);
  58. inline void SetOffset(const ULONG ulOffset);
  59. inline void SetSect(const SECT sect);
  60. inline void SetFlags(const DWORD dwFlags);
  61. inline void SetVector(CPagedVector *ppv);
  62. inline void SetDirty(void);
  63. inline void ResetDirty(void);
  64. inline BOOL IsDirty(void) const;
  65. inline BOOL IsInUse(void) const;
  66. void ByteSwap(void);
  67. private:
  68. CMSFPage *_pmpNext;
  69. CMSFPage *_pmpPrev;
  70. SID _sid;
  71. ULONG _ulOffset;
  72. CPagedVector *_ppv;
  73. SECT _sect;
  74. DWORD _dwFlags;
  75. LONG _cReferences;
  76. #ifdef _MSC_VER
  77. // disable compiler warning C4200: nonstandard extension used :
  78. // zero-sized array in struct/union
  79. #pragma warning(disable: 4200)
  80. BYTE _ab[0];
  81. #pragma warning(default: 4200)
  82. #endif
  83. #ifdef __GNUC__
  84. BYTE _ab[0];
  85. #endif
  86. };
  87. //+---------------------------------------------------------------------------
  88. //
  89. // Member: CMSFPage::~CMSFPage, public
  90. //
  91. // Synopsis: Destructor
  92. //
  93. //----------------------------------------------------------------------------
  94. inline CMSFPage::~CMSFPage()
  95. {
  96. msfAssert(_cReferences == 0);
  97. _pmpPrev->SetNext(_pmpNext);
  98. _pmpNext->SetPrev(_pmpPrev);
  99. }
  100. //+---------------------------------------------------------------------------
  101. //
  102. // Member: CMSFPage::operator new, public
  103. //
  104. // Synopsis: Overloaded new operator for CMSFPage.
  105. //
  106. // Arguments: [size] -- Default size field
  107. // [sizeData] -- Size of byte array to allocate.
  108. //
  109. // Returns: Pointer to new CMSFPage object
  110. //
  111. // Notes: *Finish This*
  112. //
  113. //----------------------------------------------------------------------------
  114. inline void * CMSFPage::operator new(size_t size, size_t sizeData)
  115. {
  116. msfAssert(size == sizeof(CMSFPage));
  117. UNREFERENCED_PARM(size); // for the retail build
  118. return ::new BYTE[sizeData + sizeof(CMSFPage)];
  119. }
  120. //+---------------------------------------------------------------------------
  121. //
  122. // Member: CMSFPage::GetNext, public
  123. //
  124. // Synopsis: Returns the next page in the list
  125. //
  126. //----------------------------------------------------------------------------
  127. inline CMSFPage * CMSFPage::GetNext(void) const
  128. {
  129. return _pmpNext;
  130. }
  131. //+---------------------------------------------------------------------------
  132. //
  133. // Member: CMSFPage::GetPrev, public
  134. //
  135. // Synopsis: Returns the next page in the list
  136. //
  137. //----------------------------------------------------------------------------
  138. inline CMSFPage * CMSFPage::GetPrev(void) const
  139. {
  140. return _pmpPrev;
  141. }
  142. //+---------------------------------------------------------------------------
  143. //
  144. // Member: CMSFPage::GetSid, public
  145. //
  146. // Synopsis: Returns the SID for this page
  147. //
  148. //----------------------------------------------------------------------------
  149. inline SID CMSFPage::GetSid(void) const
  150. {
  151. return _sid;
  152. }
  153. //+---------------------------------------------------------------------------
  154. //
  155. // Member: CMSFPage::GetOffset, public
  156. //
  157. // Synopsis: Returns the array offset for this page
  158. //
  159. //----------------------------------------------------------------------------
  160. inline ULONG CMSFPage::GetOffset(void) const
  161. {
  162. return _ulOffset;
  163. }
  164. //+---------------------------------------------------------------------------
  165. //
  166. // Member: CMSFPage::GetSect, public
  167. //
  168. // Synopsis: Returns the SECT for this page
  169. //
  170. //----------------------------------------------------------------------------
  171. inline SECT CMSFPage::GetSect(void) const
  172. {
  173. return _sect;
  174. }
  175. //+---------------------------------------------------------------------------
  176. //
  177. // Member: CMSFPage::GetFlags, public
  178. //
  179. // Synopsis: Returns the flags for this page
  180. //
  181. //----------------------------------------------------------------------------
  182. inline DWORD CMSFPage::GetFlags(void) const
  183. {
  184. return _dwFlags;
  185. }
  186. //+---------------------------------------------------------------------------
  187. //
  188. // Member: CMSFPage::GetData, public
  189. //
  190. // Synopsis: Returns a pointer to the page storage for this page
  191. //
  192. //----------------------------------------------------------------------------
  193. inline void * CMSFPage::GetData(void) const
  194. {
  195. return (void *) _ab;
  196. }
  197. //+---------------------------------------------------------------------------
  198. //
  199. // Member: CMSFPage::GetVector, public
  200. //
  201. // Synopsis: Returns a pointer to the vector holding this page
  202. //
  203. //----------------------------------------------------------------------------
  204. inline CPagedVector * CMSFPage::GetVector(void) const
  205. {
  206. return _ppv;
  207. }
  208. //+---------------------------------------------------------------------------
  209. //
  210. // Member: CMSFPage::SetChain, public
  211. //
  212. // Synopsis: Sets the chain pointers for this page
  213. //
  214. //----------------------------------------------------------------------------
  215. inline void CMSFPage::SetChain(
  216. CMSFPage *const pmpPrev,
  217. CMSFPage *const pmpNext)
  218. {
  219. _pmpPrev = pmpPrev;
  220. _pmpNext = pmpNext;
  221. }
  222. //+---------------------------------------------------------------------------
  223. //
  224. // Member: CMSFPage::SetPrev, public
  225. //
  226. // Synopsis: Sets the prev pointer for this page
  227. //
  228. //----------------------------------------------------------------------------
  229. inline void CMSFPage::SetPrev(CMSFPage *const pmpPrev)
  230. {
  231. _pmpPrev = pmpPrev;
  232. }
  233. //+---------------------------------------------------------------------------
  234. //
  235. // Member: CMSFPage::SetNext, public
  236. //
  237. // Synopsis: Sets the next pointer for this page
  238. //
  239. //----------------------------------------------------------------------------
  240. inline void CMSFPage::SetNext(CMSFPage *const pmpNext)
  241. {
  242. _pmpNext = pmpNext;
  243. }
  244. //+---------------------------------------------------------------------------
  245. //
  246. // Member: CMSFPage::SetSid, public
  247. //
  248. // Synopsis: Sets the SID for this page
  249. //
  250. //----------------------------------------------------------------------------
  251. inline void CMSFPage::SetSid(const SID sid)
  252. {
  253. _sid = sid;
  254. }
  255. //+---------------------------------------------------------------------------
  256. //
  257. // Member: CMSFPage::SetOffset, public
  258. //
  259. // Synopsis: Sets the offset for this page
  260. //
  261. //----------------------------------------------------------------------------
  262. inline void CMSFPage::SetOffset(const ULONG ulOffset)
  263. {
  264. _ulOffset = ulOffset;
  265. }
  266. //+---------------------------------------------------------------------------
  267. //
  268. // Member: CMSFPage::SetSect, public
  269. //
  270. // Synopsis: Sets the SECT for this page
  271. //
  272. //----------------------------------------------------------------------------
  273. inline void CMSFPage::SetSect(const SECT sect)
  274. {
  275. _sect = sect;
  276. }
  277. //+---------------------------------------------------------------------------
  278. //
  279. // Member: CMSFPage::SetSect, public
  280. //
  281. // Synopsis: Sets the SECT for this page
  282. //
  283. //----------------------------------------------------------------------------
  284. inline void CMSFPage::SetFlags(const DWORD dwFlags)
  285. {
  286. _dwFlags = dwFlags;
  287. }
  288. //+---------------------------------------------------------------------------
  289. //
  290. // Member: CMSFPage::SetVector, public
  291. //
  292. // Synopsis: Sets the pointer to the vector holding this page
  293. //
  294. //----------------------------------------------------------------------------
  295. inline void CMSFPage::SetVector(CPagedVector *ppv)
  296. {
  297. _ppv = ppv;
  298. }
  299. //+---------------------------------------------------------------------------
  300. //
  301. // Member: CMSFPage::SetDirty, public
  302. //
  303. // Synopsis: Sets the dirty bit for this page
  304. //
  305. //----------------------------------------------------------------------------
  306. inline void CMSFPage::SetDirty(void)
  307. {
  308. _dwFlags = _dwFlags | FB_DIRTY;
  309. }
  310. //+---------------------------------------------------------------------------
  311. //
  312. // Member: CMSFPage::ResetDirty, public
  313. //
  314. // Synopsis: Resets the dirty bit for this page
  315. //
  316. //----------------------------------------------------------------------------
  317. inline void CMSFPage::ResetDirty(void)
  318. {
  319. _dwFlags = _dwFlags & ~FB_DIRTY;
  320. }
  321. //+---------------------------------------------------------------------------
  322. //
  323. // Member: CMSFPage::IsDirty, public
  324. //
  325. // Synopsis: Returns TRUE if the dirty bit is set on this page
  326. //
  327. //----------------------------------------------------------------------------
  328. inline BOOL CMSFPage::IsDirty(void) const
  329. {
  330. return (_dwFlags & FB_DIRTY) != 0;
  331. }
  332. //+---------------------------------------------------------------------------
  333. //
  334. // Member: CMSFPage::IsInUse, public
  335. //
  336. // Synopsis: Returns TRUE if the page is currently in use
  337. //
  338. //----------------------------------------------------------------------------
  339. inline BOOL CMSFPage::IsInUse(void) const
  340. {
  341. return (_cReferences != 0);
  342. }
  343. //+---------------------------------------------------------------------------
  344. //
  345. // Member: CMSFPage::AddRef, public
  346. //
  347. // Synopsis: Increment the reference count
  348. //
  349. //----------------------------------------------------------------------------
  350. inline void CMSFPage::AddRef(void)
  351. {
  352. msfAssert(_cReferences >= 0);
  353. AtomicInc(&_cReferences);
  354. }
  355. //+---------------------------------------------------------------------------
  356. //
  357. // Member: CMSFPage::Release, public
  358. //
  359. // Synopsis: Decrement the reference count
  360. //
  361. //----------------------------------------------------------------------------
  362. inline void CMSFPage::Release(void)
  363. {
  364. msfAssert(_cReferences > 0);
  365. AtomicDec(&_cReferences);
  366. }
  367. //+---------------------------------------------------------------------------
  368. //
  369. // Class: CMSFPageTable
  370. //
  371. // Purpose: Page allocator and handler for MSF
  372. //
  373. // Interface: See below
  374. //
  375. // Notes:
  376. //
  377. //----------------------------------------------------------------------------
  378. class CMSFPageTable
  379. {
  380. public:
  381. CMSFPageTable( CMStream *const pmsParent,
  382. const ULONG _cMinPages,
  383. const ULONG _cMaxPages);
  384. ~CMSFPageTable();
  385. inline void AddRef();
  386. inline void Release();
  387. SCODE Init(void);
  388. SCODE GetPage( CPagedVector *ppv,
  389. SID sid,
  390. ULONG ulOffset,
  391. CMSFPage **ppmp);
  392. SCODE FindPage( CPagedVector *ppv,
  393. SID sid,
  394. ULONG ulOffset,
  395. CMSFPage **ppmp);
  396. SCODE GetFreePage(CMSFPage **ppmp);
  397. void ReleasePage(CPagedVector *ppv, SID sid, ULONG ulOffset);
  398. void FreePages(CPagedVector *ppv);
  399. SCODE Flush(void);
  400. SCODE FlushPage(CMSFPage *pmp);
  401. inline void SetParent(CMStream *pms);
  402. private:
  403. inline CMSFPage * GetNewPage(void);
  404. CMSFPage * FindSwapPage(void);
  405. CMStream * _pmsParent;
  406. const ULONG _cbSector;
  407. const ULONG _cMinPages;
  408. const ULONG _cMaxPages;
  409. ULONG _cActivePages;
  410. ULONG _cPages;
  411. CMSFPage *_pmpCurrent;
  412. LONG _cReferences;
  413. #ifdef _MSC_VER
  414. #pragma warning(disable:4512)
  415. // since there is a const member, there should be no assignment operator
  416. #endif // _MSC_VER
  417. };
  418. #ifdef _MSC_VER
  419. #pragma warning(default:4512)
  420. #endif // _MSC_VER
  421. //+---------------------------------------------------------------------------
  422. //
  423. // Member: CMSFPageTable::GetNewPage, private
  424. //
  425. // Synopsis: Insert a new page into the list and return a pointer to it.
  426. //
  427. // Arguments: None.
  428. //
  429. // Returns: Pointer to new page. Null if there was an allocation error.
  430. //
  431. // Notes:
  432. //
  433. //----------------------------------------------------------------------------
  434. inline CMSFPage * CMSFPageTable::GetNewPage(void)
  435. {
  436. return new((size_t)_cbSector) CMSFPage(_pmpCurrent);
  437. }
  438. //+---------------------------------------------------------------------------
  439. //
  440. // Member: CMSFPageTable::AddRef, public
  441. //
  442. // Synopsis: Increment the ref coutn
  443. //
  444. //----------------------------------------------------------------------------
  445. inline void CMSFPageTable::AddRef(void)
  446. {
  447. AtomicInc(&_cReferences);
  448. }
  449. //+---------------------------------------------------------------------------
  450. //
  451. // Member: CMSFPageTable::Release, public
  452. //
  453. // Synopsis: Decrement the ref count, delete if necessary
  454. //
  455. //----------------------------------------------------------------------------
  456. inline void CMSFPageTable::Release(void)
  457. {
  458. msfAssert(_cReferences > 0);
  459. AtomicDec(&_cReferences);
  460. if (_cReferences == 0)
  461. {
  462. delete this;
  463. }
  464. }
  465. //+---------------------------------------------------------------------------
  466. //
  467. // Member: CMSFPageTable::SetParent, public
  468. //
  469. // Synopsis: Set the parent of this page table
  470. //
  471. // Arguments: [pms] -- Pointer to new parent
  472. //
  473. //----------------------------------------------------------------------------
  474. inline void CMSFPageTable::SetParent(CMStream *pms)
  475. {
  476. _pmsParent = pms;
  477. }
  478. #endif // #ifndef __PAGE_HXX__