|
1 | 1 | /* |
2 | 2 | * FreeLoader |
3 | 3 | * Copyright (C) 1998-2003 Brian Palmer <[email protected]> |
| 4 | + * Copyright (C) 2024-2025 Daniel Victor <[email protected]> |
4 | 5 | * |
5 | 6 | * This program is free software; you can redistribute it and/or modify |
6 | 7 | * it under the terms of the GNU General Public License as published by |
|
39 | 40 | * along with GRUB. If not, see <http://www.gnu.org/licenses/>. |
40 | 41 | */ |
41 | 42 |
|
42 | | -/* Magic value used to identify an ext filesystem. */ |
43 | | -#define EXT_MAGIC 0xEF53 |
44 | | -/* Amount of indirect blocks in an inode. */ |
45 | | -#define INDIRECT_BLOCKS 12 |
46 | | -/* Maximum length of a pathname. */ |
47 | | -#define EXT_PATH_MAX 4096 |
48 | | -/* Maximum nesting of symlinks, used to prevent a loop. */ |
49 | | -#define EXT_MAX_SYMLINKCNT 8 |
50 | | - |
51 | | -/* The good old revision and the default inode size. */ |
52 | | -#define EXT_GOOD_OLD_REVISION 0 |
53 | | -#define EXT_DYNAMIC_REVISION 1 |
54 | | -#define EXT_GOOD_OLD_INODE_SIZE 128 |
55 | | - |
56 | | -/* Filetype used in directory entry. */ |
57 | | -#define FILETYPE_UNKNOWN 0 |
58 | | -#define FILETYPE_REG 1 |
59 | | -#define FILETYPE_DIRECTORY 2 |
60 | | -#define FILETYPE_SYMLINK 7 |
61 | | - |
62 | | -/* Filetype information as used in inodes. */ |
63 | | -#define FILETYPE_INO_MASK 0170000 |
64 | | -#define FILETYPE_INO_REG 0100000 |
65 | | -#define FILETYPE_INO_DIRECTORY 0040000 |
66 | | -#define FILETYPE_INO_SYMLINK 0120000 |
67 | | - |
68 | | -/* The ext superblock. */ |
69 | | -struct ext_sblock |
| 43 | +#include <pshpack1.h> |
| 44 | + |
| 45 | +#define EXT_SUPERBLOCK_MAGIC 0xEF53 |
| 46 | +#define EXT_DYNAMIC_REVISION 1 |
| 47 | +#define EXT_DEFAULT_INODE_SIZE 128 |
| 48 | +#define EXT_DEFAULT_GROUP_DESC_SIZE 32 |
| 49 | + |
| 50 | +#define EXT_DIR_ENTRY_MAX_NAME_LENGTH 255 |
| 51 | + |
| 52 | +typedef struct _ExtSuperBlock |
70 | 53 | { |
71 | | - ULONG total_inodes; |
72 | | - ULONG total_blocks; |
73 | | - ULONG reserved_blocks; |
74 | | - ULONG free_blocks; |
75 | | - ULONG free_inodes; |
76 | | - ULONG first_data_block; |
77 | | - ULONG log2_block_size; |
78 | | - LONG log2_fragment_size; |
79 | | - ULONG blocks_per_group; |
80 | | - ULONG fragments_per_group; |
81 | | - ULONG inodes_per_group; |
82 | | - ULONG mtime; |
83 | | - ULONG utime; |
84 | | - USHORT mnt_count; |
85 | | - USHORT max_mnt_count; |
86 | | - USHORT magic; |
87 | | - USHORT fs_state; |
88 | | - USHORT error_handling; |
89 | | - USHORT minor_revision_level; |
90 | | - ULONG lastcheck; |
91 | | - ULONG checkinterval; |
92 | | - ULONG creator_os; |
93 | | - ULONG revision_level; |
94 | | - USHORT uid_reserved; |
95 | | - USHORT gid_reserved; |
96 | | - ULONG first_inode; |
97 | | - USHORT inode_size; |
98 | | - USHORT block_group_number; |
99 | | - ULONG feature_compatibility; |
100 | | - ULONG feature_incompat; |
101 | | - ULONG feature_ro_compat; |
102 | | - ULONG unique_id[4]; |
103 | | - char volume_name[16]; |
104 | | - char last_mounted_on[64]; |
105 | | - ULONG compression_info; |
106 | | - ULONG padding[77]; |
107 | | -}; |
108 | | - |
109 | | -/* The ext blockgroup. */ |
110 | | -struct ext_block_group |
| 54 | + /* SuperBlock Information Ext2 */ |
| 55 | + ULONG InodesCount; |
| 56 | + ULONG BlocksCountLo; |
| 57 | + ULONG RBlocksCountLo; |
| 58 | + ULONG FreeBlocksCountLo; |
| 59 | + ULONG FreeInodesCount; |
| 60 | + ULONG FirstDataBlock; |
| 61 | + ULONG LogBlockSize; |
| 62 | + LONG LogFragSize; |
| 63 | + ULONG BlocksPerGroup; |
| 64 | + ULONG FragsPerGroup; |
| 65 | + ULONG InodesPerGroup; |
| 66 | + ULONG MTime; |
| 67 | + ULONG WTime; |
| 68 | + USHORT MntCount; |
| 69 | + USHORT MaxMntCount; |
| 70 | + USHORT Magic; |
| 71 | + USHORT State; |
| 72 | + USHORT Errors; |
| 73 | + USHORT MinorRevisionLevel; |
| 74 | + ULONG LastCheck; |
| 75 | + ULONG CheckInterval; |
| 76 | + ULONG CreatorOS; |
| 77 | + ULONG RevisionLevel; |
| 78 | + USHORT DefResUID; |
| 79 | + USHORT DefResGID; |
| 80 | + |
| 81 | + /* SuperBlock Information Ext3 */ |
| 82 | + ULONG FirstInode; |
| 83 | + USHORT InodeSize; |
| 84 | + USHORT BlockGroupNr; |
| 85 | + ULONG FeatureCompat; |
| 86 | + ULONG FeatureIncompat; |
| 87 | + ULONG FeatureROCompat; |
| 88 | + UCHAR UUID[16]; |
| 89 | + CHAR VolumeName[16]; |
| 90 | + CHAR LastMounted[64]; |
| 91 | + ULONG AlgorithmUsageBitmap; |
| 92 | + UCHAR PreallocBlocks; |
| 93 | + UCHAR PreallocDirBlocks; |
| 94 | + USHORT ReservedGdtBlocks; |
| 95 | + UCHAR JournalUUID[16]; |
| 96 | + ULONG JournalInum; |
| 97 | + ULONG JournalDev; |
| 98 | + ULONG LastOrphan; |
| 99 | + ULONG HashSeed[4]; |
| 100 | + UCHAR DefHashVersion; |
| 101 | + UCHAR JournalBackupType; |
| 102 | + USHORT GroupDescSize; |
| 103 | + UCHAR Reserved[768]; |
| 104 | +} EXT_SUPER_BLOCK, *PEXT_SUPER_BLOCK; |
| 105 | + |
| 106 | +typedef struct _ExtGroupDescriptor |
111 | 107 | { |
112 | | - ULONG block_id; |
113 | | - ULONG inode_id; |
114 | | - ULONG inode_table_id; |
115 | | - USHORT free_blocks; |
116 | | - USHORT free_inodes; |
117 | | - USHORT used_dirs; |
118 | | - USHORT pad; |
119 | | - ULONG reserved[3]; |
120 | | -}; |
121 | | - |
122 | | -/* The ext inode. */ |
123 | | -struct ext_inode |
| 108 | + ULONG BlockBitmap; |
| 109 | + ULONG InodeBitmap; |
| 110 | + ULONG InodeTable; |
| 111 | + USHORT FreeBlocksCount; |
| 112 | + USHORT FreeInodesCount; |
| 113 | + USHORT UsedDirsCount; |
| 114 | +} EXT_GROUP_DESC, *PEXT_GROUP_DESC; |
| 115 | + |
| 116 | +typedef struct _Ext4ExtentHeader |
124 | 117 | { |
125 | | - USHORT mode; |
126 | | - USHORT uid; |
127 | | - ULONG size; |
128 | | - ULONG atime; |
129 | | - ULONG ctime; |
130 | | - ULONG mtime; |
131 | | - ULONG dtime; |
132 | | - USHORT gid; |
133 | | - USHORT nlinks; |
134 | | - ULONG blockcnt; /* Blocks of 512 bytes!! */ |
135 | | - ULONG flags; |
136 | | - ULONG osd1; |
137 | | - union |
138 | | - { |
139 | | - struct datablocks |
140 | | - { |
141 | | - ULONG dir_blocks[INDIRECT_BLOCKS]; |
142 | | - ULONG indir_block; |
143 | | - ULONG double_indir_block; |
144 | | - ULONG tripple_indir_block; |
145 | | - } blocks; |
146 | | - char symlink[60]; |
147 | | - }; |
148 | | - ULONG version; |
149 | | - ULONG acl; |
150 | | - ULONG dir_acl; |
151 | | - ULONG fragment_addr; |
152 | | - ULONG osd2[3]; |
153 | | -}; |
154 | | - |
155 | | -/* The header of an ext directory entry. */ |
156 | | -#define EXT_NAME_LEN 255 |
157 | | - |
158 | | -struct ext_dirent |
| 118 | + USHORT Magic; |
| 119 | + USHORT Entries; |
| 120 | + USHORT Max; |
| 121 | + USHORT Depth; |
| 122 | + ULONG Generation; |
| 123 | +} EXT4_EXTENT_HEADER, *PEXT4_EXTENT_HEADER; |
| 124 | + |
| 125 | +typedef struct _Ext4ExtentIdx |
159 | 126 | { |
160 | | - ULONG inode; |
161 | | - USHORT direntlen; |
162 | | - UCHAR namelen; |
163 | | - UCHAR filetype; |
164 | | - CHAR name[EXT_NAME_LEN]; |
165 | | -}; |
| 127 | + ULONG Block; |
| 128 | + ULONG Leaf; |
| 129 | + USHORT LeafHigh; |
| 130 | + USHORT Unused; |
| 131 | +} EXT4_EXTENT_IDX, *PEXT4_EXTENT_IDX; |
166 | 132 |
|
167 | | -/* |
168 | | - * End of code from grub/fs/ext2.c |
169 | | - */ |
| 133 | +typedef struct _Ext4Extent |
| 134 | +{ |
| 135 | + ULONG Block; |
| 136 | + USHORT Length; |
| 137 | + USHORT StartHigh; |
| 138 | + ULONG Start; |
| 139 | +} EXT4_EXTENT, *PEXT4_EXTENT; |
| 140 | + |
| 141 | +typedef struct _ExtInode |
| 142 | +{ |
| 143 | + USHORT Mode; |
| 144 | + USHORT UID; |
| 145 | + ULONG Size; |
| 146 | + ULONG Atime; |
| 147 | + ULONG Ctime; |
| 148 | + ULONG Mtime; |
| 149 | + ULONG Dtime; |
| 150 | + USHORT GID; |
| 151 | + USHORT LinksCount; |
| 152 | + ULONG BlocksCount; |
| 153 | + ULONG Flags; |
| 154 | + ULONG OSD1; |
| 155 | + union |
| 156 | + { |
| 157 | + CHAR SymLink[60]; |
| 158 | + struct |
| 159 | + { |
| 160 | + ULONG DirectBlocks[12]; |
| 161 | + ULONG IndirectBlock; |
| 162 | + ULONG DoubleIndirectBlock; |
| 163 | + ULONG TripleIndirectBlock; |
| 164 | + } Blocks; |
| 165 | + EXT4_EXTENT_HEADER ExtentHeader; |
| 166 | + }; |
| 167 | + ULONG Generation; |
| 168 | + ULONG FileACL; |
| 169 | + ULONG DirACL; |
| 170 | + ULONG FragAddress; |
| 171 | + ULONG OSD2[3]; |
| 172 | +} EXT_INODE, *PEXT_INODE; |
| 173 | + |
| 174 | +typedef struct _ExtDirEntry |
| 175 | +{ |
| 176 | + ULONG Inode; |
| 177 | + USHORT EntryLen; |
| 178 | + UCHAR NameLen; |
| 179 | + UCHAR FileType; |
| 180 | + CHAR Name[EXT_DIR_ENTRY_MAX_NAME_LENGTH]; |
| 181 | +} EXT_DIR_ENTRY, *PEXT_DIR_ENTRY; |
170 | 182 |
|
171 | | -typedef struct ext_sblock EXT_SUPER_BLOCK, *PEXT_SUPER_BLOCK; |
172 | | -typedef struct ext_inode EXT_INODE, *PEXT_INODE; |
173 | | -typedef struct ext_block_group EXT_GROUP_DESC, *PEXT_GROUP_DESC; |
174 | | -typedef struct ext_dirent EXT_DIR_ENTRY, *PEXT_DIR_ENTRY; |
| 183 | +#include <poppack.h> |
175 | 184 |
|
176 | 185 | /* Special inode numbers. */ |
177 | | -#define EXT_ROOT_INO 2 |
| 186 | +#define EXT_ROOT_INODE 2 |
| 187 | + |
| 188 | +/* The revision level. */ |
| 189 | +#define EXT_REVISION(sb) (sb->RevisionLevel) |
178 | 190 |
|
179 | | -/* Feature set definitions. */ |
180 | | -#define EXT3_FEATURE_INCOMPAT_SUPP 0x0002 |
| 191 | +/* The inode size. */ |
| 192 | +#define EXT_INODE_SIZE(sb) \ |
| 193 | + (EXT_REVISION(sb) < EXT_DYNAMIC_REVISION ? EXT_DEFAULT_INODE_SIZE : sb->InodeSize) |
181 | 194 |
|
182 | | -/* Log2 size of ext block in bytes. */ |
183 | | -#define LOG2_BLOCK_SIZE(sb) (sb->log2_block_size + 10) |
| 195 | +/* The group descriptor size. */ |
| 196 | +#define EXT_GROUP_DESC_SIZE(sb) \ |
| 197 | + ((EXT_REVISION(sb) >= EXT_DYNAMIC_REVISION && sb->GroupDescSize) ? sb->GroupDescSize : EXT_DEFAULT_GROUP_DESC_SIZE) |
184 | 198 |
|
185 | | -/* The size of an ext block in bytes. */ |
186 | | -#define EXT_BLOCK_SIZE(sb) (((SIZE_T)1) << LOG2_BLOCK_SIZE(sb)) |
| 199 | +/* The inode extents flag. */ |
| 200 | +#define EXT4_INODE_FLAG_EXTENTS 0x80000 |
187 | 201 |
|
188 | | -/* The revision level. */ |
189 | | -#define EXT_REVISION(sb) (sb->revision_level) |
| 202 | +/* The extent header magic value. */ |
| 203 | +#define EXT4_EXTENT_HEADER_MAGIC 0xF30A |
190 | 204 |
|
191 | | -/* The inode size. */ |
192 | | -#define EXT_INODE_SIZE(sb) (EXT_REVISION(sb) == EXT_GOOD_OLD_REVISION \ |
193 | | - ? EXT_GOOD_OLD_INODE_SIZE \ |
194 | | - : sb->inode_size) |
| 205 | +/* The maximum extent level. */ |
| 206 | +#define EXT4_EXTENT_MAX_LEVEL 5 |
195 | 207 |
|
196 | | -#define EXT_DESC_PER_BLOCK(s) (EXT_BLOCK_SIZE(s) / sizeof(struct ext_block_group)) |
| 208 | +/* The maximum extent length used to check for sparse extents. */ |
| 209 | +#define EXT4_EXTENT_MAX_LENGTH 32768 |
197 | 210 |
|
198 | 211 | // EXT_INODE::mode values |
199 | | -#define EXT_S_IRWXO 0x0007 // Other mask |
200 | | -#define EXT_S_IXOTH 0x0001 // ---------x execute |
201 | | -#define EXT_S_IWOTH 0x0002 // --------w- write |
202 | | -#define EXT_S_IROTH 0x0004 // -------r-- read |
203 | | - |
204 | | -#define EXT_S_IRWXG 0x0038 // Group mask |
205 | | -#define EXT_S_IXGRP 0x0008 // ------x--- execute |
206 | | -#define EXT_S_IWGRP 0x0010 // -----w---- write |
207 | | -#define EXT_S_IRGRP 0x0020 // ----r----- read |
208 | | - |
209 | | -#define EXT_S_IRWXU 0x01C0 // User mask |
210 | | -#define EXT_S_IXUSR 0x0040 // ---x------ execute |
211 | | -#define EXT_S_IWUSR 0x0080 // --w------- write |
212 | | -#define EXT_S_IRUSR 0x0100 // -r-------- read |
213 | | - |
214 | | -#define EXT_S_ISVTX 0x0200 // Sticky bit |
215 | | -#define EXT_S_ISGID 0x0400 // SGID |
216 | | -#define EXT_S_ISUID 0x0800 // SUID |
217 | | - |
218 | | -#define EXT_S_IFMT 0xF000 // Format mask |
219 | | -#define EXT_S_IFIFO 0x1000 // FIFO buffer |
220 | | -#define EXT_S_IFCHR 0x2000 // Character device |
221 | | -#define EXT_S_IFDIR 0x4000 // Directory |
222 | | -#define EXT_S_IFBLK 0x6000 // Block device |
223 | | -#define EXT_S_IFREG 0x8000 // Regular file |
224 | | -#define EXT_S_IFLNK 0xA000 // Symbolic link |
225 | | -#define EXT_S_IFSOCK 0xC000 // Socket |
226 | | - |
227 | | -#define FAST_SYMLINK_MAX_NAME_SIZE 60 |
| 212 | +#define EXT_S_IRWXO 0x0007 // Other mask |
| 213 | +#define EXT_S_IXOTH 0x0001 // ---------x execute |
| 214 | +#define EXT_S_IWOTH 0x0002 // --------w- write |
| 215 | +#define EXT_S_IROTH 0x0004 // -------r-- read |
| 216 | + |
| 217 | +#define EXT_S_IRWXG 0x0038 // Group mask |
| 218 | +#define EXT_S_IXGRP 0x0008 // ------x--- execute |
| 219 | +#define EXT_S_IWGRP 0x0010 // -----w---- write |
| 220 | +#define EXT_S_IRGRP 0x0020 // ----r----- read |
| 221 | + |
| 222 | +#define EXT_S_IRWXU 0x01C0 // User mask |
| 223 | +#define EXT_S_IXUSR 0x0040 // ---x------ execute |
| 224 | +#define EXT_S_IWUSR 0x0080 // --w------- write |
| 225 | +#define EXT_S_IRUSR 0x0100 // -r-------- read |
| 226 | + |
| 227 | +#define EXT_S_ISVTX 0x0200 // Sticky bit |
| 228 | +#define EXT_S_ISGID 0x0400 // SGID |
| 229 | +#define EXT_S_ISUID 0x0800 // SUID |
| 230 | + |
| 231 | +#define EXT_S_IFMT 0xF000 // Format mask |
| 232 | +#define EXT_S_IFIFO 0x1000 // FIFO buffer |
| 233 | +#define EXT_S_IFCHR 0x2000 // Character device |
| 234 | +#define EXT_S_IFDIR 0x4000 // Directory |
| 235 | +#define EXT_S_IFBLK 0x6000 // Block device |
| 236 | +#define EXT_S_IFREG 0x8000 // Regular file |
| 237 | +#define EXT_S_IFLNK 0xA000 // Symbolic link |
| 238 | +#define EXT_S_IFSOCK 0xC000 // Socket |
| 239 | + |
| 240 | +#define FAST_SYMLINK_MAX_NAME_SIZE 60 |
228 | 241 |
|
229 | 242 | typedef struct _EXT_VOLUME_INFO *PEXT_VOLUME_INFO; |
230 | 243 |
|
231 | | -typedef struct |
| 244 | +typedef struct _EXT_FILE_INFO |
232 | 245 | { |
233 | | - ULONGLONG FileSize; // File size |
234 | | - ULONGLONG FilePointer; // File pointer |
235 | | - ULONG* FileBlockList; // File block list |
236 | | - EXT_INODE Inode; // File's inode |
237 | | - PEXT_VOLUME_INFO Volume; |
238 | | -} EXT_FILE_INFO, * PEXT_FILE_INFO; |
| 246 | + ULONGLONG FileSize; // File size |
| 247 | + ULONGLONG FilePointer; // File pointer |
| 248 | + PULONG FileBlockList; // File block list |
| 249 | + EXT_INODE Inode; // File's inode |
| 250 | + PEXT_VOLUME_INFO Volume; |
| 251 | +} EXT_FILE_INFO, *PEXT_FILE_INFO; |
239 | 252 |
|
240 | 253 | const DEVVTBL* ExtMount(ULONG DeviceId); |
0 commit comments