summaryrefslogtreecommitdiff
path: root/libparted/fs/hfs/hfs.h
blob: 5b9138c3c8df5493b00e39562deaf1b78c767f41 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
/*
    libparted - a library for manipulating disk partitions
    Copyright (C) 2003-2005, 2007, 2009-2014, 2019-2023 Free Software
    Foundation, Inc.

    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/

#ifndef _HFS_H
#define _HFS_H

/* WARNING : bn is used 2 times in theses macro */
/* so _never_ use side effect operators when using them */
#define TST_BLOC_OCCUPATION(tab,bn) \
	(((tab)[(bn)/8])  &  (1<<(7-((bn)&7))))
#define SET_BLOC_OCCUPATION(tab,bn) \
	(((tab)[(bn)/8]) |=  (1<<(7-((bn)&7))))
#define CLR_BLOC_OCCUPATION(tab,bn) \
	(((tab)[(bn)/8]) &= ~(1<<(7-((bn)&7))))

/* Maximum number of blocks for the copy buffers */
#define BLOCK_MAX_BUFF	256
/* Maximum size of the copy buffers, in bytes */
#define BYTES_MAX_BUFF	8388608

/* Apple Creator Codes follow */
#define HFSP_IMPL_Shnk	0x53686e6b	/* in use */
#define HFSP_IMPL_Xpnd	0x58706e64	/* reserved */
#define HFSP_IMPL_Resz	0x5265737a	/* reserved */
#define HFSP_IMPL_PHpx	0x50482b78	/* reserved */
#define HFSP_IMPL_traP  0x74726150	/* reserved */
#define HFSP_IMPL_GnuP  0x476e7550	/* reserved */

#define HFS_SIGNATURE	0x4244		/* 'BD' */
#define HFSP_SIGNATURE	0x482B		/* 'H+' */
#define HFSX_SIGNATURE  0x4858		/* 'HX' */

#define HFSP_VERSION	 4
#define HFSX_VERSION	 5

#define HFS_HARD_LOCK	 7
#define HFS_UNMOUNTED	 8
#define HFS_BAD_SPARED	 9
#define HFS_SOFT_LOCK	15
#define HFSP_NO_CACHE	10
#define HFSP_INCONSISTENT 11
#define HFSP_REUSE_CNID	12
#define HFSP_JOURNALED	13

#define HFS_IDX_NODE	0x00
#define HFS_HDR_NODE	0x01
#define HFS_MAP_NODE	0x02
#define HFS_LEAF_NODE	0xFF

#define HFS_FIRST_REC	0x0E
#define HFS_NSD_HD_REC	0x78
#define HFS_MAP_REC	0xF8

#define HFS_DATA_FORK	0x00
#define HFS_RES_FORK	0xFF

#define HFS_CAT_DIR	0x01
#define HFS_CAT_FILE	0x02
#define HFS_CAT_DIR_TH	0x03
#define HFS_CAT_FILE_TH	0x04

#define HFSP_ATTR_INLINE	0x10
#define HFSP_ATTR_FORK		0x20
#define HFSP_ATTR_EXTENTS	0x30

#define HFS_ROOT_PAR_ID		0x01
#define HFS_ROOT_DIR_ID		0x02
#define HFS_XTENT_ID		0x03
#define HFS_CATALOG_ID		0x04
#define HFS_BAD_BLOCK_ID	0x05
#define HFSP_ALLOC_ID		0x06
#define HFSP_STARTUP_ID		0x07
#define HFSP_ATTRIB_ID		0x08
#define HFSP_BOGUS_ID		0x0F
#define HFSP_FIRST_AV_ID	0x10

#define HFSJ_JOURN_IN_FS	0x00
#define HFSJ_JOURN_OTHER_DEV	0x01
#define HFSJ_JOURN_NEED_INIT	0x02

#define HFSJ_HEADER_MAGIC	0x4a4e4c78
#define HFSJ_ENDIAN_MAGIC	0x12345678

