wok view syslinux/stuff/iso2exe/win32.c @ rev 25682

Up libqcow (20240308)
author Pascal Bellard <pascal.bellard@slitaz.org>
date Sun Mar 24 18:25:46 2024 +0000 (5 weeks ago)
parents 7744355508b9
children
line source
1 #include <windows.h>
2 #include <winnt.h>
3 #include <winioctl.h>
4 #include <commctrl.h>
5 #include <sys/types.h>
6 #include <sys/stat.h>
7 #include <fcntl.h>
9 #define e_grave "\xE8"
10 #define e_acute "\xE9"
11 #define e_circ "\xEA"
12 #define e_trema "\xEB"
13 #define E_grave "\xC8"
14 #define E_acute "\xC9"
15 #define E_circ "\xCA"
16 #define E_trema "\xCB"
17 #define a_grave "\xE0"
18 #define A_grave "\xC0"
19 #define a_circ "\xE2"
20 #define A_circ "\xC2"
21 #define c_cedil "\xE7"
22 #define C_cedil "\xC7"
23 #define i_circ "\xEE"
24 #define I_circ "\xCE"
25 #define i_trema "\xEF"
26 #define I_trema "\xCF"
27 #define o_circ "\xF4"
28 #define O_circ "\xD4"
29 #define o_trema "\xF6"
30 #define O_trema "\xD6"
31 #define u_grave "\xF9"
32 #define U_grave "\xD9"
33 #define u_circ "\xFB"
34 #define U_circ "\xDB"
35 #define u_trema "\xFC"
36 #define U_trema "\xDC"
38 static char *MsgSet[2][27] = {
39 {
40 #define LANG_EN 0
41 #define MSG_BUILD_KEY 0
42 "Build the SliTaz USB key...",
43 #define MSG_EITHER_CREATE_KEY_OR_BOOT_FLOPPY 1
44 "You can either:\n\n"
45 "- create a SliTaz USB boot key or a boot memory card.\n"
46 " (note that the Linux kernel will not be upgradable.\n"
47 " The Slitaz utility 'tazusb' can be used later to create\n"
48 " a true read/write USB key).\n\n"
49 "- create a SliTaz bootstrap floppy for the ISO image\n"
50 " on the hard disk.\n"
51 "\nDo you want to create a boot key now ?",
52 #define MSG_NOT_DOS_MODE 2
53 "This program should run in DOS mode.\n"
54 "It can create the file slitaz.pif and launch it,\n"
55 "but you can reboot in DOS mode too and run it.\n"
56 "\nDo you want to create the slitaz.pif file and execute it now ?",
57 #define MSG_CRATE_PIF_NOW 3
58 "Create slitaz.pif now ?",
59 #define MSG_NOT_HYBRID 4
60 "Not an isolinux hybrid ISO.\n"
61 "This ISO image will not boot\n"
62 "from the media that you create !",
63 #define MSG_WILL_NOT_BOOT 5
64 "Will not boot !",
65 #define MSG_WANT_CREATE_BOOT_KEY 6
66 "You can create a SliTaz USB boot key or\n"
67 "a boot memory card.\n"
68 "\nDo you want to create a boot key now ?",
69 #define MSG_Q_CREATE_STICK 7
70 "Create a boot stick ?",
71 #define MSG_STEP_1 8
72 "Step 1: unplug the USB stick.",
73 #define MSG_DETECT_1 9
74 "Drive detection 1/2",
75 #define MSG_STEP_2 10
76 "Step 2: plug the USB stick in, "
77 "wait for Windows to mount it",
78 #define MSG_DETECT_2 11
79 "Drive detection 2/2",
80 #define MSG_NOT_FOUND 12
81 "No USB stick found.",
82 #define MSG_SORRY 13
83 "Sorry",
84 #define MSG_HD0_UP_TO_DATE 14
85 "(hd0) is up to date.",
86 #define MSG_HD0_UP_TO_DATE_BUT 15
87 "(hd0) is up to date but the partition table is not\n"
88 "updated because I can't get the total USB stick size\n\n"
89 "You can boot SliTaz with this stick and you can update\n"
90 "the partition table with 'taziso' by selecting "
91 "'usbbootkey' as root.",
92 #define MSG_NO_REPART 16
93 "Finished without repartitioning",
94 #define MSG_KEEP_CUSTOM_CONF 17
95 "Do you want to keep your custom configuration ?",
96 #define MSG_KEEP_CONF 18
97 "keep configuration ?",
98 #define MSG_WANT_HOME 19
99 "Do you want to create a persistent partition for /home ?",
100 #define MSG_DO_HOME 20
101 "Create a persistent /home ?",
102 #define MSG_FINISHED 21
103 "Finished",
104 #define MSG_WANT_FLOPPY 22
105 "Do you want to create a bootstrap floppy ?",
106 #define MSG_DO_FLOPPY 23
107 "Create a bootstrap floppy ?",
108 #define MSG_INSERT_A_FLOPPY 24
109 "Insert a floppy disk in drive now",
110 #define MSG_INSERT_FLOPPY 25
111 "Insert floppy",
112 #define MSG_FLOPPY_DONE 26
113 "The bootstrap floppy is up to date."
114 },
115 {
116 #define LANG_FR 1
117 // MSG_BUILD_KEY
118 "Construit la cl" e_acute " USB SliTaz...",
119 // MSG_EITHER_CREATE_KEY_OR BOOT_FLOPPY
120 "Vous pouvez soit :\n\n"
121 "- cr" e_acute "er une cl" e_acute " USB ou une carte m" e_acute "moire de d" e_acute "marrage.\n"
122 " (notez que le noyau Linux ne pourra pas " e_circ "tre mis " a_grave " jour.\n"
123 " L'outil SliTaz 'tazusb' pourra " e_circ "tre utilis" e_acute " ensuite pour cr" e_acute "er\n"
124 " une v" e_acute "ritable cl" e_acute " USB read/write).\n\n"
125 "- cr" e_acute "er une disquette de d" e_acute "marrage pour une image ISO\n"
126 " plac" e_acute " sur le disque dur.\n"
127 "\nVoulez vous cr" e_acute "er une disquette de d" e_acute "marrage maintenant ?",
128 // MSG_NOT_DOS_MODE
129 "Ce programme devrait " e_circ "tre lanc" e_acute " en mode DOS.\n"
130 "Il peut cr" e_acute "er le fichier slitaz.pif et l'ex" e_acute "cuter,\n"
131 "mais vous pouvez aussi red" e_acute "marrer en mode DOS et le lancer.\n"
132 "\nVoulez cr" e_acute "er le fichier slitaz.pif et le lancer maintenant ?",
133 // MSG_CRATE_PIF_NOW
134 "Cr" e_acute "er slitaz.pif maintenant ?",
135 // MSG_NOT_HYBRID
136 "Ce n'est pas une image ISO hybride isolinux.\n"
137 "Cette image ISO ne d" e_acute "marrera pas\n"
138 "depuis le media o" u_grave " vous la cr" e_acute "er !",
139 // MSG_WILL_NOT_BOOT
140 "Ne d" e_acute "marrera pas !\n",
141 // MSG_WANT_CREATE_BOOT_KEY
142 "Vous pouvez cr" e_acute "er une cl" e_acute " USB / carte m" e_acute "moire de d" e_acute "marrage.\n"
143 "\nVoulez vous cr" e_acute "er une cl" e_acute " de d" e_acute "marrage maintenant ?",
144 // MSG_Q_CREATE_STICK
145 "Cr" e_acute "er une cl" e_acute " de d" e_acute "marrage ?",
146 // MSG_STEP_1
147 "Etape 1 : d" e_acute "branchez la cl" e_acute " USB.",
148 // MSG_DETECT_1
149 "D" e_acute "tection du p" e_acute "riph" e_acute "rique 1/2",
150 // MSG_STEP_2
151 "Etape 2 : rebranchez la cl" e_acute " USB, "
152 "et attendez que Windows la reconnaisse.",
153 // MSG_DETECT_2
154 "D" e_acute "tection du p" e_acute "riph" e_acute "rique 2/2",
155 // MSG_NOT_FOUND
156 "Aucune cl" e_acute " USB trouv" e_acute "e.",
157 // MSG_SORRY
158 "D" e_acute " sol" e_acute,
159 // MSG_HD0_UP_TO_DATE
160 "(hd0) a " e_acute "t" e_acute " mis " a_grave " jour.",
161 // MSG_HD0_UP_TO_DATE_BUT
162 "(hd0) a " e_acute "t" e_acute " mis " a_grave " jour mais la table de partition n'est pas\n"
163 "modifi" e_acute "e car la taille totale de la cl" e_acute " USB n'a pu " e_circ "tre d" e_acute "tect" e_acute "e\n\n"
164 "Vous pouvez d" e_acute "marrer avec cette cl" e_acute " puis vous pouvez mettre " a_grave " jour\n"
165 "la table de partition avec 'taziso' en choisissant "
166 "'usbbootkey' (si root).",
167 // MSG_NO_REPART
168 "Termin" e_acute " sans repartitionement",
169 // MSG_KEEP_CUSTOM_CONF
170 "Voulez vous conserver votre configuration personnelle ?",
171 // MSG_KEEP_CONF
172 "Garder votre configuration ?",
173 // MSG_WANT_HOME
174 "voulez vous cr" e_acute "er une partition persistante pour /home ?",
175 // MSG_DO_HOME
176 "Cr" e_acute "er un /home persistant ?",
177 // MSG_FINISHED
178 "Termin" e_acute,
179 // MSG_WANT_FLOPPY
180 "Voulez-vous cr" e_acute "er une disquette de d" e_acute "marrage ?",
181 // MSG_DO_FLOPPY
182 "Cr" e_acute "er une disquette de boot ?",
183 // MSG_INSERT_A_FLOPPY
184 "Veuillez ins" e_acute "rer une disquette maintenant",
185 // MSG_INSERT_FLOPPY
186 "Ins" e_acute "rer une disquette",
187 // MSG_FLOPPY_DONE
188 "La disquette de d" e_acute "marage est cr" e_acute e_acute "e."
189 }
190 };
191 static char **Msg = MsgSet[LANG_EN];
193 #define BOOTSTRAP_SECTOR_COUNT_OFFSET 26
194 #define BOOTSTRAP_SECTOR_COUNT_OFFSET 26
196 static int fullread(int fd, char *p, int n)
197 {
198 int i, j;
199 for (i = 0; n > 0; i += j, n -= j) {
200 j = read(fd, p + i, n);
201 if (j <= 0) break;
202 }
203 return i;
204 #define read fullread
205 }
207 static int fullwrite(int fd, char *p, int n)
208 {
209 int i, j;
210 for (i = 0; n > 0; i += j, n -= j) {
211 j = write(fd, p + i, n);
212 if (j <= 0) break;
213 }
214 return i;
215 #define write fullwrite
216 }
218 #pragma pack(push,1)
219 struct PIF_section_header {
220 char name[16];
221 short next_header_offset;
222 short data_offset;
223 short data_length;
224 };
226 struct PIF_basic_section {
227 unsigned char unused;
228 unsigned char checksum;
229 char window_title[30];
230 unsigned short max_mem;
231 unsigned short min_mem;
232 char program_filename[63];
233 unsigned short bitmask;
234 char working_directory[64];
235 char parameters_string[64];
236 unsigned char video_mode;
237 unsigned char video_pages;
238 unsigned char first_interrupt;
239 unsigned char last_interrupt;
240 unsigned char height_screen;
241 unsigned char width_screen;
242 unsigned char horizontal_pos;
243 unsigned char vertical_pos;
244 unsigned short last_text_page;
245 char unused2[128];
246 unsigned short bitmask2;
247 };
249 struct PIF_section_win_386_3_0 {
250 unsigned short max_mem;
251 unsigned short min_mem;
252 unsigned short active_priority;
253 unsigned short background_priority;
254 unsigned short max_ems;
255 unsigned short required_ems;
256 unsigned short max_xms;
257 unsigned short required_xms;
258 unsigned long bitmask;
259 unsigned short bitmask2;
260 unsigned short unknown;
261 unsigned short shortcut_key_code;
262 unsigned short shortcut_key_modifier;
263 unsigned short shortcut_key_use;
264 unsigned short shortcut_key_scan;
265 unsigned short unknown2;
266 unsigned short unknown3;
267 unsigned long unknown4;
268 char parameters_string[64];
269 };
271 struct PIF_section_win_vmm_4_0 {
272 char unknown[88];
273 char iconfile[80];
274 unsigned short icon_number;
275 unsigned short bitmask;
276 char unknown2[10];
277 unsigned short priority;
278 unsigned short bitmask2; // video
279 char unknown3[8];
280 unsigned short text_lines;
281 unsigned short bitmask3; // Key modifiers
282 unsigned short unknown4;
283 unsigned short unknown5;
284 unsigned short unknown6;
285 unsigned short unknown7;
286 unsigned short unknown8;
287 unsigned short unknown9;
288 unsigned short unknown10;
289 unsigned short unknown11;
290 unsigned short bitmask4; // Mouse
291 char unknown12[6];
292 unsigned short bitmask5; // Fonts
293 unsigned short unknown13;
294 unsigned short rasterfontHsize;
295 unsigned short rasterfontVsize;
296 unsigned short fontHsize;
297 unsigned short fontVsize;
298 char raster_name[32];
299 char truetype_name[32];
300 unsigned short unknown14;
301 unsigned short bitmask6;
302 unsigned short restore_settings;
303 unsigned short Hsize;
304 unsigned short Vsize;
305 unsigned short HsizePixelsClient;
306 unsigned short VsizePixelsClient;
307 unsigned short HsizePixels;
308 unsigned short VsizePixels;
309 unsigned short unknown15;
310 unsigned short bitmask7;
311 unsigned short maximized;
312 char unknown16[4];
313 char window_geom[16];
314 char bat_file_name[80];
315 unsigned short env_size;
316 unsigned short dpmi_size;
317 unsigned short unknown17;
318 };
320 static struct {
321 struct PIF_basic_section s0;
322 struct PIF_section_header h0;
323 struct PIF_section_header h1;
324 struct PIF_section_win_386_3_0 s1;
325 struct PIF_section_header h2;
326 struct PIF_section_win_vmm_4_0 s2;
327 } PIF_content = {
328 { 0, 0x78, "MS-DOS Prompt ", 640, 0, "" /*slitaz.exe*/,
329 0x10, "", "", 0, 1, 0, 255, 25, 80, 0, 0, 7, "", 0 },
330 { "MICROSOFT PIFEX", sizeof(struct PIF_basic_section)
331 + sizeof(struct PIF_section_header), 0,
332 sizeof(struct PIF_basic_section) },
333 { "WINDOWS 386 3.0", sizeof(struct PIF_basic_section)
334 + 2*sizeof(struct PIF_section_header)
335 + sizeof(struct PIF_section_win_386_3_0),
336 sizeof(struct PIF_basic_section)
337 + 2*sizeof(struct PIF_section_header),
338 sizeof(struct PIF_section_win_386_3_0) },
339 { 640, 0, 100, 50, 65535, 0, 65535, 0, 0x10821002, 31, 0, 0, 0, 0, 0, 0,
340 0, 0, "" },
341 { "WINDOWS VMM 4.0", 65535, sizeof(struct PIF_basic_section)
342 + 3*sizeof(struct PIF_section_header)
343 + sizeof(struct PIF_section_win_386_3_0),
344 sizeof(struct PIF_section_win_vmm_4_0) },
345 { "", "PIFMGR.DLL", 0, 2, "", 50, 1, "", 0, 1, 0, 5, 25, 3, 0xC8,
346 0x3E8, 2, 10, 1, "", 28, 0, 0, 0, 7, 12, "Terminal", "Courier New",
347 0, 3, 0, 80, 25, 0x250, 0x140, 0, 0, 22, 0, 0, "", "", "", 0, 0, 1 }
348 };
349 #pragma pack(pop)
351 static void exec16bits(const char *isoFileName)
352 {
353 int fd;
354 const char pifFileName[] = "slitaz.pif";
356 strcpy(PIF_content.s0.program_filename, isoFileName);
357 fd = open(pifFileName, O_WRONLY|O_BINARY|O_CREAT|O_TRUNC,0555);
358 write(fd,(void*)&PIF_content,sizeof(PIF_content));
359 close(fd);
360 WinExec(pifFileName, SW_MINIMIZE);
361 exit(0);
362 }
364 static int iswinnt(void)
365 {
366 OSVERSIONINFOA Version;
367 Version.dwOSVersionInfoSize = sizeof(Version);
368 return (GetVersionEx(&Version) &&
369 Version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); // not Win9x
370 }
372 #define LONG(x) * (unsigned long *) (x)
373 static int ishybrid(const char *isoFileName)
374 {
375 int fdiso;
376 char buffer[2048];
377 unsigned long magic = 0;
379 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
380 if (lseek(fdiso, 17 * 2048L, SEEK_SET) != -1 &&
381 read(fdiso, buffer, 2048) == 2048 &&
382 strncmp(buffer+7,"EL TORITO SPECIFICATION",23) == 0) {
383 unsigned long lba = LONG(buffer + 71);
385 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
386 read(fdiso, buffer, 2048) == 2048 &&
387 LONG(buffer + 0) == 1 && LONG(buffer + 30) == 0x88AA55) {
388 lba = LONG(buffer + 40);
389 if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 &&
390 read(fdiso, buffer, 2048) == 2048)
391 magic = LONG(buffer + 64);
392 }
393 }
394 close(fdiso);
395 return (magic == 1886961915);
396 }
398 static unsigned long crc32(void *buf, int cnt)
399 {
400 static unsigned long t[256] = {
401 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
402 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91,
403 0x1DB71064, 0x6AB020F2, 0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7,
404 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F, 0x63066CD9, 0xFA0F3D63, 0x8D080DF5,
405 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
406 0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59,
407 0x26D930AC, 0x51DE003A, 0xC8D75180, 0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F,
408 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11, 0xC1611DAB, 0xB6662D3D,
409 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433,
410 0x7807C9A2, 0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01,
411 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E, 0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457,
412 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3, 0xFBD44C65,
413 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB,
414 0x4369E96A, 0x346ED9FC, 0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9,
415 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525, 0x206F85B3, 0xB966D409, 0xCE61E49F,
416 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
417 0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683,
418 0xE3630B12, 0x94643B84, 0x0D6D6A3E, 0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1,
419 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB, 0x196C3671, 0x6E6B06E7,
420 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5,
421 0xD6D6A3E8, 0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B,
422 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60, 0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79,
423 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9, 0x5505262F,
424 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D,
425 0x9B64C2B0, 0xEC63F226, 0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713,
426 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B, 0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21,
427 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
428 0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45,
429 0xA00AE278, 0xD70DD2EE, 0x4E048354, 0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB,
430 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5, 0x47B2CF7F, 0x30B5FFE9,
431 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF,
432 0xB3667A2E, 0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
433 unsigned long crc;
434 unsigned char *p = buf;
435 int i;
437 for (crc=0xFFFFFFFF, i=0; i < cnt; i++) {
438 crc=((crc >> 8) ^ t[(crc ^ p[i]) & 255]);
439 }
440 return crc ^ 0xFFFFFFFF;
441 }
443 static char buffer[2048];
445 static int getDrive(unsigned long mask)
446 {
447 int dev;
448 if (mask == 0) {
449 exit(1);
450 }
451 for (dev = 128; (mask & 1) == 0; dev++)
452 mask >>= 1;
453 return dev;
454 }
456 static unsigned long end = 0;
457 #define MODE_READ 0
458 #define MODE_WRITE 1
459 #define MODE_GET_SIZE 2
460 static int rdwrsector(int mode, int drive, unsigned long startingsector, int bufsiz)
461 {
462 HANDLE hDevice;
463 DWORD result;
464 char devname[sizeof("\\\\.\\PhysicalDrive0")];
466 if (drive >= 128) {
467 strcpy(devname, "\\\\.\\PhysicalDrive0");
468 devname[17] += drive - 128;
469 }
470 else {
471 strcpy(devname, "\\\\.\\A:");
472 devname[4] += drive;
473 }
474 hDevice = CreateFile (devname, (mode == MODE_READ) ? GENERIC_READ : GENERIC_WRITE,
475 FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
476 if (hDevice == INVALID_HANDLE_VALUE)
477 return -1;
479 SetFilePointer(hDevice, (startingsector*bufsiz), NULL, FILE_BEGIN);
480 if (mode == MODE_READ) {
481 if (!ReadFile(hDevice, buffer, bufsiz, &result, NULL))
482 result = -1;
483 }
484 else if (mode == MODE_WRITE) {
485 if (!WriteFile(hDevice, buffer, bufsiz, &result, NULL))
486 result = -1;
487 }
488 else {
489 GET_LENGTH_INFORMATION li;
490 DWORD rsize;
492 result = -1;
493 if (DeviceIoControl(hDevice, IOCTL_DISK_GET_LENGTH_INFO, NULL, 0, &li, sizeof(li),
494 &rsize, NULL) != 0) {
495 end = li.Length.QuadPart >> 9;
496 result = 0;
497 }
498 else {
499 long i, high;
500 high = -1;
501 i = GetFileSize(hDevice, &high);
502 if (i == INVALID_FILE_SIZE) {
503 high = -1;
504 i = SetFilePointer(hDevice, 0, &high, FILE_END);
505 }
506 if (i != INVALID_SET_FILE_POINTER) {
507 end = (high << 23)|(i >> 9);
508 result = 0;
509 }
510 #if 0
511 if (result == -1) {
512 LARGE_INTEGER size;
513 //if (GetFileSizeEx(hDevice, &size) != 0) {
514 if ((*GetProcAddress(GetModuleHandle("kernel32.dll"),
515 "GetFileSizeEx"))(hDevice, &size) != 0) {
516 end = (size.QuadPart >> 9);
517 result = 0;
518 }
519 }
520 #endif
521 #if 0
522 if (result == -1) {
523 for (end = 0x40000000, i = (end >> 1); i != 0; i >>= 1) {
524 high = (end >> 23);
525 if (SetFilePointer(hDevice, end << 9, &high, FILE_BEGIN) == INVALID_SET_FILE_POINTER ||
526 !ReadFile(hDevice, buffer, 512, &result, NULL) || result != 512) end -= i;
527 else end += i;
528 }
529 high = (end >> 23);
530 if (SetFilePointer(hDevice, end << 9, &high, FILE_BEGIN)
531 != INVALID_SET_FILE_POINTER) end++;
532 if (end > startingsector) result = 0;
533 }
534 #endif
535 }
537 }
538 CloseHandle(hDevice);
539 return result;
540 }
542 static int rawrite(int dev, char *isoFileName)
543 {
544 int fdiso, s;
545 float next;
546 off_t size;
547 HWND hwndPB;
549 fdiso = open(isoFileName, O_RDONLY|O_BINARY);
550 size = lseek(fdiso,0,SEEK_END);
551 lseek(fdiso,0,SEEK_SET);
552 if (size != -1) { // https://docs.microsoft.com/en-us/windows/win32/controls/create-progress-bar-controls
553 const left=100, right=100+400, bottom=80, scroll=50;
555 InitCommonControls(); // need -lcomctl32
556 hwndPB = CreateWindowEx(0, PROGRESS_CLASS, Msg[MSG_BUILD_KEY],
557 WS_VISIBLE | PBS_SMOOTH, left,
558 bottom - scroll, right, scroll,
559 NULL, (HMENU) 0, GetModuleHandle(0), NULL);
560 if (hwndPB == NULL) size = -1;
561 else SendMessage(hwndPB, PBM_SETRANGE, 0, MAKELPARAM(0, 0xFFFF));
562 }
563 for (s = 0, next = 0.0;; s++) {
564 int n = read(fdiso, buffer, 2048);
565 if (n <= 0) break;
566 rdwrsector(MODE_WRITE, dev, s, 2048);
567 if (size != -1) SendMessage(hwndPB, PBM_SETPOS, (WPARAM) floor((65536.0*2048.0*s)/size), 0 );
568 }
569 close(fdiso);
570 if (size != -1) DestroyWindow(hwndPB);
571 return dev;
572 }
574 static unsigned long drives(void)
575 {
576 int i, mask, result;
578 for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) {
579 if (rdwrsector(MODE_READ, getDrive(i+128), 0, 512) != -1)
580 result |= mask;
581 }
582 return result;
583 }
585 static int EndOfIso(int dev, unsigned long *endiso, unsigned long *endcustom)
586 {
587 if (rdwrsector(MODE_READ, dev, 16, 2048) == -1) return -1;
588 *endiso = *endcustom = LONG(buffer+80);
589 if (rdwrsector(MODE_GET_SIZE, dev, *endiso, 512) == -1) return -1;
590 if (rdwrsector(MODE_READ, dev, *endiso, 2048) != -1 && !memcmp(buffer,"#!boot",6)) {
591 char *s;
592 *endcustom++;
593 s = strstr(buffer, "\ninitrd:");
594 if (s) {
595 long n = strtol(s+8,&s,10);
596 n += s - buffer;
597 *endcustom += n/2048;
598 }
599 *endcustom += 511L; *endcustom &= ~511L;
600 }
601 return 0;
602 }
604 static void AddPartition(int dev, char *label, unsigned long next)
605 {
606 int i;
607 unsigned long crc;
609 // https://en.wikipedia.org/wiki/GUID_Partition_Table
610 if (rdwrsector(MODE_READ, dev, 2, 512) == -1) return;
611 if (buffer[128+56] == 0) {
612 static char id[16] = { 0xA2, 0xA0, 0xD0, 0xEB,
613 0xE5, 0xB9, 0x33, 0x44, 0x87, 0xC0,
614 0x68, 0xB6, 0xB7, 0x26, 0x99, 0xC7 };
615 memcpy(buffer + 128, id, 16);
616 for (i = 0; i < 16; i += 2)
617 * (unsigned short *) (buffer + 128+16 + i) = rand();
618 for (i = 56; *label; i += 2)
619 buffer[128+i] = *label++;
620 LONG(buffer + 128+32) = next * 2048/512;
621 LONG(buffer + 128+40) = end - 3;
622 }
623 rdwrsector(MODE_WRITE, dev, 2, 512);
624 rdwrsector(MODE_WRITE, dev, end - 2, 512);
625 crc = crc32(buffer, 512L);
626 if (rdwrsector(MODE_READ, dev, 1, 512) == -1) return;
627 LONG(buffer+88) = crc;
628 LONG(buffer+24) = 1; // Current header
629 LONG(buffer+28) = 0;
630 LONG(buffer+32) = end - 1; // Backup header
631 LONG(buffer+36) = 0;
632 LONG(buffer+48) = end - 3; // Last usable sector
633 LONG(buffer+52) = 0;
634 LONG(buffer+16) = 0;
635 crc = crc32(buffer, LONG(buffer + 0x0C));
636 LONG(buffer+16) = crc;
637 rdwrsector(MODE_WRITE, dev, 1, 512);
638 LONG(buffer+24) = end - 1; // Current header
639 LONG(buffer+28) = 0;
640 LONG(buffer+32) = 1; // Backup header
641 LONG(buffer+36) = 0;
642 LONG(buffer+16) = 0;
643 crc = crc32(buffer, LONG(buffer + 0x0C));
644 LONG(buffer+16) = crc;
645 rdwrsector(MODE_WRITE, dev, end - 1, 512);
646 }
648 static void writefloppy(char *isoFileName)
649 {
650 int i, n, fd;
652 buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
653 fd = open(isoFileName, O_RDONLY|O_BINARY);
654 if (fd != -1) {
655 read(fd, buffer, 512);
656 n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET];
657 if (n != 0 &&
658 lseek(fd, * (unsigned short *) (buffer + 66) - (512 * n),
659 SEEK_SET) != -1) {
660 for (i = 0; i <= n; i++) {
661 if (i == 1) strncpy(buffer, isoFileName, 512);
662 else read(fd, buffer, 512);
663 rdwrsector(MODE_WRITE, 0, i, 512);
664 }
665 }
666 close(fd);
667 }
668 }
670 int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
671 LPSTR lpCmdLine, int nCmdShow)
672 {
673 char isoFileName[MAX_PATH];
674 char header[32];
675 int fd;
676 int usbkeyicon = MB_ICONASTERISK;
677 char *usbkeymsg;
679 GetModuleFileName(hInstance, isoFileName, MAX_PATH);
680 if (iswinnt()) {
681 LANGID lid = (*GetProcAddress(GetModuleHandle("kernel32.dll"), "GetSystemDefaultUILanguage"))();
682 if ((lid & 0xff) == 0x0c) Msg = MsgSet[LANG_FR];
683 }
684 else {
685 struct stat statbuf;
686 if (stat("C:\\Mes Documents",&statbuf) != -1) Msg = MsgSet[LANG_FR];
687 if (MessageBox(NULL, Msg[MSG_NOT_DOS_MODE], Msg[MSG_CRATE_PIF_NOW],
688 MB_YESNO|MB_ICONQUESTION) == IDYES) {
689 exec16bits(isoFileName);
690 }
691 exit(1);
692 }
693 if (!ishybrid(isoFileName)) {
694 if (MessageBox(NULL, Msg[MSG_NOT_HYBRID], Msg[MSG_WILL_NOT_BOOT],
695 MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL)
696 exit(0);
697 }
698 header[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0;
699 fd = open(isoFileName, O_RDONLY|O_BINARY);
700 if (fd != -1) {
701 read(fd, header, sizeof(header));
702 close(fd);
703 }
704 usbkeymsg = Msg[MSG_EITHER_CREATE_KEY_OR_BOOT_FLOPPY];
705 if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available
706 usbkeyicon = MB_ICONQUESTION;
707 usbkeymsg = Msg[MSG_WANT_CREATE_BOOT_KEY];
708 }
709 if (MessageBox(NULL,usbkeymsg, Msg[MSG_Q_CREATE_STICK],
710 MB_YESNO|usbkeyicon) == IDYES) {
711 unsigned long base, new;
712 int retry;
714 if (MessageBox(NULL, Msg[MSG_STEP_1], Msg[MSG_DETECT_1],
715 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
716 exit(0);
717 base = drives();
718 if (MessageBox(NULL, Msg[MSG_STEP_2], Msg[MSG_DETECT_2],
719 MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL)
720 exit(0);
721 retry = 0;
722 do {
723 Sleep(1000); // ms
724 new = drives();
725 } while (new == base && retry++ < 10);
726 if (new == base) {
727 MessageBox(NULL, Msg[MSG_NOT_FOUND], Msg[MSG_SORRY],
728 MB_OK|MB_ICONERROR);
729 }
730 else {
731 unsigned long endiso, endcustom;
732 char *msg = Msg[MSG_HD0_UP_TO_DATE];
733 int drive = getDrive(base ^ new);
734 msg[3] += rawrite(drive, isoFileName) - 128;
735 if (EndOfIso(drive, &endiso, &endcustom) == -1) {
736 char *msg2 = Msg[MSG_HD0_UP_TO_DATE_BUT];
737 msg2[3] = msg[3];
738 MessageBox(NULL,msg2, Msg[MSG_NO_REPART] ,MB_OK|MB_ICONEXCLAMATION);
739 }
740 else {
741 static char *labels[2] = { "Basic data partition", "SliTaz persistent /home" };
742 if (endiso != endcustom && MessageBox(NULL, Msg[MSG_KEEP_CUSTOM_CONF],
743 Msg[MSG_KEEP_CONF], MB_YESNO|MB_ICONQUESTION) == IDYES)
744 endiso = endcustom;
745 AddPartition(drive, labels[MessageBox(NULL, Msg[MSG_WANT_HOME],
746 Msg[MSG_DO_HOME], MB_YESNO|MB_ICONQUESTION) == IDYES], endiso);
747 MessageBox(NULL,msg, Msg[MSG_FINISHED], MB_OK);
748 }
749 }
750 }
751 else if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 &&
752 MessageBox(NULL, Msg[MSG_WANT_FLOPPY], Msg[MSG_DO_FLOPPY],
753 MB_YESNO|MB_ICONQUESTION) == IDYES &&
754 MessageBox(NULL, Msg[MSG_INSERT_A_FLOPPY], Msg[MSG_INSERT_FLOPPY],
755 MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) {
757 // Create a 9k bootstrap with vfat, exfat, ntfs, ext2 & usb drivers
758 // to boot the ISO image on hard disk
759 writefloppy(isoFileName);
760 MessageBox(NULL, Msg[MSG_FLOPPY_DONE],
761 Msg[MSG_FINISHED], MB_OK);
762 }
763 }