feat: Added editions and mirrors (#95)

This commit is contained in:
Kroese 2024-04-30 23:33:00 +02:00 committed by GitHub
parent 5768ae5c2a
commit 9d2f095054
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 431 additions and 172 deletions

View file

@ -1,5 +1,5 @@
FROM scratch
COPY --from=qemux/qemu-arm:1.15 / /
COPY --from=qemux/qemu-arm:1.16 / /
ARG DEBCONF_NOWARNINGS "yes"
ARG DEBIAN_FRONTEND "noninteractive"

View file

@ -80,10 +80,10 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
Select from the values below:
| **Value** | **Description** | **Platform** | **Source** | **Size** |
|---|---|---|---|---|
| `win11` | Windows 11 Pro | ARM64 | Microsoft | 4.6 GB |
| `win10` | Windows 10 Pro | ARM64 | Microsoft | 3.9 GB |
| **Value** | **Version** | **Platform** | **Size** |
|---|---|---|---|
| `win11` | Windows 11 Pro | ARM64 | 4.6 GB |
| `win10` | Windows 10 Pro | ARM64 | 3.9 GB |
To install x86 or x64 versions of Windows use [dockur/windows](https://github.com/dockur/windows/).

147
src/define.sh Normal file
View file

@ -0,0 +1,147 @@
#!/usr/bin/env bash
set -Eeuo pipefail
: "${MANUAL:=""}"
: "${VERSION:=""}"
: "${DETECTED:=""}"
: "${PLATFORM:="ARM64"}"
parseVersion() {
[ -z "$VERSION" ] && VERSION="win11"
if [[ "${VERSION}" == \"*\" || "${VERSION}" == \'*\' ]]; then
VERSION="${VERSION:1:-1}"
fi
case "${VERSION,,}" in
"11" | "win11" | "windows11" | "windows 11")
VERSION="win11${PLATFORM,,}"
;;
"10" | "win10" | "windows10" | "windows 10")
VERSION="win10${PLATFORM,,}"
;;
esac
return 0
}
printVersion() {
local id="$1"
local desc="$2"
[[ "$id" == "win10"* ]] && desc="Windows 10"
[[ "$id" == "win11"* ]] && desc="Windows 11"
[ -z "$desc" ] && desc="Windows"
echo "$desc for ${PLATFORM}"
return 0
}
getName() {
local file="$1"
local desc="$2"
[[ "${file,,}" == "win11"* ]] && desc="Windows 11"
[[ "${file,,}" == "win10"* ]] && desc="Windows 10"
[[ "${file,,}" == *"windows11"* ]] && desc="Windows 11"
[[ "${file,,}" == *"windows10"* ]] && desc="Windows 10"
[[ "${file,,}" == *"windows_11"* ]] && desc="Windows 11"
[[ "${file,,}" == *"windows_10"* ]] && desc="Windows 10"
[[ "${file,,}" == *"windows 11"* ]] && desc="Windows 11"
[[ "${file,,}" == *"windows 10"* ]] && desc="Windows 10"
[ -z "$desc" ] && desc="Windows"
echo "$desc for ${PLATFORM}"
return 0
}
getVersion() {
local name="$1"
local detected=""
[[ "${name,,}" == *"windows 11"* ]] && detected="win11${PLATFORM,,}"
[[ "${name,,}" == *"windows 10"* ]] && detected="win10${PLATFORM,,}"
echo "$detected"
return 0
}
isESD() {
local id="$1"
case "${id,,}" in
"win11${PLATFORM,,}")
return 0
;;
"win10${PLATFORM,,}")
return 0
;;
esac
return 1
}
getLink() {
# Fallbacks for users who cannot connect to the Microsoft servers
local id="$1"
local url=""
local host="https://dl.bobpony.com"
case "${id,,}" in
"win11${PLATFORM,,}")
url="$host/windows/11/en-us_windows_11_23h2_${PLATFORM,,}.iso"
;;
"win10${PLATFORM,,}")
url="$host/windows/10/en-us_windows_10_22h2_${PLATFORM,,}.iso"
;;
esac
echo "$url"
return 0
}
secondLink() {
# Fallbacks for users who cannot connect to the Microsoft servers
local id="$1"
local url=""
local host="https://drive.massgrave.dev"
case "${id,,}" in
"win11${PLATFORM,,}")
url="$host/SW_DVD9_Win_Pro_11_23H2.2_Arm64_English_Pro_Ent_EDU_N_MLF_X23-68023.ISO"
;;
"win10${PLATFORM,,}")
url="$host/SW_DVD9_Win_Pro_10_22H2.15_Arm64_English_Pro_Ent_EDU_N_MLF_X23-67223.ISO"
;;
esac
echo "$url"
return 0
}
validVersion() {
local id="$1"
local url
isESD "$id" && return 0
url=$(getLink "$id")
[ -n "$url" ] && return 0
url=$(secondLink "$id")
[ -n "$url" ] && return 0
return 1
}

