# GRUB is free software: you can redistribute it and/or modify
# GRUB is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# GRUB is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with GRUB.  If not, see <http://www.gnu.org/licenses/>.

function esc {
	if [ -n "$2" ]; then
		echo -e "\n${2}"
	fi
	if [ "$1" == "1" ]; then
		echo -e -n "\n${escreturnmsg}"
	elif [ "$1" == "2" ]; then
		echo -e -n "\n${esccontinuemsg}"
	fi
	sleep -i -v 999999
}

function escctrl {
	if keystatus --ctrl; then
		configfile ${prefix}/Main.cfg
	fi
}

function helpmenu {
	set pager=1
	if test -e $prefix/locale/${lang}_${1}.cfg; then cat --dos $prefix/locale/${lang}_${1}.cfg;
	else cat --dos $prefix/locale/en_${1}.cfg; fi
	esc 1
	set pager=0
}

if [ -n "$pc" ]; then
	source ${prefix}/AliasCmds.cfg
fi

function strcontains {
	set str="$1"
	set pattern="$2"
	if regexp ".*${pattern}.*" "$str"; then
		return 0;
	else
		return 1;
	fi
}

function GetDiskPartNum {
	regexp -s 1:disknum -s 2:partnum "hd([0-9]+),${scheme}([0-9]+)" "$root"
}

function Grub4dosRoot {
	GetDiskPartNum
	set g4dpartnum="${partnum}"
	decrement g4dpartnum
	set g4droot="(hd${disknum},${g4dpartnum})"
}

function WinLegacy {
	if [ x$scheme = xmsdos ] -o [ -n "$cd" ]; then
		ntldr /AIO/Tools/MS/bootmgr
	else
		configfile /AIO/Menu/WinLegacy.cfg
	fi
}
function WinUEFI {
	if [ -n "$cd" ]; then
		chainloader /EFI/CLOVER/tools/Shell64.efi
	else
		chainloader /EFI/BOOT/WinPE_${_SPEC_UEFI_ARCH}.efi
	fi
}

function booting {
	echo -e "${loadingiso} ${1}"
}

function beforeins {
	echo
	echo -e "${beforeins}"
	echo
	ls -l
	echo "${escctrll}"
	esc 2
	escctrl
}

function freebsd_ufs_variants {
	
	menuentry "FreeBSD ($2 - $1) (Default boot loader)" $1 --hotkey=1 {
	    set root="$2"
	    kfreebsd /boot/loader
	}
	
	if test -e ($1)/boot/kernel/kernel; then set kernel="/boot/kernel/kernel"; elif
	test -e ($1)/boot/kernel/kernel.gz; then set kernel="/boot/kernel/kernel.gz"; fi
	if [ -n "$kernel" ]; then
		menuentry "FreeBSD ($2 - $1)" $1 $3 $kernel --hotkey=2 {
			set root="$2"
			kfreebsd $4
			set kFreeBSD.acpi_load=YES
			set kFreeBSD.hint.acpi.0.disabled=0
			set kFreeBSD.vfs.root.mountfrom=ufs:ufsid/$3
			kfreebsd_loadenv /boot/device.hints
		}

		menuentry "FreeBSD ($2 - $1) (single)" $1 $3 $kernel --hotkey=3 {
			set root="$2"
			kfreebsd $4 -s
			set kFreeBSD.acpi_load=YES
			set kFreeBSD.hint.acpi.0.disabled=0
			set kFreeBSD.vfs.root.mountfrom=ufs:ufsid/$3
			kfreebsd_loadenv /boot/device.hints
		}

		menuentry "FreeBSD ($2 - $1) (verbose)" $1 $3 $kernel --hotkey=4 {
			set root="$2"
			kfreebsd $4 -v
			set kFreeBSD.acpi_load=YES
			set kFreeBSD.hint.acpi.0.disabled=0
			set kFreeBSD.vfs.root.mountfrom=ufs:ufsid/$3
			kfreebsd_loadenv /boot/device.hints
		}

		menuentry "FreeBSD ($2 - $1) (no ACPI)" $1 $3 $kernel --hotkey=5 {
			set root="$2"
			kfreebsd $4 -v
			unset kFreeBSD.acpi_load
			set kFreeBSD.hint.acpi.0.disabled=1
			set kFreeBSD.loader.acpi_disabled_by_user=1
			set kFreeBSD.vfs.root.mountfrom=ufs:ufsid/$3
			kfreebsd_loadenv /boot/device.hints
		}

		menuentry "FreeBSD ($2 - $1) (safe mode)" $1 $3 $kernel --hotkey=6 {
			set root="$2"
			kfreebsd $4 -v
			unset kFreeBSD.acpi_load
			set kFreeBSD.hint.acpi.0.disabled=1
			set kFreeBSD.loader.acpi_disabled_by_user=1
			set kFreeBSD.hint.apic.0.disabled=1
			set kFreeBSD.hw.ata.ata_dma=0
			set kFreeBSD.hw.ata.atapi_dma=0
			set kFreeBSD.hw.ata.wc=0
			set kFreeBSD.hw.eisa_slots=0
			set kFreeBSD.hint.kbdmux.0.disabled=1
			set kFreeBSD.vfs.root.mountfrom=ufs:ufsid/$3
			kfreebsd_loadenv /boot/device.hints
		}
		unset kernel
	else
		set timeout=0
	fi
}

