wok-next annotate syslinux/stuff/iso2exe/iso2exe.c @ rev 16055

syslinux/iso2exe: fix 'a la tazusb' install
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Mar 11 15:44:47 2014 +0000 (2014-03-11)
parents 19258b949c1b
children aca562aa836e
rev   line source
pascal@14150 1 #include <sys/types.h>
pascal@14150 2 #include <fcntl.h>
pascal@14150 3 #include <stdio.h>
pascal@14268 4 #ifdef WIN32
pascal@14268 5 #include <windows.h>
pascal@14268 6 #endif
pascal@14150 7 #include "iso2exe.h"
pascal@14150 8
pascal@16055 9 static int fd, forced, status = 1;
pascal@14264 10 static char tazlitoinfo[10*1024];
pascal@14264 11 #define buffer tazlitoinfo
pascal@14264 12 #define BUFFERSZ 2048
pascal@14150 13
pascal@14150 14 static void readsector(unsigned long sector)
pascal@14150 15 {
pascal@14264 16 if (lseek(fd, sector * BUFFERSZ, SEEK_SET) == -1 ||
pascal@14268 17 read(fd, buffer, BUFFERSZ) != BUFFERSZ) {
pascal@14268 18 puts("Read sector failure.\n");
pascal@14268 19 exit(1);
pascal@14268 20 }
pascal@14150 21 }
pascal@14150 22
pascal@14268 23 static char *install(char *filename)
pascal@14150 24 {
pascal@14150 25 #define heads 64
pascal@14150 26 #define sectors 32
pascal@14150 27 #define partition 446
pascal@14150 28 #define trksz (512 * heads * sectors)
pascal@14150 29 unsigned long size, catalog, lba;
pascal@14261 30 int cylinders, i, j, isohybrid;
pascal@14150 31 unsigned n;
pascal@14150 32 #ifndef WIN32
pascal@14150 33 char *bootiso;
pascal@14268 34 for (bootiso = (char *) install;
pascal@14150 35 bootiso[0] != 'M' || bootiso[1] != 'Z' || bootiso[2] != 0xEB;
pascal@14268 36 bootiso++) if (bootiso < (char *) install) return "No bootiso data.\n";
pascal@14150 37 #endif
pascal@14268 38 if (!filename)
pascal@16055 39 return "Usage: isohybrid.exe file.iso [--forced]\n";
pascal@14268 40 fd = open(filename,O_RDWR|O_BINARY);
pascal@14150 41 if (fd == -1)
pascal@14268 42 return "Can't open rw the iso file.\n";
pascal@14150 43
pascal@16055 44 if (forced == 0) {
pascal@16055 45 status = 2;
pascal@16055 46 // Install hybridiso boot sector
pascal@16055 47 readsector(17UL);
pascal@16055 48 if (strncmp(buffer+7, "EL TORITO SPECIFICATION", 23))
pascal@16055 49 return "No EL TORITO signature.\n";
pascal@16055 50 catalog = * (unsigned long *) (buffer + 71);
pascal@16055 51 readsector(catalog);
pascal@16055 52 if (* (unsigned long *) buffer != 1 ||
pascal@16055 53 * (unsigned long *) (buffer + 30) != 0x88AA55)
pascal@16055 54 return "Invalid boot catalog.\n";
pascal@16055 55 lba = * (unsigned long *) (buffer + 40);
pascal@16055 56 readsector(lba);
pascal@16055 57 if (* (unsigned long *) (buffer + 64) != 1886961915)
pascal@16055 58 return "No isolinux.bin hybrid signature.\n";
pascal@16055 59 isohybrid = bootiso[69] * 512;
pascal@16055 60 * (unsigned long *) &bootiso[isohybrid + 432] = lba * 4;
pascal@16055 61 * (unsigned long *) &bootiso[isohybrid + 440] = rand();
pascal@16055 62 * (unsigned long *) &bootiso[isohybrid + partition] = 0x10080;
pascal@16055 63 * (unsigned short *) &bootiso[isohybrid + 510] = 0xAA55;
pascal@16055 64 size = lseek(fd, 0UL, SEEK_END);
pascal@16055 65 cylinders = (size + trksz - 1) / trksz;
pascal@16055 66 bootiso[isohybrid + partition + 4] = 23; // "Windows hidden IFS"
pascal@16055 67 bootiso[isohybrid + partition + 5] = heads - 1;
pascal@16055 68 bootiso[isohybrid + partition + 6] = (((cylinders - 1) & 0x300) >> 2) + sectors;
pascal@16055 69 bootiso[isohybrid + partition + 7] = (cylinders - 1) & 0xFF;
pascal@16055 70 * (unsigned long *) &bootiso[isohybrid + partition + 8] = 0;
pascal@16055 71 * (unsigned long *) &bootiso[isohybrid + partition + 12] = cylinders * sectors * heads;
pascal@14150 72
pascal@16055 73 // Copy the partition table
pascal@16055 74 memcpy(bootiso + 0x1BE, bootiso + isohybrid + 0x1BE, 66);
pascal@16055 75 }
pascal@14266 76
pascal@14150 77 // Install iso2exe boot sector
pascal@14150 78 * (unsigned short *) (bootiso + 26) = rand();
pascal@14150 79
pascal@14261 80 // read tazlito flavor data
pascal@14261 81 lseek(fd, 1024UL, SEEK_SET);
pascal@14261 82 read(fd, tazlitoinfo, sizeof(tazlitoinfo));
pascal@14261 83
pascal@14150 84 // Update iso image
pascal@14261 85 n = (bootiso[69] + 1) * 512;
pascal@14151 86 lseek(fd, 0UL, SEEK_SET);
pascal@14261 87 write(fd, bootiso, n); // EXE/PE + isohybrid mbr
pascal@14261 88 write(fd, tazlitoinfo, ((0x8000U - BOOTISOSZ) > sizeof(tazlitoinfo))
pascal@14261 89 ? sizeof(tazlitoinfo) : (0x8000U - BOOTISOSZ));
pascal@14261 90 write(fd, bootiso + n, BOOTISOSZ - n); // COM + rootfs + EXE/DOS
pascal@14150 91
pascal@14150 92 // Compute the checksum
pascal@14151 93 lseek(fd, 0UL, SEEK_SET);
pascal@14150 94 for (i = 66, n = 0, j = 0; j < 16; j++, i = 0) {
pascal@14264 95 if (read(fd, buffer, BUFFERSZ) != BUFFERSZ)
pascal@14150 96 goto nochksum;
pascal@14264 97 for (; i < BUFFERSZ; i += 2)
pascal@14150 98 n += * (unsigned short *) (buffer + i);
pascal@14150 99 }
pascal@14150 100 * (unsigned short *) (bootiso + 64) = -n;
pascal@14151 101 lseek(fd, 0UL, SEEK_SET);
pascal@14150 102 write(fd, bootiso, 512);
pascal@14150 103 nochksum:
pascal@14150 104 close(fd);
pascal@14268 105 status = 0;
pascal@14268 106 return "Now you can create a USB key with your .iso file.\n"
pascal@14268 107 "Simply rename it to a .exe file and run it.\n";
pascal@14150 108 }
pascal@14268 109
pascal@14268 110 int main(int argc, char *argv[])
pascal@14268 111 {
pascal@16055 112 forced = (argc > 2);
pascal@14268 113 puts(install(argv[1]));
pascal@16055 114 if (status > 1)
pascal@16055 115 puts("You can add --forced to proceed anayway");
pascal@14268 116 #ifdef WIN32
pascal@14268 117 Sleep(2000);
pascal@14268 118 #endif
pascal@14268 119 return status;
pascal@14268 120 }