Compare commits

..

4 Commits
v3.01 ... v3.03

Author SHA1 Message Date
Kroese
4b23877eaa feat: Improved installation (#459) 2024-05-05 21:24:47 +02:00
Kroese
0cb936d64d Update install.sh (#455) 2024-05-04 19:12:58 +02:00
Kroese
22a5bd72d3 feat: Show download percentage (#454) 2024-05-04 18:29:05 +02:00
Kroese
0616eb3447 feat: Improved installation (#453) 2024-05-04 13:28:12 +02:00
10 changed files with 1312 additions and 704 deletions

View File

@@ -21,5 +21,5 @@ jobs:
uses: hadolint/hadolint-action@v3.1.0 uses: hadolint/hadolint-action@v3.1.0
with: with:
dockerfile: Dockerfile dockerfile: Dockerfile
ignore: DL3008,DL4006,SC3037 ignore: DL3008
failure-threshold: warning failure-threshold: warning

View File

@@ -1,5 +1,5 @@
FROM scratch FROM scratch
COPY --from=qemux/qemu-docker:4.27 / / COPY --from=qemux/qemu-docker:5.02 / /
ARG DEBCONF_NOWARNINGS "yes" ARG DEBCONF_NOWARNINGS "yes"
ARG DEBIAN_FRONTEND "noninteractive" ARG DEBIAN_FRONTEND "noninteractive"
@@ -12,14 +12,11 @@ RUN apt-get update && \
7zip \ 7zip \
wsdd \ wsdd \
samba \ samba \
wimtools \
dos2unix \ dos2unix \
cabextract \ cabextract \
genisoimage \ genisoimage \
libxml2-utils && \ libxml2-utils && \
echo "deb http://deb.debian.org/debian/ sid main" >> /etc/apt/sources.list.d/sid.list && \
echo -e "Package: *\nPin: release n=trixie\nPin-Priority: 900\nPackage: *\nPin: release n=sid\nPin-Priority: 400" | tee /etc/apt/preferences.d/preferences > /dev/null && \
apt-get update && \
apt-get -t sid --no-install-recommends -y install wimtools && \
apt-get clean && \ apt-get clean && \
rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/*

View File

@@ -52,8 +52,8 @@
<OSImage> <OSImage>
<InstallFrom> <InstallFrom>
<MetaData wcm:action="add"> <MetaData wcm:action="add">
<Value>1</Value> <Value>Windows 7 PROFESSIONAL</Value>
<Key>/IMAGE/INDEX</Key> <Key>/IMAGE/NAME</Key>
</MetaData> </MetaData>
</InstallFrom> </InstallFrom>
<InstallTo> <InstallTo>
@@ -76,7 +76,7 @@
<FullName>Docker</FullName> <FullName>Docker</FullName>
<Organization>Windows for Docker</Organization> <Organization>Windows for Docker</Organization>
<ProductKey> <ProductKey>
<Key>H7X92-3VPBB-Q799D-Y6JJ3-86WC6</Key> <Key>HYF8J-CVRMY-CM74G-RPHKF-PW487</Key>
<WillShowUI>OnError</WillShowUI> <WillShowUI>OnError</WillShowUI>
</ProductKey> </ProductKey>
</UserData> </UserData>

View File

@@ -51,7 +51,7 @@
<OSImage> <OSImage>
<InstallFrom> <InstallFrom>
<MetaData wcm:action="add"> <MetaData wcm:action="add">
<Value>Windows Vista Ultimate</Value> <Value>Windows Vista BUSINESS</Value>
<Key>/IMAGE/NAME</Key> <Key>/IMAGE/NAME</Key>
</MetaData> </MetaData>
</InstallFrom> </InstallFrom>
@@ -68,7 +68,7 @@
<FullName>Docker</FullName> <FullName>Docker</FullName>
<Organization>Windows for Docker</Organization> <Organization>Windows for Docker</Organization>
<ProductKey> <ProductKey>
<Key>VMCB9-FDRV6-6CDQM-RV23K-RP8F7</Key> <Key>4D2XH-PRBMM-8Q22B-K8BM3-MRW4W</Key>
</ProductKey> </ProductKey>
</UserData> </UserData>
</component> </component>
@@ -100,7 +100,7 @@
</component> </component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS"> <component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<ComputerName>*</ComputerName> <ComputerName>*</ComputerName>
<ProductKey>VMCB9-FDRV6-6CDQM-RV23K-RP8F7</ProductKey> <ProductKey>4D2XH-PRBMM-8Q22B-K8BM3-MRW4W</ProductKey>
<TimeZone>Pacific Standard Time</TimeZone> <TimeZone>Pacific Standard Time</TimeZone>
<OEMInformation> <OEMInformation>
<Manufacturer>Dockur</Manufacturer> <Manufacturer>Dockur</Manufacturer>

126
readme.md
View File

@@ -88,7 +88,7 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
| `win81` | Windows 8.1 Pro | 4.2 GB | | `win81` | Windows 8.1 Pro | 4.2 GB |
| `win81e` | Windows 8.1 Enterprise | 3.8 GB | | `win81e` | Windows 8.1 Enterprise | 3.8 GB |
| `win7` | Windows 7 Enterprise | 3.0 GB | | `win7` | Windows 7 Enterprise | 3.0 GB |
| `vista` | Windows Vista Ultimate | 3.6 GB | | `vista` | Windows Vista Enterprise | 3.0 GB |
| `winxp` | Windows XP Professional | 0.6 GB | | `winxp` | Windows XP Professional | 0.6 GB |
|||| ||||
| `2022` | Windows Server 2022 | 4.7 GB | | `2022` | Windows Server 2022 | 4.7 GB |
@@ -103,37 +103,6 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
To install ARM64 versions of Windows use [dockur/windows-arm](https://github.com/dockur/windows-arm/). To install ARM64 versions of Windows use [dockur/windows-arm](https://github.com/dockur/windows-arm/).
* ### How do I connect using RDP?
The web-viewer is mainly meant to be used during installation, as its picture quality is low, and it has no audio or clipboard for example.
So for a better experience you can connect using any Microsoft Remote Desktop client to the IP of the container, using the username `docker` and by leaving the password empty.
There is a good RDP client for [Android](https://play.google.com/store/apps/details?id=com.microsoft.rdc.androidx) available from the Play Store and one for [iOS](https://apps.apple.com/nl/app/microsoft-remote-desktop/id714464092?l=en-GB) in the Apple Store. For Linux you can use [FreeRDP](https://www.freerdp.com/) and on Windows just type `mstsc` in the search box.
* ### How do I increase the amount of CPU or RAM?
By default, 2 CPU cores and 4 GB of RAM are allocated to the container, as those are the minimum requirements of Windows 11.
To increase this, add the following environment variables:
```yaml
environment:
RAM_SIZE: "8G"
CPU_CORES: "4"
```
* ### How do I change the size of the disk?
To expand the default size of 64 GB, add the `DISK_SIZE` setting to your compose file and set it to your preferred capacity:
```yaml
environment:
DISK_SIZE: "256G"
```
This can also be used to resize the existing disk to a larger capacity without any data loss.
* ### How do I change the storage location? * ### How do I change the storage location?
To change the storage location, include the following bind mount in your compose file: To change the storage location, include the following bind mount in your compose file:
@@ -145,40 +114,58 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
Replace the example path `/var/win` with the desired storage folder. Replace the example path `/var/win` with the desired storage folder.
* ### How do I change the size of the disk?
To expand the default size of 64 GB, add the `DISK_SIZE` setting to your compose file and set it to your preferred capacity:
```yaml
environment:
DISK_SIZE: "256G"
```
This can also be used to resize the existing disk to a larger capacity without any data loss.
* ### How do I share files with the host? * ### 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. ```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? * ### How do I install a custom image?
In order to download a custom ISO image, start a fresh container with the URL of the ISO specified in the `VERSION` environment variable: In order to download any ISO image that is not part of the list above, start a fresh container with the URL of that ISO specified in the `VERSION` environment variable, for example:
```yaml ```yaml
environment: environment:
VERSION: "https://example.com/win.iso" VERSION: "https://example.com/win.iso"
``` ```
Alternatively, you can also use a local file directly, and skip the download, by binding it in your compose file in this way: Alternatively, you can also use a local file directly, and skip the download altogether, by binding it in your compose file in this way:
```yaml ```yaml
volumes: 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 the desired ISO file. The value of `VERSION` will be ignored in this case. 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.
* ### How do I customize the installation? * ### How do I customize the installation?
You can customize every setting used by the automatic installation. Download the XML file corresponding to your Windows version, for example [win11x64.xml](https://raw.githubusercontent.com/dockur/windows/master/assets/win11x64.xml). Then apply your modifications to it, and add this line to your compose file: If you want to modify the settings used during the automatic installation, you can do this by editing the answer file corresponding to your Windows edition, for example [win11x64.xml](https://raw.githubusercontent.com/dockur/windows/master/assets/win11x64.xml) in the case of Windows 11 Pro.
Apply your modifications to it, and add this line to your compose file:
```yaml ```yaml
volumes: volumes:
- /home/user/custom.xml:/run/assets/win11x64.xml - /home/user/example.xml:/custom.xml
``` ```
Replace the example path `/home/user/custom.xml` with the filename of the modified XML file. Replace the example path `/home/user/example.xml` with the filename of the modified XML file.
* ### How do I run a script after installation? * ### How do I run a script after installation?
@@ -186,10 +173,10 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
```yaml ```yaml
volumes: volumes:
- /home/user/example:/storage/oem - /home/user/example:/oem
``` ```
The example path `/home/user/example` will be copied to `C:\OEM` during installation and the containing `install.bat` will be executed. 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.
* ### How do I perform a manual installation? * ### How do I perform a manual installation?
@@ -219,6 +206,37 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
- Once you see the desktop, open File Explorer and navigate to the CD-ROM drive (E:). Double-click on `virtio-win-gt-x64.msi` and proceed to install the VirtIO drivers. - Once you see the desktop, open File Explorer and navigate to the CD-ROM drive (E:). Double-click on `virtio-win-gt-x64.msi` and proceed to install the VirtIO drivers.
Enjoy your brand new machine, and don't forget to star this repo! Enjoy your brand new machine, and don't forget to star this repo!
* ### How do I verify if my system supports KVM?
To verify if your system supports KVM, run the following commands:
```bash
sudo apt install cpu-checker
sudo kvm-ok
```
If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, check the virtualization settings in the BIOS.
* ### How do I increase the amount of CPU or RAM?
By default, 2 CPU cores and 4 GB of RAM are allocated to the container, as those are the minimum requirements of Windows 11.
If there arises a need to increase this, add the following environment variables:
```yaml
environment:
RAM_SIZE: "8G"
CPU_CORES: "4"
```
* ### How do I connect using RDP?
The web-viewer is mainly meant to be used during installation, as its picture quality is low, and it has no audio or clipboard for example.
So for a better experience you can connect using any Microsoft Remote Desktop client to the IP of the container, using the username `docker` and by leaving the password empty.
There is a good RDP client for [Android](https://play.google.com/store/apps/details?id=com.microsoft.rdc.androidx) available from the Play Store and one for [iOS](https://apps.apple.com/nl/app/microsoft-remote-desktop/id714464092?l=en-GB) in the Apple Store. For Linux you can use [FreeRDP](https://www.freerdp.com/) and on Windows just type `mstsc` in the search box.
* ### How do I assign an individual IP address to the container? * ### How do I assign an individual IP address to the container?
@@ -272,21 +290,18 @@ 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 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:
```yaml ```yaml
environment:
DEVICE: "/dev/sda"
DEVICE2: "/dev/sdb"
devices: devices:
- /dev/sda - /dev/sdb:/disk1
- /dev/sdb - /dev/sdc:/disk2
``` ```
Use `DEVICE` if you want it to become your main drive, and use `DEVICE2` 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? * ### How do I pass-through a USB device?
@@ -298,17 +313,6 @@ docker run -it --rm --name windows -p 8006:8006 --device=/dev/kvm --cap-add NET_
devices: devices:
- /dev/bus/usb - /dev/bus/usb
``` ```
* ### How do I verify if my system supports KVM?
To verify if your system supports KVM, run the following commands:
```bash
sudo apt install cpu-checker
sudo kvm-ok
```
If you receive an error from `kvm-ok` indicating that KVM acceleration can't be used, check the virtualization settings in the BIOS.
* ### Is this project legal? * ### Is this project legal?

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +1,6 @@
#!/usr/bin/env bash #!/usr/bin/env bash
set -Eeuo pipefail set -Eeuo pipefail
ESD_URL=""
TMP="$STORAGE/tmp" TMP="$STORAGE/tmp"
DIR="$TMP/unpack" DIR="$TMP/unpack"
FB="falling back to manual installation!" FB="falling back to manual installation!"
@@ -10,6 +9,8 @@ EFISYS="efi/microsoft/boot/efisys_noprompt.bin"
hasDisk() { hasDisk() {
[ -b "/disk1" ] && return 0
[ -b "/dev/disk1" ] && return 0
[ -b "${DEVICE:-}" ] && return 0 [ -b "${DEVICE:-}" ] && return 0
if [ -s "$STORAGE/data.img" ] || [ -s "$STORAGE/data.qcow2" ]; then if [ -s "$STORAGE/data.img" ] || [ -s "$STORAGE/data.qcow2" ]; then
@@ -28,6 +29,72 @@ skipInstall() {
return 1 return 1
} }
startInstall() {
html "Starting Windows..."
[ -z "$MANUAL" ] && MANUAL="N"
if [ -n "$CUSTOM" ]; then
ISO="$CUSTOM"
else
local file="${VERSION/\//}.iso"
if [[ "${VERSION,,}" == "http"* ]]; then
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
skipInstall && return 1
if [ -f "$ISO" ] && [ -s "$ISO" ]; then
# 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="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
[[ "$magic" == "16" ]] && return 1
fi
if [ -z "$CUSTOM" ]; then
BOOT="$ISO"
ISO=$(basename "$ISO")
ISO="$TMP/$ISO"
else
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"
rm -rf "$TMP"
mkdir -p "$TMP"
return 0
}
finishInstall() { finishInstall() {
local iso="$1" local iso="$1"
@@ -44,7 +111,6 @@ finishInstall() {
fi fi
fi fi
rm -f "$STORAGE/windows.ver"
rm -f "$STORAGE/windows.old" rm -f "$STORAGE/windows.old"
rm -f "$STORAGE/windows.boot" rm -f "$STORAGE/windows.boot"
rm -f "$STORAGE/windows.mode" rm -f "$STORAGE/windows.mode"
@@ -76,101 +142,60 @@ abortInstall() {
local iso="$1" local iso="$1"
if [[ "$iso" != "$STORAGE/$BASE" ]]; then [[ "${iso,,}" == *".esd" ]] && exit 60
if ! mv -f "$iso" "$STORAGE/$BASE"; then
error "Failed to move ISO file: $iso" && return 1
fi
fi
finishInstall "$STORAGE/$BASE" "Y" && return 0
return 1
}
startInstall() {
html "Starting Windows..."
[ -z "$MANUAL" ] && MANUAL="N"
if [ -f "$STORAGE/$CUSTOM" ]; then
EXTERNAL="Y"
BASE="$CUSTOM"
if [ -n "$CUSTOM" ]; then
BOOT="$iso"
REMOVE="N"
else else
if [[ "$iso" != "$BOOT" ]]; then
CUSTOM="" if ! mv -f "$iso" "$BOOT"; then
error "Failed to move ISO file: $iso" && return 1
if [[ "${VERSION,,}" != "http"* ]]; then
EXTERNAL="N"
BASE="$VERSION.iso"
else
EXTERNAL="Y"
BASE=$(basename "${VERSION%%\?*}")
: "${BASE//+/ }"; printf -v BASE '%b' "${_//%/\\x}"
BASE=$(echo "$BASE" | sed -e 's/[^A-Za-z0-9._-]/_/g')
fi
fi
if [[ "${PLATFORM,,}" == "x64" ]]; then
! migrateFiles "$BASE" "$VERSION" && error "Migration failed!" && exit 57
fi
if skipInstall; then
[ ! -f "$STORAGE/$BASE" ] && BASE=""
[[ "${PLATFORM,,}" == "arm64" ]] && VGA="virtio-gpu"
return 1
fi
if [ -f "$STORAGE/$BASE" ]; then
# 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="$(printf '%s' "$magic" | od -A n -t x1 -v | tr -d ' \n')"
if [[ "$magic" == "16" ]]; then
if hasDisk || [[ "$MANUAL" == [Yy1]* ]]; then
return 1
fi fi
fi fi
EXTERNAL="Y"
CUSTOM="$BASE"
fi fi
rm -rf "$TMP" finishInstall "$BOOT" "Y" && return 0
mkdir -p "$TMP" return 1
if [ ! -f "$STORAGE/$CUSTOM" ]; then
CUSTOM=""
ISO="$TMP/$BASE"
else
ISO="$STORAGE/$CUSTOM"
fi
return 0
} }
detectCustom() { detectCustom() {
CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname windows.iso -printf "%f\n" | head -n 1) local file=""
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname custom.iso -printf "%f\n" | head -n 1) local size base
[ -z "$CUSTOM" ] && CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname boot.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)
if [ -z "$CUSTOM" ] && [[ "${VERSION,,}" != "http"* ]]; then CUSTOM=""
FN="${VERSION/\/storage\//}" ORIGINAL=""
[[ "$FN" == "."* ]] && FN="${FN:1}"
CUSTOM=$(find "$STORAGE" -maxdepth 1 -type f -iname "$FN" -printf "%f\n" | head -n 1) if [[ "${VERSION,,}" != "http"* ]]; then
base="${VERSION/\/storage\//}"
[[ "$base" == "."* ]] && base="${file:1}"
[[ "$base" == *"/"* ]] && base=""
[ -n "$base" ] && file=$(find "$STORAGE" -maxdepth 1 -type f -iname "$base" -printf "%f\n" | head -n 1)
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.img -printf "%f\n" | head -n 1)
[ -n "$file" ] && file="$STORAGE/$file"
base="/custom.iso"
[ -f "$base" ] && [ -s "$base" ] && file="$base"
[ -z "$file" ] && return 0
[ ! -f "$file" ] && return 0
[ ! -s "$file" ] && return 0
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
CUSTOM="$file"
rm -f "$base"
fi fi
return 0 return 0
@@ -180,19 +205,15 @@ getESD() {
local dir="$1" local dir="$1"
local version="$2" local version="$2"
local editionName
local winCatalog size local winCatalog size
case "${version,,}" in if ! isESD "${version,,}"; then
"win11${PLATFORM,,}") error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
winCatalog="https://go.microsoft.com/fwlink?linkid=2156292" fi
;;
"win10${PLATFORM,,}") winCatalog=$(getCatalog "$version" "url")
winCatalog="https://go.microsoft.com/fwlink/?LinkId=841361" editionName=$(getCatalog "$version" "edition")
;;
*)
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
;;
esac
local msg="Downloading product information from Microsoft..." local msg="Downloading product information from Microsoft..."
info "$msg" && html "$msg" info "$msg" && html "$msg"
@@ -205,7 +226,7 @@ getESD() {
local eFile="esd_edition.xml" local eFile="esd_edition.xml"
local fFile="products_filter.xml" local fFile="products_filter.xml"
{ wget "$winCatalog" -O "$dir/$wFile" -q; rc=$?; } || : { wget "$winCatalog" -O "$dir/$wFile" -q --timeout=10; rc=$?; } || :
(( rc != 0 )) && error "Failed to download $winCatalog , reason: $rc" && return 1 (( rc != 0 )) && error "Failed to download $winCatalog , reason: $rc" && return 1
cd "$dir" cd "$dir"
@@ -222,7 +243,6 @@ getESD() {
fi fi
local esdLang="en-us" local esdLang="en-us"
local editionName="Professional"
local edQuery='//File[Architecture="'${PLATFORM}'"][Edition="'${editionName}'"]' local edQuery='//File[Architecture="'${PLATFORM}'"][Edition="'${editionName}'"]'
echo -e '<Catalog>' > "$dir/$fFile" echo -e '<Catalog>' > "$dir/$fFile"
@@ -235,29 +255,75 @@ getESD() {
error "Failed to find Windows product in $eFile!" && return 1 error "Failed to find Windows product in $eFile!" && return 1
fi fi
ESD_URL=$(xmllint --nonet --xpath '//FilePath' "$dir/$eFile" | sed -E -e 's/<[\/]?FilePath>//g') local tag="FilePath"
ESD=$(xmllint --nonet --xpath "//$tag" "$dir/$eFile" | sed -E -e "s/<[\/]?$tag>//g")
if [ -z "$ESD_URL" ]; then if [ -z "$ESD" ]; then
error "Failed to find ESD URL in $eFile!" && return 1 error "Failed to find ESD URL in $eFile!" && return 1
fi fi
tag="Sha1"
ESD_SUM=$(xmllint --nonet --xpath "//$tag" "$dir/$eFile" | sed -E -e "s/<[\/]?$tag>//g")
tag="Size"
ESD_SIZE=$(xmllint --nonet --xpath "//$tag" "$dir/$eFile" | sed -E -e "s/<[\/]?$tag>//g")
rm -rf "$dir" rm -rf "$dir"
return 0 return 0
} }
verifyFile() {
local iso="$1"
local size="$2"
local total="$3"
local check="$4"
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"
fi
local hash=""
local algo="SHA256"
[ -z "$check" ] && return 0
[[ "$VERIFY" != [Yy1]* ]] && return 0
[[ "${#check}" == "40" ]] && algo="SHA1"
local msg="Verifying downloaded ISO..."
info "$msg" && html "$msg"
if [[ "${algo,,}" != "sha256" ]]; then
hash=$(sha1sum "$iso" | cut -f1 -d' ')
else
hash=$(sha256sum "$iso" | cut -f1 -d' ')
fi
if [[ "$hash" == "$check" ]]; then
info "Succesfully verified ISO!" && return 0
fi
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() { doMido() {
local iso="$1" local iso="$1"
local version="$2" local version="$2"
local desc="$3" local desc="$3"
local rc local rc sum size total
rm -f "$iso" rm -f "$iso"
rm -f "$iso.PART" rm -f "$iso.PART"
size=$(getMido "$version" "size")
sum=$(getMido "$version" "sum")
local msg="Downloading $desc..." local msg="Downloading $desc..."
info "$msg" && html "$msg" info "$msg" && html "$msg"
/run/progress.sh "$iso.PART" "Downloading $desc ([P])..." & /run/progress.sh "$iso.PART" "$size" "Downloading $desc ([P])..." &
cd "$TMP" cd "$TMP"
{ /run/mido.sh "${version,,}"; rc=$?; } || : { /run/mido.sh "${version,,}"; rc=$?; } || :
@@ -266,7 +332,9 @@ doMido() {
fKill "progress.sh" fKill "progress.sh"
if (( rc == 0 )) && [ -f "$iso" ]; then if (( rc == 0 )) && [ -f "$iso" ]; then
if [ "$(stat -c%s "$iso")" -gt 100000000 ]; then total=$(stat -c%s "$iso")
if [ "$total" -gt 100000000 ]; then
! verifyFile "$iso" "$size" "$total" "$sum" && return 1
html "Download finished successfully..." && return 0 html "Download finished successfully..." && return 0
fi fi
fi fi
@@ -281,8 +349,10 @@ downloadFile() {
local iso="$1" local iso="$1"
local url="$2" local url="$2"
local desc="$3" local sum="$3"
local rc progress domain local size="$4"
local desc="$5"
local rc total progress domain dots
rm -f "$iso" rm -f "$iso"
@@ -294,27 +364,34 @@ downloadFile() {
fi fi
local msg="Downloading $desc..." local msg="Downloading $desc..."
html "$msg"
domain=$(echo "$url" | awk -F/ '{print $3}') domain=$(echo "$url" | awk -F/ '{print $3}')
domain=$(expr "$domain" : '.*\.\(.*\..*\)') dots=$(echo "$domain" | tr -cd '.' | wc -c)
[[ "${domain,,}" != *"microsoft.com" ]] && msg="Downloading $desc from $domain..." (( dots > 1 )) && domain=$(expr "$domain" : '.*\.\(.*\..*\)')
info "$msg" && html "$msg" if [ -n "$domain" ] && [[ "${domain,,}" != *"microsoft.com" ]]; then
/run/progress.sh "$iso" "Downloading $desc ([P])..." & msg="Downloading $desc from $domain..."
fi
{ wget "$url" -O "$iso" -q --show-progress "$progress"; rc=$?; } || : info "$msg"
/run/progress.sh "$iso" "$size" "Downloading $desc ([P])..." &
{ wget "$url" -O "$iso" -q --timeout=10 --show-progress "$progress"; rc=$?; } || :
fKill "progress.sh" fKill "progress.sh"
if (( rc == 0 )) && [ -f "$iso" ]; then if (( rc == 0 )) && [ -f "$iso" ]; then
if [ "$(stat -c%s "$iso")" -gt 100000000 ]; then total=$(stat -c%s "$iso")
if [ "$total" -gt 100000000 ]; then
! verifyFile "$iso" "$size" "$total" "$sum" && return 1
html "Download finished successfully..." && return 0 html "Download finished successfully..." && return 0
fi fi
fi fi
rm -f "$iso"
error "Failed to download $url , reason: $rc" error "Failed to download $url , reason: $rc"
rm -f "$iso"
return 1 return 1
} }
@@ -323,33 +400,27 @@ downloadImage() {
local iso="$1" local iso="$1"
local version="$2" local version="$2"
local tried="n" local tried="n"
local url desc local url sum size base desc
if [[ "${version,,}" == "http"* ]]; then if [[ "${version,,}" == "http"* ]]; then
base=$(basename "$iso")
desc=$(getName "$BASE" "$BASE") desc=$(fromFile "$base")
downloadFile "$iso" "$version" "$desc" && return 0 downloadFile "$iso" "$version" "" "" "$desc" && return 0
return 1 return 1
fi fi
if ! validVersion "$version"; then if ! validVersion "$version"; then
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1 error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
fi fi
if [[ "${PLATFORM,,}" == "x64" ]]; then desc=$(printVersion "$version" "")
desc=$(printVersion "$version" "Windows")
else if isMido "$version"; then
desc=$(printVersion "$version" "Windows for ${PLATFORM}") tried="y"
doMido "$iso" "$version" "$desc" && return 0
fi fi
if [[ "${PLATFORM,,}" == "x64" ]]; then switchEdition "$version"
if isMido "$version"; then
tried="y"
doMido "$iso" "$version" "$desc" && return 0
fi
switchEdition "$version"
fi
if isESD "$version"; then if isESD "$version"; then
@@ -360,42 +431,44 @@ downloadImage() {
tried="y" tried="y"
if getESD "$TMP/esd" "$version"; then if getESD "$TMP/esd" "$version"; then
ISO="$TMP/$version.esd" local prev="$ISO"
downloadFile "$ISO" "$ESD_URL" "$desc" && return 0 ISO="${ISO%.*}.esd"
ISO="$TMP/$BASE" downloadFile "$ISO" "$ESD" "$ESD_SUM" "$ESD_SIZE" "$desc" && return 0
ISO="$prev"
fi fi
fi fi
url=$(getLink "$version") for ((i=1;i<=MIRRORS;i++)); do
if [ -n "$url" ]; then url=$(getLink "$i" "$version")
if [[ "$tried" != "n" ]]; then if [ -n "$url" ]; then
info "Failed to download $desc from Microsoft, will try another mirror now..." if [[ "$tried" != "n" ]]; then
info "Failed to download $desc, will try another mirror now..."
fi
tried="y"
size=$(getSize "$i" "$version")
sum=$(getHash "$i" "$version")
downloadFile "$iso" "$url" "$sum" "$size" "$desc" && return 0
fi fi
tried="y" done
downloadFile "$iso" "$url" "$desc" && return 0
fi
url=$(secondLink "$version")
if [ -n "$url" ]; then
if [[ "$tried" != "n" ]]; then
info "Failed to download $desc, will try another mirror now..."
fi
tried="y"
downloadFile "$iso" "$url" "$desc" && return 0
fi
return 1 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() { extractESD() {
local iso="$1" local iso="$1"
@@ -450,26 +523,25 @@ extractESD() {
error "Adding Windows Setup failed" && return ${retVal} error "Adding Windows Setup failed" && return ${retVal}
} }
if [[ "${PLATFORM,,}" == "x64" ]]; then
LABEL="CCCOMA_X64FRE_EN-US_DV9"
else
LABEL="CPBA_A64FRE_EN-US_DV9"
fi
local msg="Extracting $desc image..." local msg="Extracting $desc image..."
info "$msg" && html "$msg" info "$msg" && html "$msg"
local edition imageIndex imageEdition local edition imageIndex imageEdition
edition=$(getCatalog "$version" "name")
case "${version,,}" in if [ -z "$edition" ]; then
"win11${PLATFORM,,}") error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
edition="11 pro" fi
;;
"win10${PLATFORM,,}")
edition="10 pro"
;;
*)
error "Invalid VERSION specified, value \"$version\" is not recognized!" && return 1
;;
esac
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
@@ -477,7 +549,7 @@ extractESD() {
return 0 return 0
done done
error "Failed to find product in install.wim!" && return 1 error "Failed to find product '$edition' in install.wim!" && return 1
} }
extractImage() { extractImage() {
@@ -485,11 +557,14 @@ extractImage() {
local iso="$1" local iso="$1"
local dir="$2" local dir="$2"
local version="$3" local version="$3"
local desc="downloaded ISO" local desc="local ISO"
local size size_gb space space_gb local size size_gb space space_gb
if [[ "$EXTERNAL" != [Yy1]* ]] && [ -z "$CUSTOM" ]; then if [ -z "$CUSTOM" ]; then
desc=$(printVersion "$version" "downloaded ISO") desc="downloaded ISO"
if [[ "$version" != "http"* ]]; then
desc=$(printVersion "$version" "$desc")
fi
fi fi
if [[ "${iso,,}" == *".esd" ]]; then if [[ "${iso,,}" == *".esd" ]]; then
@@ -498,7 +573,6 @@ extractImage() {
fi fi
local msg="Extracting $desc image..." local msg="Extracting $desc image..."
[ -n "$CUSTOM" ] && msg="Extracting local ISO image..."
info "$msg" && html "$msg" info "$msg" && html "$msg"
rm -rf "$dir" rm -rf "$dir"
@@ -523,56 +597,118 @@ extractImage() {
error "Failed to extract ISO file: $iso" && return 1 error "Failed to extract ISO file: $iso" && return 1
fi fi
LABEL=$(isoinfo -d -i "$iso" | sed -n 's/Volume id: //p')
return 0
}
setXML() {
[[ "$MANUAL" == [Yy1]* ]] && return 0
local file="/custom.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
file="$STORAGE/custom.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
file="/run/assets/custom.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
file="$1"
[ -z "$file" ] && file="/run/assets/$DETECTED.xml"
[ -f "$file" ] && [ -s "$file" ] && XML="$file" && return 0
return 1
}
selectVersion() {
local tag="$1"
local xml="$2"
local id find name prefer
name=$(sed -n "/$tag/{s/.*<$tag>\(.*\)<\/$tag>.*/\1/;p}" <<< "$xml")
[[ "$name" == *"Operating System"* ]] && name=""
[ -z "$name" ] && return 0
id=$(fromName "$name")
[ -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
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
prefer="$id"
[ -f "/run/assets/$prefer.xml" ] && find=$(printEdition "$prefer" "") || find=""
if [ -n "$find" ] && [[ "${xml,,}" == *"<${tag,,}>${find,,}</${tag,,}>"* ]]; then
echo "$prefer" && return 0
fi
prefer=$(getVersion "$name")
echo "$prefer"
return 0
}
detectVersion() {
local xml="$1"
local id=""
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
return 0 return 0
} }
detectImage() { detectImage() {
XML=""
local dsc
local dir="$1" local dir="$1"
local version="$2"
local desc msg
if [ -n "$CUSTOM" ]; then XML=""
DETECTED=""
else if [ -z "$DETECTED" ] && [[ "${version,,}" != "http"* ]]; then
if [ -z "$DETECTED" ] && [[ "$EXTERNAL" != [Yy1]* ]]; then [ -z "$CUSTOM" ] && DETECTED="$version"
DETECTED="$VERSION"
fi
fi fi
if [ -n "$DETECTED" ]; then if [ -n "$DETECTED" ]; then
if [ -f "/run/assets/$DETECTED.xml" ]; then [[ "${DETECTED,,}" == "winxp"* ]] && return 0
[[ "$MANUAL" != [Yy1]* ]] && XML="$DETECTED.xml"
return 0
fi
if [[ "${DETECTED,,}" != "winxp"* ]]; then setXML "" && return 0
dsc=$(printVersion "$DETECTED" "$DETECTED")
warn "got $dsc, but no matching file called $DETECTED.xml exists, $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
info "Detecting Windows version from ISO image..." info "Detecting version from ISO image..."
if [[ "${PLATFORM,,}" == "x64" ]]; then if [ -f "$dir/WIN51" ] || [ -f "$dir/SETUPXP.HTM" ]; then
if [ -f "$dir/WIN51" ] || [ -f "$dir/SETUPXP.HTM" ]; then [ -d "$dir/AMD64" ] && DETECTED="winxpx64" || DETECTED="winxpx86"
if [ -d "$dir/AMD64" ]; then desc=$(printEdition "$DETECTED" "Windows XP")
DETECTED="winxpx64" info "Detected: $desc"
else return 0
DETECTED="winxpx86"
fi
dsc=$(printVersion "$DETECTED" "$DETECTED")
info "Detected: $dsc"
return 0
fi
fi fi
local src loc tag result name name2 desc local src loc info
src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1) src=$(find "$dir" -maxdepth 1 -type d -iname sources | head -n 1)
if [ ! -d "$src" ]; then if [ ! -d "$src" ]; then
@@ -588,33 +724,26 @@ detectImage() {
warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" && return 1 warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" && return 1
fi fi
tag="DISPLAYNAME" info=$(wimlib-imagex info -xml "$loc" | tr -d '\000')
result=$(wimlib-imagex info -xml "$loc" | tr -d '\000') DETECTED=$(detectVersion "$info")
name=$(sed -n "/$tag/{s/.*<$tag>\(.*\)<\/$tag>.*/\1/;p}" <<< "$result")
DETECTED=$(getVersion "$name")
if [ -z "$DETECTED" ]; then if [ -z "$DETECTED" ]; then
msg="Failed to determine Windows version from image"
tag="PRODUCTNAME" setXML "" && info "${msg}!" && return 0
name2=$(sed -n "/$tag/{s/.*<$tag>\(.*\)<\/$tag>.*/\1/;p}" <<< "$result") warn "${msg}, $FB" && return 0
[ -z "$name" ] && name="$name2"
DETECTED=$(getVersion "$name2")
fi fi
if [ -z "$DETECTED" ]; then desc=$(printEdition "$DETECTED" "$DETECTED")
warn "failed to determine Windows version from string '$name', $FB" && return 0
fi
desc=$(printVersion "$DETECTED" "$DETECTED") info "Detected: $desc"
setXML "" && return 0
if [ -f "/run/assets/$DETECTED.xml" ]; then msg="the answer file for $desc was not found ($DETECTED.xml)"
[[ "$MANUAL" != [Yy1]* ]] && XML="$DETECTED.xml" local fallback="/run/assets/${DETECTED%%-*}.xml"
info "Detected: $desc"
else
warn "detected $desc, but no matching file called $DETECTED.xml exists, $FB."
fi
setXML "$fallback" && warn "${msg}." && return 0
warn "${msg}, $FB."
return 0 return 0
} }
@@ -622,45 +751,40 @@ prepareImage() {
local iso="$1" local iso="$1"
local dir="$2" local dir="$2"
local missing
case "${DETECTED,,}" in
"winxp"* )
BOOT_MODE="windows_legacy"
prepareXP "$iso" "$dir" && return 0
error "Failed to prepare Windows XP ISO!" && return 1
;;
"winvista"* | "win7"* | "win2008"* )
BOOT_MODE="windows_legacy" ;;
esac
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
if [[ "${DETECTED,,}" != "winxp"* ]] && [[ "${DETECTED,,}" != "win2008"* ]]; then
if [[ "${DETECTED,,}" != "winvista"* ]] && [[ "${DETECTED,,}" != "win7"* ]]; then
if [ -f "$dir/$ETFS" ] && [ -f "$dir/$EFISYS" ]; then [ -f "$dir/$ETFS" ] && [ -f "$dir/$EFISYS" ] && return 0
return 0
fi
if [ ! -f "$dir/$ETFS" ]; then missing=$(basename "$dir/$EFISYS")
warn "failed to locate file 'etfsboot.com' in ISO image, falling back to legacy boot!" [ ! -f "$dir/$ETFS" ] && missing=$(basename "$dir/$ETFS")
else warn "failed to locate file '${missing,,}' in ISO image!"
warn "failed to locate file 'efisys_noprompt.bin' in ISO image, falling back to legacy boot!"
fi
fi [[ "${PLATFORM,,}" == "arm64" ]] && return 1
fi BOOT_MODE="windows_legacy"
fi fi
[[ "${PLATFORM,,}" == "arm64" ]] && return 1 prepareLegacy "$iso" "$dir" && return 0
if [[ "${DETECTED,,}" == "winxp"* ]]; then error "Failed to extract boot image from ISO!"
if ! prepareXP "$iso" "$dir"; then return 1
error "Failed to prepare Windows XP ISO!" && return 1
fi
else
if ! prepareLegacy "$iso" "$dir"; then
error "Failed to prepare Windows ISO!" && return 1
fi
fi
return 0
} }
updateImage() { updateImage() {
local iso="$1" local dir="$1"
local dir="$2" local asset="$2"
local asset="/run/assets/$3"
local path src loc xml index result local path src loc xml index result
[ ! -s "$asset" ] || [ ! -f "$asset" ] && return 0 [ ! -s "$asset" ] || [ ! -f "$asset" ] && return 0
@@ -694,20 +818,21 @@ updateImage() {
fi fi
if ! wimlib-imagex update "$loc" "$index" --command "add $asset /autounattend.xml" > /dev/null; then if ! wimlib-imagex update "$loc" "$index" --command "add $asset /autounattend.xml" > /dev/null; then
warn "failed to add $xml to ISO image, $FB" && return 1 warn "failed to add answer file ($xml) to ISO image, $FB" && return 1
fi fi
return 0 return 0
} }
copyOEM() { copyOEM() {
local dir="$1" local dir="$1"
local folder="$STORAGE/oem" local folder="/oem"
local src 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 [ ! -d "$folder" ] && return 0
local msg="Copying OEM folder to image..." local msg="Copying OEM folder to image..."
@@ -734,12 +859,15 @@ buildImage() {
local dir="$1" local dir="$1"
local failed="N" local failed="N"
local cat="BOOT.CAT" local cat="BOOT.CAT"
local label="${BASE%.*}"
local log="/run/shm/iso.log" local log="/run/shm/iso.log"
local size size_gb space space_gb desc local base size size_gb space space_gb desc
label="${label::30}" if [ -f "$BOOT" ]; then
local out="$TMP/$label.tmp" error "File $BOOT does already exist?!" && return 1
fi
base=$(basename "$BOOT")
local out="$TMP/${base%.*}.tmp"
rm -f "$out" rm -f "$out"
desc=$(printVersion "$DETECTED" "ISO") desc=$(printVersion "$DETECTED" "ISO")
@@ -756,9 +884,11 @@ buildImage() {
error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1 error "Not enough free space in $STORAGE, have $space_gb GB available but need at least $size_gb GB." && return 1
fi fi
[ -z "$LABEL" ] && LABEL="Windows"
if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then if [[ "${BOOT_MODE,,}" != "windows_legacy" ]]; then
if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -c "$cat" -iso-level 4 -J -l -D -N -joliet-long -relaxed-filenames -V "$label" \ if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -c "$cat" -iso-level 4 -J -l -D -N -joliet-long -relaxed-filenames -V "${LABEL::30}" \
-udf -boot-info-table -eltorito-alt-boot -eltorito-boot "$EFISYS" -no-emul-boot -allow-limited-size -quiet "$dir" 2> "$log"; then -udf -boot-info-table -eltorito-alt-boot -eltorito-boot "$EFISYS" -no-emul-boot -allow-limited-size -quiet "$dir" 2> "$log"; then
failed="Y" failed="Y"
fi fi
@@ -767,7 +897,7 @@ buildImage() {
if [[ "${DETECTED,,}" != "winxp"* ]]; then if [[ "${DETECTED,,}" != "winxp"* ]]; then
if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -c "$cat" -iso-level 2 -J -l -D -N -joliet-long -relaxed-filenames -V "$label" \ if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -c "$cat" -iso-level 2 -J -l -D -N -joliet-long -relaxed-filenames -V "${LABEL::30}" \
-udf -allow-limited-size -quiet "$dir" 2> "$log"; then -udf -allow-limited-size -quiet "$dir" 2> "$log"; then
failed="Y" failed="Y"
fi fi
@@ -775,7 +905,7 @@ buildImage() {
else else
if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -boot-load-seg 1984 -boot-load-size 4 -c "$cat" -iso-level 2 -J -l -D -N -joliet-long \ if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -boot-load-seg 1984 -boot-load-size 4 -c "$cat" -iso-level 2 -J -l -D -N -joliet-long \
-relaxed-filenames -V "$label" -quiet "$dir" 2> "$log"; then -relaxed-filenames -V "${LABEL::30}" -quiet "$dir" 2> "$log"; then
failed="Y" failed="Y"
fi fi
@@ -793,11 +923,7 @@ buildImage() {
[ -s "$log" ] && error="$(<"$log")" [ -s "$log" ] && error="$(<"$log")"
[[ "$error" != "$hide" ]] && echo "$error" [[ "$error" != "$hide" ]] && echo "$error"
if [ -f "$STORAGE/$BASE" ]; then mv "$out" "$BOOT"
error "File $STORAGE/$BASE does already exist?!" && return 1
fi
mv "$out" "$STORAGE/$BASE"
return 0 return 0
} }
@@ -805,6 +931,15 @@ bootWindows() {
rm -rf "$TMP" 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 if [ -s "$STORAGE/windows.mode" ] && [ -f "$STORAGE/windows.mode" ]; then
BOOT_MODE=$(<"$STORAGE/windows.mode") BOOT_MODE=$(<"$STORAGE/windows.mode")
if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then if [ -s "$STORAGE/windows.old" ] && [ -f "$STORAGE/windows.old" ]; then
@@ -872,7 +1007,7 @@ if ! extractImage "$ISO" "$DIR" "$VERSION"; then
exit 62 exit 62
fi fi
if ! detectImage "$DIR"; then if ! detectImage "$DIR" "$VERSION"; then
abortInstall "$ISO" && return 0 abortInstall "$ISO" && return 0
exit 60 exit 60
fi fi
@@ -882,15 +1017,13 @@ if ! prepareImage "$ISO" "$DIR"; then
exit 60 exit 60
fi fi
if ! updateImage "$ISO" "$DIR" "$XML"; then if ! updateImage "$DIR" "$XML"; then
abortInstall "$ISO" && return 0 abortInstall "$ISO" && return 0
exit 60 exit 60
fi fi
if ! rm -f "$ISO" 2> /dev/null; then if ! removeDownload "$ISO"; then
BASE="windows.iso" exit 64
ISO="$STORAGE/$BASE"
rm -f "$ISO"
fi fi
if ! copyOEM "$DIR"; then if ! copyOEM "$DIR"; then
@@ -901,7 +1034,7 @@ if ! buildImage "$DIR"; then
exit 65 exit 65
fi fi
if ! finishInstall "$STORAGE/$BASE" "N"; then if ! finishInstall "$BOOT" "N"; then
exit 69 exit 69
fi fi

View File

@@ -388,7 +388,7 @@ consumer_download() {
# Filter for 64-bit ISO download URL # Filter for 64-bit ISO download URL
# sed: HTML decode "&" character # sed: HTML decode "&" character
# tr: Filter for only alphanumerics or punctuation # tr: Filter for only alphanumerics or punctuation
iso_download_link="$(echo "$iso_download_link_html" | grep -o "https://software.download.prss.microsoft.com.*IsoX64" | cut -d '"' -f 1 | sed 's/&amp;/\&/g' | tr -cd '[:alnum:][:punct:]' | head -c 512)" iso_download_link="$(echo "$iso_download_link_html" | grep -o "https://software.download.prss.microsoft.com.*IsoX64" | cut -d '"' -f 1 | sed 's/&amp;/\&/g' | tr -cd '[:alnum:][:punct:]')"
if ! [ "$iso_download_link" ]; then if ! [ "$iso_download_link" ]; then
# This should only happen if there's been some change to the download endpoint web address # This should only happen if there's been some change to the download endpoint web address

View File

@@ -28,7 +28,7 @@ boot() {
[ -f "$QEMU_END" ] && return 0 [ -f "$QEMU_END" ] && return 0
if [ -s "$QEMU_PTY" ]; then if [ -s "$QEMU_PTY" ]; then
if grep -iq " hard" "$QEMU_PTY"; then if [ "$(stat -c%s "$QEMU_PTY")" -gt 7 ]; then
info "Windows started succesfully, visit http://localhost:8006/ to view the screen..." info "Windows started succesfully, visit http://localhost:8006/ to view the screen..."
return 0 return 0
fi fi
@@ -81,11 +81,12 @@ finish() {
done done
fi fi
if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$STORAGE/$BASE" ]; then if [ ! -f "$STORAGE/windows.boot" ] && [ -f "$BOOT" ]; then
# Remove CD-ROM ISO after install # Remove CD-ROM ISO after install
if ready; then 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 fi
fi fi
@@ -93,7 +94,9 @@ finish() {
pid="/var/run/tpm.pid" pid="/var/run/tpm.pid"
[ -s "$pid" ] && pKill "$(<"$pid")" [ -s "$pid" ] && pKill "$(<"$pid")"
fKill "wsdd" pid="/var/run/wsdd.pid"
[ -s "$pid" ] && pKill "$(<"$pid")"
fKill "smbd" fKill "smbd"
closeNetwork closeNetwork

View File

@@ -14,10 +14,14 @@ if [[ "$DHCP" == [Yy1]* ]]; then
interface="$VM_NET_DEV" interface="$VM_NET_DEV"
fi fi
share="$STORAGE/shared" share="/shared"
if [ ! -d "$share" ] && [ -d "$STORAGE/shared" ]; then
share="$STORAGE/shared"
fi
mkdir -p "$share" mkdir -p "$share"
[ -z "$(ls -A "$share")" ] && chmod -R 777 "$share" [ -z "$(ls -A "$share")" ] && chmod 777 "$share"
{ echo "[global]" { echo "[global]"
echo " server string = Dockur" echo " server string = Dockur"
@@ -53,16 +57,16 @@ mkdir -p "$share"
echo "" echo ""
echo "Using this folder you can share files with the host machine." echo "Using this folder you can share files with the host machine."
echo "" 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 ""
echo " volumes:" echo " volumes:"
echo " - \"/home/user/example:/storage/shared\"" echo " - \"/home/user/example:/shared\""
echo "" echo ""
echo "Or in your run command:" echo "Or in your run command:"
echo "" echo ""
echo " -v \"/home/user/example:/storage/shared\"" echo " -v \"/home/user/example:/shared\""
echo "" 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 "" echo ""
} | unix2dos > "$share/readme.txt" } | unix2dos > "$share/readme.txt"
@@ -82,6 +86,7 @@ if [[ "$isXP" == [Yy1]* ]]; then
else else
# Enable Web Service Discovery # Enable Web Service Discovery
wsdd -i "$interface" -p -n "$hostname" & wsdd -i "$interface" -p -n "$hostname" &
echo "$!" > /var/run/wsdd.pid
fi fi
return 0 return 0