function freebsd_zfs_variants {
	
	menuentry "FreeBSD (zfs - $1) (Default boot loader)" $1 --hotkey=1 {
	    set root="$2"
	    kfreebsd /@/boot/loader
	}
	
	if test -e ($1)/@/boot/kernel/kernel; then set kernel="/@/boot/kernel/kernel"; elif
	test -e ($1)/@/boot/kernel/kernel.gz; then set kernel="/@/boot/kernel/kernel.gz"; fi
	if [ -n "$kernel" ]; then
		menuentry "FreeBSD (zfs - $1)" $1 $kernel --hotkey=2 {
			set root="$2"
			kfreebsd $3
			set kFreeBSD.acpi_load=YES
			set kFreeBSD.hint.acpi.0.disabled=0
			kfreebsd_module_elf /@/boot/kernel/opensolaris.ko
			kfreebsd_module_elf /@/boot/kernel/zfs.ko
			kfreebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
			probe -l -s name $root
			set kFreeBSD.vfs.root.mountfrom=zfs:$name
			kfreebsd_loadenv /@/boot/device.hints
		}

		menuentry "FreeBSD (zfs - $1) (single)" $1 $kernel --hotkey=3 {
			set root="$2"
			kfreebsd $3 -s
			set kFreeBSD.acpi_load=YES
			set kFreeBSD.hint.acpi.0.disabled=0
			kfreebsd_module_elf /@/boot/kernel/opensolaris.ko
			kfreebsd_module_elf /@/boot/kernel/zfs.ko
			kfreebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
			probe -l -s name $root
			set kFreeBSD.vfs.root.mountfrom=zfs:$name
			kfreebsd_loadenv /@/boot/device.hints
		}

		menuentry "FreeBSD (zfs - $1) (verbose)" $1 $kernel --hotkey=4 {
			set root="$2"
			kfreebsd $3 -v
			set kFreeBSD.acpi_load=YES
			set kFreeBSD.hint.acpi.0.disabled=0
			kfreebsd_module_elf /@/boot/kernel/opensolaris.ko
			kfreebsd_module_elf /@/boot/kernel/zfs.ko
			kfreebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
			probe -l -s name $root
			set kFreeBSD.vfs.root.mountfrom=zfs:$name
			kfreebsd_loadenv /@/boot/device.hints
		}

		menuentry "FreeBSD (zfs - $1) (no ACPI)" $1 $kernel --hotkey=5 {
			set root="$2"
			kfreebsd $3 -v
			unset kFreeBSD.acpi_load
			set kFreeBSD.hint.acpi.0.disabled=1
			set kFreeBSD.loader.acpi_disabled_by_user=1
			kfreebsd_module_elf /@/boot/kernel/opensolaris.ko
			kfreebsd_module_elf /@/boot/kernel/zfs.ko
			kfreebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
			probe -l -s name $root
			set kFreeBSD.vfs.root.mountfrom=zfs:$name
			kfreebsd_loadenv /@/boot/device.hints
		}

		menuentry "FreeBSD (zfs - $1) (safe mode)" $1 $kernel --hotkey=6 {
			set root="$2"
			kfreebsd $3 -v
			unset kFreeBSD.acpi_load
			set kFreeBSD.hint.acpi.0.disabled=1
			set kFreeBSD.loader.acpi_disabled_by_user=1
			set kFreeBSD.hint.apic.0.disabled=1
			set kFreeBSD.hw.ata.ata_dma=0
			set kFreeBSD.hw.ata.atapi_dma=0
			set kFreeBSD.hw.ata.wc=0
			set kFreeBSD.hw.eisa_slots=0
			set kFreeBSD.hint.kbdmux.0.disabled=1
			kfreebsd_module_elf /@/boot/kernel/opensolaris.ko
			kfreebsd_module_elf /@/boot/kernel/zfs.ko
			kfreebsd_module /@/boot/zfs/zpool.cache type=/boot/zfs/zpool.cache
			probe -l -s name $root
			set kFreeBSD.vfs.root.mountfrom=zfs:$name
			kfreebsd_loadenv /@/boot/device.hints
		}
		unset kernel
	else
		set timeout=0
	fi
}

function drivemap_hd0_to_hdn {
	GetDiskPartNum
	if [ "${disknum}" == "0" ]; then
		set _disk="(hd0)"
		for _next_disk in (hd*); do
			if regexp '^\(hd([0-9]+)\)$' "$_next_disk"; then
				if [ "x${_disk}" != "x${_next_disk}" ]; then
					drivemap -s ${_next_disk} ${_disk}
					set _disk="${_next_disk}"
				fi
			fi
		done
		if [ "(hd0)" != "${_disk}" ] -a [ "(hd1)" != "${_disk}" ]; then
			drivemap (hd0) ${_disk}
		fi
		regexp -s disk_n '^\(hd(.*)\)$' "$_disk"
		unset _disk
		unset _next_disk
	else
		set disk_n="${disknum}"
	fi
}

function GetConfigFile {
	export enable_progress_indicator=1
	for file in "/boot/grub/grub.cfg" "/efi/boot/grub.cfg" "/grub/grub.cfg"; do
		if test -e ($1)$file; then
			set hotkey="_"
			GetHotkey
			menuentry "Load ${file} ${on} (${1}) - ${2} - ${3} - ${4}" "$1" "$file" --hotkey="${hotkey}" {
				if [ -e (${2})/boot/grub/themes ] -o [ -e (${2})/boot/grub/fonts ] -o [ -e (${2})/boot/grub/locale ]	\
					 -o \
					[ -e (${2})/boot/grub/i386-efi ] -o [ -e (${2})/boot/grub/x86_64-efi ]; then
						set root=${2}
						set prefix="(${2})/boot/grub"
				fi
				configfile $3
			}
		fi
	done
	export enable_progress_indicator=0
}

function ntbootcmd {
	set _file="$1"
	if [ -n "$2" ]; then
		set _file_ext="$2"
	else
		regexp -s _file_ext '\.([^!/.]+)$' "$_file"
	fi
	if [ "$_file_ext" == "wim" ]; then
		set _args="--testmode=no --wim"
	else
		set _args="--vhd"
	fi
	if [ -n "$pc" ]; then
		set lang=en_US
		terminal_output console
		ntboot ${_args} --efi=/AIO/Tools/MS/PXE/bootmgr "${_file}"
	else
		if [ "$_file_ext" == "wim" ]; then
			if wimtools --is64 "${_file}"; then set wimarch="64"; else set wimarch="32"; fi
			if [ "$_SPEC_UEFI_ARCH_3" != "$wimarch" ]; then
				esc 1 "$efi3264msg"
				return 1
			fi
		fi
		set lang=en_US
		terminal_output console
		ntboot ${_args} --efi=/AIO/Tools/MS/PXE/x${_SPEC_UEFI_ARCH_2}/bootmgfw.efi "${_file}"
	fi
}

