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.

602 lines
12 KiB

  1. /*++
  2. Copyright (c) 1991-2000 Microsoft Corporation
  3. Module Name:
  4. ntfsbit.hxx
  5. Abstract:
  6. This module contains the declarations for NTFS_BITMAP,
  7. which models the bitmaps on an NTFS volume. There are three
  8. kinds of bitmaps on an NTFS volume:
  9. (1) The Volume Bitmap, which is stored as the nameless $DATA
  10. attribute of the bitmap file. This bitmap has one bit for
  11. each cluster on the disk, and is of fixed size. It is unique.
  12. (2) The MFT Bitmap, which is stored as the value of the nameless
  13. $BITMAP attribute of the Master File Table File. It has one
  14. bit per File Record Segment in the Master File Table, and grows
  15. with the Master File Table. It is unique.
  16. (3) Index Allocation bitmaps. An index allocation bitmap is stored
  17. as the value of a $BITMAP attribute in a File Record Segment
  18. that has an $INDEX_ALLOCATION attribute. The name of the $BITMAP
  19. attribute agrees with the associated $INDEX_ALLOCATION attribute.
  20. This bitmap has one bit for each index allocation buffer in the
  21. associated $INDEX_ALLOCATION attribute, and grows with that
  22. attribute.
  23. In every case, a set bit indicates that the associated allocation
  24. unit (cluster, File Record Segment, or Index Allocation Buffer) is
  25. allocated; a reset bit indicates that it is free.
  26. The size of a bitmap (in bytes) is always quad-word aligned; bytes
  27. are added at the end of the bitmap to pad it to the correct size.
  28. If the bitmap is of fixed size, then all bits in the padding are
  29. set (allocated); if it is growable, the bits of the padding are
  30. reset (free).
  31. Author:
  32. Bill McJohn (billmc) 17-June-91
  33. Environment:
  34. ULIB, User Mode
  35. --*/
  36. #if !defined( _NTFS_BITMAP_DEFN_ )
  37. #define _NTFS_BITMAP_DEFN_
  38. #include "bitvect.hxx"
  39. #include "attrib.hxx"
  40. DECLARE_CLASS( NTFS_ATTRIBUTE );
  41. DECLARE_CLASS( NTFS_BITMAP );
  42. DECLARE_CLASS( NTFS_MASTER_FILE_TABLE );
  43. class NTFS_BITMAP : public OBJECT {
  44. public:
  45. UNTFS_EXPORT
  46. DECLARE_CONSTRUCTOR( NTFS_BITMAP );
  47. VIRTUAL
  48. UNTFS_EXPORT
  49. ~NTFS_BITMAP(
  50. );
  51. NONVIRTUAL
  52. UNTFS_EXPORT
  53. BOOLEAN
  54. Initialize(
  55. IN BIG_INT NumberOfClusters,
  56. IN BOOLEAN IsGrowable,
  57. IN PLOG_IO_DP_DRIVE Drive DEFAULT NULL,
  58. IN ULONG ClusterFactor DEFAULT 0
  59. );
  60. NONVIRTUAL
  61. BOOLEAN
  62. Create(
  63. );
  64. NONVIRTUAL
  65. BIG_INT
  66. QuerySize(
  67. ) CONST;
  68. NONVIRTUAL
  69. VOID
  70. SetFree(
  71. IN LCN Lcn,
  72. IN BIG_INT NumberOfClusters
  73. );
  74. NONVIRTUAL
  75. VOID
  76. SetAllocated(
  77. IN LCN Lcn,
  78. IN BIG_INT NumberOfClusters
  79. );
  80. NONVIRTUAL
  81. VOID
  82. SetNextAlloc(
  83. IN LCN Lcn
  84. );
  85. NONVIRTUAL
  86. BIG_INT
  87. QueryFreeClusters(
  88. ) CONST;
  89. NONVIRTUAL
  90. BIG_INT
  91. QueryFreeBlockSize(
  92. IN LCN Lcn
  93. ) CONST;
  94. NONVIRTUAL
  95. UNTFS_EXPORT
  96. BOOLEAN
  97. IsFree(
  98. IN LCN Lcn,
  99. IN BIG_INT RunLength
  100. ) CONST;
  101. NONVIRTUAL
  102. UNTFS_EXPORT
  103. BOOLEAN
  104. IsAllocated(
  105. IN LCN Lcn,
  106. IN BIG_INT RunLength
  107. ) CONST;
  108. NONVIRTUAL
  109. BOOLEAN
  110. IsInRange(
  111. IN LCN Lcn,
  112. IN BIG_INT RunLength
  113. ) CONST;
  114. NONVIRTUAL
  115. BOOLEAN
  116. AllocateClusters(
  117. IN LCN NearHere OPTIONAL,
  118. IN BIG_INT NumberOfClusters,
  119. OUT PLCN FirstAllocatedLcn,
  120. IN ULONG AlignmentFactor DEFAULT 1
  121. );
  122. NONVIRTUAL
  123. BOOLEAN
  124. Read(
  125. IN OUT PNTFS_ATTRIBUTE BitmapAttribute
  126. );
  127. NONVIRTUAL
  128. UNTFS_EXPORT
  129. BOOLEAN
  130. Write(
  131. IN OUT PNTFS_ATTRIBUTE BitmapAttribute,
  132. IN OUT PNTFS_BITMAP VolumeBitmap OPTIONAL
  133. );
  134. NONVIRTUAL
  135. BOOLEAN
  136. CheckAttributeSize(
  137. IN OUT PNTFS_ATTRIBUTE BitmapAttribute,
  138. IN OUT PNTFS_BITMAP VolumeBitmap
  139. );
  140. NONVIRTUAL
  141. BOOLEAN
  142. Resize(
  143. IN BIG_INT NumberOfClusters
  144. );
  145. NONVIRTUAL
  146. PCVOID
  147. GetBitmapData(
  148. OUT PULONG SizeInBytes
  149. ) CONST;
  150. NONVIRTUAL
  151. VOID
  152. SetMftPointer(
  153. IN PNTFS_MASTER_FILE_TABLE Mft
  154. );
  155. NONVIRTUAL
  156. VOID
  157. SetGrowable(
  158. IN BOOLEAN Growable
  159. );
  160. private:
  161. NONVIRTUAL
  162. VOID
  163. Construct (
  164. );
  165. NONVIRTUAL
  166. VOID
  167. Destroy(
  168. );
  169. BIG_INT _NumberOfClusters;
  170. BOOLEAN _IsGrowable;
  171. ULONG _BitmapSize;
  172. PVOID _BitmapData;
  173. BIG_INT _NextAlloc;
  174. BITVECTOR _Bitmap;
  175. //
  176. // This is to support testing newly-allocated clusters in the
  177. // volume bitmap to ensure they can support IO.
  178. //
  179. PLOG_IO_DP_DRIVE _Drive;
  180. ULONG _ClusterFactor;
  181. PNTFS_MASTER_FILE_TABLE _Mft;
  182. };
  183. INLINE
  184. BIG_INT
  185. NTFS_BITMAP::QuerySize(
  186. ) CONST
  187. /*++
  188. Routine Description:
  189. This method returns the number of clusters covered by this bitmap.
  190. Arguments:
  191. None.
  192. Return Value:
  193. The number of clusters covered by this bitmap.
  194. --*/
  195. {
  196. return _NumberOfClusters;
  197. }
  198. INLINE
  199. VOID
  200. NTFS_BITMAP::SetFree(
  201. IN LCN Lcn,
  202. IN BIG_INT RunLength
  203. )
  204. /*++
  205. Routine Description:
  206. This method marks a run of clusters as free in the bitmap.
  207. Arguments:
  208. Lcn -- supplies the LCN of the first cluster in the run
  209. RunLength -- supplies the length of the run
  210. Return Value:
  211. None.
  212. Notes:
  213. This method performs range checking.
  214. --*/
  215. {
  216. // Since the high part of _NumberOfClusters is zero, if
  217. // Lcn and RunLength pass the range-checking, their high
  218. // parts must also be zero.
  219. if( !(Lcn < 0) &&
  220. !(RunLength < 0 ) &&
  221. !(Lcn + RunLength > _NumberOfClusters) ) {
  222. _Bitmap.ResetBit( Lcn.GetLowPart(), RunLength.GetLowPart() ) ;
  223. }
  224. }
  225. INLINE
  226. VOID
  227. NTFS_BITMAP::SetAllocated(
  228. IN LCN Lcn,
  229. IN BIG_INT RunLength
  230. )
  231. /*++
  232. Routine Description:
  233. This method marks a run of clusters as used in the bitmap.
  234. Arguments:
  235. Lcn -- supplies the LCN of the first cluster in the run
  236. RunLength -- supplies the length of the run
  237. Return Value:
  238. None.
  239. Notes:
  240. This method performs range checking.
  241. --*/
  242. {
  243. // Since the high part of _NumberOfClusters is zero, if
  244. // Lcn and RunLength pass the range-checking, their high
  245. // parts must also be zero.
  246. if( !(Lcn < 0) &&
  247. !(Lcn + RunLength > _NumberOfClusters) ) {
  248. _Bitmap.SetBit( Lcn.GetLowPart(), RunLength.GetLowPart() );
  249. }
  250. }
  251. INLINE
  252. VOID
  253. NTFS_BITMAP::SetNextAlloc(
  254. IN LCN Lcn
  255. )
  256. /*++
  257. Routine Description:
  258. This method sets the next allocation location from the bitmap.
  259. Arguments:
  260. Lcn -- supplies the LCN of the first cluster to allocate
  261. Return Value:
  262. None.
  263. Notes:
  264. This method performs range checking.
  265. --*/
  266. {
  267. if( !(Lcn < 0) &&
  268. !(Lcn > _NumberOfClusters) ) {
  269. _NextAlloc = Lcn;
  270. }
  271. }
  272. INLINE
  273. BIG_INT
  274. NTFS_BITMAP::QueryFreeClusters(
  275. ) CONST
  276. /*++
  277. Routine Description:
  278. This method returns the number of free clusters in the bitmap.
  279. Arguments:
  280. None.
  281. Return Value:
  282. The number of free clusters in the bitmap.
  283. --*/
  284. {
  285. BIG_INT result;
  286. if( _IsGrowable ) {
  287. // The bits in the padding are marked as free (ie. are
  288. // not set). Thus, we can just count the number of set
  289. // bits and subtract that from the number of clusters.
  290. //
  291. result = _NumberOfClusters - ((PNTFS_BITMAP) this)->_Bitmap.QueryCountSet();
  292. } else {
  293. // The bits in the padding are marked as in-use (ie.
  294. // are set), so we need to compensate for them when
  295. // we count the number of bits that are set.
  296. //
  297. result = _BitmapSize*8 - ((PNTFS_BITMAP) this)->_Bitmap.QueryCountSet();
  298. }
  299. return result;
  300. }
  301. INLINE
  302. BOOLEAN
  303. NTFS_BITMAP::Create(
  304. )
  305. /*++
  306. Routine Description:
  307. This method sets up an NTFS_BITMAP object in memory. Note that
  308. it does not write the bitmap to disk.
  309. Arguments:
  310. None.
  311. Return Value:
  312. TRUE upon successful completion.
  313. Notes:
  314. The newly-created bitmap begins with all clusters marked as FREE.
  315. --*/
  316. {
  317. SetFree( 0, _NumberOfClusters );
  318. return TRUE;
  319. }
  320. INLINE
  321. BOOLEAN
  322. NTFS_BITMAP::IsInRange(
  323. IN LCN Lcn,
  324. IN BIG_INT RunLength
  325. ) CONST
  326. /*++
  327. Routine Description:
  328. This routine computes whether or not the given range of clusters is
  329. in the range allowed by this bitmap.
  330. Arguments:
  331. Lcn - Supplies the first cluster in the range.
  332. RunLength - Supplies the number of clusters in the range.
  333. Return Value:
  334. FALSE - The specified range of clusters is not within the range of
  335. the bitmap.
  336. TRUE - The specified range of clusters is within the range of
  337. the bitmap.
  338. --*/
  339. {
  340. return (BOOLEAN) ((Lcn >= 0) &&
  341. (RunLength >= 0 ) &&
  342. (Lcn + RunLength <= _NumberOfClusters));
  343. }
  344. INLINE
  345. BOOLEAN
  346. NTFS_BITMAP::Read(
  347. PNTFS_ATTRIBUTE BitmapAttribute
  348. )
  349. /*++
  350. Routine Description:
  351. This method reads the bitmap.
  352. Arguments:
  353. BitmapAttribute -- supplies the attribute which describes the
  354. bitmap's location on disk.
  355. Return Value:
  356. TRUE upon successful completion.
  357. --*/
  358. {
  359. ULONG BytesRead;
  360. DebugPtrAssert( _BitmapData );
  361. return( BitmapAttribute->Read( _BitmapData,
  362. 0,
  363. _BitmapSize,
  364. &BytesRead ) &&
  365. BytesRead == _BitmapSize );
  366. }
  367. INLINE
  368. BOOLEAN
  369. NTFS_BITMAP::CheckAttributeSize(
  370. IN OUT PNTFS_ATTRIBUTE BitmapAttribute,
  371. IN OUT PNTFS_BITMAP VolumeBitmap
  372. )
  373. /*++
  374. Routine Description:
  375. This method ensures that the allocated size of the attribute is
  376. big enough to hold the bitmap.
  377. Arguments:
  378. BitmapAttribute -- Supplies the attribute which describes the
  379. bitmap's location on disk.
  380. VolumeBitmap -- Supplies the volume bitmap.
  381. Return Value:
  382. TRUE upon successful completion.
  383. --*/
  384. {
  385. DebugAssert( BitmapAttribute != NULL );
  386. return( BitmapAttribute->QueryValueLength() == _BitmapSize ||
  387. BitmapAttribute->Resize( _BitmapSize, VolumeBitmap ) );
  388. }
  389. INLINE
  390. PCVOID
  391. NTFS_BITMAP::GetBitmapData(
  392. OUT PULONG SizeInBytes
  393. ) CONST
  394. /*++
  395. Routine Description:
  396. This routine returns a pointer to the in memory bitmap contained by
  397. this class. It also return the size in bytes of the bitmap.
  398. Arguments:
  399. SizeInBytes - Returns the size of the bitmap.
  400. Return Value:
  401. The bitmap contained by this class.
  402. --*/
  403. {
  404. *SizeInBytes = _BitmapSize;
  405. return _BitmapData;
  406. }
  407. INLINE
  408. VOID
  409. NTFS_BITMAP::SetMftPointer(
  410. IN PNTFS_MASTER_FILE_TABLE Mft
  411. )
  412. /*++
  413. Routine Description:
  414. This routine set the _Mft member in the NTFS_BITMAP so that
  415. subsequent calls to AllocateClusters will be able to add any
  416. bad clusters found to the bad cluster file.
  417. Arguments:
  418. Mft - pointer to the volume's mft.
  419. Return Value:
  420. None.
  421. --*/
  422. {
  423. _Mft = Mft;
  424. }
  425. #endif // _NTFS_BITMAP_DEFN_