wok view syslinux/stuff/iso2exe/iso2exe.sh @ rev 17591

syslinux/isohybrib.exe: add --md5, --undo
author Pascal Bellard <pascal.bellard@slitaz.org>
date Tue Feb 10 08:53:27 2015 +0100 (2015-02-10)
parents 00bb1e4137c6
children 639e963885dd
line source
1 #!/bin/sh
3 ddq()
4 {
5 dd $@ 2> /dev/null
6 }
8 store()
9 {
10 n=$2; for i in $(seq 8 8 ${4:-16}); do
11 printf '\\\\x%02X' $(($n & 255))
12 n=$(($n >> 8))
13 done | xargs echo -en | ddq bs=1 conv=notrunc of=$3 seek=$(($1))
14 }
16 get()
17 {
18 echo $(od -j $(($1)) -N ${3:-2} -t u${3:-2} -An $2)
19 }
21 compress()
22 {
23 if [ "$1" ]; then
24 gzip -9 > $1
25 [ "$(which advdef 2> /dev/null)" ] &&
26 advdef -z4 $1 > /dev/null
27 elif [ "$(which xz 2> /dev/null)" ]; then
28 xz -z -e --format=lzma --lzma1=mode=normal --stdout
29 else
30 lzma e -si -so
31 fi 2> /dev/null
32 }
34 add_rootfs()
35 {
36 TMP=/tmp/iso2exe$$
37 mkdir -p $TMP/bin $TMP/dev
38 cp -a /dev/?d?* /dev/tty /dev/tty0 $TMP/dev
39 $0 --get init > $TMP/init.exe
40 # mount -o loop,ro $1 $TMP
41 # oldslitaz="$(ls $TMP/boot/isolinux/splash.lss 2> /dev/null)"
42 # umount -d $TMP
43 # [ "$oldslitaz" ] && # for SliTaz <= 3.0 only...
44 # grep -q mount.posixovl.iso2exe $TMP/init.exe &&
45 # cp /usr/sbin/mount.posixovl $TMP/bin/mount.posixovl.iso2exe \
46 # 2> /dev/null && echo "Store mount.posixovl ($(wc -c \
47 # < /usr/sbin/mount.posixovl) bytes) ..."
48 find $TMP -type f -print0 | xargs -0 chmod +x
49 ( cd $TMP ; find * | cpio -o -H newc ) | compress $TMP/rootfs.gz
50 SIZE=$(wc -c < $TMP/rootfs.gz)
51 store 24 $SIZE $1
52 OFS=$(( $OFS - $SIZE ))
53 printf "Adding rootfs.gz file at %04X (%d bytes) ...\n" $OFS $SIZE
54 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
55 rm -rf $TMP
56 }
58 add_dosexe()
59 {
60 TMP=/tmp/bootiso$$
61 $0 --get bootiso.bin > $TMP 2> /dev/null
62 OFS=$(($(get 20 $TMP) - 0xC0))
63 printf "Adding DOS/EXE stub at %04X (%d bytes) ...\n" $OFS $((0x8000 - $OFS))
64 ddq if=$TMP bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc
65 rm -f $TMP
66 }
68 add_doscom()
69 {
70 SIZE=$($0 --get boot.com | wc -c)
71 OFS=$(( $OFS - $SIZE ))
72 printf "Adding DOS boot file at %04X (%d bytes) ...\n" $OFS $SIZE
73 $0 --get boot.com | ddq of=$1 bs=1 seek=$OFS conv=notrunc
74 store 66 $(($OFS+0xC0)) $1
75 }
77 add_win32exe()
78 {
79 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c)
80 printf "Adding WIN32 file at %04X (%d bytes) ...\n" 0 $SIZE
81 ddq if=/tmp/exe$$ of=$1 conv=notrunc
82 printf "Adding bootiso head at %04X...\n" 0
83 $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$
84 ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc
85 store $((0x94)) $((0xE0 - 12*8)) $1
86 store $((0xF4)) $((16 - 12)) $1
87 ddq if=$1 of=/tmp/coff$$ bs=1 skip=$((0x178)) count=$((0x88))
88 ddq if=/tmp/coff$$ of=$1 conv=notrunc bs=1 seek=$((0x178 - 12*8))
89 ddq if=/tmp/exe$$ of=$1 bs=1 count=30 seek=$((0x1A0)) skip=$((0x1A0)) conv=notrunc
90 ddq if=$2 bs=1 skip=$((0x1BE)) seek=$((0x1BE)) count=66 of=$1 conv=notrunc
91 store 69 $(($SIZE/512)) $1 8
92 store 510 $((0xAA55)) $1
93 rm -f /tmp/exe$$ /tmp/coff$$
94 printf "Moving syslinux hybrid boot record at %04X (512 bytes) ...\n" $SIZE
95 ddq if=$2 bs=1 count=512 of=$1 seek=$SIZE conv=notrunc
96 OFS=$(($SIZE+512))
97 }
99 add_fdbootstrap()
100 {
101 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
102 if [ $SIZE -ne 0 ]; then
103 SIZE=$(( $SIZE - 512 )) # sector 2 is data
104 OFS=$(( $OFS - $SIZE ))
105 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
106 $0 --get bootfd.bin | \
107 ddq of=$1 bs=1 count=512 seek=$OFS conv=notrunc
108 $0 --get bootfd.bin | \
109 ddq of=$1 bs=1 skip=1024 seek=$((512 + $OFS)) conv=notrunc
110 store 28 $(($SIZE/512)) $1 8
111 fi
112 }
113 case "$1" in
114 --build)
115 shift
116 ls -l $@
117 cat >> $0 <<EOM
118 $(tar cf - $@ | compress | uuencode -m -)
119 EOT
120 EOM
121 sed -i '/^case/,/^esac/d' $0
122 exit ;;
123 --get)
124 cat $2
125 exit ;;
126 --array)
127 DATA=/tmp/dataiso$$
128 ddq if=/dev/zero bs=32k count=1 of=$DATA
129 add_win32exe $DATA $2 > /dev/null
130 HSZ=$OFS
131 add_dosexe $DATA > /dev/null
132 add_rootfs $DATA > /dev/null
133 add_doscom $DATA > /dev/null
134 add_fdbootstrap $DATA > /dev/null
135 name=${3:-bootiso}
136 BOOTISOSZ=$((0x8000 - $OFS + $HSZ))
137 cat <<EOT
139 #define $(echo $name | tr '[a-z]' '[A-Z]')SZ $BOOTISOSZ
141 #ifdef WIN32
142 static char $name[] = {
143 /* head */
144 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g')
145 /* tail */
146 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' $DATA | sed 's/ 0x ,/ /g')
148 /* These strange constants are defined in RFC 1321 as
149 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
150 */
151 /* static const uint32_t C_array[64] */
152 EOT
153 while read a b c d; do
154 for i in $a $b $c $d; do
155 echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
156 done
157 done <<EOT
158 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
159 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
160 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
161 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
162 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
163 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
164 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
165 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
166 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
167 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
168 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
169 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
170 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
171 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
172 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
173 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
174 EOT
175 cat <<EOT
176 /* static const char P_array[64] */
177 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
178 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
179 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
180 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
181 /* static const char S_array[16] */
182 7, 12, 17, 22,
183 5, 9, 14, 20,
184 4, 11, 16, 23,
185 6, 10, 15, 21,
186 EOT
188 for mode in data offset ; do
189 ofs=0
190 while read tag str; do
191 if [ "$mode" == "data" ]; then
192 echo -en "$str\0" | hexdump -v -e '" " 16/1 "0x%02X, "' \
193 -e '" // %04.4_ax |" 16/1 "%_p" "| \n"' | \
194 sed 's/ 0x ,/ /g'
195 else
196 if [ $ofs -eq 0 ]; then
197 cat <<EOT
198 };
199 #else
200 static char *$name;
201 #endif
203 #define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
204 #define P_array (char *) ($name + $(($BOOTISOSZ+(64*4))))
205 #define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64)))
206 #define ELTORITOOFS 3
207 EOT
208 fi
209 echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))"
210 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
211 fi
212 done <<EOT
213 READSECTORERR Read sector failure.
214 USAGE Usage: isohybrid.exe file.iso [--forced|--undo|--md5]
215 OPENERR Can't open r/w the iso file.
216 ELTORITOERR No EL TORITO SPECIFICATION signature.
217 CATALOGERR Invalid boot catalog.
218 HYBRIDERR No isolinux.bin hybrid signature.
219 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to a .exe file and run it.
220 FORCEMSG You can add --forced to proceed anyway.
221 MD5MSG Computing md5sum...
222 UNINSTALLMSG Uninstall done.
223 EOT
224 done
225 rm -rf $DATA
226 exit ;;
227 --exe)
228 # --exe mvcom.bin x.com y.exe > xy.exe
229 cat $4 $3 > /tmp/exe$$
230 S=$(stat -c %s /tmp/exe$$)
231 store 2 $(($S%512)) /tmp/exe$$
232 store 4 $((($S+511)/512)) /tmp/exe$$
233 store 14 -16 /tmp/exe$$
234 store 16 -2 /tmp/exe$$
235 store 20 256 /tmp/exe$$
236 store 22 -16 /tmp/exe$$
237 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
238 store 65 $(stat -c %s $3) /tmp/exe$$
239 store 68 $((0x100-0x40+$(stat -c %s $4))) /tmp/exe$$
240 cat /tmp/exe$$
241 rm -f /tmp/exe$$
242 exit ;;
243 esac
245 main()
246 {
247 [ $(id -u) -ne 0 ] && exec su -c "$0 $@" < /dev/tty
248 case "${1/--/-}" in
249 -get) shift
250 uudecode | unlzma | tar xOf - $@
251 exit ;;
252 *) cat > /dev/null
253 esac
255 [ ! -s "$1" ] &&
256 echo "usage: $0 image.iso [--undo|\"DOS help message\"]" 1>&2 && exit 1
257 case "${2/--/-}" in
258 -u*|-r*|-w*)
259 case "$(get 0 $1)" in
260 23117)
261 ddq if=$1 bs=512 count=2 skip=$(get 69 $1 1) of=$1 conv=notrunc
262 ddq if=/dev/zero bs=1k seek=1 count=31 of=$1 conv=notrunc ;;
263 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
264 esac
265 exit 0
266 esac
267 case "$(get 0 $1)" in
268 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
269 0) $0 --get isohdpfx.bin | ddq bs=512 count=1 of=$1 conv=notrunc
270 esac
272 echo "Read hybrid & tazlito data..."
273 ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$
274 ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$
275 add_win32exe $1 /tmp/hybrid$$
276 printf "Moving tazlito data record at %04X (512 bytes) ...\n" $OFS
277 ddq if=/tmp/tazlito$$ bs=1 count=512 of=$1 seek=$OFS conv=notrunc
278 rm -f /tmp/tazlito$$ /tmp/hybrid$$