function wimbootwinsetup {
	echo "${loading} ${1}... ${plswait}".
	if wimtools --is64 "${1}"; then
		set wimarch="64"
		set procarch="AMD64"
	else
		set wimarch="32"
		set procarch="x86"
	fi
	if [ "$pc" ]; then
		drivemap_hd0_to_hdn
		set lang=en_US
		terminal_output console
		wimboot --highest=no --testmode=no	\
			@:bootmgr:/AIO/Tools/MS/PXE/bootmgr					\
			@:bootmgr.exe:/AIO/Tools/MS/PXE/bootmgr.exe			\
			@:Lmsify${procarch}.exe:/AIO/Tools/winsetup/Lmsify${wimarch}.exe	\
			@:grubenv:/AIO/grub/grubenv	\
			@:Winpeshl.ini:/AIO/Tools/winsetup/Winpeshl.ini		\
			@:boot.wim:"${1}"
	else
		if [ "$_SPEC_UEFI_ARCH_3" != "$wimarch" ]; then
			esc 1 "$efi3264msg"
			return 1
		fi
		set lang=en_US
		terminal_output console
		wimboot --highest=no --testmode=no	\
				@:bootmgfw.efi:/AIO/Tools/MS/PXE/x${_SPEC_UEFI_ARCH_2}/bootmgfw.efi \
				@:Lmsify${procarch}.exe:/AIO/Tools/winsetup/Lmsify${wimarch}.exe	\
				@:grubenv:/AIO/grub/grubenv	\
				@:Winpeshl.ini:/AIO/Tools/winsetup/Winpeshl.ini	\
				@:boot.wim:"${1}";
	fi
	boot;
}