#define HFSX_CASE_FOLDING	0xCF	/* case insensitive HFSX */
#define HFSX_BINARY_COMPARE	0xBC	/* case sensitive   HFSX */

#define HFS_EXT_NB	3
#define HFSP_EXT_NB	8

/* Define the filenames used by the FS extractor */
#ifdef HFS_EXTRACT_FS

#define HFS_MDB_FILENAME	"mdb.hfs"
#define HFS_CATALOG_FILENAME	"catalog.hfs"
#define HFS_EXTENTS_FILENAME	"extents.hfs"
#define HFS_BITMAP_FILENAME	"bitmap.hfs"

#define HFSP_VH_FILENAME	"vh.hfsplus"
#define HFSP_CATALOG_FILENAME	"catalog.hfsplus"
#define HFSP_EXTENTS_FILENAME	"extents.hfsplus"
#define HFSP_BITMAP_FILENAME	"bitmap.hfsplus"
#define HFSP_ATTRIB_FILENAME	"attributes.hfsplus"
#define HFSP_STARTUP_FILENAME	"startup.hfsplus"

#endif /* HFS_EXTRACT_FS */



/* ----------------------------------- */
/* --      HFS DATA STRUCTURES      -- */
/* ----------------------------------- */

/* Extent descriptor */
struct __attribute__ ((packed)) _HfsExtDescriptor {
        uint16_t	start_block;
        uint16_t	block_count;
};
typedef struct _HfsExtDescriptor HfsExtDescriptor;
typedef HfsExtDescriptor HfsExtDataRec[HFS_EXT_NB];

/* Volume header */
struct __attribute__ ((packed)) _HfsMasterDirectoryBlock {
        uint16_t         signature;
        uint32_t         create_date;
        uint32_t         modify_date;
        uint16_t         volume_attributes;
        uint16_t         files_in_root;
        uint16_t         volume_bitmap_block;       /* in sectors */
        uint16_t         next_allocation;
        uint16_t         total_blocks;
        uint32_t         block_size;                /* in bytes */
        uint32_t         def_clump_size;            /* in bytes */
        uint16_t         start_block;               /* in sectors */
        uint32_t         next_free_node;
        uint16_t         free_blocks;
        uint8_t          name_length;
        char             name[27];
        uint32_t         backup_date;
        uint16_t         backup_number;
        uint32_t         write_count;
        uint32_t         extents_clump;
        uint32_t         catalog_clump;
        uint16_t         dirs_in_root;
        uint32_t         file_count;
        uint32_t         dir_count;
        uint32_t         finder_info[8];
        union __attribute__ ((packed)) {
                struct __attribute__ ((packed)) {
                        uint16_t    volume_cache_size;    /* in blocks */
                        uint16_t    bitmap_cache_size;    /* in blocks */
                        uint16_t    common_cache_size;    /* in blocks */
                } legacy;
                struct __attribute__ ((packed)) {
                        uint16_t            signature;
                        HfsExtDescriptor    location;
                } embedded;
        } old_new;
        uint32_t         extents_file_size;  /* in bytes, block size multiple */
        HfsExtDataRec    extents_file_rec;
        uint32_t         catalog_file_size;  /* in bytes, block size multiple */
        HfsExtDataRec    catalog_file_rec;
};
typedef struct _HfsMasterDirectoryBlock HfsMasterDirectoryBlock;

/* B*-Tree Node Descriptor */
struct __attribute__ ((packed)) _HfsNodeDescriptor {
        uint32_t        next;
        uint32_t        previous;
        int8_t          type;
        uint8_t         height;
        uint16_t        rec_nb;
        uint16_t        reserved;
};
typedef struct _HfsNodeDescriptor HfsNodeDescriptor;

/* Header record of a whole B*-Tree */
struct __attribute__ ((packed)) _HfsHeaderRecord {
        uint16_t        depth;
        uint32_t        root_node;
        uint32_t        leaf_records;
        uint32_t        first_leaf_node;
        uint32_t        last_leaf_node;
        uint16_t        node_size;
        uint16_t        max_key_len;
        uint32_t        total_nodes;
        uint32_t        free_nodes;
        int8_t          reserved[76];
};
typedef struct _HfsHeaderRecord HfsHeaderRecord;

