Source code of Windows XP (NT5)
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.

587 lines
19 KiB

  1. /*++
  2. joejoe most of this will just disappear....VBO will remain......
  3. Copyright (c) 1989 Microsoft Corporation
  4. Module Name:
  5. Rx.h
  6. Abstract:
  7. This module defines the on-disk structure of the Rx file system.
  8. Author:
  9. Gary Kimura [GaryKi] 28-Dec-1989
  10. Revision History:
  11. --*/
  12. #ifndef _RDBSS_
  13. #define _RDBSS_
  14. //
  15. // The following nomenclature is used to describe the Rx on-disk
  16. // structure:
  17. //
  18. // LBN - is the number of a sector relative to the start of the disk.
  19. //
  20. // VBN - is the number of a sector relative to the start of a file,
  21. // directory, or allocation.
  22. //
  23. // LBO - is a byte offset relative to the start of the disk.
  24. //
  25. // VBO - is a byte offset relative to the start of a file, directory
  26. // or allocation.
  27. //
  28. //typedef ULONG LBO;
  29. //typedef LBO *PLBO;
  30. //typedef ULONG VBO;
  31. //typedef LONGLONG RXVBO;
  32. //typedef VBO *PVBO;
  33. #if 0
  34. //
  35. // The boot sector is the first physical sector (LBN == 0) on the volume.
  36. // Part of the sector contains a BIOS Parameter Block. The BIOS in the
  37. // sector is packed (i.e., unaligned) so we'll supply a unpacking macro
  38. // to translate a packed BIOS into its unpacked equivalent. The unpacked
  39. // BIOS structure is already defined in ntioapi.h so we only need to define
  40. // the packed BIOS.
  41. //
  42. //
  43. // Define the Packed and Unpacked BIOS Parameter Block
  44. //
  45. typedef struct _PACKED_BIOS_PARAMETER_BLOCK {
  46. UCHAR BytesPerSector[2]; // offset = 0x000 0
  47. UCHAR SectorsPerCluster[1]; // offset = 0x002 2
  48. UCHAR ReservedSectors[2]; // offset = 0x003 3
  49. UCHAR Rxs[1]; // offset = 0x005 5
  50. UCHAR RootEntries[2]; // offset = 0x006 6
  51. UCHAR Sectors[2]; // offset = 0x008 8
  52. UCHAR Media[1]; // offset = 0x00A 10
  53. UCHAR SectorsPerRx[2]; // offset = 0x00B 11
  54. UCHAR SectorsPerTrack[2]; // offset = 0x00D 13
  55. UCHAR Heads[2]; // offset = 0x00F 15
  56. UCHAR HiddenSectors[4]; // offset = 0x011 17
  57. UCHAR LargeSectors[4]; // offset = 0x015 21
  58. } PACKED_BIOS_PARAMETER_BLOCK; // sizeof = 0x019 25
  59. typedef PACKED_BIOS_PARAMETER_BLOCK *PPACKED_BIOS_PARAMETER_BLOCK;
  60. typedef struct BIOS_PARAMETER_BLOCK {
  61. USHORT BytesPerSector;
  62. UCHAR SectorsPerCluster;
  63. USHORT ReservedSectors;
  64. UCHAR Rxs;
  65. USHORT RootEntries;
  66. USHORT Sectors;
  67. UCHAR Media;
  68. USHORT SectorsPerRx;
  69. USHORT SectorsPerTrack;
  70. USHORT Heads;
  71. ULONG HiddenSectors;
  72. ULONG LargeSectors;
  73. } BIOS_PARAMETER_BLOCK, *PBIOS_PARAMETER_BLOCK;
  74. //
  75. // This macro takes a Packed BIOS and fills in its Unpacked equivalent
  76. //
  77. #define RxUnpackBios(Bios,Pbios) { \
  78. CopyUchar2(&(Bios)->BytesPerSector, &(Pbios)->BytesPerSector[0] ); \
  79. CopyUchar1(&(Bios)->SectorsPerCluster, &(Pbios)->SectorsPerCluster[0]); \
  80. CopyUchar2(&(Bios)->ReservedSectors, &(Pbios)->ReservedSectors[0] ); \
  81. CopyUchar1(&(Bios)->Rxs, &(Pbios)->Rxs[0] ); \
  82. CopyUchar2(&(Bios)->RootEntries, &(Pbios)->RootEntries[0] ); \
  83. CopyUchar2(&(Bios)->Sectors, &(Pbios)->Sectors[0] ); \
  84. CopyUchar1(&(Bios)->Media, &(Pbios)->Media[0] ); \
  85. CopyUchar2(&(Bios)->SectorsPerRx, &(Pbios)->SectorsPerRx[0] ); \
  86. CopyUchar2(&(Bios)->SectorsPerTrack, &(Pbios)->SectorsPerTrack[0] ); \
  87. CopyUchar2(&(Bios)->Heads, &(Pbios)->Heads[0] ); \
  88. CopyUchar4(&(Bios)->HiddenSectors, &(Pbios)->HiddenSectors[0] ); \
  89. CopyUchar4(&(Bios)->LargeSectors, &(Pbios)->LargeSectors[0] ); \
  90. }
  91. //
  92. // Define the boot sector
  93. //
  94. typedef struct _PACKED_BOOT_SECTOR {
  95. UCHAR Jump[3]; // offset = 0x000 0
  96. UCHAR Oem[8]; // offset = 0x003 3
  97. PACKED_BIOS_PARAMETER_BLOCK PackedBpb; // offset = 0x00B 11
  98. UCHAR PhysicalDriveNumber; // offset = 0x024 36
  99. UCHAR Reserved; // offset = 0x025 37
  100. UCHAR Signature; // offset = 0x026 38
  101. UCHAR Id[4]; // offset = 0x027 39
  102. UCHAR VolumeLabel[11]; // offset = 0x02B 43
  103. UCHAR SystemId[8]; // offset = 0x036 54
  104. } PACKED_BOOT_SECTOR; // sizeof = 0x03E 62
  105. typedef PACKED_BOOT_SECTOR *PPACKED_BOOT_SECTOR;
  106. //
  107. // Define a Rx Entry type.
  108. //
  109. // This type is used when representing a rx table entry. It also used
  110. // to be used when dealing with a rx table index and a count of entries,
  111. // but the ensuing type casting nightmare sealed this rxe. These other
  112. // two types are represented as ULONGs.
  113. //
  114. typedef USHORT RDBSS_ENTRY;
  115. typedef RDBSS_ENTRY *PRDBSS_ENTRY;
  116. #define ENTRIES_PER_PAGE (PAGE_SIZE / sizeof(RDBSS_ENTRY))
  117. //
  118. // The following constants the are the valid Rx index values.
  119. //
  120. #define RDBSS_CLUSTER_AVAILABLE (RDBSS_ENTRY)0x0000
  121. #define RDBSS_CLUSTER_RESERVED (RDBSS_ENTRY)0xfff0
  122. #define RDBSS_CLUSTER_BAD (RDBSS_ENTRY)0xfff7
  123. #define RDBSS_CLUSTER_LAST (RDBSS_ENTRY)0xffff
  124. //
  125. // Rx files have the following time/date structures. Note that the
  126. // following structure is a 32 bits long but USHORT aligned.
  127. //
  128. typedef struct _RDBSS_TIME {
  129. USHORT DoubleSeconds : 5;
  130. USHORT Minute : 6;
  131. USHORT Hour : 5;
  132. } RDBSS_TIME;
  133. typedef RDBSS_TIME *PRDBSS_TIME;
  134. typedef struct _RDBSS_DATE {
  135. USHORT Day : 5;
  136. USHORT Month : 4;
  137. USHORT Year : 7; // Relative to 1980
  138. } RDBSS_DATE;
  139. typedef RDBSS_DATE *PRDBSS_DATE;
  140. typedef struct _RDBSS_TIME_STAMP {
  141. RDBSS_TIME Time;
  142. RDBSS_DATE Date;
  143. } RDBSS_TIME_STAMP;
  144. typedef RDBSS_TIME_STAMP *PRDBSS_TIME_STAMP;
  145. //
  146. // Rx files have 8 character file names and 3 character extensions
  147. //
  148. typedef UCHAR RDBSS8DOT3[11];
  149. typedef RDBSS8DOT3 *PRDBSS8DOT3;
  150. //
  151. // The directory entry record exists for every file/directory on the
  152. // disk except for the root directory.
  153. //
  154. typedef struct _PACKED_DIRENT {
  155. RDBSS8DOT3 FileName; // offset = 0
  156. UCHAR Attributes; // offset = 11
  157. UCHAR NtByte; // offset = 12
  158. UCHAR CreationMSec; // offset = 13
  159. RDBSS_TIME_STAMP CreationTime; // offset = 14
  160. RDBSS_DATE LastAccessDate; // offset = 18
  161. USHORT ExtendedAttributes; // offset = 20
  162. RDBSS_TIME_STAMP LastWriteTime; // offset = 22
  163. RDBSS_ENTRY FirstClusterOfFile; // offset = 26
  164. ULONG FileSize; // offset = 28
  165. } PACKED_DIRENT; // sizeof = 32
  166. typedef PACKED_DIRENT *PPACKED_DIRENT;
  167. //
  168. // A packed dirent is already quadword aligned so simply declare a dirent as a
  169. // packed dirent
  170. //
  171. typedef PACKED_DIRENT DIRENT;
  172. typedef DIRENT *PDIRENT;
  173. //
  174. // The first byte of a dirent describes the dirent. There is also a routine
  175. // to help in deciding how to interpret the dirent.
  176. //
  177. #define RDBSS_DIRENT_NEVER_USED 0x00
  178. #define RDBSS_DIRENT_REALLY_0E5 0x05
  179. #define RDBSS_DIRENT_DIRECTORY_ALIAS 0x2e
  180. #define RDBSS_DIRENT_DELETED 0xe5
  181. //
  182. // Define the NtByte bits.
  183. //
  184. #define RDBSS_DIRENT_NT_BYTE_DIRTY 0x01
  185. #define RDBSS_DIRENT_NT_BYTE_TEST_SURFACE 0x02
  186. #define RDBSS_DIRENT_NT_BYTE_8_LOWER_CASE 0x08
  187. #define RDBSS_DIRENT_NT_BYTE_3_LOWER_CASE 0x10
  188. //
  189. // Define the various dirent attributes
  190. //
  191. #define RDBSS_DIRENT_ATTR_READ_ONLY 0x01
  192. #define RDBSS_DIRENT_ATTR_HIDDEN 0x02
  193. #define RDBSS_DIRENT_ATTR_SYSTEM 0x04
  194. #define RDBSS_DIRENT_ATTR_VOLUME_ID 0x08
  195. #define RDBSS_DIRENT_ATTR_DIRECTORY 0x10
  196. #define RDBSS_DIRENT_ATTR_ARCHIVE 0x20
  197. #define RDBSS_DIRENT_ATTR_DEVICE 0x40
  198. #define RDBSS_DIRENT_ATTR_LFN (RDBSS_DIRENT_ATTR_READ_ONLY | \
  199. RDBSS_DIRENT_ATTR_HIDDEN | \
  200. RDBSS_DIRENT_ATTR_SYSTEM | \
  201. RDBSS_DIRENT_ATTR_VOLUME_ID)
  202. //
  203. // These macros convert a number of fields in the Bpb to bytes from sectors
  204. //
  205. // ULONG
  206. // RxBytesPerCluster (
  207. // IN PBIOS_PARAMETER_BLOCK Bios
  208. // );
  209. //
  210. // ULONG
  211. // RxBytesPerRx (
  212. // IN PBIOS_PARAMETER_BLOCK Bios
  213. // );
  214. //
  215. // ULONG
  216. // RxReservedBytes (
  217. // IN PBIOS_PARAMETER_BLOCK Bios
  218. // );
  219. //
  220. #define RxBytesPerCluster(B) ((ULONG)((B)->BytesPerSector * (B)->SectorsPerCluster))
  221. #define RxBytesPerRx(B) ((ULONG)((B)->BytesPerSector * (B)->SectorsPerRx))
  222. #define RxReservedBytes(B) ((ULONG)((B)->BytesPerSector * (B)->ReservedSectors))
  223. //
  224. // This macro returns the size of the root directory dirent area in bytes
  225. //
  226. // ULONG
  227. // RxRootDirectorySize (
  228. // IN PBIOS_PARAMETER_BLOCK Bios
  229. // );
  230. //
  231. #define RxRootDirectorySize(B) ((ULONG)((B)->RootEntries * sizeof(DIRENT)))
  232. //
  233. // This macro returns the first Lbo (zero based) of the root directory on
  234. // the device. This area is after the reserved and rxs.
  235. //
  236. // LBO
  237. // RxRootDirectoryLbo (
  238. // IN PBIOS_PARAMETER_BLOCK Bios
  239. // );
  240. //
  241. #define RxRootDirectoryLbo(B) (RxReservedBytes(B) + ((B)->Rxs * RxBytesPerRx(B)))
  242. //
  243. // This macro returns the first Lbo (zero based) of the file area on the
  244. // the device. This area is after the reserved, rxs, and root directory.
  245. //
  246. // LBO
  247. // RxFirstFileAreaLbo (
  248. // IN PBIOS_PARAMTER_BLOCK Bios
  249. // );
  250. //
  251. #define RxFileAreaLbo(B) (RxRootDirectoryLbo(B) + RxRootDirectorySize(B))
  252. //
  253. // This macro returns the number of clusters on the disk. This value is
  254. // computed by taking the total sectors on the disk subtracting up to the
  255. // first file area sector and then dividing by the sectors per cluster count.
  256. // Note that I don't use any of the above macros since far too much
  257. // superfluous sector/byte conversion would take place.
  258. //
  259. // ULONG
  260. // RxNumberOfClusters (
  261. // IN PBIOS_PARAMETER_BLOCK Bios
  262. // );
  263. //
  264. #define RxNumberOfClusters(B) ( \
  265. \
  266. (((B)->Sectors + (B)->LargeSectors \
  267. \
  268. - ((B)->ReservedSectors + \
  269. (B)->Rxs * (B)->SectorsPerRx + \
  270. (B)->RootEntries * sizeof(DIRENT) / (B)->BytesPerSector ) ) \
  271. \
  272. / \
  273. \
  274. (B)->SectorsPerCluster) \
  275. )
  276. //
  277. // This macro returns the rx table bit size (i.e., 12 or 16 bits)
  278. //
  279. // ULONG
  280. // RxIndexBitSize (
  281. // IN PBIOS_PARAMETER_BLOCK Bios
  282. // );
  283. //
  284. #define RxIndexBitSize(B) ((UCHAR)(RxNumberOfClusters(B) < 4087 ? 12 : 16))
  285. //
  286. // This macro raises RxStatus(FILE_CORRUPT) and marks the Fcb bad if an
  287. // index value is not within the proper range.
  288. // Note that the first two index values are invalid (0, 1), so we must
  289. // add two from the top end to make sure the everything is within range
  290. //
  291. // VOID
  292. // RxVerifyIndexIsValid (
  293. // IN PRX_CONTEXT RxContext,
  294. // IN PVCB Vcb,
  295. // IN ULONG Index
  296. // );
  297. //
  298. #define RxVerifyIndexIsValid(IC,V,I) { \
  299. if (((I) < 2) || ((I) > ((V)->AllocationSupport.NumberOfClusters + 1))) { \
  300. RxRaiseStatus(IC,RxStatus(FILE_CORRUPT_ERROR)); \
  301. } \
  302. }
  303. //
  304. // These two macros are used to translate between Logical Byte Offsets,
  305. // and rx entry indexes. Note the use of variables stored in the Vcb.
  306. // These two macros are used at a higher level than the other macros
  307. // above.
  308. //
  309. // LBO
  310. // GetLboFromRxIndex (
  311. // IN RDBSS_ENTRY Rx_Index,
  312. // IN PVCB Vcb
  313. // );
  314. //
  315. // RDBSS_ENTRY
  316. // GetRxIndexFromLbo (
  317. // IN LBO Lbo,
  318. // IN PVCB Vcb
  319. // );
  320. //
  321. #define RxGetLboFromIndex(VCB,RDBSS_INDEX) ( \
  322. (VCB)->AllocationSupport.FileAreaLbo + \
  323. ((LBO)((RDBSS_INDEX) - 2) << (VCB)->AllocationSupport.LogOfBytesPerCluster) \
  324. )
  325. #define RxGetIndexFromLbo(VCB,LBO) ( \
  326. (((LBO) - (VCB)->AllocationSupport.FileAreaLbo) >> \
  327. (VCB)->AllocationSupport.LogOfBytesPerCluster) + 2 \
  328. )
  329. //
  330. // The following macro does the tmp shifting and such to lookup an entry
  331. //
  332. // VOID
  333. // RxLookup12BitEntry(
  334. // IN PVOID Rx,
  335. // IN RDBSS_ENTRY Index,
  336. // OUT PRDBSS_ENTRY Entry
  337. // );
  338. //
  339. #define RxLookup12BitEntry(RDBSS,INDEX,ENTRY) { \
  340. \
  341. CopyUchar2((PUCHAR)(ENTRY), (PUCHAR)(RDBSS) + (INDEX) * 3 / 2); \
  342. \
  343. *ENTRY = ((INDEX) & 1) ? *(ENTRY) >> 4 : (RDBSS_ENTRY)(*(ENTRY) & 0xfff); \
  344. }
  345. //
  346. // The following macro does the tmp shifting and such to store an entry
  347. //
  348. // VOID
  349. // RxSet12BitEntry(
  350. // IN PVOID Rx,
  351. // IN RDBSS_ENTRY Index,
  352. // IN RDBSS_ENTRY Entry
  353. // );
  354. //
  355. #define RxSet12BitEntry(RDBSS,INDEX,ENTRY) { \
  356. \
  357. RDBSS_ENTRY TmpRxEntry; \
  358. \
  359. CopyUchar2((PUCHAR)&TmpRxEntry, (PUCHAR)(RDBSS) + (INDEX) * 3 / 2); \
  360. \
  361. TmpRxEntry = (RDBSS_ENTRY) \
  362. (((INDEX) & 1) ? ((ENTRY) << 4) | (TmpRxEntry & 0xf) \
  363. : (ENTRY) | (TmpRxEntry & 0xf000)); \
  364. \
  365. *((UNALIGNED UCHAR2 *)((PUCHAR)(RDBSS) + (INDEX) * 3 / 2)) = *((UNALIGNED UCHAR2 *)(&TmpRxEntry)); \
  366. }
  367. //
  368. // The following macro compares two RDBSS_TIME_STAMPs
  369. //
  370. #define RxAreTimesEqual(TIME1,TIME2) ((BOOLEAN) \
  371. (RtlCompareMemory((TIME1),(TIME2), sizeof(RDBSS_TIME_STAMP)) == \
  372. sizeof(RDBSS_TIME_STAMP)) \
  373. )
  374. #define EA_FILE_SIGNATURE (0x4445) // "ED"
  375. #define EA_SET_SIGNATURE (0x4145) // "EA"
  376. //
  377. // If the volume contains any ea data then there is one EA file called
  378. // "EA DATA. SF" located in the root directory as Hidden, System and
  379. // ReadOnly.
  380. //
  381. typedef struct _EA_FILE_HEADER {
  382. USHORT Signature; // offset = 0
  383. USHORT FormatType; // offset = 2
  384. USHORT LogType; // offset = 4
  385. USHORT Cluster1; // offset = 6
  386. USHORT NewCValue1; // offset = 8
  387. USHORT Cluster2; // offset = 10
  388. USHORT NewCValue2; // offset = 12
  389. USHORT Cluster3; // offset = 14
  390. USHORT NewCValue3; // offset = 16
  391. USHORT Handle; // offset = 18
  392. USHORT NewHOffset; // offset = 20
  393. UCHAR Reserved[10]; // offset = 22
  394. USHORT EaBaseTable[240]; // offset = 32
  395. } EA_FILE_HEADER; // sizeof = 512
  396. typedef EA_FILE_HEADER *PEA_FILE_HEADER;
  397. typedef USHORT EA_OFF_TABLE[128];
  398. typedef EA_OFF_TABLE *PEA_OFF_TABLE;
  399. //
  400. // Every file with an extended attribute contains in its dirent an index
  401. // into the EaMapTable. The map table contains an offset within the ea
  402. // file (cluster aligned) of the ea data for the file. The individual
  403. // ea data for each file is prefaced with an Ea Data Header.
  404. //
  405. typedef struct _EA_SET_HEADER {
  406. USHORT Signature; // offset = 0
  407. USHORT OwnEaHandle; // offset = 2
  408. ULONG NeedEaCount; // offset = 4
  409. UCHAR OwnerFileName[14]; // offset = 8
  410. UCHAR Reserved[4]; // offset = 22
  411. UCHAR cbList[4]; // offset = 26
  412. UCHAR PackedEas[1]; // offset = 30
  413. } EA_SET_HEADER; // sizeof = 30
  414. typedef EA_SET_HEADER *PEA_SET_HEADER;
  415. #define SIZE_OF_EA_SET_HEADER 30
  416. #define MAXIMUM_EA_SIZE 0x0000ffff
  417. #define GetcbList(EASET) (((EASET)->cbList[0] << 0) + \
  418. ((EASET)->cbList[1] << 8) + \
  419. ((EASET)->cbList[2] << 16) + \
  420. ((EASET)->cbList[3] << 24))
  421. #define SetcbList(EASET,CB) { \
  422. (EASET)->cbList[0] = (CB >> 0) & 0x0ff; \
  423. (EASET)->cbList[1] = (CB >> 8) & 0x0ff; \
  424. (EASET)->cbList[2] = (CB >> 16) & 0x0ff; \
  425. (EASET)->cbList[3] = (CB >> 24) & 0x0ff; \
  426. }
  427. //
  428. // Every individual ea in an ea set is declared the following packed ea
  429. //
  430. typedef struct _PACKED_EA {
  431. UCHAR Flags;
  432. UCHAR EaNameLength;
  433. UCHAR EaValueLength[2];
  434. CHAR EaName[1];
  435. } PACKED_EA;
  436. typedef PACKED_EA *PPACKED_EA;
  437. //
  438. // The following two macros are used to get and set the ea value length
  439. // field of a packed ea
  440. //
  441. // VOID
  442. // GetEaValueLength (
  443. // IN PPACKED_EA Ea,
  444. // OUT PUSHORT ValueLength
  445. // );
  446. //
  447. // VOID
  448. // SetEaValueLength (
  449. // IN PPACKED_EA Ea,
  450. // IN USHORT ValueLength
  451. // );
  452. //
  453. #define GetEaValueLength(EA,LEN) { \
  454. *(LEN) = 0; \
  455. CopyUchar2( (LEN), (EA)->EaValueLength ); \
  456. }
  457. #define SetEaValueLength(EA,LEN) { \
  458. CopyUchar2( &((EA)->EaValueLength), (LEN) ); \
  459. }
  460. //
  461. // The following macro is used to get the size of a packed ea
  462. //
  463. // VOID
  464. // SizeOfPackedEa (
  465. // IN PPACKED_EA Ea,
  466. // OUT PUSHORT EaSize
  467. // );
  468. //
  469. #define SizeOfPackedEa(EA,SIZE) { \
  470. ULONG _NL,_DL; _NL = 0; _DL = 0; \
  471. CopyUchar1(&_NL, &(EA)->EaNameLength); \
  472. GetEaValueLength(EA, &_DL); \
  473. *(SIZE) = 1 + 1 + 2 + _NL + 1 + _DL; \
  474. }
  475. #define EA_NEED_EA_FLAG 0x80
  476. #define MIN_EA_HANDLE 1
  477. #define MAX_EA_HANDLE 30719
  478. #define UNUSED_EA_HANDLE 0xffff
  479. #define EA_CBLIST_OFFSET 0x1a
  480. #define MAX_EA_BASE_INDEX 240
  481. #define MAX_EA_OFFSET_INDEX 128
  482. #endif
  483. #endif // _RDBSS_
  484.