function ListWimBoot {
	echo "${wimmsg}"
	for file in /AIO/Files/WinPE/*.wim /AIO/Files/WinPE/*.WIM /AIO/Files/WinPE/*/*.wim /AIO/Files/WinPE/*/*.WIM; do
		if ! test -f "$file"; then continue; fi
		regexp -s filename "/AIO/Files/WinPE/(.*)" "$file"
		if [ -z "$havefile" ]; then set havefile="1"; fi
		set hotkey="_"
		GetHotkey
		menuentry "${filename}" "$filename" --hotkey="${hotkey}" {
			wimboot "/AIO/Files/WinPE/${2}"
		}
	done
	if [ -z "$havefile" ]; then
		esc 2 "${nowim}"
	else
		unset havefile
		ReturnMainMenu;
	fi
	unset filename
}

function WindowsDetect {
    set saved_root=$root
	for dev in (hd*,*); do
		regexp -s device '\((.*)\)' $dev
		probe -s fstype -f $device
		if [ -z "$fstype" ] -o [ "$fstype" == "procfs" ]; then continue; fi
		probe -s tscheme -p $device
		if [ -n "$pc" ] -a [ "$tscheme" == "msdos" ]; then
			if test \
				   '(' -f ($device)/bootmgr -a -f ($device)/boot/bcd ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/boot/Bcd ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/boot/BCD ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/Boot/bcd ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/Boot/Bcd ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/Boot/BCD ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/BOOT/bcd ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/BOOT/Bcd ')' \
				   -o \
				   '(' -f ($device)/bootmgr -a -f ($device)/BOOT/BCD ')' \
				; then
				set root="$device"
				ntldr /bootmgr
				boot
			elif test \
				   '(' -f ($device)/ntldr -a -e ($device)/ntdetect.com -a -f ($device)/boot.ini ')' \
				   -o \
				   '(' -f ($device)/ntldr -a -e ($device)/ntdetect.com -a -f ($device)/BOOT.INI ')' \
				   -o \
				   '(' -f ($device)/ntldr -a -e ($device)/NTDETECT.COM -a -f ($device)/boot.ini ')' \
				   -o \
				   '(' -f ($device)/ntldr -a -e ($device)/NTDETECT.COM -a -f ($device)/BOOT.INI ')' \
				   -o \
				   '(' -f ($device)/NTLDR -a -e ($device)/ntdetect.com -a -f ($device)/boot.ini ')' \
				   -o \
				   '(' -f ($device)/NTLDR -a -e ($device)/ntdetect.com -a -f ($device)/BOOT.INI ')' \
				   -o \
				   '(' -f ($device)/NTLDR -a -e ($device)/NTDETECT.COM -a -f ($device)/boot.ini ')' \
				   -o \
				   '(' -f ($device)/NTLDR -a -e ($device)/NTDETECT.COM -a -f ($device)/BOOT.INI ')' \
				; then
				set root="$device"
				#drivemap_to_hd0 "$root"
				ntldr /ntldr
				boot
			fi
		elif [ -n "$efi" ] -a [ "$fstype" == "fat" ] -a [ "$tscheme" == "gpt" ] -a [ -f ($device)/EFI/Microsoft/Boot/bootmgfw.efi ] -a [ -f ($device)/EFI/Microsoft/Boot/BCD ]; then
			root="$device"
			chainloader /EFI/Microsoft/Boot/bootmgfw.efi
			boot
		fi
		unset tscheme
		unset fstype
    done
	set root=$saved_root
	esc 1 "${nowindows}"
}

function GetHotkey {
	if [ "$hotkey" != "." ]; then
		set hotkeys="_0123456789adfghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`=,."
		regexp -s hotkey "${hotkey}(.)" "$hotkeys"
	fi
}

function PartitionImageMapperBack {
	if [ -n "$pim" ]; then
		if ! test -e "${1}"; then
			search -n -s root -f /AIO/aioboot.mbr
			set prefix="(${root})/AIO/grub"
			unset bgloaded
			configfile ${prefix}/grub.cfg
			return 0
		fi
	fi
	return 1
}

function PartitionImageMapper {
	Grub4dosRoot
	hexdump -q -s 510 -n 4 (hd${disknum})1+2 _signature
	if [ "$_signature" != "\x55\xaa\x52\x56" ]; then
		echo -e "${reinstallgrub2msg}"
		esc 1 "${errormsg}: Code 0x0006"
		return 1
	fi
	unset _signature
	
	set file="$1"
	
	PartitionImageMapperBack "$file"
	
	echo "${frag1msg}"
	stat --set=frag_partimg -c -q "/AIO/Files/PartIMG_ROOT.img"
	stat --set=frag_file -c -q "$file"
	
	unset datafile
	set frag_datafile="1"
	if [ -e "${file}.data" ]; then
		set datafile="${file}.data"
		stat --set=frag_datafile -c -q "$datafile"
	fi
	
	if [ "${frag_partimg}" != "1" ] -o [ "${frag_file}" != "1" ] -o [ "${frag_datafile}" != "1" ]; then
		echo "${errormsg}: Code 0x0001"
		echo "${frag2msg}"
		if [ "${frag_partimg}" != "1" ];
		then
			esc 1 "/AIO/Files/PartIMG_ROOT.img (${frag_partimg} fragments)"
		fi
		if [ "${frag_file}" != "1" ];
		then
			esc 1 "${file} (${frag_file} fragments)"
		fi
		if [ "${frag_datafile}" != "1" ];
		then
			esc 1 "${datafile} (${frag_datafile} fragments)"
		fi
		return 1
	fi
	unset frag_file
	unset frag_partimg
	unset frag_datafile
	echo "${donemsg}"
	
	echo "${backupmbrmsg}"
	if ! dd --if=(hd${disknum}) --of=(hd${disknum})1+1 --bs=512 --count=1; then
		esc 1 "${errormsg}: Code 0x0002"
		return 1
	fi
	echo "${donemsg}"
	
	echo "${filefs1msg}"
	loopback fileloop "$file"
	unset _fstype
	unset _filefs
	probe -f -s _filefs fileloop
	
	if [ -z "$_filefs" ]; then 
		for _filepart in (fileloop,*); do
			if ! probe -f -s _filefs $_filepart; then
				continue
			else
				set filepart=${_filepart}
				unset _filepart
				break
			fi
		done
	fi
	
	set maptype="FD"
	if [ "$_filefs" == "iso9660" ] -o [ "$_filefs" == "udf" ]; then
		if [ -e (fileloop)/netbsd ] -o [ -e ${filepart}/netbsd ]; then
			set _fstype=0xA9
		elif [ -e (fileloop)/*/*/bsd.rd ] -o [ -e ${filepart}/*/*/bsd.rd ]; then
			set _fstype=0xA6
		else
			set _fstype=0xA8
		fi
		set maptype="CD"
	elif [ "$_filefs" == "fat" ]; then
		set _fstype=0x0C
	elif [ "$_filefs" == "ntfs" ] -o [ "$_filefs" == "exfat" ]; then
		set _fstype=0x07
	elif [ "$_filefs" == "ufs1" ] -o [ "$_filefs" == "ufs2" ]; then
		if [ -e ${filepart}/netbsd ] -o [ -e (fileloop)/netbsd ]; then
			set _fstype=0xA9
		elif regexp -s 1:_disk -s 2:_part '^\(([a-z0-9]+)\,([a-z0-9]+)\,dfly' "$filepart"; then
			set filepart="(${_disk},${_part})"
			unset _disk
			unset _part
			set _fstype=0x6C
		else
			set _fstype=0xA5
		fi
	elif [ "$_filefs" == "hfsplus" ] -o [ "$_filefs" == "hfs" ]; then
		set _fstype=0xAF
	elif [ "$_filefs" == "ext2" ]; then
		set _fstype=0x83
	elif [ "$_filefs" == "sfs" ]; then
		set _fstype=0xBF
	elif [ -z "$_filefs" ]; then
		esc 1 "${filefs2msg}"
		return 1
	fi
	
	if [ -n "$datafile" ]; then
		loopback dataloop "$datafile"
		unset _datafs
		probe -f -s _datafs dataloop
		if [ "$_datafs" == "ext2" ]; then
			set _datafs=0x83
		elif [ "$_datafs" == "fat" ]; then
			set _datafs=0x0C
		elif [ "$_datafs" == "ntfs" ] -o [ "$_datafs" == "exfat" ]; then
			set _datafs=0x07
		elif [ "$_datafs" == "ufs1" ] -o [ "$_datafs" == "ufs2" ]; then
			set _datafs=0xA5
		elif [ "$_datafs" == "hfsplus" ] -o [ "$_datafs" == "hfs" ]; then
			set _datafs=0xAF
		elif [ "$_datafs" == "sfs" ]; then
			set _datafs=0xBF
		else
			set _datafs=0x00
		fi
		loopback -d dataloop
	fi
	echo "${donemsg}"

	blocklist --disk --set=fileblocklist "${file}"
	blocklist --disk --set=imgblocklist "/AIO/Files/PartIMG_ROOT.img"

	if [ -n "$filepart" ]; then
		regexp -s 1:fileoffset -s 2:filesectors '(.*)\+(.*)' "$fileblocklist"
		stat -q -s partsectors -z $filepart
		stat -q -s partoffset -o $filepart
		expr -s partsectors $partsectors/512
		expr -s partoffset ${fileoffset}+${partoffset}
		set file=(hd${disknum})${partoffset}+${partsectors}
		set maptype="HD"
	fi
	
	if [ "$_filefs" == "fat" ] -o [ "$_filefs" == "ntfs" ] -o [ "$_filefs" == "exfat" ]; then
		for partfile in 1 2 3 4; do
			if [ "$partnum" != "$partfile" ]; then
				break;
			fi
		done
		for partpartimg in 1 2 3 4; do
			if [ "$partnum" != "$partpartimg" ] -a [ "$partpartimg" != "$partfile" ]; then
				break;
			fi
		done
	else
		for partpartimg in 1 2 3 4; do
			if [ "$partnum" != "$partpartimg" ]; then
				break;
			fi
		done
		for partfile in 1 2 3 4; do
			if [ "$partnum" != "$partfile" ] -a [ "$partpartimg" != "$partfile" ]; then
				break;
			fi
		done
	fi
	if [ -n "$datafile" ]; then
		for partdata in 1 2 3 4; do
			if [ "$partnum" != "$partdata" ] -a [ "$partpartimg" != "$partdata" ] -a [ "$partfile" != "$partdata" ]; then
				break;
			fi
		done
	fi
	 
	echo "${file} --> hd${disknum},${scheme}${partfile}"
	if ! partnew --type=${_fstype} --active --file="${file}" hd${disknum} ${partfile}; then
		esc 1 "${errormsg}: Code 0x0003"
		return 1
	fi
	echo "${donemsg}"
	if [ -e (hd${disknum},${scheme}${partfile})/AIO/aioboot_img.mbr ]; then
		dd --if=(hd${disknum})1+1 --of=(hd${disknum},${scheme}${partfile})/AIO/aioboot_img.mbr --bs=512 --count=1
	fi
	
	echo "/AIO/Files/PartIMG_ROOT.img --> hd${disknum},${scheme}${partpartimg}"
	if ! partnew --type=0xEF --file="/AIO/Files/PartIMG_ROOT.img" hd${disknum} ${partpartimg}; then
		esc 1 "${errormsg}: Code 0x0004"
		return 1
	fi
	echo "${donemsg}"
	if [ -e (hd${disknum},${scheme}${partpartimg})/AIO/aioboot.mbr ]; then
		dd --if=(hd${disknum})1+1 --of=(hd${disknum},${scheme}${partpartimg})/AIO/aioboot.mbr --bs=512 --count=1
	fi
	
	if [ -n "$datafile" ]; then
		echo "${datafile} --> hd${disknum},${scheme}${partdata}"
		if ! partnew --type=${_datafs} --file="${datafile}" hd${disknum} ${partdata}; then
			esc 1 "${errormsg}: Code 0x0005"
			return 1
		fi
		echo "${donemsg}"
	fi
	
	if [ -e "${file}.cfg" ] -o [ -n "$datafile" ]; then
		mount (hd${disknum},${scheme}${partpartimg}) 9
		if [ -e (hd${disknum},${scheme}${partpartimg})/grub2cfg.cfg ]; then
			rm "9:/grub2cfg.cfg"
		fi
		if [ -e "${file}.cfg" ]; then
			cp "${file}.cfg" "9:/grub2cfg.cfg"
		elif [ -n "$datafile" ]; then
			if [ -e (fileloop)/boot/grub/grub.cfg ]; then
				cat -s cfgtext (fileloop)/boot/grub/grub.cfg
				if StringReplace "${cfgtext}" "boot=casper" "persistent boot=casper"; then
					touch "9:/grub2cfg.cfg"
					write_file "9:/grub2cfg.cfg" "$NewString"
				elif StringReplace "${cfgtext}" "file=/cdrom/" "persistent file=/cdrom/"; then
					touch "9:/grub2cfg.cfg"
					write_file "9:/grub2cfg.cfg" "$NewString"
				elif StringReplace "${cfgtext}" "boot=live" "boot=live persistence"; then
					touch "9:/grub2cfg.cfg"
					write_file "9:/grub2cfg.cfg" "$NewString"
				fi
				unset NewString
				unset cfgtext
			fi
		fi
		umount 9
		if [ -e (hd${disknum},${scheme}${partpartimg})/grub2cfg.cfg ]; then
			parttool hd${disknum},${scheme}${partnum} type=0x00
			map (hd${disknum})${fileblocklist} -t ${maptype} vd0
			set root=vd0
			set prefix="/boot/grub"
			configfile "(hd${disknum},${scheme}${partpartimg})/grub2cfg.cfg"
			return 0
		fi
	fi
	loopback -d fileloop
	
	parttool hd${disknum},${scheme}${partnum} type=0x00
	if [ -n "$efi" ]; then
		map -x vd0
		if [ "$_filefs" == "ntfs" ]; then
			efiload (hd${disknum},${scheme}${partpartimg})/efi/drivers/ntfs_${_SPEC_UEFI_ARCH}.efi
		fi
		if map (hd${disknum})${fileblocklist} -t ${maptype} vd0; then
			if [ -n "$filepart" ]; then
				regexp -s _part '\(fileloop(.*)\)' "$filepart"
				unset filepart
				set root=vd0${_part}
			else
				set root=vd0
			fi
			
			if [ -e /efi/microsoft/boot/bcd ]; then
				for _grub_path in /*/*/grub.cfg; do
					regexp -s _grub_path '^(.*)\/grub\.cfg$' "$_grub_path"
					set prefix=${_grub_path}
					configfile ${_grub_path}/grub.cfg
					return 0
				done
			fi
			if [ -e /FreeNAS ]; then
				for _efifile in (vd0,*)/efi/boot/bootx64.efi; do
					if chainloader -b $_efifile; then
						return 0
					fi
				done
			fi
			if [ -e /boot/loader.efi ]; then
				if chainloader -b /boot/loader.efi; then
					return 0
				fi
			fi
			if [ -e /boot/boot1.efi ]; then
				if chainloader -b /boot/boot1.efi; then
					return 0
				fi
			fi
			boot
		else
			if [ -n "$filepart" ]; then
				regexp -s _part '\(fileloop(.*)\)' "$filepart"
				unset filepart
				set root=vd0${_part}
			else
				set root=vd0
			fi
			
			if [ -e /efi/boot/boot${_SPEC_UEFI_ARCH}.efi ]; then
				chainloader -b /efi/boot/boot${_SPEC_UEFI_ARCH}.efi
			fi
			if [ -e /efi/boot/grub${_SPEC_UEFI_ARCH}.efi ]; then
				chainloader -b /efi/boot/grub${_SPEC_UEFI_ARCH}.efi
			fi
			
			if [ -e /boot/grub/grub.cfg ]; then
				configfile /boot/grub/grub.cfg
			elif [ -e /efi/boot/grub.cfg ]; then
				configfile /efi/boot/grub.cfg
			elif [ -e /isolinux/isolinux.cfg ]; then
				syslinux_configfile -i /isolinux/isolinux.cfg
			elif [ -e /syslinux/syslinux.cfg ]; then
				syslinux_configfile -s /syslinux/syslinux.cfg
			elif [ -e /boot/isolinux/isolinux.cfg ]; then
				syslinux_configfile -i /boot/isolinux/isolinux.cfg
			elif [ -e /boot/syslinux/syslinux.cfg ]; then
				syslinux_configfile -s /boot/syslinux/syslinux.cfg
			else
				esc 1 "${nobootablemsg}"
				PartitionImageMapperBack "${file}"
			fi
		fi
	else
		if test -n "$partoffset" -a -e (hd${disknum},${scheme}${partfile})/bootmgr; then
			set fileblocklist=${partoffset}+${partsectors}
			set maptype="FD"
			unset partoffset
			unset partsectors
		fi
		loopback imgloop (hd${disknum})${imgblocklist}
		set opt="map (hd${disknum})${imgblocklist} (fd1) || map --mem (hd${disknum})${imgblocklist} (fd1);map --hook;(fd1)/AIO/MAP (hd${disknum})${fileblocklist} ${maptype}"
		linux16	(imgloop)/AIO/grub.exe --config-file=${opt}
	fi
	return 0
}

