1 /* 2 ** apple_driver.c: extract Mac partition label, maps and boot driver 3 ** 4 ** Based on Apple_Driver.pl, part of "mkisofs 1.05 PLUS" by Andy Polyakov 5 ** <appro@fy.chalmers.se> (I don't know Perl, so I rewrote it C ...) 6 ** (see http://fy.chalmers.se/~appro/mkisofs_plus.html for details) 7 ** 8 ** usage: apple_driver CDROM_device > HFS_driver_file 9 ** 10 ** The format of the HFS driver file: 11 ** 12 ** HFS CD Label Block 512 bytes 13 ** Driver Partition Map (for 2048 byte blocks) 512 bytes 14 ** Driver Partition Map (for 512 byte blocks) 512 bytes 15 ** Empty 512 bytes 16 ** Driver Partition N x 2048 bytes 17 ** HFS Partition Boot Block 1024 bytes 18 ** 19 ** By extracting a driver from an Apple CD, you become liable to obey 20 ** Apple Computer, Inc. Software License Agreements. 21 ** 22 ** James Pearson 17/5/98 23 */ 24 25 #include <config.h> 26 #include <mkisofs.h> 27 #include <mac_label.h> 28 29 int 30 get_732(char *p) 31 { 32 return ((p[3] & 0xff) 33 | ((p[2] & 0xff) << 8) 34 | ((p[1] & 0xff) << 16) 35 | ((p[0] & 0xff) << 24)); 36 } 37 38 int 39 get_722(char *p) 40 { 41 return ((p[1] & 0xff) 42 | ((p[0] & 0xff) << 8)); 43 } 44 45 46 main(int argc, char **argv) 47 { 48 FILE *fp; 49 MacLabel *mac_label; 50 MacPart *mac_part; 51 unsigned char Block0[HFS_BLOCKSZ]; 52 unsigned char block[SECTOR_SIZE]; 53 unsigned char bootb[2*HFS_BLOCKSZ]; 54 unsigned char pmBlock512[HFS_BLOCKSZ]; 55 unsigned int sbBlkSize; 56 unsigned int pmPyPartStart; 57 unsigned int pmPartStatus; 58 unsigned int pmMapBlkCnt; 59 int have_boot = 0, have_hfs = 0; 60 int hfs_start; 61 int i, j; 62 63 64 if (argc != 2) 65 perr(argv[0], "Usage: %s device-path", argv[0]); 66 67 if ((fp = fopen(argv[1], "rb")) == NULL) 68 perr(argv[0], "can't open %s", argv[1]); 69 70 if (fread(Block0, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) 71 perr(argv[0], "can't read %s", argv[1]); 72 73 mac_label = (MacLabel *)Block0; 74 mac_part = (MacPart *)block; 75 76 sbBlkSize = get_722(mac_label->sbBlkSize); 77 78 if (! IS_MAC_LABEL(mac_label) || sbBlkSize != SECTOR_SIZE) 79 perr(argv[0], "%s is not a bootable Mac disk", argv[1]); 80 81 i = 1; 82 do { 83 if (fseek(fp, i * HFS_BLOCKSZ, 0) != 0) 84 perr(argv[0], "can't seek %s", argv[1]); 85 86 if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) 87 perr(argv[0], "can't read %s", argv[1]); 88 89 pmMapBlkCnt = get_732(mac_part->pmMapBlkCnt); 90 91 if (!have_boot && !strncmp(mac_part->pmPartType, pmPartType_2, 12)) { 92 hfs_start = get_732(mac_part->pmPyPartStart); 93 94 fprintf(stderr, "%s: found 512 driver partition (at block %d)\n", argv[0], hfs_start); 95 memcpy(pmBlock512, block, HFS_BLOCKSZ); 96 have_boot = 1; 97 } 98 99 if (!have_hfs && !strncmp(mac_part->pmPartType, pmPartType_4, 9)) { 100 101 hfs_start = get_732(mac_part->pmPyPartStart); 102 103 if (fseek(fp, hfs_start*HFS_BLOCKSZ, 0) != 0) 104 perr(argv[0], "can't seek %s", argv[1]); 105 106 if (fread(bootb, 2, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) 107 perr(argv[0], "can't read %s", argv[1]); 108 109 if (get_722(bootb) == 0x4c4b) { 110 111 fprintf(stderr, "%s: found HFS partition (at blk %d)\n", argv[0], hfs_start); 112 have_hfs = 1; 113 } 114 } 115 } while (i++ < pmMapBlkCnt); 116 117 if (!have_hfs || !have_boot) 118 perr(argv[0], "%s is not a bootable Mac disk", argv[1]); 119 120 i = 1; 121 122 do { 123 if (fseek(fp, i*sbBlkSize, 0) != 0) 124 perr(argv[0], "can't seek %s", argv[1]); 125 126 if (fread(block, 1, HFS_BLOCKSZ, fp) != HFS_BLOCKSZ) 127 perr(argv[0], "can't read %s", argv[1]); 128 129 pmMapBlkCnt = get_732(mac_part->pmMapBlkCnt); 130 131 if (!strncmp(mac_part->pmPartType, pmPartType_2, 12)) { 132 133 int start, num; 134 135 fprintf(stderr, "%s: extracting %s ", argv[0], mac_part->pmPartType); 136 start = get_732(mac_part->pmPyPartStart); 137 num = get_732(mac_part->pmPartBlkCnt); 138 fwrite(Block0, 1, HFS_BLOCKSZ, stdout); 139 fwrite(block, 1, HFS_BLOCKSZ, stdout); 140 fwrite(pmBlock512, 1, HFS_BLOCKSZ, stdout); 141 memset(block, 0, HFS_BLOCKSZ); 142 fwrite(block, 1, HFS_BLOCKSZ, stdout); 143 144 if (fseek(fp, start*sbBlkSize, 0) != 0) 145 perr(argv[0], "can't seek %s", argv[1]); 146 147 for (j=0;j<num;j++) { 148 if (fread(block, 1, sbBlkSize, fp) != sbBlkSize) 149 perr(argv[0], "can't read %s", argv[1]); 150 151 fwrite(block, 1, sbBlkSize, stdout); 152 fprintf(stderr, "."); 153 } 154 fprintf(stderr, "\n"); 155 156 fwrite(bootb, 2, HFS_BLOCKSZ, stdout); 157 fclose(fp); 158 exit (0); 159 } 160 161 if (! IS_MAC_PART(mac_part) ) 162 perr(argv[0], "unable to find boot partition", 0); 163 164 } while (i++ < pmMapBlkCnt); 165 166 167 } 168 169 perr(char *a, char *b, char *c) 170 { 171 fprintf(stderr, "%s: ", a); 172 fprintf(stderr, b, c); 173 fprintf(stderr, "\n"); 174 exit (1); 175 } 176