wok annotate syslinux/stuff/iso2exe/win32.c @ rev 21822

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