wok-next view syslinux/stuff/iso2exe/win32.c @ rev 20197
syslinux: updates from rolling
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Nov 03 15:07:20 2017 +0100 (2017-11-03) |
parents | 6df5e186612d |
children |
line source
1 #include <windows.h>
2 #include <winnt.h>
3 #include <sys/types.h>
4 #include <sys/stat.h>
5 #include <fcntl.h>
7 #define VCPI_LINUX_LOADER The DOS/EXE loader can boot in VM86 using VCPI API
8 #define BOOTSTRAP_SECTOR_COUNT_OFFSET 26
10 static int fullread(int fd, char *p, int n)
11 {
12 int i, j;
13 for (i = 0; n > 0; i += j, n -= j) {
14 j = read(fd, p + i, n);
15 if (j <= 0) break;
16 }
17 return i;
18 #define read fullread
19 }
21 static int fullwrite(int fd, char *p, int n)
22 {
23 int i, j;
24 for (i = 0; n > 0; i += j, n -= j) {
25 j = write(fd, p + i, n);
26 if (j <= 0) break;
27 }
28 return i;
29 #define write fullwrite
30 }
32 #ifdef VCPI_LINUX_LOADER
33 static void exec16bits(char *isoFileName)
34 {
35 int fdiso, fdtmp, i;
36 long buffer[512/4];
37 char tmpFileName[MAX_PATH], *p;
39 strcpy(tmpFileName, isoFileName);
40 p = strrchr(tmpFileName, '\\');
41 if (!p++) p = tmpFileName;
42 strcpy(p, "tazboot.exe");
43 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
44 fdtmp = open(tmpFileName, O_WRONLY|O_BINARY|O_CREAT,0555);
45 for (i = 0; i < 0x8000; i += sizeof(buffer)) {
46 read(fdiso, (char *) buffer, sizeof(buffer));
47 if (i == 0) buffer[15] = 0; // kill PE header
48 write(fdtmp, (char *) buffer, sizeof(buffer));
49 }
50 close(fdiso);
51 close(fdtmp);
52 execl(tmpFileName, isoFileName);
53 }
54 #endif
56 static int iswinnt(void)
57 {
58 OSVERSIONINFOA Version;
59 Version.dwOSVersionInfoSize = sizeof(Version);
60 return (GetVersionEx(&Version) &&
61 Version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); // not Win9x
62 }
64 #define LONG(x) * (unsigned long *) (x)
65 static int ishybrid(char *isoFileName)
66 {
67 int fdiso;
68 char buffer[2048];
69 unsigned long magic = 0;
71 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
72 if (lseek(fdiso, 17 * 2048L, SEEK_SET) != -1 &&
73 read(fdiso, buffer, 2048) == 2048 &&
74 strncmp(buffer+7,"EL TORITO SPECIFICATION",23) == 0) {
75 unsigned long lba = LONG(buffer + 71);
77 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
78 read(fdiso, buffer, 2048) == 2048 &&
79 LONG(buffer + 0) == 1 && LONG(buffer + 30) == 0x88AA55) {
80 lba = LONG(buffer + 40);
81 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
82 read(fdiso, buffer, 2048) == 2048)
83 magic = LONG(buffer + 64);
84 }
85 }
86 close(fdiso);
87 return (magic == 1886961915);
88 }
90 static char buffer[512];
92 #define MODE_READ 0
93 #define MODE_WRITE 1
94 static int rdwrsector(int mode, int drive, unsigned long startingsector)
95 {
96 HANDLE hDevice;
97 DWORD result;
98 char devname[sizeof("\\\\.\\PhysicalDrive0")];
100 if (drive >= 128) {
101 strcpy(devname, "\\\\.\\PhysicalDrive0");
102 devname[17] += drive - 128;
103 }
104 else {
105 strcpy(devname, "\\\\.\\A:");
106 devname[4] += drive;
107 }
108 hDevice = CreateFile (devname, (mode == MODE_READ) ? GENERIC_READ : GENERIC_WRITE,
109 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
110 if (hDevice == INVALID_HANDLE_VALUE)
111 return -1;
112 SetFilePointer(hDevice, (startingsector*512), NULL, FILE_BEGIN);
113 if (mode == MODE_READ) {
114 if (!ReadFile(hDevice, buffer, 512, &result, NULL))
115 result = -1;
116 }
117 else {
118 if (!WriteFile(hDevice, buffer, 512, &result, NULL))
119 result = -1;
120 }
121 CloseHandle(hDevice);
122 return result;
123 }
125 static int rawrite(unsigned long drive, char *isoFileName)
126 {
127 int fdiso, s, dev;
129 if (drive == 0) return;
130 for (dev = 128; (drive & 1) == 0; dev++)
131 drive >>= 1;
132 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
133 for (s = 0;; s++) {
134 int n = read(fdiso, buffer, sizeof(buffer));
135 if (n <= 0) break;
136 rdwrsector(MODE_WRITE, dev, s);
137 }
138 close(fdiso);
139 return dev;
140 }
142 static unsigned long drives(void)
143 {
144 int i, mask, result;
146 for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) {
147 if (rdwrsector(MODE_READ, i+128, 0) != -1)
148 result |= mask;
149 }
150 return result;
151 }
153 static void writefloppy(char *isoFileName)
154 {
155 int i, n, fd;
157 buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
158 fd = open(isoFileName, O_RDONLY|O_BINARY);
159 if (fd != -1) {
160 read(fd, buffer, sizeof(buffer));
161 n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET];
162 if (n != 0 &&
163 lseek(fd, * (unsigned short *) (buffer + 66) - (512 * n),
164 SEEK_SET) != -1) {
165 for (i = 0; i <= n; i++) {
166 if (i == 1) strncpy(buffer, isoFileName, 512);
167 else read(fd, buffer, 512);
168 rdwrsector(MODE_WRITE, 0, i);
169 }
170 }
171 close(fd);
172 }
173 }
175 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
176 LPSTR lpCmdLine, int nCmdShow)
177 {
178 char isoFileName[MAX_PATH];
179 char header[32];
180 int fd;
181 int usbkeyicon = MB_ICONASTERISK;
182 char *usbkeymsg = "You can either:\n\n"
183 "- create a SliTaz USB boot key or a boot memory card.\n"
184 " (note that this will be read only like a CDROM.\n"
185 " The Slitaz utility 'tazusb' can be used later to create\n"
186 " a true read/write USB key).\n\n"
187 "- create a SliTaz bootstrap floppy for the ISO image\n"
188 " on the hard disk.\n"
189 "\nDo you want to create a boot key now ?";
191 GetModuleFileName(hInstance, isoFileName, MAX_PATH);
192 if (!iswinnt()) {
193 #ifdef VCPI_LINUX_LOADER
194 exec16bits(isoFileName);
195 #else
196 MessageBox(NULL,"No support for Win9x yet.\n"
197 "Retry in DOS mode without emm386.\n",
198 "Sorry", MB_OK|MB_ICONERROR);
199 exit(1);
200 #endif
201 }
202 if (!ishybrid(isoFileName)) {
203 if (MessageBox(NULL,"Not an isolinux hybrid ISO.\n"
204 "This ISO image will not boot\n"
205 "from the media that you create !",
206 "Will not boot !",
207 MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL)
208 exit(0);
209 }
210 header[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
211 fd = open(isoFileName, O_RDONLY|O_BINARY);
212 if (fd != -1) {
213 read(fd, header, sizeof(header));
214 close(fd);
215 }
216 if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available
217 usbkeyicon = MB_ICONQUESTION;
218 usbkeymsg =
219 "You can create a SliTaz USB boot key or\n"
220 "a boot memory card.\n"
221 "(note that this will be read only like\n"
222 "a CDROM. The Slitaz utility 'tazusb'\n"
223 "can be used later to create a true\n"
224 "read/write USB key).\n"
225 "\nDo you want to create a boot key now ?";
226 }
227 if (MessageBox(NULL,usbkeymsg, "Create a boot stick ?",
228 MB_YESNO|usbkeyicon) == IDYES) {
229 unsigned long base, new;
230 int retry;
232 if (MessageBox(NULL,"Step 1: unplug the USB stick.",
233 "Drive detection 1/2",
234 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
235 exit(0);
236 base = drives();
237 if (MessageBox(NULL,"Step 2: plug the USB stick in, "
238 "wait for Windows to mount it",
239 "Drive detection 2/2",
240 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
241 exit(0);
242 retry = 0;
243 do {
244 Sleep(1000); // ms
245 new = drives();
246 } while (new == base && retry++ < 10);
247 if (new == base) {
248 MessageBox(NULL,"No USB stick found.","Sorry",
249 MB_OK|MB_ICONERROR);
250 }
251 else {
252 char *msg = "(hd0) is up to date.";
253 msg[3] += rawrite(base ^ new, isoFileName) - 128;
254 MessageBox(NULL,msg,"Finished",MB_OK);
255 }
256 }
257 else if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 &&
258 MessageBox(NULL,"Do you want to create a bootstrap floppy ?",
259 "Create a bootstrap floppy ?",
260 MB_YESNO|MB_ICONQUESTION) == IDYES &&
261 MessageBox(NULL,"Insert a floppy disk in drive now",
262 "Insert floppy",
263 MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) {
265 // Create a 9k bootstrap with vfat, ext2 & ntfs drivers
266 // to boot the ISO image on hard disk
267 writefloppy(isoFileName);
268 MessageBox(NULL,"The bootstrap floppy is up to date.",
269 "Finished",MB_OK);
270 }
271 }