⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 low.c

📁 创建一个符合iso-9660标准的iso文件系统
💻 C
字号:
/* * 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 <mconfig.h>#include <strdefs.h>#include <stdxlib.h>#include <errno.h>#include <unixstd.h>#include <fcntl.h>#include "internal.h"#include "data.h"#include "block.h"#include "low.h"#include "file.h"/* * NAME:	low->lockvol() * DESCRIPTION:	prevent destructive simultaneous access */int l_lockvol(vol)	hfsvol	*vol;{# ifndef NODEVLOCKS  struct flock lock;  lock.l_type   = (vol->flags & HFS_READONLY) ? F_RDLCK : F_WRLCK;  lock.l_start  = 0;  lock.l_whence = SEEK_SET;  lock.l_len    = 0;  if (fcntl(vol->fd, F_SETLK, &lock) < 0)    {      ERROR(errno, "unable to obtain lock for device");      return -1;    }# endif  return 0;}/* * NAME:	low->readblock0() * DESCRIPTION:	read the first sector and get bearings */int l_readblock0(vol)	hfsvol	*vol;{  block b;  unsigned char *ptr = b;  Block0 rec;  if (b_readlb(vol, 0, &b) < 0)    return -1;  d_fetchw(&ptr, &rec.sbSig);  d_fetchw(&ptr, &rec.sbBlkSize);  d_fetchl(&ptr, &rec.sbBlkCount);  d_fetchw(&ptr, &rec.sbDevType);  d_fetchw(&ptr, &rec.sbDevId);  d_fetchl(&ptr, &rec.sbData);  d_fetchw(&ptr, &rec.sbDrvrCount);  d_fetchl(&ptr, &rec.ddBlock);  d_fetchw(&ptr, &rec.ddSize);  d_fetchw(&ptr, &rec.ddType);  switch (rec.sbSig)    {    case 0x4552:  /* block device with a partition table */      {	if (rec.sbBlkSize != HFS_BLOCKSZ)	  {	    ERROR(EINVAL, "unsupported block size");	    return -1;	  }	vol->vlen = rec.sbBlkCount;	if (l_readpm(vol) < 0)	  return -1;      }      break;    case 0x4c4b:  /* bootable floppy */      vol->pnum = 0;      break;    default:  /* non-bootable floppy or something else */      /* some miscreant media may also be partitioned;	 we attempt to read a partition map, but ignore any failure */      if (l_readpm(vol) < 0)	vol->pnum = 0;    }  return 0;}/* * NAME:	low->readpm() * DESCRIPTION:	read the partition map and locate an HFS volume */int l_readpm(vol)	hfsvol	*vol;{  block b;  unsigned char *ptr;  Partition map;  unsigned long bnum;  int pnum;  bnum = 1;  pnum = vol->pnum;  while (1)    {      if (b_readlb(vol, bnum, &b) < 0)	return -1;      ptr = b;      d_fetchw(&ptr, &map.pmSig);      d_fetchw(&ptr, &map.pmSigPad);      d_fetchl(&ptr, &map.pmMapBlkCnt);      d_fetchl(&ptr, &map.pmPyPartStart);      d_fetchl(&ptr, &map.pmPartBlkCnt);      memcpy(map.pmPartName, ptr, 32);      map.pmPartName[32] = 0;      ptr += 32;      memcpy(map.pmParType, ptr, 32);      map.pmParType[32] = 0;      ptr += 32;      d_fetchl(&ptr, &map.pmLgDataStart);      d_fetchl(&ptr, &map.pmDataCnt);      d_fetchl(&ptr, &map.pmPartStatus);      d_fetchl(&ptr, &map.pmLgBootStart);      d_fetchl(&ptr, &map.pmBootSize);      d_fetchl(&ptr, &map.pmBootAddr);      d_fetchl(&ptr, &map.pmBootAddr2);      d_fetchl(&ptr, &map.pmBootEntry);      d_fetchl(&ptr, &map.pmBootEntry2);      d_fetchl(&ptr, &map.pmBootCksum);      memcpy(map.pmProcessor, ptr, 16);      map.pmProcessor[16] = 0;      ptr += 16;      if (map.pmSig == 0x5453)	{	  /* old partition map sig */	  ERROR(EINVAL, "unsupported partition map signature");	  return -1;	}      if (map.pmSig != 0x504d)	{	  ERROR(EINVAL, "bad partition map");	  return -1;	}      if (strcmp((char *) map.pmParType, "Apple_HFS") == 0 && --pnum == 0)	{	  if (map.pmLgDataStart != 0)	    {	      ERROR(EINVAL, "unsupported start of partition logical data");	      return -1;	    }	  vol->vstart = map.pmPyPartStart;	  vol->vlen   = map.pmPartBlkCnt;	  return 0;	}      if (bnum >= map.pmMapBlkCnt)	{	  ERROR(EINVAL, "can't find HFS partition");	  return -1;	}      ++bnum;    }}/* * NAME:	low->readmdb() * DESCRIPTION:	read the master directory block into memory */int l_readmdb(vol)	hfsvol	*vol;{  block b;  unsigned char *ptr = b;  MDB *mdb = &vol->mdb;  hfsfile *ext = &vol->ext.f;  hfsfile *cat = &vol->cat.f;  int i;  if (b_readlb(vol, 2, &b) < 0)    return -1;  d_fetchw(&ptr, &mdb->drSigWord);  d_fetchl(&ptr, &mdb->drCrDate);  d_fetchl(&ptr, &mdb->drLsMod);  d_fetchw(&ptr, &mdb->drAtrb);  d_fetchw(&ptr, (short *) &mdb->drNmFls);  d_fetchw(&ptr, (short *) &mdb->drVBMSt);  d_fetchw(&ptr, (short *) &mdb->drAllocPtr);  d_fetchw(&ptr, (short *) &mdb->drNmAlBlks);  d_fetchl(&ptr, (long *) &mdb->drAlBlkSiz);  d_fetchl(&ptr, (long *) &mdb->drClpSiz);  d_fetchw(&ptr, (short *) &mdb->drAlBlSt);  d_fetchl(&ptr, &mdb->drNxtCNID);  d_fetchw(&ptr, (short *) &mdb->drFreeBks);  d_fetchs(&ptr, mdb->drVN, sizeof(mdb->drVN));  if (ptr - b != 64)    abort();  d_fetchl(&ptr, &mdb->drVolBkUp);  d_fetchw(&ptr, &mdb->drVSeqNum);  d_fetchl(&ptr, (long *) &mdb->drWrCnt);  d_fetchl(&ptr, (long *) &mdb->drXTClpSiz);  d_fetchl(&ptr, (long *) &mdb->drCTClpSiz);  d_fetchw(&ptr, (short *) &mdb->drNmRtDirs);  d_fetchl(&ptr, (long *) &mdb->drFilCnt);  d_fetchl(&ptr, (long *) &mdb->drDirCnt);  for (i = 0; i < 8; ++i)    d_fetchl(&ptr, &mdb->drFndrInfo[i]);  if (ptr - b != 124)    abort();  d_fetchw(&ptr, (short *) &mdb->drVCSize);  d_fetchw(&ptr, (short *) &mdb->drVBMCSize);  d_fetchw(&ptr, (short *) &mdb->drCtlCSize);  d_fetchl(&ptr, (long *) &mdb->drXTFlSize);  for (i = 0; i < 3; ++i)    {      d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrStABN);      d_fetchw(&ptr, (short *) &mdb->drXTExtRec[i].xdrNumABlks);    }  if (ptr - b != 146)    abort();  d_fetchl(&ptr, (long *) &mdb->drCTFlSize);  for (i = 0; i < 3; ++i)    {      d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrStABN);      d_fetchw(&ptr, (short *) &mdb->drCTExtRec[i].xdrNumABlks);    }  if (ptr - b != 162)    abort();  vol->lpa = mdb->drAlBlkSiz / HFS_BLOCKSZ;  /* extents pseudo-file structs */  ext->vol   = vol;  ext->parid = 0;  strcpy(ext->name, "extents overflow");  ext->cat.cdrType          = cdrFilRec;  /* ext->cat.cdrResrv2 */  ext->cat.u.fil.filFlags   = 0;  ext->cat.u.fil.filTyp     = 0;  /* ext->cat.u.fil.filUsrWds */  ext->cat.u.fil.filFlNum   = HFS_CNID_EXT;  ext->cat.u.fil.filStBlk   = mdb->drXTExtRec[0].xdrStABN;  ext->cat.u.fil.filLgLen   = mdb->drXTFlSize;  ext->cat.u.fil.filPyLen   = mdb->drXTFlSize;  ext->cat.u.fil.filRStBlk  = 0;  ext->cat.u.fil.filRLgLen  = 0;  ext->cat.u.fil.filRPyLen  = 0;  ext->cat.u.fil.filCrDat   = mdb->drCrDate;  ext->cat.u.fil.filMdDat   = mdb->drLsMod;  ext->cat.u.fil.filBkDat   = 0;  /* ext->cat.u.fil.filFndrInfo */  ext->cat.u.fil.filClpSize = 0;  memcpy(ext->cat.u.fil.filExtRec, mdb->drXTExtRec, sizeof(ExtDataRec));  for (i = 0; i < 3; ++i)    {      ext->cat.u.fil.filRExtRec[i].xdrStABN    = 0;      ext->cat.u.fil.filRExtRec[i].xdrNumABlks = 0;    }  f_selectfork(ext, 0);  ext->clump = mdb->drXTClpSiz;  ext->flags = 0;  ext->prev = ext->next = 0;  /* catalog pseudo-file structs */  cat->vol   = vol;  cat->parid = 0;  strcpy(cat->name, "catalog");  cat->cat.cdrType          = cdrFilRec;  /* cat->cat.cdrResrv2 */  cat->cat.u.fil.filFlags   = 0;  cat->cat.u.fil.filTyp     = 0;  /* cat->cat.u.fil.filUsrWds */  cat->cat.u.fil.filFlNum   = HFS_CNID_CAT;  cat->cat.u.fil.filStBlk   = mdb->drCTExtRec[0].xdrStABN;  cat->cat.u.fil.filLgLen   = mdb->drCTFlSize;  cat->cat.u.fil.filPyLen   = mdb->drCTFlSize;  cat->cat.u.fil.filRStBlk  = 0;  cat->cat.u.fil.filRLgLen  = 0;  cat->cat.u.fil.filRPyLen  = 0;  cat->cat.u.fil.filCrDat   = mdb->drCrDate;  cat->cat.u.fil.filMdDat   = mdb->drLsMod;  cat->cat.u.fil.filBkDat   = 0;  /* cat->cat.u.fil.filFndrInfo */  cat->cat.u.fil.filClpSize = 0;  memcpy(cat->cat.u.fil.filExtRec, mdb->drCTExtRec, sizeof(ExtDataRec));  for (i = 0; i < 3; ++i)    {      cat->cat.u.fil.filRExtRec[i].xdrStABN    = 0;      cat->cat.u.fil.filRExtRec[i].xdrNumABlks = 0;    }  f_selectfork(cat, 0);  cat->clump = mdb->drCTClpSiz;  cat->flags = 0;  cat->prev = cat->next = 0;  return 0;}/* * NAME:	low->writemdb() * DESCRIPTION:	write the master directory block to disk */int l_writemdb(vol)	hfsvol	*vol;{  block b;  unsigned char *ptr = b;  MDB *mdb = &vol->mdb;  hfsfile *ext = &vol->ext.f;  hfsfile *cat = &vol->cat.f;  int i;  memset(&b, 0, sizeof(b));  mdb->drXTFlSize = ext->cat.u.fil.filPyLen;  mdb->drXTClpSiz = ext->clump;  memcpy(mdb->drXTExtRec, ext->cat.u.fil.filExtRec, sizeof(ExtDataRec));  mdb->drCTFlSize = cat->cat.u.fil.filPyLen;  mdb->drCTClpSiz = cat->clump;  memcpy(mdb->drCTExtRec, cat->cat.u.fil.filExtRec, sizeof(ExtDataRec));  d_storew(&ptr, mdb->drSigWord);  d_storel(&ptr, mdb->drCrDate);  d_storel(&ptr, mdb->drLsMod);  d_storew(&ptr, mdb->drAtrb);  d_storew(&ptr, mdb->drNmFls);  d_storew(&ptr, mdb->drVBMSt);  d_storew(&ptr, mdb->drAllocPtr);  d_storew(&ptr, mdb->drNmAlBlks);  d_storel(&ptr, mdb->drAlBlkSiz);  d_storel(&ptr, mdb->drClpSiz);  d_storew(&ptr, mdb->drAlBlSt);  d_storel(&ptr, mdb->drNxtCNID);  d_storew(&ptr, mdb->drFreeBks);  d_stores(&ptr, mdb->drVN, sizeof(mdb->drVN));  if (ptr - b != 64)    abort();  d_storel(&ptr, mdb->drVolBkUp);  d_storew(&ptr, mdb->drVSeqNum);  d_storel(&ptr, mdb->drWrCnt);  d_storel(&ptr, mdb->drXTClpSiz);  d_storel(&ptr, mdb->drCTClpSiz);  d_storew(&ptr, mdb->drNmRtDirs);  d_storel(&ptr, mdb->drFilCnt);  d_storel(&ptr, mdb->drDirCnt);  for (i = 0; i < 8; ++i)    d_storel(&ptr, mdb->drFndrInfo[i]);  if (ptr - b != 124)    abort();  d_storew(&ptr, mdb->drVCSize);  d_storew(&ptr, mdb->drVBMCSize);  d_storew(&ptr, mdb->drCtlCSize);  d_storel(&ptr, mdb->drXTFlSize);  for (i = 0; i < 3; ++i)    {      d_storew(&ptr, mdb->drXTExtRec[i].xdrStABN);      d_storew(&ptr, mdb->drXTExtRec[i].xdrNumABlks);    }  if (ptr - b != 146)    abort();  d_storel(&ptr, mdb->drCTFlSize);  for (i = 0; i < 3; ++i)    {      d_storew(&ptr, mdb->drCTExtRec[i].xdrStABN);      d_storew(&ptr, mdb->drCTExtRec[i].xdrNumABlks);    }  if (ptr - b != 162)    abort();  if (b_writelb(vol, 2, &b) < 0)    return -1;  if (vol->flags & HFS_UPDATE_ALTMDB)    {#ifdef APPLE_HYB      /* "write" alternative MDB to memory copy */      memcpy(vol->hce->hfs_alt_mdb, &b, sizeof(b));#else      if (b_writelb(vol, vol->vlen - 2, &b) < 0)	return -1;#endif /* APPLE_HYB */    }  vol->flags &= ~(HFS_UPDATE_MDB | HFS_UPDATE_ALTMDB);  return 0;}/* * NAME:	low->readvbm() * DESCRIPTION:	read the volume bit map into memory */int l_readvbm(vol)	hfsvol	*vol;{  int vbmst = vol->mdb.drVBMSt;  int vbmsz = (vol->mdb.drNmAlBlks + 4095) / 4096;  block *bp;  if (vol->mdb.drAlBlSt - vbmst < vbmsz)    {      ERROR(EIO, "volume bitmap collides with volume data");      return -1;    }  bp = ALLOC(block, vbmsz);  if (bp == 0)    {      ERROR(ENOMEM, 0);      return -1;    }  vol->vbm = bp;  while (vbmsz--)    {      if (b_readlb(vol, vbmst++, bp++) < 0)	{	  FREE(vol->vbm);	  vol->vbm = 0;	  return -1;	}    }  return 0;}/* * NAME:	low->writevbm() * DESCRIPTION:	write the volume bit map to disk */int l_writevbm(vol)	hfsvol	*vol;{  int vbmst = vol->mdb.drVBMSt;  int vbmsz = (vol->mdb.drNmAlBlks + 4095) / 4096;  block *bp = vol->vbm;  while (vbmsz--)    {      if (b_writelb(vol, vbmst++, bp++) < 0)	return -1;    }  vol->flags &= ~HFS_UPDATE_VBM;  return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -