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.

703 lines
17 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. indxtree.hxx
  5. Abstract:
  6. this module contains the declarations for the NTFS_INDEX_TREE
  7. class, which models index trees on an NTFS volume.
  8. An NTFS Index Tree consists of an index root and a set of
  9. index buffers. The index root is stored as the value of
  10. an INDEX_ROOT attribute; the index buffers are part of the
  11. value of an INDEX_ALLOCATION attribute.
  12. Author:
  13. Bill McJohn (billmc) 30-Aug-1991
  14. Environment:
  15. ULIB, User Mode
  16. --*/
  17. #if !defined( _NTFS_INDEX_TREE_DEFN_ )
  18. #define _NTFS_INDEX_TREE_DEFN_
  19. #include "hmem.hxx"
  20. #include "intstack.hxx"
  21. DECLARE_CLASS( LOG_IO_DP_DRIVE );
  22. DECLARE_CLASS( WSTRING );
  23. DECLARE_CLASS( NTFS_ATTRIBUTE );
  24. DECLARE_CLASS( NTFS_BITMAP );
  25. DECLARE_CLASS( NTFS_INDEX_ROOT );
  26. DECLARE_CLASS( NTFS_INDEX_BUFFER );
  27. DECLARE_CLASS( NTFS_FILE_RECORD_SEGMENT );
  28. DECLARE_CLASS( NTFS_UPCASE_TABLE );
  29. // This constant is given to FindEntry to indicate it should skip
  30. // all matching entries.
  31. //
  32. CONST ULONG INDEX_SKIP = (ULONG)(-1);
  33. typedef enum INDEX_ITERATOR_STATE {
  34. INDEX_ITERATOR_RESET,
  35. INDEX_ITERATOR_CURRENT,
  36. INDEX_ITERATOR_INVALID,
  37. INDEX_ITERATOR_DELETED,
  38. INDEX_ITERATOR_CORRUPT
  39. };
  40. typedef enum INDEX_ENTRY_TYPE {
  41. INDEX_ENTRY_WITH_DATA_TYPE_4 = 0, // value is used as an index to
  42. INDEX_ENTRY_WITH_DATA_TYPE_8 = 1, // IndexEntryAttributeLength array;
  43. INDEX_ENTRY_WITH_DATA_TYPE_12 = 2, // these values should not be changed
  44. INDEX_ENTRY_WITH_DATA_TYPE_16 = 3,
  45. INDEX_ENTRY_WITH_DATA_TYPE,
  46. INDEX_ENTRY_WITH_FILE_NAME_TYPE,
  47. INDEX_ENTRY_GENERIC_TYPE
  48. };
  49. LONG
  50. NtfsCollate(
  51. IN PCVOID Value1,
  52. IN ULONG Length1,
  53. IN PCVOID Value2,
  54. IN ULONG Length2,
  55. IN COLLATION_RULE CollationRule,
  56. IN PNTFS_UPCASE_TABLE UpcaseTable OPTIONAL
  57. );
  58. LONG
  59. CompareNtfsIndexEntries(
  60. IN PCINDEX_ENTRY Entry1,
  61. IN PCINDEX_ENTRY Entry2,
  62. IN COLLATION_RULE CollationRule,
  63. IN PNTFS_UPCASE_TABLE UpcaseTable OPTIONAL
  64. );
  65. class NTFS_INDEX_TREE : public OBJECT {
  66. public:
  67. UNTFS_EXPORT
  68. DECLARE_CONSTRUCTOR( NTFS_INDEX_TREE );
  69. VIRTUAL
  70. UNTFS_EXPORT
  71. ~NTFS_INDEX_TREE(
  72. );
  73. NONVIRTUAL
  74. UNTFS_EXPORT
  75. BOOLEAN
  76. Initialize(
  77. IN OUT PLOG_IO_DP_DRIVE Drive,
  78. IN ULONG ClusterFactor,
  79. IN OUT PNTFS_BITMAP VolumeBitmap,
  80. IN PNTFS_UPCASE_TABLE UpcaseTable,
  81. IN ULONG MaximumRootSize,
  82. IN PNTFS_FILE_RECORD_SEGMENT SourceFrs,
  83. IN PCWSTRING IndexName DEFAULT NULL
  84. );
  85. NONVIRTUAL
  86. UNTFS_EXPORT
  87. BOOLEAN
  88. Initialize(
  89. IN ATTRIBUTE_TYPE_CODE IndexedAttributeType,
  90. IN OUT PLOG_IO_DP_DRIVE Drive,
  91. IN ULONG ClusterFactor,
  92. IN OUT PNTFS_BITMAP VolumeBitmap,
  93. IN PNTFS_UPCASE_TABLE UpcaseTable,
  94. IN COLLATION_RULE CollationRule,
  95. IN ULONG IndexBufferSize,
  96. IN ULONG MaximumRootSize,
  97. IN PCWSTRING IndexName DEFAULT NULL
  98. );
  99. NONVIRTUAL
  100. UNTFS_EXPORT
  101. BOOLEAN
  102. QueryFileReference(
  103. IN ULONG KeyLength,
  104. IN PVOID Key,
  105. IN ULONG Ordinal,
  106. OUT PMFT_SEGMENT_REFERENCE SegmentReference,
  107. OUT PBOOLEAN Error
  108. );
  109. NONVIRTUAL
  110. UNTFS_EXPORT
  111. BOOLEAN
  112. QueryEntry(
  113. IN ULONG KeyLength,
  114. IN PVOID Key,
  115. IN ULONG Ordinal,
  116. OUT PINDEX_ENTRY* FoundEntry,
  117. OUT PNTFS_INDEX_BUFFER* ContainingBuffer,
  118. OUT PBOOLEAN Error
  119. );
  120. NONVIRTUAL
  121. UNTFS_EXPORT
  122. BOOLEAN
  123. InsertEntry(
  124. IN ULONG KeyLength,
  125. IN PVOID KeyValue,
  126. IN MFT_SEGMENT_REFERENCE FileReference,
  127. IN BOOLEAN NoDuplicates DEFAULT TRUE
  128. );
  129. NONVIRTUAL
  130. BOOLEAN
  131. InsertEntry(
  132. IN PCINDEX_ENTRY NewEntry,
  133. IN BOOLEAN NoDuplicates DEFAULT TRUE,
  134. IN PBOOLEAN Duplicate DEFAULT NULL
  135. );
  136. NONVIRTUAL
  137. BOOLEAN
  138. DeleteEntry(
  139. IN ULONG KeyLength,
  140. IN PVOID Key,
  141. IN ULONG Ordinal
  142. );
  143. NONVIRTUAL
  144. UNTFS_EXPORT
  145. BOOLEAN
  146. Save(
  147. IN OUT PNTFS_FILE_RECORD_SEGMENT TargetFrs
  148. );
  149. NONVIRTUAL
  150. BOOLEAN
  151. IsBadlyOrdered(
  152. OUT PBOOLEAN Error,
  153. IN BOOLEAN DuplicatesAllowed
  154. );
  155. NONVIRTUAL
  156. BOOLEAN
  157. Sort(
  158. IN OUT PNTFS_FILE_RECORD_SEGMENT TargetFrs
  159. );
  160. NONVIRTUAL
  161. ATTRIBUTE_TYPE_CODE
  162. QueryTypeCode(
  163. ) CONST;
  164. NONVIRTUAL
  165. UNTFS_EXPORT
  166. VOID
  167. ResetIterator(
  168. );
  169. NONVIRTUAL
  170. UNTFS_EXPORT
  171. PCINDEX_ENTRY
  172. GetNext(
  173. OUT PULONG Depth,
  174. OUT PBOOLEAN Error,
  175. IN BOOLEAN FilterEndEntries DEFAULT TRUE
  176. );
  177. NONVIRTUAL
  178. UNTFS_EXPORT
  179. BOOLEAN
  180. CopyIterator(
  181. PNTFS_INDEX_TREE Index
  182. );
  183. NONVIRTUAL
  184. BOOLEAN
  185. DeleteCurrentEntry(
  186. );
  187. NONVIRTUAL
  188. BOOLEAN
  189. WriteCurrentEntry(
  190. );
  191. NONVIRTUAL
  192. COLLATION_RULE
  193. QueryCollationRule(
  194. );
  195. NONVIRTUAL
  196. ATTRIBUTE_TYPE_CODE
  197. QueryIndexedAttributeType(
  198. );
  199. NONVIRTUAL
  200. UCHAR
  201. QueryClustersPerBuffer(
  202. );
  203. NONVIRTUAL
  204. ULONG
  205. QueryBufferSize(
  206. );
  207. NONVIRTUAL
  208. VOID
  209. FreeAllocation(
  210. );
  211. NONVIRTUAL
  212. BOOLEAN
  213. UpdateFileName(
  214. IN PCFILE_NAME Name,
  215. IN FILE_REFERENCE ContainingFile
  216. );
  217. NONVIRTUAL
  218. PCWSTRING
  219. GetName(
  220. ) CONST;
  221. STATIC
  222. BOOLEAN
  223. IsIndexEntryCorrupt(
  224. IN PCINDEX_ENTRY IndexEntry,
  225. IN ULONG MaximumLength,
  226. IN PMESSAGE Message,
  227. IN INDEX_ENTRY_TYPE IndexEntryType DEFAULT INDEX_ENTRY_GENERIC_TYPE
  228. );
  229. NONVIRTUAL
  230. BOOLEAN
  231. ResetLsns(
  232. IN OUT PMESSAGE Message
  233. );
  234. NONVIRTUAL
  235. BOOLEAN
  236. FindHighestLsn(
  237. IN OUT PMESSAGE Message,
  238. OUT PLSN HighestLsn
  239. ) CONST;
  240. private:
  241. NONVIRTUAL
  242. VOID
  243. Construct(
  244. );
  245. NONVIRTUAL
  246. VOID
  247. Destroy(
  248. );
  249. NONVIRTUAL
  250. BOOLEAN
  251. FindEntry(
  252. IN ULONG KeyLength,
  253. IN PVOID KeyValue,
  254. IN ULONG Ordinal,
  255. OUT PINDEX_ENTRY* FoundEntry,
  256. OUT PNTFS_INDEX_BUFFER* ContainingBuffer,
  257. OUT PINTSTACK ParentTrail
  258. );
  259. NONVIRTUAL
  260. BOOLEAN
  261. RemoveEntry(
  262. IN PINDEX_ENTRY EntryToRemove,
  263. IN PNTFS_INDEX_BUFFER ContainingBuffer,
  264. IN PINTSTACK ParentTrail
  265. );
  266. NONVIRTUAL
  267. BOOLEAN
  268. QueryReplacementEntry(
  269. IN PINDEX_ENTRY Successor,
  270. OUT PINDEX_ENTRY ReplacementEntry,
  271. OUT PBOOLEAN Error,
  272. OUT PBOOLEAN EmptyLeaf,
  273. OUT PVCN EmptyLeafVcn
  274. );
  275. NONVIRTUAL
  276. BOOLEAN
  277. FixupEmptyLeaf(
  278. IN VCN EmptyLeafVcn
  279. );
  280. NONVIRTUAL
  281. BOOLEAN
  282. FindBuffer(
  283. IN VCN BufferVcn,
  284. IN PNTFS_INDEX_BUFFER ParentBuffer,
  285. OUT PNTFS_INDEX_BUFFER FoundBuffer,
  286. IN OUT PINTSTACK ParentTrail,
  287. OUT PBOOLEAN Error
  288. );
  289. NONVIRTUAL
  290. BOOLEAN
  291. InsertIntoRoot(
  292. IN PCINDEX_ENTRY NewEntry,
  293. IN PINDEX_ENTRY InsertionPoint DEFAULT NULL
  294. );
  295. NONVIRTUAL
  296. BOOLEAN
  297. InsertIntoBuffer(
  298. IN OUT PNTFS_INDEX_BUFFER TargetBuffer,
  299. IN OUT PINTSTACK ParentTrail,
  300. IN PCINDEX_ENTRY NewEntry,
  301. IN PINDEX_ENTRY InsertionPoint DEFAULT NULL
  302. );
  303. NONVIRTUAL
  304. BOOLEAN
  305. WriteIndexBuffer(
  306. IN VCN BufferVcn,
  307. OUT PVOID Data
  308. );
  309. NONVIRTUAL
  310. BOOLEAN
  311. AllocateIndexBuffer(
  312. OUT PVCN NewBufferVcn
  313. );
  314. NONVIRTUAL
  315. VOID
  316. FreeIndexBuffer(
  317. IN VCN BufferVcn
  318. );
  319. NONVIRTUAL
  320. VOID
  321. FreeChildren(
  322. IN PINDEX_ENTRY IndexEntry
  323. );
  324. NONVIRTUAL
  325. ULONG
  326. QueryMaximumEntrySize(
  327. ) CONST;
  328. NONVIRTUAL
  329. BOOLEAN
  330. CreateAllocationAttribute(
  331. );
  332. NONVIRTUAL
  333. BOOLEAN
  334. InvalidateIterator(
  335. );
  336. NONVIRTUAL
  337. PCINDEX_ENTRY
  338. GetNextUnfiltered(
  339. OUT PULONG Depth,
  340. OUT PBOOLEAN Error
  341. );
  342. NONVIRTUAL
  343. BOOLEAN
  344. GetNextLeafEntry(
  345. );
  346. NONVIRTUAL
  347. BOOLEAN
  348. GetNextParent(
  349. );
  350. NONVIRTUAL
  351. VOID
  352. UpdateOrdinal(
  353. );
  354. NONVIRTUAL
  355. VOID
  356. SaveCurrentKey(
  357. );
  358. ULONG
  359. QueryCurrentEntryDepth(
  360. );
  361. PLOG_IO_DP_DRIVE _Drive;
  362. ULONG _ClusterFactor;
  363. ULONG _ClustersPerBuffer;
  364. ULONG _BufferSize;
  365. PNTFS_BITMAP _VolumeBitmap;
  366. PNTFS_ATTRIBUTE _AllocationAttribute;
  367. PNTFS_INDEX_ROOT _IndexRoot;
  368. PNTFS_BITMAP _IndexAllocationBitmap;
  369. PWSTRING _Name;
  370. ATTRIBUTE_TYPE_CODE _IndexedAttributeType;
  371. COLLATION_RULE _CollationRule;
  372. PNTFS_UPCASE_TABLE _UpcaseTable;
  373. // Iterator state information:
  374. //
  375. // Each index tree has a single iterator associated with it.
  376. // This iterator oscillates among the following states:
  377. //
  378. // INDEX_ITERATOR_RESET -- the iterator is at the beginning
  379. // of the index, and the next call
  380. // to GetNext will return the first
  381. // entry in the index.
  382. // INDEX_ITERATOR_CURRENT -- _CurrentEntry points at the current
  383. // entry. _IsCurrentEntryInRoot is
  384. // TRUE if that entry is in the index
  385. // root, otherwise _CurrentEntryBuffer
  386. // points to the buffer that contains
  387. // the entry, and _CurrentEntryTrail
  388. // contains the parent trail of that
  389. // buffer. In either case,
  390. // _CurrentKeyOrdinal gives the
  391. // ordinal of the current entry
  392. // (ie. it is the nth entry for
  393. // the current key).
  394. // INDEX_ITERATOR_INVALID -- _CurrentEntry has been invalidated,
  395. // and the tree must relocate the
  396. // current entry. _CurrentKey,
  397. // _CurrentKeyLength, and
  398. // _CurrentKeyOrdinal give the entry
  399. // information to locate the current
  400. // entry.
  401. // INDEX_ITERATOR_DELETED -- Differs from INDEX_ITERATOR_INVALID
  402. // only in that _CurrentKey,
  403. // _CurrentKeyLength, and
  404. // _CurrentKeyOrdinal describe the
  405. // next entry, rather than the current.
  406. // INDEX_ITERATOR_CORRUPT -- The iterator (or the tree itself)
  407. // has become corrupt; any attempt to
  408. // use it will return error.
  409. //
  410. // Since the iterator is very closely coupled to the index
  411. // tree, it is built into this class, rather than being maintained
  412. // as a separate object.
  413. INDEX_ITERATOR_STATE _IteratorState;
  414. BOOLEAN _IsCurrentEntryInRoot;
  415. PINDEX_ENTRY _CurrentEntry;
  416. PNTFS_INDEX_BUFFER _CurrentBuffer;
  417. INTSTACK _CurrentEntryTrail;
  418. ULONG _CurrentKeyOrdinal;
  419. PVOID _CurrentKey;
  420. ULONG _CurrentKeyLength;
  421. ULONG _CurrentKeyMaxLength;
  422. };
  423. INLINE
  424. ATTRIBUTE_TYPE_CODE
  425. NTFS_INDEX_TREE::QueryTypeCode(
  426. ) CONST
  427. /*++
  428. Routine Description:
  429. This routine returns the attribute type code over which this index
  430. acts.
  431. Arguments:
  432. None.
  433. Return Value:
  434. The attribute type code for this index.
  435. --*/
  436. {
  437. return _IndexedAttributeType;
  438. }
  439. INLINE
  440. NONVIRTUAL
  441. COLLATION_RULE
  442. NTFS_INDEX_TREE::QueryCollationRule(
  443. )
  444. /*++
  445. Routine Description:
  446. This method returns the collation rule by which this
  447. index tree is ordered.
  448. Arguments:
  449. None.
  450. Return Value:
  451. The index tree's collation rule.
  452. --*/
  453. {
  454. return _CollationRule;
  455. }
  456. INLINE
  457. NONVIRTUAL
  458. ATTRIBUTE_TYPE_CODE
  459. NTFS_INDEX_TREE::QueryIndexedAttributeType(
  460. )
  461. /*++
  462. Routine Description:
  463. This method returns the type code of the attribute which is
  464. indexed by this index tree.
  465. Arguments:
  466. None.
  467. Return Value:
  468. --*/
  469. {
  470. return _IndexedAttributeType;
  471. }
  472. INLINE
  473. NONVIRTUAL
  474. UCHAR
  475. NTFS_INDEX_TREE::QueryClustersPerBuffer(
  476. )
  477. /*++
  478. Routine Description:
  479. This method returns the number of clusters in each allocation
  480. buffer in this index tree.
  481. Arguments:
  482. None.
  483. Return Value:
  484. The number of clusters per allocation buffer in this tree.
  485. --*/
  486. {
  487. return (UCHAR)_ClustersPerBuffer;
  488. }
  489. INLINE
  490. NONVIRTUAL
  491. ULONG
  492. NTFS_INDEX_TREE::QueryBufferSize(
  493. )
  494. /*++
  495. Routine Description:
  496. This method returns the size of each allocation
  497. buffer in this index tree.
  498. Arguments:
  499. None.
  500. Return Value:
  501. The number of bytes per allocation buffer in this tree.
  502. --*/
  503. {
  504. return _BufferSize;
  505. }
  506. INLINE
  507. ULONG
  508. NTFS_INDEX_TREE::QueryCurrentEntryDepth(
  509. )
  510. /*++
  511. Routine Description:
  512. This method returns the depth in the tree of _CurrentEntry.
  513. (Root is zero.)
  514. Arguments:
  515. None.
  516. Return Value:
  517. Depth.
  518. Notes:
  519. This method should only be called if _IteratorState
  520. is INDEX_ITERATOR_CURRENT.
  521. --*/
  522. {
  523. ULONG Result;
  524. if( _IteratorState == INDEX_ITERATOR_CURRENT ) {
  525. Result = _IsCurrentEntryInRoot ?
  526. 0 :
  527. ( _CurrentEntryTrail.QuerySize() + 1 );
  528. } else {
  529. DebugAbort( "Tried to determine depth of invalid iterator.\n" );
  530. Result = 0;
  531. }
  532. return Result;
  533. }
  534. INLINE
  535. PCWSTRING
  536. NTFS_INDEX_TREE::GetName(
  537. ) CONST
  538. /*++
  539. Routine Description:
  540. This method returns the name of the index.
  541. Arguments:
  542. None.
  543. Return Value:
  544. The name of the index.
  545. --*/
  546. {
  547. return _Name;
  548. }
  549. #endif