1 /* 2 * libhfs - library for reading and writing Macintosh HFS volumes 3 * Copyright (C) 1996-1998 Robert Leslie 4 * 5 * This program is free software; you can redistribute it and/or modify 6 * it under the terms of the GNU General Public License as published by 7 * the Free Software Foundation; either version 2 of the License, or 8 * (at your option) any later version. 9 * 10 * This program is distributed in the hope that it will be useful, 11 * but WITHOUT ANY WARRANTY; without even the implied warranty of 12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 * GNU General Public License for more details. 14 * 15 * You should have received a copy of the GNU General Public License 16 * along with this program; if not, write to the Free Software 17 * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, 18 * MA 02110-1301, USA. 19 * 20 * $Id: libhfs.h,v 1.7 1998/11/02 22:09:02 rob Exp $ 21 */ 22 23 # include "hfs.h" 24 # include "apple.h" 25 26 # define ERROR(code, str) \ 27 do { hfs_error = (str), errno = (code); goto fail; } while (0) 28 29 # ifdef DEBUG 30 # define ASSERT(cond) do { if (! (cond)) abort(); } while (0) 31 # else 32 # define ASSERT(cond) /* nothing */ 33 # endif 34 35 # define SIZE(type, n) ((size_t) (sizeof(type) * (n))) 36 # define ALLOC(type, n) ((type *) malloc(SIZE(type, n))) 37 # define ALLOCX(type, n) ((n) ? ALLOC(type, n) : (type *) 0) 38 # define FREE(ptr) ((ptr) ? (void) free((void *) ptr) : (void) 0) 39 40 # define REALLOC(ptr, type, n) \ 41 ((type *) ((ptr) ? realloc(ptr, SIZE(type, n)) : malloc(SIZE(type, n)))) 42 # define REALLOCX(ptr, type, n) \ 43 ((n) ? REALLOC(ptr, type, n) : (FREE(ptr), (type *) 0)) 44 45 # define BMTST(bm, num) \ 46 (((const byte *) (bm))[(num) >> 3] & (0x80 >> ((num) & 0x07))) 47 # define BMSET(bm, num) \ 48 (((byte *) (bm))[(num) >> 3] |= (0x80 >> ((num) & 0x07))) 49 # define BMCLR(bm, num) \ 50 (((byte *) (bm))[(num) >> 3] &= ~(0x80 >> ((num) & 0x07))) 51 52 # define STRINGIZE(x) #x 53 # define STR(x) STRINGIZE(x) 54 55 typedef unsigned char byte; 56 typedef byte block[HFS_BLOCKSZ]; 57 58 typedef struct _bucket_ { 59 int flags; /* bit flags */ 60 unsigned int count; /* number of times this block is requested */ 61 62 unsigned long bnum; /* logical block number */ 63 block *data; /* pointer to block contents */ 64 65 struct _bucket_ *cnext; /* next bucket in cache chain */ 66 struct _bucket_ *cprev; /* previous bucket in cache chain */ 67 68 struct _bucket_ *hnext; /* next bucket in hash chain */ 69 struct _bucket_ **hprev; /* previous bucket's pointer to this bucket */ 70 } bucket; 71 72 # define HFS_BUCKET_INUSE 0x01 73 # define HFS_BUCKET_DIRTY 0x02 74 75 # define HFS_CACHESZ 128 76 # define HFS_HASHSZ 32 77 # define HFS_BLOCKBUFSZ 16 78 79 typedef struct { 80 struct _hfsvol_ *vol; /* volume to which cache belongs */ 81 bucket *tail; /* end of bucket chain */ 82 83 unsigned int hits; /* number of cache hits */ 84 unsigned int misses; /* number of cache misses */ 85 86 bucket chain[HFS_CACHESZ]; /* cache bucket chain */ 87 bucket *hash[HFS_HASHSZ]; /* hash table for bucket chain */ 88 89 block pool[HFS_CACHESZ]; /* physical blocks in cache */ 90 } bcache; 91 92 # define HFS_MAP1SZ 256 93 # define HFS_MAPXSZ 492 94 95 # define HFS_NODEREC(nd, rnum) ((nd).data + (nd).roff[rnum]) 96 # define HFS_RECLEN(nd, rnum) ((nd).roff[(rnum) + 1] - (nd).roff[rnum]) 97 98 # define HFS_RECKEYLEN(ptr) (*(const byte *) (ptr)) 99 # define HFS_RECKEYSKIP(ptr) ((size_t) ((1 + HFS_RECKEYLEN(ptr) + 1) & ~1)) 100 # define HFS_RECDATA(ptr) ((ptr) + HFS_RECKEYSKIP(ptr)) 101 102 # define HFS_SETKEYLEN(ptr, x) (*(byte *) (ptr) = (x)) 103 104 # define HFS_CATDATALEN sizeof(CatDataRec) 105 # define HFS_EXTDATALEN sizeof(ExtDataRec) 106 # define HFS_MAX_DATALEN (HFS_CATDATALEN > HFS_EXTDATALEN ? \ 107 HFS_CATDATALEN : HFS_EXTDATALEN) 108 109 # define HFS_CATKEYLEN sizeof(CatKeyRec) 110 # define HFS_EXTKEYLEN sizeof(ExtKeyRec) 111 # define HFS_MAX_KEYLEN (HFS_CATKEYLEN > HFS_EXTKEYLEN ? \ 112 HFS_CATKEYLEN : HFS_EXTKEYLEN) 113 114 # define HFS_MAX_CATRECLEN (HFS_CATKEYLEN + HFS_CATDATALEN) 115 # define HFS_MAX_EXTRECLEN (HFS_EXTKEYLEN + HFS_EXTDATALEN) 116 # define HFS_MAX_RECLEN (HFS_MAX_KEYLEN + HFS_MAX_DATALEN) 117 118 # define HFS_SIGWORD 0x4244 119 # define HFS_SIGWORD_MFS ((Integer) 0xd2d7) 120 121 # define HFS_ATRB_BUSY (1 << 6) 122 # define HFS_ATRB_HLOCKED (1 << 7) 123 # define HFS_ATRB_UMOUNTED (1 << 8) 124 # define HFS_ATRB_BBSPARED (1 << 9) 125 # define HFS_ATRB_BVINCONSIS (1 << 11) 126 # define HFS_ATRB_COPYPROT (1 << 14) 127 # define HFS_ATRB_SLOCKED (1 << 15) 128 129 struct _hfsfile_ { 130 struct _hfsvol_ *vol; /* pointer to volume descriptor */ 131 unsigned long parid; /* parent directory ID of this file */ 132 char name[HFS_MAX_FLEN + 1]; /* catalog name of this file */ 133 CatDataRec cat; /* catalog information */ 134 ExtDataRec ext; /* current extent record */ 135 unsigned int fabn; /* starting file allocation block number */ 136 int fork; /* current selected fork for I/O */ 137 unsigned long pos; /* current file seek pointer */ 138 int flags; /* bit flags */ 139 140 struct _hfsfile_ *prev; 141 struct _hfsfile_ *next; 142 }; 143 144 # define HFS_FILE_UPDATE_CATREC 0x01 145 146 # define HFS_MAX_NRECS 35 /* maximum based on minimum record size */ 147 148 typedef struct _node_ { 149 struct _btree_ *bt; /* btree to which this node belongs */ 150 unsigned long nnum; /* node index */ 151 NodeDescriptor nd; /* node descriptor */ 152 int rnum; /* current record index */ 153 UInteger roff[HFS_MAX_NRECS + 1]; 154 /* record offsets */ 155 block data; /* raw contents of node */ 156 } node; 157 158 struct _hfsdir_ { 159 struct _hfsvol_ *vol; /* associated volume */ 160 unsigned long dirid; /* directory ID of interest (or 0) */ 161 162 node n; /* current B*-tree node */ 163 struct _hfsvol_ *vptr; /* current volume pointer */ 164 165 struct _hfsdir_ *prev; 166 struct _hfsdir_ *next; 167 }; 168 169 typedef void (*keyunpackfunc)(const byte *, void *); 170 typedef int (*keycomparefunc)(const void *, const void *); 171 172 typedef struct _btree_ { 173 hfsfile f; /* subset file information */ 174 node hdrnd; /* header node */ 175 BTHdrRec hdr; /* header record */ 176 byte *map; /* usage bitmap */ 177 unsigned long mapsz; /* number of bytes in bitmap */ 178 int flags; /* bit flags */ 179 180 keyunpackfunc keyunpack; /* key unpacking function */ 181 keycomparefunc keycompare; /* key comparison function */ 182 } btree; 183 184 # define HFS_BT_UPDATE_HDR 0x01 185 186 struct _hfsvol_ { 187 int os_fd; /* OS-dependent private descriptor data */ 188 int flags; /* bit flags */ 189 190 int pnum; /* ordinal HFS partition number */ 191 unsigned long vstart; /* logical block offset to start of volume */ 192 unsigned long vlen; /* number of logical blocks in volume */ 193 unsigned int lpa; /* number of logical blocks per allocation block */ 194 195 bcache *cache; /* cache of recently used blocks */ 196 197 MDB mdb; /* master directory block */ 198 block *vbm; /* volume bitmap */ 199 unsigned short vbmsz; /* number of blocks in bitmap */ 200 201 btree ext; /* B*-tree control block for extents overflow file */ 202 btree cat; /* B*-tree control block for catalog file */ 203 204 unsigned long cwd; /* directory id of current working directory */ 205 206 int refs; /* number of external references to this volume */ 207 hfsfile *files; /* list of open files */ 208 hfsdir *dirs; /* list of open directories */ 209 210 struct _hfsvol_ *prev; 211 struct _hfsvol_ *next; 212 }; 213 214 # define HFS_VOL_OPEN 0x0001 215 # define HFS_VOL_MOUNTED 0x0002 216 # define HFS_VOL_READONLY 0x0004 217 # define HFS_VOL_USINGCACHE 0x0008 218 219 # define HFS_VOL_UPDATE_MDB 0x0010 220 # define HFS_VOL_UPDATE_ALTMDB 0x0020 221 # define HFS_VOL_UPDATE_VBM 0x0040 222 223 # define HFS_VOL_OPT_MASK 0xff00 224 225 extern hfsvol *hfs_mounts; 226