# HG changeset patch # User Pascal Bellard # Date 1364665006 -3600 # Node ID 5ed4d6b2d690ec732b4b892daed2305964f9df9c # Parent bf872cb6f5c10d85865994abbda6c178e519e29c syslinux/iso2exe: add NT+ support diff -r bf872cb6f5c1 -r 5ed4d6b2d690 syslinux/stuff/iso2exe/README --- a/syslinux/stuff/iso2exe/README Sat Mar 30 18:45:07 2013 +0000 +++ b/syslinux/stuff/iso2exe/README Sat Mar 30 18:36:46 2013 +0100 @@ -18,7 +18,7 @@ - to start SliTaz in RAM (live) in graphics mode or text mode. - to install SliTaz "a la UMSDOS" in the \slitaz\ subdirectory. The easiest - way to install SliTaz. No partitioning. No questions. + way to install SliTaz. No partitioning. No questions. But (very) slow. - to create a SliTaz USB Key. @@ -55,22 +55,23 @@ +-----------------+ | untouched | ISO9660 files including /boot/bzImage and /boot/rootfs* 32K +-----------------+ + | DOS .EXE stub | Start DOS .COM loader + +-----------------+ | ISO initramfs | Live loader and UMSDOS like install script +-----------------+ | DOS .COM loader | Load bzImage, the last rootfs*.gz and the ISO initramfs +-----------------+ - | WIN32 PE .exe | NT+ boot device creator / Win9x DOS .COM launcher. - +-----------------+ | floppy bootstrap| CD-ROM emulation boot driver for hard disk ISO image +-----------------+ unused +-----------------+ | tazlito info | Flavor missing data for 'tazlito iso2flavor' - 1K +-----------------+ + +-----------------+ | isohybrid boot | Starts isolinux.bin -512 +-----------------+ - | iso2exe boot | Boot starts isohybrid (*), .EXE starts DOS .COM loader - 0 +-----------------+ or 32 bits Windows boot device creator + +-----------------+ + | iso2exe boot + | Boot starts isohybrid (*), .EXE starts DOS .COM loader + | WIN32 PE .exe | NT+ boot device creator / Win9x DOS .COM launcher. + 0 +-----------------+ * Eltorito boot (i.e. bootable CD-ROM by BIOS) is not concerned by iso2exe. diff -r bf872cb6f5c1 -r 5ed4d6b2d690 syslinux/stuff/iso2exe/bootiso.S --- a/syslinux/stuff/iso2exe/bootiso.S Sat Mar 30 18:45:07 2013 +0000 +++ b/syslinux/stuff/iso2exe/bootiso.S Sat Mar 30 18:36:46 2013 +0100 @@ -4,7 +4,8 @@ CODESZ = 0x8000 // 16 sectors = 32Kb #define EXEADRS(x) x+0xC0 -#define EXESTR(x) x-0x40 +#define EXELOC(x) x-0x40 +#define EXESTR(x) x-0x7F40 .globl _start _start: @@ -52,15 +53,15 @@ ljmp $0, $0x0600+start2 .org 60 - .long 0 // PE header offset + .long 0x0080 // PE header offset end_header: chksum: .word 0 comstart: .word 0 -readsector2: - incw %cx +readsectorX: + movb $0, %cl readsector1: movw %cx, (%bx) incw %cx @@ -87,14 +88,14 @@ xchgw %ax, %dx jnz dxloop fail: - movw $0x0600+noloader, %si - call putslp +// movw $0x0600+noloader, %si +// call putslp stop: hlt jmp stop dxfound: movw %dx, 10(%bp) - call readsector2 + call readsectorX lodsw shrw $1, %ax jz fail // read fail or not isohydrid @@ -102,51 +103,12 @@ popa iret - + .org 0x0080 +////////////////////////////// EXE/PE header ////////////////////////////////// + + .org 0x7EE0 ////////////////////////////// DOS EXE code /////////////////////////////////// -help: - .ascii "SliTaz GNU/L" // SliTaz GNU/Linux boot loader - .byte EXESTR(iloader) -no386: - .ascii "No 386" // No 386+ - .byte EXESTR(plus) -ERRvcpi: - .ascii "No EMM386/VCPI 4" // No EMM386/VCPI 4.0+ - .byte EXESTR(dot0) -chkerr: - .ascii "Broken ISO image fil" // Broken ISO image file. - .byte EXESTR(eeol) -vm86modemsg: - .ascii "vm86" // vm86 mode. - .byte EXESTR(mode) -rmPaging: - .ascii "Invalid: paging + " // Invalid: paging + real mode. -realmodemsg: - .ascii "real" // real mode. -// --------------- Must be in 00C0 013F range ------------------------ -mode: - .ascii " mod" -eeol: - .ascii "e" - .byte EXESTR(eol) -noloader: - .ascii "No isol" // No isolinux boot loader -iloader: - .ascii "inux boot loader" -eol: - .ascii "." -eol2: - .asciz "\r\n" -noDOS3: - .ascii "No DOS 3" // No DOS 3.0+ -dot0: - .ascii ".0" -plus: - .ascii "+" - .byte EXESTR(eol2) -// ------------------------------------------------------------------- - exestart: cld movw $0x100, %si @@ -173,7 +135,7 @@ movw (%si), %cx jcxz is386 #endif - movw $(EXESTR(0x8000))/2, %cx + movw $(EXELOC(0x8000))/2, %cx chklp: lodsw addw %ax, %dx @@ -182,7 +144,7 @@ je is386 // dx == 0 ? abort: puts: - movb $1, %ah + movb $0x80, %ah xchgw %ax, %si putslp: lodsb @@ -209,21 +171,14 @@ cmpb $3, %al movb $EXESTR(noDOS3), %al jb abort - movw $moveend-move, %cx - movw $0xC000, %di - call move2 -move: - movb $0x80, %ch movw $0x0100, %di - pushw comstart-end_header(%di) // .com address -move2: - popw %si + movw comstart-end_header(%di), %si // .com address pushw %di + movb $0x7D, %ch rep movsb moveret: ret -moveend: VersionVCPI: cmpb $0x40, %dl // >= 4.0 ? @@ -259,6 +214,49 @@ .byte 0x46 // version .byte 0 - .org 440 -//////////////////////////// partition table ////////////////////////////////// +// ------------------------------------------------------------------- +help: + .ascii "SliTaz GNU/L" // SliTaz GNU/Linux boot loader + .byte EXESTR(iloader) +no386: + .ascii "No 386" // No 386+ + .byte EXESTR(plus) +ERRvcpi: + .ascii "No EMM386/VCPI 4" // No EMM386/VCPI 4.0+ + .byte EXESTR(dot0) +chkerr: + .ascii "Broken ISO image fil" // Broken ISO image file. + .byte EXESTR(eeol) +vm86modemsg: + .ascii "vm86" // vm86 mode. + .byte EXESTR(mode) +rmPaging: + .ascii "Invalid: paging + " // Invalid: paging + real mode. +realmodemsg: + .ascii "real" // real mode. +// --------------- Must be in 00C0 013F range ------------------------ +mode: + .ascii " mod" +eeol: + .ascii "e" + .byte EXESTR(eol) +//noloader: +// .ascii "No isol" // No isolinux boot loader +iloader: + .ascii "inux boot loader" +eol: + .ascii "." +eol2: + .asciz "\r\n" +noDOS3: + .ascii "No DOS 3" // No DOS 3.0+ +dot0: + .ascii ".0" +plus: + .ascii "+" + .byte EXESTR(eol2) + + .org 0x8000 +////////////////////////// ISO9660 header ///////////////////////////////////// + diff -r bf872cb6f5c1 -r 5ed4d6b2d690 syslinux/stuff/iso2exe/bootlinux.h --- a/syslinux/stuff/iso2exe/bootlinux.h Sat Mar 30 18:45:07 2013 +0000 +++ b/syslinux/stuff/iso2exe/bootlinux.h Sat Mar 30 18:36:46 2013 +0100 @@ -1,6 +1,6 @@ #ifndef __BOOTLINUX_H #define __BOOTLINUX_H -extern long loadkernel(void); +extern unsigned long loadkernel(void); extern void loadinitrd(void); extern void bootlinux(char *cmdline); #endif diff -r bf872cb6f5c1 -r 5ed4d6b2d690 syslinux/stuff/iso2exe/init --- a/syslinux/stuff/iso2exe/init Sat Mar 30 18:45:07 2013 +0000 +++ b/syslinux/stuff/iso2exe/init Sat Mar 30 18:36:46 2013 +0100 @@ -353,6 +353,13 @@ [ $? -eq 0 ] || return usbdev || return dd if=/mnt/$ISO of=$device + if [ $(get 0 /mnt/$ISO) -eq 23117 ]; then # iso2exe ? + LOC=$(get 69 /mnt/$ISO 1) + # move isohybrid boot sector (partitionable) + dd if=/mnt/$ISO bs=512 count=1 skip=$LOC of=$device conv=notrunc + # move tazlito data (backward compatibility) + dd if=/mnt/$ISO bs=512 count=20 skip=$(($LOC+1)) of=$device seek=2 conv=notrunc + fi } usbkey() diff -r bf872cb6f5c1 -r 5ed4d6b2d690 syslinux/stuff/iso2exe/iso2exe.c --- a/syslinux/stuff/iso2exe/iso2exe.c Sat Mar 30 18:45:07 2013 +0000 +++ b/syslinux/stuff/iso2exe/iso2exe.c Sat Mar 30 18:36:46 2013 +0100 @@ -26,8 +26,9 @@ #define partition 446 #define trksz (512 * heads * sectors) unsigned long size, catalog, lba; - int cylinders, i, j; + int cylinders, i, j, isohybrid; unsigned n; + char tazlitoinfo[31*1024]; #ifndef WIN32 char *bootiso; for (bootiso = (char *) main; @@ -53,28 +54,34 @@ readsector(lba); if (* (unsigned long *) (buffer + 64) != 1886961915) quit("no isolinux.bin hybrid signature in bootloader"); - * (unsigned long *) &bootiso[512 + 432] = lba * 4; - * (unsigned long *) &bootiso[512 + 440] = rand(); - * (unsigned long *) &bootiso[512 + partition] = 0x10080; - * (unsigned short *) &bootiso[512 + 510] = 0xAA55; + isohybrid = bootiso[69] * 512; + * (unsigned long *) &bootiso[isohybrid + 432] = lba * 4; + * (unsigned long *) &bootiso[isohybrid + 440] = rand(); + * (unsigned long *) &bootiso[isohybrid + partition] = 0x10080; + * (unsigned short *) &bootiso[isohybrid + 510] = 0xAA55; size = lseek(fd, 0UL, SEEK_END); cylinders = (size + trksz - 1) / trksz; - bootiso[512 + partition + 4] = 23; // "Windows hidden IFS" - bootiso[512 + partition + 5] = heads - 1; - bootiso[512 + partition + 6] = (((cylinders - 1) & 0x300) >> 2) + sectors; - bootiso[512 + partition + 7] = (cylinders - 1) & 0xFF; - * (unsigned long *) &bootiso[512 + partition + 8] = 0; - * (unsigned long *) &bootiso[512 + partition + 12] = cylinders * sectors * heads; + bootiso[isohybrid + partition + 4] = 23; // "Windows hidden IFS" + bootiso[isohybrid + partition + 5] = heads - 1; + bootiso[isohybrid + partition + 6] = (((cylinders - 1) & 0x300) >> 2) + sectors; + bootiso[isohybrid + partition + 7] = (cylinders - 1) & 0xFF; + * (unsigned long *) &bootiso[isohybrid + partition + 8] = 0; + * (unsigned long *) &bootiso[isohybrid + partition + 12] = cylinders * sectors * heads; // Install iso2exe boot sector - memcpy(bootiso + 512 - 66, bootiso + 1024 - 66, 66); * (unsigned short *) (bootiso + 26) = rand(); + // read tazlito flavor data + lseek(fd, 1024UL, SEEK_SET); + read(fd, tazlitoinfo, sizeof(tazlitoinfo)); + // Update iso image + n = (bootiso[69] + 1) * 512; lseek(fd, 0UL, SEEK_SET); - write(fd, bootiso, 1024); - lseek(fd, 0x8400UL - BOOTISOSZ, SEEK_SET); - write(fd, bootiso + 1024, BOOTISOSZ - 1024); + write(fd, bootiso, n); // EXE/PE + isohybrid mbr + write(fd, tazlitoinfo, ((0x8000U - BOOTISOSZ) > sizeof(tazlitoinfo)) + ? sizeof(tazlitoinfo) : (0x8000U - BOOTISOSZ)); + write(fd, bootiso + n, BOOTISOSZ - n); // COM + rootfs + EXE/DOS // Compute the checksum lseek(fd, 0UL, SEEK_SET); @@ -89,4 +96,6 @@ write(fd, bootiso, 512); nochksum: close(fd); + printf("Note you can create a USB key with %s.\n" + "Simply rename it to a .exe file and run it.\n", argv[1]); } diff -r bf872cb6f5c1 -r 5ed4d6b2d690 syslinux/stuff/iso2exe/iso2exe.sh --- a/syslinux/stuff/iso2exe/iso2exe.sh Sat Mar 30 18:45:07 2013 +0000 +++ b/syslinux/stuff/iso2exe/iso2exe.sh Sat Mar 30 18:36:46 2013 +0100 @@ -25,18 +25,27 @@ cp -a /dev/?d?* $TMP/dev $0 --get init > $TMP/init.exe grep -q mount.posixovl.iso2exe $TMP/init.exe && - cp /usr/sbin/mount.posixovl $TMP/bin/mount.posixovl.iso2exe + cp /usr/sbin/mount.posixovl $TMP/bin/mount.posixovl.iso2exe && + echo "Store mount.posixovl..." find $TMP -type f | xargs chmod +x ( cd $TMP ; find * | cpio -o -H newc ) | \ lzma e $TMP/rootfs.gz -si 2> /dev/null SIZE=$(wc -c < $TMP/rootfs.gz) store 24 $SIZE $1 - OFS=$(( 0x8000 - $SIZE )) + OFS=$(( $OFS - $SIZE )) printf "Adding rootfs.gz file at %04X...\n" $OFS cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc rm -rf $TMP } +add_dosexe() +{ + OFS=$((0x7EE0)) + printf "Adding DOS/EXE at %04X...\n" $OFS + $0 --get bootiso.bin 2> /dev/null | \ + ddq bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc +} + add_doscom() { SIZE=$($0 --get boot.com | wc -c) @@ -48,20 +57,19 @@ add_win32exe() { + printf "Adding WIN32 file at %04X...\n" 0 + ddq if=/tmp/exe$$ of=$1 conv=notrunc SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c) - if [ $SIZE -ne 0 ]; then - OFS=$(( 128 + ( ($OFS - $SIZE + 128) & 0xFE00 ) )) - printf "Adding WIN32 file at %04X...\n" $OFS - LOC=$((0xAC+$(get 0x94 /tmp/exe$$))) - for i in $(seq 1 $(get 0x86 /tmp/exe$$)); do - CUR=$(get $LOC /tmp/exe$$) - [ $CUR -eq 0 ] || store $LOC $(($CUR+$OFS-128)) /tmp/exe$$ - LOC=$(($LOC+40)) - done - ddq if=/tmp/exe$$ of=$1 bs=1 skip=128 seek=$OFS conv=notrunc - store 60 $OFS $1 - fi + ddq if=/tmp/exe$$ of=$1 conv=notrunc + printf "Adding bootiso head at %04X...\n" 0 + $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$ + ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc + store 69 $(($SIZE/512)) $1 8 + store 510 $((0xAA55)) $1 rm -f /tmp/exe$$ + printf "Moving syslinux hybrid boot record at %04X ...\n" $SIZE + ddq if=$2 bs=1 count=512 of=$1 seek=$SIZE conv=notrunc + OFS=$(($SIZE+512)) } add_fdbootstrap() @@ -77,9 +85,7 @@ case "$1" in --build) shift - [ $(tar cf - $@ | wc -c) -gt $((32 * 1024)) ] && - echo "WARNING: The file set $@ is too large (31K max) :" && - ls -l $@ + ls -l $@ cat >> $0 < /dev/null + HSZ=$OFS + add_dosexe $DATA > /dev/null add_rootfs $DATA > /dev/null add_doscom $DATA > /dev/null - add_win32exe $DATA > /dev/null add_fdbootstrap $DATA > /dev/null name=${3:-bootiso} cat <&2 && exit 1 case "$(get 0 $1)" in 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;; - 0) [ -x /usr/bin/isohybrid ] && isohybrid $1 + 0) [ -x /usr/bin/isohybrid ] && isohybrid $1 && echo "Do isohybrid" esac - echo "Moving syslinux hybrid boot record..." - ddq if=$1 bs=512 count=1 | ddq of=$1 bs=512 count=1 seek=1 conv=notrunc + echo "Read hybrid & tazlito data..." + ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$ + ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$ + add_win32exe $1 /tmp/hybrid$$ + printf "Moving tazlito data record at %04X ...\n" $OFS + ddq if=/tmp/tazlito$$ bs=1 count=512 of=$1 seek=$OFS conv=notrunc + rm -f /tmp/tazlito$$ /tmp/hybrid$$ - echo "Inserting EXE boot record..." - $0 --get bootiso.bin | ddq of=$1 conv=notrunc - # keep the largest room for the tazlito info file + add_dosexe $1 add_rootfs $1 add_doscom $1 - add_win32exe $1 add_fdbootstrap $1 store 26 ${RANDOM:-0} $1 i=66 diff -r bf872cb6f5c1 -r 5ed4d6b2d690 syslinux/stuff/iso2exe/win32.c --- a/syslinux/stuff/iso2exe/win32.c Sat Mar 30 18:45:07 2013 +0000 +++ b/syslinux/stuff/iso2exe/win32.c Sat Mar 30 18:36:46 2013 +0100 @@ -1,6 +1,259 @@ #include +#include +#include +#include +#include -int main() +#define BOOTSTRAP_SECTOR_COUNT_OFFSET 28 + +static int fullread(int fd, char *p, int n) { - MessageBox(NULL,"No support for Windows yet.","Sorry",MB_OK|MB_ICONERROR); + int i, j; + for (i = 0; n > 0; i += j, n -= j) { + j = read(fd, p + i, n); + if (j <= 0) break; + } + return i; } + +static int fullwrite(int fd, char *p, int n) +{ + int i, j; + for (i = 0; n > 0; i += j, n -= j) { + j = write(fd, p + i, n); + if (j <= 0) break; + } + return i; +} + +static void exec16bits(char *isoFileName) +{ + int fdiso, fdtmp, i; + long buffer[512/4]; + char tmpFileName[MAX_PATH], *p; + + strcpy(tmpFileName, isoFileName); + p = strrchr(tmpFileName, '\\'); + if (!p++) p = tmpFileName; + strcpy(p, "tazboot.exe"); + fdiso = open(isoFileName, O_RDONLY|O_BINARY); + fdtmp = open(tmpFileName, O_WRONLY|O_BINARY|O_CREAT,0555); + for (i = 0; i < 0x8000; i += sizeof(buffer)) { + fullread(fdiso, (char *) buffer, sizeof(buffer)); + if (i == 0) buffer[15] = 0; // kill PE header + fullwrite(fdtmp, (char *) buffer, sizeof(buffer)); + } + close(fdiso); + close(fdtmp); + execl(tmpFileName, isoFileName); +} + +static int iswinnt(void) +{ + OSVERSIONINFOA Version; + Version.dwOSVersionInfoSize = sizeof(Version); + return (GetVersionEx(&Version) && + Version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); // not Win9x +} + +static int ishybrid(char *isoFileName) +{ + int fdiso; + char buffer[2048]; + unsigned long magic = 0; + + fdiso = open(isoFileName, O_RDONLY|O_BINARY); + if (lseek(fdiso, 17 * 2048L, SEEK_SET) != -1 && + fullread(fdiso, buffer, 2048) == 2048 && + strncmp(buffer+23,"EL TORITO SPECIFICATION",23) == 0) { + unsigned long lba = * (unsigned long *) (buffer + 71); + + if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 && + fullread(fdiso, buffer, 2048) == 2048 && + * (unsigned long *) (buffer + 0) == 1 && + * (unsigned long *) (buffer + 30) == 0x88AA55) { + lba = * (unsigned long *) (buffer + 40); + if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 && + fullread(fdiso, buffer, 2048) == 2048) + magic = * (unsigned long *) (buffer + 64); + } + } + close(fdiso); + return (magic == 1886961915); +} + +#define MODE_READ 0 +#define MODE_WRITE 1 +static int rdwrsector(int mode, int drive, unsigned long startingsector, + unsigned long count, char *buffer) +{ + HANDLE hDevice; + DWORD result; + char devname[sizeof("\\\\.\\PhysicalDrive0")]; + + if (drive >= 128) { + strcpy(devname, "\\\\.\\PhysicalDrive0"); + devname[17] += drive - 128; + } + else { + strcpy(devname, "\\\\.\\A:"); + devname[4] += drive; + } + hDevice = CreateFile (devname, GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); + if (hDevice == INVALID_HANDLE_VALUE) + return -1; + SetFilePointer(hDevice, (startingsector*512), NULL, FILE_BEGIN); + if (mode == MODE_READ) { + if (!ReadFile(hDevice, buffer, 512*count, &result, NULL)) + result = -1; + } + else { + if (!WriteFile(hDevice, buffer, 512*count, &result, NULL)) + result = -1; + } + CloseHandle(hDevice); + return result; +} + +static void rawrite(unsigned long drive, char *isoFileName) +{ + int fdiso, s, dev, isohybrid = -1; + char buffer[2048]; + + if (drive == 0) return; + for (dev = 128; (drive & 1) == 0; dev++) + drive >>= 1; + fdiso = open(isoFileName, O_RDONLY|O_BINARY); + for (s = 0;;) { + int s, n = fullread(fdiso, buffer, sizeof(buffer)); + if (n <= 0) break; + n = (n+511)/512; + if (s == 0) isohybrid = buffer[69]; + rdwrsector(MODE_WRITE, dev, s, n, buffer); + if (s == isohybrid) + rdwrsector(MODE_WRITE, dev, 0, 1, buffer); + s += n; + } + close(fdiso); +} + +static unsigned long drives(void) +{ + int i, mask, result; + char buffer[512]; + for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) { + if (rdwrsector(MODE_READ, i+128, 0, 1, buffer) != -1) + result |= mask; + } + return result; +} + +static void writefloppy(char *isoFileName) +{ + char buffer[512]; + int i, n, fd; + + buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0; + fd = open(isoFileName, O_RDONLY|O_BINARY); + if (fd != -1) { + read(fd, buffer, sizeof(buffer)); + n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET]; + if (n != 0 && + lseek(fd, * (unsigned long *) (buffer + 60) - (512 * n), + SEEK_SET) != -1) { + for (i = 0; i < n; i++) { + fullread(fd, buffer, 512); + if (i == 1) strncpy(buffer, isoFileName, 512); + rdwrsector(MODE_WRITE, 0, i, 1, buffer); + } + } + close(fd); + } +} + +//TODO #define VCPI_LINUX_LOADER The DOS/EXE loader can boot in VM86 using VCPI API +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, + LPSTR lpCmdLine, int nCmdShow) +{ + char isoFileName[MAX_PATH]; + char header[32]; + int fd; + int usbkeyicon = MB_ICONASTERISK; + char *usbkeymsg = "You can either:\n\n" + "- create a SliTaz USB boot key or a boot memory card.\n" + " (note that this will be read only like a CDROM.\n" + " The Slitaz utility 'tazusb' can be used later to create\n" + " a true read/write USB key).\n\n" + "- create a SliTaz bootstrap floppy for the ISO image\n" + " on the hard disk.\n" + "\nDo you want to create a boot key now ?"; + + GetModuleFileName(hInstance, isoFileName, MAX_PATH); + if (!iswinnt()) { +#ifdef VCPI_LINUX_LOADER + exec16bits(isoFileName); +#else + MessageBox(NULL,"No support for Win9x yet.\n" + "Retry in DOS mode without emm386.\n", + "Sorry", MB_OK|MB_ICONERROR); + exit(1); +#endif + } + if (!ishybrid(isoFileName)) { + if (MessageBox(NULL,"Not an isolinux hybrid ISO.\n" + "This ISO image will not boot\n" + "from the media you will create !", + "Will not boot !", + MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) + exit(0); + } + header[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0; + fd = open(isoFileName, O_RDONLY|O_BINARY); + if (fd != -1) { + read(fd, header, sizeof(header)); + close(fd); + } + if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available + usbkeyicon = MB_ICONQUESTION; + usbkeymsg = "Do you want to create a boot key ?"; + } + if (MessageBox(NULL,usbkeymsg, "Create a boot stick ?", + MB_YESNO|usbkeyicon) == IDYES) { + unsigned long base, new; + int retry; + + if (MessageBox(NULL,"Step 1: unplug the USB stick.", + "Drive detection 1/2", + MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL) + exit(0); + base = drives(); + if (MessageBox(NULL,"Step 2: plug the USB stick in.", + "Drive detection 2/2", + MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL) + exit(0); + retry = 0; + do { + Sleep(1000); // ms + new = drives(); + } while (new == base && retry++ < 10); + if (new == base) { + MessageBox(NULL,"No USB stick found.","Sorry", + MB_OK|MB_ICONERROR); + exit(1); + } + rawrite(base ^ new, isoFileName); + } + if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 && + MessageBox(NULL,"Do you want to create a bootstrap floppy ?", + "Create a bootstrap floppy ?", + MB_YESNO|MB_ICONQUESTION) == IDYES && + MessageBox(NULL,"Insert a floppy disk in drive now", + "Insert floppy", + MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) { + + // Create a 9k bootstrap with vfat, ext2 & ntfs drivers + // to boot the ISO image on hard disk + writefloppy(isoFileName); + } +}