View file

@ -9,6 +9,7 @@ SUPPORT="https://github.com/dockur/windows-arm"
cd /run
. reset.sh # Initialize system
. define.sh # Define versions
. install.sh # Run installation
. disk.sh # Initialize disks
. display.sh # Initialize graphics
@ -28,8 +29,8 @@ info "Booting ${APP}${BOOT_DESC}..."
(( rc != 0 )) && error "$(<"$QEMU_LOG")" && exit 15
terminal
( sleep 10; boot ) &
tail -fn +0 "$QEMU_LOG" 2>/dev/null &
( sleep 10; [ ! -f "$QEMU_END" ] && info "Windows started succesfully, visit http://localhost:8006/ to view the screen..." ) &
cat "$QEMU_TERM" 2> /dev/null | tee "$QEMU_PTY" &
wait $! || :

View file

@ -1,85 +1,13 @@
#!/usr/bin/env bash
set -Eeuo pipefail
: "${MANUAL:=""}"
: "${VERSION:=""}"
: "${DETECTED:=""}"
[ -z "$VERSION" ] && VERSION="win11arm64"
if [[ "${VERSION}" == \"*\" || "${VERSION}" == \'*\' ]]; then
VERSION="${VERSION:1:-1}"
fi
[[ "${VERSION,,}" == "11" ]] && VERSION="win11arm64"
[[ "${VERSION,,}" == "win11" ]] && VERSION="win11arm64"
[[ "${VERSION,,}" == "10" ]] && VERSION="win10arm64"
[[ "${VERSION,,}" == "win10" ]] && VERSION="win10arm64"
CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname windows.iso -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname boot.iso -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.img -printf "%f\n" | head -n 1)
if [ -z "$CUSTOM" ] && [[ "${VERSION,,}" != "http"* ]]; then
FN="${VERSION/\/storage\//}"
[[ "$FN" == "."* ]] && FN="${FN:1}"
CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname "$FN" -printf "%f\n" | head -n 1)
fi
ESD_URL=""
PLATFORM="ARM64"
TMP="$STORAGE/tmp"
DIR="$TMP/unpack"
FB="falling back to manual installation!"
ETFS="boot/etfsboot.com"
EFISYS="efi/microsoft/boot/efisys_noprompt.bin"
printVersion() {
local id="$1"
local desc="$2"
[[ "$id" == "win10"* ]] && desc="Windows 10 for ARM"
[[ "$id" == "win11"* ]] && desc="Windows 11 for ARM"
[ -z "$desc" ] && desc="Windows for ARM"
echo "$desc"
return 0
}
getName() {
local file="$1"
local desc="$2"
[[ "${file,,}" == "win11"* ]] && desc="Windows 11 for ARM"
[[ "${file,,}" == "win10"* ]] && desc="Windows 10 for ARM"
[[ "${file,,}" == *"windows11"* ]] && desc="Windows 11 for ARM"
[[ "${file,,}" == *"windows10"* ]] && desc="Windows 10 for ARM"
[[ "${file,,}" == *"windows_11"* ]] && desc="Windows 11 for ARM"
[[ "${file,,}" == *"windows_10"* ]] && desc="Windows 10 for ARM"
[ -z "$desc" ] && desc="Windows for ARM"
echo "$desc"
return 0
}
getVersion() {
local name="$1"
local detected=""
[[ "${name,,}" == *"windows 11"* ]] && detected="win11arm64"
[[ "${name,,}" == *"windows 10"* ]] && detected="win10arm64"
echo "$detected"
return 0
}
hasDisk() {
[ -b "${DEVICE:-}" ] && return 0
@ -106,19 +34,39 @@ finishInstall() {
local aborted="$2"
if [ ! -s "$iso" ] || [ ! -f "$iso" ]; then
error "Failed to find ISO: $iso" && return 1
error "Failed to find ISO file: $iso" && return 1
fi
if [ -w "$iso" ] && [[ "$aborted" != [Yy1]* ]]; then
# Mark ISO as prepared via magic byte
if ! printf '\x16' | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then
error "Failed to set magic byte!" && return 1
error "Failed to set magic byte in ISO file: $iso" && return 1
fi
fi
rm -f "$STORAGE/windows.boot"
cp /run/version "$STORAGE/windows.ver"
rm -f "$STORAGE/windows.ver"
rm -f "$STORAGE/windows.old"
rm -f "$STORAGE/windows.boot"
rm -f "$STORAGE/windows.mode"
cp /run/version "$STORAGE/windows.ver"
if [[ "${PLATFORM,,}" == "x64" ]]; then
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
if [[ "${MACHINE,,}" != "q35" ]]; then
echo "$MACHINE" > "$STORAGE/windows.old"
fi
else
# Enable secure boot + TPM on manual installs as Win11 requires
if [[ "$MANUAL" == [Yy1]* ]] || [[ "$aborted" == [Yy1]* ]]; then
if [[ "${DETECTED,,}" == "win11"* ]]; then
BOOT_MODE="windows_secure"
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
fi
fi
fi
fi
rm -rf "$TMP"
return 0
@ -130,7 +78,7 @@ abortInstall() {
if [[ "$iso" != "$STORAGE/$BASE" ]]; then
if ! mv -f "$iso" "$STORAGE/$BASE"; then
error "Failed to move ISO: $iso" && return 1
error "Failed to move ISO file: $iso" && return 1
fi
fi
@ -154,18 +102,14 @@ startInstall() {
CUSTOM=""
if [[ "${VERSION,,}" == "http"* ]]; then
EXTERNAL="Y"
else
if [[ "${VERSION,,}" != "http"* ]]; then
EXTERNAL="N"
fi
if [[ "$EXTERNAL" != [Yy1]* ]]; then
BASE="$VERSION.iso"
else
EXTERNAL="Y"
BASE=$(basename "${VERSION%%\?*}")
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
@ -173,9 +117,13 @@ startInstall() {
fi
fi
if [[ "${PLATFORM,,}" == "x64" ]]; then
! migrateFiles "$BASE" "$VERSION" && error "Migration failed!" && exit 57
fi
if skipInstall; then
[ ! -f "$STORAGE/$BASE" ] && BASE=""
VGA="virtio-gpu"
[[ "${PLATFORM,,}" == "arm64" ]] && VGA="virtio-gpu"
return 1
fi
@ -204,11 +152,7 @@ startInstall() {
if [ ! -f "$STORAGE/$CUSTOM" ]; then
CUSTOM=""
if [[ "$EXTERNAL" == [Yy1]* ]]; then
ISO="$TMP/$BASE"
else
ISO="$TMP/$VERSION.esd"
fi
else
ISO="$STORAGE/$CUSTOM"
fi
@ -216,12 +160,29 @@ startInstall() {
return 0
}
detectCustom() {
CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname windows.iso -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname boot.iso -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.img -printf "%f\n" | head -n 1)
if [ -z "$CUSTOM" ] && [[ "${VERSION,,}" != "http"* ]]; then
FN="${VERSION/\/storage\//}"
[[ "$FN" == "."* ]] && FN="${FN:1}"
CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname "$FN" -printf "%f\n" | head -n 1)
fi
return 0
}
getESD() {
local dir="$1"
local version="$2"
local winCatalog size
case "${VERSION,,}" in
case "${version,,}" in
"win11${PLATFORM,,}")
winCatalog="https://go.microsoft.com/fwlink?linkid=2156292"
;;
@ -229,7 +190,7 @@ getESD() {
winCatalog="https://go.microsoft.com/fwlink/?LinkId=841361"
;;
*)
error "Invalid version specified: $VERSION" && return 1
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
;;
esac
@ -240,41 +201,44 @@ getESD() {
mkdir -p "$dir"
local wFile="catalog.cab"
local xFile="products.xml"
local eFile="esd_edition.xml"
local fFile="products_filter.xml"
{ wget "$winCatalog" -O "$dir/$wFile" -q --no-check-certificate; rc=$?; } || :
{ wget "$winCatalog" -O "$dir/$wFile" -q; rc=$?; } || :
(( rc != 0 )) && error "Failed to download $winCatalog , reason: $rc" && return 1
cd "$dir"
if ! cabextract "$wFile" > /dev/null; then
cd /run
error "Failed to extract CAB file!" && return 1
error "Failed to extract $wFile!" && return 1
fi
cd /run
if [ ! -s "$dir/products.xml" ]; then
error "Failed to find products.xml!" && return 1
if [ ! -s "$dir/$xFile" ]; then
error "Failed to find $xFile in $wFile!" && return 1
fi
local esdLang="en-us"
local editionName="Professional"
local edQuery='//File[Architecture="'${PLATFORM}'"][Edition="'${editionName}'"]'
echo -e '<Catalog>' > "${dir}/products_filter.xml"
xmllint --nonet --xpath "${edQuery}" "${dir}/products.xml" >> "${dir}/products_filter.xml" 2>/dev/null
echo -e '</Catalog>'>> "${dir}/products_filter.xml"
xmllint --nonet --xpath '//File[LanguageCode="'${esdLang}'"]' "${dir}/products_filter.xml" >"${dir}/esd_edition.xml"
echo -e '<Catalog>' > "$dir/$fFile"
xmllint --nonet --xpath "${edQuery}" "$dir/$xFile" >> "$dir/$fFile" 2>/dev/null
echo -e '</Catalog>'>> "$dir/$fFile"
xmllint --nonet --xpath '//File[LanguageCode="'${esdLang}'"]' "$dir/$fFile" >"$dir/$eFile"
size=$(stat -c%s "${dir}/esd_edition.xml")
size=$(stat -c%s "$dir/$eFile")
if ((size<20)); then
error "Failed to find Windows product!" && return 1
error "Failed to find Windows product in $eFile!" && return 1
fi
ESD_URL=$(xmllint --nonet --xpath '//FilePath' "${dir}/esd_edition.xml" | sed -E -e 's/<[\/]?FilePath>//g')
ESD_URL=$(xmllint --nonet --xpath '//FilePath' "$dir/$eFile" | sed -E -e 's/<[\/]?FilePath>//g')
if [ -z "$ESD_URL" ]; then
error "Failed to find ESD URL!" && return 1
error "Failed to find ESD URL in $eFile!" && return 1
fi
rm -rf "$dir"
@ -286,7 +250,7 @@ downloadFile() {
local iso="$1"
local url="$2"
local desc="$3"
local rc progress
local rc progress domain
rm -f "$iso"
@ -298,10 +262,15 @@ downloadFile() {
fi
local msg="Downloading $desc..."
domain=$(echo "$url" | awk -F/ '{print $3}')
domain=$(expr "$domain" : '.*\.\(.*\..*\)')
[[ "${domain,,}" != *"microsoft.com" ]] && msg="Downloading $desc from $domain..."
info "$msg" && html "$msg"
/run/progress.sh "$iso" "Downloading $desc ([P])..." &
{ wget "$url" -O "$iso" -q --no-check-certificate --show-progress "$progress"; rc=$?; } || :
{ wget "$url" -O "$iso" -q --show-progress "$progress"; rc=$?; } || :
fKill "progress.sh"
@ -320,57 +289,78 @@ downloadFile() {
downloadImage() {
local iso="$1"
local url="$2"
local rc desc
local version="$2"
local tried="n"
local url desc
if [[ "$EXTERNAL" != [Yy1]* ]]; then
desc=$(printVersion "$VERSION" "Windows for ARM")
else
if [[ "${version,,}" == "http"* ]]; then
desc=$(getName "$BASE" "$BASE")
downloadFile "$iso" "$version" "$desc" && return 0
return 1
fi
if [[ "$EXTERNAL" != [Yy1]* ]]; then
if ! validVersion "$version"; then
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
fi
if ! getESD "$TMP/esd"; then
url=""
if [[ "${PLATFORM,,}" == "x64" ]]; then
desc=$(printVersion "$version" "Windows")
else
url="$ESD_URL"
desc=$(printVersion "$version" "Windows for ${PLATFORM}")
fi
if [[ "${PLATFORM,,}" == "x64" ]]; then
if isMido "$version"; then
tried="y"
doMido "$iso" "$version" "$desc" && return 0
fi
switchEdition "$version"
fi
if isESD "$version"; then
if [[ "$tried" != "n" ]]; then
info "Failed to download $desc using Mido, will try a diferent method now..."
fi
tried="y"
if getESD "$TMP/esd" "$version"; then
ISO="$TMP/$version.esd"
downloadFile "$ISO" "$ESD_URL" "$desc" && return 0
ISO="$TMP/$BASE"
fi
fi
url=$(getLink "$version")
if [ -n "$url" ]; then
downloadFile "$iso" "$url" "$desc" && return 0
if [[ "$tried" != "n" ]]; then
info "Failed to download $desc from Microsoft, will try another mirror now..."
fi
[[ "$EXTERNAL" == [Yy1]* ]] && return 1
case "${VERSION,,}" in
"win11${PLATFORM,,}")
url="https://dl.bobpony.com/windows/11/en-us_windows_11_23h2_${PLATFORM,,}.iso"
;;
"win10${PLATFORM,,}")
url="https://dl.bobpony.com/windows/10/en-us_windows_10_22h2_${PLATFORM,,}.iso"
;;
*)
return 1
;;
esac
info "Failed to download $desc from Microsoft, will try another mirror now..."
rm -rf "$TMP"
mkdir -p "$TMP"
ISO="$TMP/$BASE"
iso="$ISO"
tried="y"
downloadFile "$iso" "$url" "$desc" && return 0
fi
url=$(secondLink "$version")
if [ -n "$url" ]; then
if [[ "$tried" != "n" ]]; then
info "Failed to download $desc, will try another mirror now..."
fi
tried="y"
downloadFile "$iso" "$url" "$desc" && return 0
fi
return 1
}
@ -378,9 +368,10 @@ extractESD() {
local iso="$1"
local dir="$2"
local version="$3"
local desc="$4"
local size size_gb space space_gb desc
desc=$(printVersion "$VERSION" "Windows for ARM")
local msg="Extracting $desc bootdisk..."
info "$msg" && html "$msg"
@ -405,7 +396,7 @@ extractESD() {
wimlib-imagex apply "$iso" 1 "${dir}" --quiet 2>/dev/null || {
retVal=$?
error "Extracting bootdisk failed" && return $retVal
error "Extracting $desc bootdisk failed" && return $retVal
}
local bootWimFile="${dir}/sources/boot.wim"
@ -432,7 +423,7 @@ extractESD() {
local edition imageIndex imageEdition
case "${VERSION,,}" in
case "${version,,}" in
"win11${PLATFORM,,}")
edition="11 pro"
;;
@ -440,7 +431,7 @@ extractESD() {
edition="10 pro"
;;
*)
error "Invalid version specified: $VERSION" && return 1
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
;;
esac
@ -449,7 +440,7 @@ extractESD() {
[[ "${imageEdition,,}" != *"$edition"* ]] && continue
wimlib-imagex export "${iso}" ${imageIndex} "${installWimFile}" --compress=LZMS --chunk-size 128K --quiet || {
retVal=$?
error "Addition of ${imageIndex} to the image failed" && return $retVal
error "Addition of ${imageIndex} to the $desc image failed" && return $retVal
}
return 0
done
@ -461,16 +452,17 @@ extractImage() {
local iso="$1"
local dir="$2"
local version="$3"
local desc="downloaded ISO"
local size size_gb space space_gb
if [[ "${iso,,}" == *".esd" ]]; then
extractESD "$iso" "$dir" && return 0
return 1
if [[ "$EXTERNAL" != [Yy1]* ]] && [ -z "$CUSTOM" ]; then
desc=$(printVersion "$version" "downloaded ISO")
fi
if [[ "$EXTERNAL" != [Yy1]* ]] && [ -z "$CUSTOM" ]; then
desc=$(printVersion "$VERSION" "downloaded ISO")
if [[ "${iso,,}" == *".esd" ]]; then
extractESD "$iso" "$dir" "$version" "$desc" && return 0
return 1
fi
local msg="Extracting $desc image..."
@ -505,6 +497,7 @@ extractImage() {
detectImage() {
XML=""
local dsc
local dir="$1"
if [ -n "$CUSTOM" ]; then
@ -524,10 +517,9 @@ detectImage() {
if [[ "${DETECTED,,}" != "winxp"* ]]; then
local dsc
dsc=$(printVersion "$DETECTED" "$DETECTED")
warn "got $dsc, but no matching XML file exists, $FB."
warn "got $dsc, but no matching file called $DETECTED.xml exists, $FB."
fi
return 0
@ -535,10 +527,24 @@ detectImage() {
info "Detecting Windows version from ISO image..."
if [[ "${PLATFORM,,}" == "x64" ]]; then
if [ -f "$dir/WIN51" ] || [ -f "$dir/SETUPXP.HTM" ]; then
if [ -d "$dir/AMD64" ]; then
DETECTED="winxpx64"
else
DETECTED="winxpx86"
fi
dsc=$(printVersion "$DETECTED" "$DETECTED")
info "Detected: $dsc"
return 0
fi
fi
local src loc tag result name name2 desc
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
if [ ! -d "$src" ]; then
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
warn "failed to locate 'sources' folder in ISO image, $FB" && return 1
fi
@ -546,6 +552,7 @@ detectImage() {
[ ! -f "$loc" ] && loc=$(find "$src" -maxdepth 1 -type f -iname install.esd | head -n 1)
if [ ! -f "$loc" ]; then
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" && return 1
fi
@ -573,7 +580,7 @@ detectImage() {
[[ "$MANUAL" != [Yy1]* ]] && XML="$DETECTED.xml"
info "Detected: $desc"
else
warn "detected $desc, but no matching XML file exists, $FB."
warn "detected $desc, but no matching file called $DETECTED.xml exists, $FB."
fi
return 0
@ -584,17 +591,37 @@ prepareImage() {
local iso="$1"
local dir="$2"
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
if [[ "${DETECTED,,}" != "winxp"* ]] && [[ "${DETECTED,,}" != "win2008"* ]]; then
if [[ "${DETECTED,,}" != "winvista"* ]] && [[ "${DETECTED,,}" != "win7"* ]]; then
if [ -f "$dir/$ETFS" ] && [ -f "$dir/$EFISYS" ]; then
return 0
fi
if [ ! -f "$dir/$ETFS" ]; then
warn "failed to locate file 'etfsboot.com' in ISO image!"
warn "failed to locate file 'etfsboot.com' in ISO image, falling back to legacy boot!"
else
warn "failed to locate file 'efisys_noprompt.bin' in ISO image!"
warn "failed to locate file 'efisys_noprompt.bin' in ISO image, falling back to legacy boot!"
fi
return 1
fi
fi
fi
[[ "${PLATFORM,,}" == "arm64" ]] && return 1
if [[ "${DETECTED,,}" == "winxp"* ]]; then
if ! prepareXP "$iso" "$dir"; then
error "Failed to prepare Windows XP ISO!" && return 1
fi
else
if ! prepareLegacy "$iso" "$dir"; then
error "Failed to prepare Windows ISO!" && return 1
fi
fi
return 0
}
updateImage() {
@ -602,7 +629,7 @@ updateImage() {
local iso="$1"
local dir="$2"
local asset="/run/assets/$3"
local path src loc index result
local path src loc xml index result
[ ! -s "$asset" ] || [ ! -f "$asset" ] && return 0
@ -612,6 +639,7 @@ updateImage() {
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
if [ ! -d "$src" ]; then
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
warn "failed to locate 'sources' folder in ISO image, $FB" && return 1
fi
@ -619,10 +647,12 @@ updateImage() {
[ ! -f "$loc" ] && loc=$(find "$src" -maxdepth 1 -type f -iname boot.esd | head -n 1)
if [ ! -f "$loc" ]; then
[[ "${PLATFORM,,}" == "x64" ]] && BOOT_MODE="windows_legacy"
warn "failed to locate 'boot.wim' or 'boot.esd' in ISO image, $FB" && return 1
fi
info "Adding XML file for automatic installation..."
xml=$(basename "$asset")
info "Adding $xml for automatic installation..."
index="1"
result=$(wimlib-imagex info -xml "$loc" | tr -d '\000')
@ -632,7 +662,7 @@ updateImage() {
fi
if ! wimlib-imagex update "$loc" "$index" --command "add $asset /autounattend.xml" > /dev/null; then
warn "failed to add XML to ISO image, $FB" && return 1
warn "failed to add $xml to ISO image, $FB" && return 1
fi
return 0
@ -670,6 +700,7 @@ copyOEM() {
buildImage() {
local dir="$1"
local failed="N"
local cat="BOOT.CAT"
local label="${BASE%.*}"
local log="/run/shm/iso.log"
@ -693,8 +724,33 @@ buildImage() {
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
fi
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -c "$cat" -iso-level 4 -J -l -D -N -joliet-long -relaxed-filenames -V "$label" \
-udf -boot-info-table -eltorito-alt-boot -eltorito-boot "$EFISYS" -no-emul-boot -allow-limited-size -quiet "$dir" 2> "$log"; then
failed="Y"
fi
else
if [[ "${DETECTED,,}" != "winxp"* ]]; then
if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -c "$cat" -iso-level 2 -J -l -D -N -joliet-long -relaxed-filenames -V "$label" \
-udf -allow-limited-size -quiet "$dir" 2> "$log"; then
failed="Y"
fi
else
if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -boot-load-seg 1984 -boot-load-size 4 -c "$cat" -iso-level 2 -J -l -D -N -joliet-long \
-relaxed-filenames -V "$label" -quiet "$dir" 2> "$log"; then
failed="Y"
fi
fi
fi
if [[ "$failed" != "N" ]]; then
[ -s "$log" ] && echo "$(<"$log")"
error "Failed to build image!" && return 1
fi
@ -715,18 +771,58 @@ buildImage() {
bootWindows() {
rm -rf "$TMP"
if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
BOOT_MODE=$(<"$STORAGE/windows.mode")
rm -rf "$TMP"
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
[[ "${PLATFORM,,}" == "x64" ]] && MACHINE=$(<"$STORAGE/windows.old")
fi
return 0
fi
rm -rf "$TMP"
# Migrations
[[ "${PLATFORM,,}" != "x64" ]] && return 0
if [ -f "$STORAGE/windows.old" ]; then
MACHINE=$(<"$STORAGE/windows.old")
[ -z "$MACHINE" ] && MACHINE="q35"
BOOT_MODE="windows_legacy"
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
return 0
fi
local creation="1.10"
local minimal="2.14"
if [ -f "$STORAGE/windows.ver" ]; then
creation=$(<"$STORAGE/windows.ver")
[[ "${creation}" != *"."* ]] && creation="$minimal"
fi
# Force secure boot on installs created prior to v2.14
if (( $(echo "$creation < $minimal" | bc -l) )); then
if [[ "${BOOT_MODE,,}" == "windows" ]]; then
BOOT_MODE="windows_secure"
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
if [ -f "$STORAGE/windows.rom" ] && [ ! -f "$STORAGE/$BOOT_MODE.rom" ]; then
mv "$STORAGE/windows.rom" "$STORAGE/$BOOT_MODE.rom"
fi
if [ -f "$STORAGE/windows.vars" ] && [ ! -f "$STORAGE/$BOOT_MODE.vars" ]; then
mv "$STORAGE/windows.vars" "$STORAGE/$BOOT_MODE.vars"
fi
fi
fi
return 0
}
######################################
! parseVersion && exit 58
! detectCustom && exit 59
if ! startInstall; then
bootWindows && return 0
exit 68
@ -734,13 +830,13 @@ fi
if [ ! -s "$ISO" ] || [ ! -f "$ISO" ]; then
if ! downloadImage "$ISO" "$VERSION"; then
rm -f "$ISO"
rm -f "$ISO" 2> /dev/null || true
exit 61
fi
fi
if ! extractImage "$ISO" "$DIR"; then
rm -f "$ISO"
if ! extractImage "$ISO" "$DIR" "$VERSION"; then
rm -f "$ISO" 2> /dev/null || true
exit 62
fi

View file

@ -23,6 +23,21 @@ _trap() {
done
}
boot() {
[ -f "$QEMU_END" ] && return 0
if [ -s "$QEMU_PTY" ]; then
if grep -iq " hard" "$QEMU_PTY"; then
info "Windows started succesfully, visit http://localhost:8006/ to view the screen..."
return 0
fi
fi
error "Timeout while waiting for QEMU to boot the machine!"
return 0
}
ready() {
[ -f "$STORAGE/windows.boot" ] && return 0