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 }
|