2007-03-22 16:21:28 +03:00
|
|
|
/* $NetBSD: libhfs.h,v 1.3 2007/03/22 13:21:28 dillo Exp $ */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/*-
|
|
|
|
* Copyright (c) 2005, 2007 The NetBSD Foundation, Inc.
|
|
|
|
* All rights reserved.
|
|
|
|
*
|
|
|
|
* This code is derived from software contributed to The NetBSD Foundation
|
2007-03-22 16:21:28 +03:00
|
|
|
* by Yevgeny Binder, Dieter Baron, and Pelle Johansson.
|
2007-03-06 03:10:34 +03:00
|
|
|
*
|
|
|
|
* Redistribution and use in source and binary forms, with or without
|
|
|
|
* modification, are permitted provided that the following conditions
|
|
|
|
* are met:
|
|
|
|
* 1. Redistributions of source code must retain the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer.
|
|
|
|
* 2. Redistributions in binary form must reproduce the above copyright
|
|
|
|
* notice, this list of conditions and the following disclaimer in the
|
|
|
|
* documentation and/or other materials provided with the distribution.
|
|
|
|
*
|
|
|
|
* THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
|
|
|
|
* ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
|
|
|
|
* TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
|
|
|
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
|
|
|
|
* BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
|
|
*/
|
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
#ifndef _FS_HFS_LIBHFS_H_
|
|
|
|
#define _FS_HFS_LIBHFS_H_
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
#include <sys/endian.h>
|
|
|
|
#include <sys/param.h>
|
|
|
|
#include <sys/mount.h> /* needs to go after sys/param.h or compile fails */
|
|
|
|
#include <sys/types.h>
|
|
|
|
#if defined(_KERNEL)
|
|
|
|
#include <sys/kernel.h>
|
|
|
|
#include <sys/systm.h>
|
|
|
|
#include <machine/stdarg.h>
|
|
|
|
#include <sys/fcntl.h>
|
|
|
|
#endif /* defined(_KERNEL) */
|
|
|
|
|
|
|
|
#if !defined(_KERNEL) && !defined(STANDALONE)
|
|
|
|
#include <fcntl.h>
|
|
|
|
#include <iconv.h>
|
|
|
|
#include <stdarg.h>
|
|
|
|
#include <stdint.h>
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <unistd.h>
|
|
|
|
#endif /* !defined(_KERNEL) && !defined(STANDALONE) */
|
|
|
|
|
|
|
|
#ifndef va_list
|
|
|
|
#define va_list _BSD_VA_LIST_
|
|
|
|
#endif /* !va_list */
|
|
|
|
|
|
|
|
#define max(A,B) ((A) > (B) ? (A):(B))
|
|
|
|
#define min(A,B) ((A) < (B) ? (A):(B))
|
|
|
|
|
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
/* Macros to handle errors in this library. Not recommended outside libhfs.c */
|
|
|
|
#define HFS_LIBERR(format, ...) \
|
|
|
|
do{ hfslib_error(format, __FILE__, __LINE__ , ##__VA_ARGS__); \
|
2007-03-06 03:10:34 +03:00
|
|
|
goto error; } while(/*CONSTCOND*/ 0)
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
#pragma mark Constants (on-disk)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_SIG_HFSP = 0x482B, /* 'H+' */
|
|
|
|
HFS_SIG_HFSX = 0x4858, /* 'HX' */
|
|
|
|
HFS_SIG_HFS = 0x4244 /* 'BD' */
|
2007-03-06 03:10:34 +03:00
|
|
|
}; /* volume signatures */
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
|
|
|
/* bits 0-6 are reserved */
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_VOL_HWLOCK = 7,
|
|
|
|
HFS_VOL_UNMOUNTED = 8,
|
|
|
|
HFS_VOL_BADBLOCKS = 9,
|
|
|
|
HFS_VOL_NOCACHE = 10,
|
|
|
|
HFS_VOL_DIRTY = 11,
|
|
|
|
HFS_VOL_CNIDS_RECYCLED = 12,
|
|
|
|
HFS_VOL_JOURNALED = 13,
|
2007-03-06 03:10:34 +03:00
|
|
|
/* bit 14 is reserved */
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_VOL_SWLOCK = 15
|
2007-03-06 03:10:34 +03:00
|
|
|
/* bits 16-31 are reserved */
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_volume_attribute_bit; /* volume header attribute bits */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_LEAFNODE = -1,
|
|
|
|
HFS_INDEXNODE = 0,
|
|
|
|
HFS_HEADERNODE = 1,
|
|
|
|
HFS_MAPNODE = 2
|
|
|
|
} hfs_node_kind; /* btree node kinds */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_BAD_CLOSE_MASK = 0x00000001,
|
|
|
|
HFS_BIG_KEYS_MASK = 0x00000002,
|
|
|
|
HFS_VAR_INDEX_KEYS_MASK = 0x00000004
|
2007-03-06 03:10:34 +03:00
|
|
|
}; /* btree header attribute masks */
|
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_CNID_ROOT_PARENT = 1,
|
|
|
|
HFS_CNID_ROOT_FOLDER = 2,
|
|
|
|
HFS_CNID_EXTENTS = 3,
|
|
|
|
HFS_CNID_CATALOG = 4,
|
|
|
|
HFS_CNID_BADBLOCKS = 5,
|
|
|
|
HFS_CNID_ALLOCATION = 6,
|
|
|
|
HFS_CNID_STARTUP = 7,
|
|
|
|
HFS_CNID_ATTRIBUTES = 8,
|
2007-03-06 03:10:34 +03:00
|
|
|
/* CNIDs 9-13 are reserved */
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_CNID_REPAIR = 14,
|
|
|
|
HFS_CNID_TEMP = 15,
|
|
|
|
HFS_CNID_USER = 16
|
|
|
|
} hfs_special_cnid; /* special CNID values */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_REC_FLDR = 0x0001,
|
|
|
|
HFS_REC_FILE = 0x0002,
|
|
|
|
HFS_REC_FLDR_THREAD = 0x0003,
|
|
|
|
HFS_REC_FILE_THREAD = 0x0004
|
|
|
|
} hfs_catalog_rec_kind; /* catalog record types */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_JOURNAL_ON_DISK_MASK = 0x00000001, /* journal on same volume */
|
|
|
|
HFS_JOURNAL_ON_OTHER_MASK = 0x00000002, /* journal elsewhere */
|
|
|
|
HFS_JOURNAL_NEEDS_INIT_MASK = 0x00000004
|
2007-03-06 03:10:34 +03:00
|
|
|
}; /* journal flag masks */
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_JOURNAL_HEADER_MAGIC = 0x4a4e4c78,
|
|
|
|
HFS_JOURNAL_ENDIAN_MAGIC = 0x12345678
|
2007-03-06 03:10:34 +03:00
|
|
|
}; /* journal magic numbers */
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_DATAFORK = 0x00,
|
|
|
|
HFS_RSRCFORK = 0xFF
|
2007-03-06 03:10:34 +03:00
|
|
|
}; /* common fork types */
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_KEY_CASEFOLD = 0xCF,
|
|
|
|
HFS_KEY_BINARY = 0XBC
|
2007-03-06 03:10:34 +03:00
|
|
|
}; /* catalog key comparison method types */
|
|
|
|
|
|
|
|
enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_MIN_CAT_KEY_LEN = 6,
|
|
|
|
HFS_MAX_CAT_KEY_LEN = 516,
|
|
|
|
HFS_MAX_EXT_KEY_LEN = 10
|
2007-03-06 03:10:34 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_HARD_LINK_FILE_TYPE = 0x686C6E6B, /* 'hlnk' */
|
|
|
|
HFS_HFSLUS_CREATOR = 0x6866732B /* 'hfs+' */
|
2007-03-06 03:10:34 +03:00
|
|
|
};
|
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Constants (custom)
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
/* number of bytes between start of volume and volume header */
|
2007-03-06 14:28:44 +03:00
|
|
|
#define HFS_VOLUME_HEAD_RESERVE_SIZE 1024
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef enum
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
HFS_CATALOG_FILE = 1,
|
|
|
|
HFS_EXTENTS_FILE = 2,
|
|
|
|
HFS_ATTRIBUTES_FILE = 3
|
|
|
|
} hfs_btree_file_type; /* btree file kinds */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark On-Disk Types (Mac OS specific)
|
|
|
|
#endif
|
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
typedef uint32_t hfs_macos_type_code; /* four 1-byte char field */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t v;
|
|
|
|
int16_t h;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_macos_point_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t t; /* top */
|
|
|
|
int16_t l; /* left */
|
|
|
|
int16_t b; /* bottom */
|
|
|
|
int16_t r; /* right */
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_macos_rect_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_macos_type_code file_type;
|
|
|
|
hfs_macos_type_code file_creator;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint16_t finder_flags;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_macos_point_t location;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint16_t reserved;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_macos_file_info_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t reserved[4];
|
|
|
|
uint16_t extended_finder_flags;
|
|
|
|
int16_t reserved2;
|
|
|
|
int32_t put_away_folder_cnid;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_macos_extended_file_info_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_macos_rect_t window_bounds;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint16_t finder_flags;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_macos_point_t location;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint16_t reserved;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_macos_folder_info_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_macos_point_t scroll_position;
|
2007-03-06 03:10:34 +03:00
|
|
|
int32_t reserved;
|
|
|
|
uint16_t extended_finder_flags;
|
|
|
|
int16_t reserved2;
|
|
|
|
int32_t put_away_folder_cnid;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_macos_extended_folder_info_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark On-Disk Types
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef uint16_t unichar_t;
|
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
typedef uint32_t hfs_cnid_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t length;
|
|
|
|
unichar_t unicode[255];
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_unistr255_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t start_block;
|
|
|
|
uint32_t block_count;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_extent_descriptor_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
typedef hfs_extent_descriptor_t hfs_extent_record_t[8];
|
2007-03-06 03:10:34 +03:00
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
typedef struct hfs_fork_t
|
2007-03-06 03:10:34 +03:00
|
|
|
{
|
|
|
|
uint64_t logical_size;
|
|
|
|
uint32_t clump_size;
|
|
|
|
uint32_t total_blocks;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_extent_record_t extents;
|
|
|
|
} hfs_fork_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t signature;
|
|
|
|
uint16_t version;
|
|
|
|
uint32_t attributes;
|
|
|
|
uint32_t last_mounting_version;
|
|
|
|
uint32_t journal_info_block;
|
|
|
|
|
|
|
|
uint32_t date_created;
|
|
|
|
uint32_t date_modified;
|
|
|
|
uint32_t date_backedup;
|
|
|
|
uint32_t date_checked;
|
|
|
|
|
|
|
|
uint32_t file_count;
|
|
|
|
uint32_t folder_count;
|
|
|
|
|
|
|
|
uint32_t block_size;
|
|
|
|
uint32_t total_blocks;
|
|
|
|
uint32_t free_blocks;
|
|
|
|
|
|
|
|
uint32_t next_alloc_block;
|
|
|
|
uint32_t rsrc_clump_size;
|
|
|
|
uint32_t data_clump_size;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_cnid_t next_cnid;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
uint32_t write_count;
|
|
|
|
uint64_t encodings;
|
|
|
|
|
|
|
|
uint32_t finder_info[8];
|
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_fork_t allocation_file;
|
|
|
|
hfs_fork_t extents_file;
|
|
|
|
hfs_fork_t catalog_file;
|
|
|
|
hfs_fork_t attributes_file;
|
|
|
|
hfs_fork_t startup_file;
|
|
|
|
} hfs_volume_header_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t flink;
|
|
|
|
uint32_t blink;
|
|
|
|
int8_t kind;
|
|
|
|
uint8_t height;
|
|
|
|
uint16_t num_recs;
|
|
|
|
uint16_t reserved;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_node_descriptor_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t tree_depth;
|
|
|
|
uint32_t root_node;
|
|
|
|
uint32_t leaf_recs;
|
|
|
|
uint32_t first_leaf;
|
|
|
|
uint32_t last_leaf;
|
|
|
|
uint16_t node_size;
|
|
|
|
uint16_t max_key_len;
|
|
|
|
uint32_t total_nodes;
|
|
|
|
uint32_t free_nodes;
|
|
|
|
uint16_t reserved;
|
|
|
|
uint32_t clump_size; /* misaligned */
|
|
|
|
uint8_t btree_type;
|
|
|
|
uint8_t keycomp_type;
|
|
|
|
uint32_t attributes; /* long aligned again */
|
|
|
|
uint32_t reserved2[16];
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_header_record_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t key_len;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_cnid_t parent_cnid;
|
|
|
|
hfs_unistr255_t name;
|
|
|
|
} hfs_catalog_key_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t key_length;
|
|
|
|
uint8_t fork_type;
|
|
|
|
uint8_t padding;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_cnid_t file_cnid;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint32_t start_block;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_extent_key_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t owner_id;
|
|
|
|
uint32_t group_id;
|
|
|
|
uint8_t admin_flags;
|
|
|
|
uint8_t owner_flags;
|
|
|
|
uint16_t file_mode;
|
|
|
|
union
|
|
|
|
{
|
|
|
|
uint32_t inode_num;
|
|
|
|
uint32_t link_count;
|
|
|
|
uint32_t raw_device;
|
|
|
|
} special;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_bsd_data_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t rec_type;
|
|
|
|
uint16_t flags;
|
|
|
|
uint32_t valence;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_cnid_t cnid;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint32_t date_created;
|
|
|
|
uint32_t date_content_mod;
|
|
|
|
uint32_t date_attrib_mod;
|
|
|
|
uint32_t date_accessed;
|
|
|
|
uint32_t date_backedup;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_bsd_data_t bsd;
|
|
|
|
hfs_macos_folder_info_t user_info;
|
|
|
|
hfs_macos_extended_folder_info_t finder_info;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint32_t text_encoding;
|
|
|
|
uint32_t reserved;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_folder_record_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t rec_type;
|
|
|
|
uint16_t flags;
|
|
|
|
uint32_t reserved;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_cnid_t cnid;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint32_t date_created;
|
|
|
|
uint32_t date_content_mod;
|
|
|
|
uint32_t date_attrib_mod;
|
|
|
|
uint32_t date_accessed;
|
|
|
|
uint32_t date_backedup;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_bsd_data_t bsd;
|
|
|
|
hfs_macos_file_info_t user_info;
|
|
|
|
hfs_macos_extended_file_info_t finder_info;
|
2007-03-06 03:10:34 +03:00
|
|
|
uint32_t text_encoding;
|
|
|
|
uint32_t reserved2;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_fork_t data_fork;
|
|
|
|
hfs_fork_t rsrc_fork;
|
|
|
|
} hfs_file_record_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
int16_t rec_type;
|
|
|
|
int16_t reserved;
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_cnid_t parent_cnid;
|
|
|
|
hfs_unistr255_t name;
|
|
|
|
} hfs_thread_record_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t flags;
|
|
|
|
uint32_t device_signature[8];
|
|
|
|
uint64_t offset;
|
|
|
|
uint64_t size;
|
|
|
|
uint64_t reserved[32];
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_journal_info_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint32_t magic;
|
|
|
|
uint32_t endian;
|
|
|
|
uint64_t start;
|
|
|
|
uint64_t end;
|
|
|
|
uint64_t size;
|
|
|
|
uint32_t blocklist_header_size;
|
|
|
|
uint32_t checksum;
|
|
|
|
uint32_t journal_header_size;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_journal_header_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
2007-03-22 16:21:28 +03:00
|
|
|
/* plain HFS structures needed for hfs wrapper support */
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t start_block;
|
|
|
|
uint16_t block_count;
|
|
|
|
} hfs_hfs_extent_descriptor_t;
|
|
|
|
|
|
|
|
typedef hfs_hfs_extent_descriptor_t hfs_hfs_extent_record_t[3];
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
uint16_t signature;
|
|
|
|
uint32_t date_created;
|
|
|
|
uint32_t date_modified;
|
|
|
|
uint16_t attributes;
|
|
|
|
uint16_t root_file_count;
|
|
|
|
uint16_t volume_bitmap;
|
|
|
|
uint16_t next_alloc_block;
|
|
|
|
uint16_t total_blocks;
|
|
|
|
uint32_t block_size;
|
|
|
|
uint32_t clump_size;
|
|
|
|
uint16_t first_block;
|
|
|
|
hfs_cnid_t next_cnid;
|
|
|
|
uint16_t free_blocks;
|
|
|
|
unsigned char volume_name[28];
|
|
|
|
uint32_t date_backedup;
|
|
|
|
uint16_t backup_seqnum;
|
|
|
|
uint32_t write_count;
|
|
|
|
uint32_t extents_clump_size;
|
|
|
|
uint32_t catalog_clump_size;
|
|
|
|
uint16_t root_folder_count;
|
|
|
|
uint32_t file_count;
|
|
|
|
uint32_t folder_count;
|
|
|
|
uint32_t finder_info[8];
|
|
|
|
uint16_t embedded_signature;
|
|
|
|
hfs_hfs_extent_descriptor_t embedded_extent;
|
|
|
|
uint32_t extents_size;
|
|
|
|
hfs_hfs_extent_record_t extents_extents;
|
|
|
|
uint32_t catalog_size;
|
|
|
|
hfs_hfs_extent_record_t catalog_extents;
|
|
|
|
} hfs_hfs_master_directory_block_t;
|
|
|
|
|
2007-03-06 03:10:34 +03:00
|
|
|
#if 0
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Custom Types
|
|
|
|
#endif
|
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_volume_header_t vh; /* volume header */
|
|
|
|
hfs_header_record_t chr; /* catalog file header node record*/
|
|
|
|
hfs_header_record_t ehr; /* extent overflow file header node record*/
|
2007-03-06 03:10:34 +03:00
|
|
|
uint8_t catkeysizefieldsize; /* size of catalog file key_len field in
|
|
|
|
* bytes (1 or 2); always 2 for HFS+ */
|
|
|
|
uint8_t extkeysizefieldsize; /* size of extent file key_len field in
|
|
|
|
* bytes (1 or 2); always 2 for HFS+ */
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_unistr255_t name; /* volume name */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/* pointer to catalog file key comparison function */
|
|
|
|
int (*keycmp) (const void*, const void*);
|
|
|
|
|
|
|
|
int journaled; /* 1 if volume is journaled, else 0 */
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_journal_info_t jib; /* journal info block */
|
|
|
|
hfs_journal_header_t jh; /* journal header */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
2007-03-22 16:21:28 +03:00
|
|
|
uint64_t offset; /* offset, in bytes, of HFS+ volume */
|
2007-03-06 03:10:34 +03:00
|
|
|
int readonly; /* 0 if mounted r/w, 1 if mounted r/o */
|
|
|
|
void* cbdata; /* application-specific data; allocated, defined and
|
|
|
|
* used (if desired) by the program, usually within
|
|
|
|
* callback routines */
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_volume;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef union
|
|
|
|
{
|
|
|
|
/* for leaf nodes */
|
|
|
|
int16_t type; /* type of record: folder, file, or thread */
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_folder_record_t folder;
|
|
|
|
hfs_file_record_t file;
|
|
|
|
hfs_thread_record_t thread;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/* for pointer nodes */
|
|
|
|
/* (using this large union for just one tiny field is not memory-efficient,
|
|
|
|
* so change this if it becomes problematic) */
|
|
|
|
uint32_t child; /* node number of this node's child node */
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_catalog_keyed_record_t;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/*
|
2007-03-06 14:28:44 +03:00
|
|
|
* These arguments are passed among libhfs without any inspection. This struct
|
|
|
|
* is accepted by all public functions of libhfs, and passed to each callback.
|
2007-03-06 03:10:34 +03:00
|
|
|
* An application dereferences each pointer to its own specific struct of
|
|
|
|
* arguments. Callbacks must be prepared to deal with NULL values for any of
|
|
|
|
* these fields (by providing default values to be used in lieu of that
|
|
|
|
* argument). However, a NULL pointer to this struct is an error.
|
|
|
|
*
|
|
|
|
* It was decided to make one unified argument structure, rather than many
|
|
|
|
* separate, operand-specific structures, because, when this structure is passed
|
2007-03-06 14:28:44 +03:00
|
|
|
* to a public function (e.g., hfslib_open_volume()), the function may make
|
2007-03-06 03:10:34 +03:00
|
|
|
* several calls (and subcalls) to various facilities, e.g., read(), malloc(),
|
|
|
|
* and free(), all of which require their own particular arguments. The
|
|
|
|
* facilities to be used are quite impractical to foreshadow, so the application
|
|
|
|
* takes care of all possible calls at once. This also reinforces the idea that
|
|
|
|
* a public call is an umbrella to a set of system calls, and all of these calls
|
|
|
|
* must be passed arguments which do not change within the context of this
|
|
|
|
* umbrella. (E.g., if a public function makes two calls to read(), one call
|
|
|
|
* should not be passed a uid of root and the other passed a uid of daemon.)
|
|
|
|
*/
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
/* The 'error' function does not take an argument. All others do. */
|
|
|
|
|
|
|
|
void* allocmem;
|
|
|
|
void* reallocmem;
|
|
|
|
void* freemem;
|
|
|
|
void* openvol;
|
|
|
|
void* closevol;
|
|
|
|
void* read;
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_callback_args;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
typedef struct
|
|
|
|
{
|
|
|
|
/* error(in_format, in_file, in_line, in_args) */
|
|
|
|
void (*error) (const char*, const char*, int, va_list);
|
|
|
|
|
|
|
|
/* allocmem(in_size, cbargs) */
|
2007-03-06 14:28:44 +03:00
|
|
|
void* (*allocmem) (size_t, hfs_callback_args*);
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/* reallocmem(in_ptr, in_size, cbargs) */
|
2007-03-06 14:28:44 +03:00
|
|
|
void* (*reallocmem) (void*, size_t, hfs_callback_args*);
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/* freemem(in_ptr, cbargs) */
|
2007-03-06 14:28:44 +03:00
|
|
|
void (*freemem) (void*, hfs_callback_args*);
|
2007-03-06 03:10:34 +03:00
|
|
|
|
2007-03-22 16:21:28 +03:00
|
|
|
/* openvol(in_volume, in_devicepath, cbargs)
|
2007-03-06 03:10:34 +03:00
|
|
|
* returns 0 on success */
|
2007-03-22 16:21:28 +03:00
|
|
|
int (*openvol) (hfs_volume*, const char*, hfs_callback_args*);
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/* closevol(in_volume, cbargs) */
|
2007-03-06 14:28:44 +03:00
|
|
|
void (*closevol) (hfs_volume*, hfs_callback_args*);
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/* read(in_volume, out_buffer, in_length, in_offset, cbargs)
|
|
|
|
* returns 0 on success */
|
2007-03-06 14:28:44 +03:00
|
|
|
int (*read) (hfs_volume*, void*, uint64_t, uint64_t,
|
|
|
|
hfs_callback_args*);
|
2007-03-06 03:10:34 +03:00
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
} hfs_callbacks;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_callbacks hfs_gcb; /* global callbacks */
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
/*
|
|
|
|
* global case folding table
|
2007-03-06 14:28:44 +03:00
|
|
|
* (lazily initialized; see comments at bottom of hfs_open_volume())
|
2007-03-06 03:10:34 +03:00
|
|
|
*/
|
2007-03-06 14:28:44 +03:00
|
|
|
unichar_t* hfs_gcft;
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
#if 0
|
|
|
|
#pragma mark -
|
|
|
|
#pragma mark Functions
|
|
|
|
#endif
|
|
|
|
|
2007-03-06 14:28:44 +03:00
|
|
|
void hfslib_init(hfs_callbacks*);
|
|
|
|
void hfslib_done(void);
|
|
|
|
void hfslib_init_cbargs(hfs_callback_args*);
|
|
|
|
|
2007-03-22 16:21:28 +03:00
|
|
|
int hfslib_open_volume(const char*, int, hfs_volume*,
|
2007-03-06 14:28:44 +03:00
|
|
|
hfs_callback_args*);
|
|
|
|
void hfslib_close_volume(hfs_volume*, hfs_callback_args*);
|
|
|
|
|
|
|
|
int hfslib_path_to_cnid(hfs_volume*, hfs_cnid_t, char**, uint16_t*,
|
|
|
|
hfs_callback_args*);
|
|
|
|
hfs_cnid_t hfslib_find_parent_thread(hfs_volume*, hfs_cnid_t,
|
|
|
|
hfs_thread_record_t*, hfs_callback_args*);
|
|
|
|
int hfslib_find_catalog_record_with_cnid(hfs_volume*, hfs_cnid_t,
|
|
|
|
hfs_catalog_keyed_record_t*, hfs_catalog_key_t*, hfs_callback_args*);
|
|
|
|
int hfslib_find_catalog_record_with_key(hfs_volume*, hfs_catalog_key_t*,
|
|
|
|
hfs_catalog_keyed_record_t*, hfs_callback_args*);
|
|
|
|
int hfslib_find_extent_record_with_key(hfs_volume*, hfs_extent_key_t*,
|
|
|
|
hfs_extent_record_t*, hfs_callback_args*);
|
|
|
|
int hfslib_get_directory_contents(hfs_volume*, hfs_cnid_t,
|
|
|
|
hfs_catalog_keyed_record_t**, hfs_unistr255_t**, uint32_t*,
|
|
|
|
hfs_callback_args*);
|
|
|
|
int hfslib_is_journal_clean(hfs_volume*);
|
|
|
|
int hfslib_is_private_file(hfs_catalog_key_t*);
|
|
|
|
|
|
|
|
int hfslib_get_hardlink(hfs_volume *, uint32_t,
|
|
|
|
hfs_catalog_keyed_record_t *, hfs_callback_args *);
|
|
|
|
|
|
|
|
size_t hfslib_read_volume_header(void*, hfs_volume_header_t*);
|
2007-03-22 16:21:28 +03:00
|
|
|
size_t hfslib_read_master_directory_block(void*,
|
|
|
|
hfs_hfs_master_directory_block_t*);
|
2007-03-06 14:28:44 +03:00
|
|
|
size_t hfslib_reada_node(void*, hfs_node_descriptor_t*, void***, uint16_t**,
|
|
|
|
hfs_btree_file_type, hfs_volume*, hfs_callback_args*);
|
|
|
|
size_t hfslib_reada_node_offsets(void*, uint16_t*);
|
|
|
|
size_t hfslib_read_header_node(void**, uint16_t*, uint16_t,
|
|
|
|
hfs_header_record_t*, void*, void*);
|
|
|
|
size_t hfslib_read_catalog_keyed_record(void*, hfs_catalog_keyed_record_t*,
|
|
|
|
int16_t*, hfs_catalog_key_t*, hfs_volume*);
|
|
|
|
size_t hfslib_read_extent_record(void*, hfs_extent_record_t*, hfs_node_kind,
|
|
|
|
hfs_extent_key_t*, hfs_volume*);
|
|
|
|
void hfslib_free_recs(void***, uint16_t**, uint16_t*, hfs_callback_args*);
|
|
|
|
|
|
|
|
size_t hfslib_read_fork_descriptor(void*, hfs_fork_t*);
|
|
|
|
size_t hfslib_read_extent_descriptors(void*, hfs_extent_record_t*);
|
|
|
|
size_t hfslib_read_unistr255(void*, hfs_unistr255_t*);
|
|
|
|
size_t hfslib_read_bsd_data(void*, hfs_bsd_data_t*);
|
|
|
|
size_t hfslib_read_file_userinfo(void*, hfs_macos_file_info_t*);
|
|
|
|
size_t hfslib_read_file_finderinfo(void*, hfs_macos_extended_file_info_t*);
|
|
|
|
size_t hfslib_read_folder_userinfo(void*, hfs_macos_folder_info_t*);
|
|
|
|
size_t hfslib_read_folder_finderinfo(void*, hfs_macos_extended_folder_info_t*);
|
|
|
|
size_t hfslib_read_journal_info(void*, hfs_journal_info_t*);
|
|
|
|
size_t hfslib_read_journal_header(void*, hfs_journal_header_t*);
|
|
|
|
|
|
|
|
uint16_t hfslib_make_catalog_key(hfs_cnid_t, uint16_t, unichar_t*,
|
|
|
|
hfs_catalog_key_t*);
|
|
|
|
uint16_t hfslib_make_extent_key(hfs_cnid_t, uint8_t, uint32_t,
|
|
|
|
hfs_extent_key_t*);
|
|
|
|
uint16_t hfslib_get_file_extents(hfs_volume*, hfs_cnid_t, uint8_t,
|
|
|
|
hfs_extent_descriptor_t**, hfs_callback_args*);
|
|
|
|
int hfslib_readd_with_extents(hfs_volume*, void*, uint64_t*, uint64_t,
|
|
|
|
uint64_t, hfs_extent_descriptor_t*, uint16_t, hfs_callback_args*);
|
|
|
|
|
|
|
|
int hfslib_compare_catalog_keys_cf(const void*, const void*);
|
|
|
|
int hfslib_compare_catalog_keys_bc(const void*, const void*);
|
|
|
|
int hfslib_compare_extent_keys(const void*, const void*);
|
2007-03-06 03:10:34 +03:00
|
|
|
|
|
|
|
|
|
|
|
/* callback wrappers */
|
2007-03-06 14:28:44 +03:00
|
|
|
void hfslib_error(const char*, const char*, int, ...) __attribute__ ((format (printf, 1, 4)));
|
|
|
|
void* hfslib_malloc(size_t, hfs_callback_args*);
|
|
|
|
void* hfslib_realloc(void*, size_t, hfs_callback_args*);
|
|
|
|
void hfslib_free(void*, hfs_callback_args*);
|
2007-03-22 16:21:28 +03:00
|
|
|
int hfslib_openvoldevice(hfs_volume*, const char*, hfs_callback_args*);
|
2007-03-06 14:28:44 +03:00
|
|
|
void hfslib_closevoldevice(hfs_volume*, hfs_callback_args*);
|
|
|
|
int hfslib_readd(hfs_volume*, void*, uint64_t, uint64_t, hfs_callback_args*);
|
|
|
|
|
|
|
|
#endif /* !_FS_HFS_LIBHFS_H_ */
|