?? mac_label.c
字號:
/* @(#)mac_label.c 1.2 00/07/20 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson */#ifndef lintstatic char sccsid[] = "@(#)mac_label.c 1.2 00/07/20 joerg, Copyright 1997, 1998, 1999, 2000 James Pearson";#endif/* * Copyright (c) 1997, 1998, 1999, 2000 James Pearson * * 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, 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; see the file COPYING. If not, write to * the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. *//* * mac_label.c: generate Mactintosh partition maps and label * * Taken from "mkisofs 1.05 PLUS" by Andy Polyakov <appro@fy.chalmers.se> * (see http://fy.chalmers.se/~appro/mkisofs_plus.html for details) * * The format of the HFS driver file: * * HFS CD Label Block 512 bytes * Driver Partition Map (for 2048 byte blocks) 512 bytes * Driver Partition Map (for 512 byte blocks) 512 bytes * Empty 512 bytes * Driver Partition N x 2048 bytes * HFS Partition Boot Block 1024 bytes * * File of the above format can be extracted from a CD using * apple_driver.c * * James Pearson 16/5/98 *//* PREP_BOOT Troy Benjegerdes 2/4/99 */#include <mconfig.h>#include "mkisofs.h"#include <statdefs.h>#include <mac_label.h>#include "apple.h"#ifdef PREP_BOOTvoid gen_prepboot_label __PR((unsigned char *ml));#endif /* PREP_BOOT */int gen_mac_label __PR((defer * mac_boot));int autostart __PR((void));#ifdef PREP_BOOTvoidgen_prepboot_label(ml) unsigned char *ml;{ struct directory_entry *de; int i, block, size; MacLabel *mac_label = (MacLabel *) ml; if (verbose > 1) { fprintf(stderr, "Creating %d PReP boot partition(s)\n", use_prep_boot); } mac_label->fdiskMagic[0] = fdiskMagic0; mac_label->fdiskMagic[1] = fdiskMagic1; for (i = 0; i < use_prep_boot; i++) { de = search_tree_file(root, prep_boot_image[i]); if (!de) { fprintf(stderr, "Uh oh, I cant find the boot image \"%s\"!\n", prep_boot_image[i]); exit(1); } /* get size and block in 512-byte blocks */ block = get_733(de->isorec.extent) * 2048 / 512; size = get_733(de->isorec.size) / 512 + 1; fprintf(stderr, "PReP boot partition %d is \"%s\"\n", i + 1, prep_boot_image[i]); /* deal with endianess */ mac_label->image[i].type = prepPartType; /* 0x41 */ mac_label->image[i].startSect[0] = block & 0xff; mac_label->image[i].startSect[1] = (block >> 8) & 0xff; mac_label->image[i].startSect[2] = (block >> 16) & 0xff; mac_label->image[i].startSect[3] = (block >> 24) & 0xff; mac_label->image[i].size[0] = size & 0xff; mac_label->image[i].size[1] = (size >> 8) & 0xff; mac_label->image[i].size[2] = (size >> 16) & 0xff; mac_label->image[i].size[3] = (size >> 24) & 0xff; }}#endif /* PREP_BOOT */intgen_mac_label(mac_boot) defer *mac_boot;{ FILE *fp; MacLabel *mac_label; MacPart *mac_part; char *buffer = (char *) hce->hfs_map; int block_size; int have_hfs_boot = 0; char tmp[SECTOR_SIZE]; struct stat stat_buf; mac_partition_table mpm[2]; int mpc = 0; int i; /* If we have a boot file, then open and check it */ if (mac_boot->name) { if (stat(mac_boot->name, &stat_buf) < 0) { sprintf(hce->error, "unable to stat HFS boot file %s", mac_boot->name); return (-1); } if ((fp = fopen(mac_boot->name, "rb")) == NULL) { sprintf(hce->error, "unable to open HFS boot file %s", mac_boot->name); return (-1); } if (fread(tmp, 1, SECTOR_SIZE, fp) != SECTOR_SIZE) { sprintf(hce->error, "unable to read HFS boot file %s", mac_boot->name); return (-1); } /* check we have a bootable partition */ mac_part = (MacPart *) (tmp + HFS_BLOCKSZ); if (!(IS_MAC_PART(mac_part) && !strncmp((char *) mac_part->pmPartType, pmPartType_2, 12))) { sprintf(hce->error, "%s is not a HFS boot file", mac_boot->name); return (-1); } /* check we have a boot block as well - last 2 blocks of file */ if (fseek(fp, -2 * HFS_BLOCKSZ, 2) != 0) { sprintf(hce->error, "unable to seek HFS boot file %s", mac_boot->name); return (-1); } /* overwrite (empty) boot block for our HFS volume */ if (fread(hce->hfs_hdr, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) { sprintf(hce->error, "unable to read HFS boot block %s", mac_boot->name); return (-1); } fclose(fp); /* check boot block is valid */ if (d_getw((unsigned char *) hce->hfs_hdr) != HFS_BB_SIGWORD) { sprintf(hce->error, "%s does not contain a valid boot block", mac_boot->name); return (-1); } /* * collect info about boot file for later user * - skip over the bootfile header */ mac_boot->size = stat_buf.st_size - SECTOR_SIZE - 2*HFS_BLOCKSZ; mac_boot->off = SECTOR_SIZE; mac_boot->pad = 0; /* * get size in SECTOR_SIZE blocks * - shouldn't need to round up */ mpm[mpc].size = ISO_ROUND_UP(mac_boot->size) / SECTOR_SIZE; mpm[mpc].ntype = PM2; mpm[mpc].type = (char *) mac_part->pmPartType; mpm[mpc].start = mac_boot->extent = last_extent; mpm[mpc].name = 0; /* flag that we have a boot file */ have_hfs_boot++; /* add boot file size to the total size */ last_extent += mpm[mpc].size; hfs_extra += mpm[mpc].size; mpc++; } /* set info about our hybrid volume */ mpm[mpc].ntype = PM4; mpm[mpc].type = pmPartType_4; mpm[mpc].start = session_start + hce->hfs_map_size / HFS_BLK_CONV; mpm[mpc].size = last_extent - mpm[mpc].start - (ISO_ROUND_UP(mac_boot->size) / SECTOR_SIZE); mpm[mpc].name = volume_id; mpc++; if (verbose > 1) fprintf(stderr, "Creating HFS Label %s %s\n", mac_boot->name ? "with boot file" : "", mac_boot->name ? mac_boot->name : ""); /* for a bootable CD, block size is SECTOR_SIZE */ block_size = have_hfs_boot ? SECTOR_SIZE : HFS_BLOCKSZ; /* create the CD label */ mac_label = (MacLabel *) buffer; mac_label->sbSig[0] = 'E'; mac_label->sbSig[1] = 'R'; set_722((char *) mac_label->sbBlkSize, block_size); set_732((char *) mac_label->sbBlkCount, last_extent * (SECTOR_SIZE / block_size)); set_722((char *) mac_label->sbDevType, 1); set_722((char *) mac_label->sbDevId, 1); /* create the partition map entry */ mac_part = (MacPart *) (buffer + block_size); mac_part->pmSig[0] = 'P'; mac_part->pmSig[1] = 'M'; set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); set_732((char *) mac_part->pmPyPartStart, 1); set_732((char *) mac_part->pmPartBlkCnt, mpc + 1); strncpy((char *) mac_part->pmPartName, "Apple", sizeof(mac_part->pmPartName)); strncpy((char *) mac_part->pmPartType, "Apple_partition_map", sizeof(mac_part->pmPartType)); set_732((char *) mac_part->pmLgDataStart, 0); set_732((char *) mac_part->pmDataCnt, mpc + 1); set_732((char *) mac_part->pmPartStatus, PM_STAT_DEFAULT); /* create partition map entries for our partitions */ for (i = 0; i < mpc; i++) { mac_part = (MacPart *) (buffer + (i + 2) * block_size); if (mpm[i].ntype == PM2) { /* get driver label and patch it */ memcpy((char *) mac_label, tmp, HFS_BLOCKSZ); set_732((char *) mac_label->sbBlkCount, last_extent * (SECTOR_SIZE / block_size)); set_732((char *) mac_label->ddBlock, (mpm[i].start) * (SECTOR_SIZE / block_size)); memcpy((char *) mac_part, tmp + HFS_BLOCKSZ, HFS_BLOCKSZ); set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); set_732((char *) mac_part->pmPyPartStart, (mpm[i].start) * (SECTOR_SIZE / block_size)); } else { mac_part->pmSig[0] = 'P'; mac_part->pmSig[1] = 'M'; set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); set_732((char *) mac_part->pmPyPartStart, mpm[i].start * (SECTOR_SIZE / HFS_BLOCKSZ)); set_732((char *) mac_part->pmPartBlkCnt, mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); strncpy((char *) mac_part->pmPartName, mpm[i].name, sizeof(mac_part->pmPartName)); strncpy((char *) mac_part->pmPartType, mpm[i].type, sizeof(mac_part->pmPartType)); set_732((char *) mac_part->pmLgDataStart, 0); set_732((char *) mac_part->pmDataCnt, mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); set_732((char *) mac_part->pmPartStatus, PM_STAT_DEFAULT); } } if (have_hfs_boot) { /* generate 512 partition table as well */ mac_part = (MacPart *) (buffer + HFS_BLOCKSZ); if (mpc < 3) { /* don't have to interleave with 2048 table */ mac_part->pmSig[0] = 'P'; mac_part->pmSig[1] = 'M'; set_732((char *) mac_part->pmMapBlkCnt, mpc + 1); set_732((char *) mac_part->pmPyPartStart, 1); set_732((char *) mac_part->pmPartBlkCnt, mpc + 1); strncpy((char *) mac_part->pmPartName, "Apple", sizeof(mac_part->pmPartName)); strncpy((char *) mac_part->pmPartType, "Apple_partition_map", sizeof(mac_part->pmPartType)); set_732((char *) mac_part->pmLgDataStart, 0); set_732((char *) mac_part->pmDataCnt, mpc + 1); set_732((char *) mac_part->pmPartStatus, PM_STAT_DEFAULT); mac_part++; /* +HFS_BLOCKSZ */ } for (i = 0; i < mpc; i++, mac_part++) { if (mac_part == (MacPart *) (buffer + SECTOR_SIZE)) mac_part++; /* jump over 2048 partition entry */ if (mpm[i].ntype == PM2) { memcpy((char *) mac_part, tmp + HFS_BLOCKSZ * 2, HFS_BLOCKSZ); if (!IS_MAC_PART(mac_part)) { mac_part--; continue; } set_732((char *) mac_part->pmMapBlkCnt, mpc+1); set_732((char *) mac_part->pmPyPartStart, mpm[i].start * (SECTOR_SIZE / HFS_BLOCKSZ)); } else { mac_part->pmSig[0] = 'P'; mac_part->pmSig[1] = 'M'; set_732((char *) mac_part->pmMapBlkCnt, mpc+1); set_732((char *) mac_part->pmPyPartStart, mpm[i].start * (SECTOR_SIZE / HFS_BLOCKSZ)); set_732((char *) mac_part->pmPartBlkCnt, mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); strncpy((char *) mac_part->pmPartName, mpm[i].name, sizeof(mac_part->pmPartName)); strncpy((char *) mac_part->pmPartType, mpm[i].type, sizeof(mac_part->pmPartType)); set_732((char *) mac_part->pmLgDataStart, 0); set_732((char *) mac_part->pmDataCnt, mpm[i].size * (SECTOR_SIZE / HFS_BLOCKSZ)); set_732((char *) mac_part->pmPartStatus, PM_STAT_DEFAULT); } } } return (0);}/* * autostart: make the HFS CD use the QuickTime 2.0 Autostart feature. * * based on information from Eric Eisenhart <eric@sonic.net> and * http://developer.apple.com/qa/qtpc/qtpc12.html and * http://developer.apple.com/dev/techsupport/develop/issue26/macqa.html * * The name of the AutoStart file is stored in the area allocated for * the Clipboard name. This area begins 106 bytes into the sector of * block 0, with the first four bytes at that offset containing the * hex value 0x006A7068. This value indicates that an AutoStart * filename follows. After this 4-byte tag, 12 bytes remain, starting * at offset 110. In these 12 bytes, the name of the AutoStart file is * stored as a Pascal string, giving you up to 11 characters to identify * the file. The file must reside in the root directory of the HFS * volume or partition. */intautostart(){ int len; int i; if ((len = strlen(autoname)) > 11) return (-1); hce->hfs_hdr[106] = 0x00; hce->hfs_hdr[107] = 0x6A; hce->hfs_hdr[108] = 0x70; hce->hfs_hdr[109] = 0x68; hce->hfs_hdr[110] = len; for (i = 0; i < len; i++) hce->hfs_hdr[111 + i] = autoname[i]; return (0);}
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -