Compare commits

..

9 Commits
v3.02 ... 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
Kroese
4b23877eaa feat: Improved installation (#459) 2024-05-05 21:24:47 +02:00
8 changed files with 654 additions and 328 deletions

View File

@@ -3,10 +3,20 @@ description: General questions about the container
title: "[Question]: "
labels: ["question"]
body:
- type: markdown
- type: checkboxes
attributes:
value: |
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!
label: Is your question not already answered in the FAQ?
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
id: question
attributes:

View File

@@ -1,5 +1,5 @@
FROM scratch
COPY --from=qemux/qemu-docker:5.01 / /
COPY --from=qemux/qemu-docker:5.02 / /
ARG DEBCONF_NOWARNINGS "yes"
ARG DEBIAN_FRONTEND "noninteractive"

View File

@@ -127,9 +127,14 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
* ### How do I share files with the host?
Open 'File Explorer' and click on the 'Network' section, you will see a computer called `host.lan`, double-click it and it will show a folder called `Data`.
Open 'File Explorer' and click on the 'Network' section, you will see a computer called `host.lan`. Double-click it and it will show a folder called `Data`, which can be binded to any folder on your host via the compose file:
Inside this folder you can access any files that are placed in `/storage/shared` (see above) on the host. You can optionally map it to a drive letter, for easy access.
```yaml
volumes:
- /home/user/example:/shared
```
The example folder `/home/user/example` will be available as ` \\host.lan\Data`. You can optionally map this path to a drive letter in Windows, for easier access.
* ### How do I install a custom image?
@@ -144,7 +149,7 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
```yaml
volumes:
- /home/user/example.iso:/storage/custom.iso
- /home/user/example.iso:/custom.iso
```
Replace the example path `/home/user/example.iso` with the filename of your desired ISO file. The value of `VERSION` will be ignored in this case.
@@ -157,7 +162,7 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
```yaml
volumes:
- /home/user/example.xml:/storage/custom.xml
- /home/user/example.xml:/custom.xml
```
Replace the example path `/home/user/example.xml` with the filename of the modified XML file.
@@ -168,7 +173,7 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
```yaml
volumes:
- /home/user/example:/storage/oem
- /home/user/example:/oem
```
The example folder `/home/user/example` will be copied to `C:\OEM` during installation and the containing `install.bat` will be executed during the last step.
@@ -286,17 +291,30 @@ 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.
* ### 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?
It is possible to pass-through disk devices directly by adding them to your compose file in this way:
```yaml
devices:
- /dev/sdb:/dev/disk1
- /dev/sdc:/dev/disk2
- /dev/sdb:/disk1
- /dev/sdc:/disk2
```
Use `/dev/disk1` if you want it to become your main drive, and use `/dev/disk2` and higher to add them as secondary drives.
Use `/disk1` if you want it to become your main drive, and use `/disk2` and higher to add them as secondary drives.
* ### How do I pass-through a USB device?

View File

@@ -3,34 +3,37 @@ set -Eeuo pipefail
: "${VERIFY:=""}"
: "${MANUAL:=""}"
: "${REMOVE:=""}"
: "${VERSION:=""}"
: "${DETECTED:=""}"
: "${PLATFORM:="x64"}"
MIRRORS=5
PLATFORM="x64"
parseVersion() {
[ -z "$VERSION" ] && VERSION="win11"
VERSION="${VERSION/\//}"
if [[ "${VERSION}" == \"*\" || "${VERSION}" == \'*\' ]]; then
VERSION="${VERSION:1:-1}"
fi
[ -z "$VERSION" ] && VERSION="win11"
case "${VERSION,,}" in
"11" | "win11" | "windows11" | "windows 11" )
"11" | "11p" | "win11" | "win11p" | "windows11" | "windows 11" )
VERSION="win11${PLATFORM,,}"
;;
"11e" | "win11e" | "windows11e" | "windows 11e" )
VERSION="win11${PLATFORM,,}-enterprise-eval"
;;
"10" | "win10" | "windows10" | "windows 10" )
"10" | "10p" | "win10" | "win10p" | "windows10" | "windows 10" )
VERSION="win10${PLATFORM,,}"
;;
"10e" | "win10e" | "windows10e" | "windows 10e" )
VERSION="win10${PLATFORM,,}-enterprise-eval"
;;
"8" | "81" | "8.1" | "win8" | "win81" | "windows 8" )
"8" | "8p" | "81" | "81p" | "8.1" | "win8" | "win8p" | "win81" | "win81p" | "windows 8" )
VERSION="win81${PLATFORM,,}"
;;
"8e" | "81e" | "8.1e" | "win8e" | "win81e" | "windows 8e" )
@@ -38,17 +41,23 @@ parseVersion() {
;;
"7" | "7e" | "win7" | "win7e" | "windows7" | "windows 7" )
VERSION="win7${PLATFORM,,}"
DETECTED="win7${PLATFORM,,}-enterprise"
[ -z "$DETECTED" ] && DETECTED="win7${PLATFORM,,}-enterprise"
;;
"7u" | "win7u" | "windows7u" | "windows 7u" )
VERSION="win7${PLATFORM,,}-ultimate"
;;
"vista" | "winvista" | "windowsvista" | "windows vista" )
VERSION="winvista${PLATFORM,,}"
DETECTED="winvista${PLATFORM,,}-enterprise"
[ -z "$DETECTED" ] && DETECTED="winvista${PLATFORM,,}-enterprise"
;;
"xp" | "xp32" | "winxp" | "windowsxp" | "windows xp" )
"vistu" | "winvistu" | "windowsvistu" | "windows vistu" )
VERSION="winvista${PLATFORM,,}-ultimate"
;;
"xp" | "xp32" | "xpx86" | "winxp" | "winxp86" | "windowsxp" | "windows xp" )
VERSION="winxpx86"
;;
"xp64" | "winxp64" | "windowsxp64" | "windows xp 64" )
VERSION="winxpx64"
"xp64" | "xpx64" | "winxp64" | "winxpx64" | "windowsxp64" | "windowsxpx64" )
VERSION="winxp${PLATFORM,,}"
;;
"22" | "2022" | "win22" | "win2022" | "windows2022" | "windows 2022" )
VERSION="win2022-eval"
@@ -67,27 +76,27 @@ parseVersion() {
;;
"core11" | "core 11" )
VERSION="core11"
DETECTED="win11${PLATFORM,,}"
[ -z "$DETECTED" ] && DETECTED="win11${PLATFORM,,}"
;;
"tiny11" | "tiny 11" )
VERSION="tiny11"
DETECTED="win11${PLATFORM,,}"
[ -z "$DETECTED" ] && DETECTED="win11${PLATFORM,,}"
;;
"tiny10" | "tiny 10" )
VERSION="tiny10"
DETECTED="win10${PLATFORM,,}-ltsc"
[ -z "$DETECTED" ] && DETECTED="win10${PLATFORM,,}-ltsc"
;;
"iot11" | "11iot" | "win11-iot" | "win11${PLATFORM,,}-iot" | "win11${PLATFORM,,}-enterprise-iot-eval" )
DETECTED="win11${PLATFORM,,}-iot"
VERSION="win11${PLATFORM,,}-enterprise-iot-eval"
[ -z "$DETECTED" ] && DETECTED="win11${PLATFORM,,}-iot"
;;
"iot10" | "10iot" | "win10-iot" | "win10${PLATFORM,,}-iot" | "win10${PLATFORM,,}-enterprise-iot-eval" )
DETECTED="win10${PLATFORM,,}-iot"
VERSION="win10${PLATFORM,,}-enterprise-iot-eval"
[ -z "$DETECTED" ] && DETECTED="win10${PLATFORM,,}-iot"
;;
"ltsc10" | "10ltsc" | "win10-ltsc" | "win10${PLATFORM,,}-ltsc" | "win10${PLATFORM,,}-enterprise-ltsc-eval" )
DETECTED="win10${PLATFORM,,}-ltsc"
VERSION="win10${PLATFORM,,}-enterprise-ltsc-eval"
[ -z "$DETECTED" ] && DETECTED="win10${PLATFORM,,}-ltsc"
;;
esac
@@ -137,75 +146,39 @@ printEdition() {
[[ "$result" == "x" ]] && echo "$desc" && return 0
case "${id,,}" in
"win7${PLATFORM,,}-home"* )
*"-iot" )
edition="IoT"
;;
*"-ltsc" )
edition="LTSC"
;;
*"-home" )
edition="Home"
;;
"win7${PLATFORM,,}-starter"* )
*"-starter" )
edition="Starter"
;;
"win7${PLATFORM,,}-ultimate"* )
*"-ultimate" )
edition="Ultimate"
;;
"win7${PLATFORM,,}-enterprise"* )
*"-enterprise" )
edition="Enterprise"
;;
*"-education" )
edition="Education"
;;
*"-enterprise-eval" )
edition="Enterprise (Evaluation)"
;;
"win7"* )
edition="Professional"
;;
"win8${PLATFORM,,}-enterprise"* )
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"* )
"win8"* | "win10"* | "win11"* )
edition="Pro"
;;
"winxp"* )
edition="Professional"
;;
"winvista${PLATFORM,,}-home"* )
edition="Home"
;;
"winvista${PLATFORM,,}-starter"* )
edition="Starter"
;;
"winvista${PLATFORM,,}-ultimate"* )
edition="Ultimate"
;;
"winvista${PLATFORM,,}-enterprise"* )
edition="Enterprise"
;;
"winvista"* )
edition="Business"
;;
@@ -214,7 +187,6 @@ printEdition() {
;;
esac
[[ "${id,,}" == *"-eval" ]] && edition="$edition (Evaluation)"
[ -n "$edition" ] && result="$result $edition"
echo "$result"
@@ -226,25 +198,38 @@ fromFile() {
local id=""
local desc="$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
"win7"* | "win_7"* | *"windows7"* | *"windows_7"* )
id="win7${PLATFORM,,}"
id="win7${arch}"
;;
"win8"* | "win_8"* | *"windows8"* | *"windows_8"* )
id="win81${PLATFORM,,}"
id="win81${arch}"
;;
"win10"*| "win_10"* | *"windows10"* | *"windows_10"* )
id="win10${PLATFORM,,}"
id="win10${arch}"
;;
"win11"* | "win_11"* | *"windows11"* | *"windows_11"* )
id="win11${PLATFORM,,}"
id="win11${arch}"
;;
*"winxp"* | *"win_xp"* | *"windowsxp"* | *"windows_xp"* )
id="winxpx86"
;;
*"winvista"* | *"win_vista"* | *"windowsvista"* | *"windows_vista"* )
id="winvista${PLATFORM,,}"
id="winvista${arch}"
;;
"tiny11core"* | "tiny11_core"* | "tiny_11_core"* )
id="core11"
@@ -287,6 +272,7 @@ fromName() {
local id=""
local name="$1"
local arch="$2"
case "${name,,}" in
*"server 2025"* ) id="win2025" ;;
@@ -295,11 +281,11 @@ fromName() {
*"server 2016"* ) id="win2016" ;;
*"server 2012"* ) id="win2012r2" ;;
*"server 2008"* ) id="win2008r2" ;;
*"windows 7"* ) id="win7${PLATFORM,,}" ;;
*"windows 8"* ) id="win81${PLATFORM,,}" ;;
*"windows 10"* ) id="win10${PLATFORM,,}" ;;
*"windows 11"* ) id="win11${PLATFORM,,}" ;;
*"windows vista"* ) id="winvista${PLATFORM,,}" ;;
*"windows 7"* ) id="win7${arch}" ;;
*"windows 8"* ) id="win81${arch}" ;;
*"windows 10"* ) id="win10${arch}" ;;
*"windows 11"* ) id="win11${arch}" ;;
*"windows vista"* ) id="winvista${arch}" ;;
esac
echo "$id"
@@ -310,8 +296,9 @@ getVersion() {
local id
local name="$1"
local arch="$2"
id=$(fromName "$name")
id=$(fromName "$name" "$arch")
case "${id,,}" in
"win7"* | "winvista"* )
@@ -382,31 +369,109 @@ switchEdition() {
return 0
}
isESD() {
getCatalog() {
local id="$1"
local ret="$2"
local url=""
local name=""
local edition=""
case "${id,,}" in
"win11${PLATFORM,,}" ) return 0 ;;
"win10${PLATFORM,,}" ) return 0 ;;
"win11${PLATFORM,,}" )
edition="Professional"
name="Windows 11 Pro"
url="https://go.microsoft.com/fwlink?linkid=2156292"
;;
"win10${PLATFORM,,}" )
edition="Professional"
name="Windows 10 Pro"
url="https://go.microsoft.com/fwlink/?LinkId=841361"
;;
"win11${PLATFORM,,}-enterprise" | "win11${PLATFORM,,}-enterprise-eval")
edition="Enterprise"
name="Windows 11 Enterprise"
url="https://go.microsoft.com/fwlink?linkid=2156292"
;;
"win10${PLATFORM,,}-enterprise" | "win10${PLATFORM,,}-enterprise-eval" )
edition="Enterprise"
name="Windows 10 Enterprise"
url="https://go.microsoft.com/fwlink/?LinkId=841361"
;;
esac
return 1
case "${ret,,}" in
"url" ) echo "$url" ;;
"name" ) echo "$name" ;;
"edition" ) echo "$edition" ;;
*) echo "";;
esac
return 0
}
isMido() {
getMido() {
local id="$1"
local ret="$2"
local sum=""
local size=""
case "${id,,}" in
"win11${PLATFORM,,}" | "win11${PLATFORM,,}-enterprise-eval" )
return 0 ;;
"win10${PLATFORM,,}" | "win10${PLATFORM,,}-enterprise-eval" | "win10${PLATFORM,,}-enterprise-ltsc-eval" )
return 0 ;;
"win81${PLATFORM,,}" | "win81${PLATFORM,,}-enterprise-eval" )
return 0 ;;
"win2022-eval" | "win2019-eval" | "win2016-eval" | "win2012r2-eval" | "win2008r2" )
return 0 ;;
"win11${PLATFORM,,}" )
size=6812706816
sum="36de5ecb7a0daa58dce68c03b9465a543ed0f5498aa8ae60ab45fb7c8c4ae402"
;;
"win11${PLATFORM,,}-enterprise-eval" )
size=6209064960
sum="c8dbc96b61d04c8b01faf6ce0794fdf33965c7b350eaa3eb1e6697019902945c"
;;
"win10${PLATFORM,,}" )
size=6140975104
sum="a6f470ca6d331eb353b815c043e327a347f594f37ff525f17764738fe812852e"
;;
"win10${PLATFORM,,}-enterprise-eval" )
size=5550497792
sum="ef7312733a9f5d7d51cfa04ac497671995674ca5e1058d5164d6028f0938d668"
;;
"win10${PLATFORM,,}-enterprise-ltsc-eval" )
size=4898582528
sum="e4ab2e3535be5748252a8d5d57539a6e59be8d6726345ee10e7afd2cb89fefb5"
;;
"win81${PLATFORM,,}" )
size=4320526336
sum="d8333cf427eb3318ff6ab755eb1dd9d433f0e2ae43745312c1cd23e83ca1ce51"
;;
"win81${PLATFORM,,}-enterprise-eval" )
size=3961473024
sum="2dedd44c45646c74efc5a028f65336027e14a56f76686a4631cf94ffe37c72f2"
;;
"win2022-eval" )
size=5044094976
sum="3e4fa6d8507b554856fc9ca6079cc402df11a8b79344871669f0251535255325"
;;
"win2019-eval" )
size=5652088832
sum="6dae072e7f78f4ccab74a45341de0d6e2d45c39be25f1f5920a2ab4f51d7bcbb"
;;
"win2016-eval" )
size=6972221440
sum="1ce702a578a3cb1ac3d14873980838590f06d5b7101c5daaccbac9d73f1fb50f"
;;
"win2012r2-eval" )
size=4542291968
sum="6612b5b1f53e845aacdf96e974bb119a3d9b4dcb5b82e65804ab7e534dc7b4d5"
;;
"win2008r2" )
size=3166840832
sum="30832ad76ccfa4ce48ccb936edefe02079d42fb1da32201bf9e3a880c8ed6312"
;;
esac
case "${ret,,}" in
"sum" ) echo "$sum" ;;
"size" ) echo "$size" ;;
*) echo "";;
esac
return 1
@@ -484,11 +549,26 @@ getLink1() {
sum="0b738b55a5ea388ad016535a5c8234daf2e5715a0638488ddd8a228a836055a1"
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" )
size=3861460992
sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78"
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" )
size=617756672
sum="62b6c91563bad6cd12a352aa018627c314cfc5162d8e9f8af0756a642e602a46"
@@ -550,6 +630,16 @@ getLink2() {
sum="36f4fa2416d0982697ab106e3a72d2e120dbcdb6cc54fd3906d06120d0653808"
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" )
size=3205953536
sum="0a0cd511b3eac95c6f081419c9c65b12317b9d6a8d9707f89d646c910e788016"
@@ -560,6 +650,16 @@ getLink2() {
sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78"
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" )
size=617756672
sum="62b6c91563bad6cd12a352aa018627c314cfc5162d8e9f8af0756a642e602a46"
@@ -704,6 +804,16 @@ getLink4() {
sum="36f4fa2416d0982697ab106e3a72d2e120dbcdb6cc54fd3906d06120d0653808"
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" )
size=3205953536
sum="0a0cd511b3eac95c6f081419c9c65b12317b9d6a8d9707f89d646c910e788016"
@@ -714,6 +824,16 @@ getLink4() {
sum="edf9f947c5791469fd7d2d40a5dcce663efa754f91847aa1d28ed7f585675b78"
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
case "${ret,,}" in
@@ -808,6 +928,28 @@ getSize() {
return 0
}
isMido() {
local id="$1"
local sum
sum=$(getMido "$id" "sum")
[ -n "$sum" ] && return 0
return 1
}
isESD() {
local id="$1"
local url
url=$(getCatalog "$id" "url")
[ -n "$url" ] && return 0
return 1
}
validVersion() {
local id="$1"
@@ -832,7 +974,7 @@ migrateFiles() {
local version="$2"
local file=""
[ -f "$STORAGE/$base" ] && return 0
[ -f "$base" ] && return 0
[[ "${version,,}" == "tiny10" ]] && file="tiny10_${PLATFORM,,}_23h2.iso"
[[ "${version,,}" == "tiny11" ]] && file="tiny11_2311_${PLATFORM,,}.iso"
@@ -841,10 +983,8 @@ migrateFiles() {
[[ "${version,,}" == "winvista${PLATFORM,,}" ]] && file="en_windows_vista_sp2_${PLATFORM,,}_dvd_342267.iso"
[[ "${version,,}" == "win7${PLATFORM,,}" ]] && file="en_windows_7_enterprise_with_sp1_${PLATFORM,,}_dvd_u_677651.iso"
[ -z "$file" ] && return 0
[ ! -f "$STORAGE/$file" ] && return 0
! mv "$STORAGE/$file" "$STORAGE/$base" && return 1
! mv -f "$STORAGE/$file" "$base" && return 1
return 0
}
@@ -1059,15 +1199,17 @@ prepareLegacy() {
local iso="$1"
local dir="$2"
local file="$dir/boot.img"
ETFS="boot.img"
rm -f "$dir/$ETFS"
ETFS=$(basename "$file")
[ -f "$file" ] && [ -s "$file" ] && return 0
rm -f "$file"
local len offset
len=$(isoinfo -d -i "$iso" | grep "Nsect " | 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
}

View File

@@ -9,6 +9,8 @@ EFISYS="efi/microsoft/boot/efisys_noprompt.bin"
hasDisk() {
[ -b "/disk1" ] && return 0
[ -b "/dev/disk1" ] && return 0
[ -b "${DEVICE:-}" ] && return 0
if [ -s "$STORAGE/data.img" ] || [ -s "$STORAGE/data.qcow2" ]; then
@@ -29,73 +31,80 @@ skipInstall() {
startInstall() {
html "Starting Windows..."
html "Starting $APP..."
[ -z "$MANUAL" ] && MANUAL="N"
if [ -n "$CUSTOM" ]; then
if [ -f "$STORAGE/$CUSTOM" ]; then
BASE="$CUSTOM"
ISO="$CUSTOM"
else
CUSTOM=""
local file="${VERSION/\//}.iso"
if [[ "${VERSION,,}" != "http"* ]]; then
if [[ "${VERSION,,}" == "http"* ]]; then
BASE="$VERSION.iso"
else
BASE=$(basename "${VERSION%%\?*}")
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
file=$(basename "${VERSION%%\?*}")
: "${file//+/ }"; printf -v file '%b' "${_//%/\\x}"
file=$(echo "$file" | sed -e 's/[^A-Za-z0-9._-]/_/g')
fi
ISO="$STORAGE/$file"
! migrateFiles "$ISO" "$VERSION" && error "Migration failed!" && exit 57
fi
if [[ "${PLATFORM,,}" == "x64" ]]; then
! migrateFiles "$BASE" "$VERSION" && error "Migration failed!" && exit 57
fi
skipInstall && return 1
if skipInstall; then
if [ ! -f "$STORAGE/$BASE" ]; then
BASE="custom.iso"
[ ! -f "$STORAGE/$BASE" ] && BASE=""
fi
[[ "${PLATFORM,,}" == "arm64" ]] && VGA="virtio-gpu"
return 1
fi
if [ -f "$ISO" ] && [ -s "$ISO" ]; then
if [ -f "$STORAGE/$BASE" ]; 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
local magic=""
magic=$(dd if="$STORAGE/$BASE" 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')"
if [[ "$magic" == "16" ]]; then
if hasDisk || [[ "$MANUAL" == [Yy1]* ]]; then
if [[ "$magic" == "$byte" ]]; then
if [ -z "$CUSTOM" ] || [ -n "$ORIGINAL" ]; then
return 1
fi
fi
CUSTOM="$BASE"
fi
rm -rf "$TMP"
mkdir -p "$TMP"
if [ ! -f "$STORAGE/$CUSTOM" ]; then
CUSTOM=""
ISO="$TMP/$BASE"
if [ -z "$CUSTOM" ]; then
BOOT="$ISO"
ISO=$(basename "$ISO")
ISO="$TMP/$ISO"
if [ -f "$BOOT" ] && [ -s "$BOOT" ]; then
mv -f "$BOOT" "$ISO"
fi
else
ISO="$STORAGE/$CUSTOM"
if [ -n "$ORIGINAL" ]; then
rm -f "$ISO"
ISO="$ORIGINAL"
CUSTOM="$ISO"
fi
local size
size="$(stat -c%s "$ISO")"
BOOT="$STORAGE/windows.$size.iso"
fi
rm -f "$BOOT"
return 0
}
@@ -110,7 +119,9 @@ finishInstall() {
if [ -w "$iso" ] && [[ "$aborted" != [Yy1]* ]]; then
# Mark ISO as prepared via magic byte
if ! printf '\x16' | dd of="$iso" bs=1 seek=0 count=1 conv=notrunc status=none; then
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
fi
fi
@@ -119,8 +130,7 @@ finishInstall() {
rm -f "$STORAGE/windows.boot"
rm -f "$STORAGE/windows.mode"
cp /run/version "$STORAGE/windows.ver"
echo "$BASE" > "$STORAGE/windows.base"
cp -f /run/version "$STORAGE/windows.ver"
if [[ "${PLATFORM,,}" == "x64" ]]; then
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
@@ -147,42 +157,60 @@ abortInstall() {
local iso="$1"
if [[ "$iso" != "$STORAGE/$BASE" ]]; then
if ! mv -f "$iso" "$STORAGE/$BASE"; then
error "Failed to move ISO file: $iso" && return 1
[[ "${iso,,}" == *".esd" ]] && exit 60
if [ -n "$CUSTOM" ]; then
BOOT="$iso"
REMOVE="N"
else
if [[ "$iso" != "$BOOT" ]]; then
if ! mv -f "$iso" "$BOOT"; then
error "Failed to move ISO file: $iso" && return 1
fi
fi
fi
finishInstall "$STORAGE/$BASE" "Y" && return 0
finishInstall "$BOOT" "Y" && return 0
return 1
}
detectCustom() {
local file=""
local size base
CUSTOM=""
local file size
ORIGINAL=""
if [[ "${VERSION,,}" != "http"* ]]; then
file="${VERSION/\/storage\//}"
[[ "$file" == "."* ]] && file="${file:1}"
[[ "$file" == *"/"* ]] && file=""
[ -n "$file" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname "$file" -printf "%f\n" | head -n 1)
base="${VERSION/\/storage\//}"
[[ "$base" == "."* ]] && base="${file:1}"
[[ "$base" == *"/"* ]] && base=""
[ -n "$base" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname "$base" | head -n 1)
fi
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.img -printf "%f\n" | head -n 1)
[ -z "$CUSTOM" ] && return 0
[ -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 | head -n 1)
size="$(stat -c%s "$STORAGE/$CUSTOM")"
base="/custom.iso"
[ -f "$base" ] && [ -s "$base" ] && file="$base"
if [ -z "$size" ] || [[ "$size" == "0" ]]; then
CUSTOM=""
if [ ! -f "$file" ] || [ ! -s "$file" ]; then
return 0
fi
file="windows.$size.iso"
[ -s "$STORAGE/$file" ] && CUSTOM="$file"
size="$(stat -c%s "$file")"
[ -z "$size" ] || [[ "$size" == "0" ]] && return 0
base="$STORAGE/windows.$size.iso"
if [ -f "$base" ] && [ -s "$base" ]; then
CUSTOM="$base"
ORIGINAL="$file"
else
rm -f "$base"
CUSTOM="$file"
fi
return 0
}
@@ -191,13 +219,15 @@ getESD() {
local dir="$1"
local version="$2"
local editionName
local winCatalog size
case "${version,,}" in
"win11${PLATFORM,,}" ) winCatalog="https://go.microsoft.com/fwlink?linkid=2156292" ;;
"win10${PLATFORM,,}" ) winCatalog="https://go.microsoft.com/fwlink/?LinkId=841361" ;;
*) error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1 ;;
esac
if ! isESD "${version,,}"; then
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
fi
winCatalog=$(getCatalog "$version" "url")
editionName=$(getCatalog "$version" "edition")
local msg="Downloading product information from Microsoft..."
info "$msg" && html "$msg"
@@ -227,7 +257,6 @@ getESD() {
fi
local esdLang="en-us"
local editionName="Professional"
local edQuery='//File[Architecture="'${PLATFORM}'"][Edition="'${editionName}'"]'
echo -e '<Catalog>' > "$dir/$fFile"
@@ -256,47 +285,15 @@ getESD() {
return 0
}
doMido() {
local iso="$1"
local version="$2"
local desc="$3"
local rc
rm -f "$iso"
rm -f "$iso.PART"
local msg="Downloading $desc..."
info "$msg" && html "$msg"
/run/progress.sh "$iso.PART" "" "Downloading $desc ([P])..." &
cd "$TMP"
{ /run/mido.sh "${version,,}"; rc=$?; } || :
cd /run
fKill "progress.sh"
if (( rc == 0 )) && [ -f "$iso" ]; then
if [ "$(stat -c%s "$iso")" -gt 100000000 ]; then
html "Download finished successfully..." && return 0
fi
fi
rm -f "$iso"
rm -f "$iso.PART"
return 1
}
verifyFile() {
local iso="$1"
local size="$2"
local total="$3"
local total="$3"
local check="$4"
if [ -n "$size" ] && [[ "$total" != "$size" ]]; then
[[ "$size" != "0" ]] && warn "The download file has an unexpected size: $total"
if [ -n "$size" ] && [[ "$total" != "$size" ]] && [[ "$size" != "0" ]]; then
warn "The downloaded file has an unexpected size: $total bytes, while expected value was: $size bytes. Please report this at $SUPPORT/issues"
fi
local hash=""
@@ -316,15 +313,52 @@ verifyFile() {
fi
if [[ "$hash" == "$check" ]]; then
info "Succesfully verified that the checksum was correct!" && return 0
info "Succesfully verified ISO!" && return 0
fi
error "Invalid $algo checksum: $hash , but expected value is: $check ! Please report this at $SUPPORT/issues"
error "The downloaded file has an invalid $algo checksum: $hash , while expected value was: $check. Please report this at $SUPPORT/issues"
rm -f "$iso"
return 1
}
doMido() {
local iso="$1"
local version="$2"
local desc="$3"
local rc sum size total
rm -f "$iso"
rm -f "$iso.PART"
size=$(getMido "$version" "size")
sum=$(getMido "$version" "sum")
local msg="Downloading $desc..."
info "$msg" && html "$msg"
/run/progress.sh "$iso.PART" "$size" "Downloading $desc ([P])..." &
cd "$TMP"
{ /run/mido.sh "${version,,}"; rc=$?; } || :
cd /run
fKill "progress.sh"
if (( rc == 0 )) && [ -f "$iso" ]; then
total=$(stat -c%s "$iso")
if [ "$total" -gt 100000000 ]; then
! verifyFile "$iso" "$size" "$total" "$sum" && return 1
html "Download finished successfully..." && return 0
fi
fi
rm -f "$iso"
rm -f "$iso.PART"
return 1
}
downloadFile() {
local iso="$1"
@@ -380,10 +414,11 @@ downloadImage() {
local iso="$1"
local version="$2"
local tried="n"
local url sum size desc
local url sum size base desc
if [[ "${version,,}" == "http"* ]]; then
desc=$(fromFile "$BASE")
base=$(basename "$iso")
desc=$(fromFile "$base")
downloadFile "$iso" "$version" "" "" "$desc" && return 0
return 1
fi
@@ -410,9 +445,9 @@ downloadImage() {
tried="y"
if getESD "$TMP/esd" "$version"; then
ISO="$TMP/$version.esd"
ISO="${ISO%.*}.esd"
downloadFile "$ISO" "$ESD" "$ESD_SUM" "$ESD_SIZE" "$desc" && return 0
ISO="$TMP/$BASE"
ISO="$iso"
fi
fi
@@ -436,6 +471,17 @@ downloadImage() {
return 1
}
removeDownload() {
local iso="$1"
[ ! -f "$iso" ] && return 0
[ -n "$CUSTOM" ] && return 0
! rm -f "$iso" 2> /dev/null && warn "failed to remove $iso !"
return 0
}
extractESD() {
local iso="$1"
@@ -464,20 +510,20 @@ extractESD() {
fi
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=$?
error "Extracting $desc bootdisk failed" && return $retVal
}
local bootWimFile="${dir}/sources/boot.wim"
local installWimFile="${dir}/sources/install.wim"
local bootWimFile="$dir/sources/boot.wim"
local installWimFile="$dir/sources/install.wim"
local msg="Extracting $desc environment..."
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=$?
error "Adding WinPE failed" && return ${retVal}
}
@@ -485,7 +531,7 @@ extractESD() {
local msg="Extracting $desc setup..."
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=$?
error "Adding Windows Setup failed" && return ${retVal}
}
@@ -500,24 +546,23 @@ extractESD() {
info "$msg" && html "$msg"
local edition imageIndex imageEdition
edition=$(getCatalog "$version" "name")
case "${version,,}" in
"win11${PLATFORM,,}" ) edition="11 pro" ;;
"win10${PLATFORM,,}" ) edition="10 pro" ;;
*) error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1 ;;
esac
if [ -z "$edition" ]; then
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
fi
for (( imageIndex=4; imageIndex<=esdImageCount; imageIndex++ )); do
imageEdition=$(wimlib-imagex info "${iso}" ${imageIndex} | grep '^Description:' | sed 's/Description:[ \t]*//')
[[ "${imageEdition,,}" != *"$edition"* ]] && continue
wimlib-imagex export "${iso}" ${imageIndex} "${installWimFile}" --compress=LZMS --chunk-size 128K --quiet || {
imageEdition=$(wimlib-imagex info "$iso" ${imageIndex} | grep '^Description:' | sed 's/Description:[ \t]*//')
[[ "${imageEdition,,}" != "${edition,,}" ]] && continue
wimlib-imagex export "$iso" ${imageIndex} "$installWimFile" --compress=LZMS --chunk-size 128K --quiet || {
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
done
error "Failed to find product in install.wim!" && return 1
error "Failed to find product '$edition' in install.wim!" && return 1
}
extractImage() {
@@ -572,72 +617,112 @@ extractImage() {
setXML() {
[[ "$MANUAL" == [Yy1]* ]] && return 0
local file="/custom.xml"
[ ! -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
local file="$STORAGE/custom.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
XML="$file"
return 0
}
file="/run/assets/custom.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
getPlatform() {
file="$1"
[ -z "$file" ] && file="/run/assets/$DETECTED.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
local xml="$1"
local tag="ARCH"
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() {
local tag="$1"
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" == *"Operating System"* ]] && name=""
[ -z "$name" ] && return 0
id=$(fromName "$name")
id=$(fromName "$name" "$platform")
[ -z "$id" ] && warn "Unknown ${tag,,}: '$name'" && return 0
prefer="$id-enterprise"
[ -f "/run/assets/$prefer.xml" ] && find=$(printEdition "$prefer" "") || find=""
if [ -n "$find" ] && [[ "${xml,,}" == *"<${tag,,}>${find,,}</${tag,,}>"* ]]; then
echo "$prefer" && return 0
fi
hasVersion "$prefer" "$tag" "$xml" && echo "$prefer" && return 0
prefer="$id-ultimate"
[ -f "/run/assets/$prefer.xml" ] && find=$(printEdition "$prefer" "") || find=""
if [ -n "$find" ] && [[ "${xml,,}" == *"<${tag,,}>${find,,}</${tag,,}>"* ]]; then
echo "$prefer" && return 0
fi
hasVersion "$prefer" "$tag" "$xml" && echo "$prefer" && return 0
prefer="$id"
[ -f "/run/assets/$prefer.xml" ] && find=$(printEdition "$prefer" "") || find=""
if [ -n "$find" ] && [[ "${xml,,}" == *"<${tag,,}>${find,,}</${tag,,}>"* ]]; then
echo "$prefer" && return 0
fi
hasVersion "$prefer" "$tag" "$xml" && echo "$prefer" && return 0
prefer=$(getVersion "$name")
prefer=$(getVersion "$name" "$platform")
echo "$prefer"
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() {
local xml="$1"
local id=""
local id platform
id=$(selectVersion "DISPLAYNAME" "$xml")
[ -n "$id" ] && [[ "${id,,}" != *"unknown"* ]] && echo "$id" && return 0
id=$(selectVersion "PRODUCTNAME" "$xml")
[ -n "$id" ] && [[ "${id,,}" != *"unknown"* ]] && echo "$id" && return 0
id=$(selectVersion "NAME" "$xml")
[ -n "$id" ] && [[ "${id,,}" != *"unknown"* ]] && echo "$id" && return 0
platform=$(getPlatform "$xml")
id=$(selectVersion "DISPLAYNAME" "$xml" "$platform")
[ -z "$id" ] && id=$(selectVersion "PRODUCTNAME" "$xml" "$platform")
[ -z "$id" ] && id=$(selectVersion "NAME" "$xml" "$platform")
echo "$id"
return 0
}
@@ -649,22 +734,20 @@ detectImage() {
XML=""
if [ -n "$CUSTOM" ]; then
DETECTED=""
else
if [ -z "$DETECTED" ] && [[ "${version,,}" != "http"* ]]; then
DETECTED="$version"
fi
if [ -z "$DETECTED" ] && [ -z "$CUSTOM" ]; then
[[ "${version,,}" != "http"* ]] && DETECTED="$version"
fi
if [ -n "$DETECTED" ]; then
[[ "${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
fi
@@ -694,12 +777,19 @@ detectImage() {
fi
info=$(wimlib-imagex info -xml "$loc" | tr -d '\000')
! checkPlatform "$info" && exit 67
DETECTED=$(detectVersion "$info")
if [ -z "$DETECTED" ]; then
msg="Failed to determine Windows version from image"
setXML "" && info "${msg}!" && return 0
warn "${msg}, $FB" && return 0
if setXML "" || [[ "$MANUAL" == [Yy1]* ]]; then
info "${msg}!"
else
MANUAL="Y"
warn "${msg}, $FB."
fi
return 0
fi
desc=$(printEdition "$DETECTED" "$DETECTED")
@@ -710,9 +800,13 @@ detectImage() {
msg="the answer file for $desc was not found ($DETECTED.xml)"
local fallback="/run/assets/${DETECTED%%-*}.xml"
setXML "$fallback" && warn "${msg}." && return 0
warn "${msg}, $FB."
if setXML "$fallback" || [[ "$MANUAL" == [Yy1]* ]]; then
[[ "$MANUAL" != [Yy1]* ]] && warn "${msg}."
else
MANUAL="Y"
warn "${msg}, $FB."
fi
return 0
}
@@ -752,15 +846,20 @@ prepareImage() {
updateImage() {
local iso="$1"
local dir="$2"
local asset="$3"
local path src loc xml index result
local dir="$1"
local asset="$2"
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
path=$(find "$dir" -maxdepth 1 -type f -iname autounattend.xml | head -n 1)
[ -n "$path" ] && cp "$asset" "$path"
if [ ! -s "$asset" ] || [ ! -f "$asset" ]; then
asset=""
if [[ "$MANUAL" != [Yy1]* ]]; then
MANUAL="Y"
warn "no answer file provided, $FB."
fi
fi
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
@@ -777,9 +876,6 @@ updateImage() {
warn "failed to locate 'boot.wim' or 'boot.esd' in ISO image, $FB" && return 1
fi
xml=$(basename "$asset")
info "Adding $xml for automatic installation..."
index="1"
result=$(wimlib-imagex info -xml "$loc" | tr -d '\000')
@@ -787,8 +883,56 @@ updateImage() {
index="2"
fi
if ! wimlib-imagex update "$loc" "$index" --command "add $asset /autounattend.xml" > /dev/null; then
warn "failed to add answer file ($xml) to ISO image, $FB" && return 1
if wimlib-imagex extract "$loc" "$index" "/$file" "--dest-dir=$TMP" >/dev/null 2>&1; then
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
return 0
@@ -801,10 +945,8 @@ copyOEM() {
local src
[ ! -d "$folder" ] && folder="/OEM"
[ ! -d "$folder" ] && folder="$STORAGE/oem"
[ ! -d "$folder" ] && folder="$STORAGE/OEM"
[ ! -d "$folder" ] && folder="$STORAGE/OEM"
[ ! -d "$folder" ] && folder="$STORAGE/shared/oem"
[ ! -d "$folder" ] && folder="$STORAGE/shared/OEM"
[ ! -d "$folder" ] && return 0
local msg="Copying OEM folder to image..."
@@ -832,9 +974,14 @@ buildImage() {
local failed="N"
local cat="BOOT.CAT"
local log="/run/shm/iso.log"
local size size_gb space space_gb desc
local out="$TMP/${BASE%.*}.tmp"
local base size size_gb space space_gb desc
if [ -f "$BOOT" ]; then
error "File $BOOT does already exist?!" && return 1
fi
base=$(basename "$BOOT")
local out="$TMP/${base%.*}.tmp"
rm -f "$out"
desc=$(printVersion "$DETECTED" "ISO")
@@ -890,11 +1037,7 @@ buildImage() {
[ -s "$log" ] && error="$(<"$log")"
[[ "$error" != "$hide" ]] && echo "$error"
if [ -f "$STORAGE/$BASE" ]; then
error "File $STORAGE/$BASE does already exist?!" && return 1
fi
mv "$out" "$STORAGE/$BASE"
! mv -f "$out" "$BOOT" && return 1
return 0
}
@@ -902,6 +1045,15 @@ bootWindows() {
rm -rf "$TMP"
if [ ! -f "$ISO" ] || [ ! -s "$ISO" ]; then
ISO="/custom.iso"
[ ! -f "$ISO" ] && ISO="${STORAGE}$ISO"
fi
BOOT="$ISO"
[[ "${PLATFORM,,}" == "arm64" ]] && VGA="virtio-gpu"
if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
BOOT_MODE=$(<"$STORAGE/windows.mode")
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
@@ -936,10 +1088,10 @@ bootWindows() {
BOOT_MODE="windows_secure"
echo "$BOOT_MODE" > "$STORAGE/windows.mode"
if [ -f "$STORAGE/windows.rom" ] && [ ! -f "$STORAGE/$BOOT_MODE.rom" ]; then
mv "$STORAGE/windows.rom" "$STORAGE/$BOOT_MODE.rom"
mv -f "$STORAGE/windows.rom" "$STORAGE/$BOOT_MODE.rom"
fi
if [ -f "$STORAGE/windows.vars" ] && [ ! -f "$STORAGE/$BOOT_MODE.vars" ]; then
mv "$STORAGE/windows.vars" "$STORAGE/$BOOT_MODE.vars"
mv -f "$STORAGE/windows.vars" "$STORAGE/$BOOT_MODE.vars"
fi
fi
fi
@@ -979,16 +1131,13 @@ if ! prepareImage "$ISO" "$DIR"; then
exit 60
fi
if ! updateImage "$ISO" "$DIR" "$XML"; then
if ! updateImage "$DIR" "$XML"; then
abortInstall "$ISO" && return 0
exit 60
fi
if ! rm -f "$ISO" 2> /dev/null; then
size="$(stat -c%s "$ISO")"
BASE="windows.$size.iso"
ISO="$STORAGE/$BASE"
rm -f "$ISO"
if ! removeDownload "$ISO"; then
exit 64
fi
if ! copyOEM "$DIR"; then
@@ -999,7 +1148,7 @@ if ! buildImage "$DIR"; then
exit 65
fi
if ! finishInstall "$STORAGE/$BASE" "N"; then
if ! finishInstall "$BOOT" "N"; then
exit 69
fi

View File

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

View File

@@ -29,8 +29,10 @@ boot() {
if [ -s "$QEMU_PTY" ]; then
if [ "$(stat -c%s "$QEMU_PTY")" -gt 7 ]; then
info "Windows started succesfully, visit http://localhost:8006/ to view the screen..."
return 0
if ! grep -Fq "BOOTMGR is missing" "$QEMU_PTY"; then
info "Windows started succesfully, visit http://localhost:8006/ to view the screen..."
return 0
fi
fi
fi
@@ -48,7 +50,9 @@ ready() {
local bios="Booting from Hard"
last=$(grep "^Booting.*" "$QEMU_PTY" | tail -1)
if [[ "${last,,}" == "${bios,,}"* ]]; then
return 0
if ! grep -Fq "BOOTMGR is missing" "$QEMU_PTY"; then
return 0
fi
fi
return 1
fi
@@ -81,11 +85,12 @@ finish() {
done
fi
if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$STORAGE/$BASE" ]; then
if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$BOOT" ]; then
# Remove CD-ROM ISO after install
if ready; then
if rm -f "$STORAGE/$BASE" 2>/dev/null; then
touch "$STORAGE/windows.boot"
touch "$STORAGE/windows.boot"
if [[ "$REMOVE" != [Nn]* ]]; then
rm -f "$BOOT" 2>/dev/null || true
fi
fi
fi

View File

@@ -14,10 +14,14 @@ if [[ "$DHCP" == [Yy1]* ]]; then
interface="$VM_NET_DEV"
fi
share="$STORAGE/shared"
share="/shared"
if [ ! -d "$share" ] && [ -d "$STORAGE/shared" ]; then
share="$STORAGE/shared"
fi
mkdir -p "$share"
[ -z "$(ls -A "$share")" ] && chmod -R 777 "$share"
[ -z "$(ls -A "$share")" ] && chmod 777 "$share"
{ echo "[global]"
echo " server string = Dockur"
@@ -53,16 +57,16 @@ mkdir -p "$share"
echo ""
echo "Using this folder you can share files with the host machine."
echo ""
echo "To change the storage location, include the following bind mount in your compose file:"
echo "To change its location, include the following bind mount in your compose file:"
echo ""
echo " volumes:"
echo " - \"/home/user/example:/storage/shared\""
echo " - \"/home/user/example:/shared\""
echo ""
echo "Or in your run command:"
echo ""
echo " -v \"/home/user/example:/storage/shared\""
echo " -v \"/home/user/example:/shared\""
echo ""
echo "Replace the example path /home/user/example with the desired storage folder."
echo "Replace the example path /home/user/example with the desired shared folder."
echo ""
} | unix2dos > "$share/readme.txt"