wok-6.x 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$$
279 HOLE=$(($OFS+512))
281 # keep the largest room for the tazlito info file
282 add_dosexe $1
283 add_rootfs $1
284 add_doscom $1
285 add_fdbootstrap $1
286 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
287 store 26 ${RANDOM:-0} $1
288 [ "$2" ] && echo "$2 " | \
289 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
290 if [ $(stat -c %s $1) -gt 34816 ]; then
291 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
292 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(get 32848 $1 4) | \
293 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
294 ddq bs=16 seek=2047 conv=notrunc of=$1
295 fi
296 echo -n "Adding boot checksum..."
297 store 64 $(od -v -j 66 -N 32702 -t u2 -w2 -An $1 | \
298 awk '{ i+= $0 } END { print -(i % 65536) }') $1
299 if [ $(stat -c %s $1) -gt 32768 ]; then
300 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
301 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
302 awk '{ i+= $0 } END { print (i % 65536) }') \
303 + $(get $(($n+1)) $1 1)))
304 store 18 $(( (-$n -1) % 65536 )) $1
305 fi
306 echo " done."
307 }
309 main $@ <<EOT