1 /* 2 * hfsutils - tools for reading and writing Macintosh HFS volumes 3 * Copyright (C) 1996, 1997 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., 675 Mass Ave, Cambridge, MA 02139, USA. 18 */ 19 20 # include <time.h> 21 22 # include "hfs.h" 23 24 # define ERROR(code, str) (hfs_error = (str), errno = (code)) 25 26 # define SIZE(type, n) ((size_t) (sizeof(type) * (n))) 27 # define ALLOC(type, n) ((type *) malloc(SIZE(type, n))) 28 # define ALLOCX(type, n) ((n) ? ALLOC(type, n) : (type *) 0) 29 # define FREE(ptr) ((ptr) ? (void) free((void *) ptr) : (void) 0) 30 31 # define REALLOC(ptr, type, n) \ 32 ((type *) ((ptr) ? realloc(ptr, SIZE(type, n)) : malloc(SIZE(type, n)))) 33 # define REALLOCX(ptr, type, n) \ 34 ((n) ? REALLOC(type, n) : (FREE(ptr), (type *) 0)) 35 36 # define BMTST(bm, num) \ 37 (((char *) (bm))[(num) >> 3] & (0x80 >> ((num) & 0x07))) 38 # define BMSET(bm, num) \ 39 (((char *) (bm))[(num) >> 3] |= (0x80 >> ((num) & 0x07))) 40 # define BMCLR(bm, num) \ 41 (((char *) (bm))[(num) >> 3] &= ~(0x80 >> ((num) & 0x07))) 42 43 typedef unsigned char block[HFS_BLOCKSZ]; 44 45 typedef signed char Char; 46 typedef unsigned char UChar; 47 typedef signed char SignedByte; 48 typedef signed short Integer; 49 typedef unsigned short UInteger; 50 typedef signed long LongInt; 51 typedef unsigned long ULongInt; 52 typedef char Str15[16]; 53 typedef char Str31[32]; 54 typedef long OSType; 55 56 typedef struct { 57 UInteger xdrStABN; /* first allocation block */ 58 UInteger xdrNumABlks; /* number of allocation blocks */ 59 } ExtDescriptor; 60 61 typedef ExtDescriptor ExtDataRec[3]; 62 63 typedef struct { 64 SignedByte xkrKeyLen; /* key length */ 65 SignedByte xkrFkType; /* fork type (0x00/0xff == data/resource */ 66 ULongInt xkrFNum; /* file number */ 67 UInteger xkrFABN; /* starting file allocation block */ 68 } ExtKeyRec; 69 70 typedef struct { 71 SignedByte ckrKeyLen; /* key length */ 72 SignedByte ckrResrv1; /* reserved */ 73 ULongInt ckrParID; /* parent directory ID */ 74 Str31 ckrCName; /* catalog node name */ 75 } CatKeyRec; 76 77 # define HFS_MAP1SZ 256 78 # define HFS_MAPXSZ 492 79 80 # define HFS_NODEREC(nd, rnum) ((nd).data + (nd).roff[rnum]) 81 82 # define HFS_RECKEYLEN(ptr) (*(unsigned char *) (ptr)) 83 # define HFS_RECKEYSKIP(ptr) ((1 + HFS_RECKEYLEN(ptr) + 1) & ~1) 84 # define HFS_RECDATA(ptr) ((ptr) + HFS_RECKEYSKIP(ptr)) 85 86 # define HFS_CATDATALEN sizeof(CatDataRec) 87 # define HFS_EXTDATALEN sizeof(ExtDataRec) 88 89 # define HFS_CATKEYLEN sizeof(CatKeyRec) 90 # define HFS_EXTKEYLEN sizeof(ExtKeyRec) 91 92 # define HFS_CATRECMAXLEN (HFS_CATKEYLEN + HFS_CATDATALEN) 93 # define HFS_EXTRECMAXLEN (HFS_EXTKEYLEN + HFS_EXTDATALEN) 94 95 # define HFS_MAXRECLEN HFS_CATRECMAXLEN 96 97 typedef struct { 98 Integer v; /* vertical coordinate */ 99 Integer h; /* horizontal coordinate */ 100 } Point; 101 102 typedef struct { 103 Integer top; /* top edge of rectangle */ 104 Integer left; /* left edge */ 105 Integer bottom; /* bottom edge */ 106 Integer right; /* rightmost edge */ 107 } Rect; 108 109 typedef struct { 110 Rect frRect; /* folder's rectangle */ 111 Integer frFlags; /* flags */ 112 Point frLocation; /* folder's location */ 113 Integer frView; /* folder's view */ 114 } DInfo; 115 116 typedef struct { 117 Point frScroll; /* scroll position */ 118 LongInt frOpenChain; /* directory ID chain of open folders */ 119 Integer frUnused; /* reserved */ 120 Integer frComment; /* comment ID */ 121 LongInt frPutAway; /* directory ID */ 122 } DXInfo; 123 124 typedef struct { 125 OSType fdType; /* file type */ 126 OSType fdCreator; /* file's creator */ 127 Integer fdFlags; /* flags */ 128 Point fdLocation; /* file's location */ 129 Integer fdFldr; /* file's window */ 130 } FInfo; 131 132 typedef struct { 133 Integer fdIconID; /* icon ID */ 134 Integer fdUnused[4]; /* reserved */ 135 Integer fdComment; /* comment ID */ 136 LongInt fdPutAway; /* home directory ID */ 137 } FXInfo; 138 139 typedef struct { 140 Integer drSigWord; /* volume signature (0x4244 for HFS) */ 141 LongInt drCrDate; /* date and time of volume creation */ 142 LongInt drLsMod; /* date and time of last modification */ 143 Integer drAtrb; /* volume attributes */ 144 UInteger drNmFls; /* number of files in root directory */ 145 UInteger drVBMSt; /* first block of volume bit map (always 3) */ 146 UInteger drAllocPtr; /* start of next allocation search */ 147 UInteger drNmAlBlks; /* number of allocation blocks in volume */ 148 ULongInt drAlBlkSiz; /* size (in bytes) of allocation blocks */ 149 ULongInt drClpSiz; /* default clump size */ 150 UInteger drAlBlSt; /* first allocation block in volume */ 151 LongInt drNxtCNID; /* next unused catalog node ID (dir/file ID) */ 152 UInteger drFreeBks; /* number of unused allocation blocks */ 153 char drVN[28]; /* volume name (1-27 chars) */ 154 LongInt drVolBkUp; /* date and time of last backup */ 155 Integer drVSeqNum; /* volume backup sequence number */ 156 ULongInt drWrCnt; /* volume write count */ 157 ULongInt drXTClpSiz; /* clump size for extents overflow file */ 158 ULongInt drCTClpSiz; /* clump size for catalog file */ 159 UInteger drNmRtDirs; /* number of directories in root directory */ 160 ULongInt drFilCnt; /* number of files in volume */ 161 ULongInt drDirCnt; /* number of directories in volume */ 162 LongInt drFndrInfo[8]; /* information used by the Finder */ 163 UInteger drVCSize; /* size (in blocks) of volume cache */ 164 UInteger drVBMCSize; /* size (in blocks) of volume bitmap cache */ 165 UInteger drCtlCSize; /* size (in blocks) of common volume cache */ 166 ULongInt drXTFlSize; /* size (in bytes) of extents overflow file */ 167 ExtDataRec drXTExtRec; /* first extent record for extents file */ 168 ULongInt drCTFlSize; /* size (in bytes) of catalog file */ 169 ExtDataRec drCTExtRec; /* first extent record for catalog file */ 170 } MDB; 171 172 # define HFS_ATRB_BUSY (1 << 6) 173 # define HFS_ATRB_HLOCKED (1 << 7) 174 # define HFS_ATRB_UMOUNTED (1 << 8) 175 # define HFS_ATRB_BBSPARED (1 << 9) 176 # define HFS_ATRB_COPYPROT (1 << 14) 177 # define HFS_ATRB_SLOCKED (1 << 15) 178 179 typedef enum { 180 cdrDirRec = 1, 181 cdrFilRec = 2, 182 cdrThdRec = 3, 183 cdrFThdRec = 4 184 } CatDataType; 185 186 typedef struct { 187 SignedByte cdrType; /* record type */ 188 SignedByte cdrResrv2; /* reserved */ 189 union { 190 struct { /* cdrDirRec */ 191 Integer dirFlags; /* directory flags */ 192 UInteger dirVal; /* directory valence */ 193 ULongInt dirDirID; /* directory ID */ 194 LongInt dirCrDat; /* date and time of creation */ 195 LongInt dirMdDat; /* date and time of last modification */ 196 LongInt dirBkDat; /* date and time of last backup */ 197 DInfo dirUsrInfo; /* Finder information */ 198 DXInfo dirFndrInfo; /* additional Finder information */ 199 LongInt dirResrv[4]; /* reserved */ 200 } dir; 201 struct { /* cdrFilRec */ 202 SignedByte 203 filFlags; /* file flags */ 204 SignedByte 205 filTyp; /* file type */ 206 FInfo filUsrWds; /* Finder information */ 207 ULongInt filFlNum; /* file ID */ 208 UInteger filStBlk; /* first alloc block of data fork */ 209 ULongInt filLgLen; /* logical EOF of data fork */ 210 ULongInt filPyLen; /* physical EOF of data fork */ 211 UInteger filRStBlk; /* first alloc block of resource fork */ 212 ULongInt filRLgLen; /* logical EOF of resource fork */ 213 ULongInt filRPyLen; /* physical EOF of resource fork */ 214 LongInt filCrDat; /* date and time of creation */ 215 LongInt filMdDat; /* date and time of last modification */ 216 LongInt filBkDat; /* date and time of last backup */ 217 FXInfo filFndrInfo; /* additional Finder information */ 218 UInteger filClpSize; /* file clump size */ 219 ExtDataRec 220 filExtRec; /* first data fork extent record */ 221 ExtDataRec 222 filRExtRec; /* first resource fork extent record */ 223 LongInt filResrv; /* reserved */ 224 } fil; 225 struct { /* cdrThdRec */ 226 LongInt thdResrv[2]; /* reserved */ 227 ULongInt thdParID; /* parent ID for this directory */ 228 Str31 thdCName; /* name of this directory */ 229 } dthd; 230 struct { /* cdrFThdRec */ 231 LongInt fthdResrv[2]; /* reserved */ 232 ULongInt fthdParID; /* parent ID for this file */ 233 Str31 fthdCName; /* name of this file */ 234 } fthd; 235 } u; 236 } CatDataRec; 237 238 struct _hfsfile_ { 239 struct _hfsvol_ *vol; /* pointer to volume descriptor */ 240 long parid; /* parent directory ID of this file */ 241 char name[HFS_MAX_FLEN + 1]; /* catalog name of this file */ 242 CatDataRec cat; /* catalog information */ 243 ExtDataRec ext; /* current extent record */ 244 unsigned int fabn; /* starting file allocation block number */ 245 int fork; /* current selected fork for I/O */ 246 unsigned long pos; /* current file seek pointer */ 247 unsigned long clump; /* file's clump size, for allocation */ 248 int flags; /* bit flags */ 249 250 struct _hfsfile_ *prev; 251 struct _hfsfile_ *next; 252 }; 253 254 # define HFS_UPDATE_CATREC 0x01 255 256 typedef struct { 257 ULongInt ndFLink; /* forward link */ 258 ULongInt ndBLink; /* backward link */ 259 SignedByte ndType; /* node type */ 260 SignedByte ndNHeight; /* node level */ 261 UInteger ndNRecs; /* number of records in node */ 262 Integer ndResv2; /* reserved */ 263 } NodeDescriptor; 264 265 # define HFS_MAXRECS 35 /* maximum based on minimum record size */ 266 267 typedef struct _node_ { 268 struct _btree_ *bt; /* btree to which this node belongs */ 269 unsigned long nnum; /* node index */ 270 NodeDescriptor nd; /* node descriptor */ 271 int rnum; /* current record index */ 272 UInteger roff[HFS_MAXRECS + 1]; /* record offsets */ 273 block data; /* raw contents of node */ 274 } node; 275 276 enum { 277 ndIndxNode = 0x00, 278 ndHdrNode = 0x01, 279 ndMapNode = 0x02, 280 ndLeafNode = 0xff 281 }; 282 283 struct _hfsdir_ { 284 struct _hfsvol_ *vol; /* associated volume */ 285 long dirid; /* directory ID of interest (or 0) */ 286 287 node n; /* current B*-tree node */ 288 struct _hfsvol_ *vptr; /* current volume pointer */ 289 290 struct _hfsdir_ *prev; 291 struct _hfsdir_ *next; 292 }; 293 294 typedef struct { 295 UInteger bthDepth; /* current depth of tree */ 296 ULongInt bthRoot; /* number of root node */ 297 ULongInt bthNRecs; /* number of leaf records in tree */ 298 ULongInt bthFNode; /* number of first leaf node */ 299 ULongInt bthLNode; /* number of last leaf node */ 300 UInteger bthNodeSize; /* size of a node */ 301 UInteger bthKeyLen; /* maximum length of a key */ 302 ULongInt bthNNodes; /* total number of nodes in tree */ 303 ULongInt bthFree; /* number of free nodes */ 304 SignedByte bthResv[76]; /* reserved */ 305 } BTHdrRec; 306 307 typedef struct _btree_ { 308 hfsfile f; /* subset file information */ 309 node hdrnd; /* header node */ 310 BTHdrRec hdr; /* header record */ 311 char *map; /* usage bitmap */ 312 unsigned long mapsz; /* number of bytes in bitmap */ 313 int flags; /* bit flags */ 314 315 int (*compare)(unsigned char *, unsigned char *); 316 /* key comparison function */ 317 } btree; 318 319 # define HFS_UPDATE_BTHDR 0x01 320 321 struct _hfsvol_ { 322 int fd; /* volume's open file descriptor */ 323 int flags; /* bit flags */ 324 325 #ifdef APPLE_HYB 326 hce_mem *hce; /* Extras needed by libhfs/mkisofs */ 327 #endif /* APPLE_HYB */ 328 329 int pnum; /* ordinal HFS partition number */ 330 unsigned long vstart; /* logical block offset to start of volume */ 331 unsigned long vlen; /* number of logical blocks in volume */ 332 unsigned int lpa; /* number of logical blocks per allocation block */ 333 334 MDB mdb; /* master directory block */ 335 block *vbm; /* volume bit map */ 336 btree ext; /* B*-tree control block for extents overflow file */ 337 btree cat; /* B*-tree control block for catalog file */ 338 long cwd; /* directory id of current working directory */ 339 340 int refs; /* number of external references to this volume */ 341 hfsfile *files; /* list of open files */ 342 hfsdir *dirs; /* list of open directories */ 343 344 struct _hfsvol_ *prev; 345 struct _hfsvol_ *next; 346 }; 347 348 # define HFS_READONLY 0x01 349 350 # define HFS_UPDATE_MDB 0x10 351 # define HFS_UPDATE_ALTMDB 0x20 352 # define HFS_UPDATE_VBM 0x40 353 354 extern hfsvol *hfs_mounts; 355 extern hfsvol *hfs_curvol; 356