diff --git a/macos_okiomov.sh b/macos_okiomov.sh new file mode 100644 index 0000000..33a9e99 --- /dev/null +++ b/macos_okiomov.sh @@ -0,0 +1,518 @@ +#!/bin/bash +# One-Key-Installation of macOS on VirtualBox +# (c) img2tab, licensed under GPL2.0 or higher +# url: https://github.com/img2tab/okiomov +# version 0.1 + +# Requirements: 33.5GB available storage on host +# Dependencies: bash>4.0, unzip, wget, dmg2img, VirtualBox>5.2 + +# Personalized the installation by setting these variables: +vmname="Mojave" # name of VirtualBox virtual machine +storagesize=22000 # size of target virtual disk image. minimum 22000 +cpucount=4 # VM CPU cores, minimum 2 +memorysize=4096 # VM RAM in MB, minimum 2048 +gpuvram=128 # VM video RAM in MB, minimum 34 +resolution=1280x800 # display resolution + +# welcome message +whiteonred="\e[48;2;255;0;0m\e[38;2;255;255;255m" +whiteonblack="\e[48;2;0;0;9m\e[38;2;255;255;255m" +printf ' + One-Key-Installation of macOS On VirtualBox - Mojave 10.14.11 +------------------------------------------------------------------------------- + +'${whiteonblack}'This installer uses only open-source software and original +unmodified Apple binaries.\033[0m + +The installation requires '${whiteonred}'33.5GB\033[0m of available storage, +22GB for the virtual machine and 11.5GB for temporary installation files. + +The script checks for dependencies and will prompt to install them if unmet. + +Press enter to continue, CTRL-C to exit.' +read + +# silence stderr +exec 2>/dev/null + +# check dependencies + +if [ -n "${BASH_VERSION}" ]; then + if [ "${BASH_VERSION:0:1}" -lt 4 ]; then + echo "Please run this script in BASH 4.0 or higher." + exit + fi +fi + +if [ -z "$(unzip -hh)" \ + -o -z "$(wget --version)" ]; then + echo "Please install the packages 'unzip' and 'wget'." + exit +fi + +# add ${PATH} for VirtualBox and currend directory in Cygwin + +windows="" +if [ -n "$(cygcheck -V)" ]; then + PATH="${PATH}:/cygdrive/c/Program Files/Oracle/VirtualBox:$(pwd)" + windows="True" +fi + +# VirtualBox in ${PATH} + +if [ -z "$(VBoxManage -v)" ]; then + echo "Please make sure VirtualBox is installed, and that the path to" + echo "the VBoxManage executable is in the PATH variable." + if [ -n "${windows}" ]; then echo -n "VBoxManage is usually installed in" + echo "/cygdrive/c/Program Files/Oracle/VirtualBox" + echo "and can be added with PATH=\"\${PATH}:/cygdrive/c/<...>\"" + fi + exit +fi + +# dmg2img +if [ -z "$(dmg2img -d)" ]; then + if [ -z "${windows}" ]; then + echo "Please install the package dmg2img." + exit + else + echo "Downloading dmg2img" + wget -c "http://vu1tur.eu.org/tools/dmg2img-1.6.6-win32.zip" \ + -O "dmg2img-1.6.6-win32.zip" --quiet --show-progress 2>/dev/tty + unzip -oj "dmg2img-1.6.6-win32.zip" "dmg2img.exe" + rm "dmg2img-1.6.6-win32.zip" + chmod +x "dmg2img.exe" + fi +fi + +# Finally done with dependencies. + +if [ -n "$(VBoxManage showvminfo "${vmname}")" ]; then + echo "${vmname} virtual machine already exists. Exiting." + exit +fi + +# Create the macOS base system virtual disk image: +if [ -r "BaseSystem.vdi" ]; then + echo "BaseSystem.vdi bootstrap virtual disk image ready." +else + echo "Downloading BaseSystem.dmg from swcdn.apple.com" + wget -c 'http://swcdn.apple.com/content/downloads/35/53/091-93471/ff5kp0aiow1d87t494xp5twbugymnlvz16/BaseSystem.dmg' -O "BaseSystem.dmg" --quiet --show-progress 2>/dev/tty + echo "Downloaded BaseSystem.dmg. Converting to BaseSystem.img" + dmg2img "BaseSystem.dmg" "BaseSystem.img" + VBoxManage convertfromraw --format VDI "BaseSystem.img" "BaseSystem.vdi" + rm "BaseSystem.dmg" "BaseSystem.img" +fi + +# initialize the VirtualBox macOS Mojave 10.14.1 virtual machine: +echo "Creating ${vmname} virtual disk images." +VBoxManage createvm --name "${vmname}" --ostype "MacOS_64" --register + +# Create the target virtual disk image: +VBoxManage createmedium --size="${storagesize}" \ + --filename "${vmname}.vdi" \ + --variant fixed 2>/dev/tty + +# Create the installation media virtual disk image: +VBoxManage createmedium --size=8000 \ + --filename "Install ${vmname}.vdi" \ + --variant fixed 2>/dev/tty + +# Attach the target virtual disk image, the EFI drivers, +# and the base system in the virtual machine: +VBoxManage storagectl "${vmname}" --add sata --name SATA --hostiocache on +VBoxManage storageattach "${vmname}" --storagectl SATA --port 0 \ + --type hdd --nonrotational on --medium "${vmname}.vdi" +VBoxManage storageattach "${vmname}" --storagectl SATA --port 1 \ + --type hdd --nonrotational on --medium "Install ${vmname}.vdi" +VBoxManage storageattach "${vmname}" --storagectl SATA --port 2 \ + --type hdd --nonrotational on --medium BaseSystem.vdi + +# Configure the VM +VBoxManage modifyvm "${vmname}" --cpus "${cpucount}" --memory "${memorysize}" \ + --vram "${gpuvram}" --pae on --boot1 dvd --boot2 disk --boot3 none \ + --boot4 none --firmware efi --rtcuseutc on --usbxhci on --chipset ich9 \ + --mouse usb --keyboard usb --audio none +VBoxManage setextradata "${vmname}" \ + "VBoxInternal/Devices/efi/0/Config/DmiSystemProduct" "MacBookPro11,3" +VBoxManage setextradata "${vmname}" \ + "VBoxInternal/Devices/efi/0/Config/DmiSystemVersion" "1.0" +VBoxManage setextradata "${vmname}" \ + "VBoxInternal/Devices/efi/0/Config/DmiBoardProduct" "Mac-2BD1B31983FE1663" +VBoxManage setextradata "${vmname}" \ + "VBoxInternal/Devices/smc/0/Config/DeviceKey" "ourhardworkbythesewordsguardedpleasedontsteal(c)AppleComputerInc" +VBoxManage setextradata "${vmname}" \ + "VBoxInternal/Devices/smc/0/Config/GetKeyFromRealSMC" 1 +VBoxManage setextradata "${vmname}" \ + "VBoxInternal2/EfiGraphicsResolution" "${resolution}" + +# sterr back +exec 2>/dev/tty + +# Start the virtual machine. This should take a couple of minutes. +VBoxManage startvm "${vmname}" + +# QWERTY-to-scancode dictionary. Hex scancodes, keydown and keyup event. +# Virtualbox Mac scancodes found here: +# https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_1 +# First half of hex code - press, second half - release, unless otherwise specified +declare -A ksc=( + ["ESC"]="01 81" + ["1"]="02 82" + ["2"]="03 83" + ["3"]="04 84" + ["4"]="05 85" + ["5"]="06 86" + ["6"]="07 87" + ["7"]="08 88" + ["8"]="09 89" + ["9"]="0A 8A" + ["0"]="0B 8B" + ["-"]="0C 8C" + ["="]="0D 8D" + ["BKSP"]="0E 8E" + ["TAB"]="0F 8F" + ["q"]="10 90" + ["w"]="11 91" + ["e"]="12 92" + ["r"]="13 93" + ["t"]="14 94" + ["y"]="15 95" + ["u"]="16 96" + ["i"]="17 97" + ["o"]="18 98" + ["p"]="19 99" + ["["]="1A 9A" + ["]"]="1B 9B" + ["ENTER"]="1C 9C" + ["CTRLprs"]="1D" + ["CTRLrls"]="9D" + ["a"]="1E 9E" + ["s"]="1F 9F" + ["d"]="20 A0" + ["f"]="21 A1" + ["g"]="22 A2" + ["h"]="23 A3" + ["j"]="24 A4" + ["k"]="25 A5" + ["l"]="26 A6" + [";"]="27 A7" + ["'"]="28 A8" + ['`']="29 A9" + ["LSHIFTprs"]="2A" + ["LSHIFTrls"]="AA" + ['\']="2B AB" + ["z"]="2C AC" + ["x"]="2D AD" + ["c"]="2E AE" + ["v"]="2F AF" + ["b"]="30 B0" + ["n"]="31 B1" + ["m"]="32 B2" + [","]="33 B3" + ["."]="34 B4" + ["/"]="35 B5" + ["RSHIFTprs"]="36" + ["RSHIFTrls"]="B6" + ["ALTprs"]="38" + ["ALTrls"]="B8" + ["LALT"]="38 B8" + ["SPACE"]="39 B9" + [" "]="39 B9" + ["CAPS"]="3A BA" + ["F1"]="3B BB" + ["F2"]="3C BC" + ["F3"]="3D BD" + ["F4"]="3E BE" + ["F5"]="3F BF" + ["F6"]="40 C0" + ["F7"]="41 C1" + ["F8"]="42 C2" + ["F9"]="43 C3" + ["F10"]="44 C4" + ["UP"]="E0 48 E0 C8" + ["RIGHT"]="E0 4D E0 CD" + ["LEFT"]="E0 4B E0 CB" + ["DOWN"]="E0 50 E0 D0" + ["HOME"]="E0 47 E0 C7" + ["END"]="E0 4F E0 CF" + ["PGUP"]="E0 49 E0 C9" + ["PGDN"]="E0 51 E0 D1" + ["CMDprs"]="E0 5C" + ["CMDrls"]="E0 DC" + # all codes below start with LSHIFTprs as commented in first item: + ["!"]="2A 02 82 AA" # LSHIFTprs 1prs 1rls LSHIFTrls + ["@"]="2A 03 83 AA" + ["#"]="2A 04 84 AA" + ["$"]="2A 05 85 AA" + ["%"]="2A 06 86 AA" + ["^"]="2A 07 87 AA" + ["&"]="2A 08 88 AA" + ["*"]="2A 09 89 AA" + ["("]="2A 0A 8A AA" + [")"]="2A 0B 8B AA" + ["_"]="2A 0C 8C AA" + ["+"]="2A 0D 8D AA" + ["Q"]="2A 10 90 AA" + ["W"]="2A 11 91 AA" + ["E"]="2A 12 92 AA" + ["R"]="2A 13 93 AA" + ["T"]="2A 14 94 AA" + ["Y"]="2A 15 95 AA" + ["U"]="2A 16 96 AA" + ["I"]="2A 17 97 AA" + ["O"]="2A 18 98 AA" + ["P"]="2A 19 99 AA" + ["{"]="2A 1A 9A AA" + ["}"]="2A 1B 9B AA" + ["A"]="2A 1E 9E AA" + ["S"]="2A 1F 9F AA" + ["D"]="2A 20 A0 AA" + ["F"]="2A 21 A1 AA" + ["G"]="2A 22 A2 AA" + ["H"]="2A 23 A3 AA" + ["J"]="2A 24 A4 AA" + ["K"]="2A 25 A5 AA" + ["L"]="2A 26 A6 AA" + [":"]="2A 27 A7 AA" + ['"']="2A 28 A8 AA" + ["~"]="2A 29 A9 AA" + ["|"]="2A 2B AB AA" + ["Z"]="2A 2C AC AA" + ["X"]="2A 2D AD AA" + ["C"]="2A 2E AE AA" + ["V"]="2A 2F AF AA" + ["B"]="2A 30 B0 AA" + ["N"]="2A 31 B1 AA" + ["M"]="2A 32 B2 AA" + ["<"]="2A 33 B3 AA" + [">"]="2A 34 B4 AA" + ["?"]="2A 35 B5 AA" +) + +# send-string-as-keyboard-keystrokes and send-special-key to virtual machine +function sendkeys() { + scancode=$(for (( i=0; i < ${#kbstring}; i++ )); + do c[i]=${kbstring:i:1}; echo -n ${ksc[${c[i]}]}" "; done) + scancode="${scancode} ${ksc['ENTER']}" + VBoxManage controlvm "${vmname}" keyboardputscancode ${scancode} +} + +function sendspecial() { + scancode="" + for keypress in ${kbspecial}; do + scancode="${scancode}${ksc[${keypress}]}"" " + done + VBoxManage controlvm "${vmname}" keyboardputscancode ${scancode} +} + +function sendenter() { + kbspecial="ENTER" + sendspecial +} + +function promptlangutils() { +echo "" +read -p "Press enter when the language select screen is ready." +sendenter + +echo "" +read -p "Press enter when the macOS Utilities screen is ready." + +kbspecial='CTRLprs F2 CTRLrls u ENTER t ENTER' +sendspecial +} + +promptlangutils + +function promptterminalready() { +echo "" +read -p "Press enter when the Terminal command prompt is ready." +} + +promptterminalready + +echo "" +echo "Partitioning target virtual disk." + +# get "physical" disks from largest to smallest +kbstring='disks="$(diskutil list | grep -o "[0-9][^ ]* GB *disk[012]$" | sort -gr | grep -o disk[012])"; disks=(${disks[@]})' +sendkeys + +# partition largest disk as APFS +kbstring='diskutil partitionDisk "/dev/${disks[0]}" 1 GPT APFS "'"${vmname}"'" R' +sendkeys +promptterminalready +echo "" +echo "Partitioning installer virtual disk." + +# partition second-largest disk as JHFS+ +kbstring='diskutil partitionDisk "/dev/${disks[1]}" 1 GPT JHFS+ "Install" R' +sendkeys +promptterminalready +echo "" +echo "Downloading macOS Mojave 10.14.1 installer." + +# downloading macOS +kbstring='urlpath="http://swcdn.apple.com/content/downloads/35/53/091-93471/ff5kp0aiow1d87t494xp5twbugymnlvz16/"; for filename in BaseSystem.chunklist InstallInfo.plist AppleDiagnostics.dmg AppleDiagnostics.chunklist BaseSystem.dmg InstallESDDmg.pkg; do curl "${urlpath}${filename}" -o "/Volumes/'"${vmname}"'/${filename}"; done' +sendkeys +promptterminalready +echo "" +echo "Loading base system onto installer virtual disk" + +# Create secondary base system and shut down the virtual machine +kbstring='asr restore --source /Volumes/'"${vmname}"'/BaseSystem.dmg --target /Volumes/Install --erase --noprompt' +sendkeys + +promptterminalready + +kbstring='shutdown -h now' +sendkeys + +echo "" +echo "Shutting down virtual machine." +read -p "Press enter when the virtual machine shutdown is complete." + +# Detach the original 2GB BaseSystem.vdi and boot from the new 8GB BaseSystem +echo "" +echo "Detaching initial base system and starting virtual machine." +echo "The VM will boot from the new base system on the installer virtual disk." +VBoxManage storageattach "${vmname}" --storagectl SATA --port 2 --medium emptydrive +VBoxManage startvm "${vmname}" + +promptlangutils +promptterminalready +echo "" +echo "Moving installation files to installer virtual disk" +kbstring='mount -rw / && installpath="/Install macOS Mojave.app/Contents/SharedSupport/" && mkdir -p "${installpath}" && cd "/Volumes/'"${vmname}/"'" && mv *.chunklist *.plist *.dmg *.pkg "${installpath}"' +sendkeys + +# Rename InstallESDDmg.pkg to InstallESD.dmg and update InstallInfo.plist +kbstring='mv "${installpath}InstallESDDmg.pkg" "${installpath}InstallESD.dmg" && sed -i.bak -e "s/InstallESDDmg\.pkg/InstallESD.dmg/" -e "s/pkg\.InstallESDDmg/dmg.InstallESD/" "${installpath}InstallInfo.plist" && sed -i.bak2 -e "/InstallESD\.dmg/{n;N;N;N;d;}" "${installpath}InstallInfo.plist"' +sendkeys + +# reboot, because the installer does't work when the partition is remounted +kbstring="reboot" +echo "" +echo "Rebooting the virtual machine" +promptlangutils +promptterminalready + +# Start the installer. +kbstring='cd "/Install macOS Mojave.app/Contents/Resources/"; ./startosinstall --volume "/Volumes/'"${vmname}"'"' +sendkeys +echo "" +echo "Installer started. Please wait for the license prompt to appear at" +echo "the bottom of the virtual machine terminal, then press enter here." +read -p "This will accept the license on the virtual machine." +kbspecial="A ENTER" +sendspecial + +echo "" +echo "When the installer finishes preparing, the virtual machine will reboot" +echo "into the base system, not the installer." +read -p "After the reboot, press enter when the language select screen is ready." +sendenter + +echo "" +read -p "Press enter when the macOS Utilities screen is ready." + +# Start Safari (Get Help Online) +kbspecial="UP UP UP UP DOWN DOWN TAB SPACE" +sendspecial + +echo "" +read -p "Press enter when Safari is ready." + +# Browse the web! +kbspecial="CMDprs l CMDrls" +sendspecial +kbstring="https://github.com/acidanthera/AppleSupportPkg/releases/tag/2.0.4" +sendkeys +echo "" +printf 'In the VM, '${whiteonred}'manually\033[0m right-click on AppleSupport-v2.0.4-RELEASE.zip' +echo "and 'Download Linked File As...' and select ${vmname} for 'Where:'" +echo "from the dropdown menu. Then unbind the mouse cursor from the virtual" +printf 'machine with the '${whiteonblack}'right control key\033[0m.' +read -p "Click here and press enter when the download is complete." + +kbspecial="CMDprs q CMDrls" +sendspecial +echo "" +read -p "Press enter when the macOS Utilities screen is ready." +kbspecial="CTRLprs F2 CTRLrls u ENTER t ENTER" +sendspecial +promptterminalready + +# find largest drive +kbstring='disks="$(diskutil list | grep -o "[0-9][^ ]* GB *disk[012]$" | sort -gr | grep -o disk[012])"; disks=(${disks[@]})' +sendkeys + +# move drivers into path on EFI partition +kbstring='mkdir -p "/Volumes/'"${vmname}"'/mount_efi" && mount_msdos /dev/${disks[0]}s1 "/Volumes/'"${vmname}"'/mount_efi" && mkdir -p "/Volumes/'"${vmname}"'/mount_efi/EFI/driver/" && cd "/Volumes/'"${vmname}"'/mount_efi/EFI/driver/" && tar -xf "/Volumes/'"${vmname}"'/AppleSupport-v2.0.4-RELEASE.zip" && cd "Drivers/" && mv *.efi "/Volumes/'"${vmname}"'/mount_efi/EFI/driver/"' +sendkeys + +# create startup.nsh EFI script +kbstring='cd "/Volumes/'"${vmname}"'/mount_efi/" && vim startup.nsh' +sendkeys +echo "" +echo "Press enter when '\"startup.nsh\" [New File]' appears" +read -p "at the bottom of the terminal." + +kbstring='Iecho -off'; sendkeys +kbstring='load fs0:\EFI\driver\AppleImageLoader.efi'; sendkeys +kbstring='load fs0:\EFI\driver\AppleUiSupport.efi'; sendkeys +kbstring='load fs0:\EFI\driver\ApfsDriverLoader.efi'; sendkeys +kbstring='map -r'; sendkeys +kbstring='fs1:'; sendkeys +kbstring='cd "macOS Install Data\Locked Files\Boot Files"'; sendkeys +kbstring='boot.efi'; sendkeys +kbstring='cd "System\Library\CoreServices"'; sendkeys +kbstring='boot.efi'; sendkeys +kbstring='fs2:'; sendkeys +kbstring='cd "macOS Install Data\Locked Files\Boot Files"'; sendkeys +kbstring='boot.efi'; sendkeys +kbstring='cd "System\Library\CoreServices"'; sendkeys +kbstring='boot.efi'; sendkeys +kbstring='fs3:'; sendkeys +kbstring='cd "macOS Install Data\Locked Files\Boot Files"'; sendkeys +kbstring='boot.efi'; sendkeys +kbstring='cd "System\Library\CoreServices"'; sendkeys +kbstring='boot.efi'; sendkeys +kbspecial="ESC : w q ENTER"; sendspecial + +# Shut down the virtual machine +echo "" +read -p "Press enter when the terminal is ready." +kbstring='shutdown -h now' +sendkeys + +echo "" +echo "Shutting down virtual machine." +read -p "Press enter when the virtual machine shutdown is complete." + +# detach installer from virtual machine +VBoxManage storageattach "${vmname}" --storagectl SATA --port 1 --medium emptydrive + +# Start the virtual machine again. +# The VM will boot from the target virtual disk image and complete the installation. +VBoxManage startvm "${vmname}" + +echo "" +echo "macOS Mojave 10.14.1 will now install and start up." +echo "" +read -n 1 -p "Delete temporary files? [y/n] " delete +if [ "${delete}" -eq "y" ]; then +# temporary files cleanup + VBoxManage closemedium "BaseSystem.vdi" + VBoxManage closemedium "Install ${vmname}.vdi" + rm "BaseSystem.vdi" "Install ${vmname}.vdi" +echo "" +echo "macOS Mojave 10.14.1 installation should complete in a few minutes." +echo "" +echo "UEFI cleanup: after macOS successfully starts up, the two incorrect" +echo "fs: guesses in the UEFI startup.nsh may be manually removed, though they" +echo "generally have no effect except for the error messages at boot." +echo "" +echo "That's it. Enjoy your virtual machine." diff --git a/scancodes.sh b/scancodes.sh new file mode 100644 index 0000000..a2dea97 --- /dev/null +++ b/scancodes.sh @@ -0,0 +1,154 @@ +#!/bin/bash +# QWERTY-to-scancode dictionary. Hex scancodes, keydown and keyup event. +# Virtualbox Mac scancodes found here: +# https://wiki.osdev.org/PS/2_Keyboard#Scan_Code_Set_1 +# First half of hex code - press, second half - release, unless otherwise specified +declare -A ksc=( + ["ESC"]="01 81" + ["1"]="02 82" + ["2"]="03 83" + ["3"]="04 84" + ["4"]="05 85" + ["5"]="06 86" + ["6"]="07 87" + ["7"]="08 88" + ["8"]="09 89" + ["9"]="0A 8A" + ["0"]="0B 8B" + ["-"]="0C 8C" + ["="]="0D 8D" + ["BKSP"]="0E 8E" + ["TAB"]="0F 8F" + ["q"]="10 90" + ["w"]="11 91" + ["e"]="12 92" + ["r"]="13 93" + ["t"]="14 94" + ["y"]="15 95" + ["u"]="16 96" + ["i"]="17 97" + ["o"]="18 98" + ["p"]="19 99" + ["["]="1A 9A" + ["]"]="1B 9B" + ["ENTER"]="1C 9C" + ["CTRLprs"]="1D" + ["CTRLrls"]="9D" + ["a"]="1E 9E" + ["s"]="1F 9F" + ["d"]="20 A0" + ["f"]="21 A1" + ["g"]="22 A2" + ["h"]="23 A3" + ["j"]="24 A4" + ["k"]="25 A5" + ["l"]="26 A6" + [";"]="27 A7" + ["'"]="28 A8" + ['`']="29 A9" + ["LSHIFTprs"]="2A" + ["LSHIFTrls"]="AA" + ['\']="2B AB" + ["z"]="2C AC" + ["x"]="2D AD" + ["c"]="2E AE" + ["v"]="2F AF" + ["b"]="30 B0" + ["n"]="31 B1" + ["m"]="32 B2" + [","]="33 B3" + ["."]="34 B4" + ["/"]="35 B5" + ["RSHIFTprs"]="36" + ["RSHIFTrls"]="B6" + ["ALTprs"]="38" + ["ALTrls"]="B8" + ["LALT"]="38 B8" + ["SPACE"]="39 B9" + [" "]="39 B9" + ["CAPS"]="3A BA" + ["F1"]="3B BB" + ["F2"]="3C BC" + ["F3"]="3D BD" + ["F4"]="3E BE" + ["F5"]="3F BF" + ["F6"]="40 C0" + ["F7"]="41 C1" + ["F8"]="42 C2" + ["F9"]="43 C3" + ["F10"]="44 C4" + ["UP"]="E0 48 E0 C8" + ["RIGHT"]="E0 4D E0 CD" + ["LEFT"]="E0 4B E0 CB" + ["DOWN"]="E0 50 E0 D0" + ["HOME"]="E0 47 E0 C7" + ["END"]="E0 4F E0 CF" + ["PGUP"]="E0 49 E0 C9" + ["PGDN"]="E0 51 E0 D1" + ["CMDprs"]="E0 5C" + ["CMDrls"]="E0 DC" + # all codes below start with LSHIFTprs as commented in first item: + ["!"]="2A 02 82 AA" # LSHIFTprs 1prs 1rls LSHIFTrls + ["@"]="2A 03 83 AA" + ["#"]="2A 04 84 AA" + ["$"]="2A 05 85 AA" + ["%"]="2A 06 86 AA" + ["^"]="2A 07 87 AA" + ["&"]="2A 08 88 AA" + ["*"]="2A 09 89 AA" + ["("]="2A 0A 8A AA" + [")"]="2A 0B 8B AA" + ["_"]="2A 0C 8C AA" + ["+"]="2A 0D 8D AA" + ["Q"]="2A 10 90 AA" + ["W"]="2A 11 91 AA" + ["E"]="2A 12 92 AA" + ["R"]="2A 13 93 AA" + ["T"]="2A 14 94 AA" + ["Y"]="2A 15 95 AA" + ["U"]="2A 16 96 AA" + ["I"]="2A 17 97 AA" + ["O"]="2A 18 98 AA" + ["P"]="2A 19 99 AA" + ["{"]="2A 1A 9A AA" + ["}"]="2A 1B 9B AA" + ["A"]="2A 1E 9E AA" + ["S"]="2A 1F 9F AA" + ["D"]="2A 20 A0 AA" + ["F"]="2A 21 A1 AA" + ["G"]="2A 22 A2 AA" + ["H"]="2A 23 A3 AA" + ["J"]="2A 24 A4 AA" + ["K"]="2A 25 A5 AA" + ["L"]="2A 26 A6 AA" + [":"]="2A 27 A7 AA" + ['"']="2A 28 A8 AA" + ["~"]="2A 29 A9 AA" + ["|"]="2A 2B AB AA" + ["Z"]="2A 2C AC AA" + ["X"]="2A 2D AD AA" + ["C"]="2A 2E AE AA" + ["V"]="2A 2F AF AA" + ["B"]="2A 30 B0 AA" + ["N"]="2A 31 B1 AA" + ["M"]="2A 32 B2 AA" + ["<"]="2A 33 B3 AA" + [">"]="2A 34 B4 AA" + ["?"]="2A 35 B5 AA" +) + +# send-string-as-keyboard-keystrokes and send-special-key to virtual machine +function sendkeys() { + scancode=$(for (( i=0; i < ${#kbstring}; i++ )); + do c[i]=${kbstring:i:1}; echo -n ${ksc[${c[i]}]}" "; done) + scancode="${scancode}" + VBoxManage controlvm "${vmname}" keyboardputscancode ${scancode} +} + +function sendspecial() { + scancode="" + for keypress in ${kbspecial}; do + scancode="${scancode}${ksc[${keypress}]}"" " + done + VBoxManage controlvm "${vmname}" keyboardputscancode ${scancode} +}