feat: Implement Windows 95 support (#2165)

This commit is contained in:
Kroese
2026-08-20 04:50:57 +02:00
committed by GitHub
parent afb28c9234
commit eb1befd90e
9 changed files with 1316 additions and 181 deletions
+53 -5
View File
@@ -526,17 +526,28 @@ updateAutologinXML() {
return 0
}
usesWscriptLogonLauncher() {
case "${DETECTED,,}" in
"winvista"* | "win7"* | "win2008r2"* ) return 0 ;;
esac
return 1
}
updateLogonCommandXML() {
local asset="$1"
case "${DETECTED,,}" in
"winvista"* ) return 0 ;;
esac
local command="$XML_COMPONENT_SHELL_OOBE/u:FirstLogonCommands/u:SynchronousCommand/u:CommandLine"
local expected='cmd.exe /d /c call "%WINDIR%\Setup\Scripts\SetupComplete.cmd" logon'
local hidden="powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -Command \"& \$env:ComSpec /d /c ('call ' + [char]34 + \$env:WINDIR + '\Setup\Scripts\SetupComplete.cmd' + [char]34 + ' logon'); exit \$LASTEXITCODE\""
local hidden
if usesWscriptLogonLauncher; then
hidden='wscript.exe //B //NoLogo C:\Windows\Setup\Scripts\RunHidden.vbs'
else
hidden="powershell.exe -NoLogo -NoProfile -NonInteractive -WindowStyle Hidden -Command \"\$cmd = 'call ' + [char]34 + \$env:WINDIR + '\Setup\Scripts\SetupComplete.cmd' + [char]34 + ' logon'; & \$env:ComSpec /d /c \$cmd; exit \$LASTEXITCODE\""
fi
local count value
count=$(getXMLNodeCount "$asset" "$command") || return 1
@@ -1957,12 +1968,49 @@ prepareSetupScript() {
[ -n "$staged" ] || return 0
stageHiddenLogonLauncher "$stage" || return 1
updateSetupScript "$staged" "$asset" || return 1
finalizeSetupScript "$staged" || return 1
return 0
}
stageHiddenLogonLauncher() {
local stage="$1"
usesWscriptLogonLauncher || return 0
local target="$stage/\$OEM\$/\$\$/Setup/Scripts/RunHidden.vbs"
if ! mkdir -p "$(dirname "$target")"; then
error "Failed to create hidden logon launcher directory!"
return 1
fi
if ! cat > "$target" <<'EOF'
Option Explicit
Dim shell, command, result
Set shell = CreateObject("WScript.Shell")
command = shell.ExpandEnvironmentStrings("%ComSpec% /d /c call " & Chr(34) & "%WINDIR%\Setup\Scripts\SetupComplete.cmd" & Chr(34) & " logon")
result = shell.Run(command, 0, True)
WScript.Quit result
EOF
then
error "Failed to create hidden logon launcher!"
return 1
fi
if ! unix2dos -q "$target"; then
error "Failed to convert hidden logon launcher to DOS format!"
return 1
fi
return 0
}
updateSetupScript() {
local script="$1"
+1033 -95
View File
File diff suppressed because it is too large Load Diff
+2 -18
View File
@@ -113,9 +113,9 @@ parseVersion() {
VERSION="win2019-hv" ;;
"2012" | "2012r2" | "win2012" | "win2012r2" | "windows2012" | "windows 2012" )
VERSION="win2012r2-eval" ;;
"2008" | "2008r2" | "win2008" | "win2008r2" | "windows2008" | "windows 2008" )
"2008" | "2008r2" | "2k8" | "win2008" | "win2008r2" | "windows2008" | "windows 2008" )
VERSION="win2008r2" ;;
"2003" | "2003r2" | "win2003" | "win2003r2" | "windows2003" | "windows 2003" )
"2003" | "2003r2" | "2k3" | "win2003" | "win2003r2" | "windows2003" | "windows 2003" )
VERSION="win2003r2" ;;
"core11" | "core 11" )
VERSION="core11"
@@ -875,22 +875,6 @@ supportsSIF() {
return 1
}
supportsACPI() {
local id="$1"
case "${id,,}" in
"reactos" )
# If the ISO is a Live-CD it will ignore ACPI signals.
hasSystemImage && return 1 ;;
esac
return 0
}
supportsBootKey() {
local id="$1"
+67 -14
View File
@@ -388,7 +388,7 @@ finishInstall() {
local aborted="$2"
local boot="$3"
local base secure=0
local base file bios target
if ! hasImage "$iso"; then
error "Failed to find ISO file: $iso" && return 1
@@ -400,7 +400,7 @@ finishInstall() {
fi
fi
local file="$STORAGE/windows.ver"
file="$(stateFile "ver")"
cp -f /etc/version "$file" || {
error "Failed to save the Windows installation version!"
return 1
@@ -435,17 +435,16 @@ finishInstall() {
# Aborted Win11 installs boot without any answer file present,
# so enable Secure Boot and TPM to satisfy its hardware checks.
if enabled "$aborted" || enabled "$MANUAL"; then
[[ "${DETECTED,,}" == "win11"* ]] && secure=1
fi
if (( secure )); then
if [[ "${DETECTED,,}" == "win11"* ]]; then
BOOT_MODE="windows_secure"
writeState "mode" "$BOOT_MODE" || {
error "Failed to save the Windows boot mode!"
return 1
}
BOOT_MODE="windows_secure"
writeState "mode" "$BOOT_MODE" || {
error "Failed to save the Windows boot mode!"
return 1
}
fi
fi
fi
@@ -460,12 +459,12 @@ finishInstall() {
if [[ "$SYSTEM" == "$TMP/"* ]]; then
if ! mv -f -- "$SYSTEM" "$STORAGE/windows.img"; then
if ! mv -f -- "$SYSTEM" "$(stateFile "img")"; then
error "Failed to finalize the Windows system image!"
return 1
fi
BOOT="$STORAGE/windows.img"
BOOT="$(stateFile "img")"
else
@@ -481,6 +480,36 @@ finishInstall() {
BOOT="$SYSTEM"
fi
if ! setOwner "$BOOT"; then
warn "failed to set the owner for \"$BOOT\" !"
fi
fi
if [ -n "${BIOS:-}" ]; then
bios="$(stateFile "bios")"
target="${bios}.tmp"
if ! cp -f -- "$BIOS" "$target"; then
rm -f -- "$target"
error "Failed to copy the BIOS file!"
return 1
fi
if ! mv -f -- "$target" "$bios"; then
rm -f -- "$target"
error "Failed to finalize the BIOS file!"
return 1
fi
BIOS="$bios"
if ! setOwner "$BIOS"; then
warn "failed to set the owner for \"$BIOS\" !"
fi
fi
if ! rm -rf -- "$TMP"; then
@@ -964,9 +993,33 @@ isLegacyBoot() {
[[ "${BOOT_MODE,,}" == "windows_legacy" ]]
}
hasMarker() {
[ -f "$(stateFile "$1")" ]
}
hasBootMarker() {
[ -f "$STORAGE/windows.boot" ]
[ -f "$(stateFile "boot")" ]
}
createMarker() {
local marker
marker="$(stateFile "$1")"
if ! touch "$marker"; then
warn "failed to create marker \"$marker\" !"
return 1
fi
if ! setOwner "$marker"; then
rm -f "$marker"
warn "failed to set the owner for \"$marker\" !"
return 1
fi
return 0
}
hasImage() {
@@ -991,7 +1044,7 @@ getSystemImage() {
return 0
fi
image="$STORAGE/windows.img"
image="$(stateFile "img")"
hasImage "$image" || return 1
echo "$image"
+27 -12
View File
@@ -15,7 +15,6 @@ setMachine() {
return 1
fi
writeState "vga" "std" || return 1
writeState "mode" "windows_legacy" || return 1
case "${id,,}" in
@@ -23,25 +22,27 @@ setMachine() {
"win9"* | "winnt4" | "win2k"* | "reactos" )
writeState "old" "pc" || return 1
writeState "type" "auto" || return 1
writeState "type" "auto" || return 1 ;;
esac
case "${id,,}" in
"win95" | "winnt4" )
"winnt4" | "win2k"* )
writeState "vga" "cirrus" || return 1 ;;
*) writeState "vga" "std" || return 1 ;;
esac
case "${id,,}" in
"win9"* | "winnt4" )
writeState "usb" "N" || return 1
writeState "port" "on" || return 1
writeState "net" "pcnet" || return 1
writeState "sound" "sb16" || return 1 ;;
"win98" | "win9x" )
writeState "port" "on" || return 1
writeState "net" "pcnet" || return 1
writeState "sound" "sb16" || return 1
writeState "usb" "pci-ohci" || return 1 ;;
writeState "sound" "AC97" || return 1 ;;
"win2k"* )
@@ -63,13 +64,23 @@ setMachine() {
if isReactOSLiveCD "$iso"; then
SYSTEM="$iso"
createMarker "kill" || return 1
fi ;;
esac
fi
restoreBootMode || return 1
restoreMachine || return 1
restoreBootMode || return 1
case "${id,,}" in
"win95" | "winnt4" )
# Windows 95 does not support ACPI so disable graceful shutdown
createMarker "kill" || return 1 ;;
esac
case "${id,,}" in
@@ -135,6 +146,10 @@ restoreMachineState() {
restoreState "CPU_MODEL" "cpu" || return 1
restoreState "DISK_TYPE" "type" || return 1
if [ -z "${BIOS:-}" ] && [ -s "$(stateFile "bios")" ]; then
BIOS="$(stateFile "bios")"
fi
mergeState "CPU_FLAGS" "flag" "," || return 1
mergeState "ARGUMENTS" "args" " " || return 1
+9 -24
View File
@@ -398,18 +398,7 @@ markWindowsBooted() {
# now booting from the installed disk rather than from setup media.
ready || return 0
local marker="$STORAGE/windows.boot"
if ! touch "$marker"; then
warn "failed to create Windows installation marker!"
return 0
fi
if ! setOwner "$marker"; then
rm -f "$marker"
warn "failed to set the owner for \"$marker\" !"
return 0
fi
createMarker "boot" || return 0
if ! disabled "$REMOVE"; then
case "${BOOT,,}" in
@@ -506,20 +495,16 @@ gracefulShutdown() {
finish "$code"
fi
if ! supportsACPI "$DETECTED"; then
if [[ "${DETECTED,,}" != "reactos" ]]; then
info "This $(app) version does not support ACPI shutdown, decreasing timeout to 10 seconds..."
TIMEOUT=13
else
info "ReactOS LiveCD does not support ACPI shutdown, decreasing timeout to 1 second..."
TIMEOUT=7
fi
elif hasSystemImage && ! hasBootMarker; then
info "$(app) will ignore ACPI signals during setup, decreasing timeout to 10 seconds..."
TIMEOUT=13
elif ! ready; then
if hasMarker "kill"; then
info "This $(app) version does not support ACPI shutdown, decreasing timeout to 1 second..."
TIMEOUT=7
elif ! ready || { hasSystemImage && ! hasBootMarker; }; then
info "$(app) will ignore ACPI signals during setup, decreasing timeout to 10 seconds..."
TIMEOUT=13
fi
normalizeTimeout 105
+25 -11
View File
@@ -10,6 +10,9 @@ SIFInstall() {
local shortcut="Y"
local drivers="/tmp/drivers"
local msg="Preparing $desc installation..."
info "$msg" && html "$msg"
if disabled "$SHORTCUT" || disabled "${SAMBA:-Y}"; then
shortcut="N"
fi
@@ -69,8 +72,8 @@ SIFInstall() {
oem=$(writeCommand "$install") || return 1
[ -z "$WIDTH" ] && WIDTH="1280"
[ -z "$HEIGHT" ] && HEIGHT="720"
[ -z "$WIDTH" ] && WIDTH="1024"
[ -z "$HEIGHT" ] && HEIGHT="768"
validateResolution "WIDTH" "$WIDTH" 320 || return 1
validateResolution "HEIGHT" "$HEIGHT" 200 || return 1
@@ -551,7 +554,7 @@ writeSIF() {
' AutoPartition=1' \
' MsDosInitiated="0"' \
' UnattendedInstall="Yes"' \
' AutomaticUpdates="Yes"' \
' AutomaticUpdates="No"' \
'' \
'[Unattended]' \
' UnattendSwitch=Yes' \
@@ -658,6 +661,9 @@ writeRegistry() {
'[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\wscsvc]' \
'"Start"=dword:00000004' \
'' \
'[HKEY_LOCAL_MACHINE\SOFTWARE\Policies\Microsoft\Windows\WindowsUpdate\AU]' \
'"NoAutoUpdate"=dword:00000001' \
'' \
'[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\SharedAccess\Parameters\FirewallPolicy\StandardProfile\GloballyOpenPorts\List]' \
'"3389:TCP"="3389:TCP:*:Enabled:@xpsp2res.dll,-22009"' \
'' \
@@ -712,6 +718,7 @@ appendRegistry() {
'[HKEY_CURRENT_USER\Control Panel\Desktop]' \
'"SCRNSAVE.EXE"="off"' \
'"ScreenSaveActive"="0"' \
'"DragFullWindows"="1"' \
'"MenuShowDelay"="100"' \
'' \
'[HKEY_CURRENT_USER\Control Panel\Desktop\WindowMetrics]' \
@@ -733,6 +740,12 @@ appendRegistry() {
if [[ "$driver" == "2k" ]]; then
{
printf '%s\n' \
'[HKEY_CURRENT_USER\Control Panel\PowerCfg]' \
'"CurrentPowerPolicy"="3"' \
'' \
'[HKEY_CURRENT_USER\Control Panel\PowerCfg\PowerPolicies\3]' \
'"Policies"=hex:01,00,00,00,00,00,00,00,01,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,32,32,00,00,04,00,00,00,04,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,00,01,64,64,64,64,00,00' \
'' \
'[HKEY_USERS\.DEFAULT\Software\Microsoft\Windows\CurrentVersion\Runonce]' \
'"^SetupICWDesktop"=-' ''
} | unix2dos >> "$dir/\$OEM\$/install.reg" || return 1
@@ -857,15 +870,16 @@ writeVBS() {
'Set FSO = WScript.CreateObject("Scripting.FileSystemObject")' \
'PowerCfg = Shell.ExpandEnvironmentStrings("%SystemRoot%\System32\POWERCFG.EXE")' \
'' \
'Shell.RegWrite "HKCU\Control Panel\Desktop\SCRNSAVE.EXE", "off", "REG_SZ"' \
'Shell.RegWrite "HKCU\Control Panel\Desktop\ScreenSaveActive", "0", "REG_SZ"' \
'' \
'If FSO.FileExists(PowerCfg) Then' \
' Err.Clear' \
' Policy = Shell.RegRead("HKCU\Control Panel\PowerCfg\CurrentPowerPolicy")' \
' If Err.Number = 0 Then' \
' Cmd = Chr(34) & PowerCfg & Chr(34) & " /CHANGE " & Policy & " /NUMERICAL "' \
' For Each Setting In Array("/monitor-timeout-ac", "/monitor-timeout-dc", "/disk-timeout-ac", "/disk-timeout-dc", "/standby-timeout-ac", "/standby-timeout-dc")' \
' Shell.Run Cmd & Setting & " 0", 0, True' \
' Next' \
' End If' \
' Policy = 3' \
' Cmd = Chr(34) & PowerCfg & Chr(34) & " /CHANGE " & Policy & " /NUMERICAL "' \
' For Each Setting In Array("/monitor-timeout-ac", "/monitor-timeout-dc", "/disk-timeout-ac", "/disk-timeout-dc", "/standby-timeout-ac", "/standby-timeout-dc")' \
' Shell.Run Cmd & Setting & " 0", 0, True' \
' Next' \
' Shell.Run Chr(34) & PowerCfg & Chr(34) & " /SETACTIVE 3 /NUMERICAL", 0, True' \
'End If' \
''
} | unix2dos > "$power" || return 1