diff --git a/src/define.sh b/src/define.sh index 5e439391..18845dfa 100644 --- a/src/define.sh +++ b/src/define.sh @@ -1058,6 +1058,20 @@ supportsUnattended() { return 0 } +supportsBootKey() { + + local id="$1" + + case "${id,,}" in + "win9"* | "winnt4" | "reactos" ) + return 1 ;; + "win"* | "tiny"* | "core"* ) + return 0 ;; + esac + + return 1 +} + supportsXML() { local id="$1" diff --git a/src/image.sh b/src/image.sh index 317c6ef6..aeeee954 100644 --- a/src/image.sh +++ b/src/image.sh @@ -1360,11 +1360,7 @@ detectIsoImage() { # Return 1 only when no directly inspectable WIM/ESD payload is available so # the caller may extract the media. Metadata parsing/configuration errors use 2. - image=$(findIsoImage "$iso") || { - rc=$? - enabled "$DEBUG" && echo "ISO image lookup failed (status $rc)." >&2 - return "$rc" - } + image=$(findIsoImage "$iso") || return $? header=$(readWimHeader "$iso" "$image") || { error "Failed to read the Windows image header!" diff --git a/src/legacy.sh b/src/legacy.sh index 43445809..b85bf32c 100644 --- a/src/legacy.sh +++ b/src/legacy.sh @@ -1,140 +1,6 @@ #!/usr/bin/env bash set -Eeuo pipefail -detectLegacy() { - - local dir="$1" - - local marker - - [[ "${PLATFORM,,}" == "x64" ]] || return 1 - - # Legacy media is identified from setup marker files rather than WIM - # metadata. The order is intentional because several releases share markers. - marker=$(find "$dir" -maxdepth 1 -type d -iname 'ia64' -print -quit) || return 2 - - if [ -n "$marker" ]; then - error "Windows IA-64 (Itanium) images are not supported by this container!" - return 2 - fi - - marker=$(find "$dir" -maxdepth 1 -type d -iname WIN95 -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="win95" - return 0 - fi - - marker=$(find "$dir" -maxdepth 1 -type d -iname WIN98 -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="win98" - return 0 - fi - - marker=$(find "$dir" -maxdepth 1 -type d -iname WIN9X -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="win9x" - return 0 - fi - - marker=$(find "$dir" -maxdepth 1 -type f \ - \( \ - -iname CDROM_W.40 -o \ - -iname CDROM_S.40 -o \ - -iname CDROM_TS.40 \ - \) \ - -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="winnt4" - return 0 - fi - - marker=$(find "$dir" -maxdepth 1 -type f -iname CDROM_NT.5 -print -quit) || return 2 - - if [ -n "$marker" ]; then - - marker=$(find "$dir" -maxdepth 1 -type f \ - \( \ - -iname CDROM_IA.5 -o \ - -iname CDROM_ID.5 -o \ - -iname CDROM_IP.5 -o \ - -iname CDROM_IS.5 \ - \) \ - -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="win2k" - return 0 - fi - - fi - - # WIN51 identifies the NT 5.1/5.2 media family; the companion marker then - # distinguishes XP x86, XP x64, and Server 2003. - marker=$(find "$dir" -maxdepth 1 -iname WIN51 -print -quit) || return 2 - [ -n "$marker" ] || return 1 - - marker=$(find "$dir" -maxdepth 1 -type f -iname WIN51AP -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="winxpx64" - return 0 - fi - - marker=$(find "$dir" -maxdepth 1 -type f \ - \( \ - -iname WIN51IC -o \ - -iname WIN51IP -o \ - -iname setupxp.htm \ - \) \ - -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="winxpx86" - return 0 - fi - - marker=$(find "$dir" -maxdepth 1 -type f \ - \( \ - -iname WIN51IS -o \ - -iname WIN51IA -o \ - -iname WIN51IB -o \ - -iname WIN51ID -o \ - -iname WIN51IL -o \ - -iname WIN51AA -o \ - -iname WIN51AD -o \ - -iname WIN51AS -o \ - -iname WIN51MA -o \ - -iname WIN51MD -o \ - -iname WIN51MP \ - \) \ - -print -quit) || return 2 - - if [ -n "$marker" ]; then - DETECTED="win2003r2" - return 0 - fi - - return 1 -} - -detectReactOS() { - - local dir="$1" - local marker - - marker=$(find "$dir" -maxdepth 2 -type f \ - \( -ipath '*/reactos/reactos.inf' -o -ipath '*/reactos/unattend.inf' \) -print -quit) || return 2 - - [ -n "$marker" ] || return 1 - - DETECTED="reactos" - return 0 -} - setMachine() { local id="$1" @@ -177,10 +43,10 @@ setMachine() { "win9"* | "winnt4" ) + writeState "old" "pc" || return 1 writeState "usb" "N" || return 1 writeState "net" "pcnet" || return 1 - writeState "type" "auto" || return 1 - writeState "old" "pc-i440fx-2.4" || return 1 ;; + writeState "type" "auto" || return 1 ;; "win2k"* ) @@ -253,6 +119,19 @@ restoreMachine() { MACHINE="" restoreState "MACHINE" "old" || return 1 + + # Migrate existing Win9x installs to QEMU 11 + if [[ "${MACHINE,,}" == "pc-i440fx-2.4" ]]; then + MACHINE="pc" + writeState "old" "$MACHINE" || return 1 + fi + + # Migrate existing WinXP installs to QEMU 10 + if [[ "${MACHINE,,}" == "pc-q35-2.10" ]]; then + MACHINE="" + rm -f -- "$(stateFile "old")" + fi + [ -z "$MACHINE" ] && MACHINE="q35" return 0 @@ -1118,4 +997,137 @@ validateLegacyEncoding() { return 0 } +detectReactOS() { + + local dir="$1" + local marker + + marker=$(find "$dir" -maxdepth 2 -type f \ + \( -ipath '*/reactos/reactos.inf' -o -ipath '*/reactos/unattend.inf' \) -print -quit) || return 2 + + [ -n "$marker" ] || return 1 + + DETECTED="reactos" + return 0 +} + +detectLegacy() { + + local dir="$1" + local marker + + [[ "${PLATFORM,,}" == "x64" ]] || return 1 + + # Legacy media is identified from setup marker files rather than WIM + # metadata. The order is intentional because several releases share markers. + marker=$(find "$dir" -maxdepth 1 -type d -iname 'ia64' -print -quit) || return 2 + + if [ -n "$marker" ]; then + error "Windows IA-64 (Itanium) images are not supported by this container!" + return 2 + fi + + marker=$(find "$dir" -maxdepth 1 -type d -iname WIN95 -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="win95" + return 0 + fi + + marker=$(find "$dir" -maxdepth 1 -type d -iname WIN98 -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="win98" + return 0 + fi + + marker=$(find "$dir" -maxdepth 1 -type d -iname WIN9X -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="win9x" + return 0 + fi + + marker=$(find "$dir" -maxdepth 1 -type f \ + \( \ + -iname CDROM_W.40 -o \ + -iname CDROM_S.40 -o \ + -iname CDROM_TS.40 \ + \) \ + -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="winnt4" + return 0 + fi + + marker=$(find "$dir" -maxdepth 1 -type f -iname CDROM_NT.5 -print -quit) || return 2 + + if [ -n "$marker" ]; then + + marker=$(find "$dir" -maxdepth 1 -type f \ + \( \ + -iname CDROM_IA.5 -o \ + -iname CDROM_ID.5 -o \ + -iname CDROM_IP.5 -o \ + -iname CDROM_IS.5 \ + \) \ + -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="win2k" + return 0 + fi + + fi + + # WIN51 identifies the NT 5.1/5.2 media family; the companion marker then + # distinguishes XP x86, XP x64, and Server 2003. + marker=$(find "$dir" -maxdepth 1 -iname WIN51 -print -quit) || return 2 + [ -n "$marker" ] || return 1 + + marker=$(find "$dir" -maxdepth 1 -type f -iname WIN51AP -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="winxpx64" + return 0 + fi + + marker=$(find "$dir" -maxdepth 1 -type f \ + \( \ + -iname WIN51IC -o \ + -iname WIN51IP -o \ + -iname setupxp.htm \ + \) \ + -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="winxpx86" + return 0 + fi + + marker=$(find "$dir" -maxdepth 1 -type f \ + \( \ + -iname WIN51IS -o \ + -iname WIN51IA -o \ + -iname WIN51IB -o \ + -iname WIN51ID -o \ + -iname WIN51IL -o \ + -iname WIN51AA -o \ + -iname WIN51AD -o \ + -iname WIN51AS -o \ + -iname WIN51MA -o \ + -iname WIN51MD -o \ + -iname WIN51MP \ + \) \ + -print -quit) || return 2 + + if [ -n "$marker" ]; then + DETECTED="win2003r2" + return 0 + fi + + return 1 +} + return 0 diff --git a/src/power.sh b/src/power.sh index 48a4e39b..89407c81 100644 --- a/src/power.sh +++ b/src/power.sh @@ -343,20 +343,14 @@ sendKey() { return 0 } -supportsBootKey() { - - local id="$1" - - [[ "${id,,}" == "win"* ]] -} - needsBootKey() { [ ! -s "$BOOT" ] && return 1 - [[ "${BOOT,,}" != *".iso" ]] && return 1 [ -f "$STORAGE/windows.boot" ] && return 1 supportsBootKey "$DETECTED" + + return $? } bootKeyReady() { @@ -423,8 +417,7 @@ finish() { local reason=$1 failed=0 - # QEMU_END distinguishes an expected shutdown path from an unexpected QEMU - # exit carrying the same process status. + # A nonzero exit is unexpected only when QEMU_END is missing. if [ ! -f "$QEMU_END" ] && (( reason != 0 )); then failed=1 fi