wok-6.x view syslinux/stuff/iso2exe/iso2exe.sh @ rev 19425
syslinux/isohybrid: boot efi support
author | Pascal Bellard <pascal.bellard@slitaz.org> |
---|---|
date | Fri Sep 30 21:29:58 2016 +0200 (2016-09-30) |
parents | 4e8ef03c7137 |
children | 986d5902efcf |
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 -i100 $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/dev
38 cp -a /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 && mkdir $TMP/bin &&
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 find $TMP -print0 | xargs -0 touch -t 197001010100.00
50 ( cd $TMP ; find * | grep -v rootfs.gz | cpio -o -H newc ) | \
51 compress $TMP/rootfs.gz
52 SIZE=$(wc -c < $TMP/rootfs.gz)
53 store 24 $SIZE $1
54 OFS=$(( $OFS - $SIZE ))
55 printf "Adding rootfs.gz file at %04X (%d bytes) ...\n" $OFS $SIZE
56 cat $TMP/rootfs.gz | ddq of=$1 bs=1 seek=$OFS conv=notrunc
57 rm -rf $TMP
58 }
60 add_dosexe()
61 {
62 TMP=/tmp/bootiso$$
63 $0 --get bootiso.bin > $TMP 2> /dev/null
64 OFS=$(($(get 20 $TMP) - 0xC0))
65 printf "Adding DOS/EXE stub at %04X (%d bytes) ...\n" $OFS $((0x8000 - $OFS))
66 ddq if=$TMP bs=1 skip=$OFS of=$1 seek=$OFS conv=notrunc
67 rm -f $TMP
68 }
70 add_doscom()
71 {
72 SIZE=$($0 --get boot.com | wc -c)
73 OFS=$(( $OFS - $SIZE ))
74 printf "Adding DOS boot file at %04X (%d bytes) ...\n" $OFS $SIZE
75 $0 --get boot.com | ddq of=$1 bs=1 seek=$OFS conv=notrunc
76 store 64 $(($OFS+0xC0)) $1
77 }
79 add_tazlito_info()
80 {
81 HOLE=$OFS
82 [ $(get 0 $2) -eq 35615 ] || return
83 zcat $2 | compress /tmp/rezipped$$.gz
84 n=$(stat -c %s /tmp/rezipped$$.gz)
85 printf "Moving tazlito data record at %04X ($n bytes) ...\n" $OFS
86 ddq if=/tmp/rezipped$$.gz bs=1 of=$1 seek=$OFS conv=notrunc
87 HOLE=$(($HOLE+$n))
88 rm -f /tmp/rezipped$$.gz
89 if [ -n "$gpt" ]; then
90 store $((0x25E)) $n $1
91 store $((0x25C)) $OFS $1
92 fi
93 }
95 add_win32exe()
96 {
97 SIZE=$($0 --get win32.exe 2> /dev/null | tee /tmp/exe$$ | wc -c)
98 [ -n "$gpt" ] && SIZE=$(($SIZE+1024))
99 [ -n "$mac" ] && SIZE=$(($SIZE+3072))
100 printf "Adding WIN32 file at %04X (%d bytes) ...\n" 0 $SIZE
101 ddq if=/tmp/exe$$ of=$1 conv=notrunc
102 if [ -n "$gpt" ]; then
103 printf "Adding GPT at %04X (1024 bytes) ...\n" 512
104 ddq if=$2 bs=512 skip=1 of=$1 seek=1 conv=notrunc
105 i=3; [ -n "$mac" ] && i=9
106 ddq if=/tmp/exe$$ bs=512 skip=1 of=$1 seek=$i conv=notrunc
107 for i in 12C 154 17C ; do # always 3 UPX sections
108 store $((0x$i)) $((1024 + $(get 0x$i $1))) $1 2
109 done
110 fi
111 printf "Adding bootiso head at %04X...\n" 0
112 $0 --get bootiso.bin 2> /dev/null > /tmp/exe$$
113 ddq if=/tmp/exe$$ of=$1 bs=128 count=1 conv=notrunc
114 store $((0x94)) $((0xE0 - 12*8)) $1
115 store $((0xF4)) $((16 - 12)) $1
116 ddq if=$1 of=/tmp/coff$$ bs=1 skip=$((0x178)) count=$((0x88))
117 ddq if=/tmp/coff$$ of=$1 conv=notrunc bs=1 seek=$((0x178 - 12*8))
118 ddq if=/tmp/exe$$ of=$1 bs=1 count=24 seek=$((0x1A0)) skip=$((0x1A0)) conv=notrunc
119 ddq if=$2 bs=1 skip=$((0x1B8)) seek=$((0x1B8)) count=72 of=$1 conv=notrunc
120 store 510 $((0xAA55)) $1
121 rm -f /tmp/exe$$ /tmp/coff$$
122 i=$SIZE; OFS=$(($SIZE+512))
123 [ -n "$mac" ] && OFS=$SIZE && i=1536
124 store 417 $(($i/512)) $1 8
125 printf "Moving syslinux hybrid boot record at %04X (512 bytes) ...\n" $i
126 ddq if=$2 bs=1 count=512 of=$1 seek=$i conv=notrunc
127 }
129 add_fdbootstrap()
130 {
131 SIZE=$($0 --get bootfd.bin 2> /dev/null | wc -c)
132 if [ $SIZE -ne 0 ]; then
133 SIZE=$(( $SIZE - 512 )) # sector 2 is data
134 OFS=$(( $OFS - $SIZE ))
135 printf "Adding floppy bootstrap file at %04X (%d bytes) ...\n" $OFS $SIZE
136 $0 --get bootfd.bin | \
137 ddq of=$1 bs=1 count=512 seek=$OFS conv=notrunc
138 $0 --get bootfd.bin | \
139 ddq of=$1 bs=1 skip=1024 seek=$((512 + $OFS)) conv=notrunc
140 store 26 $(($SIZE/512)) $1 8
141 fi
142 }
144 gzsize()
145 {
146 echo $(($(hexdump -C | awk ' {
147 for (i = 2; i < 18; i++) if ($i != "00") break;
148 if (i == 18) {
149 for (i = 17; i > 1; i--) if ($i != "00") break;
150 print "0x" $1 " + 7 - " (16 - i)
151 exit
152 }
153 }')))
154 }
156 fileofs()
157 {
158 [ $(get 1024 "$ISO") -eq 35615 ] && x=1024 ||
159 x=$((512*(1+$(get 417 "$ISO" 1))))
160 stub=$(($(get 20 "$ISO") - 0xC0))
161 c=$(custom_config_sector "$ISO")
162 SIZE=0; OFFSET=0
163 case "$1" in
164 win32.exe) [ $x -eq 2048 ] && x=10752
165 [ $x -eq 1024 ] || SIZE=$(($x - 512));;
166 syslinux.mbr) [ $x -eq 1024 ] || OFFSET=$(($x - 512)); SIZE=512;;
167 flavor.info) [ $(get 22528 "$ISO") -eq 35615 ] && OFFSET=22528
168 [ $x -eq 2048 ] && x=$(get 0x25C "$ISO") &&
169 SIZE=$(get 0x25E "$ISO")
170 [ $(get $x "$ISO") -eq 35615 ] && OFFSET=$x
171 [ $OFFSET -ne 0 ] && [ $SIZE -eq 0 ] &&
172 SIZE=$(ddq bs=512 skip=$(($OFFSET/512)) if="$ISO" | gzsize);;
173 floppy.boot) SIZE=$(($(get 26 "$ISO" 1)*512))
174 OFFSET=$(($(get 64 "$ISO") - 0xC0 - $SIZE));;
175 rootfs.gz) SIZE=$(get 24 "$ISO"); OFFSET=$(($stub - $SIZE));;
176 tazboot.com) OFFSET=$(($(get 64 "$ISO") - 0xC0))
177 SIZE=$(($stub - $(get 24 "$ISO") - $OFFSET));;
178 dosstub) OFFSET=$stub; SIZE=$((0x8000 - $OFFSET));;
179 boot.md5) OFFSET=$((0x7FF0)); SIZE=16;;
180 fs.iso) OFFSET=$((0x8000))
181 SIZE=$((2048*$c - $OFFSET));;
182 custom.magic) ddq bs=2k skip=$c if="$ISO" | ddq bs=1 count=6 | \
183 grep -q '#!boot' && OFFSET=$((2048*$c)) &&
184 SIZE=39 ;;
185 custom.append) OFFSET=$((2048*$c+47)) &&
186 SIZE=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
187 sed '/^append=/!d;s/^[^=]*=.//' | wc -c);;
188 custom.initrd) i=$(ddq bs=2k skip=$c if="$ISO" count=1 | \
189 sed '/^append=\|^initrd:/!d' | wc -c)
190 OFFSET=$((2048*$c+$x+40))
191 SIZE=$(($(ddq bs=2k skip=$c if="$ISO" count=1 | \
192 sed '/^initrd:/!d;s/.*://') + 0));;
193 esac
194 }
196 list()
197 {
198 HEAP=0
199 for f in win32.exe syslinux.mbr flavor.info floppy.boot tazboot.com \
200 rootfs.gz dosstub boot.md5 fs.iso custom.magic custom.append \
201 custom.initrd; do
202 fileofs $f
203 [ $SIZE -le 0 ] && continue
204 [ "${OFFSET:8}" ] && continue
205 [ $OFFSET -lt 0 ] && continue
206 [ $(get $OFFSET "$ISO") -eq 0 ] && continue
207 [ $OFFSET -gt $HEAP ] && [ $(($OFFSET - $HEAP)) -gt 16 ] &&
208 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
209 [ $OFFSET -ge $HEAP ] && HEAP=$(($OFFSET+$SIZE))
210 printf "$f at %04X ($SIZE bytes).\n" $OFFSET
211 done
212 OFFSET=$(stat -c %s "$ISO")
213 [ $OFFSET -gt $HEAP ] &&
214 printf "%d free bytes in %04X..%04X\n" $(($OFFSET - $HEAP)) $HEAP $OFFSET
215 if [ $(get 510 "$ISO") -eq 43605 ]; then
216 echo "MBR partitions :"
217 for i in 0 1 2 3; do
218 SIZE=$(get $((446+12+16*i)) "$ISO" 4)
219 [ $SIZE -eq 0 ] && continue
220 OFFSET=$(get $((446+8+16*i)) "$ISO" 4)
221 printf " $i:%08X %08X %02X\n" $OFFSET $SIZE \
222 $(get $((446+4+16*i)) "$ISO" 1)
223 done
224 if [ $(get 466 "$ISO") -eq 65263 ]; then
225 echo "EFI partitions :"
226 n=$(get 584 "$ISO" 1)
227 s=$(get 596 "$ISO")
228 o=$((($(get 552 "$ISO" 1)*512)-($(get 592 "$ISO")*$s)))
229 i=0
230 while [ $n -gt $i ]; do
231 f=$(get $(($o+0x20)) "$ISO" 4)
232 l=$(($(get $(($o+0x28)) "$ISO" 4)-$f))
233 [ $l -eq 0 ] && break
234 printf " $i:%08X %08X %s\n" $f $(($l+1)) \
235 "$(od -An -N 36 -w -j $(($o+0x38)) -t a "$ISO" \
236 | sed 's/\( nul\)*//g;s/ //g;s/ sp//')"
237 o=$(($o+$s))
238 i=$(($i+1))
239 done
240 fi
241 fi
242 o=2048
243 if [ $(get $o "$ISO") -eq 19792 ]; then
244 echo "Apple partitions :"
245 i=0
246 while [ $(get $o "$ISO") -eq 19792 ]; do
247 f=$((0x$(od -An -N 4 -j $(($o+8)) -t x1 "$ISO" | sed 's/ //g')))
248 l=$((0x$(od -An -N 4 -j $(($o+0x54)) -t x1 "$ISO" | sed 's/ //g')))
249 printf " $i:%08X %08X %s\n" $f $l \
250 "$(ddq bs=1 skip=$(($o+16)) count=32 if="$ISO")"
251 o=$(($o+2048))
252 i=$(($i+1))
253 done
254 fi
255 }
257 extract()
258 {
259 for f in $@; do
260 fileofs $f
261 [ $SIZE -eq 0 ] ||
262 ddq bs=1 count=$SIZE skip=$OFFSET if="$ISO" >$f
263 done
264 }
266 custom_config_sector()
267 {
268 get 32848 "$1" 4
269 }
271 clear_custom_config()
272 {
273 start=$(custom_config_sector $1)
274 cnt=$((512 - ($start % 512)))
275 [ $cnt -ne 512 ] &&
276 ddq if=/dev/zero of=$1 bs=2k seek=$start count=$cnt
277 }
278 case "$1" in
279 --build)
280 shift
281 ls -l $@
282 cat >> $0 <<EOM
283 $(tar cf - $@ | compress | uuencode -m -)
284 EOT
285 EOM
286 sed -i '/^case/,/^esac/d' $0
287 exit ;;
288 --get)
289 cat $2
290 exit ;;
291 --array)
292 DATA=/tmp/dataiso$$
293 ddq if=/dev/zero bs=32k count=1 of=$DATA
294 add_win32exe $DATA $2 > /dev/null
295 HSZ=$OFS
296 add_dosexe $DATA > /dev/null
297 add_rootfs $DATA > /dev/null
298 add_doscom $DATA > /dev/null
299 add_fdbootstrap $DATA > /dev/null
300 name=${3:-bootiso}
301 BOOTISOSZ=$((0x8000 - $OFS + $HSZ))
302 cat <<EOT
304 #define $(echo $name | tr '[a-z]' '[A-Z]')SZ $BOOTISOSZ
306 #ifndef __MSDOS__
307 static char $name[] = {
308 /* head */
309 $(hexdump -v -n $HSZ -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
310 /* tail */
311 $(hexdump -v -s $OFS -e '" " 16/1 "0x%02X, "' -e '" /* %04.4_ax */ \n"' $DATA | sed 's/ 0x ,/ /g')
313 /* These strange constants are defined in RFC 1321 as
314 T[i] = (int)(4294967296.0 * fabs(sin(i))), i=1..64
315 */
316 /* static const uint32_t C_array[64] */
317 EOT
318 while read a b c d; do
319 for i in $a $b $c $d; do
320 echo $i | sed 's/0x\(..\)\(..\)\(..\)\(..\),/0x\4, 0x\3, 0x\2, 0x\1, /'
321 done
322 done <<EOT
323 0xd76aa478, 0xe8c7b756, 0x242070db, 0xc1bdceee,
324 0xf57c0faf, 0x4787c62a, 0xa8304613, 0xfd469501,
325 0x698098d8, 0x8b44f7af, 0xffff5bb1, 0x895cd7be,
326 0x6b901122, 0xfd987193, 0xa679438e, 0x49b40821,
327 0xf61e2562, 0xc040b340, 0x265e5a51, 0xe9b6c7aa,
328 0xd62f105d, 0x02441453, 0xd8a1e681, 0xe7d3fbc8,
329 0x21e1cde6, 0xc33707d6, 0xf4d50d87, 0x455a14ed,
330 0xa9e3e905, 0xfcefa3f8, 0x676f02d9, 0x8d2a4c8a,
331 0xfffa3942, 0x8771f681, 0x6d9d6122, 0xfde5380c,
332 0xa4beea44, 0x4bdecfa9, 0xf6bb4b60, 0xbebfbc70,
333 0x289b7ec6, 0xeaa127fa, 0xd4ef3085, 0x04881d05,
334 0xd9d4d039, 0xe6db99e5, 0x1fa27cf8, 0xc4ac5665,
335 0xf4292244, 0x432aff97, 0xab9423a7, 0xfc93a039,
336 0x655b59c3, 0x8f0ccc92, 0xffeff47d, 0x85845dd1,
337 0x6fa87e4f, 0xfe2ce6e0, 0xa3014314, 0x4e0811a1,
338 0xf7537e82, 0xbd3af235, 0x2ad7d2bb, 0xeb86d391,
339 EOT
340 cat <<EOT
341 /* static const char P_array[64] */
342 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, /* 1 */
343 1, 6, 11, 0, 5, 10, 15, 4, 9, 14, 3, 8, 13, 2, 7, 12, /* 2 */
344 5, 8, 11, 14, 1, 4, 7, 10, 13, 0, 3, 6, 9, 12, 15, 2, /* 3 */
345 0, 7, 14, 5, 12, 3, 10, 1, 8, 15, 6, 13, 4, 11, 2, 9, /* 4 */
346 /* static const char S_array[16] */
347 7, 12, 17, 22,
348 5, 9, 14, 20,
349 4, 11, 16, 23,
350 6, 10, 15, 21,
351 EOT
353 for mode in data offset ; do
354 ofs=0
355 while read tag str; do
356 if [ "$mode" == "data" ]; then
357 echo -en "$str\0" | hexdump -v -e '" " 16/1 "0x%02X, "' \
358 -e '" /* %04.4_ax */ \n"' | \
359 sed 's/ 0x ,/ /g'
360 else
361 if [ $ofs -eq 0 ]; then
362 cat <<EOT
363 };
364 #endif
366 #define C_array (uint32_t *) ($name + $(($BOOTISOSZ)))
367 #define P_array (char *) ($name + $(($BOOTISOSZ+(64*4))))
368 #define S_array (char *) ($name + $(($BOOTISOSZ+(64*4)+64)))
369 #define ELTORITOOFS 3
370 EOT
371 fi
372 echo "#define $tag $(($BOOTISOSZ+(64*4)+64+16+$ofs))"
373 ofs=$(($(echo -en "$str\0" | wc -c)+$ofs))
374 fi
375 done <<EOT
376 READSECTORERR Read sector failure.
377 USAGE Usage: isohybrid.exe [--list|--read] [--append cmdline] [--initrd file] file.iso [--forced|--undo|--quick|filename...]
378 OPENERR Can't open the iso file.
379 ELTORITOERR No EL TORITO SPECIFICATION signature.
380 CATALOGERR Invalid boot catalog.
381 HYBRIDERR No isolinux.bin hybrid signature.
382 SUCCESSMSG Now you can create a USB key with your .iso file.\\\\nSimply rename it to an .exe file and run it.
383 FORCEMSG You can add --forced to proceed anyway.
384 MD5MSG Computing md5sum...
385 UNINSTALLMSG Uninstall done.
386 OPENINITRDERR Can't open the initrd file.
387 ALREADYEXEERR Already an EXE file.
388 WIN32_EXE win32.exe
389 SYSLINUX_MBR syslinux.mbr
390 FLAVOR_INFO flavor.info
391 FLOPPY_BOOT floppy.boot
392 TAZBOOT_COM tazboot.com
393 ROOTFS_GZ rootfs.gz
394 DOSSTUB dosstub
395 BOOT_MD5 boot.md5
396 FS_ISO fs.iso
397 CUSTOM_MAGIC custom.magic
398 CUSTOM_APPEND custom.append
399 CUSTOM_INITRD custom.initrd
400 CUSTOM_HEADER #!boot 00000000000000000000000000000000\\\\n
401 FREE_FORMAT %ld free bytes in %04lX..%04lX\\\\n
402 USED_FORMAT %s at %04lX (%ld bytes).\\\\n
403 CMDLINE_TAG append=
404 INITRD_TAG initrd:
405 EOT
406 done
407 cat <<EOT
408 #ifdef __MSDOS__
409 #define BOOTISOFULLSIZE $(($BOOTISOSZ+(64*4)+64+16+$ofs))
410 static char bootiso[BOOTISOFULLSIZE];
411 static data_fixup(void)
412 {
413 #asm
414 push ds
415 push ds
416 pop es
417 mov ax,ds
418 sub ax,#0x1000
419 mov ds,ax
420 xor si,si
421 scanlp:
422 dec si
423 jz copydone
424 cmp byte ptr [si+2],#0xEB
425 jne scanlp
426 cmp word ptr [si],#0x5A4D
427 jne scanlp
428 mov cx,#BOOTISOFULLSIZE
429 mov di,#_bootiso
430 cld
431 rep
432 movsb
433 copydone:
434 pop ds
435 #endasm
436 if (!bootiso[0]) {
437 puts("No bootiso data");
438 exit(-1);
439 }
440 }
441 #else
442 #define data_fixup()
443 #endif
444 EOT
445 rm -rf $DATA
446 exit ;;
447 --exe)
448 # --exe mvcom.bin x.com y.exe > xy.exe
449 cat $4 $3 > /tmp/exe$$
450 S=$(stat -c %s /tmp/exe$$)
451 store 2 $(($S%512)) /tmp/exe$$
452 store 4 $((($S+511)/512)) /tmp/exe$$
453 store 14 -16 /tmp/exe$$
454 store 16 -2 /tmp/exe$$
455 store 20 256 /tmp/exe$$
456 store 22 -16 /tmp/exe$$
457 ddq if=$2 bs=1 seek=64 of=/tmp/exe$$ conv=notrunc
458 store 65 $(stat -c %s $3) /tmp/exe$$
459 store 68 $((0x100-0x40+$(stat -c %s $4))) /tmp/exe$$
460 cat /tmp/exe$$
461 rm -f /tmp/exe$$
462 exit ;;
463 esac
465 main()
466 {
467 [ $(id -u) -ne 0 ] && cmd="$0 $@" && exec su -c "$cmd" < /dev/tty
468 append=
469 initrd=
471 while [ "$1" ]; do
472 case "${1/--/-}" in
473 -get) shift
474 uudecode | unlzma | tar xOf - $@
475 exit ;;
476 -a*) append="$2" ; shift 2 ;;
477 -i*) initrd="$2" ; shift 2 ;;
478 -r*|-l*)
479 ISO="$2" ; shift 2
480 [ -z "$1" ] && list || extract $@
481 exit ;;
482 *) cat > /dev/null
483 break
484 esac
485 done
487 [ ! -s "$1" ] && cat 1>&2 <<EOT && exit 1
488 usage: $0 [--list|--read] [--append custom_cmdline ] [ --initrd custom_initrd ] image.iso [--force|--undo|"DOS help message"|filename...]
489 EOT
490 case "${2/--/-}" in
491 -u*|-r*|-w*|-f*)
492 case "$(get 0 $1)" in
493 23117)
494 b=$(get 417 $1 1)
495 n=$(($(get 64 $1) + 0xC0 - ($(get 26 $1 1)*512) - ($b+1)*512))
496 ddq if=$1 bs=512 count=1 skip=$b of=$1 conv=notrunc
497 if [ $(get 512 $1) -eq 17989 ]; then
498 n=$(($(get 0x25C $1)/512))
499 ddq if=$1 bs=512 seek=44 count=20 skip=$n of=$1 conv=notrunc
500 ddq if=/dev/zero bs=512 seek=9 count=35 of=$1 conv=notrunc
501 ddq if=/dev/zero bs=512 seek=3 count=1 of=$1 conv=notrunc
502 else
503 ddq if=/dev/zero bs=512 seek=1 count=1 of=$1 conv=notrunc
504 ddq if=$1 bs=512 seek=2 count=30 skip=$(($b+1)) of=$1 conv=notrunc
505 ddq if=/dev/zero bs=1 seek=$n count=$((0x8000 - $n)) of=$1 conv=notrunc
506 fi ;;
507 *) ddq if=/dev/zero bs=1k count=32 of=$1 conv=notrunc ;;
508 esac
509 case "${2/--/-}" in
510 -f*)
511 [ "$append$initrd" ] && clear_custom_config $1
512 set -- "$1" "$3" ;;
513 *)
514 clear_custom_config $1
515 exit 0 ;;
516 esac
517 esac
518 case "$(get 0 $1)" in
519 23117) echo "The file $1 is already an EXE file." 1>&2 && exit 1;;
520 0) [ -x /usr/bin/isohybrid ] && isohybrid $1;;
521 esac
523 gpt= ; [ $(get 466 $1) -eq 65263 ] && gpt=1
524 mac= ; [ $(get 2048 $1) -eq 19792 ] && mac=1
525 echo "Read hybrid & tazlito data..."
526 if [ -n "gpt" ]; then
527 echo "GUID Partition Table..."
528 n=3; [ -n "mac" ] && n=9 && echo "Apple Partition Table..."
529 ddq if=$1 bs=512 count=$n of=/tmp/hybrid$$
530 ddq if=$1 bs=512 skip=44 count=20 of=/tmp/tazlito$$
531 else
532 ddq if=$1 bs=512 count=1 of=/tmp/hybrid$$
533 ddq if=$1 bs=512 skip=2 count=20 of=/tmp/tazlito$$
534 fi
535 add_win32exe $1 /tmp/hybrid$$
536 add_tazlito_info $1 /tmp/tazlito$$
537 rm -f /tmp/tazlito$$ /tmp/hybrid$$
539 # keep the largest room for the tazlito info file
540 add_dosexe $1
541 add_rootfs $1
542 add_doscom $1
543 add_fdbootstrap $1
544 printf "%d free bytes in %04X..%04X\n" $(($OFS-$HOLE)) $HOLE $OFS
545 store 440 $(date +%s) $1 32
546 [ "$2" ] && echo "$2 " | \
547 ddq bs=1 seek=$((0x7FDE)) count=15 conv=notrunc of=$1
548 if [ $(stat -c %s $1) -gt 34816 ]; then
549 echo "Adding ISO image md5 at 7FF0 (16 bytes) ..."
550 echo -en "$(ddq if=$1 bs=2k skip=16 count=$(($(get 32848 "$1" 4)-16)) | \
551 md5sum | cut -c-32 | sed 's/\(..\)/\\x\1/g')" | \
552 ddq bs=16 seek=2047 conv=notrunc of=$1
553 fi
554 if [ "$append$initrd" ]; then
555 echo -n "Adding custom config... "
556 DATA=/tmp/$(basename $0)$$
557 rm -f $DATA > /dev/null
558 isosz=$(stat -c %s $1)
559 [ "$append" ] && echo "append=$append" >> $DATA
560 [ -s "$initrd" ] && echo "initrd:$(stat -c %s $initrd)" >> $DATA &&
561 cat $initrd >> $DATA
562 echo "#!boot $(md5sum $DATA | sed 's/ .*//')" | cat - $DATA | \
563 ddq bs=2k seek=$(custom_config_sector $1) of=$1 conv=notrunc
564 newsz=$(stat -c %s $1)
565 for i in 0 1 2 3 ; do
566 [ $(get $((0x1BE+16*i)) $1 4) == $((0x00010080)) ] || continue
567 mb=$(((($newsz -1)/1024/1024)+1))
568 h=$((512*$(get 417 "$1" 1)))
569 store $((0x1C5+16*i)) $(($mb-1)) $1 8
570 store $(($h+0x1C5+16*i)) $(($mb-1)) $1 8
571 store $((0x1CA+16*i)) $(($mb*2048)) $1 32
572 store $(($h+0x1CA+16*i)) $(($mb*2048)) $1 32
573 done
574 if [ $newsz -gt $isosz ]; then
575 echo "$(($newsz - $isosz)) extra bytes."
576 else
577 echo "$(($isosz - 2048*$(get 32848 $1 4)
578 - $(stat -c %s $DATA) - 24)) bytes free."
579 fi
580 rm -f $DATA > /dev/null
581 fi
582 echo -n "Adding boot checksum..."
583 if [ $(stat -c %s $1) -gt 32768 ]; then
584 n=$(($(get 2 $1) - 1 + ($(get 4 $1) - 1)*512))
585 n=$(($(od -v -N $n -t u2 -w2 -An $1 | \
586 awk '{ i+= $0 } END { print (i % 65536) }') \
587 + $(get $(($n+1)) $1 1)))
588 store 18 $(( (-$n -1) % 65536 )) $1
589 fi
590 echo " done."
591 }
593 main "$@" <<EOT