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.

1065 lines
21 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. attrib.hxx
  5. Abstract:
  6. This module contains the declarations for NTFS_ATTRIBUTE,
  7. which models an NTFS attribute instance.
  8. An attribute instance models the user's view of an attribute,
  9. as a [type, name, value] triple. (The name is optional.) It
  10. does not correspond to any specific disk structure.
  11. An attribute instance may exist in:
  12. 1) a single resident attribute record,
  13. 2) a single non-resident attribute record, or
  14. 3) multiple, non-overlapping non-resident attribute records.
  15. Case (3) is rare, so we don't need to optimize for it, but we
  16. do need to handle it.
  17. The client may initialize an Attribute object by supplying the
  18. value directly [resident]; by supplying a description of the
  19. value's location on disk [non-resident]; or by supplying an
  20. attribute record or list of attribute records for the attribute.
  21. On disk, an attribute may be resident (with the data contained
  22. in the attribute record) or it may be nonresident (with the
  23. data residing on disk, outside the File Record Segment). This
  24. is reflected in the attribute object by having the value stored
  25. directly (in space allocated by the attribute object and copied
  26. at initialization) or stored on disk (with the attribute object
  27. keeping an Extent List which describes this disk storage). I
  28. chose not to reflect this difference with different classes for
  29. three reasons: first, an attribute may wish to transform itself
  30. from one form to another; second, this would introduce many
  31. virtual methods; and third, I want to have special attribute
  32. classes derive from the attribute class, and dividing attributes
  33. into resident and nonresident would force me to use multiple
  34. inheritance.
  35. Generally, the difference between resident and nonresident
  36. attributes is not visible to clients of this class. The
  37. most important exception is GetResidentValue; this method
  38. is provided for performance reasons--Read will supply the
  39. same effect, but requires copying the data.
  40. Author:
  41. Bill McJohn (billmc) 19-June-91
  42. Environment:
  43. ULIB, User Mode
  44. --*/
  45. #if !defined( _NTFS_ATTRIBUTE_DEFN_ )
  46. #define _NTFS_ATTRIBUTE_DEFN_
  47. #include "extents.hxx"
  48. #include "wstring.hxx"
  49. #include "drive.hxx"
  50. DECLARE_CLASS( LOG_IO_DP_DRIVE );
  51. DECLARE_CLASS( NTFS_FILE_RECORD_SEGMENT );
  52. DECLARE_CLASS( NTFS_EXTENT_LIST );
  53. DECLARE_CLASS( NTFS_ATTRIBUTE_RECORD );
  54. DECLARE_CLASS( NTFS_ATTRIBUTE_RECORD_LIST );
  55. DECLARE_CLASS( NTFS_BITMAP );
  56. DECLARE_CLASS( NTFS_ATTRIBUTE );
  57. DECLARE_CLASS( NTFS_BAD_CLUSTER_FILE );
  58. DECLARE_CLASS( NUMBER_SET );
  59. DECLARE_CLASS( NTFS_ATTRIBUTE );
  60. class NTFS_ATTRIBUTE : public OBJECT {
  61. public:
  62. UNTFS_EXPORT
  63. DECLARE_CONSTRUCTOR( NTFS_ATTRIBUTE );
  64. VIRTUAL
  65. UNTFS_EXPORT
  66. ~NTFS_ATTRIBUTE (
  67. );
  68. NONVIRTUAL
  69. UNTFS_EXPORT
  70. BOOLEAN
  71. Initialize (
  72. IN OUT PLOG_IO_DP_DRIVE Drive,
  73. IN ULONG ClusterFactor,
  74. IN PCVOID Value,
  75. IN ULONG ValueLength,
  76. IN ATTRIBUTE_TYPE_CODE TypeCode,
  77. IN PCWSTRING Name DEFAULT NULL,
  78. IN USHORT Flags DEFAULT 0
  79. );
  80. NONVIRTUAL
  81. UNTFS_EXPORT
  82. BOOLEAN
  83. Initialize (
  84. IN OUT PLOG_IO_DP_DRIVE Drive,
  85. IN ULONG ClusterFactor,
  86. IN PCNTFS_EXTENT_LIST Extents,
  87. IN BIG_INT ValueLength,
  88. IN BIG_INT ValidLength,
  89. IN ATTRIBUTE_TYPE_CODE TypeCode,
  90. IN PCWSTRING Name DEFAULT NULL,
  91. IN USHORT Flags DEFAULT 0
  92. );
  93. NONVIRTUAL
  94. BOOLEAN
  95. Initialize (
  96. IN OUT PLOG_IO_DP_DRIVE Drive,
  97. IN ULONG ClusterFactor,
  98. IN PCNTFS_ATTRIBUTE_RECORD AttributeRecord
  99. );
  100. NONVIRTUAL
  101. BOOLEAN
  102. AddAttributeRecord (
  103. IN PCNTFS_ATTRIBUTE_RECORD AttributeRecord,
  104. IN OUT PNTFS_EXTENT_LIST *BackupExtent
  105. );
  106. NONVIRTUAL
  107. BOOLEAN
  108. VerifyAndFix(
  109. IN BIG_INT VolumeSectors
  110. );
  111. NONVIRTUAL
  112. ATTRIBUTE_TYPE_CODE
  113. QueryTypeCode (
  114. ) CONST;
  115. NONVIRTUAL
  116. PCWSTRING
  117. GetName (
  118. ) CONST;
  119. NONVIRTUAL
  120. VOID
  121. QueryValueLength (
  122. OUT PBIG_INT ValueLength,
  123. OUT PBIG_INT AllocatedLength DEFAULT NULL,
  124. OUT PBIG_INT ValidLength DEFAULT NULL
  125. ) CONST;
  126. NONVIRTUAL
  127. BIG_INT
  128. QueryValueLength(
  129. ) CONST;
  130. NONVIRTUAL
  131. BIG_INT
  132. QueryValidDataLength(
  133. ) CONST;
  134. NONVIRTUAL
  135. BIG_INT
  136. QueryAllocatedLength(
  137. ) CONST;
  138. NONVIRTUAL
  139. BIG_INT
  140. QueryClustersAllocated(
  141. ) CONST;
  142. NONVIRTUAL
  143. BOOLEAN
  144. IsResident (
  145. ) CONST;
  146. NONVIRTUAL
  147. BOOLEAN
  148. IsIndexed (
  149. ) CONST;
  150. NONVIRTUAL
  151. VOID
  152. SetIsIndexed(
  153. IN BOOLEAN State DEFAULT TRUE
  154. );
  155. NONVIRTUAL
  156. PCVOID
  157. GetResidentValue (
  158. ) CONST;
  159. NONVIRTUAL
  160. BOOLEAN
  161. QueryLcnFromVcn (
  162. IN VCN Vcn,
  163. OUT PLCN Lcn,
  164. OUT PBIG_INT RunLength DEFAULT NULL
  165. ) CONST;
  166. VIRTUAL
  167. UNTFS_EXPORT
  168. BOOLEAN
  169. InsertIntoFile (
  170. IN OUT PNTFS_FILE_RECORD_SEGMENT BaseFileRecordSegment,
  171. IN OUT PNTFS_BITMAP Bitmap OPTIONAL
  172. );
  173. VIRTUAL
  174. UNTFS_EXPORT
  175. BOOLEAN
  176. MakeNonresident (
  177. IN OUT PNTFS_BITMAP Bitmap
  178. );
  179. VIRTUAL
  180. UNTFS_EXPORT
  181. BOOLEAN
  182. Resize (
  183. IN BIG_INT NewSize,
  184. IN OUT PNTFS_BITMAP Bitmap OPTIONAL
  185. );
  186. VIRTUAL
  187. UNTFS_EXPORT
  188. BOOLEAN
  189. SetSparse (
  190. IN BIG_INT NewSize,
  191. IN OUT PNTFS_BITMAP Bitmap
  192. );
  193. NONVIRTUAL
  194. BOOLEAN
  195. AddExtent (
  196. IN VCN Vcn,
  197. IN LCN Lcn,
  198. IN BIG_INT RunLength
  199. );
  200. NONVIRTUAL
  201. UNTFS_EXPORT
  202. BOOLEAN
  203. Read (
  204. OUT PVOID Data,
  205. IN BIG_INT ByteOffset,
  206. IN ULONG BytesToRead,
  207. OUT PULONG BytesRead
  208. );
  209. NONVIRTUAL
  210. VOID
  211. PrimeCache (
  212. IN BIG_INT ByteOffset,
  213. IN ULONG BytesToRead
  214. );
  215. VIRTUAL
  216. UNTFS_EXPORT
  217. BOOLEAN
  218. Write (
  219. IN PCVOID Data,
  220. IN BIG_INT ByteOffset,
  221. IN ULONG BytesToWrite,
  222. OUT PULONG BytesWritten,
  223. IN OUT PNTFS_BITMAP Bitmap OPTIONAL
  224. );
  225. NONVIRTUAL
  226. BOOLEAN
  227. Fill (
  228. IN BIG_INT Offset,
  229. IN CHAR FillCharacter
  230. );
  231. NONVIRTUAL
  232. BOOLEAN
  233. Fill (
  234. IN BIG_INT Offset,
  235. IN CHAR FillCharacter,
  236. IN ULONG NumberOfBytes
  237. );
  238. NONVIRTUAL
  239. BOOLEAN
  240. IsStorageModified (
  241. ) CONST;
  242. NONVIRTUAL
  243. PLOG_IO_DP_DRIVE
  244. GetDrive(
  245. );
  246. NONVIRTUAL
  247. BOOLEAN
  248. RecoverAttribute(
  249. IN OUT PNTFS_BITMAP VolumeBitmap,
  250. IN OUT PNUMBER_SET BadClusters,
  251. OUT PBIG_INT BytesRecovered DEFAULT NULL
  252. );
  253. NONVIRTUAL
  254. USHORT
  255. QueryFlags(
  256. ) CONST;
  257. NONVIRTUAL
  258. VOID
  259. SetFlags(
  260. IN USHORT Flags
  261. );
  262. NONVIRTUAL
  263. UCHAR
  264. QueryResidentFlags(
  265. ) CONST;
  266. NONVIRTUAL
  267. BOOLEAN
  268. MarkAsAllocated(
  269. IN OUT PNTFS_BITMAP VolumeBitmap
  270. ) CONST;
  271. NONVIRTUAL
  272. ULONG
  273. QueryCompressionUnit(
  274. ) CONST;
  275. NONVIRTUAL
  276. BOOLEAN
  277. IsCompressed(
  278. ) CONST;
  279. NONVIRTUAL
  280. BOOLEAN
  281. IsSparse(
  282. ) CONST;
  283. NONVIRTUAL
  284. BOOLEAN
  285. Hotfix(
  286. IN VCN Vcn,
  287. IN BIG_INT RunLength,
  288. IN OUT PNTFS_BITMAP VolumeBitmap,
  289. IN OUT PNUMBER_SET BadClusters,
  290. IN BOOLEAN Contiguous DEFAULT FALSE
  291. );
  292. NONVIRTUAL
  293. BOOLEAN
  294. ReplaceVcns(
  295. IN VCN StartingVcn,
  296. IN LCN NewLcn,
  297. IN BIG_INT NumberOfClusters
  298. );
  299. NONVIRTUAL
  300. PCNTFS_EXTENT_LIST
  301. GetExtentList(
  302. ) CONST;
  303. NONVIRTUAL
  304. BOOLEAN
  305. IsAllocationZeroed(
  306. OUT PBOOLEAN Error DEFAULT NULL
  307. );
  308. NONVIRTUAL
  309. BOOLEAN
  310. GetNextAllocationOffset(
  311. IN OUT PBIG_INT ByteOffset,
  312. IN OUT PBIG_INT Length
  313. );
  314. FRIEND
  315. BOOLEAN
  316. operator==(
  317. IN RCNTFS_ATTRIBUTE Left,
  318. IN RCNTFS_ATTRIBUTE Right
  319. );
  320. protected:
  321. NONVIRTUAL
  322. VOID
  323. SetStorageModified (
  324. );
  325. NONVIRTUAL
  326. VOID
  327. ResetStorageModified (
  328. );
  329. NONVIRTUAL
  330. ULONG
  331. QueryClusterFactor(
  332. ) CONST;
  333. private:
  334. NONVIRTUAL
  335. VOID
  336. Construct (
  337. );
  338. NONVIRTUAL
  339. VOID
  340. Destroy (
  341. );
  342. NONVIRTUAL
  343. BOOLEAN
  344. InsertMftDataIntoFile (
  345. IN OUT PNTFS_FILE_RECORD_SEGMENT BaseFileRecordSegment,
  346. IN OUT PNTFS_BITMAP Bitmap OPTIONAL,
  347. IN BOOLEAN BeConservative
  348. );
  349. NONVIRTUAL
  350. BOOLEAN
  351. ReadCompressed (
  352. OUT PVOID Data,
  353. IN BIG_INT ByteOffset,
  354. IN ULONG BytesToRead,
  355. OUT PULONG BytesRead
  356. );
  357. NONVIRTUAL
  358. BOOLEAN
  359. WriteCompressed (
  360. IN PCVOID Data,
  361. IN BIG_INT ByteOffset,
  362. IN ULONG BytesToWrite,
  363. OUT PULONG BytesWritten,
  364. IN OUT PNTFS_BITMAP Bitmap OPTIONAL
  365. );
  366. NONVIRTUAL
  367. BOOLEAN
  368. RecoverCompressedAttribute(
  369. IN OUT PNTFS_BITMAP VolumeBitmap,
  370. IN OUT PNUMBER_SET BadClusters,
  371. OUT PBIG_INT BytesRecovered DEFAULT NULL
  372. );
  373. PLOG_IO_DP_DRIVE _Drive;
  374. ULONG _ClusterFactor;
  375. ATTRIBUTE_TYPE_CODE _Type;
  376. DSTRING _Name;
  377. USHORT _Flags;
  378. UCHAR _FormCode;
  379. UCHAR _CompressionUnit;
  380. BIG_INT _ValueLength;
  381. BIG_INT _ValidDataLength;
  382. PVOID _ResidentData;
  383. PNTFS_EXTENT_LIST _ExtentList;
  384. UCHAR _ResidentFlags;
  385. BOOLEAN _StorageModified;
  386. };
  387. INLINE
  388. BOOLEAN
  389. NTFS_ATTRIBUTE::IsResident(
  390. ) CONST
  391. /*++
  392. Routine Description:
  393. This method returns whether the attribute value is resident.
  394. Arguments:
  395. None.
  396. Return Value:
  397. TRUE if the value is resident; FALSE if it is non-resident.
  398. --*/
  399. {
  400. return( _ResidentData != NULL );
  401. }
  402. INLINE
  403. BIG_INT
  404. NTFS_ATTRIBUTE::QueryValueLength(
  405. ) CONST
  406. /*++
  407. Routine Description:
  408. This routine returns the length of the attribute value in bytes.
  409. Arguments:
  410. None.
  411. Return Value:
  412. The length of the attribute value in bytes.
  413. --*/
  414. {
  415. return _ValueLength;
  416. }
  417. INLINE
  418. BIG_INT
  419. NTFS_ATTRIBUTE::QueryValidDataLength(
  420. ) CONST
  421. /*++
  422. Routine Description:
  423. This routine returns the valid data length.
  424. Arguments:
  425. None.
  426. Return Value:
  427. The valid data length.
  428. --*/
  429. {
  430. return _ValidDataLength;
  431. }
  432. INLINE
  433. BIG_INT
  434. NTFS_ATTRIBUTE::QueryAllocatedLength(
  435. ) CONST
  436. /*++
  437. Routine Description:
  438. This routine return the number of bytes allocated for this attribute
  439. on disk.
  440. Arguments:
  441. None.
  442. Return Value:
  443. The amount of disk space allocated for this attribute.
  444. --*/
  445. {
  446. BIG_INT Result;
  447. if( IsResident() ) {
  448. Result = QuadAlign( _ValueLength.GetLowPart() );
  449. } else {
  450. Result = (_ExtentList->QueryNextVcn()*_ClusterFactor*
  451. _Drive->QuerySectorSize());
  452. }
  453. return Result;
  454. }
  455. INLINE
  456. ATTRIBUTE_TYPE_CODE
  457. NTFS_ATTRIBUTE::QueryTypeCode(
  458. ) CONST
  459. /*++
  460. Routine Description:
  461. Returns the attribute's type code.
  462. Arguments:
  463. None.
  464. Return Value:
  465. The attribute's type code.
  466. --*/
  467. {
  468. return _Type;
  469. }
  470. INLINE
  471. PCWSTRING
  472. NTFS_ATTRIBUTE::GetName(
  473. ) CONST
  474. /*++
  475. Routine Description:
  476. Returns the attribute's name. (Note that this returns a pointer
  477. to the attribute's private copy of its name.)
  478. Arguments:
  479. None.
  480. Return Value:
  481. A pointer to the attribute's name, if it has one; NULL if it
  482. has none.
  483. --*/
  484. {
  485. return &_Name;
  486. }
  487. INLINE
  488. VOID
  489. NTFS_ATTRIBUTE::QueryValueLength(
  490. OUT PBIG_INT ValueLength,
  491. OUT PBIG_INT AllocatedLength,
  492. OUT PBIG_INT ValidLength
  493. ) CONST
  494. /*++
  495. Routine Description:
  496. Returns the attribute's value lengths (actual, allocated
  497. and valid length).
  498. Arguments:
  499. ValueLength -- receives the attribute value's length
  500. AllocatedLength -- receives the attribute value's allocated length
  501. (ignored if NULL)
  502. ValidLength -- receives the attribute value's valid length
  503. (ignored if NULL );
  504. Return Value:
  505. None.
  506. --*/
  507. {
  508. *ValueLength = _ValueLength;
  509. if( AllocatedLength != NULL ) {
  510. *AllocatedLength = QueryAllocatedLength();
  511. }
  512. if( ValidLength != NULL ) {
  513. *ValidLength = _ValidDataLength;
  514. }
  515. }
  516. INLINE
  517. BOOLEAN
  518. NTFS_ATTRIBUTE::IsIndexed(
  519. ) CONST
  520. /*++
  521. Routine Description:
  522. This method returns whether the attribute is indexed.
  523. Arguments:
  524. None.
  525. Return Value:
  526. TRUE if the attribute is indexed; FALSE if not.
  527. --*/
  528. {
  529. return( (_ResidentData == NULL) ?
  530. FALSE :
  531. _ResidentFlags & RESIDENT_FORM_INDEXED );
  532. }
  533. INLINE
  534. VOID
  535. NTFS_ATTRIBUTE::SetIsIndexed(
  536. IN BOOLEAN State
  537. )
  538. /*++
  539. Routine Description:
  540. This method marks the attribute as indexed. It has no effect if
  541. the attribute is nonresident.
  542. Arguments:
  543. State -- supplies a value indicating whether the attribute
  544. is indexed (TRUE) or not indexed (FALSE).
  545. Return Value:
  546. None.
  547. --*/
  548. {
  549. if( _ResidentData != NULL ) {
  550. if( State ) {
  551. _ResidentFlags |= RESIDENT_FORM_INDEXED;
  552. } else {
  553. _ResidentFlags &= ~RESIDENT_FORM_INDEXED;
  554. }
  555. }
  556. }
  557. INLINE
  558. PCVOID
  559. NTFS_ATTRIBUTE::GetResidentValue(
  560. ) CONST
  561. /*++
  562. Routine Description:
  563. Returns a pointer to the attribute's value.
  564. Arguments:
  565. None.
  566. Return Value:
  567. If the attribute value is resident, returns a pointer to the
  568. value. If it is nonresident, returns NULL.
  569. Notes:
  570. This method is provided for clients who know that the value is
  571. resident and who want to inspect it without copying it; if the
  572. client doesn't know whether the value is resident, Read is
  573. a better way to get it.
  574. --*/
  575. {
  576. return _ResidentData;
  577. }
  578. INLINE
  579. BOOLEAN
  580. NTFS_ATTRIBUTE::QueryLcnFromVcn (
  581. IN VCN Vcn,
  582. OUT PLCN Lcn,
  583. OUT PBIG_INT RunLength
  584. ) CONST
  585. /*++
  586. Routine Description:
  587. This method converts a VCN within the attribute into an LCN.
  588. (Note that it only applies to nonresident attributes.)
  589. Arguments:
  590. Vcn -- Supplies the VCN to be converted.
  591. Lcn -- Receives the corresponding LCN.
  592. RunLength -- Receives the remaining length in the current run
  593. starting at this LCN.
  594. Return Value:
  595. TRUE upon successful completion.
  596. --*/
  597. {
  598. if( _ExtentList == NULL ) {
  599. return FALSE;
  600. } else {
  601. return _ExtentList->QueryLcnFromVcn( Vcn, Lcn, RunLength );
  602. }
  603. }
  604. INLINE
  605. BOOLEAN
  606. NTFS_ATTRIBUTE::IsStorageModified(
  607. ) CONST
  608. /*++
  609. Routine Description:
  610. Query whether the attribute's storage (i.e. anything that
  611. would go into an attribute record) has changed
  612. Arguments:
  613. None.
  614. Return Value:
  615. Returns TRUE if the attribute's storage has been modified since
  616. the last time we got it from or put it into a File Record Segment.
  617. --*/
  618. {
  619. return _StorageModified;
  620. }
  621. INLINE
  622. VOID
  623. NTFS_ATTRIBUTE::SetStorageModified (
  624. )
  625. /*++
  626. Routine Description:
  627. This routine sets the 'IsStorageModified' flag.
  628. Arguments:
  629. None.
  630. Return Value:
  631. None.
  632. --*/
  633. {
  634. _StorageModified = TRUE;
  635. }
  636. INLINE
  637. VOID
  638. NTFS_ATTRIBUTE::ResetStorageModified (
  639. )
  640. /*++
  641. Routine Description:
  642. This routine resets the 'IsStorageModified' flag.
  643. Arguments:
  644. None.
  645. Return Value:
  646. None.
  647. --*/
  648. {
  649. _StorageModified = FALSE;
  650. }
  651. INLINE
  652. PLOG_IO_DP_DRIVE
  653. NTFS_ATTRIBUTE::GetDrive(
  654. )
  655. /*++
  656. Routine Description:
  657. This method returns the drive on which the Attribute resides.
  658. Arguments:
  659. None.
  660. Return Value:
  661. The drive on which the Attribute resides.
  662. --*/
  663. {
  664. return _Drive;
  665. }
  666. INLINE
  667. USHORT
  668. NTFS_ATTRIBUTE::QueryFlags(
  669. ) CONST
  670. /*++
  671. Routine Description:
  672. This routine returns this attribute's flags.
  673. Arguments:
  674. None.
  675. Return Value:
  676. This attribute's flags.
  677. --*/
  678. {
  679. return _Flags;
  680. }
  681. INLINE
  682. VOID
  683. NTFS_ATTRIBUTE::SetFlags(
  684. IN USHORT Flags
  685. )
  686. /*++
  687. Routine Description:
  688. This routine returns this attribute's flags.
  689. Arguments:
  690. None.
  691. Return Value:
  692. This attribute's flags.
  693. --*/
  694. {
  695. _Flags = Flags;
  696. SetStorageModified();
  697. }
  698. INLINE
  699. UCHAR
  700. NTFS_ATTRIBUTE::QueryResidentFlags(
  701. ) CONST
  702. /*++
  703. Routine Description:
  704. This routine returns this attribute's resident flags.
  705. Arguments:
  706. None.
  707. Return Value:
  708. This attribute's resident flags.
  709. --*/
  710. {
  711. return _ResidentFlags;
  712. }
  713. INLINE
  714. ULONG
  715. NTFS_ATTRIBUTE::QueryCompressionUnit(
  716. ) CONST
  717. {
  718. return _CompressionUnit;
  719. }
  720. INLINE
  721. BOOLEAN
  722. NTFS_ATTRIBUTE::IsCompressed(
  723. ) CONST
  724. {
  725. return ((_Flags & ATTRIBUTE_FLAG_COMPRESSION_MASK) != 0);
  726. }
  727. INLINE
  728. BOOLEAN
  729. NTFS_ATTRIBUTE::IsSparse(
  730. ) CONST
  731. {
  732. return ((_Flags & ATTRIBUTE_FLAG_SPARSE) != 0);
  733. }
  734. INLINE
  735. ULONG
  736. NTFS_ATTRIBUTE::QueryClusterFactor(
  737. ) CONST
  738. /*++
  739. Routine Description:
  740. This method returns the cluster factor.
  741. Arguments:
  742. None.
  743. Return Value:
  744. The cluster factor.
  745. --*/
  746. {
  747. return _ClusterFactor;
  748. }
  749. INLINE
  750. PCNTFS_EXTENT_LIST
  751. NTFS_ATTRIBUTE::GetExtentList(
  752. ) CONST
  753. /*++
  754. Routine Description:
  755. This routine returns a pointer to this object's extent list.
  756. Arguments:
  757. None.
  758. Return Value:
  759. A pointer to the extent list.
  760. --*/
  761. {
  762. return _ExtentList;
  763. }
  764. #endif