/* Catalog key for B*-Tree lookup in the catalog file */
struct __attribute__ ((packed)) _HfsCatalogKey {
        uint8_t         key_length; /* length of the key without key_length */
        uint8_t         reserved;
        uint32_t        parent_ID;
        uint8_t         name_length;
        char            name[31];   /* in fact physicaly 1 upto 31 */
};
typedef struct _HfsCatalogKey HfsCatalogKey;

/* Extents overflow key for B*-Tree lookup */
struct __attribute__ ((packed)) _HfsExtentKey {
        uint8_t         key_length; /* length of the key without key_length */
        uint8_t         type;       /* data or ressource fork */
        uint32_t        file_ID;
        uint16_t        start;
};
typedef struct _HfsExtentKey HfsExtentKey;

/* Catalog subdata case directory */
struct __attribute__ ((packed)) _HfsDir {
        uint16_t        flags;
        uint16_t        valence;        /* number of files in this directory */
        uint32_t        dir_ID;
        uint32_t        create_date;
        uint32_t        modify_date;
        uint32_t        backup_date;
        int8_t          DInfo[16];      /* used by Finder, handle as reserved */
        int8_t          DXInfo[16];     /* used by Finder, handle as reserved */
        uint32_t        reserved[4];
};
typedef struct _HfsDir HfsDir;

/* Catalog subdata case file */
struct __attribute__ ((packed)) _HfsFile {
        int8_t          flags;
        int8_t          type;           /* should be 0 */
        int8_t          FInfo[16];      /* used by Finder, handle as reserved */
        uint32_t        file_ID;
        uint16_t        data_start_block;
        uint32_t        data_sz_byte;
        uint32_t        data_sz_block;
        uint16_t        res_start_block;
        uint32_t        res_sz_byte;
        uint32_t        res_sz_block;
        uint32_t        create_date;
        uint32_t        modify_date;
        uint32_t        backup_date;
        int8_t          FXInfo[16];     /* used by Finder, handle as reserved */
        uint16_t        clump_size;
        HfsExtDataRec   extents_data;
        HfsExtDataRec   extents_res;
        uint32_t        reserved;
};
typedef struct _HfsFile HfsFile;

/* Catalog subdata case directory thread */
struct __attribute__ ((packed)) _HfsDirTh {
        uint32_t        reserved[2];
        uint32_t        parent_ID;
        int8_t          name_length;
        char            name[31];
};
typedef struct _HfsDirTh HfsDirTh;

/* Catalog subdata case file thread */
typedef struct _HfsDirTh HfsFileTh;        /* same as directory thread */

/* Catalog data */
struct __attribute__ ((packed)) _HfsCatalog {
        int8_t          type;
        int8_t          reserved;
        union {
                HfsDir       dir;
                HfsFile      file;
                HfsDirTh     dir_th;
                HfsFileTh    file_th;
        } sel;
};
typedef struct _HfsCatalog HfsCatalog;



/* ------------------------------------ */
/* --      HFS+ DATA STRUCTURES      -- */
/* ------------------------------------ */

/* documented since 2004 in tn1150 */
struct __attribute__ ((packed)) _HfsPPerms {
        uint32_t        owner_ID;
        uint32_t        group_ID;
        uint32_t        permissions;
        uint32_t        special_devices;
};
typedef struct _HfsPPerms HfsPPerms;

/* HFS+ extent descriptor*/
struct __attribute__ ((packed)) _HfsPExtDescriptor {
        uint32_t        start_block;
        uint32_t        block_count;
};
typedef struct _HfsPExtDescriptor HfsPExtDescriptor;
typedef HfsPExtDescriptor HfsPExtDataRec[HFSP_EXT_NB];

