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.

695 lines
25 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. MyNtfs.h
  5. Current Version Numbers:
  6. Major.Minor Version: 1.2
  7. Abstract:
  8. This module defines some on-disk structure of the Ntfs file system as
  9. needed by findfast.exe.
  10. */
  11. //
  12. // The following types and macros are used to help unpack the packed and
  13. // misaligned fields found in the Bios parameter block
  14. //
  15. typedef union _UCHAR1 {
  16. UCHAR Uchar[1];
  17. UCHAR ForceAlignment;
  18. } UCHAR1, *PUCHAR1;
  19. typedef union _UCHAR2 {
  20. UCHAR Uchar[2];
  21. USHORT ForceAlignment;
  22. } UCHAR2, *PUCHAR2;
  23. typedef union _UCHAR4 {
  24. UCHAR Uchar[4];
  25. ULONG ForceAlignment;
  26. } UCHAR4, *PUCHAR4;
  27. #define CopyUchar1(D,S) { \
  28. *((UCHAR1 *)(D)) = *((UNALIGNED UCHAR1 *)(S)); \
  29. }
  30. #define CopyUchar2(D,S) { \
  31. *((UCHAR2 *)(D)) = *((UNALIGNED UCHAR2 *)(S)); \
  32. }
  33. #define CopyUchar4(D,S) { \
  34. *((UCHAR4 *)(D)) = *((UNALIGNED UCHAR4 *)(S)); \
  35. }
  36. typedef LONGLONG LCN;
  37. typedef LCN *PLCN;
  38. typedef LONGLONG VCN;
  39. typedef VCN *PVCN;
  40. //
  41. // Define the Packed and Unpacked BIOS Parameter Block
  42. //
  43. typedef struct _PACKED_BIOS_PARAMETER_BLOCK {
  44. UCHAR BytesPerSector[2]; // offset = 0x000
  45. UCHAR SectorsPerCluster[1]; // offset = 0x002
  46. UCHAR ReservedSectors[2]; // offset = 0x003 (zero)
  47. UCHAR Fats[1]; // offset = 0x005 (zero)
  48. UCHAR RootEntries[2]; // offset = 0x006 (zero)
  49. UCHAR Sectors[2]; // offset = 0x008 (zero)
  50. UCHAR Media[1]; // offset = 0x00A
  51. UCHAR SectorsPerFat[2]; // offset = 0x00B (zero)
  52. UCHAR SectorsPerTrack[2]; // offset = 0x00D
  53. UCHAR Heads[2]; // offset = 0x00F
  54. UCHAR HiddenSectors[4]; // offset = 0x011 (zero)
  55. UCHAR LargeSectors[4]; // offset = 0x015 (zero)
  56. } PACKED_BIOS_PARAMETER_BLOCK; // sizeof = 0x019
  57. typedef PACKED_BIOS_PARAMETER_BLOCK *PPACKED_BIOS_PARAMETER_BLOCK;
  58. typedef struct BIOS_PARAMETER_BLOCK {
  59. USHORT BytesPerSector;
  60. UCHAR SectorsPerCluster;
  61. USHORT ReservedSectors;
  62. UCHAR Fats;
  63. USHORT RootEntries;
  64. USHORT Sectors;
  65. UCHAR Media;
  66. USHORT SectorsPerFat;
  67. USHORT SectorsPerTrack;
  68. USHORT Heads;
  69. ULONG HiddenSectors;
  70. ULONG LargeSectors;
  71. } BIOS_PARAMETER_BLOCK;
  72. typedef BIOS_PARAMETER_BLOCK *PBIOS_PARAMETER_BLOCK;
  73. //
  74. // This macro takes a Packed BIOS and fills in its Unpacked
  75. // equivalent
  76. //
  77. #define NtfsUnpackBios(Bios,Pbios) { \
  78. CopyUchar2(&((Bios)->BytesPerSector), &(Pbios)->BytesPerSector ); \
  79. CopyUchar1(&((Bios)->SectorsPerCluster), &(Pbios)->SectorsPerCluster); \
  80. CopyUchar2(&((Bios)->ReservedSectors), &(Pbios)->ReservedSectors ); \
  81. CopyUchar1(&((Bios)->Fats), &(Pbios)->Fats ); \
  82. CopyUchar2(&((Bios)->RootEntries), &(Pbios)->RootEntries ); \
  83. CopyUchar2(&((Bios)->Sectors), &(Pbios)->Sectors ); \
  84. CopyUchar1(&((Bios)->Media), &(Pbios)->Media ); \
  85. CopyUchar2(&((Bios)->SectorsPerFat), &(Pbios)->SectorsPerFat ); \
  86. CopyUchar2(&((Bios)->SectorsPerTrack), &(Pbios)->SectorsPerTrack ); \
  87. CopyUchar2(&((Bios)->Heads), &(Pbios)->Heads ); \
  88. CopyUchar4(&((Bios)->HiddenSectors), &(Pbios)->HiddenSectors ); \
  89. CopyUchar4(&((Bios)->LargeSectors), &(Pbios)->LargeSectors ); \
  90. }
  91. typedef ULONG ATTRIBUTE_TYPE_CODE;
  92. typedef ATTRIBUTE_TYPE_CODE *PATTRIBUTE_TYPE_CODE;
  93. //
  94. // System-defined Attribute Type Codes. For the System-defined
  95. // attributes, the Unicode Name is exactly equal to the name of the
  96. // following symbols. For this reason, all of the system-defined
  97. // attribute names start with "$", to always distinguish them when
  98. // attribute names are listed, and to reserve a namespace for
  99. // attributes defined in the future. I.e., a User-Defined
  100. // attribute name will never collide with a current or future
  101. // system-defined attribute name if it does not start with "$".
  102. // User attribute numbers should not start until
  103. // $FIRST_USER_DEFINED_ATTRIBUTE, to allow the potential for
  104. // upgrading existing volumes with new user-defined attributes in
  105. // future versions of NTFS. The tagged attribute list is
  106. // terminated with a lone-standing 0 ($END) - the rest of the
  107. // attribute record does not exist.
  108. //
  109. // The type code value of 0 is reserved for convenience of the
  110. // implementation.
  111. //
  112. #define $UNUSED (0X0)
  113. #define $STANDARD_INFORMATION (0x10)
  114. #define $ATTRIBUTE_LIST (0x20)
  115. #define $FILE_NAME (0x30)
  116. #define $OBJECT_ID (0x40)
  117. #define $SECURITY_DESCRIPTOR (0x50)
  118. #define $VOLUME_NAME (0x60)
  119. #define $VOLUME_INFORMATION (0x70)
  120. #define $DATA (0x80)
  121. #define $INDEX_ROOT (0x90)
  122. #define $INDEX_ALLOCATION (0xA0)
  123. #define $BITMAP (0xB0)
  124. #define $REPARSE_POINT (0xC0)
  125. #define $EA_INFORMATION (0xD0)
  126. #define $EA (0xE0)
  127. // #define $LOGGED_UTILITY_STREAM (0x100) // defined in ntfsexp.h
  128. #define $FIRST_USER_DEFINED_ATTRIBUTE (0x1000)
  129. #define $END (0xFFFFFFFF)
  130. //
  131. // Define the boot sector. Note that MFT2 is exactly three file
  132. // record segments long, and it mirrors the first three file record
  133. // segments from the MFT, which are MFT, MFT2 and the Log File.
  134. //
  135. // The Oem field contains the ASCII characters "NTFS ".
  136. //
  137. // The Checksum field is a simple additive checksum of all of the
  138. // ULONGs which precede the Checksum ULONG. The rest of the sector
  139. // is not included in this Checksum.
  140. //
  141. typedef struct _PACKED_BOOT_SECTOR {
  142. UCHAR Jump[3]; // offset = 0x000
  143. UCHAR Oem[8]; // offset = 0x003
  144. PACKED_BIOS_PARAMETER_BLOCK PackedBpb; // offset = 0x00B
  145. UCHAR Unused[4]; // offset = 0x024
  146. LONGLONG NumberSectors; // offset = 0x028
  147. LCN MftStartLcn; // offset = 0x030
  148. LCN Mft2StartLcn; // offset = 0x038
  149. CHAR ClustersPerFileRecordSegment; // offset = 0x040
  150. UCHAR Reserved0[3];
  151. CHAR DefaultClustersPerIndexAllocationBuffer; // offset = 0x044
  152. UCHAR Reserved1[3];
  153. LONGLONG SerialNumber; // offset = 0x048
  154. ULONG Checksum; // offset = 0x050
  155. UCHAR BootStrap[0x200-0x054]; // offset = 0x054
  156. } PACKED_BOOT_SECTOR; // sizeof = 0x200
  157. typedef PACKED_BOOT_SECTOR *PPACKED_BOOT_SECTOR;
  158. //
  159. // The MFT Segment Reference is an address in the MFT tagged with
  160. // a circularly reused sequence number set at the time that the MFT
  161. // Segment Reference was valid. Note that this format limits the
  162. // size of the Master File Table to 2**48 segments. So, for
  163. // example, with a 1KB segment size the maximum size of the master
  164. // file would be 2**58 bytes, or 2**28 gigabytes.
  165. //
  166. typedef struct _MFT_SEGMENT_REFERENCE {
  167. //
  168. // First a 48 bit segment number.
  169. //
  170. ULONG SegmentNumberLowPart; // offset = 0x000
  171. USHORT SegmentNumberHighPart; // offset = 0x004
  172. //
  173. // Now a 16 bit nonzero sequence number. A value of 0 is
  174. // reserved to allow the possibility of a routine accepting
  175. // 0 as a sign that the sequence number check should be
  176. // repressed.
  177. //
  178. USHORT SequenceNumber; // offset = 0x006
  179. } MFT_SEGMENT_REFERENCE, *PMFT_SEGMENT_REFERENCE; // sizeof = 0x008
  180. //
  181. // A file reference in NTFS is simply the MFT Segment Reference of
  182. // the Base file record.
  183. //
  184. typedef MFT_SEGMENT_REFERENCE FILE_REFERENCE, *PFILE_REFERENCE;
  185. //
  186. // File Record Segment. This is the header that begins every File
  187. // Record Segment in the Master File Table.
  188. //
  189. typedef struct _FILE_RECORD_SEGMENT_HEADER {
  190. //
  191. // Multi-Sector Header as defined by the Cache Manager. This
  192. // structure will always contain the signature "FILE" and a
  193. // description of the location and size of the Update Sequence
  194. // Array.
  195. //
  196. UCHAR Pad0[0x10]; // offset = 0x000
  197. //
  198. // Sequence Number. This is incremented each time that a File
  199. // Record segment is freed, and 0 is not used. The
  200. // SequenceNumber field of a File Reference must match the
  201. // contents of this field, or else the File Reference is
  202. // incorrect (presumably stale).
  203. //
  204. USHORT SequenceNumber; // offset = 0x010
  205. //
  206. // This is the count of the number of references which exist
  207. // for this segment, from an INDEX_xxx attribute. In File
  208. // Records Segments other than the Base File Record Segment,
  209. // this field is 0.
  210. //
  211. USHORT ReferenceCount; // offset = 0x012
  212. //
  213. // Offset to the first Attribute record in bytes.
  214. //
  215. USHORT FirstAttributeOffset; // offset = 0x014
  216. //
  217. // FILE_xxx flags.
  218. //
  219. USHORT Flags; // offset = 0x016
  220. //
  221. // First free byte available for attribute storage, from start
  222. // of this header. This value should always be aligned to a
  223. // quad-word boundary, since attributes are quad-word aligned.
  224. //
  225. ULONG FirstFreeByte; // offset = x0018
  226. //
  227. // Total bytes available in this file record segment, from the
  228. // start of this header. This is essentially the file record
  229. // segment size.
  230. //
  231. ULONG BytesAvailable; // offset = 0x01C
  232. //
  233. // This is a File Reference to the Base file record segment for
  234. // this file. If this is the Base, then the value of this
  235. // field is all 0's.
  236. //
  237. UCHAR Pad1[8]; // offset = 0x020
  238. //
  239. // This is the attribute instance number to be used when
  240. // creating an attribute. It is zeroed when the base file
  241. // record is created, and captured for each new attribute as it
  242. // is created and incremented afterwards for the next
  243. // attribute. Instance numbering must also occur for the
  244. // initial attributes. Zero is a valid attribute instance
  245. // number, and typically used for standard information.
  246. //
  247. USHORT NextAttributeInstance; // offset = 0x028
  248. //
  249. // Current FRS record - this is here for recovery alone and added in 5.1
  250. // Note: this is not aligned
  251. //
  252. USHORT SegmentNumberHighPart; // offset = 0x02A
  253. ULONG SegmentNumberLowPart; // offset = 0x02C
  254. //
  255. // Update Sequence Array to protect multi-sector transfers of
  256. // the File Record Segment. Accesses to already initialized
  257. // File Record Segments should go through the offset above, for
  258. // upwards compatibility.
  259. //
  260. UCHAR Pad2[1]; // offset = 0x030
  261. } FILE_RECORD_SEGMENT_HEADER;
  262. typedef FILE_RECORD_SEGMENT_HEADER *PFILE_RECORD_SEGMENT_HEADER;
  263. //
  264. // FILE_xxx flags.
  265. //
  266. #define FILE_RECORD_SEGMENT_IN_USE (0x0001)
  267. #define FILE_FILE_NAME_INDEX_PRESENT (0x0002)
  268. #define FILE_SYSTEM_FILE (0x0004)
  269. #define FILE_VIEW_INDEX_PRESENT (0x0008)
  270. //
  271. // Attribute Record. Logically an attribute has a type, an
  272. // optional name, and a value, however the storage details make it
  273. // a little more complicated. For starters, an attribute's value
  274. // may either be resident in the file record segment itself, on
  275. // nonresident in a separate data stream. If it is nonresident, it
  276. // may actually exist multiple times in multiple file record
  277. // segments to describe different ranges of VCNs.
  278. //
  279. // Attribute Records are always aligned on a quad word (64-bit)
  280. // boundary.
  281. //
  282. typedef struct _ATTRIBUTE_RECORD_HEADER {
  283. //
  284. // Attribute Type Code.
  285. //
  286. ATTRIBUTE_TYPE_CODE TypeCode; // offset = 0x000
  287. //
  288. // Length of this Attribute Record in bytes. The length is
  289. // always rounded to a quad word boundary, if necessary. Also
  290. // the length only reflects the size necessary to store the
  291. // given record variant.
  292. //
  293. ULONG RecordLength; // offset = 0x004
  294. //
  295. // Attribute Form Code (see below)
  296. //
  297. UCHAR FormCode; // offset = 0x008
  298. //
  299. // Length of the optional attribute name in characters, or 0 if
  300. // there is none.
  301. //
  302. UCHAR NameLength; // offset = 0x009
  303. //
  304. // Offset to the attribute name from start of attribute record,
  305. // in bytes, if it exists. This field is undefined if
  306. // NameLength is 0.
  307. //
  308. USHORT NameOffset; // offset = 0x00A
  309. //
  310. // ATTRIBUTE_xxx flags.
  311. //
  312. USHORT Flags; // offset = 0x00C
  313. //
  314. // The file-record-unique attribute instance number for this
  315. // attribute.
  316. //
  317. USHORT Instance; // offset = 0x00E
  318. //
  319. // The following union handles the cases distinguished by the
  320. // Form Code.
  321. //
  322. union {
  323. //
  324. // Resident Form. Attribute resides in file record segment.
  325. //
  326. struct {
  327. //
  328. // Length of attribute value in bytes.
  329. //
  330. ULONG ValueLength; // offset = 0x010
  331. //
  332. // Offset to value from start of attribute record, in
  333. // bytes.
  334. //
  335. USHORT ValueOffset; // offset = 0x014
  336. //
  337. // RESIDENT_FORM_xxx Flags.
  338. //
  339. UCHAR ResidentFlags; // offset = 0x016
  340. //
  341. // Reserved.
  342. //
  343. UCHAR Reserved; // offset = 0x017
  344. } Resident;
  345. //
  346. // Nonresident Form. Attribute resides in separate stream.
  347. //
  348. struct {
  349. //
  350. // Lowest VCN covered by this attribute record.
  351. //
  352. VCN LowestVcn; // offset = 0x010
  353. //
  354. // Highest VCN covered by this attribute record.
  355. //
  356. VCN HighestVcn; // offset = 0x018
  357. //
  358. // Offset to the Mapping Pairs Array (defined below),
  359. // in bytes, from the start of the attribute record.
  360. //
  361. USHORT MappingPairsOffset; // offset = 0x020
  362. //
  363. // Unit of Compression size for this stream, expressed
  364. // as a log of the cluster size.
  365. //
  366. // 0 means file is not compressed
  367. // 1, 2, 3, and 4 are potentially legal values if the
  368. // stream is compressed, however the implementation
  369. // may only choose to use 4, or possibly 3. Note
  370. // that 4 means cluster size time 16. If convenient
  371. // the implementation may wish to accept a
  372. // reasonable range of legal values here (1-5?),
  373. // even if the implementation only generates
  374. // a smaller set of values itself.
  375. //
  376. UCHAR CompressionUnit; // offset = 0x022
  377. //
  378. // Reserved to get to quad word boundary.
  379. //
  380. UCHAR Reserved[5]; // offset = 0x023
  381. //
  382. // Allocated Length of the file in bytes. This is
  383. // obviously an even multiple of the cluster size.
  384. // (Not present if LowestVcn != 0.)
  385. //
  386. LONGLONG AllocatedLength; // offset = 0x028
  387. //
  388. // File Size in bytes (highest byte which may be read +
  389. // 1). (Not present if LowestVcn != 0.)
  390. //
  391. LONGLONG FileSize; // offset = 0x030
  392. //
  393. // Valid Data Length (highest initialized byte + 1).
  394. // This field must also be rounded to a cluster
  395. // boundary, and the data must always be initialized to
  396. // a cluster boundary. (Not present if LowestVcn != 0.)
  397. //
  398. LONGLONG ValidDataLength; // offset = 0x038
  399. //
  400. // Totally allocated. This field is only present for the first
  401. // file record of a compressed stream. It represents the sum of
  402. // the allocated clusters for a file.
  403. //
  404. LONGLONG TotalAllocated; // offset = 0x040
  405. //
  406. //
  407. // Mapping Pairs Array, starting at the offset stored
  408. // above.
  409. //
  410. // The Mapping Pairs Array is stored in a compressed
  411. // form, and assumes that this information is
  412. // decompressed and cached by the system. The reason
  413. // for compressing this information is clear, it is
  414. // done in the hopes that all of the retrieval
  415. // information always fits in a single file record
  416. // segment.
  417. //
  418. // Logically, the MappingPairs Array stores a series of
  419. // NextVcn/CurrentLcn pairs. So, for example, given
  420. // that we know the first Vcn (from LowestVcn above),
  421. // the first Mapping Pair tells us what the next Vcn is
  422. // (for the next Mapping Pair), and what Lcn the
  423. // current Vcn is mapped to, or 0 if the Current Vcn is
  424. // not allocated. (This is exactly the FsRtl MCB
  425. // structure).
  426. //
  427. // For example, if a file has a single run of 8
  428. // clusters, starting at Lcn 128, and the file starts
  429. // at LowestVcn=0, then the Mapping Pairs array has
  430. // just one entry, which is:
  431. //
  432. // NextVcn = 8
  433. // CurrentLcn = 128
  434. //
  435. // The compression is implemented with the following
  436. // algorithm. Assume that you initialize two "working"
  437. // variables as follows:
  438. //
  439. // NextVcn = LowestVcn (from above)
  440. // CurrentLcn = 0
  441. //
  442. // The MappingPairs array is byte stream, which simply
  443. // store the changes to the working variables above,
  444. // when processed sequentially. The byte stream is to
  445. // be interpreted as a zero-terminated stream of
  446. // triples, as follows:
  447. //
  448. // count byte = v + (l * 16)
  449. //
  450. // where v = number of changed low-order Vcn bytes
  451. // l = number of changed low-order Lcn bytes
  452. //
  453. // v Vcn change bytes
  454. // l Lcn change bytes
  455. //
  456. // The byte stream terminates when a count byte of 0 is
  457. // encountered.
  458. //
  459. // The decompression algorithm goes as follows,
  460. // assuming that Attribute is a pointer to the
  461. // attribute record.
  462. //
  463. // 1. Initialize:
  464. // NextVcn = Attribute->LowestVcn;
  465. // CurrentLcn = 0;
  466. //
  467. // 2. Initialize byte stream pointer to: (PCHAR)Attribute +
  468. // Attribute->AttributeForm->Nonresident->MappingPairsOffset
  469. //
  470. // 3. CurrentVcn = NextVcn;
  471. //
  472. // 4. Read next byte from stream. If it is 0, then
  473. // break, else extract v and l (see above).
  474. //
  475. // 5. Interpret the next v bytes as a signed quantity,
  476. // with the low-order byte coming first. Unpack it
  477. // sign-extended into 64 bits and add it to NextVcn.
  478. // (It can really only be positive, but the Lcn
  479. // change can be positive or negative.)
  480. //
  481. // 6. Interpret the next l bytes as a signed quantity,
  482. // with the low-order byte coming first. Unpack it
  483. // sign-extended into 64 bits and add it to
  484. // CurrentLcn. Remember, if this produces a
  485. // CurrentLcn of 0, then the Vcns from the
  486. // CurrentVcn to NextVcn-1 are unallocated.
  487. //
  488. // 7. Update cached mapping information from
  489. // CurrentVcn, NextVcn and CurrentLcn.
  490. //
  491. // 8. Loop back to 3.
  492. //
  493. // The compression algorithm should now be obvious, as
  494. // it is the reverse of the above. The compression and
  495. // decompression algorithms will be available as common
  496. // RTL routines, available to NTFS and file utilities.
  497. //
  498. // In defense of this algorithm, not only does it
  499. // provide compression of the on-disk storage
  500. // requirements, but it results in a single
  501. // representation, independent of disk size and file
  502. // size. Contrast this with solutions which are in use
  503. // which define multiple sizes for virtual and logical
  504. // cluster sizes, depending on the size of the disk,
  505. // etc. For example, two byte cluster numbers might
  506. // suffice for a floppy, while four bytes would be
  507. // required for most hard disks today, and five or six
  508. // bytes are required after a certain number of
  509. // gigabytes, etc. This eventually results in more
  510. // complex code than above (because of the cases) and
  511. // worse yet - untested cases. So, more important than
  512. // the compression, the above algorithm provides one
  513. // case which efficiently handles any size disk.
  514. //
  515. } Nonresident;
  516. } Form;
  517. } ATTRIBUTE_RECORD_HEADER;
  518. typedef ATTRIBUTE_RECORD_HEADER *PATTRIBUTE_RECORD_HEADER;
  519. //
  520. // Attribute Form Codes
  521. //
  522. #define RESIDENT_FORM (0x00)
  523. #define NONRESIDENT_FORM (0x01)
  524. //
  525. // File Name attribute. A file has one File Name attribute for
  526. // every directory it is entered into (hard links).
  527. //
  528. typedef struct _FILE_NAME {
  529. //
  530. // This is a File Reference to the directory file which indexes
  531. // to this name.
  532. //
  533. FILE_REFERENCE ParentDirectory; // offset = 0x000
  534. //
  535. // Information for faster directory operations.
  536. //
  537. UCHAR Pad0[0x38]; // offset = 0x008
  538. //
  539. // Length of the name to follow, in (Unicode) characters.
  540. //
  541. UCHAR FileNameLength; // offset = 0x040
  542. //
  543. // FILE_NAME_xxx flags
  544. //
  545. UCHAR Flags; // offset = 0x041
  546. //
  547. // First character of Unicode File Name
  548. //
  549. WCHAR FileName[1]; // offset = 0x042
  550. } FILE_NAME;
  551. typedef FILE_NAME *PFILE_NAME;