function FileProcessing {
	file="$1"
	filename="$2"
	file_ext="$3"
	
	regexp -s 1:loopdev -s 2:path '\((.*)\)(.*)' "$file"
	
	if [ "$file_ext" == "iso" ]; then
		loopback isoloop "$file"
		if [ -e "(isoloop)/sources/install.wim" ] -o [ -e "(isoloop)/sources/install.esd" ]; then
			set winiso="$path"
			save_env winiso
			wimbootwinsetup "(isoloop)/sources/boot.wim"
			return 0
		elif [ -e (isoloop)/x64/sources/install.esd ] -o [ -e (isoloop)/x64/sources/install.wim ] 	\
				-o	\
				[ -e (isoloop)/x86/sources/install.esd ] -o [ -e (isoloop)/x86/sources/install.wim ]; then
						if [ -n "$pc" ]; then
							if [ -e (isoloop)/x64/sources/boot.wim ]; then
								submenu "Windows [64-bit]" "$path" {
									set winiso="$2"
									save_env winiso
									wimbootwinsetup (isoloop)/x64/sources/boot.wim
								}
							else set timeout=0; fi
							if [ -e (isoloop)/x86/sources/boot.wim ]; then
								submenu "Windows [32-bit]" "$path" {
									set winiso="$2"
									save_env winiso
									wimbootwinsetup (isoloop)/x86/sources/boot.wim
								}
							else set timeout=0; fi
						else
							set winiso="$path"
							save_env winiso
							wimbootwinsetup (isoloop)/x${_SPEC_UEFI_ARCH_2}/sources/boot.wim
						fi
						return 0
		elif [ -e (isoloop)/I386/TXTSETUP.SIF ] -o [ -e (isoloop)/AMD64/TXTSETUP.SIF ]; then
			menuentry "${installxp} - ${stepmsg} 1" "$path" {
				drivemap_hd0_to_hdn
				set g4dpartnum="$partnum"
				decrement g4dpartnum
				set g4d_cmd="root (hd${disk_n},${g4dpartnum});/AIO/INSTALLXP cd ${2}";
				linux16		${g4d_path}/grub.exe --config-file=${g4d_cmd};
				initrd16	${g4d_path}/winvblk.img;
				boot
			}
			menuentry "${installxp} - ${stepmsg} 2" "$path" {
				drivemap_hd0_to_hdn
				set g4dpartnum="$partnum"
				decrement g4dpartnum
				set g4d_cmd="root (hd${disk_n},${g4dpartnum});/AIO/INSTALLXP hd ${2}";
				linux16	${g4d_path}/grub.exe --config-file=${g4d_cmd};
				initrd16	${g4d_path}/winvblk.img;
				boot
			}
			return 0
		elif test -e (isoloop)/CdUsb.Y -o -e (isoloop)/Win10PE.cd -o -e (isoloop)/Win8PE.cd; then
			WinBuilderISO "${path}" "${loopdev}"
		fi
		
		for cfg in /boot/grub/loopback.cfg /efi/boot/loopback.cfg /EFI/BOOT/loopback.cfg; do
			if ! test -e (isoloop)$cfg; then continue; fi
			cat -s cfgtext (isoloop)$cfg
			if regexp " /grub/grub.cfg" "$cfgtext"; then
				if ! test -e (isoloop)/grub/grub.cfg; then continue; fi
			fi
			if regexp "/casper/initrd.lz" "$cfgtext"; then
				if ! test -e (isoloop)/casper/initrd.lz; then continue; fi
			fi
			if regexp "source /boot/grub/grub.cfg" "$cfgtext"; then
				cat -s new_cfgtext (isoloop)/boot/grub/grub.cfg
				if ! regexp 'iso_path' "$new_cfgtext"; then continue; fi
			fi
			
			probe -u -s rootuuid $loopdev
			export rootuuid
			set iso_path="$path"
			export iso_path
			set root=isoloop
			configfile $cfg
			
			unset cfgtext
			return 0
		done
			
		set isolinuxroot="(isoloop)/"
		for cfg in /boot/grub/grub.cfg /boot/grub2/grub.cfg /efi/boot/grub.cfg /grub/grub.cfg /grub.cfg /boot/grub/grubsrcd.cfg /boot/grub/grub-511.cfg	\
			/isolinux/isolinux.cfg /syslinux/syslinux.cfg /isolinux/live.cfg /syslinux/live.cfg /boot/isolinux/isolinux.cfg 	\
			/arch/boot/syslinux/archiso_sys.cfg /slax/boot/syslinux.cfg /isolinux/txt.cfg /boot/syslinux/menu/mesamenu.cfg; do
			
			if ! test -e (isoloop)${cfg}; then
				continue
			fi
			cat -s cfgtext (isoloop)${cfg}
			
			unset NewString
			if regexp "iso_path" "$cfgtext"; then
				probe -u -s rootuuid $loopdev
				export rootuuid
				set iso_path="$path"
				export iso_path
				set root=isoloop
				configfile $cfg
			elif StringReplace "${cfgtext}" "boot=casper" "boot=casper iso-scan/filename=${path}"; then
				true
			elif StringReplace "${cfgtext}" "boot=live" "boot=live findiso=${path}"; then
				StringReplace "${NewString}" "live-media=removable" " "
			elif StringReplace "${cfgtext}" "file=/cdrom/preseed" "iso-scan/filename=${path} file=/cdrom/preseed"; then
				true
			elif regexp "source /efi/boot/android.cfg" "$cfgtext"; then
				set NewString="${cfgtext}"
				export isofile="${path}"
			elif StringReplace "${cfgtext}" "androidboot." "iso-scan/filename=${path} androidboot."; then
				true
			elif StringReplace "${cfgtext}" "/kernel root=/dev/ram0" "/kernel root=/dev/ram0 iso-scan/filename=${path}"; then
				if [ ! -e (isoloop)/initrd.img ] -o [ ! -e (isoloop)/system.sfs ]; then
					unset NewString
				fi
			elif StringReplace "${cfgtext}" "/kernel CMDLINE" "/kernel root=/dev/ram0 androidboot.hardware=android_x86 iso-scan/filename=${path}"; then
				true
			elif regexp "archisobasedir=" "$cfgtext"; then
				probe -u -s devuuid ${loopdev}
				StringReplace "${cfgtext}" "archisobasedir=" "img_loop=${path} img_dev=/dev/disk/by-uuid/${devuuid} archisobasedir="
				StringReplace "${NewString}" " boot/" " /arch/boot/"
				StringReplace "${NewString}" ",boot/" ",/arch/boot/"
			elif StringReplace "${cfgtext}" "/antiX/vmlinuz " "/antiX/vmlinuz fromiso=${path} from=usb,cd,hd "; then
				true
			elif StringReplace "${cfgtext}" "/gentoo " "/gentoo isoboot=${path} "; then
				true
			elif regexp 'root=/dev/ram0 real_root=/dev/loop0 loop=' "$cfgtext"; then
				export platform="${grub_cpu}-${grub_platform}"
				StringReplace "${cfgtext}" 'root=/dev/ram0 real_root=/dev/loop0 loop=' "isoboot=${path} root=/dev/ram0 real_root=/dev/loop0 loop="
			elif regexp "rd.live.image" "$cfgtext"; then
				StringReplace "${cfgtext}" "root=live:" "iso-scan/filename=${path} root=live:"
			elif regexp "inst.stage2=hd:" "$cfgtext"; then
				probe -u -s isouuid isoloop
				StringReplace "${cfgtext}" 'inst.stage2=hd:[^! ]*' "iso-scan/filename=${path} inst.stage2=hd:UUID=${isouuid} "
			elif StringReplace "${cfgtext}" "/boot/x86_64/loader/linux" "/boot/x86_64/loader/linux install=hd:${path} "; then
				true
			elif StringReplace "${cfgtext}" "/boot/i686/loader/linux" "/boot/i686/loader/linux install=hd:${path} "; then
				true
			elif regexp "/pmagic/initrd.img /pmagic/fu.img" "$cfgtext"; then
				StringReplace "${cfgtext}" 'set default_settings="' "set default_settings=\"iso_filename=${path} "
			elif StringReplace "${cfgtext}" "/isolinux/rescue64" "/isolinux/rescue64 isoloop=${path}"; then
				true
			elif regexp "printk.time=" "$cfgtext"; then
				if [ -e (isoloop)/slax ]; then
					StringReplace "${cfgtext}" "printk.time=" "from=${path} printk.time="
				else
					probe -u -s devuuid ${loopdev}
					StringReplace "${cfgtext}" "printk.time=" "livemedia=/dev/disk/by-uuid/${devuuid}:${path} printk.time="
				fi
			elif regexp " kbd=" "$cfgtext"; then
				probe -u -s devuuid ${loopdev}
				StringReplace "${cfgtext}" " kbd=" " livemedia=/dev/disk/by-uuid/${devuuid}:${path} kbd="
			elif regexp "tinycore.gz" "$cfgtext"; then
				map_and_boot "${path}" "${loopdev}"
			fi
			
			if [ -n "$NewString" ]; then
				if [ -e (imgloop)/ ]; then
					loopback -d imgloop
				fi
				loopback -l imgloop /AIO/Files/PartIMG_ROOT.img
				mount (imgloop) 9
				if [ -e (imgloop)/grub2cfg.cfg ]; then
					rm "9:/grub2cfg.cfg"
				fi
				touch "9:/grub2cfg.cfg"
				write_file "9:/grub2cfg.cfg" "$NewString"
				
				if regexp "isolinux" "$cfg"; then
					set root=imgloop
					syslinux_source -i -r "${isolinuxroot}" /grub2cfg.cfg
					set root=isoloop
				elif regexp "syslinux" "$cfg"; then
					set root=imgloop
					syslinux_source -s -r "${isolinuxroot}" /grub2cfg.cfg
					set root=isoloop
				else
					set root=isoloop
					if [ -e /boot/grub ]; then
						set prefix="/boot/grub"
					elif [ -e /boot/grub2 ]; then
						set prefix="/boot/grub2"
					else
						regexp -s prefix '(.*)/' "$cfg"
					fi
					configfile (imgloop)/grub2cfg.cfg
				fi
				umount 9
				return 0
			fi
		done
		
		map_and_boot "${path}" "${loopdev}"
		
	elif [ "$file_ext" == "wim" ]; then
		wimbooting "${file}" "$file_ext"
	elif [ "$file_ext" == "vhd" ] -o [ "$file_ext" == "vhdx" ]; then
		if vhdbooting "${path}" "${file}" "${file_ext}" "${loopdev}"; then
			return 0
		fi
	elif [ "$file_ext" == "img" ] -o [ "$file_ext" == "ima" ] -o [ "$file_ext" == "partimg" ]; then
		map_and_boot "${path}" "${loopdev}"
	elif [ "$file_ext" == "ufs" ] -o [ "$file_ext" == "hfs" ] -o [ "$file_ext" == "squashfs" ] -o [ "$file_ext" == "sfs" ] -o [ "$file_ext" == "gz" ]; then
		loopback isoloop "${path}"
		FileManager (isoloop)
		return 0
	elif [ "$file_ext" == "efi" ] -a [ -n "$efi" ]; then
		if file --is-x86_64-efi "$file"; then set filearch="64"; else set filearch="32"; fi
		if [ "$_SPEC_UEFI_ARCH_3" != "$filearch" ]; then
			esc 1 "$efi3264msg"
			return 1
		fi
		chainloader -b "$file"
	elif [ "$filename" == "grub.cfg" ]; then
		if [ -d (${loopdev})/boot/grub ]; then
			set root=${loopdev}
			set prefix=/boot/grub
		fi
		configfile "$file"
	fi
	
	esc 1 "${nobootablemsg}"
	return 1
}