/* HFS+ fork data structure */
struct __attribute__ ((packed)) _HfsPForkData {
        uint64_t        logical_size;
        uint32_t        clump_size;
        uint32_t        total_blocks;
        HfsPExtDataRec  extents;
};
typedef struct _HfsPForkData HfsPForkData;

/* HFS+ catalog node ID */
typedef uint32_t HfsPNodeID;

/* HFS+ file names */
typedef uint16_t unichar;
struct __attribute__ ((packed)) _HfsPUniStr255 {
        uint16_t        length;
        unichar         unicode[255];        /* 1 upto 255 */
};
typedef struct _HfsPUniStr255 HfsPUniStr255;

/* HFS+ volume header */
struct __attribute__ ((packed)) _HfsPVolumeHeader {
        uint16_t        signature;
        uint16_t        version;
        uint32_t        attributes;
        uint32_t        last_mounted_version;
        uint32_t        journal_info_block;

        uint32_t        create_date;
        uint32_t        modify_date;
        uint32_t        backup_date;
        uint32_t        checked_date;

        uint32_t        file_count;
        uint32_t        dir_count;

        uint32_t        block_size;
        uint32_t        total_blocks;
        uint32_t        free_blocks;

        uint32_t        next_allocation;
        uint32_t        res_clump_size;
        uint32_t        data_clump_size;
        HfsPNodeID      next_catalog_ID;

        uint32_t        write_count;
        uint64_t        encodings_bitmap;

        uint8_t         finder_info[32];

        HfsPForkData    allocation_file;
        HfsPForkData    extents_file;
        HfsPForkData    catalog_file;
        HfsPForkData    attributes_file;
        HfsPForkData    startup_file;
};
typedef struct _HfsPVolumeHeader HfsPVolumeHeader;

/* HFS+ B-Tree Node Descriptor. Same as HFS btree. */
struct __attribute__ ((packed)) _HfsPNodeDescriptor {
        uint32_t        next;
        uint32_t        previous;
        int8_t          type;
        uint8_t         height;
        uint16_t        rec_nb;
        uint16_t        reserved;
};
typedef struct _HfsPNodeDescriptor HfsPNodeDescriptor;

/* Header record of a whole HFS+ B-Tree. */
struct __attribute__ ((packed)) _HfsPHeaderRecord {
        uint16_t        depth;
        uint32_t        root_node;
        uint32_t        leaf_records;
        uint32_t        first_leaf_node;
        uint32_t        last_leaf_node;
        uint16_t        node_size;
        uint16_t        max_key_len;
        uint32_t        total_nodes;
        uint32_t        free_nodes;        /* same as hfs btree until here */
        uint16_t        reserved1;

        uint32_t        clump_size;
        uint8_t         btree_type;        /* must be 0 for HFS+ B-Tree */
        uint8_t         key_compare_type; /* hfsx => 0xCF = case folding */
                                          /*         0xBC = binary compare */
                                          /* otherwise, reserved */
        uint32_t        attributes;
        uint32_t        reserved3[16];
};
typedef struct _HfsPHeaderRecord HfsPHeaderRecord;

/* Catalog key for B-Tree lookup in the HFS+ catalog file */
struct __attribute__ ((packed)) _HfsPCatalogKey {
        uint16_t        key_length;
        HfsPNodeID      parent_ID;
        HfsPUniStr255   node_name;
};
typedef struct _HfsPCatalogKey HfsPCatalogKey;

/* HFS+ catalog subdata case dir */
struct __attribute__ ((packed)) _HfsPDir {
        uint16_t        flags;
        uint32_t        valence;
        HfsPNodeID      dir_ID;
        uint32_t        create_date;
        uint32_t        modify_date;
        uint32_t        attrib_mod_date;
        uint32_t        access_date;
        uint32_t        backup_date;
        HfsPPerms       permissions;
        int8_t          DInfo[16];        /* used by Finder, handle as reserved */
        int8_t          DXInfo[16];       /* used by Finder, handle as reserved */
        uint32_t        text_encoding;
        uint32_t        reserved;
};
typedef struct _HfsPDir HfsPDir;

