# 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/>.

# By					: Nguyen Tu.
# Last modified			: 05.03.2018.
	# Partition Tools	: https://www.aioboot.com/en/grub2-parttool-command/.
	# PartIMG Mapper	: https://www.aioboot.com/en/partimg-mapper/.
	# File Manager		: List files and directories, support for opening text files, ISO, PartIMG and partition images.
	#					: https://www.aioboot.com/en/grub2-file-manager/.
	#					: FileManager.cfg.
	# Find and boot Windows XP/7/8/8.1/10 installed on the HDD.
	#					: https://www.aioboot.com/en/boot-windows-grub2/.
	# Change language, background and font size.
	#					: https://www.aioboot.com/en/grub2-background-language-font-size/.
	# Search Grub2 & Syslinux configfile.
	# Automatically add hotkeys sorted by 0-9, a-z.
	# And much more		: https://www.aioboot.com.

insmod regexp

function esc {
	if [ -n "$2" ]; then echo -e "\n${2}"; fi
	if [ "$1" == "1" ]; then echo -e -n "\n${escreturnl}"; elif [ "$1" == "2" ]; then echo -e -n "\n${esccontinuel}"; 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
}

function linuxefi {
	linux $@
}

function initrdefi {
	initrd $@
}

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
}

source ${prefix}/Tools.cfg

