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.

895 lines
29 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. HpfsBoot.h
  5. Abstract:
  6. This module defines globally used procedure and data structures used
  7. by Hpfs boot.
  8. Author:
  9. Gary Kimura [GaryKi] 19-Jul-1991
  10. Revision History:
  11. --*/
  12. #ifndef _HPFSBOOT_
  13. #define _HPFSBOOT_
  14. typedef ULONG LBN;
  15. typedef LBN *PLBN;
  16. typedef ULONG VBN;
  17. typedef VBN *PVBN;
  18. //
  19. // The following structure is a context block used by the exported
  20. // procedures in the Hpfs boot package. The context contains our cached
  21. // part of the boot mcb structure. The max number must not be smaller than
  22. // the maximum number of leafs possible in a pinball allocation sector plus
  23. // one.
  24. //
  25. #define MAXIMUM_NUMBER_OF_BOOT_MCB (41)
  26. typedef struct _HPFS_BOOT_MCB {
  27. //
  28. // The following fields indicate the number of entries in use by
  29. // the boot mcb. and the boot mcb itself. The boot mcb is
  30. // just a collection of vbn - lbn pairs. The last InUse entry
  31. // Lbn's value is ignored, because it is only used to give the
  32. // length of the previous run.
  33. //
  34. ULONG InUse;
  35. VBN Vbn[ MAXIMUM_NUMBER_OF_BOOT_MCB ];
  36. LBN Lbn[ MAXIMUM_NUMBER_OF_BOOT_MCB ];
  37. } HPFS_BOOT_MCB, *PHPFS_BOOT_MCB;
  38. typedef struct _HPFS_STRUCTURE_CONTEXT {
  39. //
  40. // The following field contains the fnode lbn of the file
  41. //
  42. LBN Fnode;
  43. //
  44. // The following field contains the cached mcb
  45. //
  46. HPFS_BOOT_MCB BootMcb;
  47. } HPFS_STRUCTURE_CONTEXT, *PHPFS_STRUCTURE_CONTEXT;
  48. //
  49. // Define Hpfs file context structure.
  50. //
  51. typedef struct _HPFS_FILE_CONTEXT {
  52. //
  53. // The following field contains the size of the file, in bytes.
  54. //
  55. ULONG FileSize;
  56. } HPFS_FILE_CONTEXT, *PHPFS_FILE_CONTEXT;
  57. //
  58. // HPFS file system structures
  59. //
  60. typedef ULONG SIGNATURE;
  61. typedef SIGNATURE *PSIGNATURE;
  62. typedef ULONG PINBALL_TIME;
  63. typedef PINBALL_TIME *PPINBALL_TIME;
  64. //
  65. // There are only three sectors on the disk that have fixed locations. They
  66. // are the boot sector, the super sector, and the spare sector.
  67. //
  68. #define BOOT_SECTOR_LBN (0)
  69. #define SUPER_SECTOR_LBN (16)
  70. #define SPARE_SECTOR_LBN (17)
  71. typedef struct _SUPER_SECTOR {
  72. //
  73. // The Super Sector starts with a double signature.
  74. //
  75. SIGNATURE Signature1; // offset = 0x000 0
  76. SIGNATURE Signature2; // offset = 0x004 4
  77. //
  78. // The version and functional version describe the version of
  79. // the on-disk file system structures and the oldest version of the
  80. // file system that can understand this disk.
  81. //
  82. UCHAR Version; // offset = 0x008 8
  83. UCHAR FunctionalVersion; // offset = 0x009 9
  84. USHORT Unused1; // offset = 0x00A 10
  85. //
  86. // This field denotes the sector containing the FNODE for the root
  87. // directory for the volume.
  88. //
  89. LBN RootDirectoryFnode; // offset = 0x00C 12
  90. //
  91. // The follow two fields indicate the number of total sectors on the
  92. // volume (good and bad), and the number of bad sectors on the volume.
  93. //
  94. ULONG NumberOfSectors; // offset = 0x010 16
  95. ULONG NumberOfBadSectors; // offset = 0x014 20
  96. //
  97. // This field denotes the sector containing the first level of the
  98. // volumes bitmap table.
  99. //
  100. LBN BitMapIndirect; // offset = 0x018 24
  101. ULONG Unused2; // offset = 0x01C 28
  102. //
  103. // This field denotes the sector containing the first bad sector disk
  104. // buffer for the volume.
  105. //
  106. LBN BadSectorList; // offset = 0x020 32
  107. ULONG Unused3; // offset = 0x024 36
  108. //
  109. // The following two dates are the time of the last execution of
  110. // chkdsk and disk optimize on the volume.
  111. //
  112. PINBALL_TIME ChkdskDate; // offset = 0x028 40
  113. PINBALL_TIME DiskOptimizeDate; // offset = 0x02C 44
  114. //
  115. // The following four fields describe the directory disk buffer pool.
  116. // It is a contiguous run on of sectors on the disk set aside for
  117. // holding directory disk buffers. PoolSize is the total number of
  118. // sectors in the pool. First and Last Sector denote the boundaries
  119. // of the pool, and BitMap denotes the start of a small bitmap used to
  120. // describe the directory disk buffer pool's current allocation. The
  121. // bitmap is 4 contiguous sectors in size, and each bit in the map
  122. // corresponds to 1 Directory Disk Buffer (i.e., 4 Sectors worth)
  123. //
  124. ULONG DirDiskBufferPoolSize; // offset = 0x030 48
  125. LBN DirDiskBufferPoolFirstSector; // offset = 0x034 52
  126. LBN DirDiskBufferPoolLastSector; // offset = 0x038 56
  127. LBN DirDiskBufferPoolBitMap; // offset = 0x03C 60
  128. //
  129. // The following field contains the name of the volume
  130. //
  131. UCHAR VolumeName[32]; // offset = 0x040 64
  132. //
  133. // The following field denotes the start of the Small ID (SID) table
  134. // which is used to store the Small ID to GUID mappings used on the
  135. // volume. The SID table is 8 contiguous sectors in size.
  136. //
  137. LBN SidTable; // offset = 0x060 96
  138. UCHAR Unused4[512-100]; // offset = 0x064 100
  139. } SUPER_SECTOR; // sizeof = 0x200 512
  140. typedef SUPER_SECTOR *PSUPER_SECTOR;
  141. //
  142. // Super Sector signatures
  143. //
  144. #define SUPER_SECTOR_SIGNATURE1 (0xf995e849)
  145. #define SUPER_SECTOR_SIGNATURE2 (0xfa53e9c5)
  146. //
  147. // Super Sector versions
  148. //
  149. #define SUPER_SECTOR_VERSION (0x02)
  150. #define SUPER_SECTOR_FUNC_VERSION (0x02)
  151. typedef struct _SPARE_SECTOR {
  152. //
  153. // The Spare Sector starts with a double signature.
  154. //
  155. SIGNATURE Signature1; // offset = 0x000 0
  156. SIGNATURE Signature2; // offset = 0x004 4
  157. //
  158. // The flags field describe how "clean" the volume is.
  159. //
  160. UCHAR Flags; // offset = 0x008 8
  161. UCHAR Unused1[3]; // offset = 0x009 9
  162. //
  163. // The following three fields describe the hotfix structure for the
  164. // volume. The List field is denotes the disk buffer used to store
  165. // the hotfix table. The InUse describes how many hotfixes are
  166. // currently being used, and MaxSize is the total number of hotfixes
  167. // that can be in use at any one time.
  168. //
  169. LBN HotFixList; // offset = 0x00C 12
  170. ULONG HotFixInUse; // offset = 0x010 16
  171. ULONG HotFixMaxSize; // offset = 0x014 20
  172. //
  173. // The following two fields describe the "emergency" pool of spare
  174. // directory disk buffers. Free describes how many spare directory
  175. // disk buffers are currently available for use. MaxSize is the total
  176. // number of spare directory disk buffers available. The actual location
  177. // of the spare directory disk buffers is denoted in the table at the
  178. // end of the spare sector (i.e., field SpareDirDiskBuffer).
  179. //
  180. ULONG SpareDirDiskBufferAvailable; // offset = 0x018 24
  181. ULONG SpareDirDiskBufferMaxSize; // offset = 0x01C 28
  182. //
  183. // The following two fields describe the code page information used
  184. // on the volume. The InfoSector field is the sector of the beginning
  185. // Code Page Information Sector, and the InUse field is the total number
  186. // of code pages currently in use on the volume.
  187. //
  188. LBN CodePageInfoSector; // offset = 0x020 32
  189. ULONG CodePageInUse; // offset = 0x024 36
  190. ULONG Unused2[17]; // offset = 0x028 40
  191. //
  192. // The following field is an array of LBN's for the spare directory
  193. // disk buffers that are for "emergency" use.
  194. //
  195. LBN SpareDirDiskBuffer[101]; // offset = 0x06C 108
  196. } SPARE_SECTOR; // sizeof = 0x200 512
  197. typedef SPARE_SECTOR *PSPARE_SECTOR;
  198. //
  199. // Spare Sector signatures
  200. //
  201. #define SPARE_SECTOR_SIGNATURE1 (0xf9911849)
  202. #define SPARE_SECTOR_SIGNATURE2 (0xfa5229c5)
  203. //
  204. // The on-disk allocation structure is defined using B-Trees. For every
  205. // B-Tree block there is an Allocation Header, followed by a list of
  206. // either Allocation Leafs or Allocation Nodes. This structure will either
  207. // appear in an FNODE or in an AllocationSector.
  208. //
  209. // The allocation header (called Allocation Block in earlier implementations)
  210. // describes a B-tree block.
  211. //
  212. typedef struct _ALLOCATION_HEADER {
  213. //
  214. // The following flag describes the state of the B-tree block (e.g.,
  215. // indicates if the block is a leaf or an internal node.
  216. //
  217. UCHAR Flags; // offset = 0x000 0
  218. UCHAR Unused[3]; // offset = 0x001 1
  219. //
  220. // The following two fields denote the number of free records in the
  221. // B-Tree block, and the number of records that are currently in use
  222. //
  223. UCHAR FreeCount; // offset = 0x004 4
  224. UCHAR OccupiedCount; // offset = 0x005 5
  225. //
  226. // The next field contains the offset (in bytes) from the beginning
  227. // of the allocation header to the first free byte in the B-Tree block
  228. //
  229. USHORT FirstFreeByte; // offset = 0x006 6
  230. } ALLOCATION_HEADER; // sizeof = 0x008 8
  231. typedef ALLOCATION_HEADER *PALLOCATION_HEADER;
  232. //
  233. // Allocation header flags
  234. //
  235. // NODE - if set this indicates that the B-Tree block contains internal
  236. // nodes and not leaf entries.
  237. //
  238. // BINARY_SEARCH - if set this suggest that a binary search should be used
  239. // to search the B-Tree block.
  240. //
  241. // FNODE_PARENT - if set this indicates that the sector which is the
  242. // parent of the sector with this header (not this sector), is an
  243. // FNODE.
  244. //
  245. #define ALLOCATION_BLOCK_NODE (0x80)
  246. #define ALLOCATION_BLOCK_BINARY (0x40)
  247. #define ALLOCATION_BLOCK_FNODE_PARENT (0x20)
  248. //
  249. // Immediately following an allocation header are one or more allocation nodes
  250. // of allocation leafs.
  251. //
  252. typedef struct _ALLOCATION_NODE {
  253. //
  254. // All children of this allocation node will have values less than
  255. // the following VBN field.
  256. //
  257. VBN Vbn; // offset = 0x000 0
  258. //
  259. // This is the LBN of the allocation sector refered to by this node
  260. //
  261. LBN Lbn; // offset = 0x004 4
  262. } ALLOCATION_NODE; // sizeof = 0x008 8
  263. typedef ALLOCATION_NODE *PALLOCATION_NODE;
  264. typedef struct _ALLOCATION_LEAF {
  265. //
  266. // The following field has the starting VBN for this run
  267. //
  268. VBN Vbn; // offset = 0x000 0
  269. //
  270. // This is the length of the run in sectors
  271. //
  272. ULONG Length; // offset = 0x004 4
  273. //
  274. // This is the starting LBN of the run
  275. //
  276. LBN Lbn; // offset = 0x008 8
  277. } ALLOCATION_LEAF; // sizeof = 0x00C 12
  278. typedef ALLOCATION_LEAF *PALLOCATION_LEAF;
  279. //
  280. // An allocation sector is an on-disk structure that contains allocation
  281. // information. It contains some bookkeeping information, an allocation
  282. // header and then an array of either allocation leafs or allocation nodes.
  283. //
  284. // AllocationSector
  285. // +-------------------+
  286. // | bookkeeping |
  287. // +- - - - - - - - - -+
  288. // | Allocation Header |
  289. // +- - - - - - - - - -+
  290. // | Allocation Leafs |
  291. // | or |
  292. // | Allocation Nodes |
  293. // +-------------------+
  294. //
  295. // where the number of allocation leafs that can be stored in a sector is
  296. // 40 and the number of nodes is 60.
  297. //
  298. #define ALLOCATION_NODES_PER_SECTOR (60)
  299. #define ALLOCATION_LEAFS_PER_SECTOR (40)
  300. typedef struct _ALLOCATION_SECTOR {
  301. //
  302. // The allocation sector starts off with a signature field
  303. //
  304. SIGNATURE Signature; // offset = 0x000 0
  305. //
  306. // This following two fields contains the LBN of this allocation
  307. // sector itself, and the LBN of the parent of this sector (the
  308. // parent is either an FNODE or another allocation sector)
  309. //
  310. LBN Lbn; // offset = 0x004 4
  311. LBN ParentLbn; // offset = 0x008 8
  312. //
  313. // The allocation header for the sector
  314. //
  315. ALLOCATION_HEADER AllocationHeader; // offset = 0x00C 12
  316. //
  317. // The remainder of the sector is either an array of allocation leafs
  318. // of allocation nodes
  319. //
  320. union { // offset = 0x014 20
  321. ALLOCATION_NODE Node[ ALLOCATION_NODES_PER_SECTOR ];
  322. ALLOCATION_LEAF Leaf[ ALLOCATION_LEAFS_PER_SECTOR ];
  323. } Allocation;
  324. UCHAR Unused[12]; // offset = 0x1F4 500
  325. } ALLOCATION_SECTOR; // sizeof = 0x200 512
  326. typedef ALLOCATION_SECTOR *PALLOCATION_SECTOR;
  327. //
  328. // The allocation sector signature
  329. //
  330. #define ALLOCATION_SECTOR_SIGNATURE (0x37e40aae)
  331. //
  332. // The on-disk FNODE structure is used to describe both files and directories
  333. // It contains some fixed data information, the EA and ACL lookup information,
  334. // allocation information and then a free space for storing some EAs and
  335. // ACLs that fit in the sector
  336. //
  337. #define ALLOCATION_NODES_PER_FNODE (12)
  338. #define ALLOCATION_LEAFS_PER_FNODE (8)
  339. typedef struct _FNODE_SECTOR {
  340. //
  341. // The sector starts with a signature field
  342. //
  343. SIGNATURE Signature; // offset = 0x000 0
  344. //
  345. // The following fields was for history tracking, but in NT Pinball
  346. // doesn't need this information.
  347. //
  348. ULONG Unused1[2]; // offset = 0x004 4
  349. //
  350. // The following two fields contain the file name length, and the first
  351. // 15 bytes of the filename, as stored in the dirent that references
  352. // this fnode. For the root directory theses values are all zeros.
  353. //
  354. UCHAR FileNameLength; // offset = 0x00C 12
  355. UCHAR FileName[15]; // offset = 0x00D 13
  356. //
  357. // The following field denotes the parent directory's FNODE
  358. //
  359. LBN ParentFnode; // offset = 0x01C 28
  360. //
  361. // The following four fields describe the ACL for the file/directory.
  362. //
  363. // AclDiskAllocationLength holds the number of bytes in the ACL that
  364. // are stored outside of this FNODE. If this value is not zero
  365. // then AclFnodeLength must be equal to zero.
  366. //
  367. // AclLbn points to the first sector of the data run or the allocation
  368. // sector containing describing the ACL. AclFlags indicates if
  369. // it is a data run or an allocation sector. AclLbn is only used
  370. // if AclDiskAllocationLength is not zero.
  371. //
  372. // AclFnodeLength holds the number of bytes in the ACL that are
  373. // stored within this FNODE. If value is not zero then
  374. // AclDiskAllocationLength must be equal to zero. The ACL, if stored
  375. // in the FNODE, is located at AclEaFnodeBuffer in this FNODE sector.
  376. //
  377. // AclFlags if the data is outside the FNODE this flag indicates whether
  378. // ACL is stored in a single data run (AclFlags == 0) or via an
  379. // allocation sector (AclFlags != 0). AclFlags is only used if
  380. // AclDiskAllocationLength is not zero.
  381. //
  382. ULONG AclDiskAllocationLength; // offset = 0x020 32
  383. LBN AclLbn; // offset = 0x024 36
  384. USHORT AclFnodeLength; // offset = 0x028 40
  385. UCHAR AclFlags; // offset = 0x02A 42
  386. //
  387. // The following field was used for the number of valid history
  388. // bits but we don't need this field of NT Pinball
  389. //
  390. UCHAR Unused2; // offset = 0x02B 43
  391. //
  392. // The following four fields describe the EA for the file/directory.
  393. //
  394. // EaDiskAllocationLength holds the number of bytes in the EA that
  395. // are stored outside of this FNODE. If this value is not zero
  396. // then EaFnodeLength must be equal to zero.
  397. //
  398. // EaLbn points to the first sector of the data run or the allocation
  399. // sector containing describing the EA. EaFlags indicates if
  400. // it is a data run or an allocation sector. EaLbn is only used
  401. // if EaDiskAllocationLength is not zero.
  402. //
  403. // EaFnodeLength holds the number of bytes in the EA that are
  404. // stored within this FNODE. If value is not zero then
  405. // EaDiskAllocationLength must be equal to zero. The EA, if stored
  406. // in the FNODE, is located immediately after the ACL stored in the
  407. // AclEaFnodeBuffer.
  408. //
  409. // EaFlags if the data is outside the FNODE this flag indicates whether
  410. // EA is stored in a single data run (EaFlags == 0) or via an
  411. // allocation sector (EaFlags != 0). EaFlags is only used if
  412. // EaDiskAllocationLength is not zero.
  413. //
  414. ULONG EaDiskAllocationLength; // offset = 0x02C 44
  415. LBN EaLbn; // offset = 0x030 48
  416. USHORT EaFnodeLength; // offset = 0x034 52
  417. UCHAR EaFlags; // offset = 0x036 54
  418. //
  419. // The following byte contains the FNODE flags
  420. //
  421. UCHAR Flags; // offset = 0x037 55
  422. //
  423. // The following two fields describe the top level allocation for
  424. // this file/directory
  425. //
  426. ALLOCATION_HEADER AllocationHeader; // offset = 0x038 56
  427. union { // offset = 0x040 64
  428. ALLOCATION_NODE Node[ ALLOCATION_NODES_PER_FNODE ];
  429. ALLOCATION_LEAF Leaf[ ALLOCATION_LEAFS_PER_FNODE ];
  430. } Allocation;
  431. //
  432. // The following field contains the valid length of the file. The size
  433. // of the file is stored in the dirent. The difference between these two
  434. // values is that the file size is the actual size allocated and visible
  435. // to the user. The Valid length is the number of bytes that have
  436. // had their data zeroed out or modified. (i.e., if a read request
  437. // is greater than valid length but less than file size then the file
  438. // system must first zero out the data in the file up to and including
  439. // data being read.
  440. //
  441. ULONG ValidDataLength; // offset = 0x0A0 160
  442. //
  443. // The following field contains the number of EAs in this file that have
  444. // the need ea attribute set.
  445. //
  446. ULONG NeedEaCount; // offset = 0x0A4 164
  447. UCHAR Unused3[16]; // offset = 0x0A8 168
  448. //
  449. // The following field contains the offset, in bytes, from the start of
  450. // FNODE to the first ACE stored in the FNODE
  451. //
  452. USHORT AclBase; // offset = 0x0B8 184
  453. UCHAR Unused4[10]; // offset = 0x0BA 186
  454. //
  455. // The following buffer is used to store acl/ea in the FNODE
  456. //
  457. UCHAR AclEaFnodeBuffer[316]; // offset = 0x0C4 196
  458. } FNODE_SECTOR; // sizeof = 0x200 512
  459. typedef FNODE_SECTOR *PFNODE_SECTOR;
  460. //
  461. // The FNODE Sector signature
  462. //
  463. #define FNODE_SECTOR_SIGNATURE (0xf7e40aae)
  464. //
  465. // The on-disk directory disk buffer is used to contain directory entries.
  466. // It contains a fixed header followed by a collection of one or more
  467. // dirents. Dirents are variable so size we cannot use a simply C struct
  468. // declartion for the entire disk buffer.
  469. //
  470. typedef struct _DIRECTORY_DISK_BUFFER {
  471. //
  472. // The disk buffer starts with a signature field
  473. //
  474. SIGNATURE Signature; // offset = 0x000 0
  475. //
  476. // The following field is the offset to the first free byte in this
  477. // disk buffer
  478. //
  479. ULONG FirstFree; // offset = 0x004 4
  480. //
  481. // The following field is a change count that is kept around for
  482. // bookkeeping purposes. It is incremented whenever we move any
  483. // of the entries in this disk buffer. This means for any file if we
  484. // remember its offset and its change count we will be able to quickly
  485. // locate the dirent again without needing to search from the top
  486. // of the directory again. (i.e., only if the remembered change count
  487. // and the current change count match). For this to work the file system
  488. // in memory will need to keep track of whenever it removes a Directory
  489. // Disk Buffer from a directory, and have each saved dirent location
  490. // keep this Directory change count, the Directory Disk Buffer Change
  491. // Count, LBN and Offset.
  492. //
  493. // In addition we overload the bit in this value to indicate if this
  494. // is the topmost directory disk buffer for the directory (low order bit
  495. // = 1) or if it is a lower lever buffer (low order bit = 0).
  496. //
  497. ULONG ChangeCount; // offset = 0x008 8
  498. //
  499. // The following field contains the LBN of either the parent
  500. // directory disk buffer containing this disk buffer or the FNODE.
  501. // It is the FNODE if this is a topmost disk buffer and a parent
  502. // directory disk buffer otherwise.
  503. //
  504. LBN Parent; // offset = 0x00C 12
  505. //
  506. // The following field is the LBN of the sector containing the
  507. // start of this disk buffer
  508. //
  509. LBN Sector; // offset = 0x010 16
  510. //
  511. // This following buffer contains the dirents stored in this disk buffer
  512. //
  513. UCHAR Dirents[2028]; // offset = 0x014 20
  514. } DIRECTORY_DISK_BUFFER; // sizeof = 0x800 2048
  515. typedef DIRECTORY_DISK_BUFFER *PDIRECTORY_DISK_BUFFER;
  516. //
  517. // Size of Directory Disk Buffer in sectors.
  518. //
  519. #define DIRECTORY_DISK_BUFFER_SECTORS (4)
  520. //
  521. // Directory Disk Buffer Signature
  522. //
  523. #define DIRECTORY_DISK_BUFFER_SIGNATURE (0x77e40aae)
  524. typedef struct _PBDIRENT {
  525. USHORT DirentSize; // offset = 0x000 0
  526. UCHAR Flags; // offset = 0x002 2
  527. UCHAR FatFlags; // offset = 0x003 3
  528. LBN Fnode; // offset = 0x004 4
  529. PINBALL_TIME LastModificationTime; // offset = 0x008 8
  530. ULONG FileSize; // offset = 0x00C 12
  531. PINBALL_TIME LastAccessTime; // offset = 0x010 16
  532. PINBALL_TIME FnodeCreationTime; // offset = 0x014 20
  533. ULONG EaLength; // offset = 0x018 24
  534. UCHAR ResidentAceCount; // offset = 0x01C 28
  535. UCHAR CodePageIndex; // offset = 0x01D 29
  536. UCHAR FileNameLength; // offset = 0x01E 30
  537. UCHAR FileName[1]; // offset = 0x01F 31
  538. } PBDIRENT; // sizeof = 0x020 32
  539. typedef PBDIRENT *PPBDIRENT;
  540. //
  541. // Define sizes of .. and End PBDIRENT.
  542. //
  543. #define SIZEOF_DIR_DOTDOT (sizeof(PBDIRENT) + sizeof(LONG))
  544. #define SIZEOF_DIR_END (sizeof(PBDIRENT))
  545. #define SIZEOF_DIR_MAXPBDIRENT (sizeof(PBDIRENT) + 256 + \
  546. (3*sizeof(PINBALL_ACE)) + sizeof(LBN))
  547. #define DIRENT_FIRST_ENTRY (0x0001)
  548. #define DIRENT_ACL (0x0002)
  549. #define DIRENT_BTREE_POINTER (0x0004)
  550. #define DIRENT_END (0x0008)
  551. #define DIRENT_EXPLICIT_ACL (0x0040)
  552. #define DIRENT_NEED_EA (0x0080)
  553. #define DIRENT_NEW_NAMING_RULES (0x4000)
  554. //
  555. // The following macros are used to help locate dirents within a Directory
  556. // Disk Buffer. GetFirstDirent returns a pointer to the first dirent entry
  557. // in the directory disk buffer. GetNextDirent returns a pointer to the
  558. // next dirent entry in a directory disk buffer, without checking for the
  559. // end of the Directory Disk Buffer.
  560. //
  561. // PDIRENT
  562. // GetFirstDirent (
  563. // IN PDIRECTORY_DISK_BUFFER DirectoryDiskBuffer
  564. // );
  565. //
  566. // PDIRENT
  567. // GetNextDirent (
  568. // IN PDIRENT Dirent
  569. // );
  570. //
  571. #define GetFirstDirent(DIR) ( \
  572. (PDIRENT)&(DIR)->Dirents[0] \
  573. )
  574. //
  575. // This macro blindly returns a pointer to the next Dirent, without checking
  576. // for the end of the Directory Disk Buffer, i.e., callers must always check
  577. // for the End record in the Directory Disk Buffer. If GetNextDirent is
  578. // called with the End record as input, it will return the next free byte
  579. // in the buffer.
  580. //
  581. #define GetNextDirent(ENT) ( \
  582. (PDIRENT)((PUCHAR)(ENT)+(ENT)->DirentSize) \
  583. )
  584. //
  585. // The following macros are used to help retrieve the variable fields
  586. // within a dirent. GetAceInDirent returns a pointer to the ACE within
  587. // the dirent corresponding to the supplied index, or NULL if there isn't
  588. // a corresponding ACE. GetBtreePointerInDirent returns the LBN field of
  589. // the down B-tree pointer stored in the dirent, or it returns a value of
  590. // zero if there isn't a down pointer. SetBtreePointerInDirent sets the
  591. // LBN downpointer field.
  592. //
  593. // PPINBALL_ACE
  594. // GetAceInDirent (
  595. // IN PDIRENT Dirent,
  596. // IN ULONG Index // (0, 1, or 2)
  597. // );
  598. //
  599. // LBN
  600. // GetBtreePointerInDirent (
  601. // IN PDIRENT Dirent
  602. // );
  603. //
  604. // VOID
  605. // SetBtreePointerInDirent (
  606. // IN OUT PDIRENT Dirent,
  607. // IN LBN Blbn
  608. // );
  609. //
  610. //
  611. //
  612. // To return a pointer to an ACE in a dirent we need to check to see if the
  613. // index is within the resident ace count. The first ace is the address of
  614. // the first longword after the filename, the second ace is the second long
  615. // word.
  616. //
  617. #define GetAceInDirent(ENT,I) ( \
  618. ((I) >= 0 && (I) < (ENT)->ResidentAceCount ? \
  619. (PPINBALL_ACE)( \
  620. (LONG)LongAlign((ENT)->FileName[(ENT)->FileNameLength]) + \
  621. (I)*sizeof(PINBALL_ACE) \
  622. ) \
  623. : \
  624. NULL \
  625. ) \
  626. )
  627. //
  628. // To return the Btree pointer we need to first check to see if there
  629. // is Btree pointer field, otherwise we return NULL. The field, if present,
  630. // is located 4 bytes back from the end of the dirent.
  631. //
  632. #define GetBtreePointerInDirent(ENT) ( \
  633. (FlagOn((ENT)->Flags,DIRENT_BTREE_POINTER) ? \
  634. *(PLBN)(((PUCHAR)(ENT)) + (ENT)->DirentSize - sizeof(LBN)) \
  635. : \
  636. 0 \
  637. ) \
  638. )
  639. //
  640. // To set the Btree pointer we assume there is a Btree pointer field.
  641. // The field is located 4 bytes back from the end of the dirent.
  642. //
  643. #define SetBtreePointerInDirent(ENT,BLBN) ( \
  644. *(PLBN)(((PUCHAR)(ENT)) + (ENT)->DirentSize - sizeof(LBN)) = (BLBN) \
  645. )
  646. //
  647. // Define file I/O prototypes.
  648. //
  649. ARC_STATUS
  650. HpfsClose (
  651. IN ULONG FileId
  652. );
  653. ARC_STATUS
  654. HpfsOpen (
  655. IN CHAR * FIRMWARE_PTR OpenPath,
  656. IN OPEN_MODE OpenMode,
  657. OUT ULONG * FIRMWARE_PTR FileId
  658. );
  659. ARC_STATUS
  660. HpfsRead (
  661. IN ULONG FileId,
  662. OUT VOID * FIRMWARE_PTR Buffer,
  663. IN ULONG Length,
  664. OUT ULONG * FIRMWARE_PTR Count
  665. );
  666. ARC_STATUS
  667. HpfsSeek (
  668. IN ULONG FileId,
  669. IN LARGE_INTEGER * FIRMWARE_PTR Offset,
  670. IN SEEK_MODE SeekMode
  671. );
  672. ARC_STATUS
  673. HpfsWrite (
  674. IN ULONG FileId,
  675. IN VOID * FIRMWARE_PTR Buffer,
  676. IN ULONG Length,
  677. OUT ULONG * FIRMWARE_PTR Count
  678. );
  679. ARC_STATUS
  680. HpfsGetFileInformation (
  681. IN ULONG FileId,
  682. OUT FILE_INFORMATION * FIRMWARE_PTR Buffer
  683. );
  684. ARC_STATUS
  685. HpfsSetFileInformation (
  686. IN ULONG FileId,
  687. IN ULONG AttributeFlags,
  688. IN ULONG AttributeMask
  689. );
  690. ARC_STATUS
  691. HpfsInitialize(
  692. VOID
  693. );
  694. #endif // _HPFSBOOT_