mirror of
https://github.com/dockur/windows.git
synced 2026-08-24 15:48:59 +01:00
fix: Do not fail if marker cannot be created (#2117)
This commit is contained in:
+83
-73
@@ -133,16 +133,10 @@ hasAnswerFile() {
|
||||
fi
|
||||
|
||||
# Editions without a dedicated template can use the generic template.
|
||||
case "${id,,}" in
|
||||
file="/run/assets/${id%%-*}.xml"
|
||||
[ -s "$file" ] || return 1
|
||||
|
||||
"win7"* | "win8"* | "win10"* | "win11"* | "winvista"* | "win20"* )
|
||||
|
||||
file="/run/assets/${id%%-*}.xml"
|
||||
[ -s "$file" ] && return 0 ;;
|
||||
|
||||
esac
|
||||
|
||||
return 1
|
||||
return 0
|
||||
}
|
||||
|
||||
addAnswerFile() {
|
||||
@@ -444,22 +438,25 @@ generateFallbackXML() {
|
||||
updateUserXML() {
|
||||
|
||||
local asset="$1"
|
||||
|
||||
local setup="$XML_COMPONENT_SETUP"
|
||||
local specialize="$XML_COMPONENT_SHELL_SPECIALIZE"
|
||||
local oobe="$XML_COMPONENT_SHELL_OOBE"
|
||||
local app="$APP for $ENGINE"
|
||||
|
||||
local xpath
|
||||
xpath="$XML_COMPONENT_SETUP/u:UserData/u:Organization"
|
||||
xpath+=" | $XML_COMPONENT_SHELL_SPECIALIZE/u:OEMInformation/u:Model"
|
||||
xpath+=" | $XML_COMPONENT_SHELL_SPECIALIZE/u:OEMName"
|
||||
xpath+=" | $XML_COMPONENT_SHELL_SPECIALIZE/u:RegisteredOwner"
|
||||
xpath+=" | $XML_COMPONENT_SHELL_OOBE/u:RegisteredOwner"
|
||||
|
||||
local -a args=(
|
||||
-L
|
||||
-N "$XML_NS_UNATTEND_ARG"
|
||||
-u "$setup/u:UserData/u:Organization | $specialize/u:OEMInformation/u:Model | $specialize/u:OEMName | $specialize/u:RegisteredOwner | $oobe/u:RegisteredOwner" -v "$app"
|
||||
-u "$oobe/u:Display/u:VerticalResolution" -v "$HEIGHT"
|
||||
-u "$oobe/u:Display/u:HorizontalResolution" -v "$WIDTH"
|
||||
-u "$xpath" -v "$app"
|
||||
-u "$XML_COMPONENT_SHELL_OOBE/u:Display/u:VerticalResolution" -v "$HEIGHT"
|
||||
-u "$XML_COMPONENT_SHELL_OOBE/u:Display/u:HorizontalResolution" -v "$WIDTH"
|
||||
)
|
||||
|
||||
if [ -n "${HOST:-}" ]; then
|
||||
args+=(-u "$specialize/u:ComputerName" -v "$HOST")
|
||||
args+=(-u "$XML_COMPONENT_SHELL_SPECIALIZE/u:ComputerName" -v "$HOST")
|
||||
fi
|
||||
|
||||
xmlstarlet ed "${args[@]}" "$asset" || return 1
|
||||
@@ -537,23 +534,27 @@ updateWorkgroup() {
|
||||
|
||||
local asset="$1"
|
||||
local workgroup="$2"
|
||||
|
||||
local component="$XML_COMPONENT_UNATTENDED_JOIN"
|
||||
local identification="$component/u:Identification"
|
||||
local join="$identification/*[local-name()='JoinWorkgroup']"
|
||||
local arch tmp
|
||||
local arch tmp xpath
|
||||
|
||||
arch=$(getXMLArchitecture "$asset") || return 1
|
||||
|
||||
# Apply all membership changes to a copy and publish it only after the old
|
||||
# domain, credential, OU, and workgroup nodes have been replaced successfully.
|
||||
tmp=$(copyXMLAsset "$asset") || return 1
|
||||
|
||||
xpath="$XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:Credentials"
|
||||
xpath+=" | $XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:JoinDomain"
|
||||
xpath+=" | $XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:JoinWorkgroup"
|
||||
xpath+=" | $XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:MachineObjectOU"
|
||||
|
||||
if ! ensureUnattendedJoin "$tmp" "$arch" ||
|
||||
! xmlstarlet ed -L \
|
||||
-N "$XML_NS_UNATTEND_ARG" \
|
||||
-d "$identification/u:Credentials | $identification/u:JoinDomain | $identification/u:JoinWorkgroup | $identification/u:MachineObjectOU" \
|
||||
-s "$identification" -t elem -n 'JoinWorkgroup' "$tmp" ||
|
||||
! xmlstarlet ed -L -N "$XML_NS_UNATTEND_ARG" -u "$join" -v "$workgroup" "$tmp" ||
|
||||
-d "$xpath" \
|
||||
-s "$XML_COMPONENT_UNATTENDED_JOIN/u:Identification" -t elem -n 'JoinWorkgroup' "$tmp" ||
|
||||
! xmlstarlet ed -L \
|
||||
-N "$XML_NS_UNATTEND_ARG" \
|
||||
-u "$XML_COMPONENT_UNATTENDED_JOIN/u:Identification/*[local-name()='JoinWorkgroup']" -v "$workgroup" "$tmp" ||
|
||||
! replaceXMLAsset "$asset" "$tmp"; then
|
||||
|
||||
rm -f "$tmp"
|
||||
@@ -575,6 +576,7 @@ updateDomain() {
|
||||
local arch tmp
|
||||
|
||||
arch=$(getXMLArchitecture "$asset") || return 1
|
||||
|
||||
# Account and join settings are separate XML transformations, so update a
|
||||
# copy to keep the original answer file intact if either transformation fails.
|
||||
tmp=$(copyXMLAsset "$asset") || return 1
|
||||
@@ -602,7 +604,8 @@ configureDomainAccounts() {
|
||||
local administrator="$accounts/u:AdministratorPassword"
|
||||
local autologon="$shell/u:AutoLogon"
|
||||
local domain_accounts="$accounts/u:DomainAccounts"
|
||||
local counts shell_count accounts_count administrator_count autologon_count child_count
|
||||
local counts shell_count administrator_count
|
||||
local accounts_count autologon_count child_count
|
||||
|
||||
counts=$(xmlstarlet sel \
|
||||
-N "$XML_NS_UNATTEND_ARG" \
|
||||
@@ -694,15 +697,19 @@ configureDomainJoin() {
|
||||
local arch="$6"
|
||||
|
||||
local cred_domain="$domain"
|
||||
local component="$XML_COMPONENT_UNATTENDED_JOIN"
|
||||
local identification="$component/u:Identification"
|
||||
local credentials="$identification/*[local-name()='Credentials']"
|
||||
local credentials="$XML_COMPONENT_UNATTENDED_JOIN/u:Identification/*[local-name()='Credentials']"
|
||||
|
||||
local xpath
|
||||
xpath="$XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:Credentials"
|
||||
xpath+=" | $XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:JoinDomain"
|
||||
xpath+=" | $XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:JoinWorkgroup"
|
||||
xpath+=" | $XML_COMPONENT_UNATTENDED_JOIN/u:Identification/u:MachineObjectOU"
|
||||
|
||||
local -a args=(
|
||||
-L
|
||||
-N "$XML_NS_UNATTEND_ARG"
|
||||
-d "$identification/u:Credentials | $identification/u:JoinDomain | $identification/u:JoinWorkgroup | $identification/u:MachineObjectOU"
|
||||
-s "$identification" -t elem -n 'Credentials'
|
||||
-d "$xpath"
|
||||
-s "$XML_COMPONENT_UNATTENDED_JOIN/u:Identification" -t elem -n 'Credentials'
|
||||
)
|
||||
|
||||
ensureUnattendedJoin "$asset" "$arch" || return 1
|
||||
@@ -720,11 +727,11 @@ configureDomainJoin() {
|
||||
args+=(
|
||||
-s "$credentials" -t elem -n 'Username'
|
||||
-s "$credentials" -t elem -n 'Password'
|
||||
-s "$identification" -t elem -n 'JoinDomain'
|
||||
-s "$XML_COMPONENT_UNATTENDED_JOIN/u:Identification" -t elem -n 'JoinDomain'
|
||||
)
|
||||
|
||||
if [ -n "$ou" ]; then
|
||||
args+=(-s "$identification" -t elem -n 'MachineObjectOU')
|
||||
args+=(-s "$XML_COMPONENT_UNATTENDED_JOIN/u:Identification" -t elem -n 'MachineObjectOU')
|
||||
fi
|
||||
|
||||
xmlstarlet ed "${args[@]}" "$asset" || return 1
|
||||
@@ -734,7 +741,7 @@ configureDomainJoin() {
|
||||
-N "$XML_NS_UNATTEND_ARG"
|
||||
-u "$credentials/*[local-name()='Username']" -v "$auth"
|
||||
-u "$credentials/*[local-name()='Password']" -v "$pass"
|
||||
-u "$identification/*[local-name()='JoinDomain']" -v "$domain"
|
||||
-u "$XML_COMPONENT_UNATTENDED_JOIN/u:Identification/*[local-name()='JoinDomain']" -v "$domain"
|
||||
)
|
||||
|
||||
if [ -n "$cred_domain" ]; then
|
||||
@@ -742,7 +749,7 @@ configureDomainJoin() {
|
||||
fi
|
||||
|
||||
if [ -n "$ou" ]; then
|
||||
values+=(-u "$identification/*[local-name()='MachineObjectOU']" -v "$ou")
|
||||
values+=(-u "$XML_COMPONENT_UNATTENDED_JOIN/u:Identification/*[local-name()='MachineObjectOU']" -v "$ou")
|
||||
fi
|
||||
|
||||
xmlstarlet ed "${values[@]}" "$asset" || return 1
|
||||
@@ -761,10 +768,9 @@ findPrimaryLocalAccount() {
|
||||
local auto_primary=0 auto_matches=0
|
||||
local admin_primary=0 admin_matches=0
|
||||
local selected=0 separator=$'\x1f'
|
||||
|
||||
local -a groups=()
|
||||
local counts records auto_user selected_user position name group
|
||||
local shell_count local_count found_admin found_autologon token
|
||||
local -a groups=()
|
||||
|
||||
counts=$(xmlstarlet sel \
|
||||
-N "$XML_NS_UNATTEND_ARG" \
|
||||
@@ -869,6 +875,7 @@ updateLocalAccount() {
|
||||
result=$(findPrimaryLocalAccount "$asset") || return 1
|
||||
mapfile -t values <<< "$result"
|
||||
(( ${#values[@]} == 4 )) || return 1
|
||||
|
||||
primary="${values[0]}"
|
||||
current_user="${values[1]}"
|
||||
admin_count="${values[2]}"
|
||||
@@ -991,9 +998,9 @@ updateEditionXML() {
|
||||
|
||||
local asset="$1"
|
||||
|
||||
local setup="$XML_COMPONENT_SETUP"
|
||||
local upper='ABCDEFGHIJKLMNOPQRSTUVWXYZ'
|
||||
local lower='abcdefghijklmnopqrstuvwxyz'
|
||||
local setup="$XML_COMPONENT_SETUP"
|
||||
local selector="$setup/u:ImageInstall/u:OSImage/u:InstallFrom/u:MetaData[translate(normalize-space(u:Key), '$lower', '$upper')='/IMAGE/NAME']/u:Value"
|
||||
local edition count records position value replacement
|
||||
local separator=$'\x1f'
|
||||
@@ -1014,17 +1021,18 @@ updateEditionXML() {
|
||||
-N "$XML_NS_UNATTEND_ARG" -T -t -m "$selector" -v 'position()' -o "$separator" -v 'string(.)' -n "$asset") || return 1
|
||||
|
||||
while IFS="$separator" read -r position value; do
|
||||
|
||||
[ -n "$position" ] || continue
|
||||
|
||||
# Only Windows Server templates use EDITION as a mutable answer-file
|
||||
# selector. Products such as Hyper-V Server have fixed SERVER* flags that
|
||||
# must not be rewritten.
|
||||
# Only Windows Server templates use EDITION as a mutable answer-file selector.
|
||||
# Products such as Hyper-V Server have fixed SERVER* flags that must not be rewritten.
|
||||
[[ "${value,,}" == *"windows server"* ]] || continue
|
||||
[[ "$value" =~ ^(.*[[:space:]])SERVER[A-Za-z0-9_-]+[[:space:]]*$ ]] || continue
|
||||
|
||||
replacement="${BASH_REMATCH[1]}SERVER$edition"
|
||||
|
||||
xmlstarlet ed -L -N "$XML_NS_UNATTEND_ARG" -u "($selector)[$position]" -v "$replacement" "$asset" || return 1
|
||||
|
||||
done <<< "$records"
|
||||
|
||||
return 0
|
||||
@@ -1169,29 +1177,30 @@ setConfigurationXML() {
|
||||
return 1
|
||||
}
|
||||
|
||||
if [ "$config_count" = "0" ] &&
|
||||
! ensureXMLDefaultNamespace "$tmp"; then
|
||||
local msg="Failed to enable the Windows configuration set!"
|
||||
|
||||
if [ "$config_count" = "0" ] && ! ensureXMLDefaultNamespace "$tmp"; then
|
||||
rm -f "$tmp"
|
||||
error "$msg (1)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [ "$config_count" = "1" ]; then
|
||||
xmlstarlet ed -L -N "$XML_NS_UNATTEND_ARG" -u "$config" -v "true" "$tmp" || {
|
||||
rm -f "$tmp"
|
||||
error "Failed to enable the Windows configuration set!"
|
||||
error "$msg (2)"
|
||||
return 1
|
||||
}
|
||||
elif [ "$userdata_count" = "1" ]; then
|
||||
xmlstarlet ed -L -N "$XML_NS_UNATTEND_ARG" -i "$userdata" -t elem -n "UseConfigurationSet" -v "true" "$tmp" || {
|
||||
rm -f "$tmp"
|
||||
error "Failed to enable the Windows configuration set!"
|
||||
error "$msg (3)"
|
||||
return 1
|
||||
}
|
||||
else
|
||||
xmlstarlet ed -L -N "$XML_NS_UNATTEND_ARG" -s "$setup" -t elem -n "UseConfigurationSet" -v "true" "$tmp" || {
|
||||
rm -f "$tmp"
|
||||
error "Failed to enable the Windows configuration set!"
|
||||
error "$msg (4)"
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
@@ -1203,7 +1212,7 @@ setConfigurationXML() {
|
||||
|
||||
if [ "$result_count" != "1" ]; then
|
||||
rm -f "$tmp"
|
||||
error "Failed to enable the Windows configuration set!"
|
||||
error "$msg (5)"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -1219,8 +1228,7 @@ removeSharedFolder() {
|
||||
|
||||
local script="$1"
|
||||
|
||||
if ! disabled "${SHORTCUT:-}" &&
|
||||
! disabled "${SAMBA:-}"; then
|
||||
if ! disabled "${SHORTCUT:-}" && ! disabled "${SAMBA:-}"; then
|
||||
return 0
|
||||
fi
|
||||
|
||||
@@ -1299,13 +1307,14 @@ removeEmbeddedProductKeys() {
|
||||
|
||||
validateXMLSettings() {
|
||||
|
||||
validateResolution "WIDTH" "$WIDTH" 320 || return 1
|
||||
validateResolution "HEIGHT" "$HEIGHT" 200 || return 1
|
||||
validateMembership || return 1
|
||||
validateComputerName "${HOST:-}" || return 1
|
||||
validateProductKey "${KEY:-}" || return 1
|
||||
validatePassword "${PASSWORD:-}" || return 1
|
||||
|
||||
validateResolution "WIDTH" "$WIDTH" 320 || return 1
|
||||
validateResolution "HEIGHT" "$HEIGHT" 200 || return 1
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
@@ -1828,15 +1837,13 @@ encodeUnattendPassword() {
|
||||
|
||||
# Windows unattend password fields use a field-specific suffix before
|
||||
# UTF-16LE/Base64 encoding; this is obfuscation rather than encryption.
|
||||
printf '%s' "${password}${suffix}" |
|
||||
iconv -f utf-8 -t utf-16le |
|
||||
base64 -w 0
|
||||
printf '%s' "${password}${suffix}" | iconv -f utf-8 -t utf-16le | base64 -w 0
|
||||
|
||||
}
|
||||
|
||||
enableLog() {
|
||||
|
||||
local script="$1"
|
||||
|
||||
local content
|
||||
|
||||
enabled "${LOG:-}" || return 0
|
||||
@@ -1887,7 +1894,6 @@ getXMLNodeCount() {
|
||||
local xpath="$2"
|
||||
|
||||
xmlstarlet sel -N "$XML_NS_UNATTEND_ARG" -T -t -v "count($xpath)" "$asset"
|
||||
|
||||
}
|
||||
|
||||
validateUniqueXMLNodes() {
|
||||
@@ -2001,8 +2007,11 @@ updateSetupScript() {
|
||||
fi
|
||||
|
||||
if [ -n "$domain" ]; then
|
||||
|
||||
removeSetupBlock "$script" "LOCAL_ACCOUNT" || return 1
|
||||
|
||||
elif [ -n "$user" ]; then
|
||||
|
||||
validateUsername "$user" "local" || return 1
|
||||
|
||||
id=$(basename "$asset") || return 1
|
||||
@@ -2026,6 +2035,7 @@ updateSetupScript() {
|
||||
esac
|
||||
|
||||
replaceSetupBlock "$script" "LOCAL_ACCOUNT" "$content" || return 1
|
||||
|
||||
fi
|
||||
|
||||
enableLog "$script" || return 1
|
||||
@@ -2047,9 +2057,9 @@ findSetupScript() {
|
||||
|
||||
dir=$(dirname "$asset") || return 1
|
||||
name=$(basename "$asset") || return 1
|
||||
|
||||
id="${name%.*}"
|
||||
normal="$id"
|
||||
|
||||
candidates+=("$dir/$id.cmd")
|
||||
|
||||
if [[ "${normal,,}" == *"-eval" ]]; then
|
||||
@@ -2057,19 +2067,19 @@ findSetupScript() {
|
||||
candidates+=("$dir/$normal.cmd")
|
||||
fi
|
||||
|
||||
# Generated edition-specific answer files inherit the script belonging to
|
||||
# their generic source template.
|
||||
case "${normal,,}" in
|
||||
"win7"* | "win8"* | "win10"* | "win11"* | "winvista"* | "win20"* )
|
||||
candidates+=("$dir/${normal%%-*}.cmd")
|
||||
;;
|
||||
esac
|
||||
# Generated edition-specific answer files inherit the
|
||||
# script belonging to their generic source template.
|
||||
if [[ "$normal" == *-* ]]; then
|
||||
candidates+=("$dir/${normal%%-*}.cmd")
|
||||
fi
|
||||
|
||||
for candidate in "${candidates[@]}"; do
|
||||
|
||||
if [ -f "$candidate" ] && [ -s "$candidate" ]; then
|
||||
printf '%s' "$candidate"
|
||||
return 0
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
error "Failed to find setup script for answer file: $asset"
|
||||
@@ -2082,7 +2092,6 @@ stageSetupScript() {
|
||||
local stage="$2"
|
||||
|
||||
local source target
|
||||
|
||||
source=$(findSetupScript "$asset") || return 1
|
||||
[ -n "$source" ] || return 0
|
||||
|
||||
@@ -2139,6 +2148,7 @@ rewriteSetupBlock() {
|
||||
while IFS= read -r line || [ -n "$line" ]; do
|
||||
|
||||
if [ "$line" = "$begin" ]; then
|
||||
|
||||
if [ "$action" = "replace" ]; then
|
||||
if ! printf '%s\n' "$line" >> "$tmp" ||
|
||||
! printf '%s\n' "$content" >> "$tmp"; then
|
||||
@@ -2152,6 +2162,7 @@ rewriteSetupBlock() {
|
||||
fi
|
||||
|
||||
if [ "$line" = "$end" ]; then
|
||||
|
||||
inside=0
|
||||
|
||||
if [ "$action" = "replace" ]; then
|
||||
@@ -2165,10 +2176,12 @@ rewriteSetupBlock() {
|
||||
fi
|
||||
|
||||
if (( ! inside )); then
|
||||
|
||||
if ! printf '%s\n' "$line" >> "$tmp"; then
|
||||
rm -f "$tmp"
|
||||
return 1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
done < "$file"
|
||||
@@ -2225,7 +2238,6 @@ escapeSIFValue() {
|
||||
escapeRegistryValue() {
|
||||
|
||||
printf '%s' "$1" | sed -e 's/\\/\\\\/g' -e 's/"/\\"/g'
|
||||
|
||||
}
|
||||
|
||||
extractDrivers() {
|
||||
@@ -2382,15 +2394,14 @@ addLegacyDrivers() {
|
||||
local arch="$4"
|
||||
local drivers="$5"
|
||||
|
||||
local file
|
||||
local msg="Adding drivers to image..."
|
||||
|
||||
info "$msg" && html "$msg"
|
||||
|
||||
extractDrivers "$drivers" || return 1
|
||||
copyStorageDriver "$dir" "$target" "$driver" "$arch" "$drivers" || return 1
|
||||
addNetworkDriver "$dir" "$driver" "$arch" "$drivers" || return 1
|
||||
|
||||
local file
|
||||
file=$(find "$target" -maxdepth 1 -type f -iname TXTSETUP.SIF -print -quit) || return 1
|
||||
|
||||
if [ -z "$file" ]; then
|
||||
@@ -2414,7 +2425,6 @@ setLegacyKey() {
|
||||
local desc="$4"
|
||||
|
||||
local setup pid key file
|
||||
|
||||
setup=$(find "$target" -maxdepth 1 -type f -iname setupp.ini -print -quit) || return 1
|
||||
|
||||
[[ -n "$setup" ]] || return 0
|
||||
@@ -2440,7 +2450,9 @@ setLegacyKey() {
|
||||
# Prefer a staging or OEM key already shipped on the media before falling
|
||||
# back to Microsoft's documented generic installation keys.
|
||||
if [[ "$driver" == "2k3" ]]; then
|
||||
|
||||
key=$(grep -i -A 2 "StagingKey" "$file" | tail -n 2 | head -n 1) || key=""
|
||||
|
||||
else
|
||||
|
||||
key="${pid: -8:5}"
|
||||
@@ -2473,8 +2485,7 @@ setLegacyKey() {
|
||||
else
|
||||
# Windows XP Professional x64 generic trial key (no activation)
|
||||
KEY="B2RBK-7KPT9-4JP6X-QQFWM-PJD6G"
|
||||
fi
|
||||
;;
|
||||
fi ;;
|
||||
|
||||
"2k3" )
|
||||
|
||||
@@ -2484,8 +2495,7 @@ setLegacyKey() {
|
||||
else
|
||||
# Windows Server 2003 Standard x64 generic trial key (no activation)
|
||||
KEY="P4WJG-WK3W7-3HM8W-RWHCK-8JTRY"
|
||||
fi
|
||||
;;
|
||||
fi ;;
|
||||
|
||||
esac
|
||||
|
||||
|
||||
+52
-32
@@ -195,6 +195,7 @@ selectVersion() {
|
||||
|
||||
IFS=$'\t' read -r id index <<< "$record"
|
||||
[[ "${id,,}" == "${candidate,,}" ]] || continue
|
||||
|
||||
hasAnswerFile "$id" || continue
|
||||
|
||||
printf '%s\n%s\n' "$id" "$index"
|
||||
@@ -278,6 +279,7 @@ detectVersion() {
|
||||
for record in "${images[@]}"; do
|
||||
|
||||
IFS=$'\t' read -r id index <<< "$record"
|
||||
|
||||
hasAnswerFile "$id" || continue
|
||||
|
||||
rank=$(getEditionRank "$id")
|
||||
@@ -327,7 +329,6 @@ detectLanguage() {
|
||||
for path in "${paths[@]}"; do
|
||||
|
||||
lang=$(xmlstarlet sel -T -t -v "normalize-space(string(($path)[1]))" - 2>/dev/null <<< "$xml") || lang=""
|
||||
|
||||
[ -n "$lang" ] && break
|
||||
|
||||
done
|
||||
@@ -502,8 +503,6 @@ createImageDirectory() {
|
||||
local image="$1"
|
||||
local directory="$2"
|
||||
|
||||
# Treat an existing directory as success; create it only when mdir cannot
|
||||
# already resolve it.
|
||||
if mdir -i "$image" "$directory" >/dev/null 2>&1; then
|
||||
return 0
|
||||
fi
|
||||
@@ -560,20 +559,25 @@ createSetupImage() {
|
||||
fi
|
||||
|
||||
for entry in "${entries[@]}"; do
|
||||
|
||||
if ! mcopy -Q -s -i "$tmp" "$entry" ::; then
|
||||
rm -f -- "$tmp"
|
||||
error "Failed to copy image file: $entry"
|
||||
return 1
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
if [ -n "$folder" ] || [ -f "$install" ]; then
|
||||
|
||||
if ! createImageDirectory "$tmp" "::/\$OEM\$" || ! createImageDirectory "$tmp" "::/\$OEM\$/\$1" ||
|
||||
! createImageDirectory "$tmp" "$target"; then
|
||||
|
||||
rm -f -- "$tmp"
|
||||
error "Failed to create OEM directory in setup image!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
if [ -n "$folder" ]; then
|
||||
@@ -592,11 +596,13 @@ createSetupImage() {
|
||||
fi
|
||||
|
||||
for entry in "${entries[@]}"; do
|
||||
|
||||
if ! mcopy -Q -s -o -i "$tmp" "$entry" "$target"; then
|
||||
rm -f -- "$tmp"
|
||||
error "Failed to copy OEM file: $entry"
|
||||
return 1
|
||||
fi
|
||||
|
||||
done
|
||||
|
||||
fi
|
||||
@@ -604,11 +610,13 @@ createSetupImage() {
|
||||
# Copy the generated overlay script last so it replaces an install.bat from
|
||||
# the mounted OEM folder when both are present.
|
||||
if [ -f "$install" ]; then
|
||||
|
||||
if ! mcopy -Q -o -i "$tmp" "$install" "$target/install.bat"; then
|
||||
rm -f -- "$tmp"
|
||||
error "Failed to replace install.bat in setup image!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
# Verify that mtools can read the completed filesystem before publishing it.
|
||||
@@ -773,7 +781,6 @@ detectLegacy() {
|
||||
detectReactOS() {
|
||||
|
||||
local dir="$1"
|
||||
|
||||
local marker
|
||||
|
||||
marker=$(find "$dir" -maxdepth 2 -type f \
|
||||
@@ -885,8 +892,8 @@ readIsoImageInfo() {
|
||||
local image="$2"
|
||||
local header="$3"
|
||||
|
||||
local raw result root xml_count rc
|
||||
local header_size version
|
||||
local raw result xml_count rc
|
||||
local root header_size version
|
||||
local part_number total_parts image_count
|
||||
local xml_offset xml_size xml_original xml_flags
|
||||
local -a bytes=() values=()
|
||||
@@ -1172,8 +1179,10 @@ findImage() {
|
||||
fi
|
||||
|
||||
for name in install.wim install.esd; do
|
||||
|
||||
result=$(find "$sources" -maxdepth 1 -type f -iname "$name" -print -quit) || return 2
|
||||
[ -n "$result" ] && break
|
||||
|
||||
done
|
||||
|
||||
if [ ! -f "$result" ]; then
|
||||
@@ -1222,13 +1231,14 @@ validateEdition() {
|
||||
# Discard a stale server-edition override when it conflicts with the image
|
||||
# that was actually detected.
|
||||
EDITION=""
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
unknownImage() {
|
||||
|
||||
local msg="Failed to determine Windows version from image"
|
||||
local rc=0
|
||||
local msg="Failed to determine Windows version from image"
|
||||
|
||||
setXML "" || rc=$?
|
||||
|
||||
@@ -1252,9 +1262,12 @@ describeImage() {
|
||||
result=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 1
|
||||
|
||||
if [[ "${LANGUAGE,,}" != "en" && "${LANGUAGE,,}" != "en-"* ]]; then
|
||||
|
||||
local language
|
||||
language=$(getLanguage "$LANGUAGE" "desc") || return 1
|
||||
|
||||
result+=" ($language)"
|
||||
|
||||
fi
|
||||
|
||||
printf '%s' "$result"
|
||||
@@ -1373,7 +1386,6 @@ detectImageInfo() {
|
||||
detectIsoImage() {
|
||||
|
||||
local iso="$1"
|
||||
|
||||
local image header image_info rc
|
||||
|
||||
# Return 1 only when no directly inspectable WIM/ESD payload is available so
|
||||
@@ -1405,19 +1417,39 @@ detectIsoImage() {
|
||||
return 0
|
||||
}
|
||||
|
||||
baseDir() {
|
||||
|
||||
local path="${1%/}"
|
||||
|
||||
[[ -z "$path" || "$path" == "/" ]] && {
|
||||
echo "/"
|
||||
return 0
|
||||
}
|
||||
|
||||
path="${path#/}"
|
||||
path="${path%%/*}"
|
||||
|
||||
echo "/$path"
|
||||
return 0
|
||||
}
|
||||
|
||||
checkFreeSpace() {
|
||||
|
||||
local dir="$1"
|
||||
local size="$2"
|
||||
|
||||
local space size_gb space_gb
|
||||
local base space size_gb space_gb
|
||||
base=$(baseDir "$dir")
|
||||
|
||||
space=$(df --output=avail -B 1 "$dir" | tail -n 1) || return 1
|
||||
|
||||
[[ "$space" =~ ^[[:space:]]*[0-9]+[[:space:]]*$ ]] || {
|
||||
error "Failed to determine available disk space for $dir!"
|
||||
if ! space=$(df --output=avail -B 1 "$dir" | tail -n 1); then
|
||||
error "Failed to check free space in $dir."
|
||||
return 1
|
||||
}
|
||||
fi
|
||||
|
||||
if [[ ! "$space" =~ ^[[:space:]]*[0-9]+[[:space:]]*$ ]]; then
|
||||
error "Failed to determine available disk space for $dir."
|
||||
return 1
|
||||
fi
|
||||
|
||||
space="${space//[[:space:]]/}"
|
||||
|
||||
@@ -1426,8 +1458,9 @@ checkFreeSpace() {
|
||||
size_gb=$(formatBytes "$size")
|
||||
space_gb=$(formatBytes "$space")
|
||||
|
||||
error "Not enough free space in $STORAGE, have $space_gb available but need at least $size_gb."
|
||||
error "Not enough free space in $base, have $space_gb available but need at least $size_gb."
|
||||
return 1
|
||||
|
||||
fi
|
||||
|
||||
return 0
|
||||
@@ -1462,7 +1495,7 @@ extractESD() {
|
||||
fi
|
||||
|
||||
if (( size < minSize )); then
|
||||
error "The downloaded ISO file is too small!"
|
||||
error "The downloaded ESD file is too small!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -1514,8 +1547,7 @@ extractESD() {
|
||||
bootTotal="${fields[1]:-}"
|
||||
bootLinks="${fields[2]:-}"
|
||||
|
||||
if [[ ! "$bootTotal" =~ ^[0-9]+$ ]] ||
|
||||
[[ ! "$bootLinks" =~ ^[0-9]+$ ]]; then
|
||||
if [[ ! "$bootTotal" =~ ^[0-9]+$ ]] || [[ ! "$bootLinks" =~ ^[0-9]+$ ]]; then
|
||||
error "Cannot read bootdisk size from ESD file!"
|
||||
return 1
|
||||
fi
|
||||
@@ -1537,6 +1569,7 @@ extractESD() {
|
||||
# installation media. Peak additional usage consists of the extracted setup
|
||||
# files and boot.wim, plus the final ISO containing those files and the ESD.
|
||||
local freeSpace=$(( size + 2 * (bootSize + wimSize) + spacePad ))
|
||||
|
||||
checkFreeSpace "$dir" "$freeSpace" || return
|
||||
|
||||
/run/progress.sh "$dir" "$bootSize" "$msg ([P])..." &
|
||||
@@ -1585,6 +1618,7 @@ extractESD() {
|
||||
}
|
||||
|
||||
fKill "progress.sh"
|
||||
html "$msg..."
|
||||
|
||||
if [[ "${PLATFORM,,}" == "x64" ]]; then
|
||||
LABEL="CCCOMA_X64FRE_EN-US_DV9"
|
||||
@@ -1592,9 +1626,6 @@ extractESD() {
|
||||
LABEL="CPBA_A64FRE_EN-US_DV9"
|
||||
fi
|
||||
|
||||
msg="Extracting image from ESD file"
|
||||
info "$msg..." && html "$msg..."
|
||||
|
||||
index=""
|
||||
|
||||
if [[ "${version,,}" == "http"* ]]; then
|
||||
@@ -1649,10 +1680,8 @@ extractESD() {
|
||||
fi
|
||||
|
||||
installSize=$(( size + installPad ))
|
||||
/run/progress.sh "$installWim" "$installSize" "$msg ([P])..." &
|
||||
|
||||
if ! rm -f -- "$dir/sources/install.wim" "$installWim"; then
|
||||
fKill "progress.sh"
|
||||
error "Failed to remove previous Windows installation image!"
|
||||
return 1
|
||||
fi
|
||||
@@ -1660,7 +1689,6 @@ extractESD() {
|
||||
# Reuse the downloaded solid ESD instead of exporting the selected image.
|
||||
# Both paths are below $TMP, so this is a same-filesystem rename.
|
||||
if ! mv -f -- "$iso" "$installWim"; then
|
||||
fKill "progress.sh"
|
||||
error "Failed to move downloaded ESD file into the installation media!"
|
||||
return 1
|
||||
fi
|
||||
@@ -1673,7 +1701,6 @@ extractESD() {
|
||||
|
||||
wimlib-imagex delete "$installWim" "$image" --soft --quiet || {
|
||||
ret=$?
|
||||
fKill "progress.sh"
|
||||
error "Failed to remove image $image from install.esd!"
|
||||
return "$ret"
|
||||
}
|
||||
@@ -1683,7 +1710,6 @@ extractESD() {
|
||||
result=$(wimlib-imagex info "$installWim" --xml 2>/dev/null |
|
||||
iconv -f UTF-16LE -t UTF-8 2>/dev/null) || {
|
||||
ret=$?
|
||||
fKill "progress.sh"
|
||||
error "Cannot verify the prepared install.esd file!"
|
||||
return "$ret"
|
||||
}
|
||||
@@ -1693,7 +1719,6 @@ extractESD() {
|
||||
-v 'count(/WIM/IMAGE[@INDEX="1"])' -n \
|
||||
-v 'normalize-space(/WIM/IMAGE[@INDEX="1"]/DESCRIPTION)' -n \
|
||||
<<< "$result" 2>/dev/null); then
|
||||
fKill "progress.sh"
|
||||
error "Cannot verify the prepared install.esd file!"
|
||||
return 1
|
||||
fi
|
||||
@@ -1705,26 +1730,22 @@ extractESD() {
|
||||
resultEdition="${fields[2]:-}"
|
||||
|
||||
if [[ "$resultCount" != "1" ]] || [[ "$resultIndex" != "1" ]]; then
|
||||
fKill "progress.sh"
|
||||
error "Prepared install.esd does not contain exactly one image at index 1!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
if [[ "${version,,}" != "http"* ]] &&
|
||||
[[ "${resultEdition,,}" != "${edition,,}" ]]; then
|
||||
fKill "progress.sh"
|
||||
error "Prepared install.esd does not contain only '$edition' at index 1!"
|
||||
return 1
|
||||
fi
|
||||
|
||||
fKill "progress.sh"
|
||||
return 0
|
||||
}
|
||||
|
||||
normalizeBatch() {
|
||||
|
||||
local file="$1"
|
||||
|
||||
local bom tmp encoding
|
||||
|
||||
[ ! -s "$file" ] && return 0
|
||||
@@ -1768,7 +1789,6 @@ reportBatchMatches() {
|
||||
local suggestion="$5"
|
||||
|
||||
local matches line
|
||||
|
||||
matches=$(grep -Pin "$pattern" "$file" || true)
|
||||
|
||||
[ -n "$matches" ] || return 0
|
||||
|
||||
+51
-34
@@ -43,16 +43,12 @@ selectWindowsImage() {
|
||||
local dir="$2"
|
||||
local boot="$3"
|
||||
|
||||
local rc
|
||||
|
||||
XML=""
|
||||
FB="falling back to manual installation!"
|
||||
|
||||
# Known catalog versions already provide the required image metadata.
|
||||
if [ -z "$DETECTED" ] && [ -z "$CUSTOM" ] && [[ "${VERSION,,}" != "http"* ]]; then
|
||||
DETECTED="$VERSION"
|
||||
fi
|
||||
|
||||
DETECTED="${DETECTED/-enterprise-iot/-iot}"
|
||||
DETECTED="${DETECTED/-enterprise-ltsc/-ltsc}"
|
||||
normalizeDetected || return 70
|
||||
|
||||
if [ -n "$DETECTED" ]; then
|
||||
|
||||
@@ -74,11 +70,15 @@ selectWindowsImage() {
|
||||
|
||||
fi
|
||||
|
||||
# Inspect unknown media directly before falling back to extraction.
|
||||
detectIsoImage "$iso" && return 0
|
||||
# Inspect unknown bootable media directly before falling back to extraction.
|
||||
if [[ "${iso,,}" != *.esd ]]; then
|
||||
|
||||
local rc=$?
|
||||
(( rc == 1 )) || return 76
|
||||
detectIsoImage "$iso" && return 0
|
||||
|
||||
rc=$?
|
||||
(( rc == 1 )) || return 76
|
||||
|
||||
fi
|
||||
|
||||
if ! extractImage "$iso" "$dir" "$VERSION"; then
|
||||
removeImage "$iso" || :
|
||||
@@ -105,10 +105,9 @@ configureMachine() {
|
||||
local boot="$3"
|
||||
|
||||
local desc
|
||||
|
||||
desc=$(printVariant "$DETECTED" "$DETECTED") || return 78
|
||||
|
||||
if ! checkMemory "$DETECTED" "$desc"; then
|
||||
if ! checkMemory "$DETECTED"; then
|
||||
if [ -z "$CUSTOM" ]; then
|
||||
useOriginalImage "$iso" || return 79
|
||||
fi
|
||||
@@ -146,7 +145,7 @@ prepareWindowsImage() {
|
||||
fi
|
||||
|
||||
if ! createSetupImage "$TMP/setup" "$STORAGE/setup.img"; then
|
||||
exit 86
|
||||
return 86
|
||||
fi
|
||||
|
||||
# Bootable ISOs can be reused unchanged with the generated setup image.
|
||||
@@ -385,7 +384,7 @@ skipInstall() {
|
||||
|
||||
local iso="$1"
|
||||
local previousBase="$2"
|
||||
local boot="$STORAGE/windows.boot"
|
||||
local marker="$STORAGE/windows.boot"
|
||||
|
||||
if [ -n "$previousBase" ]; then
|
||||
|
||||
@@ -409,7 +408,7 @@ skipInstall() {
|
||||
|
||||
# Older releases may have left a rebuilt custom ISO at its synthetic source
|
||||
# identity. A completed installation no longer needs that installation media.
|
||||
if [[ "${previousBase,,}" == "windows."* ]] && [ -f "$boot" ] && hasData; then
|
||||
if [[ "${previousBase,,}" == "windows."* ]] && hasData && [ -f "$marker" ]; then
|
||||
if ! rm -f -- "$STORAGE/$previousBase"; then
|
||||
error "Failed to remove obsolete ISO file \"$STORAGE/$previousBase\" !"
|
||||
exit 50
|
||||
@@ -441,7 +440,7 @@ skipInstall() {
|
||||
else
|
||||
method="your custom .iso file was removed"
|
||||
|
||||
if [ -f "$boot" ] && hasData; then
|
||||
if hasData && [ -f "$marker" ]; then
|
||||
info "Detected that $method, will be ignored."
|
||||
return 0
|
||||
fi
|
||||
@@ -449,7 +448,7 @@ skipInstall() {
|
||||
fi
|
||||
fi
|
||||
|
||||
if enabled "$SHUTDOWN" && [ ! -f "$boot" ]; then
|
||||
if enabled "$SHUTDOWN" && [ ! -f "$marker" ]; then
|
||||
discardPrevious "$STORAGE/$previousBase" || exit 50
|
||||
return 1
|
||||
fi
|
||||
@@ -465,7 +464,7 @@ skipInstall() {
|
||||
fi
|
||||
fi
|
||||
|
||||
[ -f "$boot" ] && hasData && return 0
|
||||
hasData && [ -f "$marker" ] && return 0
|
||||
|
||||
return 1
|
||||
}
|
||||
@@ -476,7 +475,7 @@ finishInstall() {
|
||||
local aborted="$2"
|
||||
local boot="$3"
|
||||
|
||||
local base
|
||||
local base secure=0
|
||||
|
||||
if [ ! -s "$iso" ] || [ ! -f "$iso" ]; then
|
||||
error "Failed to find ISO file: $iso" && return 1
|
||||
@@ -509,11 +508,9 @@ finishInstall() {
|
||||
|
||||
else
|
||||
|
||||
local secure=0
|
||||
|
||||
# Aborted Win11 installs boot without any answer file present,
|
||||
# so enable Secure Boot and TPM to satisfy its hardware checks.
|
||||
if [[ "$aborted" == [Yy1]* ]] || enabled "$MANUAL"; then
|
||||
if enabled "$aborted" || enabled "$MANUAL"; then
|
||||
[[ "${DETECTED,,}" == "win11"* ]] && secure=1
|
||||
fi
|
||||
|
||||
@@ -578,6 +575,7 @@ findFile() {
|
||||
|
||||
ISO="$file"
|
||||
CUSTOM="$file"
|
||||
|
||||
# Encode the custom ISO size in a synthetic source identity so replacing a
|
||||
# bind-mounted ISO is detected as a different installation source.
|
||||
BOOT="$STORAGE/windows.$size.iso"
|
||||
@@ -585,6 +583,19 @@ findFile() {
|
||||
return 0
|
||||
}
|
||||
|
||||
normalizeDetected() {
|
||||
|
||||
# Known catalog versions already provide the required image metadata.
|
||||
if [ -z "$DETECTED" ] && [ -z "$CUSTOM" ] && [[ "${VERSION,,}" != "http"* ]]; then
|
||||
DETECTED="$VERSION"
|
||||
fi
|
||||
|
||||
DETECTED="${DETECTED/-enterprise-iot/-iot}"
|
||||
DETECTED="${DETECTED/-enterprise-ltsc/-ltsc}"
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
detectCustom() {
|
||||
|
||||
CUSTOM=""
|
||||
@@ -629,10 +640,10 @@ removeImage() {
|
||||
|
||||
setImage() {
|
||||
|
||||
supportsXML "${DETECTED,,}" || return 0
|
||||
|
||||
local rc=0
|
||||
|
||||
supportsXML "${DETECTED,,}" || return 0
|
||||
|
||||
setXML "" || rc=$?
|
||||
|
||||
if (( rc == 0 )); then
|
||||
@@ -688,8 +699,7 @@ getArchiveSize() {
|
||||
local result_name="$2"
|
||||
local -n result="$result_name"
|
||||
|
||||
local listing line value
|
||||
local found=0 rc
|
||||
local found=0 listing line value rc
|
||||
|
||||
result=0
|
||||
|
||||
@@ -728,8 +738,7 @@ extractImage() {
|
||||
local target="$dir"
|
||||
local desc="local ISO"
|
||||
local archive="${dir}.archive"
|
||||
local file size required archiveSize
|
||||
local rc
|
||||
local file size required archiveSize rc
|
||||
|
||||
if [ -z "$CUSTOM" ]; then
|
||||
desc="downloaded ISO"
|
||||
@@ -850,25 +859,30 @@ extractImage() {
|
||||
detectImage() {
|
||||
|
||||
local dir="$1"
|
||||
|
||||
local desc rc
|
||||
|
||||
info "Detecting version from ISO image..."
|
||||
|
||||
# Marker-based legacy and ReactOS detection must run before looking for a WIM.
|
||||
# Marker-based legacy detection must run before looking for a WIM.
|
||||
if detectLegacy "$dir"; then
|
||||
|
||||
desc=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 2
|
||||
|
||||
info "Detected: $desc"
|
||||
return 0
|
||||
|
||||
else
|
||||
rc=$?
|
||||
(( rc == 1 )) || return "$rc"
|
||||
fi
|
||||
|
||||
if detectReactOS "$dir"; then
|
||||
|
||||
desc=$(printEdition "$DETECTED" "$DETECTED" "Y") || return 2
|
||||
|
||||
info "Detected: $desc"
|
||||
return 0
|
||||
|
||||
else
|
||||
rc=$?
|
||||
(( rc == 1 )) || return "$rc"
|
||||
@@ -962,9 +976,11 @@ addFolder() {
|
||||
rm -f -- "$install" || return 1
|
||||
|
||||
if [ -n "$folder" ]; then
|
||||
|
||||
source=$(find -L "$folder" -maxdepth 1 -type f -iname install.bat -print -quit) || return 1
|
||||
|
||||
if [ -n "$source" ]; then
|
||||
|
||||
if ! cp -L -- "$source" "$install"; then
|
||||
error "Failed to create a writable copy of $source!"
|
||||
return 1
|
||||
@@ -972,6 +988,7 @@ addFolder() {
|
||||
|
||||
file="$install"
|
||||
fi
|
||||
|
||||
fi
|
||||
|
||||
else
|
||||
@@ -1338,10 +1355,10 @@ restoreBootMode() {
|
||||
|
||||
restoreMachine() {
|
||||
|
||||
# Restore the saved machine only when q35 is still the default; an explicit
|
||||
# user-selected machine must remain untouched.
|
||||
[[ "${PLATFORM,,}" != "x64" ]] && return 0
|
||||
# Restore the saved machine only when q35 is still the default;
|
||||
# an explicit user-selected machine must remain untouched.
|
||||
[[ "${MACHINE,,}" != "q35" ]] && return 0
|
||||
[[ "${PLATFORM,,}" != "x64" ]] && return 0
|
||||
|
||||
MACHINE=""
|
||||
restoreState "MACHINE" "old" || return 1
|
||||
|
||||
+20
-16
@@ -7,8 +7,6 @@ handleCurlError() {
|
||||
local server="$2"
|
||||
local reason="${3:-}"
|
||||
|
||||
local signal
|
||||
|
||||
if [ -n "$reason" ] && (( code <= 125 )); then
|
||||
error "Request to $server servers failed: ${reason%.}."
|
||||
return 1
|
||||
@@ -23,6 +21,7 @@ handleCurlError() {
|
||||
return 1
|
||||
fi
|
||||
|
||||
local signal
|
||||
signal=$(kill -l "$((code - 128))" 2>/dev/null || true)
|
||||
|
||||
case "$signal" in
|
||||
@@ -72,10 +71,7 @@ curlRequest() {
|
||||
rm -f "$log"
|
||||
handleCurlError "$rc" "$server" "$reason" || :
|
||||
|
||||
if (( rc >= 129 )); then
|
||||
return "$rc"
|
||||
fi
|
||||
|
||||
(( rc >= 129 )) && return "$rc"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -579,11 +575,13 @@ getWindows() {
|
||||
"win81${PLATFORM,,}"* | \
|
||||
"win10${PLATFORM,,}-enterprise-ltsc-eval" | \
|
||||
"win11${PLATFORM,,}-enterprise-iot-eval" )
|
||||
|
||||
if [[ "${lang,,}" != "en" && "${lang,,}" != "en-"* ]]; then
|
||||
error "No download in the $language language available for $edition!"
|
||||
MIDO_URL=""
|
||||
return 1
|
||||
fi ;;
|
||||
|
||||
esac
|
||||
|
||||
# ARM64 downloads exist only for the explicitly supported Windows 11
|
||||
@@ -593,24 +591,28 @@ getWindows() {
|
||||
"win11${PLATFORM,,}" ) ;;
|
||||
"win11${PLATFORM,,}-enterprise"* ) ;;
|
||||
* )
|
||||
|
||||
if [[ "${PLATFORM,,}" != "x64" ]]; then
|
||||
error "No download for the ${PLATFORM^^} platform available for $edition!"
|
||||
MIDO_URL=""
|
||||
return 1
|
||||
fi ;;
|
||||
|
||||
esac
|
||||
|
||||
# Prefer live Microsoft download routes. Unsupported or failed live routes
|
||||
# fall through to the configured static catalog below.
|
||||
case "${version,,}" in
|
||||
|
||||
"win10x64" | "win11${PLATFORM,,}" )
|
||||
|
||||
if downloadWindows "$version" "$lang" "$edition"; then
|
||||
return 0
|
||||
else
|
||||
rc=$?
|
||||
(( rc == 1 )) || return "$rc"
|
||||
fi ;;
|
||||
fi
|
||||
|
||||
(( rc == 1 )) || return "$rc" ;;
|
||||
|
||||
"win11${PLATFORM,,}-enterprise"* )
|
||||
|
||||
@@ -618,8 +620,9 @@ getWindows() {
|
||||
return 0
|
||||
else
|
||||
rc=$?
|
||||
(( rc == 1 )) || return "$rc"
|
||||
fi ;;
|
||||
fi
|
||||
|
||||
(( rc == 1 )) || return "$rc" ;;
|
||||
|
||||
"win2025-eval" | "win2022-eval" | "win2019-eval" | \
|
||||
"win2019-hv" | "win2016-eval" | "win2012r2-eval" )
|
||||
@@ -628,14 +631,16 @@ getWindows() {
|
||||
return 0
|
||||
else
|
||||
rc=$?
|
||||
(( rc == 1 )) || return "$rc"
|
||||
fi ;;
|
||||
fi
|
||||
|
||||
(( rc == 1 )) || return "$rc" ;;
|
||||
|
||||
"win2008r2"*| "win81${PLATFORM,,}"* | "win10${PLATFORM,,}-enterprise"* ) ;;
|
||||
|
||||
* )
|
||||
error "Invalid VERSION specified, value \"$version\" is not recognized!"
|
||||
return 1 ;;
|
||||
|
||||
esac
|
||||
|
||||
# Static catalog URLs are the last resort after live Microsoft methods are
|
||||
@@ -995,10 +1000,7 @@ getESD() {
|
||||
|
||||
rm -f "$log"
|
||||
|
||||
if (( rc >= 129 )); then
|
||||
return "$rc"
|
||||
fi
|
||||
|
||||
(( rc >= 129 )) && return "$rc"
|
||||
return 1
|
||||
fi
|
||||
|
||||
@@ -1209,6 +1211,7 @@ tryDownload() {
|
||||
if ! rm -f -- "$iso" "$iso.aria2"; then
|
||||
warn "failed to remove invalid download \"$iso\"!"
|
||||
fi
|
||||
|
||||
return 2
|
||||
}
|
||||
|
||||
@@ -1278,6 +1281,7 @@ downloadImage() {
|
||||
web_desc="$desc"
|
||||
|
||||
tryDownload "$iso" "$version" "" "" "$desc" "$seconds" "$web_desc" || return
|
||||
|
||||
return 0
|
||||
fi
|
||||
|
||||
|
||||
+1
-1
@@ -429,7 +429,7 @@ finish() {
|
||||
failed=1
|
||||
fi
|
||||
|
||||
touch "$QEMU_END"
|
||||
touch "$QEMU_END" || :
|
||||
|
||||
forceKillQemu "$reason"
|
||||
|
||||
|
||||
Reference in New Issue
Block a user