358 lines
12 KiB
C
358 lines
12 KiB
C
/* @(#)internal.h 1.3 06/09/13 joerg */
|
|
/*
|
|
* hfsutils - tools for reading and writing Macintosh HFS volumes
|
|
* Copyright (C) 1996, 1997 Robert Leslie
|
|
*
|
|
* 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 2 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, write to the Free Software
|
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
*/
|
|
|
|
#include <schily/time.h>
|
|
#include <schily/standard.h>
|
|
|
|
# include "hfs.h"
|
|
|
|
# define ERROR(code, str) (hfs_error = (str), errno = (code))
|
|
|
|
# define SIZE(type, n) ((size_t) (sizeof(type) * (n)))
|
|
# define ALLOC(type, n) ((type *) malloc(SIZE(type, n)))
|
|
# define ALLOCX(type, n) ((n) ? ALLOC(type, n) : (type *) 0)
|
|
# define FREE(ptr) {if (ptr) free((void *) ptr) ;}
|
|
|
|
# define REALLOC(ptr, type, n) \
|
|
((type *) ((ptr) ? realloc(ptr, SIZE(type, n)) : malloc(SIZE(type, n))))
|
|
# define REALLOCX(ptr, type, n) \
|
|
((n) ? REALLOC(type, n) : (FREE(ptr), (type *) 0))
|
|
|
|
# define BMTST(bm, num) \
|
|
(((char *) (bm))[(num) >> 3] & (0x80 >> ((num) & 0x07)))
|
|
# define BMSET(bm, num) \
|
|
(((char *) (bm))[(num) >> 3] |= (0x80 >> ((num) & 0x07)))
|
|
# define BMCLR(bm, num) \
|
|
(((char *) (bm))[(num) >> 3] &= ~(0x80 >> ((num) & 0x07)))
|
|
|
|
typedef unsigned char block[HFS_BLOCKSZ];
|
|
|
|
typedef signed char Char;
|
|
typedef unsigned char UChar;
|
|
typedef signed char SignedByte;
|
|
typedef signed short Integer;
|
|
typedef unsigned short UInteger;
|
|
typedef signed long LongInt;
|
|
typedef unsigned long ULongInt;
|
|
typedef char Str15[16];
|
|
typedef char Str31[32];
|
|
typedef long OSType;
|
|
|
|
typedef struct {
|
|
UInteger xdrStABN; /* first allocation block */
|
|
UInteger xdrNumABlks; /* number of allocation blocks */
|
|
} ExtDescriptor;
|
|
|
|
typedef ExtDescriptor ExtDataRec[3];
|
|
|
|
typedef struct {
|
|
SignedByte xkrKeyLen; /* key length */
|
|
SignedByte xkrFkType; /* fork type (0x00/0xff == data/resource */
|
|
ULongInt xkrFNum; /* file number */
|
|
UInteger xkrFABN; /* starting file allocation block */
|
|
} ExtKeyRec;
|
|
|
|
typedef struct {
|
|
SignedByte ckrKeyLen; /* key length */
|
|
SignedByte ckrResrv1; /* reserved */
|
|
ULongInt ckrParID; /* parent directory ID */
|
|
Str31 ckrCName; /* catalog node name */
|
|
} CatKeyRec;
|
|
|
|
# define HFS_MAP1SZ 256
|
|
# define HFS_MAPXSZ 492
|
|
|
|
# define HFS_NODEREC(nd, rnum) ((nd).data + (nd).roff[rnum])
|
|
|
|
# define HFS_RECKEYLEN(ptr) (*(unsigned char *) (ptr))
|
|
# define HFS_RECKEYSKIP(ptr) ((1 + HFS_RECKEYLEN(ptr) + 1) & ~1)
|
|
# define HFS_RECDATA(ptr) ((ptr) + HFS_RECKEYSKIP(ptr))
|
|
|
|
# define HFS_CATDATALEN sizeof(CatDataRec)
|
|
# define HFS_EXTDATALEN sizeof(ExtDataRec)
|
|
|
|
# define HFS_CATKEYLEN sizeof(CatKeyRec)
|
|
# define HFS_EXTKEYLEN sizeof(ExtKeyRec)
|
|
|
|
# define HFS_CATRECMAXLEN (HFS_CATKEYLEN + HFS_CATDATALEN)
|
|
# define HFS_EXTRECMAXLEN (HFS_EXTKEYLEN + HFS_EXTDATALEN)
|
|
|
|
# define HFS_MAXRECLEN HFS_CATRECMAXLEN
|
|
|
|
typedef struct {
|
|
Integer v; /* vertical coordinate */
|
|
Integer h; /* horizontal coordinate */
|
|
} Point;
|
|
|
|
typedef struct {
|
|
Integer top; /* top edge of rectangle */
|
|
Integer left; /* left edge */
|
|
Integer bottom; /* bottom edge */
|
|
Integer right; /* rightmost edge */
|
|
} Rect;
|
|
|
|
typedef struct {
|
|
Rect frRect; /* folder's rectangle */
|
|
Integer frFlags; /* flags */
|
|
Point frLocation; /* folder's location */
|
|
Integer frView; /* folder's view */
|
|
} DInfo;
|
|
|
|
typedef struct {
|
|
Point frScroll; /* scroll position */
|
|
LongInt frOpenChain; /* directory ID chain of open folders */
|
|
Integer frUnused; /* reserved */
|
|
Integer frComment; /* comment ID */
|
|
LongInt frPutAway; /* directory ID */
|
|
} DXInfo;
|
|
|
|
typedef struct {
|
|
OSType fdType; /* file type */
|
|
OSType fdCreator; /* file's creator */
|
|
Integer fdFlags; /* flags */
|
|
Point fdLocation; /* file's location */
|
|
Integer fdFldr; /* file's window */
|
|
} FInfo;
|
|
|
|
typedef struct {
|
|
Integer fdIconID; /* icon ID */
|
|
Integer fdUnused[4]; /* reserved */
|
|
Integer fdComment; /* comment ID */
|
|
LongInt fdPutAway; /* home directory ID */
|
|
} FXInfo;
|
|
|
|
typedef struct {
|
|
Integer drSigWord; /* volume signature (0x4244 for HFS) */
|
|
LongInt drCrDate; /* date and time of volume creation */
|
|
LongInt drLsMod; /* date and time of last modification */
|
|
Integer drAtrb; /* volume attributes */
|
|
UInteger drNmFls; /* number of files in root directory */
|
|
UInteger drVBMSt; /* first block of volume bit map (always 3) */
|
|
UInteger drAllocPtr; /* start of next allocation search */
|
|
UInteger drNmAlBlks; /* number of allocation blocks in volume */
|
|
ULongInt drAlBlkSiz; /* size (in bytes) of allocation blocks */
|
|
ULongInt drClpSiz; /* default clump size */
|
|
UInteger drAlBlSt; /* first allocation block in volume */
|
|
LongInt drNxtCNID; /* next unused catalog node ID (dir/file ID) */
|
|
UInteger drFreeBks; /* number of unused allocation blocks */
|
|
char drVN[28]; /* volume name (1-27 chars) */
|
|
LongInt drVolBkUp; /* date and time of last backup */
|
|
Integer drVSeqNum; /* volume backup sequence number */
|
|
ULongInt drWrCnt; /* volume write count */
|
|
ULongInt drXTClpSiz; /* clump size for extents overflow file */
|
|
ULongInt drCTClpSiz; /* clump size for catalog file */
|
|
UInteger drNmRtDirs; /* number of directories in root directory */
|
|
ULongInt drFilCnt; /* number of files in volume */
|
|
ULongInt drDirCnt; /* number of directories in volume */
|
|
LongInt drFndrInfo[8]; /* information used by the Finder */
|
|
UInteger drVCSize; /* size (in blocks) of volume cache */
|
|
UInteger drVBMCSize; /* size (in blocks) of volume bitmap cache */
|
|
UInteger drCtlCSize; /* size (in blocks) of common volume cache */
|
|
ULongInt drXTFlSize; /* size (in bytes) of extents overflow file */
|
|
ExtDataRec drXTExtRec; /* first extent record for extents file */
|
|
ULongInt drCTFlSize; /* size (in bytes) of catalog file */
|
|
ExtDataRec drCTExtRec; /* first extent record for catalog file */
|
|
} MDB;
|
|
|
|
# define HFS_ATRB_BUSY (1 << 6)
|
|
# define HFS_ATRB_HLOCKED (1 << 7)
|
|
# define HFS_ATRB_UMOUNTED (1 << 8)
|
|
# define HFS_ATRB_BBSPARED (1 << 9)
|
|
# define HFS_ATRB_COPYPROT (1 << 14)
|
|
# define HFS_ATRB_SLOCKED (1 << 15)
|
|
|
|
typedef enum {
|
|
cdrDirRec = 1,
|
|
cdrFilRec = 2,
|
|
cdrThdRec = 3,
|
|
cdrFThdRec = 4
|
|
} CatDataType;
|
|
|
|
typedef struct {
|
|
SignedByte cdrType; /* record type */
|
|
SignedByte cdrResrv2; /* reserved */
|
|
union {
|
|
struct { /* cdrDirRec */
|
|
Integer dirFlags; /* directory flags */
|
|
UInteger dirVal; /* directory valence */
|
|
ULongInt dirDirID; /* directory ID */
|
|
LongInt dirCrDat; /* date and time of creation */
|
|
LongInt dirMdDat; /* date and time of last modification */
|
|
LongInt dirBkDat; /* date and time of last backup */
|
|
DInfo dirUsrInfo; /* Finder information */
|
|
DXInfo dirFndrInfo; /* additional Finder information */
|
|
LongInt dirResrv[4]; /* reserved */
|
|
} dir;
|
|
struct { /* cdrFilRec */
|
|
SignedByte
|
|
filFlags; /* file flags */
|
|
SignedByte
|
|
filTyp; /* file type */
|
|
FInfo filUsrWds; /* Finder information */
|
|
ULongInt filFlNum; /* file ID */
|
|
UInteger filStBlk; /* first alloc block of data fork */
|
|
ULongInt filLgLen; /* logical EOF of data fork */
|
|
ULongInt filPyLen; /* physical EOF of data fork */
|
|
UInteger filRStBlk; /* first alloc block of resource fork */
|
|
ULongInt filRLgLen; /* logical EOF of resource fork */
|
|
ULongInt filRPyLen; /* physical EOF of resource fork */
|
|
LongInt filCrDat; /* date and time of creation */
|
|
LongInt filMdDat; /* date and time of last modification */
|
|
LongInt filBkDat; /* date and time of last backup */
|
|
FXInfo filFndrInfo; /* additional Finder information */
|
|
UInteger filClpSize; /* file clump size */
|
|
ExtDataRec
|
|
filExtRec; /* first data fork extent record */
|
|
ExtDataRec
|
|
filRExtRec; /* first resource fork extent record */
|
|
LongInt filResrv; /* reserved */
|
|
} fil;
|
|
struct { /* cdrThdRec */
|
|
LongInt thdResrv[2]; /* reserved */
|
|
ULongInt thdParID; /* parent ID for this directory */
|
|
Str31 thdCName; /* name of this directory */
|
|
} dthd;
|
|
struct { /* cdrFThdRec */
|
|
LongInt fthdResrv[2]; /* reserved */
|
|
ULongInt fthdParID; /* parent ID for this file */
|
|
Str31 fthdCName; /* name of this file */
|
|
} fthd;
|
|
} u;
|
|
} CatDataRec;
|
|
|
|
struct _hfsfile_ {
|
|
struct _hfsvol_ *vol; /* pointer to volume descriptor */
|
|
long parid; /* parent directory ID of this file */
|
|
char name[HFS_MAX_FLEN + 1]; /* catalog name of this file */
|
|
CatDataRec cat; /* catalog information */
|
|
ExtDataRec ext; /* current extent record */
|
|
unsigned int fabn; /* starting file allocation block number */
|
|
int fork; /* current selected fork for I/O */
|
|
unsigned long pos; /* current file seek pointer */
|
|
unsigned long clump; /* file's clump size, for allocation */
|
|
int flags; /* bit flags */
|
|
|
|
struct _hfsfile_ *prev;
|
|
struct _hfsfile_ *next;
|
|
};
|
|
|
|
# define HFS_UPDATE_CATREC 0x01
|
|
|
|
typedef struct {
|
|
ULongInt ndFLink; /* forward link */
|
|
ULongInt ndBLink; /* backward link */
|
|
SignedByte ndType; /* node type */
|
|
SignedByte ndNHeight; /* node level */
|
|
UInteger ndNRecs; /* number of records in node */
|
|
Integer ndResv2; /* reserved */
|
|
} NodeDescriptor;
|
|
|
|
# define HFS_MAXRECS 35 /* maximum based on minimum record size */
|
|
|
|
typedef struct _node_ {
|
|
struct _btree_ *bt; /* btree to which this node belongs */
|
|
unsigned long nnum; /* node index */
|
|
NodeDescriptor nd; /* node descriptor */
|
|
int rnum; /* current record index */
|
|
UInteger roff[HFS_MAXRECS + 1]; /* record offsets */
|
|
block data; /* raw contents of node */
|
|
} node;
|
|
|
|
enum {
|
|
ndIndxNode = 0x00,
|
|
ndHdrNode = 0x01,
|
|
ndMapNode = 0x02,
|
|
ndLeafNode = 0xff
|
|
};
|
|
|
|
struct _hfsdir_ {
|
|
struct _hfsvol_ *vol; /* associated volume */
|
|
long dirid; /* directory ID of interest (or 0) */
|
|
|
|
node n; /* current B*-tree node */
|
|
struct _hfsvol_ *vptr; /* current volume pointer */
|
|
|
|
struct _hfsdir_ *prev;
|
|
struct _hfsdir_ *next;
|
|
};
|
|
|
|
typedef struct {
|
|
UInteger bthDepth; /* current depth of tree */
|
|
ULongInt bthRoot; /* number of root node */
|
|
ULongInt bthNRecs; /* number of leaf records in tree */
|
|
ULongInt bthFNode; /* number of first leaf node */
|
|
ULongInt bthLNode; /* number of last leaf node */
|
|
UInteger bthNodeSize; /* size of a node */
|
|
UInteger bthKeyLen; /* maximum length of a key */
|
|
ULongInt bthNNodes; /* total number of nodes in tree */
|
|
ULongInt bthFree; /* number of free nodes */
|
|
SignedByte bthResv[76]; /* reserved */
|
|
} BTHdrRec;
|
|
|
|
typedef struct _btree_ {
|
|
hfsfile f; /* subset file information */
|
|
node hdrnd; /* header node */
|
|
BTHdrRec hdr; /* header record */
|
|
char *map; /* usage bitmap */
|
|
unsigned long mapsz; /* number of bytes in bitmap */
|
|
int flags; /* bit flags */
|
|
|
|
int (*compare) __PR((unsigned char *, unsigned char *));
|
|
/* key comparison function */
|
|
} btree;
|
|
|
|
# define HFS_UPDATE_BTHDR 0x01
|
|
|
|
struct _hfsvol_ {
|
|
int fd; /* volume's open file descriptor */
|
|
int flags; /* bit flags */
|
|
|
|
#ifdef APPLE_HYB
|
|
hce_mem *hce; /* Extras needed by libhfs/mkisofs */
|
|
#endif /* APPLE_HYB */
|
|
|
|
int pnum; /* ordinal HFS partition number */
|
|
unsigned long vstart; /* logical block offset to start of volume */
|
|
unsigned long vlen; /* number of logical blocks in volume */
|
|
unsigned int lpa; /* number of logical blocks per allocation block */
|
|
|
|
MDB mdb; /* master directory block */
|
|
block *vbm; /* volume bit map */
|
|
btree ext; /* B*-tree control block for extents overflow file */
|
|
btree cat; /* B*-tree control block for catalog file */
|
|
long cwd; /* directory id of current working directory */
|
|
|
|
int refs; /* number of external references to this volume */
|
|
hfsfile *files; /* list of open files */
|
|
hfsdir *dirs; /* list of open directories */
|
|
|
|
struct _hfsvol_ *prev;
|
|
struct _hfsvol_ *next;
|
|
};
|
|
|
|
# define HFS_READONLY 0x01
|
|
|
|
# define HFS_UPDATE_MDB 0x10
|
|
# define HFS_UPDATE_ALTMDB 0x20
|
|
# define HFS_UPDATE_VBM 0x40
|
|
|
|
extern hfsvol *hfs_mounts;
|
|
extern hfsvol *hfs_curvol;
|