1 |
/* |
2 |
* libhfsp - library for reading and writing Macintosh HFS+ volumes |
3 |
* |
4 |
* This file includes definitions for the structures found on |
5 |
* HFS+ Volumes. The structures are further wrapped by struct |
6 |
* found in libhfsp.h. fucntions on those enhanced structures |
7 |
* are found in files mentioned in comments below. |
8 |
* |
9 |
* Copyright (C) 2000 Klaus Halfmann <klaus.halfmann@feri.de> |
10 |
* Original code 1996-1998 by Robert Leslie <rob@mars.rog> |
11 |
* other work 2000 from Brad Boyer (flar@pants.nu) |
12 |
* |
13 |
* This program is free software; you can redistribute it and/or modify |
14 |
* it under the terms of the GNU General Public License as published by |
15 |
* the Free Software Foundation; either version 2 of the License, or |
16 |
* (at your option) any later version. |
17 |
* |
18 |
* This program is distributed in the hope that it will be useful, |
19 |
* but WITHOUT ANY WARRANTY; without even the implied warranty of |
20 |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
21 |
* GNU General Public License for more details. |
22 |
* |
23 |
* You should have received a copy of the GNU General Public License |
24 |
* along with this program; if not, write to the Free Software |
25 |
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. |
26 |
* |
27 |
*/ |
28 |
|
29 |
/* # include <time.h> */ |
30 |
|
31 |
#define HFSP_BLOCKSZ 512 /* A sector for Apple is always 512 bytes */ |
32 |
#define HFSP_BLOCKSZ_BITS 9 /* 1<<9 == 512 */ |
33 |
#define HFSP_VOLHEAD_SIG 0x482B /* 'H+' */ |
34 |
|
35 |
// Minimum Key size for all btrees |
36 |
#define HFSP_CAT_KEY_MIN_LEN 6 |
37 |
|
38 |
// Maximum Key size for all btrees |
39 |
#define HFSP_CAT_KEY_MAX_LEN 516 |
40 |
|
41 |
/* HFS+ includes POSIX permissions , although marked as reserved they will be |
42 |
* used as such. Is ignored by MacOS 8-9 but probably not by MacOS X. |
43 |
*/ |
44 |
typedef struct { |
45 |
UInt32 owner; |
46 |
UInt32 group; |
47 |
UInt32 mode; |
48 |
UInt32 dev; |
49 |
} hfsp_perm; |
50 |
|
51 |
/* A single contiguous area (fragment) of a file */ |
52 |
typedef struct { |
53 |
UInt32 start_block; |
54 |
UInt32 block_count; |
55 |
} hfsp_extent; |
56 |
|
57 |
/* A file may contain up to 8 normale extents, all other |
58 |
are found in some extra extent area */ |
59 |
typedef hfsp_extent hfsp_extent_rec[8]; |
60 |
|
61 |
/* Information for a "Fork" in a file |
62 |
* Forks are the "usual" DATA and RSRC forks or special files |
63 |
* (e.g. the Volume Bitmap) |
64 |
*/ |
65 |
typedef struct { |
66 |
APPLEUInt64 total_size; // logical size |
67 |
UInt32 clump_size; // number of bytes to preallocate |
68 |
UInt32 total_blocks; |
69 |
hfsp_extent_rec extents; // initial (8) extents |
70 |
} hfsp_fork_raw; |
71 |
|
72 |
/* HFS+ Volume Header |
73 |
* Always found at block 2 of the disk, a copy is stored |
74 |
* at the second to last block of the disk. |
75 |
*/ |
76 |
typedef struct hfsp_vh { |
77 |
UInt16 signature; // must be HFSPLUS_VOLHEAD_SIG 'H+' |
78 |
UInt16 version; // currently 4, ignored |
79 |
UInt32 attributes; // See bit constants below |
80 |
UInt32 last_mount_vers; |
81 |
// Use a registered creator code here (See libhfsp.h) |
82 |
// Mac OS uses '8.10' well |
83 |
UInt32 reserved; |
84 |
|
85 |
UInt32 create_date; // local time ! |
86 |
UInt32 modify_date; // GMT (?) |
87 |
UInt32 backup_date; // GMT (?) |
88 |
UInt32 checked_date; // GMT (?) fsck ? |
89 |
|
90 |
UInt32 file_count; |
91 |
// not including special files but including DATA and RSRC forks |
92 |
UInt32 folder_count; // excluding the root folder |
93 |
|
94 |
UInt32 blocksize; |
95 |
// must be multiple of HFSPLUS_SECTOR_SIZE, |
96 |
// should be a multiple of 4k for harddisk |
97 |
UInt32 total_blocks; |
98 |
UInt32 free_blocks; |
99 |
// The total number of unused allocation blocks on the disk. |
100 |
|
101 |
UInt32 next_alloc; |
102 |
// hint where to search for next allocation blocks |
103 |
UInt32 rsrc_clump_sz; |
104 |
// default clump size for rsrc forks |
105 |
UInt32 data_clump_sz; |
106 |
// default clump size for data forks |
107 |
UInt32 next_cnid; |
108 |
// next unused catalog id |
109 |
UInt32 write_count; |
110 |
// increment on every mount (and write ?) |
111 |
APPLEUInt64 encodings_bmp; |
112 |
// for every encoding used on the disk a bit is set |
113 |
// ignored but eventually must be cared for |
114 |
Char finder_info[32]; |
115 |
hfsp_fork_raw alloc_file; |
116 |
// stores bitmap of use/free blocks |
117 |
hfsp_fork_raw ext_file; |
118 |
// stores oferflow extents |
119 |
hfsp_fork_raw cat_file; |
120 |
// This contains the root directory |
121 |
hfsp_fork_raw attr_file; |
122 |
hfsp_fork_raw start_file; |
123 |
// a special startup file may be described here (used by ?) |
124 |
} hfsp_vh; |
125 |
|
126 |
/* HFS+ volume attributes */ |
127 |
/* 0-6 reserved, may be used in memory only */ |
128 |
#define HFSPLUS_VOL_RESERVED1 0x000000FF |
129 |
#define HFSPLUS_VOL_HARDLOCK 0x00000080 // Used in Memory by finder only |
130 |
#define HFSPLUS_VOL_UNMNT 0x00000100 |
131 |
// clear this bit when mounting, set as last step of unmounting |
132 |
// This is checked by (slower) ROM code |
133 |
#define HFSPLUS_VOL_SPARE_BLK 0x00000200 |
134 |
#define HFSPLUS_VOL_NOCACHE 0x00000400 |
135 |
// in case of RAM or ROM disk (try a HFS+ Ramdisk :) |
136 |
#define HFSPLUS_VOL_INCNSTNT 0x00000800 |
137 |
// Reverse meaning as of HFSPLUS_VOL_UNMNT |
138 |
// This is checked by (faster) Mac OS code |
139 |
/* 12-14 reserved */ |
140 |
#define HFSPLUS_VOL_RESERVED2 0x00007000 |
141 |
#define HFSPLUS_VOL_SOFTLOCK 0x00008000 |
142 |
#define HFSPLUS_VOL_RESERVED3 0xFFFF0000 |
143 |
|
144 |
/* HFS+ Btree node descriptor */ |
145 |
typedef struct { |
146 |
UInt32 next; /* pointer to next node of this kind, or 0 */ |
147 |
/* Header Node points to first MAP node */ |
148 |
UInt32 prev; /* pointer to previous node of this kind, or 0 */ |
149 |
UInt8 kind; /* see below */ |
150 |
UInt8 height; /* root node starts with 0 */ |
151 |
UInt16 num_rec; /* number of records in this node */ |
152 |
UInt16 reserved; /* fill up to 4 byte alignment */ |
153 |
} btree_node_desc; |
154 |
|
155 |
/* HFS+ Btree Node types */ |
156 |
#define HFSP_NODE_NDX 0x00 |
157 |
#define HFSP_NODE_HEAD 0x01 |
158 |
#define HFSP_NODE_MAP 0x02 |
159 |
#define HFSP_NODE_LEAF 0xFF |
160 |
|
161 |
#define HFSP_CATALOG_MIN_NODE_SIZE 0x1000 |
162 |
#define HFSP_ATTRMIN_DOE_SIZE 0x1000 |
163 |
|
164 |
/* The record offsets are found at the end of the fork |
165 |
* containing the Btree */ |
166 |
|
167 |
typedef UInt16 btree_record_offset; |
168 |
|
169 |
typedef struct { |
170 |
UInt16 depth; |
171 |
// equal to height of btree_node_desc |
172 |
UInt32 root; |
173 |
// root node of the hierarchy |
174 |
UInt32 leaf_count; |
175 |
// number of leaf Records (not nodes) |
176 |
UInt32 leaf_head; |
177 |
// first leaf node |
178 |
UInt32 leaf_tail; |
179 |
// last leaf node |
180 |
UInt16 node_size; |
181 |
// node size of _all_ nodes in this fork |
182 |
UInt16 max_key_len; |
183 |
// maximum (or fixed) length of keys in this btree |
184 |
UInt32 node_count; |
185 |
// count of all (free and used) nodes in tree |
186 |
UInt32 free_nodes; |
187 |
UInt16 reserved1; |
188 |
UInt32 clump_size; |
189 |
// ignored my MacOS used by ? |
190 |
UInt8 btree_type; |
191 |
// always 0 for HFS+ |
192 |
UInt8 reserved2; |
193 |
UInt32 attributes; |
194 |
// see below |
195 |
UInt32 reserved3[16]; |
196 |
} btree_head; |
197 |
|
198 |
/* BTree attributes */ |
199 |
#define HFSPLUS_BAD_CLOSE 0x01 |
200 |
// Btree was not properly closed and should be checked |
201 |
// not used for HFS+ but reserved |
202 |
#define HFSPLUS_TREE_BIGKEYS 0x02 |
203 |
// always set for HFS+ |
204 |
#define HFSPLUS_TREE_VAR_NDXKEY_SIZE 0x04 |
205 |
// use variable length index nodes, always set for catalog btree, |
206 |
// always cleared for extents btree. |
207 |
#define HFSPLUS_TREE_RESERVED 0xFFFFFFF8 |
208 |
// Reserved bits in Attributes |
209 |
|
210 |
#define HFSPLUS_TREE_UNUSED 0xFFFFFFF8 |
211 |
|
212 |
/* Some special File ID numbers */ |
213 |
#define HFSP_POR_CNID 1 /* Parent Of the Root */ |
214 |
#define HFSP_ROOT_CNID 2 /* ROOT directory */ |
215 |
#define HFSP_EXT_CNID 3 /* EXTents B-tree */ |
216 |
#define HFSP_CAT_CNID 4 /* CATalog B-tree */ |
217 |
#define HFSP_BAD_CNID 5 /* BAD blocks file */ |
218 |
#define HFSP_ALLOC_CNID 6 /* ALLOCation file */ |
219 |
#define HFSP_START_CNID 7 /* STARTup file */ |
220 |
#define HFSP_ATTR_CNID 8 /* ATTRibutes file */ |
221 |
#define HFSP_EXCH_CNID 15 /* ExchangeFiles temp id */ |
222 |
#define HFSP_MIN_CNID 15 /* Minimum expected value */ |
223 |
|
224 |
/* Unicode String */ |
225 |
typedef struct { |
226 |
UInt16 strlen; |
227 |
UInt16 name[255]; // unicode characters |
228 |
} hfsp_unistr255; |
229 |
|
230 |
/* HFS+ key "superclass" for follwoing keys ...*/ |
231 |
typedef struct { |
232 |
UInt16 key_length; /* excluding length */ |
233 |
char data[0]; |
234 |
} hfsp_key; |
235 |
|
236 |
/* HFS+ catalog entry key */ |
237 |
typedef struct { |
238 |
UInt16 key_length; /* excluding length */ |
239 |
UInt32 parent_cnid; |
240 |
hfsp_unistr255 name; |
241 |
} hfsp_cat_key; |
242 |
|
243 |
/* HFS+ extends entry key */ |
244 |
typedef struct { |
245 |
UInt16 key_length; /* excluding length */ |
246 |
UInt8 fork_type; /* Seee below */ |
247 |
UInt8 filler; |
248 |
UInt32 file_id; |
249 |
UInt32 start_block; |
250 |
} hfsp_extent_key; |
251 |
|
252 |
#define HFSP_EXTENT_DATA 0x00 |
253 |
#define HFSP_EXTENT_RSRC 0xFF |
254 |
|
255 |
/* The key is followed by a record, an index or some other data */ |
256 |
|
257 |
/* The types of these records are defined as follows */ |
258 |
|
259 |
#define HFSP_FOLDER 0x0001 // entry fo a Folder |
260 |
#define HFSP_FILE 0x0002 // entry for a File |
261 |
#define HFSP_FOLDER_THREAD 0x0003 |
262 |
// Like '.' in unix, identifies the folder by its id, only |
263 |
#define HFSP_FILE_THREAD 0x0004 |
264 |
|
265 |
#define HFSP_THREAD_OFFSET 0x0002 |
266 |
// add to create a thread type from a simple type |
267 |
|
268 |
/* HFS+ folder data (part of an hfsp_cat_entry) */ |
269 |
typedef struct { |
270 |
UInt16 flags; /* no flags defined yet */ |
271 |
UInt32 valence; /* Numer of files and folders contained in folder */ |
272 |
UInt32 id; |
273 |
UInt32 create_date; // GMT |
274 |
UInt32 content_mod_date; // GMT |
275 |
UInt32 attribute_mod_date; // GMT |
276 |
UInt32 access_date; // GMT |
277 |
UInt32 backup_date; // GMT |
278 |
hfsp_perm permissions; |
279 |
DInfo user_info; |
280 |
DXInfo finder_info; |
281 |
UInt32 text_encoding; |
282 |
// hint fo the finder what encoding to use, unused here |
283 |
UInt32 reserved; |
284 |
} hfsp_cat_folder; |
285 |
|
286 |
#define HFSP_FOLDER_RESERVED 0xFFFF // all are reserved :) |
287 |
|
288 |
/* HFS+ file data (part of a cat_entry) */ |
289 |
typedef struct { |
290 |
UInt16 flags; /* See below */ |
291 |
UInt32 reserved1; |
292 |
UInt32 id; |
293 |
UInt32 create_date; |
294 |
UInt32 content_mod_date; |
295 |
UInt32 attribute_mod_date; |
296 |
UInt32 access_date; |
297 |
UInt32 backup_date; |
298 |
hfsp_perm permissions; |
299 |
FInfo user_info; |
300 |
FXInfo finder_info; |
301 |
UInt32 text_encoding; |
302 |
UInt32 reserved2; |
303 |
|
304 |
hfsp_fork_raw data_fork; |
305 |
hfsp_fork_raw res_fork; |
306 |
} hfsp_cat_file; |
307 |
|
308 |
/* File attribute bits */ |
309 |
#define HFSP_FILE_LOCKED 0x0001 |
310 |
#define HFSP_THREAD_EXISTS 0x0002 /* Always set in HFS+ */ |
311 |
#define HFSP_FILE_RESERVED 0xFFFC |
312 |
|
313 |
/* HFS+ catalog thread (part of a cat_entry) */ |
314 |
/* In fact this is a almost a hfsp_cat_key */ |
315 |
typedef struct { |
316 |
UInt16 reserved; |
317 |
UInt32 parentID; |
318 |
hfsp_unistr255 nodeName; |
319 |
} hfsp_cat_thread; |
320 |
|
321 |
|
322 |
/* A data record in the catalog tree */ |
323 |
typedef struct { |
324 |
UInt16 type; |
325 |
union { |
326 |
hfsp_cat_folder folder; |
327 |
hfsp_cat_file file; |
328 |
hfsp_cat_thread thread; |
329 |
} u; |
330 |
} hfsp_cat_entry; |