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

syslinux/iso2exe: add --undo
author Pascal Bellard <pascal.bellard@slitaz.org>
date Wed Dec 17 12:25:20 2014 +0100 (2014-12-17)
parents 9c889f88b9fd
children 054f70cb9bec
rev   line source
pascal@17451 1 #ifdef __TURBOC__
pascal@17451 2 #include <io.h>
pascal@17451 3 #endif
pascal@14150 4 #include <sys/types.h>
pascal@14150 5 #include <fcntl.h>
pascal@14150 6 #include <stdio.h>
pascal@17451 7 #include <stdlib.h>
pascal@17451 8 #include <string.h>
pascal@14268 9 #ifdef WIN32
pascal@14268 10 #include <windows.h>
pascal@14268 11 #endif
pascal@14150 12 #include "iso2exe.h"
pascal@14150 13
pascal@16055 14 static int fd, forced, status = 1;
pascal@14264 15 static char tazlitoinfo[10*1024];
pascal@14264 16 #define buffer tazlitoinfo
pascal@14264 17 #define BUFFERSZ 2048
pascal@17451 18 #define WORD(n) * (unsigned short *) (n)
pascal@17451 19 #define LONG(n) * (unsigned long *) (n)
pascal@14150 20
pascal@14150 21 static void readsector(unsigned long sector)
pascal@14150 22 {
pascal@14264 23 if (lseek(fd, sector * BUFFERSZ, SEEK_SET) == -1 ||
pascal@14268 24 read(fd, buffer, BUFFERSZ) != BUFFERSZ) {
pascal@17451 25 puts(bootiso+READSECTORERR);
pascal@14268 26 exit(1);
pascal@14268 27 }
pascal@14150 28 }
pascal@14150 29
pascal@17451 30 static unsigned install(char *filename)
pascal@14150 31 {
pascal@14150 32 #define heads 64
pascal@14150 33 #define sectors 32
pascal@14150 34 #define partition 446
pascal@17451 35 #define trksz (512UL * heads * sectors)
pascal@14150 36 unsigned long size, catalog, lba;
pascal@14261 37 int cylinders, i, j, isohybrid;
pascal@14150 38 unsigned n;
pascal@14150 39 #ifndef WIN32
pascal@14268 40 for (bootiso = (char *) install;
pascal@17451 41 bootiso[0] != 'M' || bootiso[1] != 'Z' || bootiso[2] != '\xEB';
pascal@17451 42 bootiso++) if (bootiso < (char *) install) {
pascal@17451 43 bootiso = "No bootiso data";
pascal@17451 44 return 0;
pascal@17451 45 }
pascal@14150 46 #endif
pascal@14268 47 if (!filename)
pascal@17451 48 return USAGE;
pascal@14268 49 fd = open(filename,O_RDWR|O_BINARY);
pascal@14150 50 if (fd == -1)
pascal@17451 51 return OPENERR;
pascal@14150 52
pascal@16055 53 if (forced == 0) {
pascal@16055 54 status = 2;
pascal@17451 55 /* Install hybridiso boot sector */
pascal@16055 56 readsector(17UL);
pascal@17451 57 if (strncmp(buffer+7, bootiso+ELTORITOERR+ELTORITOOFS, 23))
pascal@17451 58 return ELTORITOERR;
pascal@17451 59 catalog = LONG(buffer + 71);
pascal@16055 60 readsector(catalog);
pascal@17451 61 if (LONG(buffer) != 1 || LONG(buffer + 30) != 0x88AA55UL)
pascal@17451 62 return CATALOGERR;
pascal@17451 63 lba = LONG(buffer + 40);
pascal@16055 64 readsector(lba);
pascal@17451 65 if (LONG(buffer + 64) != 1886961915UL)
pascal@17451 66 return HYBRIDERR;
pascal@16055 67 isohybrid = bootiso[69] * 512;
pascal@17451 68 LONG(bootiso + isohybrid + 432) = lba * 4;
pascal@17451 69 LONG(bootiso + isohybrid + 440) = rand();
pascal@17451 70 LONG(bootiso + isohybrid + partition) = 0x10080UL;
pascal@17451 71 WORD(bootiso + isohybrid + 510) = 0xAA55U;
pascal@16055 72 size = lseek(fd, 0UL, SEEK_END);
pascal@16055 73 cylinders = (size + trksz - 1) / trksz;
pascal@17451 74 bootiso[isohybrid + partition + 4] = 23; /* "Windows hidden IFS" */
pascal@16055 75 bootiso[isohybrid + partition + 5] = heads - 1;
pascal@16055 76 bootiso[isohybrid + partition + 6] = (((cylinders - 1) & 0x300) >> 2) + sectors;
pascal@16055 77 bootiso[isohybrid + partition + 7] = (cylinders - 1) & 0xFF;
pascal@17451 78 LONG(bootiso + isohybrid + partition + 8) = 0;
pascal@17451 79 LONG(bootiso + isohybrid + partition + 12) = cylinders * sectors * heads;
pascal@14150 80
pascal@17451 81 /* Copy the partition table */
pascal@16055 82 memcpy(bootiso + 0x1BE, bootiso + isohybrid + 0x1BE, 66);
pascal@16055 83 }
pascal@14266 84
pascal@17451 85 /* Install iso2exe boot sector */
pascal@17451 86 WORD(bootiso + 26) = rand();
pascal@14150 87
pascal@17451 88 /* read tazlito flavor data */
pascal@14261 89 lseek(fd, 1024UL, SEEK_SET);
pascal@14261 90 read(fd, tazlitoinfo, sizeof(tazlitoinfo));
pascal@14261 91
pascal@17451 92 /* Update iso image */
pascal@14261 93 n = (bootiso[69] + 1) * 512;
pascal@14151 94 lseek(fd, 0UL, SEEK_SET);
pascal@17451 95 write(fd, bootiso, n); /* EXE/PE + isohybrid mbr */
pascal@14261 96 write(fd, tazlitoinfo, ((0x8000U - BOOTISOSZ) > sizeof(tazlitoinfo))
pascal@14261 97 ? sizeof(tazlitoinfo) : (0x8000U - BOOTISOSZ));
pascal@17451 98 write(fd, bootiso + n, BOOTISOSZ - n); /* COM + rootfs + EXE/DOS */
pascal@14150 99
pascal@17451 100 /* Compute the checksum */
pascal@14151 101 lseek(fd, 0UL, SEEK_SET);
pascal@14150 102 for (i = 66, n = 0, j = 0; j < 16; j++, i = 0) {
pascal@14264 103 if (read(fd, buffer, BUFFERSZ) != BUFFERSZ)
pascal@14150 104 goto nochksum;
pascal@14264 105 for (; i < BUFFERSZ; i += 2)
pascal@17451 106 n += WORD(buffer + i);
pascal@14150 107 }
pascal@17451 108 WORD(bootiso + 64) = -n;
pascal@14151 109 lseek(fd, 0UL, SEEK_SET);
pascal@14150 110 write(fd, bootiso, 512);
pascal@14150 111 nochksum:
pascal@14150 112 close(fd);
pascal@14268 113 status = 0;
pascal@17451 114 return SUCCESSMSG;
pascal@14150 115 }
pascal@14268 116
pascal@14268 117 int main(int argc, char *argv[])
pascal@14268 118 {
pascal@16055 119 forced = (argc > 2);
pascal@17451 120 puts(bootiso + install(argv[1]));
pascal@16055 121 if (status > 1)
pascal@17451 122 puts(bootiso + FORCEMSG);
pascal@14268 123 #ifdef WIN32
pascal@14268 124 Sleep(2000);
pascal@14268 125 #endif
pascal@14268 126 return status;
pascal@14268 127 }