wok-6.x view syslinux/stuff/iso2exe/win32.c @ rev 23820
syslinux: merge init.exe & taziso
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Thu May 28 08:35:55 2020 +0000 (2020-05-28) |
parents | 87b6697bb350 |
children | 2ac466d9d0a7 |
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 BOOTSTRAP_SECTOR_COUNT_OFFSET 26
9 static int fullread(int fd, char *p, int n)
10 {
11 int i, j;
12 for (i = 0; n > 0; i += j, n -= j) {
13 j = read(fd, p + i, n);
14 if (j <= 0) break;
15 }
16 return i;
17 #define read fullread
18 }
20 static int fullwrite(int fd, char *p, int n)
21 {
22 int i, j;
23 for (i = 0; n > 0; i += j, n -= j) {
24 j = write(fd, p + i, n);
25 if (j <= 0) break;
26 }
27 return i;
28 #define write fullwrite
29 }
31 #pragma pack(push,1)
32 struct PIF_section_header {
33 char name[16];
34 short next_header_offset;
35 short data_offset;
36 short data_length;
37 };
39 struct PIF_basic_section {
40 unsigned char unused;
41 unsigned char checksum;
42 char window_title[30];
43 unsigned short max_mem;
44 unsigned short min_mem;
45 char program_filename[63];
46 unsigned short bitmask;
47 char working_directory[64];
48 char parameters_string[64];
49 unsigned char video_mode;
50 unsigned char video_pages;
51 unsigned char first_interrupt;
52 unsigned char last_interrupt;
53 unsigned char height_screen;
54 unsigned char width_screen;
55 unsigned char horizontal_pos;
56 unsigned char vertical_pos;
57 unsigned short last_text_page;
58 char unused2[128];
59 unsigned short bitmask2;
60 };
62 struct PIF_section_win_386_3_0 {
63 unsigned short max_mem;
64 unsigned short min_mem;
65 unsigned short active_priority;
66 unsigned short background_priority;
67 unsigned short max_ems;
68 unsigned short required_ems;
69 unsigned short max_xms;
70 unsigned short required_xms;
71 unsigned long bitmask;
72 unsigned short bitmask2;
73 unsigned short unknown;
74 unsigned short shortcut_key_code;
75 unsigned short shortcut_key_modifier;
76 unsigned short shortcut_key_use;
77 unsigned short shortcut_key_scan;
78 unsigned short unknown2;
79 unsigned short unknown3;
80 unsigned long unknown4;
81 char parameters_string[64];
82 };
84 struct PIF_section_win_vmm_4_0 {
85 char unknown[88];
86 char iconfile[80];
87 unsigned short icon_number;
88 unsigned short bitmask;
89 char unknown2[10];
90 unsigned short priority;
91 unsigned short bitmask2; // video
92 char unknown3[8];
93 unsigned short text_lines;
94 unsigned short bitmask3; // Key modifiers
95 unsigned short unknown4;
96 unsigned short unknown5;
97 unsigned short unknown6;
98 unsigned short unknown7;
99 unsigned short unknown8;
100 unsigned short unknown9;
101 unsigned short unknown10;
102 unsigned short unknown11;
103 unsigned short bitmask4; // Mouse
104 char unknown12[6];
105 unsigned short bitmask5; // Fonts
106 unsigned short unknown13;
107 unsigned short rasterfontHsize;
108 unsigned short rasterfontVsize;
109 unsigned short fontHsize;
110 unsigned short fontVsize;
111 char raster_name[32];
112 char truetype_name[32];
113 unsigned short unknown14;
114 unsigned short bitmask6;
115 unsigned short restore_settings;
116 unsigned short Hsize;
117 unsigned short Vsize;
118 unsigned short HsizePixelsClient;
119 unsigned short VsizePixelsClient;
120 unsigned short HsizePixels;
121 unsigned short VsizePixels;
122 unsigned short unknown15;
123 unsigned short bitmask7;
124 unsigned short maximized;
125 char unknown16[4];
126 char window_geom[16];
127 char bat_file_name[80];
128 unsigned short env_size;
129 unsigned short dpmi_size;
130 unsigned short unknown17;
131 };
133 static struct {
134 struct PIF_basic_section s0;
135 struct PIF_section_header h0;
136 struct PIF_section_header h1;
137 struct PIF_section_win_386_3_0 s1;
138 struct PIF_section_header h2;
139 struct PIF_section_win_vmm_4_0 s2;
140 } PIF_content = {
141 { 0, 0x78, "MS-DOS Prompt ", 640, 0, "" /*slitaz.exe*/,
142 0x10, "", "", 0, 1, 0, 255, 25, 80, 0, 0, 7, "", 0 },
143 { "MICROSOFT PIFEX", sizeof(struct PIF_basic_section)
144 + sizeof(struct PIF_section_header), 0,
145 sizeof(struct PIF_basic_section) },
146 { "WINDOWS 386 3.0", sizeof(struct PIF_basic_section)
147 + 2*sizeof(struct PIF_section_header)
148 + sizeof(struct PIF_section_win_386_3_0),
149 sizeof(struct PIF_basic_section)
150 + 2*sizeof(struct PIF_section_header),
151 sizeof(struct PIF_section_win_386_3_0) },
152 { 640, 0, 100, 50, 65535, 0, 65535, 0, 0x10821002, 31, 0, 0, 0, 0, 0, 0,
153 0, 0, "" },
154 { "WINDOWS VMM 4.0", 65535, sizeof(struct PIF_basic_section)
155 + 3*sizeof(struct PIF_section_header)
156 + sizeof(struct PIF_section_win_386_3_0),
157 sizeof(struct PIF_section_win_vmm_4_0) },
158 { "", "PIFMGR.DLL", 0, 2, "", 50, 1, "", 0, 1, 0, 5, 25, 3, 0xC8,
159 0x3E8, 2, 10, 1, "", 28, 0, 0, 0, 7, 12, "Terminal", "Courier New",
160 0, 3, 0, 80, 25, 0x250, 0x140, 0, 0, 22, 0, 0, "", "", "", 0, 0, 1 }
161 };
162 #pragma pack(pop)
164 static void exec16bits(char *isoFileName)
165 {
166 int fd;
167 const char pifFileName[] = "slitaz.pif";
169 strcpy(PIF_content.s0.program_filename, isoFileName);
170 fd = open(pifFileName, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0555);
171 write(fd,&PIF_content,sizeof(PIF_content));
172 close(fd);
173 WinExec(pifFileName, SW_MINIMIZE);
174 exit(0);
175 }
177 static int iswinnt(void)
178 {
179 OSVERSIONINFOA Version;
180 Version.dwOSVersionInfoSize = sizeof(Version);
181 return (GetVersionEx(&Version) &&
182 Version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); // not Win9x
183 }
185 #define LONG(x) * (unsigned long *) (x)
186 static int ishybrid(char *isoFileName)
187 {
188 int fdiso;
189 char buffer[2048];
190 unsigned long magic = 0;
192 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
193 if (lseek(fdiso, 17 * 2048L, SEEK_SET) != -1 &&
194 read(fdiso, buffer, 2048) == 2048 &&
195 strncmp(buffer+7,"EL TORITO SPECIFICATION",23) == 0) {
196 unsigned long lba = LONG(buffer + 71);
198 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
199 read(fdiso, buffer, 2048) == 2048 &&
200 LONG(buffer + 0) == 1 && LONG(buffer + 30) == 0x88AA55) {
201 lba = LONG(buffer + 40);
202 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
203 read(fdiso, buffer, 2048) == 2048)
204 magic = LONG(buffer + 64);
205 }
206 }
207 close(fdiso);
208 return (magic == 1886961915);
209 }
211 static char buffer[512];
213 #define MODE_READ 0
214 #define MODE_WRITE 1
215 static int rdwrsector(int mode, int drive, unsigned long startingsector)
216 {
217 HANDLE hDevice;
218 DWORD result;
219 char devname[sizeof("\\\\.\\PhysicalDrive0")];
221 if (drive >= 128) {
222 strcpy(devname, "\\\\.\\PhysicalDrive0");
223 devname[17] += drive - 128;
224 }
225 else {
226 strcpy(devname, "\\\\.\\A:");
227 devname[4] += drive;
228 }
229 hDevice = CreateFile (devname, (mode == MODE_READ) ? GENERIC_READ : GENERIC_WRITE,
230 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
231 if (hDevice == INVALID_HANDLE_VALUE)
232 return -1;
233 SetFilePointer(hDevice, (startingsector*512), NULL, FILE_BEGIN);
234 if (mode == MODE_READ) {
235 if (!ReadFile(hDevice, buffer, 512, &result, NULL))
236 result = -1;
237 }
238 else {
239 if (!WriteFile(hDevice, buffer, 512, &result, NULL))
240 result = -1;
241 }
242 CloseHandle(hDevice);
243 return result;
244 }
246 static int rawrite(unsigned long drive, char *isoFileName)
247 {
248 int fdiso, s, dev;
250 if (drive == 0) return;
251 for (dev = 128; (drive & 1) == 0; dev++)
252 drive >>= 1;
253 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
254 for (s = 0;; s++) {
255 int n = read(fdiso, buffer, sizeof(buffer));
256 if (n <= 0) break;
257 rdwrsector(MODE_WRITE, dev, s);
258 }
259 close(fdiso);
260 return dev;
261 }
263 static unsigned long drives(void)
264 {
265 int i, mask, result;
267 for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) {
268 if (rdwrsector(MODE_READ, i+128, 0) != -1)
269 result |= mask;
270 }
271 return result;
272 }
274 static void writefloppy(char *isoFileName)
275 {
276 int i, n, fd;
278 buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
279 fd = open(isoFileName, O_RDONLY|O_BINARY);
280 if (fd != -1) {
281 read(fd, buffer, sizeof(buffer));
282 n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET];
283 if (n != 0 &&
284 lseek(fd, * (unsigned short *) (buffer + 66) - (512 * n),
285 SEEK_SET) != -1) {
286 for (i = 0; i <= n; i++) {
287 if (i == 1) strncpy(buffer, isoFileName, 512);
288 else read(fd, buffer, 512);
289 rdwrsector(MODE_WRITE, 0, i);
290 }
291 }
292 close(fd);
293 }
294 }
296 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
297 LPSTR lpCmdLine, int nCmdShow)
298 {
299 char isoFileName[MAX_PATH];
300 char header[32];
301 int fd;
302 int usbkeyicon = MB_ICONASTERISK;
303 char *usbkeymsg = "You can either:\n\n"
304 "- create a SliTaz USB boot key or a boot memory card.\n"
305 " (note that this will be read only like a CDROM.\n"
306 " The Slitaz utility 'tazusb' can be used later to create\n"
307 " a true read/write USB key).\n\n"
308 "- create a SliTaz bootstrap floppy for the ISO image\n"
309 " on the hard disk.\n"
310 "\nDo you want to create a boot key now ?";
312 GetModuleFileName(hInstance, isoFileName, MAX_PATH);
313 if (!iswinnt()) {
314 if (MessageBox(NULL,
315 "This program must be run in DOS mode.\n"
316 "I can create the file slitaz.pif to launch it,\n"
317 "but you can reboot in DOS mode to run it.\n"
318 "\nDo you want to create the slitaz.pif file and execute it now ?",
319 "Create slitaz.pif now ?",
320 MB_YESNO|MB_ICONQUESTION) == IDYES) {
321 exec16bits(isoFileName);
322 }
323 exit(1);
324 }
325 if (!ishybrid(isoFileName)) {
326 if (MessageBox(NULL,"Not an isolinux hybrid ISO.\n"
327 "This ISO image will not boot\n"
328 "from the media that you create !",
329 "Will not boot !",
330 MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL)
331 exit(0);
332 }
333 header[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
334 fd = open(isoFileName, O_RDONLY|O_BINARY);
335 if (fd != -1) {
336 read(fd, header, sizeof(header));
337 close(fd);
338 }
339 if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available
340 usbkeyicon = MB_ICONQUESTION;
341 usbkeymsg =
342 "You can create a SliTaz USB boot key or\n"
343 "a boot memory card.\n"
344 "(note that this will be read only like\n"
345 "a CDROM. The Slitaz utility 'tazusb'\n"
346 "can be used later to create a true\n"
347 "read/write USB key).\n"
348 "\nDo you want to create a boot key now ?";
349 }
350 if (MessageBox(NULL,usbkeymsg, "Create a boot stick ?",
351 MB_YESNO|usbkeyicon) == IDYES) {
352 unsigned long base, new;
353 int retry;
355 if (MessageBox(NULL,"Step 1: unplug the USB stick.",
356 "Drive detection 1/2",
357 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
358 exit(0);
359 base = drives();
360 if (MessageBox(NULL,"Step 2: plug the USB stick in, "
361 "wait for Windows to mount it",
362 "Drive detection 2/2",
363 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
364 exit(0);
365 retry = 0;
366 do {
367 Sleep(1000); // ms
368 new = drives();
369 } while (new == base && retry++ < 10);
370 if (new == base) {
371 MessageBox(NULL,"No USB stick found.","Sorry",
372 MB_OK|MB_ICONERROR);
373 }
374 else {
375 char *msg = "(hd0) is up to date.";
376 msg[3] += rawrite(base ^ new, isoFileName) - 128;
377 MessageBox(NULL,msg,"Finished",MB_OK);
378 }
379 }
380 else if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 &&
381 MessageBox(NULL,"Do you want to create a bootstrap floppy ?",
382 "Create a bootstrap floppy ?",
383 MB_YESNO|MB_ICONQUESTION) == IDYES &&
384 MessageBox(NULL,"Insert a floppy disk in drive now",
385 "Insert floppy",
386 MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) {
388 // Create a 9k bootstrap with vfat, ext2 & ntfs drivers
389 // to boot the ISO image on hard disk
390 writefloppy(isoFileName);
391 MessageBox(NULL,"The bootstrap floppy is up to date.",
392 "Finished",MB_OK);
393 }
394 }