wok-next rev 14261
syslinux/iso2exe: add NT+ support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Sat Mar 30 18:36:46 2013 +0100 (2013-03-30) |
parents | bf872cb6f5c1 |
children | 0c880b8c93be |
files | syslinux/stuff/iso2exe/README syslinux/stuff/iso2exe/bootiso.S syslinux/stuff/iso2exe/bootlinux.h syslinux/stuff/iso2exe/init syslinux/stuff/iso2exe/iso2exe.c syslinux/stuff/iso2exe/iso2exe.sh syslinux/stuff/iso2exe/win32.c |
line diff
1.1 --- a/syslinux/stuff/iso2exe/README Sat Mar 30 18:45:07 2013 +0000 1.2 +++ b/syslinux/stuff/iso2exe/README Sat Mar 30 18:36:46 2013 +0100 1.3 @@ -18,7 +18,7 @@ 1.4 - to start SliTaz in RAM (live) in graphics mode or text mode. 1.5 1.6 - to install SliTaz "a la UMSDOS" in the \slitaz\ subdirectory. The easiest 1.7 - way to install SliTaz. No partitioning. No questions. 1.8 + way to install SliTaz. No partitioning. No questions. But (very) slow. 1.9 1.10 - to create a SliTaz USB Key. 1.11 1.12 @@ -55,22 +55,23 @@ 1.13 +-----------------+ 1.14 | untouched | ISO9660 files including /boot/bzImage and /boot/rootfs* 1.15 32K +-----------------+ 1.16 + | DOS .EXE stub | Start DOS .COM loader 1.17 + +-----------------+ 1.18 | ISO initramfs | Live loader and UMSDOS like install script 1.19 +-----------------+ 1.20 | DOS .COM loader | Load bzImage, the last rootfs*.gz and the ISO initramfs 1.21 +-----------------+ 1.22 - | WIN32 PE .exe | NT+ boot device creator / Win9x DOS .COM launcher. 1.23 - +-----------------+ 1.24 | floppy bootstrap| CD-ROM emulation boot driver for hard disk ISO image 1.25 +-----------------+ 1.26 unused 1.27 +-----------------+ 1.28 | tazlito info | Flavor missing data for 'tazlito iso2flavor' 1.29 - 1K +-----------------+ 1.30 + +-----------------+ 1.31 | isohybrid boot | Starts isolinux.bin 1.32 -512 +-----------------+ 1.33 - | iso2exe boot | Boot starts isohybrid (*), .EXE starts DOS .COM loader 1.34 - 0 +-----------------+ or 32 bits Windows boot device creator 1.35 + +-----------------+ 1.36 + | iso2exe boot + | Boot starts isohybrid (*), .EXE starts DOS .COM loader 1.37 + | WIN32 PE .exe | NT+ boot device creator / Win9x DOS .COM launcher. 1.38 + 0 +-----------------+ 1.39 1.40 * Eltorito boot (i.e. bootable CD-ROM by BIOS) is not concerned by iso2exe. 1.41
2.1 --- a/syslinux/stuff/iso2exe/bootiso.S Sat Mar 30 18:45:07 2013 +0000 2.2 +++ b/syslinux/stuff/iso2exe/bootiso.S Sat Mar 30 18:36:46 2013 +0100 2.3 @@ -4,7 +4,8 @@ 2.4 2.5 CODESZ = 0x8000 // 16 sectors = 32Kb 2.6 #define EXEADRS(x) x+0xC0 2.7 -#define EXESTR(x) x-0x40 2.8 +#define EXELOC(x) x-0x40 2.9 +#define EXESTR(x) x-0x7F40 2.10 2.11 .globl _start 2.12 _start: 2.13 @@ -52,15 +53,15 @@ 2.14 ljmp $0, $0x0600+start2 2.15 2.16 .org 60 2.17 - .long 0 // PE header offset 2.18 + .long 0x0080 // PE header offset 2.19 end_header: 2.20 chksum: 2.21 .word 0 2.22 comstart: 2.23 .word 0 2.24 2.25 -readsector2: 2.26 - incw %cx 2.27 +readsectorX: 2.28 + movb $0, %cl 2.29 readsector1: 2.30 movw %cx, (%bx) 2.31 incw %cx 2.32 @@ -87,14 +88,14 @@ 2.33 xchgw %ax, %dx 2.34 jnz dxloop 2.35 fail: 2.36 - movw $0x0600+noloader, %si 2.37 - call putslp 2.38 +// movw $0x0600+noloader, %si 2.39 +// call putslp 2.40 stop: 2.41 hlt 2.42 jmp stop 2.43 dxfound: 2.44 movw %dx, 10(%bp) 2.45 - call readsector2 2.46 + call readsectorX 2.47 lodsw 2.48 shrw $1, %ax 2.49 jz fail // read fail or not isohydrid 2.50 @@ -102,51 +103,12 @@ 2.51 popa 2.52 iret 2.53 2.54 - 2.55 + .org 0x0080 2.56 +////////////////////////////// EXE/PE header ////////////////////////////////// 2.57 + 2.58 + .org 0x7EE0 2.59 ////////////////////////////// DOS EXE code /////////////////////////////////// 2.60 2.61 -help: 2.62 - .ascii "SliTaz GNU/L" // SliTaz GNU/Linux boot loader 2.63 - .byte EXESTR(iloader) 2.64 -no386: 2.65 - .ascii "No 386" // No 386+ 2.66 - .byte EXESTR(plus) 2.67 -ERRvcpi: 2.68 - .ascii "No EMM386/VCPI 4" // No EMM386/VCPI 4.0+ 2.69 - .byte EXESTR(dot0) 2.70 -chkerr: 2.71 - .ascii "Broken ISO image fil" // Broken ISO image file. 2.72 - .byte EXESTR(eeol) 2.73 -vm86modemsg: 2.74 - .ascii "vm86" // vm86 mode. 2.75 - .byte EXESTR(mode) 2.76 -rmPaging: 2.77 - .ascii "Invalid: paging + " // Invalid: paging + real mode. 2.78 -realmodemsg: 2.79 - .ascii "real" // real mode. 2.80 -// --------------- Must be in 00C0 013F range ------------------------ 2.81 -mode: 2.82 - .ascii " mod" 2.83 -eeol: 2.84 - .ascii "e" 2.85 - .byte EXESTR(eol) 2.86 -noloader: 2.87 - .ascii "No isol" // No isolinux boot loader 2.88 -iloader: 2.89 - .ascii "inux boot loader" 2.90 -eol: 2.91 - .ascii "." 2.92 -eol2: 2.93 - .asciz "\r\n" 2.94 -noDOS3: 2.95 - .ascii "No DOS 3" // No DOS 3.0+ 2.96 -dot0: 2.97 - .ascii ".0" 2.98 -plus: 2.99 - .ascii "+" 2.100 - .byte EXESTR(eol2) 2.101 -// ------------------------------------------------------------------- 2.102 - 2.103 exestart: 2.104 cld 2.105 movw $0x100, %si 2.106 @@ -173,7 +135,7 @@ 2.107 movw (%si), %cx 2.108 jcxz is386 2.109 #endif 2.110 - movw $(EXESTR(0x8000))/2, %cx 2.111 + movw $(EXELOC(0x8000))/2, %cx 2.112 chklp: 2.113 lodsw 2.114 addw %ax, %dx 2.115 @@ -182,7 +144,7 @@ 2.116 je is386 // dx == 0 ? 2.117 abort: 2.118 puts: 2.119 - movb $1, %ah 2.120 + movb $0x80, %ah 2.121 xchgw %ax, %si 2.122 putslp: 2.123 lodsb 2.124 @@ -209,21 +171,14 @@ 2.125 cmpb $3, %al 2.126 movb $EXESTR(noDOS3), %al 2.127 jb abort 2.128 - movw $moveend-move, %cx 2.129 - movw $0xC000, %di 2.130 - call move2 2.131 -move: 2.132 - movb $0x80, %ch 2.133 movw $0x0100, %di 2.134 - pushw comstart-end_header(%di) // .com address 2.135 -move2: 2.136 - popw %si 2.137 + movw comstart-end_header(%di), %si // .com address 2.138 pushw %di 2.139 + movb $0x7D, %ch 2.140 rep 2.141 movsb 2.142 moveret: 2.143 ret 2.144 -moveend: 2.145 2.146 VersionVCPI: 2.147 cmpb $0x40, %dl // >= 4.0 ? 2.148 @@ -259,6 +214,49 @@ 2.149 .byte 0x46 // version 2.150 .byte 0 2.151 2.152 - .org 440 2.153 -//////////////////////////// partition table ////////////////////////////////// 2.154 +// ------------------------------------------------------------------- 2.155 2.156 +help: 2.157 + .ascii "SliTaz GNU/L" // SliTaz GNU/Linux boot loader 2.158 + .byte EXESTR(iloader) 2.159 +no386: 2.160 + .ascii "No 386" // No 386+ 2.161 + .byte EXESTR(plus) 2.162 +ERRvcpi: 2.163 + .ascii "No EMM386/VCPI 4" // No EMM386/VCPI 4.0+ 2.164 + .byte EXESTR(dot0) 2.165 +chkerr: 2.166 + .ascii "Broken ISO image fil" // Broken ISO image file. 2.167 + .byte EXESTR(eeol) 2.168 +vm86modemsg: 2.169 + .ascii "vm86" // vm86 mode. 2.170 + .byte EXESTR(mode) 2.171 +rmPaging: 2.172 + .ascii "Invalid: paging + " // Invalid: paging + real mode. 2.173 +realmodemsg: 2.174 + .ascii "real" // real mode. 2.175 +// --------------- Must be in 00C0 013F range ------------------------ 2.176 +mode: 2.177 + .ascii " mod" 2.178 +eeol: 2.179 + .ascii "e" 2.180 + .byte EXESTR(eol) 2.181 +//noloader: 2.182 +// .ascii "No isol" // No isolinux boot loader 2.183 +iloader: 2.184 + .ascii "inux boot loader" 2.185 +eol: 2.186 + .ascii "." 2.187 +eol2: 2.188 + .asciz "\r\n" 2.189 +noDOS3: 2.190 + .ascii "No DOS 3" // No DOS 3.0+ 2.191 +dot0: 2.192 + .ascii ".0" 2.193 +plus: 2.194 + .ascii "+" 2.195 + .byte EXESTR(eol2) 2.196 + 2.197 + .org 0x8000 2.198 +////////////////////////// ISO9660 header ///////////////////////////////////// 2.199 +
3.1 --- a/syslinux/stuff/iso2exe/bootlinux.h Sat Mar 30 18:45:07 2013 +0000 3.2 +++ b/syslinux/stuff/iso2exe/bootlinux.h Sat Mar 30 18:36:46 2013 +0100 3.3 @@ -1,6 +1,6 @@ 3.4 #ifndef __BOOTLINUX_H 3.5 #define __BOOTLINUX_H 3.6 -extern long loadkernel(void); 3.7 +extern unsigned long loadkernel(void); 3.8 extern void loadinitrd(void); 3.9 extern void bootlinux(char *cmdline); 3.10 #endif
4.1 --- a/syslinux/stuff/iso2exe/init Sat Mar 30 18:45:07 2013 +0000 4.2 +++ b/syslinux/stuff/iso2exe/init Sat Mar 30 18:36:46 2013 +0100 4.3 @@ -353,6 +353,13 @@ 4.4 [ $? -eq 0 ] || return 4.5 usbdev || return 4.6 dd if=/mnt/$ISO of=$device 4.7 + if [ $(get 0 /mnt/$ISO) -eq 23117 ]; then # iso2exe ? 4.8 + LOC=$(get 69 /mnt/$ISO 1) 4.9 + # move isohybrid boot sector (partitionable) 4.10 + dd if=/mnt/$ISO bs=512 count=1 skip=$LOC of=$device conv=notrunc 4.11 + # move tazlito data (backward compatibility) 4.12 + dd if=/mnt/$ISO bs=512 count=20 skip=$(($LOC+1)) of=$device seek=2 conv=notrunc 4.13 + fi 4.14 } 4.15 4.16 usbkey()
5.1 --- a/syslinux/stuff/iso2exe/iso2exe.c Sat Mar 30 18:45:07 2013 +0000 5.2 +++ b/syslinux/stuff/iso2exe/iso2exe.c Sat Mar 30 18:36:46 2013 +0100 5.3 @@ -26,8 +26,9 @@ 5.4 #define partition 446 5.5 #define trksz (512 * heads * sectors) 5.6 unsigned long size, catalog, lba; 5.7 - int cylinders, i, j; 5.8 + int cylinders, i, j, isohybrid; 5.9 unsigned n; 5.10 + char tazlitoinfo[31*1024]; 5.11 #ifndef WIN32 5.12 char *bootiso; 5.13 for (bootiso = (char *) main; 5.14 @@ -53,28 +54,34 @@ 5.15 readsector(lba); 5.16 if (* (unsigned long *) (buffer + 64) != 1886961915) 5.17 quit("no isolinux.bin hybrid signature in bootloader"); 5.18 - * (unsigned long *) &bootiso[512 + 432] = lba * 4; 5.19 - * (unsigned long *) &bootiso[512 + 440] = rand(); 5.20 - * (unsigned long *) &bootiso[512 + partition] = 0x10080; 5.21 - * (unsigned short *) &bootiso[512 + 510] = 0xAA55; 5.22 + isohybrid = bootiso[69] * 512; 5.23 + * (unsigned long *) &bootiso[isohybrid + 432] = lba * 4; 5.24 + * (unsigned long *) &bootiso[isohybrid + 440] = rand(); 5.25 + * (unsigned long *) &bootiso[isohybrid + partition] = 0x10080; 5.26 + * (unsigned short *) &bootiso[isohybrid + 510] = 0xAA55; 5.27 size = lseek(fd, 0UL, SEEK_END); 5.28 cylinders = (size + trksz - 1) / trksz; 5.29 - bootiso[512 + partition + 4] = 23; // "Windows hidden IFS" 5.30 - bootiso[512 + partition + 5] = heads - 1; 5.31 - bootiso[512 + partition + 6] = (((cylinders - 1) & 0x300) >> 2) + sectors; 5.32 - bootiso[512 + partition + 7] = (cylinders - 1) & 0xFF; 5.33 - * (unsigned long *) &bootiso[512 + partition + 8] = 0; 5.34 - * (unsigned long *) &bootiso[512 + partition + 12] = cylinders * sectors * heads; 5.35 + bootiso[isohybrid + partition + 4] = 23; // "Windows hidden IFS" 5.36 + bootiso[isohybrid + partition + 5] = heads - 1; 5.37 + bootiso[isohybrid + partition + 6] = (((cylinders - 1) & 0x300) >> 2) + sectors; 5.38 + bootiso[isohybrid + partition + 7] = (cylinders - 1) & 0xFF; 5.39 + * (unsigned long *) &bootiso[isohybrid + partition + 8] = 0; 5.40 + * (unsigned long *) &bootiso[isohybrid + partition + 12] = cylinders * sectors * heads; 5.41 5.42 // Install iso2exe boot sector 5.43 - memcpy(bootiso + 512 - 66, bootiso + 1024 - 66, 66); 5.44 * (unsigned short *) (bootiso + 26) = rand(); 5.45 5.46 + // read tazlito flavor data 5.47 + lseek(fd, 1024UL, SEEK_SET); 5.48 + read(fd, tazlitoinfo, sizeof(tazlitoinfo)); 5.49 + 5.50 // Update iso image 5.51 + n = (bootiso[69] + 1) * 512; 5.52 lseek(fd, 0UL, SEEK_SET); 5.53 - write(fd, bootiso, 1024); 5.54 - lseek(fd, 0x8400UL - BOOTISOSZ, SEEK_SET); 5.55 - write(fd, bootiso + 1024, BOOTISOSZ - 1024); 5.56 + write(fd, bootiso, n); // EXE/PE + isohybrid mbr 5.57 + write(fd, tazlitoinfo, ((0x8000U - BOOTISOSZ) > sizeof(tazlitoinfo)) 5.58 + ? sizeof(tazlitoinfo) : (0x8000U - BOOTISOSZ)); 5.59 + write(fd, bootiso + n, BOOTISOSZ - n); // COM + rootfs + EXE/DOS 5.60 5.61 // Compute the checksum 5.62 lseek(fd, 0UL, SEEK_SET); 5.63 @@ -89,4 +96,6 @@ 5.64 write(fd, bootiso, 512); 5.65 nochksum: 5.66 close(fd); 5.67 + printf("Note you can create a USB key with %s.\n" 5.68 + "Simply rename it to a .exe file and run it.\n", argv[1]); 5.69 }
6.1 --- a/syslinux/stuff/iso2exe/iso2exe.sh Sat Mar 30 18:45:07 2013 +0000 6.2 +++ b/syslinux/stuff/iso2exe/iso2exe.sh Sat Mar 30 18:36:46 2013 +0100 6.3 @@ -25,18 +25,27 @@ 6.4 cp -a /dev/?d?* $TMP/dev 6.5 $0 --get init > $TMP/init.exe 6.6 grep -q mount.posixovl.iso2exe $TMP/init.exe && 6.7 - cp /usr/sbin/mount.posixovl $TMP/bin/mount.posixovl.iso2exe 6.8 + cp /usr/sbin/mount.posixovl $TMP/bin/mount.posixovl.iso2exe && 6.9 + echo "Store mount.posixovl..." 6.10 find $TMP -type f | xargs chmod +x 6.11 ( cd $TMP ; find * | cpio -o -H newc ) | \ 6.12 lzma e $TMP/rootfs.gz -si 2> /dev/null 6.13 SIZE=$(wc -c < $TMP/rootfs.gz) 6.14 store 24 $SIZE $1 6.15 - OFS=$(( 0x8000 - $SIZE )) 6.16 + OFS=$(( $OFS - $SIZE )) 6.17 printf "Adding rootfs.gz file at %04X...\n" $OFS 6.18 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc 6.19 rm -rf $TMP 6.20 } 6.21 6.22 +add_dosexe() 6.23 +{ 6.24 + OFS=$((0x7EE0)) 6.25 + printf "Adding DOS/EXE at %04X...\n" $OFS 6.26 + $0 --get bootiso.bin 2> /dev/null | \ 6.27 + ddq bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc 6.28 +} 6.29 + 6.30 add_doscom() 6.31 { 6.32 SIZE=$($0 --get boot.com | wc -c) 6.33 @@ -48,20 +57,19 @@ 6.34 6.35 add_win32exe() 6.36 { 6.37 + printf "Adding WIN32 file at %04X...\n" 0 6.38 + ddq if=/tmp/exe$$ of=$1 conv=notrunc 6.39 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c) 6.40 - if [ $SIZE -ne 0 ]; then 6.41 - OFS=$(( 128 + ( ($OFS - $SIZE + 128) & 0xFE00 ) )) 6.42 - printf "Adding WIN32 file at %04X...\n" $OFS 6.43 - LOC=$((0xAC+$(get 0x94 /tmp/exe$$))) 6.44 - for i in $(seq 1 $(get 0x86 /tmp/exe$$)); do 6.45 - CUR=$(get $LOC /tmp/exe$$) 6.46 - [ $CUR -eq 0 ] || store $LOC $(($CUR+$OFS-128)) /tmp/exe$$ 6.47 - LOC=$(($LOC+40)) 6.48 - done 6.49 - ddq if=/tmp/exe$$ of=$1 bs=1 skip=128 seek=$OFS conv=notrunc 6.50 - store 60 $OFS $1 6.51 - fi 6.52 + ddq if=/tmp/exe$$ of=$1 conv=notrunc 6.53 + printf "Adding bootiso head at %04X...\n" 0 6.54 + $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$ 6.55 + ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc 6.56 + store 69 $(($SIZE/512)) $1 8 6.57 + store 510 $((0xAA55)) $1 6.58 rm -f /tmp/exe$$ 6.59 + printf "Moving syslinux hybrid boot record at %04X ...\n" $SIZE 6.60 + ddq if=$2 bs=1 count=512 of=$1 seek=$SIZE conv=notrunc 6.61 + OFS=$(($SIZE+512)) 6.62 } 6.63 6.64 add_fdbootstrap() 6.65 @@ -77,9 +85,7 @@ 6.66 case "$1" in 6.67 --build) 6.68 shift 6.69 - [ $(tar cf - $@ | wc -c) -gt $((32 * 1024)) ] && 6.70 - echo "WARNING: The file set $@ is too large (31K max) :" && 6.71 - ls -l $@ 6.72 + ls -l $@ 6.73 cat >> $0 <<EOM 6.74 $(tar cf - $@ | lzma e -si -so | uuencode -m -) 6.75 EOT 6.76 @@ -92,20 +98,20 @@ 6.77 --array) 6.78 DATA=/tmp/dataiso$$ 6.79 ddq if=/dev/zero bs=32k count=1 of=$DATA 6.80 - ddq if=bootiso.bin of=$DATA conv=notrunc 6.81 - ddq if=$2 of=$DATA bs=512 seek=1 conv=notrunc 6.82 + add_win32exe $DATA $2 > /dev/null 6.83 + HSZ=$OFS 6.84 + add_dosexe $DATA > /dev/null 6.85 add_rootfs $DATA > /dev/null 6.86 add_doscom $DATA > /dev/null 6.87 - add_win32exe $DATA > /dev/null 6.88 add_fdbootstrap $DATA > /dev/null 6.89 name=${3:-bootiso} 6.90 cat <<EOT 6.91 6.92 -#define $(echo $name | tr '[a-z]' '[A-Z]')SZ $((0x8400 - $OFS)) 6.93 +#define $(echo $name | tr '[a-z]' '[A-Z]')SZ $((0x8000 - $OFS + $HSZ)) 6.94 6.95 #ifdef WIN32 6.96 static char $name[] = { 6.97 -$(hexdump -v -n 1024 -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g') 6.98 +$(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g') 6.99 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g') 6.100 }; 6.101 #endif 6.102 @@ -143,19 +149,21 @@ 6.103 [ ! -s "$1" ] && echo "usage: $0 image.iso" 1>&2 && exit 1 6.104 case "$(get 0 $1)" in 6.105 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;; 6.106 - 0) [ -x /usr/bin/isohybrid ] && isohybrid $1 6.107 + 0) [ -x /usr/bin/isohybrid ] && isohybrid $1 && echo "Do isohybrid" 6.108 esac 6.109 6.110 - echo "Moving syslinux hybrid boot record..." 6.111 - ddq if=$1 bs=512 count=1 | ddq of=$1 bs=512 count=1 seek=1 conv=notrunc 6.112 + echo "Read hybrid & tazlito data..." 6.113 + ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$ 6.114 + ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$ 6.115 + add_win32exe $1 /tmp/hybrid$$ 6.116 + printf "Moving tazlito data record at %04X ...\n" $OFS 6.117 + ddq if=/tmp/tazlito$$ bs=1 count=512 of=$1 seek=$OFS conv=notrunc 6.118 + rm -f /tmp/tazlito$$ /tmp/hybrid$$ 6.119 6.120 - echo "Inserting EXE boot record..." 6.121 - $0 --get bootiso.bin | ddq of=$1 conv=notrunc 6.122 - 6.123 # keep the largest room for the tazlito info file 6.124 + add_dosexe $1 6.125 add_rootfs $1 6.126 add_doscom $1 6.127 - add_win32exe $1 6.128 add_fdbootstrap $1 6.129 store 26 ${RANDOM:-0} $1 6.130 i=66
7.1 --- a/syslinux/stuff/iso2exe/win32.c Sat Mar 30 18:45:07 2013 +0000 7.2 +++ b/syslinux/stuff/iso2exe/win32.c Sat Mar 30 18:36:46 2013 +0100 7.3 @@ -1,6 +1,259 @@ 7.4 #include <windows.h> 7.5 +#include <winnt.h> 7.6 +#include <sys/types.h> 7.7 +#include <sys/stat.h> 7.8 +#include <fcntl.h> 7.9 7.10 -int main() 7.11 +#define BOOTSTRAP_SECTOR_COUNT_OFFSET 28 7.12 + 7.13 +static int fullread(int fd, char *p, int n) 7.14 { 7.15 - MessageBox(NULL,"No support for Windows yet.","Sorry",MB_OK|MB_ICONERROR); 7.16 + int i, j; 7.17 + for (i = 0; n > 0; i += j, n -= j) { 7.18 + j = read(fd, p + i, n); 7.19 + if (j <= 0) break; 7.20 + } 7.21 + return i; 7.22 } 7.23 + 7.24 +static int fullwrite(int fd, char *p, int n) 7.25 +{ 7.26 + int i, j; 7.27 + for (i = 0; n > 0; i += j, n -= j) { 7.28 + j = write(fd, p + i, n); 7.29 + if (j <= 0) break; 7.30 + } 7.31 + return i; 7.32 +} 7.33 + 7.34 +static void exec16bits(char *isoFileName) 7.35 +{ 7.36 + int fdiso, fdtmp, i; 7.37 + long buffer[512/4]; 7.38 + char tmpFileName[MAX_PATH], *p; 7.39 + 7.40 + strcpy(tmpFileName, isoFileName); 7.41 + p = strrchr(tmpFileName, '\\'); 7.42 + if (!p++) p = tmpFileName; 7.43 + strcpy(p, "tazboot.exe"); 7.44 + fdiso = open(isoFileName, O_RDONLY|O_BINARY); 7.45 + fdtmp = open(tmpFileName, O_WRONLY|O_BINARY|O_CREAT,0555); 7.46 + for (i = 0; i < 0x8000; i += sizeof(buffer)) { 7.47 + fullread(fdiso, (char *) buffer, sizeof(buffer)); 7.48 + if (i == 0) buffer[15] = 0; // kill PE header 7.49 + fullwrite(fdtmp, (char *) buffer, sizeof(buffer)); 7.50 + } 7.51 + close(fdiso); 7.52 + close(fdtmp); 7.53 + execl(tmpFileName, isoFileName); 7.54 +} 7.55 + 7.56 +static int iswinnt(void) 7.57 +{ 7.58 + OSVERSIONINFOA Version; 7.59 + Version.dwOSVersionInfoSize = sizeof(Version); 7.60 + return (GetVersionEx(&Version) && 7.61 + Version.dwPlatformId != VER_PLATFORM_WIN32_WINDOWS); // not Win9x 7.62 +} 7.63 + 7.64 +static int ishybrid(char *isoFileName) 7.65 +{ 7.66 + int fdiso; 7.67 + char buffer[2048]; 7.68 + unsigned long magic = 0; 7.69 + 7.70 + fdiso = open(isoFileName, O_RDONLY|O_BINARY); 7.71 + if (lseek(fdiso, 17 * 2048L, SEEK_SET) != -1 && 7.72 + fullread(fdiso, buffer, 2048) == 2048 && 7.73 + strncmp(buffer+23,"EL TORITO SPECIFICATION",23) == 0) { 7.74 + unsigned long lba = * (unsigned long *) (buffer + 71); 7.75 + 7.76 + if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 && 7.77 + fullread(fdiso, buffer, 2048) == 2048 && 7.78 + * (unsigned long *) (buffer + 0) == 1 && 7.79 + * (unsigned long *) (buffer + 30) == 0x88AA55) { 7.80 + lba = * (unsigned long *) (buffer + 40); 7.81 + if (lseek(fdiso, lba * 2048L, SEEK_SET) != -1 && 7.82 + fullread(fdiso, buffer, 2048) == 2048) 7.83 + magic = * (unsigned long *) (buffer + 64); 7.84 + } 7.85 + } 7.86 + close(fdiso); 7.87 + return (magic == 1886961915); 7.88 +} 7.89 + 7.90 +#define MODE_READ 0 7.91 +#define MODE_WRITE 1 7.92 +static int rdwrsector(int mode, int drive, unsigned long startingsector, 7.93 + unsigned long count, char *buffer) 7.94 +{ 7.95 + HANDLE hDevice; 7.96 + DWORD result; 7.97 + char devname[sizeof("\\\\.\\PhysicalDrive0")]; 7.98 + 7.99 + if (drive >= 128) { 7.100 + strcpy(devname, "\\\\.\\PhysicalDrive0"); 7.101 + devname[17] += drive - 128; 7.102 + } 7.103 + else { 7.104 + strcpy(devname, "\\\\.\\A:"); 7.105 + devname[4] += drive; 7.106 + } 7.107 + hDevice = CreateFile (devname, GENERIC_READ, 7.108 + FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); 7.109 + if (hDevice == INVALID_HANDLE_VALUE) 7.110 + return -1; 7.111 + SetFilePointer(hDevice, (startingsector*512), NULL, FILE_BEGIN); 7.112 + if (mode == MODE_READ) { 7.113 + if (!ReadFile(hDevice, buffer, 512*count, &result, NULL)) 7.114 + result = -1; 7.115 + } 7.116 + else { 7.117 + if (!WriteFile(hDevice, buffer, 512*count, &result, NULL)) 7.118 + result = -1; 7.119 + } 7.120 + CloseHandle(hDevice); 7.121 + return result; 7.122 +} 7.123 + 7.124 +static void rawrite(unsigned long drive, char *isoFileName) 7.125 +{ 7.126 + int fdiso, s, dev, isohybrid = -1; 7.127 + char buffer[2048]; 7.128 + 7.129 + if (drive == 0) return; 7.130 + for (dev = 128; (drive & 1) == 0; dev++) 7.131 + drive >>= 1; 7.132 + fdiso = open(isoFileName, O_RDONLY|O_BINARY); 7.133 + for (s = 0;;) { 7.134 + int s, n = fullread(fdiso, buffer, sizeof(buffer)); 7.135 + if (n <= 0) break; 7.136 + n = (n+511)/512; 7.137 + if (s == 0) isohybrid = buffer[69]; 7.138 + rdwrsector(MODE_WRITE, dev, s, n, buffer); 7.139 + if (s == isohybrid) 7.140 + rdwrsector(MODE_WRITE, dev, 0, 1, buffer); 7.141 + s += n; 7.142 + } 7.143 + close(fdiso); 7.144 +} 7.145 + 7.146 +static unsigned long drives(void) 7.147 +{ 7.148 + int i, mask, result; 7.149 + char buffer[512]; 7.150 + for (i = result = 0, mask = 1; i < 8; i++, mask <<= 1) { 7.151 + if (rdwrsector(MODE_READ, i+128, 0, 1, buffer) != -1) 7.152 + result |= mask; 7.153 + } 7.154 + return result; 7.155 +} 7.156 + 7.157 +static void writefloppy(char *isoFileName) 7.158 +{ 7.159 + char buffer[512]; 7.160 + int i, n, fd; 7.161 + 7.162 + buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0; 7.163 + fd = open(isoFileName, O_RDONLY|O_BINARY); 7.164 + if (fd != -1) { 7.165 + read(fd, buffer, sizeof(buffer)); 7.166 + n = buffer[BOOTSTRAP_SECTOR_COUNT_OFFSET]; 7.167 + if (n != 0 && 7.168 + lseek(fd, * (unsigned long *) (buffer + 60) - (512 * n), 7.169 + SEEK_SET) != -1) { 7.170 + for (i = 0; i < n; i++) { 7.171 + fullread(fd, buffer, 512); 7.172 + if (i == 1) strncpy(buffer, isoFileName, 512); 7.173 + rdwrsector(MODE_WRITE, 0, i, 1, buffer); 7.174 + } 7.175 + } 7.176 + close(fd); 7.177 + } 7.178 +} 7.179 + 7.180 +//TODO #define VCPI_LINUX_LOADER The DOS/EXE loader can boot in VM86 using VCPI API 7.181 +int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, 7.182 + LPSTR lpCmdLine, int nCmdShow) 7.183 +{ 7.184 + char isoFileName[MAX_PATH]; 7.185 + char header[32]; 7.186 + int fd; 7.187 + int usbkeyicon = MB_ICONASTERISK; 7.188 + char *usbkeymsg = "You can either:\n\n" 7.189 + "- create a SliTaz USB boot key or a boot memory card.\n" 7.190 + " (note that this will be read only like a CDROM.\n" 7.191 + " The Slitaz utility 'tazusb' can be used later to create\n" 7.192 + " a true read/write USB key).\n\n" 7.193 + "- create a SliTaz bootstrap floppy for the ISO image\n" 7.194 + " on the hard disk.\n" 7.195 + "\nDo you want to create a boot key now ?"; 7.196 + 7.197 + GetModuleFileName(hInstance, isoFileName, MAX_PATH); 7.198 + if (!iswinnt()) { 7.199 +#ifdef VCPI_LINUX_LOADER 7.200 + exec16bits(isoFileName); 7.201 +#else 7.202 + MessageBox(NULL,"No support for Win9x yet.\n" 7.203 + "Retry in DOS mode without emm386.\n", 7.204 + "Sorry", MB_OK|MB_ICONERROR); 7.205 + exit(1); 7.206 +#endif 7.207 + } 7.208 + if (!ishybrid(isoFileName)) { 7.209 + if (MessageBox(NULL,"Not an isolinux hybrid ISO.\n" 7.210 + "This ISO image will not boot\n" 7.211 + "from the media you will create !", 7.212 + "Will not boot !", 7.213 + MB_OKCANCEL|MB_ICONWARNING) == IDCANCEL) 7.214 + exit(0); 7.215 + } 7.216 + header[BOOTSTRAP_SECTOR_COUNT_OFFSET] = 0; 7.217 + fd = open(isoFileName, O_RDONLY|O_BINARY); 7.218 + if (fd != -1) { 7.219 + read(fd, header, sizeof(header)); 7.220 + close(fd); 7.221 + } 7.222 + if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] == 0) { // No floppy bootstrap available 7.223 + usbkeyicon = MB_ICONQUESTION; 7.224 + usbkeymsg = "Do you want to create a boot key ?"; 7.225 + } 7.226 + if (MessageBox(NULL,usbkeymsg, "Create a boot stick ?", 7.227 + MB_YESNO|usbkeyicon) == IDYES) { 7.228 + unsigned long base, new; 7.229 + int retry; 7.230 + 7.231 + if (MessageBox(NULL,"Step 1: unplug the USB stick.", 7.232 + "Drive detection 1/2", 7.233 + MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL) 7.234 + exit(0); 7.235 + base = drives(); 7.236 + if (MessageBox(NULL,"Step 2: plug the USB stick in.", 7.237 + "Drive detection 2/2", 7.238 + MB_OKCANCEL|MB_ICONEXCLAMATION) == IDCANCEL) 7.239 + exit(0); 7.240 + retry = 0; 7.241 + do { 7.242 + Sleep(1000); // ms 7.243 + new = drives(); 7.244 + } while (new == base && retry++ < 10); 7.245 + if (new == base) { 7.246 + MessageBox(NULL,"No USB stick found.","Sorry", 7.247 + MB_OK|MB_ICONERROR); 7.248 + exit(1); 7.249 + } 7.250 + rawrite(base ^ new, isoFileName); 7.251 + } 7.252 + if (header[BOOTSTRAP_SECTOR_COUNT_OFFSET] != 0 && 7.253 + MessageBox(NULL,"Do you want to create a bootstrap floppy ?", 7.254 + "Create a bootstrap floppy ?", 7.255 + MB_YESNO|MB_ICONQUESTION) == IDYES && 7.256 + MessageBox(NULL,"Insert a floppy disk in drive now", 7.257 + "Insert floppy", 7.258 + MB_OKCANCEL|MB_ICONEXCLAMATION) != IDCANCEL) { 7.259 + 7.260 + // Create a 9k bootstrap with vfat, ext2 & ntfs drivers 7.261 + // to boot the ISO image on hard disk 7.262 + writefloppy(isoFileName); 7.263 + } 7.264 +}