2 * This file has been modified for the cdrkit suite.
4 * The behaviour and appearence of the program code below can differ to a major
5 * extent from the version distributed by the original author(s).
7 * For details, see Changelog file distributed with the cdrkit package. If you
8 * received this file from another source then ask the distributing person for
9 * a log of modifications.
13 /* @(#)apple_driver.c 1.6 04/03/04 joerg */
15 * apple_driver.c: extract Mac partition label, maps and boot driver
17 * Based on Apple_Driver.pl, part of "genisoimage 1.05 PLUS" by Andy Polyakov
18 * <appro@fy.chalmers.se> (I don't know Perl, so I rewrote it C ...)
19 * (see http://fy.chalmers.se/~appro/genisoimage_plus.html for details)
21 * usage: apple_driver CDROM_device > HFS_driver_file
23 * The format of the HFS driver file:
25 * HFS CD Label Block 512 bytes
26 * Driver Partition Map (for 2048 byte blocks) 512 bytes
27 * Driver Partition Map (for 512 byte blocks) 512 bytes
29 * Driver Partition N x 2048 bytes
30 * HFS Partition Boot Block 1024 bytes
32 * By extracting a driver from an Apple CD, you become liable to obey
33 * Apple Computer, Inc. Software License Agreements.
35 * James Pearson 17/5/98
39 #include "genisoimage.h"
40 #include <mac_label.h>
50 | ((p[2] & 0xff) << 8)
51 | ((p[1] & 0xff) << 16)
52 | ((p[0] & 0xff) << 24));
59 | ((p[0] & 0xff) << 8));
71 unsigned char Block0[HFS_BLOCKSZ];
72 unsigned char block[SECTOR_SIZE];
73 unsigned char bootb[2*HFS_BLOCKSZ];
74 unsigned char pmBlock512[HFS_BLOCKSZ];
75 unsigned int sbBlkSize;
76 unsigned int pmPyPartStart;
77 unsigned int pmPartStatus;
78 unsigned int pmMapBlkCnt;
79 int have_boot = 0, have_hfs = 0;
84 save_args(argc, argv);
87 comerrno(EX_BAD, "Usage: %s device-path", argv[0]);
89 if ((fp = fopen(argv[1], "rb")) == NULL)
90 comerr("Can't open '%s'.", argv[1]);
92 if (fread(Block0, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
93 comerr("Can't read '%s'.", argv[1]);
95 mac_label = (MacLabel *)Block0;
96 mac_part = (MacPart *)block;
98 sbBlkSize = get_722((char *)mac_label->sbBlkSize);
100 if (! IS_MAC_LABEL(mac_label) || sbBlkSize != SECTOR_SIZE)
101 comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]);
105 if (fseek(fp, i * HFS_BLOCKSZ, SEEK_SET) != 0)
106 comerr("Ccan't seek %s", argv[1]);
108 if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
109 comerr("Can't read '%s'.", argv[1]);
111 pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt);
113 if (!have_boot && strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) {
114 hfs_start = get_732((char *)mac_part->pmPyPartStart);
116 fprintf(stderr, "%s: found 512 driver partition (at block %d)\n", argv[0], hfs_start);
117 memcpy(pmBlock512, block, HFS_BLOCKSZ);
121 if (!have_hfs && strncmp((char *)mac_part->pmPartType, pmPartType_4, 9) == 0) {
123 hfs_start = get_732((char *)mac_part->pmPyPartStart);
125 if (fseek(fp, hfs_start*HFS_BLOCKSZ, SEEK_SET) != 0)
126 comerr("Can't seek '%s'.", argv[1]);
128 if (fread(bootb, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
129 comerr("Can't read '%s'.", argv[1]);
131 if (get_722((char *)bootb) == 0x4c4b) {
133 fprintf(stderr, "%s: found HFS partition (at blk %d)\n", argv[0], hfs_start);
137 } while (i++ < pmMapBlkCnt);
139 if (!have_hfs || !have_boot)
140 comerrno(EX_BAD, "%s is not a bootable Mac disk", argv[1]);
145 if (fseek(fp, i*sbBlkSize, SEEK_SET) != 0)
146 comerr("Can't seek '%s'.", argv[1]);
148 if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ)
149 comerr("Can't read '%s'.", argv[1]);
151 pmMapBlkCnt = get_732((char *)mac_part->pmMapBlkCnt);
153 if (strncmp((char *)mac_part->pmPartType, pmPartType_2, 12) == 0) {
157 fprintf(stderr, "%s: extracting %s ", argv[0], mac_part->pmPartType);
158 start = get_732((char *)mac_part->pmPyPartStart);
159 num = get_732((char *)mac_part->pmPartBlkCnt);
160 fwrite(Block0, 1, HFS_BLOCKSZ, stdout);
161 fwrite(block, 1, HFS_BLOCKSZ, stdout);
162 fwrite(pmBlock512, 1, HFS_BLOCKSZ, stdout);
163 memset(block, 0, HFS_BLOCKSZ);
164 fwrite(block, 1, HFS_BLOCKSZ, stdout);
166 if (fseek(fp, start*sbBlkSize, SEEK_SET) != 0)
167 comerr("Can't seek '%s'.", argv[1]);
169 for (j = 0; j < num; j++) {
170 if (fread(block, 1, sbBlkSize, fp) != sbBlkSize)
171 comerr("Can't read '%s'.", argv[1]);
173 fwrite(block, 1, sbBlkSize, stdout);
174 fprintf(stderr, ".");
176 fprintf(stderr, "\n");
178 fwrite(bootb, 2, HFS_BLOCKSZ, stdout);
183 if (!IS_MAC_PART(mac_part))
184 comerrno(EX_BAD, "Unable to find boot partition");
186 } while (i++ < pmMapBlkCnt);