function freebsd_ufs_variants {
	
	menuentry "[1] 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 "[2] 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 "[3] 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 "[4] 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 "[5] 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 "[6] 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 "[1] 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 "[2] 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 "[3] 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 "[4] 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 "[5] 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 "[6] 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 grub4dosroot {
	if test -z "$1"; then set devicestr="${root}"; else set devicestr="${1}"; fi
	probe -f -s fstype $devicestr
	probe -p -s hdscheme $devicestr
	if [ "${fstype}" != "iso9660" ]; then
		regexp -s 1:disknum -s 2:partn "(.*),${hdscheme}([0-9]+)" "$devicestr"
		regexp -s partn "([0-9]+).${partn}" "0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31"
		set g4droot="(${disknum},${partn})"
		unset disknum
		unset partn
	else set g4droot="(${devicestr})"; fi
	unset devicestr
	unset fstype
	unset hdscheme
}

function partimgentry {
	GetHotkey
	menuentry "[${k}] ${1}" "$1" --hotkey="${k}" {
		if strcontains "$2" " " ; then esc 1 "${filenamespace}";
		else
			if ! test -d (hd0,msdos1); then partnum="0"
			elif ! test -d (hd0,msdos2); then partnum="1"
			elif ! test -d (hd0,msdos3); then partnum="2"
			elif ! test -d (hd0,msdos4); then partnum="3"
			fi
			if [ -z "$partnum" ]; then esc 1 "${fullpart}";
			else
				loopback loopimg "/AIO/Files/PartIMG/${2}"
				probe -f -s parttype loopimg
				if [ -z "$parttype" ]; then
					esc 1
				else
					loopback -d loopimg
					regexp -s g4ddisk 'hd(.*),' "$root"
					grub4dosroot
					set fstype="0x00"
					if [ "${parttype}" == "ntfs" ] -o [ "${parttype}" == "exfat" ]; then fstype="0x07"
					elif [ "${parttype}" == "iso9660" ] -o [ "${parttype}" == "ext2" ] -o [ "${parttype}" == "xfs" ] -o [ "${parttype}" == "reiserfs" ]; then fstype="0x83"
					elif [ "${parttype}" == "hfs" ] -o [ "${parttype}" == "hfsplus" ]; then fstype="0xAF"
					elif [ "${parttype}" == "ufs1" ] -o [ "${parttype}" == "ufs2" ]; then
						fstype="0xA5"
						if test -f (loopimg)/netbsd; then fstype="0xA9"
						elif test -f (loopimg)/bsd; then fstype="0xA6"
						fi
					elif [ "${parttype}" == "jfs" ]; then fstype="0x35"
					fi
					set opt="debug off; root ${g4droot} > nul; /AIO/Tools/grub4dos/partnew.g4b ${g4ddisk},${partnum} ${fstype} ${2} ${lang}"
					linux /AIO/Tools/grub4dos/grub.exe --config-file=${opt}
				fi
			fi
		fi
	}
	unset partnum
	unset parttype
	unset fstype
}

function GetConfigFile {
	for file in "/boot/grub/grub.cfg" "/efi/boot/grub.cfg" "/EFI/BOOT/grub.cfg" "/EFI/BOOT/GRUB.CFG" "/EFI/boot/grub.cfg" "/BOOT/GRUB/GRUB.CFG" "/BOOT/GRUB/grub.cfg" "/BOOT/grub/grub.cfg" "/grub/grub.cfg"; do
		if test -f ($1)$file; then
			GetHotkey
			menuentry "[${k}] Load ${file} ${on} (${1}) - ${2} - ${3} - ${4}" "$1" "$file" --hotkey="${k}" {
				set root=$2
				if test -d (${2})/boot/grub/${grub_cpu}-${grub_platform}; then set prefix="(${2})/boot/grub"; fi
				configfile $3
			}
		fi
	done
	for file in "/isolinux/isolinux.cfg" "/boot/isolinux/isolinux.cfg" "/isolinux/live.cfg" "/isolinux/install.cfg" "/isolinux.cfg" "/boot/i386/loader/isolinux.cfg" "/boot/x86_64/loader/isolinux.cfg" \
	"/ISOLINUX/ISOLINUX.CFG" "/BOOT/ISOLINUX/ISOLINUX.CFG" "/ISOLINUX/LIVE.CFG" "/ISOLINUX/INSTALL.CFG" "/ISOLINUX.CFG" "/BOOT/I386/LOADER/ISOLINUX.CFG" "/BOOT/X86_64/LOADER/ISOLINUX.CFG"; do
		if test -f ($1)$file; then
			GetHotkey
			menuentry "[${k}] Load ${file} ${on} (${1}) - ${2} - ${3} - ${4}" "$1" "$file" --hotkey="${k}" {
				set root=$2
				syslinux_configfile -i $3
			}
		fi
	done
	for file in "/boot/syslinux/syslinux.cfg" "/syslinux/syslinux.cfg" "/syslinux.cfg" "/arch/boot/syslinux/syslinux.cfg" "/isolinux/syslinux.cfg" "/slax/boot/syslinux.cfg" \
	"/BOOT/SYSLINUX/SYSLINUX.CFG" "/SYSLINUX/SYSLINUX.CFG" "/SYSLINUX.CFG" "/ARCH/BOOT/SYSLINUX/SYSLINUX.CFG" "/ISOLINUX/SYSLINUX.CFG"; do
		if test -f ($1)$file; then
			GetHotkey
			menuentry "[${k}] Load ${file} ${on} (${1}) - ${2} - ${3} - ${4}" "$1" "$file" --hotkey="${k}" {
				set root=$2
				syslinux_configfile -s $3
			}
		fi
	done
}

function wimboot {
	echo "${loading} ${1}... ${plswait}".
	linux16		/AIO/Tools/MS/PXE/wimboot.x64 rawbcd
	initrd16	\
		newc:bootmgr:/AIO/Tools/MS/PXE/bootmgr			\
		newc:bootmgr.exe:/AIO/Tools/MS/PXE/bootmgr.exe	\
		newc:bcd:/AIO/Tools/MS/PXE/boot/bcd				\
		newc:segmono_boot.ttf:/AIO/Tools/MS/PXE/boot/fonts/segmono_boot.ttf		\
		newc:segoe_slboot.ttf:/AIO/Tools/MS/PXE/boot/fonts/segoe_slboot.ttf		\
		newc:segoen_slboot.ttf:/AIO/Tools/MS/PXE/boot/fonts/segoen_slboot.ttf	\
		newc:wgl4_boot.ttf:/AIO/Tools/MS/PXE/boot/fonts/wgl4_boot.ttf			\
		newc:boot.sdi:/AIO/Tools/MS/boot.sdi	\
		newc:boot.wim:"${1}"
}

function ListWimBoot {
	echo "${wimmessage}"
	set k="_"
	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
		GetHotkey
		menuentry "[${k}] ${filename}" "$filename" --hotkey="${k}" {
			wimboot "/AIO/Files/WinPE/${2}"
		}
	done
	if [ -z "$havefile" ]; then
		esc 2 "${nowim}"
	else
		unset havefile
		source ${prefix}/ReturnMain.cfg
	fi
	unset filename
}

function WindowsDetect {
    set saved_root=$root
	for dev in (hd*,*); do
		regexp -s device '\((.*)\)' $dev
		if ! searchindevice "$device"; then continue; fi
		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"
				regexp -s devnum 'hd([0-9]+)' $root
				if test "$devnum" != "0"; then drivemap -s hd0 $root; fi
				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 ChangeBackground {
	echo "${bgmessage}"
	set k="_"
	for file in ${prefix}/themes/*; do
		if ! test -f "$file"; then continue; fi
		if [ "$file" == "${prefix}/themes/${bg}" ]; then continue; fi
		regexp -s filename "/AIO/grub/themes/(.*)" "$file"
		if [ -z "$havefile" ]; then set havefile="1"; fi
		GetHotkey
		menuentry "[${k}] ${filename}" "$filename" --hotkey="${k}" {
			bg="$2"
			background_image -m stretch "${prefix}/themes/${bg}"
			save_env bg
			configfile ${prefix}/Main.cfg
		}
	done
	if [ -z "$havefile" ]; then
		esc 2 "${nobg}"
	else
		unset havefile
		source ${prefix}/ReturnMain.cfg
	fi
	unset filename
}

function ChangeLanguage {
	set k="_"
	for langstr in "vi=Tiếng Việt" "en=English" "ast=Asturian; Bable; Leonese; Asturleonese" "ca=català" "zh_CN=中文 (Simplified)" "zh_TW=中文 (Traditional)" "da=dansk" "nl=Dutch" "en@arabic=English - Arabic"				\
					"en@cyrillic=English - Cyrillic" "en@greek=English - Greek" "en@hebrew=English - Hebrew" "en@piglatin=English - Piglatin" "en@quot=English - Quot"			\
					"eo=Esperanto" "fi=Finnish" "fr=français" "gl=Galego" "de=Deutsch" "de@hebrew=German - Hebrew" "de_CH=German - SWITZERLAND (CH)" "hu=magyar"				\
					"hr=hrvatski jezik" "id=Bahasa Indonesia" "it=Italiano" "ja=日本語" "lt=lietuvių kalba" "nb=Norsk Bokmål" "no=Norwegian" "pl=Polish" "pt_BR=Português" "pa=Panjabi" "ru=русский" "sr=српски језик"	\
					"sl=Slovenian" "es=Español" "sv=Svenska" "tr=Türkçe" "uk=Українська"; do
		regexp -s 2:langname -s 1:langcode '(.*)=(.*)' "$langstr"
		if [ "$langcode" == "$lang" ] -o [ -z "$lang" -a "$langcode" == "en" ]; then continue; fi
		GetHotkey
		menuentry "[${k}] ${langname}" "$langcode" --hotkey="${k}" {
			lang="$2"
			save_env lang
			configfile ${prefix}/grub.cfg
		}
	done
	source ${prefix}/ReturnMain.cfg
}

#function changeroot {
#	changeroot.cfg
#}

#function partimgmapper {
#	partimgmapper.cfg
#}

#function parttoolfunc {
#	PartitionTool.cfg
#}

#function partimgpartition {
#	partimgpartition.cfg
#}

#function searchcfg {
#	searchcfg.cfg
#}

function GetHotkey {
	if [ "$k" != "." ]; then
		set hotkeys="_0123456789adfghijklmnopqrstuwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ`=,."
		regexp -s k "${k}(.)" "$hotkeys"
	fi
}

function FileManager {
	echo "${gettinglist}"
	set k="_"
	GetHotkey
	submenu "[${k}] ... ${1}" "$1" --hotkey="${k}" {
		regexp -s subdir ".*\/(.*)" "$2"
		if [ -n "$subdir" ]; then
			regexp -s dir "(.*)\/.*" "$2"
			FileManager "$dir"
		else
			if regexp 'loop' "$2"; then
				regexp -s loopdev '\((.*)\)' "$2"
				loopback -d $loopdev
				unset loopdev
			fi
			configfile ${prefix}/FileManager.cfg
		fi
	}
	for file in $1/*; do
		GetHotkey
		regexp -s filename ".*\/(.*)" "$file"
		if test -d "$file"; then
			submenu "[${k}] ${filename}..." "$file" --hotkey="${k}" {
				FileManager "${2}"
			}
		elif test -f "$file"; then
			FileProcessing "$file" "$filename"
		fi
		unset filename
	done
	source ${prefix}/ReturnMain.cfg
}

function FileProcessing {
	regexp -s ext ".*\.(.*)" "$1"
	regexp -s 1:devstr -s 2:path '\((.*)\)(.*)' "$1"
	tr -D -s ext "$ext"
	
	if [ "$ext" == "iso" ]; then
		loopback isoloop "$1"
		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
			menuentry "[${k}] ${2}" "$1" "$path" "$devstr" "$cfg" --hotkey="${k}" {
				probe -u -s rootuuid $4
				export rootuuid
				set iso_path="$3"
				export iso_path
				loopback isoloop "$2"
				set root=isoloop
				configfile $5
				loopback -d isoloop
			}
			unset cfgtext
			loopback -d isoloop
			return 0
		done
		for cfg in /boot/grub/grub.cfg /EFI/BOOT/grub.cfg /EFI/boot/grub.cfg /boot/grub2/grub.cfg	\
					/efi/boot/grub.cfg /isolinux/live.cfg /boot/isolinux/isolinux.cfg /slax/boot/syslinux.cfg /isolinux/txt.cfg; do
			if ! test -e (isoloop)$cfg; then continue; fi
			cat -s cfgtext (isoloop)$cfg
			if regexp 'iso_path' "$cfgtext"; then
				menuentry "[${k}] ${2}" "$1" "$path" "$devstr" "$cfg" --hotkey="${k}" {
					probe -u -s rootuuid $4
					export rootuuid
					set iso_path="$3"
					export iso_path
					loopback isoloop "$2"
					set root=isoloop
					configfile $5
					loopback -d isoloop
				}
				set loopok=1
			elif regexp 'boot=casper' "$cfgtext"; then
				if test -f (isoloop)/casper/filesystem.squashfs -a -f (isoloop)/casper/vmlinu* -a -f (isoloop)/casper/initr*; then
					menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
						loopback isoloop "$2"
						for preseed in (isoloop)/preseed/*; do
							regexp -s preseed '\(isoloop\)(.*)' "$preseed"
							preseed="file=/cdrom/${preseed}"
							break
						done
						for vmlinuz in (isoloop)/casper/vmlinu*; do
							linux	$vmlinuz   ${preseed} boot=casper iso-scan/filename=${3} quiet splash ---
							unset vmlinuz
							break
						done
						for initrd in (isoloop)/casper/initr*; do
							initrd	$initrd
							unset initrd
							break
						done
					}
					set loopok=1
				fi
			elif regexp 'boot=live' "$cfgtext"; then
				if test -f (isoloop)/live/filesystem.squashfs -a -f (isoloop)/live/vmlinu* -a -f (isoloop)/live/initr*; then
					if regexp 'menuentry "Clonezilla' "$cfgtext"; then set params="union=overlay username=user config noswap edd=on nomodeset locales= keyboard-layouts= ocs_live_run="ocs-live-general" ocs_live_extra_param="" ocs_live_batch="no" vga=788 ip= net.ifnames=0  nosplash i915.blacklist=yes radeonhd.blacklist=yes nouveau.blacklist=yes vmwgfx.enable_fbdev=1";
					elif regexp 'menuentry "GParted' "$cfgtext"; then set params="union=overlay username=user config noswap  ip= net.ifnames=0  nosplash";
					else set params="splash"; fi
					menuentry "[${k}] ${2}" "$1" "$path" "$params" --hotkey="${k}" {
						loopback isoloop "$2"
						for vmlinuz in (isoloop)/live/vmlinu*; do
							linux	$vmlinuz   boot=live findiso=${3} components quiet ${4}
							unset vmlinuz
							break
						done
						for initrd in (isoloop)/live/initr*; do
							initrd	$initrd
							unset initrd
							break
						done
					}
					set loopok=1
				fi
			elif regexp 'rd.live.image' "$cfgtext"; then
				if test -d (isoloop)/LiveOS; then
					set isodev="UUID"
					if test -f (isoloop)/images/pxeboot/vmlinu* -a -f (isoloop)/images/pxeboot/initr*; then set bootpath="/images/pxeboot";
					elif test -f (isoloop)/isolinux/vmlinu* -a -f (isoloop)/isolinux/initr*; then set bootpath="/isolinux";
					elif test -f (isoloop)/boot/*/loader/linu* -a -f (isoloop)/boot/*/loader/initr*; then
						for bootpath in /boot/*/loader; do
							if test -d (isoloop)$bootpath; then set isodev="CDLABEL"; break; fi
						done
					fi
				fi
				if [ -n "$bootpath" ]; then 
					menuentry "[${k}] ${2}" "$1" "$path" "$bootpath" "$isodev" --hotkey="${k}" {
						loopback isoloop "$2"
						if [ "$5" == "UUID" ]; then probe -u -s isouuid isoloop; else probe -l -s isouuid isoloop; fi
						for vmlinuz in (isoloop)${4}/vmlinu* (isoloop)${4}/linu*; do
							if ! test -e $vmlinuz; then continue; fi
							linux	$vmlinuz   root=live:${5}=${isouuid} rd.live.image quiet iso-scan/filename=${3}
							unset vmlinuz
							unset isouuid
							break
						done
						for initrd in (isoloop)${4}/initr*; do
							if ! test -e $initrd; then continue; fi
							initrd	$initrd
							unset initrd
							break
						done
					}
					unset isodev
					unset bootpath
					set loopok=1
				fi
			elif regexp 'inst.stage2=hd:' "$cfgtext"; then
				if test -f (isoloop)/images/pxeboot/vmlinu* -a -f (isoloop)/images/pxeboot/initr* -a -d (isoloop)/LiveOS; then
					menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
						loopback isoloop "$2"
						probe -u -s isouuid isoloop
						for vmlinuz in (isoloop)/images/pxeboot/vmlinu*; do
							linux	$vmlinuz   inst.stage2=hd:UUID=${isouuid} rd.live.image quiet iso-scan/filename=${3}
							unset vmlinuz
							unset isouuid
							break
						done
						for initrd in (isoloop)/images/pxeboot/initr*; do
							initrd	$initrd
							unset initrd
							break
						done
					}
					set loopok=1
				fi
			elif regexp "initrd=/boot/initrd.gz root=/dev/ram0 vga=normal" "$cfgtext"; then
				if test -f (isoloop)/boot/initrd.gz -a -f (isoloop)/boot/bzImage; then
					menuentry "[${k}] ${2}" "$1" --hotkey="${k}" {
						loopback isoloop "$2"
						linux	(isoloop)/boot/bzImage root=/dev/ram0 vga=normal
						initrd	(isoloop)/boot/initrd.gz
					}
					set loopok=1
				fi
			elif regexp "tinycore.gz" "$cfgtext"; then
				menuentry "[${k}] ${2}" "$1" "$cfg" --hotkey="${k}" {
					loopback isoloop "$2"
					set root=isoloop
					if regexp 'isolinux.cfg' "$3"; then syslinux_configfile $3; else configfile $3; fi
				}
				set loopok=1
			fi
			unset cfgtext
			if [ -n "$loopok" ]; then loopback -d isoloop; unset loopok; return 0; fi
		done
		if test -f (isoloop)/casper/filesystem.squashfs -a -f (isoloop)/casper/vmlinu* -a -f (isoloop)/casper/initr*; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				for preseed in (isoloop)/preseed/*; do
					regexp -s preseed '\(isoloop\)(.*)' "$preseed"
					preseed="file=/cdrom/${preseed}"
					break
				done
				for vmlinuz in (isoloop)/casper/vmlinu*; do
					linux	$vmlinuz   ${preseed} boot=casper iso-scan/filename=${3} quiet splash ---
					unset vmlinuz
					break
				done
				for initrd in (isoloop)/casper/initr*; do
					initrd	$initrd
					unset initrd
					break
				done
			}
			set loopok=1
		elif test -f (isoloop)/live/filesystem.squashfs -a -f (isoloop)/live/vmlinu* -a -f (isoloop)/live/initr*; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				for vmlinuz in (isoloop)/live/vmlinu*; do
					linux	$vmlinuz   boot=live findiso=${3} components quiet splash
					unset vmlinuz
					break
				done
				for initrd in (isoloop)/live/initr*; do
					initrd	$initrd
					unset initrd
					break
				done
			}
			set loopok=1
		elif test -f (isoloop)/arch/boot/intel_ucode.img -a -f (isoloop)/arch/boot/*/archiso.img -a -f (isoloop)/arch/boot/*/vmlinuz; then
			menuentry "[${k}] ${2}" "$1" "$path" "$devstr" --hotkey="${k}" {
				loopback isoloop "$2"
				probe -u -s devuuid $4
				for vmlinuz in (isoloop)/arch/boot/*/vmlinuz; do
					linux	$vmlinuz img_loop=${3} img_dev=/dev/disk/by-uuid/$devuuid earlymodules=loop
					unset vmlinuz
					unset devuuid
					break
				done
				for initrd in (isoloop)/arch/boot/*/archiso.img; do
					initrd	(isoloop)/arch/boot/intel_ucode.img $initrd
					unset initrd
					break
				done
			}
			set loopok=1
		elif test -f (isoloop)/antiX/vmlinu* -a -f (isoloop)/antiX/initr*; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				for vmlinuz in (isoloop)/antiX/vmlinu*; do
					linux	$vmlinuz quiet fromiso=${3} from=usb,cd,hd
					unset vmlinuz
					break
				done
				for initrd in (isoloop)/antiX/initr*; do
					initrd	$initrd
					unset initrd
					break
				done
			}
			set loopok=1
		elif test -e (isoloop)/rescue/livecd.squashfs -a -e (isoloop)/boot/kernel.x86_64-efi -a -e (isoloop)/boot/initfs.x86_64-efi	\
		-a -e (isoloop)/boot/kernel.i386-pc -a -e (isoloop)/boot/initfs.i386-pc; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				if cpuid -l; then set arch="x86_64-efi"; else set arch="i386-pc"; fi
				linux	(isoloop)/boot/kernel.${arch} root=/dev/ram0 real_root=/dev/loop0 loop=/rescue/livecd.squashfs cdroot_marker=/rescue/livecd.squashfs initrd udev cdroot scandelay=10 quiet splash isoboot=${3} lang=en
				initrd	(isoloop)/boot/initfs.${arch}
			}
			set loopok=1
		elif test -e (isoloop)/pmagic/m64.img -a -e (isoloop)/pmagic/m32.img -a -e (isoloop)/pmagic/bzImage64 -a -e (isoloop)/pmagic/bzImage	\
		-a -e (isoloop)/pmagic/fu.img -a -e (isoloop)/pmagic/initrd.img; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				if cpuid -l; then set bz="bzImage64"; set m="m64.img"; else set bz="bzImage"; set m="m32.img"; fi
				linux	(isoloop)/pmagic/${bz} edd=on vga=normal iso_filename=${3}
				initrd	(isoloop)/pmagic/initrd.img (isoloop)/pmagic/fu.img (isoloop)/pmagic/${m}
			}
			set loopok=1
		elif test -e (isoloop)/image.squashfs -a -e (isoloop)/livecd -a -e (isoloop)/isolinux/gentoo -a -e (isoloop)/isolinux/gentoo.igz; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				linux	(isoloop)/isolinux/gentoo root=/dev/ram0 init=/linuxrc dokeymap looptype=squashfs loop=/image.squashfs cdroot vga=791 isoboot=${3} 
				initrd	(isoloop)/isolinux/gentoo.igz
			}
			set loopok=1
		elif test -e (isoloop)/image.squashfs -a -e (isoloop)/livecd -a -e (isoloop)/isolinux/gentoo -a -e (isoloop)/isolinux/gentoo.xz; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				linux	(isoloop)/isolinux/gentoo root=/dev/ram0 init=/linuxrc dokeymap aufs looptype=squashfs loop=/image.squashfs cdroot console=tty1 isoboot=${3} 
				initrd	(isoloop)/isolinux/gentoo.xz
			}
			set loopok=1
		elif test -e (isoloop)/slax/boot/vmlinuz -a -e (isoloop)/slax/boot/initrfs.img; then
			menuentry "[${k}] ${2}" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				linux	(isoloop)/slax/boot/vmlinuz vga=normal load_ramdisk=1 prompt_ramdisk=0 rw printk.time=0 slax.flags=automount from=$3
				initrd	(isoloop)/slax/boot/initrfs.img
			}
			set loopok=1
		elif test -e (isoloop)/liveslak -a -e (isoloop)/boot/generic -a -e (isoloop)/boot/initrd.img; then
			menuentry "[${k}] ${2}" "$1" "$path" "$devstr" --hotkey="${k}" {
				loopback isoloop "$2"
				probe -u -s deviceuuid $4
				linux	(isoloop)/boot/generic load_ramdisk=1 prompt_ramdisk=0 rw printk.time=0 kbd=us tz=localtime locale=us_EN.utf8 livemedia=/dev/disk/by-uuid/${deviceuuid}:$3
				initrd	(isoloop)/boot/initrd.img
			}
			set loopok=1
		elif test -e (isoloop)/wifislax64 -a -e (isoloop)/boot/vmlinuz -a -e (isoloop)/boot/initrd.xz; then
			menuentry "[${k}] ${2}" "$1" "$path" "$devstr" --hotkey="${k}" {
				loopback isoloop "$2"
				probe -u -s deviceuuid $4
				linux	(isoloop)/boot/vmlinuz kbd=us tz=US/Pacific locale=en_US.utf8 xkb= rw livemedia=/dev/disk/by-uuid/${deviceuuid}:$3
				initrd	(isoloop)/boot/initrd.xz
			}
			set loopok=1
		elif test -e (isoloop)/wifislax -a -e (isoloop)/boot/vmlinuz -a -e (isoloop)/boot/initrd.xz; then
			menuentry "[${k}] ${2} (Wifislax With KDE Desktop)" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				linux	(isoloop)/boot/vmlinuz noload=000-SMP\;006-Xfce load=English from=${3}
				initrd	(isoloop)/boot/initrd.xz
			}
			GetHotkey
			menuentry "[${k}] ${2} (Wifislax With Xfce Desktop)" "$1" "$path" --hotkey="${k}" {
				loopback isoloop "$2"
				linux	(isoloop)/boot/vmlinuz noload=000-SMP\;005-Kde load=English from=${3}
				initrd	(isoloop)/boot/initrd.xz
			}
			set loopok=1
		elif test -e (isoloop)/suse -a -e (isoloop)/boot/*/loader/initrd -a -e (isoloop)/boot/*/loader/linux; then
			for vmlinuz in (isoloop)/boot/*/loader/linux; do
				if ! test -e $vmlinuz; then continue; fi
				break
			done
			for initrd in (isoloop)/boot/*/loader/initrd; do
				if ! test -e $initrd; then continue; fi
				break
			done
			submenu "[${k}] ${2}" "$1" "$path" "$vmlinuz" "$initrd" --hotkey="${k}" {
				menuentry "[1] Installation" "$2" "$3" "$4" "$5" --hotkey=1 {
					loopback isoloop "$2"
					linux	${4} splash=silent install=hd:${3}
					initrd	${5}
				}
				menuentry "[2] Upgrade" "$1" "$path" "$4" "$5" --hotkey=2 {
					loopback isoloop "$2"
					linux	${4} splash=silent upgrade=1 install=hd:${3}
					initrd	${5}
				}
			}
			unset vmlinuz
			unset initrd
			set loopok=1
		fi
		if [ -n "$loopok" ]; then loopback -d isoloop; unset loopok; return 0; fi
		loopback -d isoloop
	fi
	
	grub4dosroot "$devstr"
	if [ "$ext" == "iso" ] -o [ "$ext" == "partimg" ] -o [ "$ext" == "img" ] -o [ "$ext" == "ufs" ] -o [ "$ext" == "hfs" ] -o [ "$ext" == "squashfs" ] -o [ "$ext" == "sfs" ] -o [ "$ext" == "ima" ] -o [ "$ext" == "gz" ]; then
		submenu "[${k}] ${2}" "$1" "$ext" "$g4droot" "$path" "$devstr" --hotkey="${k}" {
			set timeout=0
			if [ -n "$pc" ]; then
				menuentry "[1] ${bootwith} Grub4dos" "$2" "$3" "$4" "$5" --hotkey=1 {
					if [ "$3" == "iso" ]; then set boottype="bootiso"; else set boottype="bootraw"; fi
					set opt="debug off; /AIO/Tools/grub4dos/${boottype}.g4b ${4}${5}"
					linux /AIO/Tools/grub4dos/grub.exe --config-file=${opt}
				}
				menuentry "[2] ${bootwith} MemDisk" "$2" "$3" --hotkey=2 {
					booting "$2"
					if [ "$3" == "iso" ]; then set params="iso raw"; else set params="raw"; fi
					linux16 ${memdisk} ${params}
					initrd16 "$2"
				}
				unset timeout
			fi
			submenu "[3] ${openwith} Loopback" "$2" --hotkey=3 {
				if ! test -e (loop1); then loop=loop1;
				elif ! test -e (loop2); then loop=loop2; 
				elif ! test -e (loop3); then loop=loop3; 
				elif ! test -e (loop4); then loop=loop4;
				elif ! test -e (loop5); then loop=loop5;
				else loop=loop1; loopback -d $loop; fi
				loopback $loop "$2"
				if probe -f $loop; then unset timeout; FileManager ($loop); else loopback -d $loop; fi
			}
		}
	elif [ "$ext" == "wim" ] -a [ -n "$pc" ]; then
		menuentry "[${k}] ${2} (NT6 - Windows Vista/7/8/8.1/10 - ${bootwith} wimboot)" "(${devstr})${path}" --hotkey="${k}" {
			wimboot "${2}"
		}
		GetHotkey
		menuentry "[${k}] ${2} (NT5 - Windows XP/2003 - ${bootwith} NTBOOT)" "${g4droot}${path}" --hotkey="${k}" {
			set opt="debug off; /AIO/Tools/grub4dos/bootvhd.g4b PE1 ${2}"
			linux /AIO/Tools/grub4dos/grub.exe --config-file=${opt}
		}
	elif test '(' [ "$ext" == "vhd" ] -o [ "$ext" == "vhdx" ] ')' -a [ -n "$pc" ]; then
		menuentry "[${k}] ${2} (NT6 - Windows Vista/7/8/8.1/10 - ${bootwith} NTBOOT)" "${g4droot}${path}" --hotkey="${k}" {
			set opt="debug off; /AIO/Tools/grub4dos/bootvhd.g4b NT6 ${2}"
			linux /AIO/Tools/grub4dos/grub.exe --config-file=${opt}
		}
		GetHotkey
		menuentry "[${k}] ${2} (NT5 - Windows XP/2003 - ${bootwith} NTBOOT)" "${g4droot}${path}" --hotkey="${k}" {
			set opt="debug off; /AIO/Tools/grub4dos/bootvhd.g4b NT5 ${2}"
			linux /AIO/Tools/grub4dos/grub.exe --config-file=${opt}
		}
	elif test '(' [ "$ext" == "lkrn" ] -o [ "$filename" == "grub.exe" ] ')' -a [ -n "$pc" ]; then
		menuentry "[${k}] ${2}" "$1" --hotkey="${k}" {
			linux16 "$2"
		}
	elif [ "$filename" == "menu.lst" ] -a [ -n "$pc" ]; then
		menuentry "[${k}] ${2}" "$path" --hotkey="${k}" {
			grub4dosroot
			set opt="debug off; root ${g4droot} > nul; configfile ${2}"
			linux /AIO/Tools/grub4dos/grub.exe --config-file=${opt}
		}
	elif [ "$filename" == "grldr" ] -a [ -n "$pc" ]; then
		menuentry "[${k}] ${2}" "$1" --hotkey="${k}" {
			ntldr "$2"
		}
	elif [ "$ext" == "efi" ] -a [ -n "$efi" ]; then
		menuentry "[${k}] ${2}" "$1" --hotkey="${k}" {
			chainloader "$2"
		}
	elif [ "$filename" == "grub.cfg" ]; then
		menuentry "[${k}] ${2}" "$1" --hotkey="${k}" {
			configfile "$2"
		}
	elif [ "$ext" == "png" ] -o [ "$ext" == "jpg" ] -o [ "$ext" == "jpeg" ]; then
		menuentry "[${k}] ${2}" "$1" --hotkey="${k}" {
			if ! background_image "$2"; then background_image "${prefix}/themes/${bg}"; fi
		}
	else
		menuentry "[${k}] ${2}" "$1" --hotkey="${k}" {
			cat "${2}"
			esc 1
		}
	fi
}