Compare commits

...

8 Commits
v3.03 ... v3.04

Author SHA1 Message Date
Kroese
f7986f57ce feat: Improved installation (#483) 2024-05-10 18:21:41 +02:00
Kroese
5a000c1f9e feat: Store installation type (#477) 2024-05-09 15:59:06 +02:00
Kroese
3b7e2373f7 feat: Store installation type (#476) 2024-05-09 15:47:46 +02:00
Kroese
8bbd87df40 feat: Refactor platform code (#472) 2024-05-09 11:19:34 +02:00
Kroese
fd1fd1c48f fix: Disable Mido debug output (#470) 2024-05-08 23:25:15 +02:00
Kroese
f99032312c feat: Detect architecture in ISO (#463) 2024-05-07 02:11:59 +02:00
Kroese
b56db85787 docs: Update issues template (#461) 2024-05-05 22:41:38 +02:00
Kroese
5ff0e3dae5 Update QUESTION.yml (#460) 2024-05-05 22:37:43 +02:00
6 changed files with 350 additions and 176 deletions

View File

@@ -3,10 +3,20 @@ description: General questions about the container
title: "[Question]: " title: "[Question]: "
labels: ["question"] labels: ["question"]
body: body:
- type: markdown - type: checkboxes
attributes: attributes:
value: | label: Is your question not already answered in the FAQ?
Please do not use this form for technical issues, and make sure to check the [FAQ](https://github.com/dockur/windows/blob/master/readme.md) first! description: Please read the [FAQ](https://github.com/dockur/windows/blob/master/readme.md) carefully to avoid asking duplicate questions.
options:
- label: I made sure the question is not listed in the [FAQ](https://github.com/dockur/windows/blob/master/readme.md).
required: true
- type: checkboxes
attributes:
label: Is this a general question and not a technical issue?
description: For technical issues you must use the [bug report](https://github.com/dockur/windows/issues/new?assignees=&labels=bug&projects=&template=BUG_REPORT.yml&title=%5BBug%5D%3A+) form instead. It contains all the right fields (system info, logfiles, etc.) we need in order to be able to help you.
options:
- label: I am sure my question is not about a technical issue.
required: true
- type: textarea - type: textarea
id: question id: question
attributes: attributes:

View File

@@ -291,6 +291,19 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
Please note that in this mode, the container and Windows will each have their own separate IPs. The container will keep the macvlan IP, and Windows will use the DHCP IP. Please note that in this mode, the container and Windows will each have their own separate IPs. The container will keep the macvlan IP, and Windows will use the DHCP IP.
* ### How do I add multiple disks?
To create additional disks, modify your compose file like this:
```yaml
environment:
DISK2_SIZE: "32G"
DISK3_SIZE: "64G"
volumes:
- /home/example:/storage2
- /mnt/data/example:/storage3
```
* ### How do I pass-through a disk? * ### How do I pass-through a disk?
It is possible to pass-through disk devices directly by adding them to your compose file in this way: It is possible to pass-through disk devices directly by adding them to your compose file in this way:

View File

@@ -6,9 +6,9 @@ set -Eeuo pipefail
: "${REMOVE:=""}" : "${REMOVE:=""}"
: "${VERSION:=""}" : "${VERSION:=""}"
: "${DETECTED:=""}" : "${DETECTED:=""}"
: "${PLATFORM:="x64"}"
MIRRORS=5 MIRRORS=5
PLATFORM="x64"
parseVersion() { parseVersion() {
@@ -41,23 +41,23 @@ parseVersion() {
;; ;;
"7" | "7e" | "win7" | "win7e" | "windows7" | "windows 7" ) "7" | "7e" | "win7" | "win7e" | "windows7" | "windows 7" )
VERSION="win7${PLATFORM,,}" VERSION="win7${PLATFORM,,}"
DETECTED="win7${PLATFORM,,}-enterprise" [ -z "$DETECTED" ] && DETECTED="win7${PLATFORM,,}-enterprise"
;; ;;
"7u" | "win7u" | "windows7u" | "windows 7u" ) "7u" | "win7u" | "windows7u" | "windows 7u" )
VERSION="win7${PLATFORM,,}-ultimate" VERSION="win7${PLATFORM,,}-ultimate"
;; ;;
"vista" | "winvista" | "windowsvista" | "windows vista" ) "vista" | "winvista" | "windowsvista" | "windows vista" )
VERSION="winvista${PLATFORM,,}" VERSION="winvista${PLATFORM,,}"
DETECTED="winvista${PLATFORM,,}-enterprise" [ -z "$DETECTED" ] && DETECTED="winvista${PLATFORM,,}-enterprise"
;; ;;
"vistau" | "winvistau" | "windowsvistau" | "windows vistau" ) "vistu" | "winvistu" | "windowsvistu" | "windows vistu" )
VERSION="winvista${PLATFORM,,}-ultimate" VERSION="winvista${PLATFORM,,}-ultimate"
;; ;;
"xp" | "xp32" | "winxp" | "windowsxp" | "windows xp" ) "xp" | "xp32" | "xpx86" | "winxp" | "winxp86" | "windowsxp" | "windows xp" )
VERSION="winxpx86" VERSION="winxpx86"
;; ;;
"xp64" | "winxp64" | "windowsxp64" | "windows xp 64" ) "xp64" | "xpx64" | "winxp64" | "winxpx64" | "windowsxp64" | "windowsxpx64" )
VERSION="winxpx64" VERSION="winxp${PLATFORM,,}"
;; ;;
"22" | "2022" | "win22" | "win2022" | "windows2022" | "windows 2022" ) "22" | "2022" | "win22" | "win2022" | "windows2022" | "windows 2022" )
VERSION="win2022-eval" VERSION="win2022-eval"
@@ -76,27 +76,27 @@ parseVersion() {
;; ;;
"core11" | "core 11" ) "core11" | "core 11" )
VERSION="core11" VERSION="core11"
DETECTED="win11${PLATFORM,,}" [ -z "$DETECTED" ] && DETECTED="win11${PLATFORM,,}"
;; ;;
"tiny11" | "tiny 11" ) "tiny11" | "tiny 11" )
VERSION="tiny11" VERSION="tiny11"
DETECTED="win11${PLATFORM,,}" [ -z "$DETECTED" ] && DETECTED="win11${PLATFORM,,}"
;; ;;
"tiny10" | "tiny 10" ) "tiny10" | "tiny 10" )
VERSION="tiny10" VERSION="tiny10"
DETECTED="win10${PLATFORM,,}-ltsc" [ -z "$DETECTED" ] && DETECTED="win10${PLATFORM,,}-ltsc"
;; ;;
"iot11" | "11iot" | "win11-iot" | "win11${PLATFORM,,}-iot" | "win11${PLATFORM,,}-enterprise-iot-eval" ) "iot11" | "11iot" | "win11-iot" | "win11${PLATFORM,,}-iot" | "win11${PLATFORM,,}-enterprise-iot-eval" )
DETECTED="win11${PLATFORM,,}-iot"
VERSION="win11${PLATFORM,,}-enterprise-iot-eval" VERSION="win11${PLATFORM,,}-enterprise-iot-eval"
[ -z "$DETECTED" ] && DETECTED="win11${PLATFORM,,}-iot"
;; ;;
"iot10" | "10iot" | "win10-iot" | "win10${PLATFORM,,}-iot" | "win10${PLATFORM,,}-enterprise-iot-eval" ) "iot10" | "10iot" | "win10-iot" | "win10${PLATFORM,,}-iot" | "win10${PLATFORM,,}-enterprise-iot-eval" )
DETECTED="win10${PLATFORM,,}-iot"
VERSION="win10${PLATFORM,,}-enterprise-iot-eval" VERSION="win10${PLATFORM,,}-enterprise-iot-eval"
[ -z "$DETECTED" ] && DETECTED="win10${PLATFORM,,}-iot"
;; ;;
"ltsc10" | "10ltsc" | "win10-ltsc" | "win10${PLATFORM,,}-ltsc" | "win10${PLATFORM,,}-enterprise-ltsc-eval" ) "ltsc10" | "10ltsc" | "win10-ltsc" | "win10${PLATFORM,,}-ltsc" | "win10${PLATFORM,,}-enterprise-ltsc-eval" )
DETECTED="win10${PLATFORM,,}-ltsc"
VERSION="win10${PLATFORM,,}-enterprise-ltsc-eval" VERSION="win10${PLATFORM,,}-enterprise-ltsc-eval"
[ -z "$DETECTED" ] && DETECTED="win10${PLATFORM,,}-ltsc"
;; ;;
esac esac
@@ -146,75 +146,39 @@ printEdition() {
[[ "$result" == "x" ]] && echo "$desc" && return 0 [[ "$result" == "x" ]] && echo "$desc" && return 0
case "${id,,}" in case "${id,,}" in
"win7${PLATFORM,,}-home"* ) *"-iot" )
edition="IoT"
;;
*"-ltsc" )
edition="LTSC"
;;
*"-home" )
edition="Home" edition="Home"
;; ;;
"win7${PLATFORM,,}-starter"* ) *"-starter" )
edition="Starter" edition="Starter"
;; ;;
"win7${PLATFORM,,}-ultimate"* ) *"-ultimate" )
edition="Ultimate" edition="Ultimate"
;; ;;
"win7${PLATFORM,,}-enterprise"* ) *"-enterprise" )
edition="Enterprise" edition="Enterprise"
;; ;;
*"-education" )
edition="Education"
;;
*"-enterprise-eval" )
edition="Enterprise (Evaluation)"
;;
"win7"* ) "win7"* )
edition="Professional" edition="Professional"
;; ;;
"win8${PLATFORM,,}-enterprise"* ) "win8"* | "win10"* | "win11"* )
edition="Enterprise"
;;
"win8"* )
edition="Pro"
;;
"win10${PLATFORM,,}-iot"* )
edition="IoT"
;;
"win10${PLATFORM,,}-ltsc"* )
edition="LTSC"
;;
"win10${PLATFORM,,}-home"* )
edition="Home"
;;
"win10${PLATFORM,,}-education"* )
edition="Education"
;;
"win10${PLATFORM,,}-enterprise"* )
edition="Enterprise"
;;
"win10"* )
edition="Pro"
;;
"win11${PLATFORM,,}-iot"* )
edition="IoT"
;;
"win11${PLATFORM,,}-home"* )
edition="Home"
;;
"win11${PLATFORM,,}-education"* )
edition="Education"
;;
"win11${PLATFORM,,}-enterprise"* )
edition="Enterprise"
;;
"win11"* )
edition="Pro" edition="Pro"
;; ;;
"winxp"* ) "winxp"* )
edition="Professional" edition="Professional"
;; ;;
"winvista${PLATFORM,,}-home"* )
edition="Home"
;;
"winvista${PLATFORM,,}-starter"* )
edition="Starter"
;;
"winvista${PLATFORM,,}-ultimate"* )
edition="Ultimate"
;;
"winvista${PLATFORM,,}-enterprise"* )
edition="Enterprise"
;;
"winvista"* ) "winvista"* )
edition="Business" edition="Business"
;; ;;
@@ -223,7 +187,6 @@ printEdition() {
;; ;;
esac esac
[[ "${id,,}" == *"-eval" ]] && edition="$edition (Evaluation)"
[ -n "$edition" ] && result="$result $edition" [ -n "$edition" ] && result="$result $edition"
echo "$result" echo "$result"
@@ -235,25 +198,38 @@ fromFile() {
local id="" local id=""
local desc="$1" local desc="$1"
local file="${1,,}" local file="${1,,}"
local arch="${PLATFORM,,}"
case "${file/ /_}" in
*"_x64_"* | *"_x64."*)
arch="x64"
;;
*"_x86_"* | *"_x86."*)
arch="x86"
;;
*"_arm64_"* | *"_arm64."*)
arch="arm64"
;;
esac
case "${file/ /_}" in case "${file/ /_}" in
"win7"* | "win_7"* | *"windows7"* | *"windows_7"* ) "win7"* | "win_7"* | *"windows7"* | *"windows_7"* )
id="win7${PLATFORM,,}" id="win7${arch}"
;; ;;
"win8"* | "win_8"* | *"windows8"* | *"windows_8"* ) "win8"* | "win_8"* | *"windows8"* | *"windows_8"* )
id="win81${PLATFORM,,}" id="win81${arch}"
;; ;;
"win10"*| "win_10"* | *"windows10"* | *"windows_10"* ) "win10"*| "win_10"* | *"windows10"* | *"windows_10"* )
id="win10${PLATFORM,,}" id="win10${arch}"
;; ;;
"win11"* | "win_11"* | *"windows11"* | *"windows_11"* ) "win11"* | "win_11"* | *"windows11"* | *"windows_11"* )
id="win11${PLATFORM,,}" id="win11${arch}"
;; ;;
*"winxp"* | *"win_xp"* | *"windowsxp"* | *"windows_xp"* ) *"winxp"* | *"win_xp"* | *"windowsxp"* | *"windows_xp"* )
id="winxpx86" id="winxpx86"
;; ;;
*"winvista"* | *"win_vista"* | *"windowsvista"* | *"windows_vista"* ) *"winvista"* | *"win_vista"* | *"windowsvista"* | *"windows_vista"* )
id="winvista${PLATFORM,,}" id="winvista${arch}"
;; ;;
"tiny11core"* | "tiny11_core"* | "tiny_11_core"* ) "tiny11core"* | "tiny11_core"* | "tiny_11_core"* )
id="core11" id="core11"
@@ -296,6 +272,7 @@ fromName() {
local id="" local id=""
local name="$1" local name="$1"
local arch="$2"
case "${name,,}" in case "${name,,}" in
*"server 2025"* ) id="win2025" ;; *"server 2025"* ) id="win2025" ;;
@@ -304,11 +281,11 @@ fromName() {
*"server 2016"* ) id="win2016" ;; *"server 2016"* ) id="win2016" ;;
*"server 2012"* ) id="win2012r2" ;; *"server 2012"* ) id="win2012r2" ;;
*"server 2008"* ) id="win2008r2" ;; *"server 2008"* ) id="win2008r2" ;;
*"windows 7"* ) id="win7${PLATFORM,,}" ;; *"windows 7"* ) id="win7${arch}" ;;
*"windows 8"* ) id="win81${PLATFORM,,}" ;; *"windows 8"* ) id="win81${arch}" ;;
*"windows 10"* ) id="win10${PLATFORM,,}" ;; *"windows 10"* ) id="win10${arch}" ;;
*"windows 11"* ) id="win11${PLATFORM,,}" ;; *"windows 11"* ) id="win11${arch}" ;;
*"windows vista"* ) id="winvista${PLATFORM,,}" ;; *"windows vista"* ) id="winvista${arch}" ;;
esac esac
echo "$id" echo "$id"
@@ -319,8 +296,9 @@ getVersion() {
local id local id
local name="$1" local name="$1"
local arch="$2"
id=$(fromName "$name") id=$(fromName "$name" "$arch")
case "${id,,}" in case "${id,,}" in
"win7"* | "winvista"* ) "win7"* | "winvista"* )
@@ -571,11 +549,26 @@ getLink1() {
sum="0b738b55a5ea388ad016535a5c8234daf2e5715a0638488ddd8a228a836055a1" sum="0b738b55a5ea388ad016535a5c8234daf2e5715a0638488ddd8a228a836055a1"
url="$host/7/en_windows_7_with_sp1_${PLATFORM,,}.iso" url="$host/7/en_windows_7_with_sp1_${PLATFORM,,}.iso"
;; ;;
"win7x86" | "win7x86-enterprise" )
size=2434502656
sum="8bdd46ff8cb8b8de9c4aba02706629c8983c45e87da110e64e13be17c8434dad"
url="$host/7/en_windows_7_enterprise_with_sp1_x86_dvd_u_677710.iso"
;;
"win7x86-ultimate" )
size=2564411392
sum="99f3369c90160816be07093dbb0ac053e0a84e52d6ed1395c92ae208ccdf67e5"
url="$host/7/en_windows_7_with_sp1_x86.iso"
;;
"winvista${PLATFORM,,}-ultimate" ) "winvista${PLATFORM,,}-ultimate" )
size=3861460992 size=3861460992
sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78" sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78"
url="$host/vista/en_windows_vista_sp2_${PLATFORM,,}_dvd_342267.iso" url="$host/vista/en_windows_vista_sp2_${PLATFORM,,}_dvd_342267.iso"
;; ;;
"winvistax86-ultimate" )
size=3243413504
sum="9c36fed4255bd05a8506b2da88f9aad73643395e155e609398aacd2b5276289c"
url="$host/vista/en_windows_vista_with_sp2_x86_dvd_342266.iso"
;;
"winxpx86" ) "winxpx86" )
size=617756672 size=617756672
sum="62b6c91563bad6cd12a352aa018627c314cfc5162d8e9f8af0756a642e602a46" sum="62b6c91563bad6cd12a352aa018627c314cfc5162d8e9f8af0756a642e602a46"
@@ -637,6 +630,16 @@ getLink2() {
sum="36f4fa2416d0982697ab106e3a72d2e120dbcdb6cc54fd3906d06120d0653808" sum="36f4fa2416d0982697ab106e3a72d2e120dbcdb6cc54fd3906d06120d0653808"
url="$host/Windows%207/en_windows_7_ultimate_with_sp1_${PLATFORM,,}_dvd_u_677332.iso" url="$host/Windows%207/en_windows_7_ultimate_with_sp1_${PLATFORM,,}_dvd_u_677332.iso"
;; ;;
"win7x86" | "win7x86enterprise" )
size=2434502656
sum="8bdd46ff8cb8b8de9c4aba02706629c8983c45e87da110e64e13be17c8434dad"
url="$host/Windows%207/en_windows_7_enterprise_with_sp1_x86_dvd_u_677710.iso"
;;
"win7x86-ultimate" )
size=2564476928
sum="e2c009a66d63a742941f5087acae1aa438dcbe87010bddd53884b1af6b22c940"
url="$host/Windows%207/en_windows_7_ultimate_with_sp1_x86_dvd_u_677460.iso"
;;
"winvista${PLATFORM,,}" | "winvista${PLATFORM,,}-enterprise" ) "winvista${PLATFORM,,}" | "winvista${PLATFORM,,}-enterprise" )
size=3205953536 size=3205953536
sum="0a0cd511b3eac95c6f081419c9c65b12317b9d6a8d9707f89d646c910e788016" sum="0a0cd511b3eac95c6f081419c9c65b12317b9d6a8d9707f89d646c910e788016"
@@ -647,6 +650,16 @@ getLink2() {
sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78" sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78"
url="$host/Windows%20Vista/en_windows_vista_sp2_${PLATFORM,,}_dvd_342267.iso" url="$host/Windows%20Vista/en_windows_vista_sp2_${PLATFORM,,}_dvd_342267.iso"
;; ;;
"winvistax86" | "winvistax86-enterprise" )
size=2420981760
sum="54e2720004041e7db988a391543ea5228b0affc28efcf9303d2d0ff9402067f5"
url="$host/Windows%20Vista/en_windows_vista_enterprise_sp2_x86_dvd_342329.iso"
;;
"winvistax86-ultimate" )
size=3243413504
sum="9c36fed4255bd05a8506b2da88f9aad73643395e155e609398aacd2b5276289c"
url="$host/Windows%20Vista/en_windows_vista_with_sp2_x86_dvd_342266.iso"
;;
"winxpx86" ) "winxpx86" )
size=617756672 size=617756672
sum="62b6c91563bad6cd12a352aa018627c314cfc5162d8e9f8af0756a642e602a46" sum="62b6c91563bad6cd12a352aa018627c314cfc5162d8e9f8af0756a642e602a46"
@@ -791,6 +804,16 @@ getLink4() {
sum="36f4fa2416d0982697ab106e3a72d2e120dbcdb6cc54fd3906d06120d0653808" sum="36f4fa2416d0982697ab106e3a72d2e120dbcdb6cc54fd3906d06120d0653808"
url="$host/en_windows_7_ultimate_with_sp1_${PLATFORM,,}_dvd_u_677332.iso" url="$host/en_windows_7_ultimate_with_sp1_${PLATFORM,,}_dvd_u_677332.iso"
;; ;;
"win7x86" | "win7x86enterprise" )
size=2434502656
sum="8bdd46ff8cb8b8de9c4aba02706629c8983c45e87da110e64e13be17c8434dad"
url="$host/en_windows_7_enterprise_with_sp1_x86_dvd_u_677710.iso"
;;
"win7x86-ultimate" )
size=2564476928
sum="e2c009a66d63a742941f5087acae1aa438dcbe87010bddd53884b1af6b22c940"
url="$host/en_windows_7_ultimate_with_sp1_x86_dvd_u_677460.iso"
;;
"winvista${PLATFORM,,}" | "winvista${PLATFORM,,}-enterprise" ) "winvista${PLATFORM,,}" | "winvista${PLATFORM,,}-enterprise" )
size=3205953536 size=3205953536
sum="0a0cd511b3eac95c6f081419c9c65b12317b9d6a8d9707f89d646c910e788016" sum="0a0cd511b3eac95c6f081419c9c65b12317b9d6a8d9707f89d646c910e788016"
@@ -801,6 +824,16 @@ getLink4() {
sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78" sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78"
url="$host/en_windows_vista_sp2_${PLATFORM,,}_dvd_342267.iso" url="$host/en_windows_vista_sp2_${PLATFORM,,}_dvd_342267.iso"
;; ;;
"winvistax86" | "winvistax86-enterprise" )
size=2420981760
sum="54e2720004041e7db988a391543ea5228b0affc28efcf9303d2d0ff9402067f5"
url="$host/en_windows_vista_enterprise_sp2_x86_dvd_342329.iso"
;;
"winvistax86-ultimate" )
size=3243413504
sum="9c36fed4255bd05a8506b2da88f9aad73643395e155e609398aacd2b5276289c"
url="$host/en_windows_vista_with_sp2_x86_dvd_342266.iso"
;;
esac esac
case "${ret,,}" in case "${ret,,}" in
@@ -951,7 +984,7 @@ migrateFiles() {
[[ "${version,,}" == "win7${PLATFORM,,}" ]] && file="en_windows_7_enterprise_with_sp1_${PLATFORM,,}_dvd_u_677651.iso" [[ "${version,,}" == "win7${PLATFORM,,}" ]] && file="en_windows_7_enterprise_with_sp1_${PLATFORM,,}_dvd_u_677651.iso"
[ ! -f "$STORAGE/$file" ] && return 0 [ ! -f "$STORAGE/$file" ] && return 0
! mv "$STORAGE/$file" "$base" && return 1 ! mv -f "$STORAGE/$file" "$base" && return 1
return 0 return 0
} }
@@ -1166,15 +1199,17 @@ prepareLegacy() {
local iso="$1" local iso="$1"
local dir="$2" local dir="$2"
local file="$dir/boot.img"
ETFS="boot.img" ETFS=$(basename "$file")
rm -f "$dir/$ETFS" [ -f "$file" ] && [ -s "$file" ] && return 0
rm -f "$file"
local len offset local len offset
len=$(isoinfo -d -i "$iso" | grep "Nsect " | grep -o "[^ ]*$") len=$(isoinfo -d -i "$iso" | grep "Nsect " | grep -o "[^ ]*$")
offset=$(isoinfo -d -i "$iso" | grep "Bootoff " | grep -o "[^ ]*$") offset=$(isoinfo -d -i "$iso" | grep "Bootoff " | grep -o "[^ ]*$")
dd "if=$iso" "of=$dir/$ETFS" bs=2048 "count=$len" "skip=$offset" status=none && return 0 dd "if=$iso" "of=$file" bs=2048 "count=$len" "skip=$offset" status=none && return 0
return 1 return 1
} }

