/* @(#)apple_driver.c 1.6 04/03/04 joerg */ #ifndef lint static char sccsid[] = "@(#)apple_driver.c 1.6 04/03/04 joerg"; #endif /* * apple_driver.c: extract Mac partition label, maps and boot driver * * Based on Apple_Driver.pl, part of "mkisofs 1.05 PLUS" by Andy Polyakov * (I don't know Perl, so I rewrote it C ...) * (see http://fy.chalmers.se/~appro/mkisofs_plus.html for details) * * usage: apple_driver CDROM_device > HFS_driver_file * * 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 * * By extracting a driver from an Apple CD, you become liable to obey * Apple Computer, Inc. Software License Agreements. * * James Pearson 17/5/98 */ #include #include "mkisofs.h" #include #include EXPORT int get_732 __PR((char *p)); EXPORT int get_722 __PR((char *p)); EXPORT int main __PR((int argc, char **argv)); EXPORT int get_732(p) char *p; { return ((p[3] & 0xff) | ((p[2] & 0xff) << 8) | ((p[1] & 0xff) << 16) | ((p[0] & 0xff) << 24)); } EXPORT int get_722(p) char *p; { return ((p[1] & 0xff) | ((p[0] & 0xff) << 8)); } EXPORT int main(argc, argv) int argc; char **argv; { FILE *fp; MacLabel *mac_label; MacPart *mac_part; unsigned char Block0[HFS_BLOCKSZ]; unsigned char block[SECTOR_SIZE]; unsigned char bootb[2*HFS_BLOCKSZ]; unsigned char pmBlock512[HFS_BLOCKSZ]; unsigned int sbBlkSize; unsigned int pmPyPartStart; unsigned int pmPartStatus; unsigned int pmMapBlkCnt; int have_boot = 0, have_hfs = 0; int hfs_start; int i, j; save_args(argc, argv); if (argc != 2) comerrno(EX_BAD, "Usage: %s device-path", argv[0]); if ((fp = fopen(argv[1], "rb")) == NULL) comerr("Can't open '%s'.", argv[1]); if (fread(Block0, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) comerr("Can't read '%s'.", argv[1]); mac_label = (MacLabel *)Block0; mac_part = (MacPart *)block; sbBlkSize = get_722((char *)mac_label->sbBlkSize); if (! IS_MAC_LABEL(mac_label) || sbBlkSize != SECTOR_SIZE) comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]); i = 1; do { if (fseek(fp, i * HFS_BLOCKSZ, SEEK_SET) != 0) comerr("Ccan't seek %s", argv[1]); if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) comerr("Can't read '%s'.", argv[1]); pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt); if (!have_boot && strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) { hfs_start = get_732((char *)mac_part->pmPyPartStart); fprintf(stderr, "%s: found 512 driver partition (at block %d)\n", argv[0], hfs_start); memcpy(pmBlock512, block, HFS_BLOCKSZ); have_boot = 1; } if (!have_hfs && strncmp((char *)mac_part->pmPartType, pmPartType_4, 9) == 0) { hfs_start = get_732((char *)mac_part->pmPyPartStart); if (fseek(fp, hfs_start*HFS_BLOCKSZ, SEEK_SET) != 0) comerr("Can't seek '%s'.", argv[1]); if (fread(bootb, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) comerr("Can't read '%s'.", argv[1]); if (get_722((char *)bootb) == 0x4c4b) { fprintf(stderr, "%s: found HFS partition (at blk %d)\n", argv[0], hfs_start); have_hfs = 1; } } } while (i++ < pmMapBlkCnt); if (!have_hfs || !have_boot) comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]); i = 1; do { if (fseek(fp, i*sbBlkSize, SEEK_SET) != 0) comerr("Can't seek '%s'.", argv[1]); if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) comerr("Can't read '%s'.", argv[1]); pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt); if (strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) { int start, num; fprintf(stderr, "%s: extracting %s ", argv[0], mac_part->pmPartType); start = get_732((char *)mac_part->pmPyPartStart); num = get_732((char *)mac_part->pmPartBlkCnt); fwrite(Block0, 1, HFS_BLOCKSZ, stdout); fwrite(block, 1, HFS_BLOCKSZ, stdout); fwrite(pmBlock512, 1, HFS_BLOCKSZ, stdout); memset(block, 0, HFS_BLOCKSZ); fwrite(block, 1, HFS_BLOCKSZ, stdout); if (fseek(fp, start*sbBlkSize, SEEK_SET) != 0) comerr("Can't seek '%s'.", argv[1]); for (j = 0; j < num; j++) { if (fread(block, 1, sbBlkSize, fp) != sbBlkSize) comerr("Can't read '%s'.", argv[1]); fwrite(block, 1, sbBlkSize, stdout); fprintf(stderr, "."); } fprintf(stderr, "\n"); fwrite(bootb, 2, HFS_BLOCKSZ, stdout); fclose(fp); exit(0); } if (!IS_MAC_PART(mac_part)) comerrno(EX_BAD, "Unable to find boot partition"); } while (i++ < pmMapBlkCnt); return (0); }