/* * NAME: record->unpackextdata() * DESCRIPTION: unpack extent record data */ void r_unpackextdata(const byte *pdata, ExtDataRec *data) { int i; for (i = 0; i < 3; ++i) { d_fetchuw(&pdata, &(*data)[i].xdrStABN); d_fetchuw(&pdata, &(*data)[i].xdrNumABlks); } }
/* * NAME: find() * DESCRIPTION: generic routine to locate and return a resource */ static const byte *find(rsrcmap *map, const char *type, int (*compare)(rsrcmap *, const byte *, const void *), const void *key) { const byte *ptr; short nitems; unsigned short rlistoff; ptr = findtype(map, type); if (ptr == 0) goto fail; ptr += 4; d_fetchsw(&ptr, &nitems); d_fetchuw(&ptr, &rlistoff); for (ptr = map->tlist + rlistoff; nitems >= 0; ptr += 12, --nitems) { if (compare(map, ptr, key)) break; } if (nitems < 0) ERROR(EINVAL, "resource not found"); return ptr; fail: return 0; }
/* * NAME: record->unpackextkey() * DESCRIPTION: unpack an extents record key */ void r_unpackextkey(const byte *pkey, ExtKeyRec *key) { d_fetchsb(&pkey, &key->xkrKeyLen); d_fetchsb(&pkey, &key->xkrFkType); d_fetchul(&pkey, &key->xkrFNum); d_fetchuw(&pkey, &key->xkrFABN); }
/* * NAME: rsrc->init() * DESCRIPTION: initialize access to a resource file */ rsrcfile *rsrc_init(void *priv, const struct rsrcprocs *procs) { rsrcfile *rfile; byte head[16]; const byte *ptr = head; unsigned long nbytes; unsigned short tlistoff, nlistoff; rfile = ALLOC(rsrcfile, 1); if (rfile == 0) ERROR(ENOMEM, 0); rfile->priv = priv; rfile->procs = *procs; rfile->map.data = 0; if (rfile->procs.seek(rfile->priv, 0, RSRC_SEEK_SET) == (unsigned long) -1) ERROR(errno, "error seeking resource header"); nbytes = rfile->procs.read(rfile->priv, head, sizeof(head)); if (nbytes != sizeof(head)) { if (nbytes == (unsigned long) -1) ERROR(errno, "error reading resource header"); else ERROR(EINVAL, "truncated resource header"); } d_fetchul(&ptr, &rfile->hdr.dstart); d_fetchul(&ptr, &rfile->hdr.mstart); d_fetchul(&ptr, &rfile->hdr.dlen); d_fetchul(&ptr, &rfile->hdr.mlen); rfile->map.data = ALLOC(byte, rfile->hdr.mlen); if (rfile->map.data == 0) ERROR(ENOMEM, 0); if (rfile->procs.seek(rfile->priv, rfile->hdr.mstart, RSRC_SEEK_SET) == (unsigned long) -1) ERROR(errno, "error seeking resource map"); nbytes = rfile->procs.read(rfile->priv, rfile->map.data, rfile->hdr.mlen); if (nbytes != rfile->hdr.mlen) { if (nbytes == (unsigned long) -1) ERROR(errno, "error reading resource map"); else ERROR(EIO, "truncated resource map"); } memcpy(rfile->map.data, head, sizeof(head)); ptr = rfile->map.data + 22; d_fetchuw(&ptr, &rfile->map.attrs); d_fetchuw(&ptr, &tlistoff); d_fetchuw(&ptr, &nlistoff); rfile->map.tlist = rfile->map.data + tlistoff; rfile->map.nlist = rfile->map.data + nlistoff; return rfile; fail: if (rfile) FREE(rfile->map.data); FREE(rfile); return 0; }
/* * NAME: record->unpackcatdata() * DESCRIPTION: unpack catalog record data */ void r_unpackcatdata(const byte *pdata, CatDataRec *data) { int i; d_fetchsb(&pdata, &data->cdrType); d_fetchsb(&pdata, &data->cdrResrv2); switch (data->cdrType) { case cdrDirRec: d_fetchsw(&pdata, &data->u.dir.dirFlags); d_fetchuw(&pdata, &data->u.dir.dirVal); d_fetchul(&pdata, &data->u.dir.dirDirID); d_fetchsl(&pdata, &data->u.dir.dirCrDat); d_fetchsl(&pdata, &data->u.dir.dirMdDat); d_fetchsl(&pdata, &data->u.dir.dirBkDat); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frRect.top); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frRect.left); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frRect.bottom); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frRect.right); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frFlags); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frLocation.v); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frLocation.h); d_fetchsw(&pdata, &data->u.dir.dirUsrInfo.frView); d_fetchsw(&pdata, &data->u.dir.dirFndrInfo.frScroll.v); d_fetchsw(&pdata, &data->u.dir.dirFndrInfo.frScroll.h); d_fetchsl(&pdata, &data->u.dir.dirFndrInfo.frOpenChain); d_fetchsw(&pdata, &data->u.dir.dirFndrInfo.frUnused); d_fetchsw(&pdata, &data->u.dir.dirFndrInfo.frComment); d_fetchsl(&pdata, &data->u.dir.dirFndrInfo.frPutAway); for (i = 0; i < 4; ++i) d_fetchsl(&pdata, &data->u.dir.dirResrv[i]); break; case cdrFilRec: d_fetchsb(&pdata, &data->u.fil.filFlags); d_fetchsb(&pdata, &data->u.fil.filTyp); d_fetchsl(&pdata, &data->u.fil.filUsrWds.fdType); d_fetchsl(&pdata, &data->u.fil.filUsrWds.fdCreator); d_fetchsw(&pdata, &data->u.fil.filUsrWds.fdFlags); d_fetchsw(&pdata, &data->u.fil.filUsrWds.fdLocation.v); d_fetchsw(&pdata, &data->u.fil.filUsrWds.fdLocation.h); d_fetchsw(&pdata, &data->u.fil.filUsrWds.fdFldr); d_fetchul(&pdata, &data->u.fil.filFlNum); d_fetchuw(&pdata, &data->u.fil.filStBlk); d_fetchul(&pdata, &data->u.fil.filLgLen); d_fetchul(&pdata, &data->u.fil.filPyLen); d_fetchuw(&pdata, &data->u.fil.filRStBlk); d_fetchul(&pdata, &data->u.fil.filRLgLen); d_fetchul(&pdata, &data->u.fil.filRPyLen); d_fetchsl(&pdata, &data->u.fil.filCrDat); d_fetchsl(&pdata, &data->u.fil.filMdDat); d_fetchsl(&pdata, &data->u.fil.filBkDat); d_fetchsw(&pdata, &data->u.fil.filFndrInfo.fdIconID); for (i = 0; i < 4; ++i) d_fetchsw(&pdata, &data->u.fil.filFndrInfo.fdUnused[i]); d_fetchsw(&pdata, &data->u.fil.filFndrInfo.fdComment); d_fetchsl(&pdata, &data->u.fil.filFndrInfo.fdPutAway); d_fetchuw(&pdata, &data->u.fil.filClpSize); for (i = 0; i < 3; ++i) { d_fetchuw(&pdata, &data->u.fil.filExtRec[i].xdrStABN); d_fetchuw(&pdata, &data->u.fil.filExtRec[i].xdrNumABlks); } for (i = 0; i < 3; ++i) { d_fetchuw(&pdata, &data->u.fil.filRExtRec[i].xdrStABN); d_fetchuw(&pdata, &data->u.fil.filRExtRec[i].xdrNumABlks); } d_fetchsl(&pdata, &data->u.fil.filResrv); break; case cdrThdRec: for (i = 0; i < 2; ++i) d_fetchsl(&pdata, &data->u.dthd.thdResrv[i]); d_fetchul(&pdata, &data->u.dthd.thdParID); d_fetchstr(&pdata, data->u.dthd.thdCName, sizeof(data->u.dthd.thdCName)); break; case cdrFThdRec: for (i = 0; i < 2; ++i) d_fetchsl(&pdata, &data->u.fthd.fthdResrv[i]); d_fetchul(&pdata, &data->u.fthd.fthdParID); d_fetchstr(&pdata, data->u.fthd.fthdCName, sizeof(data->u.fthd.fthdCName)); break; # ifdef DEBUG default: abort(); # endif } }
/* * NAME: low->getmdb() * DESCRIPTION: read a master directory block */ int l_getmdb(hfsvol *vol, MDB *mdb, int backup) { block b; const byte *ptr = b; int i; if (b_readlb(vol, backup ? vol->vlen - 2 : 2, &b) == -1) goto fail; d_fetchsw(&ptr, &mdb->drSigWord); d_fetchsl(&ptr, &mdb->drCrDate); d_fetchsl(&ptr, &mdb->drLsMod); d_fetchsw(&ptr, &mdb->drAtrb); d_fetchuw(&ptr, &mdb->drNmFls); d_fetchuw(&ptr, &mdb->drVBMSt); d_fetchuw(&ptr, &mdb->drAllocPtr); d_fetchuw(&ptr, &mdb->drNmAlBlks); d_fetchul(&ptr, &mdb->drAlBlkSiz); d_fetchul(&ptr, &mdb->drClpSiz); d_fetchuw(&ptr, &mdb->drAlBlSt); d_fetchsl(&ptr, &mdb->drNxtCNID); d_fetchuw(&ptr, &mdb->drFreeBks); d_fetchstr(&ptr, mdb->drVN, sizeof(mdb->drVN)); ASSERT(ptr - b == 64); d_fetchsl(&ptr, &mdb->drVolBkUp); d_fetchsw(&ptr, &mdb->drVSeqNum); d_fetchul(&ptr, &mdb->drWrCnt); d_fetchul(&ptr, &mdb->drXTClpSiz); d_fetchul(&ptr, &mdb->drCTClpSiz); d_fetchuw(&ptr, &mdb->drNmRtDirs); d_fetchul(&ptr, &mdb->drFilCnt); d_fetchul(&ptr, &mdb->drDirCnt); for (i = 0; i < 8; ++i) d_fetchsl(&ptr, &mdb->drFndrInfo[i]); ASSERT(ptr - b == 124); d_fetchuw(&ptr, &mdb->drEmbedSigWord); d_fetchuw(&ptr, &mdb->drEmbedExtent.xdrStABN); d_fetchuw(&ptr, &mdb->drEmbedExtent.xdrNumABlks); d_fetchul(&ptr, &mdb->drXTFlSize); for (i = 0; i < 3; ++i) { d_fetchuw(&ptr, &mdb->drXTExtRec[i].xdrStABN); d_fetchuw(&ptr, &mdb->drXTExtRec[i].xdrNumABlks); } ASSERT(ptr - b == 146); d_fetchul(&ptr, &mdb->drCTFlSize); for (i = 0; i < 3; ++i) { d_fetchuw(&ptr, &mdb->drCTExtRec[i].xdrStABN); d_fetchuw(&ptr, &mdb->drCTExtRec[i].xdrNumABlks); } ASSERT(ptr - b == 162); return 0; fail: return -1; }