View File

@@ -31,9 +31,7 @@ skipInstall() {
startInstall() { startInstall() {
html "Starting Windows..." html "Starting $APP..."
[ -z "$MANUAL" ] && MANUAL="N"
if [ -n "$CUSTOM" ]; then if [ -n "$CUSTOM" ]; then
@@ -61,20 +59,37 @@ startInstall() {
if [ -f "$ISO" ] && [ -s "$ISO" ]; then if [ -f "$ISO" ] && [ -s "$ISO" ]; then
local magic
local auto="16"
local manual="17"
local byte="$auto"
[[ "$MANUAL" == [Yy1]* ]] && byte="$manual"
# Check if the ISO was already processed by our script # Check if the ISO was already processed by our script
local magic=""
magic=$(dd if="$ISO" seek=0 bs=1 count=1 status=none | tr -d '\000') magic=$(dd if="$ISO" seek=0 bs=1 count=1 status=none | tr -d '\000')
magic="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')" magic="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
[[ "$magic" == "16" ]] && return 1
if [[ "$magic" == "$byte" ]]; then
if [ -z "$CUSTOM" ] || [ -n "$ORIGINAL" ]; then
return 1
fi
fi
fi fi
rm -rf "$TMP"
mkdir -p "$TMP"
if [ -z "$CUSTOM" ]; then if [ -z "$CUSTOM" ]; then
BOOT="$ISO" BOOT="$ISO"
ISO=$(basename "$ISO") ISO=$(basename "$ISO")
ISO="$TMP/$ISO" ISO="$TMP/$ISO"
if [ -f "$BOOT" ] && [ -s "$BOOT" ]; then
mv -f "$BOOT" "$ISO"
fi
else else
if [ -n "$ORIGINAL" ]; then if [ -n "$ORIGINAL" ]; then
@@ -90,8 +105,6 @@ startInstall() {
fi fi
rm -f "$BOOT" rm -f "$BOOT"
rm -rf "$TMP"
mkdir -p "$TMP"
return 0 return 0
} }
@@ -106,7 +119,9 @@ finishInstall() {
if [ -w "$iso" ] && [[ "$aborted" != [Yy1]* ]]; then if [ -w "$iso" ] && [[ "$aborted" != [Yy1]* ]]; then
# Mark ISO as prepared via magic byte # Mark ISO as prepared via magic byte
if ! printf '\x16' | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then local byte="16"
[[ "$MANUAL" == [Yy1]* ]] && byte="17"
if ! printf '%b' "\x$byte" | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then
error "Failed to set magic byte in ISO file: $iso" && return 1 error "Failed to set magic byte in ISO file: $iso" && return 1
fi fi
fi fi
@@ -115,7 +130,7 @@ finishInstall() {
rm -f "$STORAGE/windows.boot" rm -f "$STORAGE/windows.boot"
rm -f "$STORAGE/windows.mode" rm -f "$STORAGE/windows.mode"
cp /run/version "$STORAGE/windows.ver" cp -f /run/version "$STORAGE/windows.ver"
if [[ "${PLATFORM,,}" == "x64" ]]; then if [[ "${PLATFORM,,}" == "x64" ]]; then
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
@@ -171,19 +186,18 @@ detectCustom() {
base="${VERSION/\/storage\//}" base="${VERSION/\/storage\//}"
[[ "$base" == "."* ]] && base="${file:1}" [[ "$base" == "."* ]] && base="${file:1}"
[[ "$base" == *"/"* ]] && base="" [[ "$base" == *"/"* ]] && base=""
[ -n "$base" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname "$base" -printf "%f\n" | head -n 1) [ -n "$base" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname "$base" | head -n 1)
fi fi
[ -z "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso -printf "%f\n" | head -n 1) [ -z "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso | head -n 1)
[ -z "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.img -printf "%f\n" | head -n 1) [ -z "$file" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.img | head -n 1)
[ -n "$file" ] && file="$STORAGE/$file"
base="/custom.iso" base="/custom.iso"
[ -f "$base" ] && [ -s "$base" ] && file="$base" [ -f "$base" ] && [ -s "$base" ] && file="$base"
[ -z "$file" ] && return 0 if [ ! -f "$file" ] || [ ! -s "$file" ]; then
[ ! -f "$file" ] && return 0 return 0
[ ! -s "$file" ] && return 0 fi
size="$(stat -c%s "$file")" size="$(stat -c%s "$file")"
[ -z "$size" ] || [[ "$size" == "0" ]] && return 0 [ -z "$size" ] || [[ "$size" == "0" ]] && return 0
@@ -194,8 +208,8 @@ detectCustom() {
CUSTOM="$base" CUSTOM="$base"
ORIGINAL="$file" ORIGINAL="$file"
else else
CUSTOM="$file"
rm -f "$base" rm -f "$base"
CUSTOM="$file"
fi fi
return 0 return 0
@@ -279,7 +293,7 @@ verifyFile() {
local check="$4" local check="$4"
if [ -n "$size" ] && [[ "$total" != "$size" ]] && [[ "$size" != "0" ]]; then if [ -n "$size" ] && [[ "$total" != "$size" ]] && [[ "$size" != "0" ]]; then
warn "The downloaded file has an invalid size: $total bytes, while expected value was: $size bytes. Please report this at $SUPPORT/issues" warn "The downloaded file has an unexpected size: $total bytes, while expected value was: $size bytes. Please report this at $SUPPORT/issues"
fi fi
local hash="" local hash=""
@@ -431,10 +445,9 @@ downloadImage() {
tried="y" tried="y"
if getESD "$TMP/esd" "$version"; then if getESD "$TMP/esd" "$version"; then
local prev="$ISO"
ISO="${ISO%.*}.esd" ISO="${ISO%.*}.esd"
downloadFile "$ISO" "$ESD" "$ESD_SUM" "$ESD_SIZE" "$desc" && return 0 downloadFile "$ISO" "$ESD" "$ESD_SUM" "$ESD_SIZE" "$desc" && return 0
ISO="$prev" ISO="$iso"
fi fi
fi fi
@@ -497,20 +510,20 @@ extractESD() {
fi fi
local esdImageCount local esdImageCount
esdImageCount=$(wimlib-imagex info "${iso}" | awk '/Image Count:/ {print $3}') esdImageCount=$(wimlib-imagex info "$iso" | awk '/Image Count:/ {print $3}')
wimlib-imagex apply "$iso" 1 "${dir}" --quiet 2>/dev/null || { wimlib-imagex apply "$iso" 1 "$dir" --quiet 2>/dev/null || {
retVal=$? retVal=$?
error "Extracting $desc bootdisk failed" && return $retVal error "Extracting $desc bootdisk failed" && return $retVal
} }
local bootWimFile="${dir}/sources/boot.wim" local bootWimFile="$dir/sources/boot.wim"
local installWimFile="${dir}/sources/install.wim" local installWimFile="$dir/sources/install.wim"
local msg="Extracting $desc environment..." local msg="Extracting $desc environment..."
info "$msg" && html "$msg" info "$msg" && html "$msg"
wimlib-imagex export "${iso}" 2 "${bootWimFile}" --compress=LZX --chunk-size 32K --quiet || { wimlib-imagex export "$iso" 2 "$bootWimFile" --compress=LZX --chunk-size 32K --quiet || {
retVal=$? retVal=$?
error "Adding WinPE failed" && return ${retVal} error "Adding WinPE failed" && return ${retVal}
} }
@@ -518,7 +531,7 @@ extractESD() {
local msg="Extracting $desc setup..." local msg="Extracting $desc setup..."
info "$msg" && html "$msg" info "$msg" && html "$msg"
wimlib-imagex export "${iso}" 3 "$bootWimFile" --compress=LZX --chunk-size 32K --boot --quiet || { wimlib-imagex export "$iso" 3 "$bootWimFile" --compress=LZX --chunk-size 32K --boot --quiet || {
retVal=$? retVal=$?
error "Adding Windows Setup failed" && return ${retVal} error "Adding Windows Setup failed" && return ${retVal}
} }
@@ -540,11 +553,11 @@ extractESD() {
fi fi
for (( imageIndex=4; imageIndex<=esdImageCount; imageIndex++ )); do for (( imageIndex=4; imageIndex<=esdImageCount; imageIndex++ )); do
imageEdition=$(wimlib-imagex info "${iso}" ${imageIndex} | grep '^Description:' | sed 's/Description:[ \t]*//') imageEdition=$(wimlib-imagex info "$iso" ${imageIndex} | grep '^Description:' | sed 's/Description:[ \t]*//')
[[ "${imageEdition,,}" != "${edition,,}" ]] && continue [[ "${imageEdition,,}" != "${edition,,}" ]] && continue
wimlib-imagex export "${iso}" ${imageIndex} "${installWimFile}" --compress=LZMS --chunk-size 128K --quiet || { wimlib-imagex export "$iso" ${imageIndex} "$installWimFile" --compress=LZMS --chunk-size 128K --quiet || {
retVal=$? retVal=$?
error "Addition of ${imageIndex} to the $desc image failed" && return $retVal error "Addition of $imageIndex to the $desc image failed" && return $retVal
} }
return 0 return 0
done done
@@ -604,75 +617,112 @@ extractImage() {
setXML() { setXML() {
[[ "$MANUAL" == [Yy1]* ]] && return 0
local file="/custom.xml" local file="/custom.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0 [ ! -f "$file" ] || [ ! -s "$file" ] && file="$STORAGE/custom.xml"
[ ! -f "$file" ] || [ ! -s "$file" ] && file="/run/assets/custom.xml"
[ ! -f "$file" ] || [ ! -s "$file" ] && file="$1"
[ ! -f "$file" ] || [ ! -s "$file" ] && file="/run/assets/$DETECTED.xml"
[ ! -f "$file" ] || [ ! -s "$file" ] && return 1
file="$STORAGE/custom.xml" XML="$file"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0 return 0
}
file="/run/assets/custom.xml" getPlatform() {
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
file="$1" local xml="$1"
[ -z "$file" ] && file="/run/assets/$DETECTED.xml" local tag="ARCH"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0 local platform="x64"
local arch
return 1 arch=$(sed -n "/$tag/{s/.*<$tag>\(.*\)<\/$tag>.*/\1/;p}" <<< "$xml")
case "${arch,,}" in
"0" ) platform="x86" ;;
"9" ) platform="x64" ;;
"12" )platform="arm64" ;;
esac
echo "$platform"
return 0
}
hasVersion() {
local id="$1"
local tag="$2"
local xml="$3"
local edition
[ ! -f "/run/assets/$id.xml" ] && return 1
edition=$(printEdition "$id" "")
[ -z "$edition" ] && return 1
[[ "${xml,,}" != *"<${tag,,}>${edition,,}</${tag,,}>"* ]] && return 1
return 0
} }
selectVersion() { selectVersion() {
local tag="$1" local tag="$1"
local xml="$2" local xml="$2"
local id find name prefer local platform="$3"
local id name prefer
name=$(sed -n "/$tag/{s/.*<$tag>\(.*\)<\/$tag>.*/\1/;p}" <<< "$xml") name=$(sed -n "/$tag/{s/.*<$tag>\(.*\)<\/$tag>.*/\1/;p}" <<< "$xml")
[[ "$name" == *"Operating System"* ]] && name="" [[ "$name" == *"Operating System"* ]] && name=""
[ -z "$name" ] && return 0 [ -z "$name" ] && return 0
id=$(fromName "$name") id=$(fromName "$name" "$platform")
[ -z "$id" ] && warn "Unknown ${tag,,}: '$name'" && return 0 [ -z "$id" ] && warn "Unknown ${tag,,}: '$name'" && return 0
prefer="$id-enterprise" prefer="$id-enterprise"
[ -f "/run/assets/$prefer.xml" ] && find=$(printEdition "$prefer" "") || find="" hasVersion "$prefer" "$tag" "$xml" && echo "$prefer" && return 0
if [ -n "$find" ] && [[ "${xml,,}" == *"<${tag,,}>${find,,}</${tag,,}>"* ]]; then
echo "$prefer" && return 0
fi
prefer="$id-ultimate" prefer="$id-ultimate"
[ -f "/run/assets/$prefer.xml" ] && find=$(printEdition "$prefer" "") || find="" hasVersion "$prefer" "$tag" "$xml" && echo "$prefer" && return 0
if [ -n "$find" ] && [[ "${xml,,}" == *"<${tag,,}>${find,,}</${tag,,}>"* ]]; then
echo "$prefer" && return 0
fi
prefer="$id" prefer="$id"
[ -f "/run/assets/$prefer.xml" ] && find=$(printEdition "$prefer" "") || find="" hasVersion "$prefer" "$tag" "$xml" && echo "$prefer" && return 0
if [ -n "$find" ] && [[ "${xml,,}" == *"<${tag,,}>${find,,}</${tag,,}>"* ]]; then
echo "$prefer" && return 0
fi
prefer=$(getVersion "$name") prefer=$(getVersion "$name" "$platform")
echo "$prefer" echo "$prefer"
return 0 return 0
} }
checkPlatform() {
local xml="$1"
local platform compat
platform=$(getPlatform "$xml")
case "${platform,,}" in
"x86" ) compat="x64" ;;
"x64" ) compat="$platform" ;;
"arm64" ) compat="$platform" ;;
* ) compat="${PLATFORM,,}" ;;
esac
[[ "${compat,,}" == "${PLATFORM,,}" ]] && return 0
error "You cannot boot ${platform^^} images on a $PLATFORM CPU!"
return 1
}
detectVersion() { detectVersion() {
local xml="$1" local xml="$1"
local id="" local id platform
id=$(selectVersion "DISPLAYNAME" "$xml") platform=$(getPlatform "$xml")
[ -n "$id" ] && [[ "${id,,}" != *"unknown"* ]] && echo "$id" && return 0 id=$(selectVersion "DISPLAYNAME" "$xml" "$platform")
[ -z "$id" ] && id=$(selectVersion "PRODUCTNAME" "$xml" "$platform")
id=$(selectVersion "PRODUCTNAME" "$xml") [ -z "$id" ] && id=$(selectVersion "NAME" "$xml" "$platform")
[ -n "$id" ] && [[ "${id,,}" != *"unknown"* ]] && echo "$id" && return 0
id=$(selectVersion "NAME" "$xml")
[ -n "$id" ] && [[ "${id,,}" != *"unknown"* ]] && echo "$id" && return 0
echo "$id"
return 0 return 0
} }
@@ -684,18 +734,20 @@ detectImage() {
XML="" XML=""
if [ -z "$DETECTED" ] && [[ "${version,,}" != "http"* ]]; then if [ -z "$DETECTED" ] && [ -z "$CUSTOM" ]; then
[ -z "$CUSTOM" ] && DETECTED="$version" [[ "${version,,}" != "http"* ]] && DETECTED="$version"
fi fi
if [ -n "$DETECTED" ]; then if [ -n "$DETECTED" ]; then
[[ "${DETECTED,,}" == "winxp"* ]] && return 0 [[ "${DETECTED,,}" == "winxp"* ]] && return 0
setXML "" && return 0 if ! setXML "" && [[ "$MANUAL" != [Yy1]* ]]; then
MANUAL="Y"
desc=$(printEdition "$DETECTED" "this version")
warn "the answer file for $desc was not found ($DETECTED.xml), $FB."
fi
desc=$(printEdition "$DETECTED" "this version")
warn "the answer file for $desc was not found ($DETECTED.xml), $FB."
return 0 return 0
fi fi
@@ -725,12 +777,19 @@ detectImage() {
fi fi
info=$(wimlib-imagex info -xml "$loc" | tr -d '\000') info=$(wimlib-imagex info -xml "$loc" | tr -d '\000')
! checkPlatform "$info" && exit 67
DETECTED=$(detectVersion "$info") DETECTED=$(detectVersion "$info")
if [ -z "$DETECTED" ]; then if [ -z "$DETECTED" ]; then
msg="Failed to determine Windows version from image" msg="Failed to determine Windows version from image"
setXML "" && info "${msg}!" && return 0 if setXML "" || [[ "$MANUAL" == [Yy1]* ]]; then
warn "${msg}, $FB" && return 0 info "${msg}!"
else
MANUAL="Y"
warn "${msg}, $FB."
fi
return 0
fi fi
desc=$(printEdition "$DETECTED" "$DETECTED") desc=$(printEdition "$DETECTED" "$DETECTED")
@@ -741,9 +800,13 @@ detectImage() {
msg="the answer file for $desc was not found ($DETECTED.xml)" msg="the answer file for $desc was not found ($DETECTED.xml)"
local fallback="/run/assets/${DETECTED%%-*}.xml" local fallback="/run/assets/${DETECTED%%-*}.xml"
setXML "$fallback" && warn "${msg}." && return 0 if setXML "$fallback" || [[ "$MANUAL" == [Yy1]* ]]; then
[[ "$MANUAL" != [Yy1]* ]] && warn "${msg}."
else
MANUAL="Y"
warn "${msg}, $FB."
fi
warn "${msg}, $FB."
return 0 return 0
} }
@@ -785,12 +848,18 @@ updateImage() {
local dir="$1" local dir="$1"
local asset="$2" local asset="$2"
local path src loc xml index result local file="autounattend.xml"
local org="${file/.xml/.org}"
local dat="${file/.xml/.dat}"
local desc path src loc xml index result
[ ! -s "$asset" ] || [ ! -f "$asset" ] && return 0 if [ ! -s "$asset" ] || [ ! -f "$asset" ]; then
asset=""
path=$(find "$dir" -maxdepth 1 -type f -iname autounattend.xml | head -n 1) if [[ "$MANUAL" != [Yy1]* ]]; then
[ -n "$path" ] && cp "$asset" "$path" MANUAL="Y"
warn "no answer file provided, $FB."
fi
fi
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1) src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
@@ -807,9 +876,6 @@ updateImage() {
warn "failed to locate 'boot.wim' or 'boot.esd' in ISO image, $FB" && return 1 warn "failed to locate 'boot.wim' or 'boot.esd' in ISO image, $FB" && return 1
fi fi
xml=$(basename "$asset")
info "Adding $xml for automatic installation..."
index="1" index="1"
result=$(wimlib-imagex info -xml "$loc" | tr -d '\000') result=$(wimlib-imagex info -xml "$loc" | tr -d '\000')
@@ -817,8 +883,56 @@ updateImage() {
index="2" index="2"
fi fi
if ! wimlib-imagex update "$loc" "$index" --command "add $asset /autounattend.xml" > /dev/null; then if wimlib-imagex extract "$loc" "$index" "/$file" "--dest-dir=$TMP" >/dev/null 2>&1; then
warn "failed to add answer file ($xml) to ISO image, $FB" && return 1 if ! wimlib-imagex extract "$loc" "$index" "/$dat" "--dest-dir=$TMP" >/dev/null 2>&1; then
if ! wimlib-imagex extract "$loc" "$index" "/$org" "--dest-dir=$TMP" >/dev/null 2>&1; then
if ! wimlib-imagex update "$loc" "$index" --command "rename /$file /$org" > /dev/null; then
warn "failed to backup original answer file ($file)."
fi
fi
fi
rm -f "$TMP/$dat"
rm -f "$TMP/$org"
rm -f "$TMP/$file"
fi
if [[ "$MANUAL" != [Yy1]* ]]; then
xml=$(basename "$asset")
info "Adding $xml for automatic installation..."
if ! wimlib-imagex update "$loc" "$index" --command "add $asset /$file" > /dev/null; then
MANUAL="Y"
warn "failed to add answer file ($xml) to ISO image, $FB"
else
wimlib-imagex update "$loc" "$index" --command "add $asset /$dat" > /dev/null || true
fi
fi
if [[ "$MANUAL" == [Yy1]* ]]; then
wimlib-imagex update "$loc" "$index" --command "delete --force /$file" > /dev/null || true
if wimlib-imagex extract "$loc" "$index" "/$org" "--dest-dir=$TMP" >/dev/null 2>&1; then
if ! wimlib-imagex update "$loc" "$index" --command "add $TMP/$org /$file" > /dev/null; then
warn "failed to restore original answer file ($org)."
fi
rm -f "$TMP/$org"
fi
fi
local find="$file"
[[ "$MANUAL" == [Yy1]* ]] && find="$org"
path=$(find "$dir" -maxdepth 1 -type f -iname "$find" | head -n 1)
if [ -f "$path" ]; then
if [[ "$MANUAL" != [Yy1]* ]]; then
mv -f "$path" "${path%.*}.org"
else
mv -f "$path" "${path%.*}.xml"
fi
fi fi
return 0 return 0
@@ -923,7 +1037,7 @@ buildImage() {
[ -s "$log" ] && error="$(<"$log")" [ -s "$log" ] && error="$(<"$log")"
[[ "$error" != "$hide" ]] && echo "$error" [[ "$error" != "$hide" ]] && echo "$error"
mv "$out" "$BOOT" ! mv -f "$out" "$BOOT" && return 1
return 0 return 0
} }
@@ -974,10 +1088,10 @@ bootWindows() {
BOOT_MODE="windows_secure" BOOT_MODE="windows_secure"
echo "$BOOT_MODE" > "$STORAGE/windows.mode" echo "$BOOT_MODE" > "$STORAGE/windows.mode"
if [ -f "$STORAGE/windows.rom" ] && [ ! -f "$STORAGE/$BOOT_MODE.rom" ]; then if [ -f "$STORAGE/windows.rom" ] && [ ! -f "$STORAGE/$BOOT_MODE.rom" ]; then
mv "$STORAGE/windows.rom" "$STORAGE/$BOOT_MODE.rom" mv -f "$STORAGE/windows.rom" "$STORAGE/$BOOT_MODE.rom"
fi fi
if [ -f "$STORAGE/windows.vars" ] && [ ! -f "$STORAGE/$BOOT_MODE.vars" ]; then if [ -f "$STORAGE/windows.vars" ] && [ ! -f "$STORAGE/$BOOT_MODE.vars" ]; then
mv "$STORAGE/windows.vars" "$STORAGE/$BOOT_MODE.vars" mv -f "$STORAGE/windows.vars" "$STORAGE/$BOOT_MODE.vars"
fi fi
fi fi
fi fi

View File

@@ -3,8 +3,6 @@
# Copyright (C) 2024 Elliot Killick <contact@elliotkillick.com> # Copyright (C) 2024 Elliot Killick <contact@elliotkillick.com>
# Licensed under the MIT License. See LICENSE file for details. # Licensed under the MIT License. See LICENSE file for details.
[ "$DEBUG" ] && set -x
# Prefer Dash shell for greater security if available # Prefer Dash shell for greater security if available
if [ "$BASH" ] && command -v dash > /dev/null; then if [ "$BASH" ] && command -v dash > /dev/null; then
exec dash "$0" "$@" exec dash "$0" "$@"

View File

@@ -29,8 +29,10 @@ boot() {
if [ -s "$QEMU_PTY" ]; then if [ -s "$QEMU_PTY" ]; then
if [ "$(stat -c%s "$QEMU_PTY")" -gt 7 ]; then if [ "$(stat -c%s "$QEMU_PTY")" -gt 7 ]; then
info "Windows started succesfully, visit http://localhost:8006/ to view the screen..." if ! grep -Fq "BOOTMGR is missing" "$QEMU_PTY"; then
return 0 info "Windows started succesfully, visit http://localhost:8006/ to view the screen..."
return 0
fi
fi fi
fi fi
@@ -48,7 +50,9 @@ ready() {
local bios="Booting from Hard" local bios="Booting from Hard"
last=$(grep "^Booting.*" "$QEMU_PTY" | tail -1) last=$(grep "^Booting.*" "$QEMU_PTY" | tail -1)
if [[ "${last,,}" == "${bios,,}"* ]]; then if [[ "${last,,}" == "${bios,,}"* ]]; then
return 0 if ! grep -Fq "BOOTMGR is missing" "$QEMU_PTY"; then
return 0
fi
fi fi
return 1 return 1
fi fi