/* HFS+ catalog subdata case file */
struct __attribute__ ((packed)) _HfsPFile {
        uint16_t        flags;
        uint32_t        reserved1;
        HfsPNodeID      file_ID;
        uint32_t        create_date;
        uint32_t        modify_date;
        uint32_t        attrib_mod_date;
        uint32_t        access_date;
        uint32_t        backup_date;
        HfsPPerms       permissions;
        int8_t          FInfo[16];        /* used by Finder, handle as reserved */
        int8_t          FXInfo[16];       /* used by Finder, handle as reserved */
        uint32_t        text_encoding;
        uint32_t        reserved2;

        HfsPForkData    data_fork;
        HfsPForkData    res_fork;
};
typedef struct _HfsPFile HfsPFile;

/* HFS+ catalog subdata case thread */
struct __attribute__ ((packed)) _HfsPThread {
        int16_t         reserved;
        HfsPNodeID      parent_ID;
        HfsPUniStr255   node_name;
};
typedef struct _HfsPThread HfsPDirTh;
typedef struct _HfsPThread HfsPFileTh;

/* HFS+ Catalog leaf data */
struct __attribute__ ((packed)) _HfsPCatalog {
        int16_t         type;
        union {
                HfsPDir         dir;
                HfsPFile        file;
                HfsPDirTh       dir_th;
                HfsPFileTh      file_th;
        } sel;
};
typedef struct _HfsPCatalog HfsPCatalog;

/* HFS+ extents file key */
struct __attribute__ ((packed)) _HfsPExtentKey {
        uint16_t        key_length;
        uint8_t         type;
        uint8_t         pad;
        HfsPNodeID      file_ID;
        uint32_t        start;
};
typedef struct _HfsPExtentKey HfsPExtentKey;

/* extent file data is HfsPExtDataRec */

/* Fork data attribute file */
struct __attribute__ ((packed)) _HfsPForkDataAttr {
        uint32_t        record_type;
        uint32_t        reserved;
        union __attribute__ ((packed)) {
                HfsPForkData        fork;
                HfsPExtDataRec      extents;
        } fork_res;
};
typedef struct _HfsPForkDataAttr HfsPForkDataAttr;


/* ----------- Journal data structures ----------- */

/* Info block : stored in a block # defined in the VH */
struct __attribute__ ((packed)) _HfsJJournalInfoBlock {
        uint32_t        flags;
        uint32_t        device_signature[8];
        uint64_t        offset;
        uint64_t        size;
        uint32_t        reserved[32];
};
typedef struct _HfsJJournalInfoBlock HfsJJournalInfoBlock;

struct __attribute__ ((packed)) _HfsJJournalHeader {
        uint32_t        magic;
        uint32_t        endian;
        uint64_t        start;
        uint64_t        end;
        uint64_t        size;
        uint32_t        blhdr_size;
        uint32_t        checksum;
        uint32_t        jhdr_size;
};
typedef struct _HfsJJournalHeader HfsJJournalHeader;

struct __attribute__ ((packed)) _HfsJBlockInfo {
        uint64_t        bnum;          /* sector number */
        uint32_t        bsize;         /* size in bytes */
        uint32_t        next;
};
typedef struct _HfsJBlockInfo HfsJBlockInfo;

struct __attribute__ ((packed)) _HfsJBlockListHeader {
        uint16_t        max_blocks;    /* reserved */
        uint16_t        num_blocks;
        uint32_t        bytes_used;
        uint32_t        checksum;
        uint32_t        pad;
        HfsJBlockInfo   binfo[];
};
typedef struct _HfsJBlockListHeader HfsJBlockListHeader;



/* ---------------------------------------- */
/* --      INTERNAL DATA STRUCTURES      -- */
/* ---------------------------------------- */

/* Data of an opened HFS file */
struct _HfsPrivateFile {
        PedSector       sect_nb;
        PedFileSystem*  fs;
        uint32_t        CNID;          /* disk order (BE) */
        HfsExtDataRec   first;         /* disk order (BE) */
        HfsExtDataRec   cache;         /* disk order (BE) */
        uint16_t        start_cache;   /* CPU order */
};
typedef struct _HfsPrivateFile HfsPrivateFile;

