Compare commits

...

6 Commits
v1.18 ... v1.19

Author SHA1 Message Date
Kroese
1215988354 feat: Windows XP support (#144) 2024-02-01 14:16:54 +01:00
Kroese
ae57b1353c docs: USB pass-through (#143) 2024-01-31 13:40:50 +01:00
Kroese
b807b422cd docs: Readme (#141) 2024-01-31 04:38:22 +01:00
Kroese
890a7e4413 docs: Readme (#139) 2024-01-30 16:49:53 +01:00
Kroese
5a9be7ffb5 docs: Readme (#138) 2024-01-30 16:47:42 +01:00
Kroese
9c8eee7a4d fix: Delete win2025 xml (#136) 2024-01-29 19:38:27 +01:00
5 changed files with 291 additions and 377 deletions

View File

@@ -11,7 +11,7 @@ jobs:
- name: Run ShellCheck - name: Run ShellCheck
uses: ludeeus/action-shellcheck@master uses: ludeeus/action-shellcheck@master
env: env:
SHELLCHECK_OPTS: -x --source-path=src -e SC1091 -e SC2001 -e SC2002 -e SC2034 -e SC2064 -e SC2153 -e SC2317 SHELLCHECK_OPTS: -x --source-path=src -e SC1091 -e SC2001 -e SC2002 -e SC2034 -e SC2064 -e SC2153 -e SC2317 -e SC2028
- name: Validate XML - name: Validate XML
uses: action-pack/valid-xml@v1 uses: action-pack/valid-xml@v1
with: with:

View File

@@ -1,331 +0,0 @@
<?xml version="1.0" encoding="UTF-8"?>
<unattend xmlns="urn:schemas-microsoft-com:unattend" xmlns:wcm="http://schemas.microsoft.com/WMIConfig/2002/State">
<settings pass="windowsPE">
<component name="Microsoft-Windows-International-Core-WinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SetupUILanguage>
<UILanguage>en-US</UILanguage>
</SetupUILanguage>
<InputLocale>0409:00000409</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>en-US</UserLocale>
</component>
<component name="Microsoft-Windows-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DiskConfiguration>
<Disk wcm:action="add">
<DiskID>0</DiskID>
<WillWipeDisk>true</WillWipeDisk>
<CreatePartitions>
<!-- System partition (ESP) -->
<CreatePartition wcm:action="add">
<Order>1</Order>
<Type>EFI</Type>
<Size>128</Size>
</CreatePartition>
<!-- Microsoft reserved partition (MSR) -->
<CreatePartition wcm:action="add">
<Order>2</Order>
<Type>MSR</Type>
<Size>128</Size>
</CreatePartition>
<!-- Windows partition -->
<CreatePartition wcm:action="add">
<Order>3</Order>
<Type>Primary</Type>
<Extend>true</Extend>
</CreatePartition>
</CreatePartitions>
<ModifyPartitions>
<!-- System partition (ESP) -->
<ModifyPartition wcm:action="add">
<Order>1</Order>
<PartitionID>1</PartitionID>
<Label>System</Label>
<Format>FAT32</Format>
</ModifyPartition>
<!-- MSR partition does not need to be modified -->
<ModifyPartition wcm:action="add">
<Order>2</Order>
<PartitionID>2</PartitionID>
</ModifyPartition>
<!-- Windows partition -->
<ModifyPartition wcm:action="add">
<Order>3</Order>
<PartitionID>3</PartitionID>
<Label>Windows</Label>
<Letter>C</Letter>
<Format>NTFS</Format>
</ModifyPartition>
</ModifyPartitions>
</Disk>
</DiskConfiguration>
<ImageInstall>
<OSImage>
<InstallFrom>
<MetaData wcm:action="add">
<Key>/IMAGE/NAME</Key>
<Value>Windows Server 2025 SERVERSTANDARD</Value>
</MetaData>
</InstallFrom>
<InstallTo>
<DiskID>0</DiskID>
<PartitionID>3</PartitionID>
</InstallTo>
<WillShowUI>OnError</WillShowUI>
<InstallToAvailablePartition>false</InstallToAvailablePartition>
</OSImage>
</ImageInstall>
<DynamicUpdate>
<Enable>true</Enable>
<WillShowUI>Never</WillShowUI>
</DynamicUpdate>
<UpgradeData>
<Upgrade>false</Upgrade>
<WillShowUI>Never</WillShowUI>
</UpgradeData>
<UserData>
<AcceptEula>true</AcceptEula>
<FullName>Docker</FullName>
<Organization>Windows for Docker</Organization>
<ProductKey />
</UserData>
<EnableFirewall>false</EnableFirewall>
<Diagnostics>
<OptIn>false</OptIn>
</Diagnostics>
</component>
<component name="Microsoft-Windows-PnpCustomizationsWinPE" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DriverPaths>
<PathAndCredentials wcm:action="add" wcm:keyValue="1">
<Path>D:\viostor\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="2">
<Path>D:\NetKVM\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="3">
<Path>D:\Balloon\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="4">
<Path>D:\pvpanic\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="5">
<Path>D:\qemupciserial\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="6">
<Path>D:\qxldod\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="7">
<Path>D:\vioinput\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="8">
<Path>D:\viorng\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="9">
<Path>D:\vioscsi\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="10">
<Path>D:\vioserial\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="11">
<Path>D:\viogpudo\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="12">
<Path>D:\sriov\2k22\amd64</Path>
</PathAndCredentials>
<PathAndCredentials wcm:action="add" wcm:keyValue="13">
<Path>D:\viofs\2k22\amd64</Path>
</PathAndCredentials>
</DriverPaths>
</component>
</settings>
<settings pass="offlineServicing">
<component name="Microsoft-Windows-LUA-Settings" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<EnableLUA>false</EnableLUA>
</component>
</settings>
<settings pass="generalize">
<component name="Microsoft-Windows-PnPSysprep" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<PersistAllDeviceInstalls>true</PersistAllDeviceInstalls>
</component>
<component name="Microsoft-Windows-Security-SPP" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SkipRearm>1</SkipRearm>
</component>
</settings>
<settings pass="specialize">
<component name="Microsoft-Windows-Security-SPP-UX" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<SkipAutoActivation>true</SkipAutoActivation>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<ComputerName>*</ComputerName>
<OEMInformation>
<Manufacturer>Dockur</Manufacturer>
<Model>Windows for Docker</Model>
<SupportHours>24/7</SupportHours>
<SupportPhone />
<SupportProvider>Dockur</SupportProvider>
<SupportURL>https://github.com/dockur/windows/issues</SupportURL>
</OEMInformation>
<OEMName>Windows for Docker</OEMName>
</component>
<component name="Microsoft-Windows-ErrorReportingCore" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DisableWER>1</DisableWER>
</component>
<component name="Microsoft-Windows-IE-InternetExplorer" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DisableAccelerators>true</DisableAccelerators>
<DisableFirstRunWizard>true</DisableFirstRunWizard>
<Home_Page>https://google.com</Home_Page>
<Help_Page>about:blank</Help_Page>
</component>
<component name="Microsoft-Windows-IE-InternetExplorer" processorArchitecture="wow64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DisableAccelerators>true</DisableAccelerators>
<DisableFirstRunWizard>true</DisableFirstRunWizard>
<Home_Page>https://google.com</Home_Page>
<Help_Page>about:blank</Help_Page>
</component>
<component name="Microsoft-Windows-SQMApi" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<CEIPEnabled>0</CEIPEnabled>
</component>
<component name="Microsoft-Windows-SystemRestore-Main" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DisableSR>1</DisableSR>
</component>
<component name="Microsoft-Windows-International-Core" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<InputLocale>0409:00000409</InputLocale>
<SystemLocale>en-US</SystemLocale>
<UILanguage>en-US</UILanguage>
<UILanguageFallback>en-US</UILanguageFallback>
<UserLocale>en-US</UserLocale>
</component>
<component name="Microsoft-Windows-ServerManager-SvrMgrNc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DoNotOpenServerManagerAtLogon>true</DoNotOpenServerManagerAtLogon>
</component>
<component name="Microsoft-Windows-OutOfBoxExperience" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<DoNotOpenInitialConfigurationTasksAtLogon>true</DoNotOpenInitialConfigurationTasksAtLogon>
</component>
<component name="Microsoft-Windows-TerminalServices-LocalSessionManager" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<fDenyTSConnections>false</fDenyTSConnections>
</component>
<component name="Microsoft-Windows-TerminalServices-RDP-WinStationExtensions" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<UserAuthentication>0</UserAuthentication>
</component>
<component name="Networking-MPSSVC-Svc" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<FirewallGroups>
<FirewallGroup wcm:action="add" wcm:keyValue="RemoteDesktop">
<Active>true</Active>
<Group>Remote Desktop</Group>
<Profile>all</Profile>
</FirewallGroup>
</FirewallGroups>
</component>
</settings>
<settings pass="oobeSystem">
<component name="Microsoft-Windows-SecureStartup-FilterDriver" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<PreventDeviceEncryption>true</PreventDeviceEncryption>
</component>
<component name="Microsoft-Windows-EnhancedStorage-Adm" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<TCGSecurityActivationDisabled>1</TCGSecurityActivationDisabled>
</component>
<component name="Microsoft-Windows-Shell-Setup" processorArchitecture="amd64" publicKeyToken="31bf3856ad364e35" language="neutral" versionScope="nonSxS">
<UserAccounts>
<LocalAccounts>
<LocalAccount wcm:action="add">
<Name>Docker</Name>
<Group>Administrators</Group>
<Password>
<Value />
<PlainText>true</PlainText>
</Password>
</LocalAccount>
</LocalAccounts>
<AdministratorPassword>
<Value>password</Value>
<PlainText>true</PlainText>
</AdministratorPassword>
</UserAccounts>
<AutoLogon>
<Username>Docker</Username>
<Enabled>true</Enabled>
<LogonCount>1</LogonCount>
<Password>
<Value />
<PlainText>true</PlainText>
</Password>
</AutoLogon>
<OOBE>
<HideEULAPage>true</HideEULAPage>
<HideLocalAccountScreen>true</HideLocalAccountScreen>
<HideOEMRegistrationScreen>true</HideOEMRegistrationScreen>
<HideOnlineAccountScreens>true</HideOnlineAccountScreens>
<HideWirelessSetupInOOBE>true</HideWirelessSetupInOOBE>
<NetworkLocation>Other</NetworkLocation>
<ProtectYourPC>3</ProtectYourPC>
<SkipUserOOBE>true</SkipUserOOBE>
<SkipMachineOOBE>true</SkipMachineOOBE>
</OOBE>
<RegisteredOrganization>Dockur</RegisteredOrganization>
<RegisteredOwner>Windows for Docker</RegisteredOwner>
<FirstLogonCommands>
<SynchronousCommand wcm:action="add">
<Order>1</Order>
<CommandLine>reg.exe add "HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon" /v AutoLogonCount /t REG_DWORD /d 0 /f</CommandLine>
<Description>Set AutoLogonCount to 0</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>2</Order>
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Lsa" /v LimitBlankPasswordUse /t REG_DWORD /d 0 /f</CommandLine>
<Description>Allow RDP login with blank password</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>3</Order>
<CommandLine>cmd /C wmic useraccount where name="Docker" set PasswordExpires=false</CommandLine>
<Description>Password Never Expires</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>4</Order>
<CommandLine>cmd /C POWERCFG -H OFF</CommandLine>
<Description>Disable Hibernation</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>5</Order>
<CommandLine>cmd /C POWERCFG -X -monitor-timeout-ac 0</CommandLine>
<Description>Disable monitor blanking</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>6</Order>
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Network\NewNetworkWindowOff" /f</CommandLine>
<Description>Disable Network Discovery popup</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>7</Order>
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Network\NetworkLocationWizard" /v "HideWizard" /t REG_DWORD /d 1 /f</CommandLine>
<Description>Disable Network Discovery popup</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>8</Order>
<CommandLine>reg.exe add "HKLM\SOFTWARE\Policies\Microsoft\Edge" /v "HideFirstRunExperience" /t REG_DWORD /d 1 /f</CommandLine>
<Description>Disable first-run experience in Edge</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>9</Order>
<CommandLine>reg.exe add "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\Advanced" /v "HideFileExt" /t REG_DWORD /d 0 /f</CommandLine>
<Description>Show file extensions in Explorer</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>10</Order>
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Power" /v "HibernateFileSizePercent" /t REG_DWORD /d 0 /f</CommandLine>
<Description>Zero Hibernation File</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>11</Order>
<CommandLine>reg.exe add "HKLM\SYSTEM\CurrentControlSet\Control\Power" /v "HibernateEnabled" /t REG_DWORD /d 0 /f</CommandLine>
<Description>Disable Hibernation Mode</Description>
</SynchronousCommand>
<SynchronousCommand wcm:action="add">
<Order>12</Order>
<CommandLine>msiexec /i E:\virtio-win-gt-x64.msi /qb!</CommandLine>
<Description>Install VirtIO drivers</Description>
</SynchronousCommand>
</FirstLogonCommands>
</component>
</settings>
</unattend>

View File

@@ -63,7 +63,7 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
* ### How do I select the Windows version? * ### How do I select the Windows version?
By default, Windows 11 will be installed. But you can add the `VERSION` environment variable to your compose file, in order to specify an alternative Windows version to download: By default, Windows 11 will be installed. But you can add the `VERSION` environment variable to your compose file, in order to specify an alternative Windows version to be downloaded:
```yaml ```yaml
environment: environment:
@@ -72,24 +72,25 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
Select from the values below: Select from the values below:
| **Value** | **Description** | **Server** | **Transfer** | **Size** | | **Value** | **Description** | **Source** | **Transfer** | **Size** |
|---|---|---|---|---| |---|---|---|---|---|
| `win11` | Windows 11 Pro | Microsoft | Fast | 6.4 GB | | `win11` | Windows 11 Pro | Microsoft | Fast | 6.4 GB |
| `win10` | Windows 10 Pro | Microsoft | Fast | 5.8 GB | | `win10` | Windows 10 Pro | Microsoft | Fast | 5.8 GB |
| `ltsc10` | Windows 10 LTSC | Microsoft | Fast | 4.6 GB | | `ltsc10` | Windows 10 LTSC | Microsoft | Fast | 4.6 GB |
| `win81` | Windows 8.1 Pro | Microsoft | Fast | 4.2 GB | | `win81` | Windows 8.1 Pro | Microsoft | Fast | 4.2 GB |
| `win7` | Windows 7 SP1 | Bob Pony | Medium | 3.0 GB | | `win7` | Windows 7 SP1 | Bob Pony | Medium | 3.0 GB |
| `vista` | Windows Vista SP2 | Bob Pony | Medium | 3.6 GB | | `vista` | Windows Vista SP2 | Bob Pony | Medium | 3.6 GB |
| `winxp` | Windows XP SP3 | Bob Pony | Medium | 0.6 GB |
|||||| ||||||
| `2022` | Windows Server 2022 | Microsoft | Fast | 4.7 GB | | `2022` | Windows Server 2022 | Microsoft | Fast | 4.7 GB |
| `2019` | Windows Server 2019 | Microsoft | Fast | 5.3 GB | | `2019` | Windows Server 2019 | Microsoft | Fast | 5.3 GB |
| `2016` | Windows Server 2016 | Microsoft | Fast | 6.5 GB | | `2016` | Windows Server 2016 | Microsoft | Fast | 6.5 GB |
| `2012` | Windows Server 2012 R2| Microsoft | Fast | 4.3 GB | | `2012` | Windows Server 2012 R2 | Microsoft | Fast | 4.3 GB |
| `2008` | Windows Server 2008 R2 | Microsoft | Fast | 3.0 GB | | `2008` | Windows Server 2008 R2 | Microsoft | Fast | 3.0 GB |
|||||| ||||||
| `core11` | Tiny 11 Core | Archive.org | Slow | 2.1 GB | | `core11` | Tiny 11 Core | Archive.org | Slow | 2.1 GB |
| `tiny11` | Tiny 11 | Archive.org | Slow | 3.8 GB | | `tiny11` | Tiny 11 | Archive.org | Slow | 3.8 GB |
| `tiny10` | Tiny 10 | Archive.org | Slow | 3.6 GB | | `tiny10` | Tiny 10 | Archive.org | Slow | 3.6 GB |
* ### How do I increase the amount of CPU or RAM? * ### How do I increase the amount of CPU or RAM?
@@ -165,6 +166,57 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
Alternatively, you can also rename a local file to `custom.iso` and place it in an empty `/storage` folder to skip the download. Alternatively, you can also rename a local file to `custom.iso` and place it in an empty `/storage` folder to skip the download.
* ### How do I assign an individual IP address to the container?
By default, the container uses bridge networking, which shares the IP address with the host.
If you want to assign an individual IP address to the container, you can create a macvlan network as follows:
```bash
docker network create -d macvlan \
--subnet=192.168.0.0/24 \
--gateway=192.168.0.1 \
--ip-range=192.168.0.100/28 \
-o parent=eth0 vlan
```
Be sure to modify these values to match your local subnet.
Once you have created the network, change your compose file to look as follows:
```yaml
services:
windows:
container_name: windows
..<snip>..
networks:
vlan:
ipv4_address: 192.168.0.100
networks:
vlan:
external: true
```
An added benefit of this approach is that you won't have to perform any port mapping anymore, since all ports will be exposed by default.
Please note that this IP address won't be accessible from the Docker host due to the design of macvlan, which doesn't permit communication between the two. If this is a concern, you need to create a [second macvlan](https://blog.oddbit.com/post/2018-03-12-using-docker-macvlan-networks/#host-access) as a workaround.
* ### How can Windows acquire an IP address from my router?
After configuring the container for macvlan (see above), it is possible for Windows to become part of your home network by requesting an IP from your router, just like a real PC.
To enable this mode, add the following lines to your compose file:
```yaml
environment:
DHCP: "Y"
device_cgroup_rules:
- 'c *:* rwm'
```
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:
@@ -179,6 +231,17 @@ docker run -it --rm -p 8006:8006 --device=/dev/kvm --cap-add NET_ADMIN --stop-ti
``` ```
Use `DEVICE` if you want it to become your main drive, and use `DEVICE2` and higher to add them as secondary drives. Use `DEVICE` if you want it to become your main drive, and use `DEVICE2` and higher to add them as secondary drives.
* ### How do I pass-through a USB device?
To pass-through a USB device, first lookup its vendor and product id via the `lsusb` command, then add them to your compose file like this:
```yaml
environment:
ARGUMENTS: "-device usb-host,vendorid=0x1234,productid=0x1234"
devices:
- /dev/bus/usb
```
* ### How do I verify if my system supports KVM? * ### How do I verify if my system supports KVM?

View File

@@ -27,6 +27,9 @@ fi
[[ "${VERSION,,}" == "vista" ]] && VERSION="winvistax64" [[ "${VERSION,,}" == "vista" ]] && VERSION="winvistax64"
[[ "${VERSION,,}" == "winvista" ]] && VERSION="winvistax64" [[ "${VERSION,,}" == "winvista" ]] && VERSION="winvistax64"
[[ "${VERSION,,}" == "xp" ]] && VERSION="winxpx86"
[[ "${VERSION,,}" == "winxp" ]] && VERSION="winxpx86"
[[ "${VERSION,,}" == "22" ]] && VERSION="win2022-eval" [[ "${VERSION,,}" == "22" ]] && VERSION="win2022-eval"
[[ "${VERSION,,}" == "2022" ]] && VERSION="win2022-eval" [[ "${VERSION,,}" == "2022" ]] && VERSION="win2022-eval"
[[ "${VERSION,,}" == "win22" ]] && VERSION="win2022-eval" [[ "${VERSION,,}" == "win22" ]] && VERSION="win2022-eval"
@@ -67,6 +70,11 @@ if [[ "${VERSION,,}" == "winvistax64" ]]; then
VERSION="https://dl.bobpony.com/windows/vista/en_windows_vista_sp2_x64_dvd_342267.iso" VERSION="https://dl.bobpony.com/windows/vista/en_windows_vista_sp2_x64_dvd_342267.iso"
fi fi
if [[ "${VERSION,,}" == "winxpx86" ]]; then
DETECTED="winxpx86"
VERSION="https://dl.bobpony.com/windows/xp/professional/en_windows_xp_professional_with_service_pack_3_x86_cd_vl_x14-73974.iso"
fi
if [[ "${VERSION,,}" == "core11" ]]; then if [[ "${VERSION,,}" == "core11" ]]; then
DETECTED="win11x64" DETECTED="win11x64"
VERSION="https://archive.org/download/tiny-11-core-x-64-beta-1/tiny11%20core%20x64%20beta%201.iso" VERSION="https://archive.org/download/tiny-11-core-x-64-beta-1/tiny11%20core%20x64%20beta%201.iso"
@@ -92,6 +100,7 @@ CUSTOM="custom.iso"
[ ! -f "$STORAGE/$CUSTOM" ] && CUSTOM="custom.IMG" [ ! -f "$STORAGE/$CUSTOM" ] && CUSTOM="custom.IMG"
[ ! -f "$STORAGE/$CUSTOM" ] && CUSTOM="CUSTOM.IMG" [ ! -f "$STORAGE/$CUSTOM" ] && CUSTOM="CUSTOM.IMG"
MACHINE="q35"
TMP="$STORAGE/tmp" TMP="$STORAGE/tmp"
DIR="$TMP/unpack" DIR="$TMP/unpack"
FB="falling back to manual installation!" FB="falling back to manual installation!"
@@ -107,6 +116,7 @@ printVersion() {
[[ "$id" == "win8"* ]] && desc="Windows 8" [[ "$id" == "win8"* ]] && desc="Windows 8"
[[ "$id" == "win10"* ]] && desc="Windows 10" [[ "$id" == "win10"* ]] && desc="Windows 10"
[[ "$id" == "win11"* ]] && desc="Windows 11" [[ "$id" == "win11"* ]] && desc="Windows 11"
[[ "$id" == "winxp"* ]] && desc="Windows XP"
[[ "$id" == "winvista"* ]] && desc="Windows Vista" [[ "$id" == "winvista"* ]] && desc="Windows Vista"
[[ "$id" == "win2025"* ]] && desc="Windows Server 2025" [[ "$id" == "win2025"* ]] && desc="Windows Server 2025"
[[ "$id" == "win2022"* ]] && desc="Windows Server 2022" [[ "$id" == "win2022"* ]] && desc="Windows Server 2022"
@@ -250,7 +260,7 @@ finishInstall() {
cp /run/version "$STORAGE/windows.ver" cp /run/version "$STORAGE/windows.ver"
if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then if [[ "${BOOT_MODE,,}" == "windows_legacy" ]]; then
touch "$STORAGE/windows.old" echo "$MACHINE" > "$STORAGE/windows.old"
else else
rm -f "$STORAGE/windows.old" rm -f "$STORAGE/windows.old"
fi fi
@@ -448,6 +458,7 @@ extractImage() {
detectImage() { detectImage() {
XML="" XML=""
local dir="$1"
if [ -n "$CUSTOM" ]; then if [ -n "$CUSTOM" ]; then
DETECTED="" DETECTED=""
@@ -464,22 +475,32 @@ detectImage() {
return 0 return 0
fi fi
local dsc if [[ "${DETECTED,,}" != "winxp"* ]]; then
dsc=$(printVersion "$DETECTED")
[ -z "$dsc" ] && dsc="$DETECTED" local dsc
dsc=$(printVersion "$DETECTED")
[ -z "$dsc" ] && dsc="$DETECTED"
warn "got $dsc, but no matching XML file exists, $FB."
fi
warn "got $dsc, but no matching XML file exists, $FB."
return 0 return 0
fi fi
info "Detecting Windows version from ISO image..." info "Detecting Windows version from ISO image..."
local dir="$1" if [ -f "$dir/WIN51" ] || [ -f "$dir/SETUPXP.HTM" ]; then
DETECTED="winxpx86"
info "Detected: Windows XP"
return 0
fi
local tag result name name2 desc local tag result name name2 desc
local loc="$dir/sources/install.wim" local loc="$dir/sources/install.wim"
[ ! -f "$loc" ] && loc="$dir/sources/install.esd" [ ! -f "$loc" ] && loc="$dir/sources/install.esd"
if [ ! -f "$loc" ]; then if [ ! -f "$loc" ]; then
warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB" warn "failed to locate 'install.wim' or 'install.esd' in ISO image, $FB"
BOOT_MODE="windows_legacy" BOOT_MODE="windows_legacy"
return 1 return 1
@@ -517,27 +538,137 @@ detectImage() {
return 0 return 0
} }
prepareImage() { prepareXP() {
local iso="$1" local iso="$1"
local dir="$2" local dir="$2"
local arch="x86"
local target="$dir/I386"
if [[ "${BOOT_MODE,,}" == "windows" ]] && [[ "${DETECTED,,}" != "win2008"* ]]; then if [ -d "$dir/AMD64" ]; then
if [[ "${DETECTED,,}" != "win7x64"* ]] && [[ "${DETECTED,,}" != "winvistax64"* ]]; then arch="amd64"
target="$dir/AMD64"
if [ -f "$dir/$ETFS" ] && [ -f "$dir/$EFISYS" ]; then
return 0
fi
if [ ! -f "$dir/$ETFS" ]; then
warn "failed to locate file 'etfsboot.com' in ISO image, falling back to legacy boot!"
else
warn "failed to locate file 'efisys_noprompt.bin' in ISO image, falling back to legacy boot!"
fi
fi
fi fi
MACHINE="pc-q35-2.10"
BOOT_MODE="windows_legacy"
ETFS="[BOOT]/Boot-NoEmul.img"
[[ "$MANUAL" == [Yy1]* ]] && return 0
local drivers="$TMP/drivers"
rm -rf "$drivers"
if ! 7z x /run/drivers.iso -o"$drivers" > /dev/null; then
error "Failed to extract driver ISO file!"
exit 66
fi
cp "$drivers/viostor/xp/$arch/viostor.sys" "$target"
mkdir -p "$dir/\$OEM\$/\$1/Drivers/viostor"
cp "$drivers/viostor/xp/$arch/viostor.cat" "$dir/\$OEM\$/\$1/Drivers/viostor"
cp "$drivers/viostor/xp/$arch/viostor.inf" "$dir/\$OEM\$/\$1/Drivers/viostor"
cp "$drivers/viostor/xp/$arch/viostor.sys" "$dir/\$OEM\$/\$1/Drivers/viostor"
mkdir -p "$dir/\$OEM\$/\$1/Drivers/NetKVM"
cp "$drivers/NetKVM/xp/$arch/netkvm.cat" "$dir/\$OEM\$/\$1/Drivers/NetKVM"
cp "$drivers/NetKVM/xp/$arch/netkvm.inf" "$dir/\$OEM\$/\$1/Drivers/NetKVM"
cp "$drivers/NetKVM/xp/$arch/netkvm.sys" "$dir/\$OEM\$/\$1/Drivers/NetKVM"
sed -i '/^\[SCSI.Load\]/s/$/\nviostor=viostor.sys,4/' "$target/TXTSETUP.SIF"
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\nviostor.sys=1,,,,,,4_,4,1,,,1,4/' "$target/TXTSETUP.SIF"
sed -i '/^\[SCSI\]/s/$/\nviostor=\"Red Hat VirtIO SCSI Disk Device\"/' "$target/TXTSETUP.SIF"
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_1AF4\&DEV_1001\&SUBSYS_00000000=\"viostor\"/' "$target/TXTSETUP.SIF"
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_1AF4\&DEV_1001\&SUBSYS_00020000=\"viostor\"/' "$target/TXTSETUP.SIF"
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_1AF4\&DEV_1001\&SUBSYS_00021AF4=\"viostor\"/' "$target/TXTSETUP.SIF"
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_1AF4\&DEV_1001\&SUBSYS_00000000=\"viostor\"/' "$target/TXTSETUP.SIF"
mkdir -p "$dir/\$OEM\$/\$1/Drivers/sata"
cp -a "$drivers/sata/xp/$arch/." "$dir/\$OEM\$/\$1/Drivers/sata"
cp -a "$drivers/sata/xp/$arch/." "$target"
sed -i '/^\[SCSI.Load\]/s/$/\niaStor=iaStor.sys,4/' "$target/TXTSETUP.SIF"
sed -i '/^\[FileFlags\]/s/$/\niaStor.sys = 16/' "$target/TXTSETUP.SIF"
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.cat = 1,,,,,,,1,0,0/' "$target/TXTSETUP.SIF"
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.inf = 1,,,,,,,1,0,0/' "$target/TXTSETUP.SIF"
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.sys = 1,,,,,,4_,4,1,,,1,4/' "$target/TXTSETUP.SIF"
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaStor.sys = 1,,,,,,,1,0,0/' "$target/TXTSETUP.SIF"
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaahci.cat = 1,,,,,,,1,0,0/' "$target/TXTSETUP.SIF"
sed -i '/^\[SourceDisksFiles.'"$arch"'\]/s/$/\niaAHCI.inf = 1,,,,,,,1,0,0/' "$target/TXTSETUP.SIF"
sed -i '/^\[SCSI\]/s/$/\niaStor=\"Intel\(R\) SATA RAID\/AHCI Controller\"/' "$target/TXTSETUP.SIF"
sed -i '/^\[HardwareIdsDatabase\]/s/$/\nPCI\\VEN_8086\&DEV_2922\&CC_0106=\"iaStor\"/' "$target/TXTSETUP.SIF"
rm -f "$target/winnt.sif"
rm -f "$target/Winnt.sif"
rm -f "$target/winnt.SIF"
rm -f "$target/WinNT.sif"
rm -f "$target/WINNT.sif"
rm -f "$target/WINNT.SIF"
local key="M6TF9-8XQ2M-YQK9F-7TBB2-XGG88"
[[ "${arch,,}" == "amd64" ]] && key="B66VY-4D94T-TPPD4-43F72-8X4FY"
local sif="$target/WINNT.SIF"
{ echo "[Data]"
echo "AutoPartition=1"
echo "MsDosInitiated=\"0\""
echo "UnattendedInstall=\"Yes\""
echo "AutomaticUpdates=\"Yes\""
echo ""
echo "[Unattended]"
echo "UnattendSwitch=Yes"
echo "UnattendMode=FullUnattended"
echo "FileSystem=NTFS"
echo "OemSkipEula=Yes"
echo "OemPreinstall=Yes"
echo "Repartition=Yes"
echo "WaitForReboot=\"No\""
echo "DriverSigningPolicy=\"Ignore\""
echo "NonDriverSigningPolicy=\"Ignore\""
echo "OemPnPDriversPath=\"Drivers\viostor;Drivers\NetKVM;Drivers\sata\""
echo "NoWaitAfterTextMode=1"
echo "NoWaitAfterGUIMode=1"
echo "FileSystem-ConvertNTFS"
echo "ExtendOemPartition=0"
echo "Hibernation=\"No\""
echo ""
echo "[GuiUnattended]"
echo "OEMSkipRegional=1"
echo "OemSkipWelcome=1"
echo "AdminPassword=*"
echo "TimeZone=0"
echo "AutoLogon=Yes"
echo "AutoLogonCount=99999"
echo ""
echo "[UserData]"
echo "FullName=\"Docker\""
echo "ComputerName=\"*\""
echo "OrgName=\"Windows for Docker\""
echo "ProductKey=$key"
echo ""
echo "[Identification]"
echo "JoinWorkgroup"
echo ""
echo "[Networking]"
echo "InstallDefaultComponents=Yes"
echo ""
echo "[RegionalSettings]"
echo "Language=00000409"
echo ""
echo "[TerminalServices]"
echo "AllowConnections=1"
} > "$sif"
return 0
}
prepareLegacy() {
local iso="$1"
local dir="$2"
ETFS="boot.img" ETFS="boot.img"
BOOT_MODE="windows_legacy" BOOT_MODE="windows_legacy"
@@ -553,6 +684,44 @@ prepareImage() {
return 0 return 0
} }
prepareImage() {
local iso="$1"
local dir="$2"
if [[ "${BOOT_MODE,,}" == "windows" ]]; then
if [[ "${DETECTED,,}" != "winxp"* ]] && [[ "${DETECTED,,}" != "win2008"* ]]; then
if [[ "${DETECTED,,}" != "winvista"* ]] && [[ "${DETECTED,,}" != "win7"* ]]; then
if [ -f "$dir/$ETFS" ] && [ -f "$dir/$EFISYS" ]; then
return 0
fi
if [ ! -f "$dir/$ETFS" ]; then
warn "failed to locate file 'etfsboot.com' in ISO image, falling back to legacy boot!"
else
warn "failed to locate file 'efisys_noprompt.bin' in ISO image, falling back to legacy boot!"
fi
fi
fi
fi
if [[ "${DETECTED,,}" == "winxp"* ]]; then
if ! prepareXP "$iso" "$dir"; then
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 iso="$1"
@@ -627,12 +796,23 @@ buildImage() {
else else
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 [[ "${DETECTED,,}" != "winxp"* ]]; then
-udf -allow-limited-size -quiet "$dir" 2> "$log"; then
[ -f "$log" ] && echo "$(<"$log")"
return 1
fi
if ! genisoimage -o "$out" -b "$ETFS" -no-emul-boot -c "$cat" -iso-level 2 -J -l -D -N -joliet-long -relaxed-filenames -V "$label" \
-udf -allow-limited-size -quiet "$dir" 2> "$log"; then
[ -f "$log" ] && echo "$(<"$log")"
return 1
fi
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 \
-relaxed-filenames -V "$label" -quiet "$dir" 2> "$log"; then
[ -f "$log" ] && echo "$(<"$log")"
return 1
fi
fi
fi fi
local error="" local error=""
@@ -655,6 +835,8 @@ buildImage() {
if ! startInstall; then if ! startInstall; then
if [ -f "$STORAGE/windows.old" ]; then if [ -f "$STORAGE/windows.old" ]; then
MACHINE=$(<"$STORAGE/windows.old")
[ -z "$MACHINE" ] && MACHINE="q35"
BOOT_MODE="windows_legacy" BOOT_MODE="windows_legacy"
fi fi

View File

@@ -374,13 +374,13 @@ consumer_download() {
if ! [ "$iso_download_link_html" ]; then if ! [ "$iso_download_link_html" ]; then
# This should only happen if there's been some change to how this API works # This should only happen if there's been some change to how this API works
echo_err "Microsoft servers gave us an empty response to our request for an automated download. Please manually download this ISO in a web browser: $url" echo_err "Microsoft servers gave us an empty response to our request for an automated download. Please check the FAQ on how to boot from a local file and manually download this ISO in a web browser: $url"
manual_verification="true" manual_verification="true"
return 1 return 1
fi fi
if echo "$iso_download_link_html" | grep -q "We are unable to complete your request at this time."; then if echo "$iso_download_link_html" | grep -q "We are unable to complete your request at this time."; then
echo_err "Microsoft blocked the automated download request based on your IP address. Please manually download this ISO in a web browser here: $url" echo_err "Microsoft blocked the automated download request based on your IP address. Please check the FAQ on how to boot from a local file and manually download this ISO in a web browser here: $url"
manual_verification="true" manual_verification="true"
return 1 return 1
fi fi
@@ -392,7 +392,7 @@ consumer_download() {
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
echo_err "Microsoft servers gave us no download link to our request for an automated download. Please manually download this ISO in a web browser: $url" echo_err "Microsoft servers gave us no download link to our request for an automated download. Please check the FAQ on how to boot from a local file and manually download this ISO in a web browser: $url"
manual_verification="true" manual_verification="true"
return 1 return 1
fi fi