function FileManager {

	if PartitionImageMapperBack "$1"; then return 1; fi
	
	export enable_progress_indicator=1
	
	echo "${gettinglist}"
	set hotkey="_"
	GetHotkey
	submenu "... ${1}" "$1" --hotkey="${hotkey}" {
		regexp -s subdir ".*\/(.*)" "$2"
		if [ "$subdir" ]; then
			unset subdir
			regexp -s parentdir "(.*)\/.*" "$2"
			FileManager "$parentdir"
		else
			if regexp '^\(isoloop\)' "$2"; then
				loopback -d isoloop
			fi
			if [ -z $pim ]; then
				configfile ${prefix}/FileManager.cfg
			else
				if PartitionImageMapperBack "$2"; then return 1; fi
				configfile ${prefix}/Main.cfg
			fi
		fi
	}
	for file in $1/*; do
		regexp -s filename ".*\/(.*)" "$file"
		if test -d "$file"; then
			if [ "$filename" == "System Volume Information" ] -o [ "$filename" == "system volume information" ] -o [ "$filename" == "lost+found" ]	\
			-o [ "$filename" == "\$Extend" ] -o [ "$filename" == "\$extend" ] -o [ "$filename" == "\$Recycle.Bin" ] -o [ "$filename" == "\$recycle.bin" ]	\
			-o [ "$filename" == "\$RECYCLE.BIN" ] -o [ "$filename" == "pagefile.sys" ] -o [ "$filename" == "swapfile.sys" ]; then continue; fi
			GetHotkey
			submenu "${filename}..." "$file" --hotkey="${hotkey}" {
				FileManager "${2}"
			}
		elif test -f "$file"; then
			if ! regexp -s file_ext '\.([^!/.]+)$' "$file"; then continue; fi
			tr -D -s file_ext "$file_ext"
			if [ -n "$file_ext_args" ]; then
				set _ok="0"
				for _file_ext in $file_ext_args; do
					if [ "$_file_ext" == "$file_ext" ]; then set _ok="1"; break; fi
				done
				unset _file_ext
				if [ "$_ok" == "0" ]; then continue; fi
			fi
			if [ -n "$file_in_loop_args" ]; then
				set _ok="0"
				loopback isoloop "$file"
				for _file_in_loop in $file_in_loop_args; do
					if [ -e "(isoloop)${_file_in_loop}" ]; then set _ok="1"; break; fi
				done
				loopback -d isoloop
				unset _file_in_loop
				if [ "$_ok" == "0" ]; then continue; fi
			fi
			GetHotkey
			submenu "${filename}" "$file" "$filename" "$file_ext" --hotkey="${hotkey}" {
				if [ -z $pim ]; then
					FileProcessing "$2" "$3" "$4"
				else
					PartitionImageMapper "$2" "$3" "$4"
				fi
			}
		fi
		unset filename
	done
	ReturnMainMenu;
	
	export enable_progress_indicator=0
}

function setdefault {
  if [ -z "${boot_once}" ]; then
	if [ x"${1}" = x ]; then
		saved_entry=
	elif [ -z "${chosen}" ]; then
		saved_entry="${1}"
	else
		saved_entry="${chosen}>${1}"
	fi
	if [ -e ${prefix}/grubenv_${grub_platform} ]; then
		save_env --file ${prefix}/grubenv_${grub_platform} saved_entry
	else
		save_env saved_entry
	fi
	esc 2 "${donemsg}"
	configfile $prefix/grub.cfg
  fi
}

function settimeout {
  set timeout=${1}
  save_env timeout
}

function ReturnMainMenu {
	menuentry "${backcfg} [${press} B]" --hotkey=b {
		configfile ${prefix}/Main.cfg
	}
}

function memdiskcmd {
	booting "${1}"
	
	loopback _loop "${1}"
	
	set param="fd raw"
	if probe -s _fs -f _loop; then
		if [ "$_fs" == "iso9660" ] -o [ "$_fs" == "udf" ]; then
			set param="iso raw"
		fi
		unset _fs
	else
		stat -z -s _filesize "${_file}"
		if [ "$_filesize" != "1474560" ] -a [ "$_filesize" != "2949120" ]; then
			set param="raw"
		fi
		unset _filesize
	fi
	loopback -d _loop
	
	linux16 ${memdisk} ${param}
	initrd16 "${1}"
	boot
}

function map_and_boot {
	if [ -n "$2" ]; then
		set _file="(${2})${1}"
	else
		set _file="${1}"
	fi
	booting "${_file}"
	
	set param="FD"
	loopback _loop "${_file}"
	if probe -s _fs -f _loop; then
		if [ "$_fs" == "iso9660" ] -o [ "$_fs" == "udf" ]; then
			set param="CD"
		fi
		unset _fs
	else
		if file --is-x86-linux "${_file}"; then
			if [ -n "$pc" ]; then
				linux16		"${_file}"
			else
				linuxefi	"${_file}"
			fi
			boot
		elif file --is-x86-multiboot "${_file}"; then
			set root="${2}"
			multiboot	"${1}"
			boot
		elif file --is-x86-multiboot2 "${_file}"; then
			set root="${2}"
			multiboot2	"${1}"
			boot
		fi
		stat -z -s _filesize "${_file}"
		if [ "$_filesize" != "1474560" ] -a [ "$_filesize" != "2949120" ]; then
			set param="HD"
		fi
		unset _filesize
	fi
	loopback -d _loop
	
	if [ -n "$pc" ]; then
		Grub4dosRoot
		set opt="root ${g4droot};/AIO/MAP ${param} ${1}"
		linux16 ${g4d_path}/grub.exe --config-file=${opt}
	elif map "${_file}" -t ${param} vd5; then
		boot
	else
		map -x vd5
		esc 1 "${nobootablemsg}"
	fi
	boot
}

function WinBuilderISO {
	regexp -s IsoName '^.(.*)$' "${1}"
	for _ini in Win10PESE.ini Win8PESE.ini Win7PESE.ini; do
		if [ -e /${_ini} ]; then
			save_env -f /${_ini} IsoName
		fi
	done
	unset IsoName
	map_and_boot "${1}" "${2}"
}

function StringReplace {
	set OldString="${1}"
	set OldPattern="${2}"
	set NewPattern="${3}"
	
	if ! regexp -s 1:strs1 -s 2:strs2 "(.*)${OldPattern}(.*)" "${OldString}"; then
		return 1
	else
		set NewString="${NewPattern}${strs2}"
	fi
	
	while regexp -s 1:strs1 -s 2:strs2 "(.*)${OldPattern}(.*)" "${strs1}"; do
		set NewString="${NewPattern}${strs2}${NewString}"
	done
	
	set NewString="${strs1}${NewString}"
	
	return 0
}

function vhdbooting {
	vhd -d vhd9
	vhd -p vhd9 "${2}"
	for _vhd_part in (vhd9,*); do
		if [ -e "${_vhd_part}/windows/system32/winload.exe" ] -o [ -e "${_vhd_part}/windows/system32/winload.efi" ]; then
			ntbootcmd "$2" "$3"
			return 0
		fi
	done
	if [ -n "$efi" ]; then
		if map -t HD (vhd9) vd9; then
			boot
		else
			map -x vd9
			vhd -d vhd9
		fi
	elif [ -n "$pc" ]; then
		vhd -d vhd9
		probe -s dev_uuid -u "${4}"
		loopback vboot ${prefix}/i386-pc/vbootldr.gz
		set vbootloader=(vboot)/vboot
		vbootinsmod (vboot)/vbootcore.mod
		vboot "harddisk=(UUID=${dev_uuid})${1}"
		boot
		return 0
	fi
}

function wimbooting {
	if [ -n "$efi" ]; then
		set winload_ext="efi"
	else
		set winload_ext="exe"
	fi
	if wimtools --exist "${1}" '\windows\system32\boot\winload.'$winload_ext; then
		ntbootcmd "${1}" "$2"
	elif [ -n "$pc" ]; then
		if wimtools --exist "${1}" '\i386\system32\cmd.exe'; then
			Grub4dosRoot
			set opt="root ${g4droot};/AIO/NTBOOT PE1 ${path}"
			linux16 ${g4d_path}/grub.exe --config-file=${opt}
			boot
		fi
	fi
	unset winload_ext
}

function Refresh {
	search --file --no-floppy --set=root /AIO/aioboot.com.html
	if [ -n "${efi}" ]; then
		chainloader /efi/boot/boot${_SPEC_UEFI_ARCH}.efi
	else
		multiboot /aio/grub/i386-pc/core.img
	fi
}