/* To store bad block list */
struct _HfsPrivateLinkExtent {
        HfsExtDescriptor                 extent;
        struct _HfsPrivateLinkExtent*    next;
};
typedef struct _HfsPrivateLinkExtent HfsPrivateLinkExtent;

/* HFS Filesystem specific data */
struct _HfsPrivateFSData {
        uint8_t                     alloc_map[(1<<16) / 8];
        HfsMasterDirectoryBlock*    mdb;
        HfsPrivateFile*             extent_file;
        HfsPrivateFile*             catalog_file;
        HfsPrivateLinkExtent*       bad_blocks_xtent_list;
        unsigned int                bad_blocks_xtent_nb;
        char                        bad_blocks_loaded;
};
typedef struct _HfsPrivateFSData HfsPrivateFSData;

/* Generic btree key */
struct __attribute__ ((packed)) _HfsPrivateGenericKey {
        uint8_t         key_length;
        uint8_t         key_content[1];                /* we use 1 as a minimum size */
};
typedef struct _HfsPrivateGenericKey HfsPrivateGenericKey;

/* ----- HFS+ ----- */

/* Data of an opened HFS file */
struct _HfsPPrivateFile {
        PedSector       sect_nb;
        PedFileSystem*  fs;
        HfsPNodeID      CNID;          /* disk order (BE) */
        HfsPExtDataRec  first;         /* disk order (BE) */
        HfsPExtDataRec  cache;         /* disk order (BE) */
        uint32_t        start_cache;   /* CPU order */
};
typedef struct _HfsPPrivateFile HfsPPrivateFile;

struct _HfsPPrivateExtent {
        PedSector       start_sector;
        PedSector       sector_count;
};
typedef struct _HfsPPrivateExtent HfsPPrivateExtent;

/* To store bad block list */
struct _HfsPPrivateLinkExtent {
        HfsPExtDescriptor                 extent;
        struct _HfsPPrivateLinkExtent*    next;
};
typedef struct _HfsPPrivateLinkExtent HfsPPrivateLinkExtent;

/* HFS+ file system specific data */
struct _HfsPPrivateFSData {
        PedFileSystem*          wrapper;      /* NULL if hfs+ is not embedded */
        PedGeometry*            plus_geom;    /* Geometry of HFS+ _volume_ */
        uint8_t*                alloc_map;
        uint8_t*                dirty_alloc_map;
        HfsPVolumeHeader*       vh;
        HfsPPrivateFile*        extents_file;
        HfsPPrivateFile*        catalog_file;
        HfsPPrivateFile*        attributes_file;
        HfsPPrivateFile*        allocation_file;
        HfsPPrivateLinkExtent*  bad_blocks_xtent_list;
        uint32_t                jib_start_block;
        uint32_t                jl_start_block;
        unsigned int            bad_blocks_xtent_nb;
        char                    bad_blocks_loaded;
        char                    free_geom;    /* 1 = plus_geom must be freed */
};
typedef struct _HfsPPrivateFSData HfsPPrivateFSData;

/* Generic + btree key */
struct __attribute__ ((packed)) _HfsPPrivateGenericKey {
        uint16_t        key_length;
        uint8_t         key_content[1];       /* we use 1 as a minimum size */
};
typedef struct _HfsPPrivateGenericKey HfsPPrivateGenericKey;

/* ---- common ---- */

/* node and lead record reference for a BTree search */
struct _HfsCPrivateLeafRec {
        unsigned int    node_size;     /* in sectors */
        unsigned int    node_number;
        unsigned int    record_pos;
        unsigned int    record_number;
};
typedef struct _HfsCPrivateLeafRec HfsCPrivateLeafRec;

extern uint8_t*    hfs_block;
extern uint8_t*    hfsp_block;
extern unsigned    hfs_block_count;
extern unsigned    hfsp_block_count;

#endif /* _HFS_H */