summaryrefslogtreecommitdiffstats
path: root/include/grub/hfsplus.h
diff options
context:
space:
mode:
Diffstat (limited to 'include/grub/hfsplus.h')
-rw-r--r--include/grub/hfsplus.h259
1 files changed, 259 insertions, 0 deletions
diff --git a/include/grub/hfsplus.h b/include/grub/hfsplus.h
new file mode 100644
index 0000000..e14dd31
--- /dev/null
+++ b/include/grub/hfsplus.h
@@ -0,0 +1,259 @@
+/*
+ * GRUB -- GRand Unified Bootloader
+ * Copyright (C) 2005,2006,2007,2008,2009,2012,2013 Free Software Foundation, Inc.
+ *
+ * GRUB 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.
+ *
+ * GRUB 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 GRUB. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <grub/types.h>
+#include <grub/disk.h>
+
+#define GRUB_HFSPLUS_MAGIC 0x482B
+#define GRUB_HFSPLUSX_MAGIC 0x4858
+#define GRUB_HFSPLUS_SBLOCK 2
+
+/* A HFS+ extent. */
+struct grub_hfsplus_extent
+{
+ /* The first block of a file on disk. */
+ grub_uint32_t start;
+ /* The amount of blocks described by this extent. */
+ grub_uint32_t count;
+} GRUB_PACKED;
+
+/* The descriptor of a fork. */
+struct grub_hfsplus_forkdata
+{
+ grub_uint64_t size;
+ grub_uint32_t clumpsize;
+ grub_uint32_t blocks;
+ struct grub_hfsplus_extent extents[8];
+} GRUB_PACKED;
+
+/* The HFS+ Volume Header. */
+struct grub_hfsplus_volheader
+{
+ grub_uint16_t magic;
+ grub_uint16_t version;
+ grub_uint32_t attributes;
+ grub_uint8_t unused1[12];
+ grub_uint32_t utime;
+ grub_uint8_t unused2[16];
+ grub_uint32_t blksize;
+ grub_uint8_t unused3[36];
+
+ grub_uint32_t ppc_bootdir;
+ grub_uint32_t intel_bootfile;
+ /* Folder opened when disk is mounted. Unused by GRUB. */
+ grub_uint32_t showfolder;
+ grub_uint32_t os9folder;
+ grub_uint8_t unused4[4];
+ grub_uint32_t osxfolder;
+
+ grub_uint64_t num_serial;
+ struct grub_hfsplus_forkdata allocations_file;
+ struct grub_hfsplus_forkdata extents_file;
+ struct grub_hfsplus_forkdata catalog_file;
+ struct grub_hfsplus_forkdata attr_file;
+ struct grub_hfsplus_forkdata startup_file;
+} GRUB_PACKED;
+
+struct grub_hfsplus_compress_index
+{
+ grub_uint32_t start;
+ grub_uint32_t size;
+};
+
+struct grub_hfsplus_file
+{
+ struct grub_hfsplus_data *data;
+ struct grub_hfsplus_extent extents[8];
+ struct grub_hfsplus_extent resource_extents[8];
+ grub_uint64_t size;
+ grub_uint64_t resource_size;
+ grub_uint32_t fileid;
+ grub_int32_t mtime;
+ int compressed;
+ char *cbuf;
+ void *file;
+ struct grub_hfsplus_compress_index *compress_index;
+ grub_uint32_t cbuf_block;
+ grub_uint32_t compress_index_size;
+};
+
+struct grub_hfsplus_btree
+{
+ grub_uint32_t root;
+ grub_size_t nodesize;
+
+ /* Catalog file node. */
+ struct grub_hfsplus_file file;
+};
+
+/* Information about a "mounted" HFS+ filesystem. */
+struct grub_hfsplus_data
+{
+ struct grub_hfsplus_volheader volheader;
+ grub_disk_t disk;
+
+ unsigned int log2blksize;
+
+ struct grub_hfsplus_btree catalog_tree;
+ struct grub_hfsplus_btree extoverflow_tree;
+ struct grub_hfsplus_btree attr_tree;
+
+ int extoverflow_tree_ready;
+
+ struct grub_hfsplus_file dirroot;
+ struct grub_hfsplus_file opened_file;
+
+ /* This is the offset into the physical disk for an embedded HFS+
+ filesystem (one inside a plain HFS wrapper). */
+ grub_disk_addr_t embedded_offset;
+ int case_sensitive;
+};
+
+/* Internal representation of a catalog key. */
+struct grub_hfsplus_catkey_internal
+{
+ grub_uint32_t parent;
+ const grub_uint16_t *name;
+ grub_size_t namelen;
+};
+
+/* Internal representation of an extent overflow key. */
+struct grub_hfsplus_extkey_internal
+{
+ grub_uint32_t fileid;
+ grub_uint32_t start;
+ grub_uint8_t type;
+};
+
+struct grub_hfsplus_attrkey
+{
+ grub_uint16_t keylen;
+ grub_uint16_t unknown1[1];
+ grub_uint32_t cnid;
+ grub_uint16_t unknown2[2];
+ grub_uint16_t namelen;
+ grub_uint16_t name[0];
+} GRUB_PACKED;
+
+struct grub_hfsplus_attrkey_internal
+{
+ grub_uint32_t cnid;
+ const grub_uint16_t *name;
+ grub_size_t namelen;
+};
+
+struct grub_hfsplus_key_internal
+{
+ union
+ {
+ struct grub_hfsplus_extkey_internal extkey;
+ struct grub_hfsplus_catkey_internal catkey;
+ struct grub_hfsplus_attrkey_internal attrkey;
+ };
+};
+
+/* The on disk layout of a catalog key. */
+struct grub_hfsplus_catkey
+{
+ grub_uint16_t keylen;
+ grub_uint32_t parent;
+ grub_uint16_t namelen;
+ grub_uint16_t name[0];
+} GRUB_PACKED;
+
+/* The on disk layout of an extent overflow file key. */
+struct grub_hfsplus_extkey
+{
+ grub_uint16_t keylen;
+ grub_uint8_t type;
+ grub_uint8_t unused;
+ grub_uint32_t fileid;
+ grub_uint32_t start;
+} GRUB_PACKED;
+
+struct grub_hfsplus_key
+{
+ union
+ {
+ struct grub_hfsplus_extkey extkey;
+ struct grub_hfsplus_catkey catkey;
+ struct grub_hfsplus_attrkey attrkey;
+ grub_uint16_t keylen;
+ };
+} GRUB_PACKED;
+
+struct grub_hfsplus_btnode
+{
+ grub_uint32_t next;
+ grub_uint32_t prev;
+ grub_int8_t type;
+ grub_uint8_t height;
+ grub_uint16_t count;
+ grub_uint16_t unused;
+} GRUB_PACKED;
+
+/* Return the offset of the record with the index INDEX, in the node
+ NODE which is part of the B+ tree BTREE. */
+static inline grub_uint16_t
+grub_hfsplus_btree_recoffset (struct grub_hfsplus_btree *btree,
+ struct grub_hfsplus_btnode *node, unsigned index)
+{
+ char *cnode = (char *) node;
+ void *recptr;
+ if (btree->nodesize < index * sizeof (grub_uint16_t) + 2)
+ index = 0;
+ recptr = (&cnode[btree->nodesize - index * sizeof (grub_uint16_t) - 2]);
+ return grub_be_to_cpu16 (grub_get_unaligned16 (recptr));
+}
+
+/* Return a pointer to the record with the index INDEX, in the node
+ NODE which is part of the B+ tree BTREE. */
+static inline struct grub_hfsplus_key *
+grub_hfsplus_btree_recptr (struct grub_hfsplus_btree *btree,
+ struct grub_hfsplus_btnode *node, unsigned index)
+{
+ char *cnode = (char *) node;
+ grub_uint16_t offset;
+ offset = grub_hfsplus_btree_recoffset (btree, node, index);
+ if (offset > btree->nodesize - sizeof (struct grub_hfsplus_key))
+ offset = 0;
+ return (struct grub_hfsplus_key *) &cnode[offset];
+}
+
+extern grub_err_t (*grub_hfsplus_open_compressed) (struct grub_hfsplus_file *node);
+extern grub_ssize_t (*grub_hfsplus_read_compressed) (struct grub_hfsplus_file *node,
+ grub_off_t pos,
+ grub_size_t len,
+ char *buf);
+
+grub_ssize_t
+grub_hfsplus_read_file (struct grub_hfsplus_file *node,
+ grub_disk_read_hook_t read_hook, void *read_hook_data,
+ grub_off_t pos, grub_size_t len, char *buf);
+grub_err_t
+grub_hfsplus_btree_search (struct grub_hfsplus_btree *btree,
+ struct grub_hfsplus_key_internal *key,
+ int (*compare_keys) (struct grub_hfsplus_key *keya,
+ struct grub_hfsplus_key_internal *keyb),
+ struct grub_hfsplus_btnode **matchnode,
+ grub_off_t *keyoffset);
+grub_err_t
+grub_mac_bless_inode (grub_device_t dev, grub_uint32_t inode, int is_dir,
+ int intel);
+grub_err_t
+grub_mac_bless_file (grub_device_t dev, const char *path_in, int intel);