TrueNAS 25.04-BETA.1 is Now Available!

I want to confirm you method works also for Windows 10.

I also created another method that installs all virtio drivers and registry the same way distrobuilder would do it, but on live system before migration.

Your method is easier, so I write mine just to have a backup.
And for everyone, this method is quite experimental.

GUIDE:

First I will simply write steps how to do it. Then I will explain step by step how I made it and what everything means. This is just for Win10 and Win11 but easily applied to other versions. It includes adding drivers and editing registry, so dangerous. Dont forget to snapshot first. Here we go:

  1. You need to download and extract this prepared zip which includes everything you will need and put it on your VM. In this guide I will assume its placed directly on C drive and I am using Windows.10. In different conditions modify your steps accordingly. virtio-drivers.zip - Google Drive

  2. Our actions will need the highest privileges so we use PsExec.exe to run Powershell as SYSTEM user which is the highest in Windows. First run Powershell as Administrator.
    image
    Next use command: C:\virtio-win10\PsExec.exe -i -s powershell.exe
    This opens another Powershell, this time as SYSTEM. You can check with whoami.


    Everything after this is done in the SYSTEM Powershell.

  3. Windows folder in our downloaded zip contains all needed virtio drivers placed in correct folder hierarchy. We just need to copy it to Windows folder on our VM. Use this command to copy (and overwrite if needed) all the files:
    Copy-Item -Path "C:\virtio-win10\Windows\*" -Destination "C:\Windows" -Recurse -Force

  4. Now we need to edit registry. First load missing hive with command:
    reg load HKEY_LOCAL_MACHINE\DRIVERS "C:\Windows\System32\config\DRIVERS"
    Next import three reg files:
    reg import "C:\virtio-win10\driversRegistry.reg"
    reg import "C:\virtio-win10\softwareRegistry.reg"
    reg import "C:\virtio-win10\systemRegistry.reg"
    Finally, unload DRIVERS hive:
    reg unload HKEY_LOCAL_MACHINE\DRIVERS

  5. Thats all. Shutdown the VM and try to migrate it to Fangtooth. This way all virtio drivers and registry entries should be installed the same way as if you used distrobuilder.

Extended explanation:

I will write here how I derived my solution so anyone can check or do it their own way.

When installing Windows on Incus you should repack it with Distrobuilder which does basically two things. Adds virtio drivers to specific folders in ISO and edits registry.
Lets start with driver files, thats easy.
Just have original Windows ISO and another that was repacked by distrobuilder. Inside are many files, but Distrobuilder edits BOOT.WIM (windows installer) and INSTALL.WIM (origin files for installed system).
I used PowerISO to extract INSTALL.WIM from both original and repacked ISO. Then I compared contents with WinMerge.
And I saw what exactly Distrobuilder added/edited.

The driver files are obvious and those three files in config folder are hives (Windows Registry).

Next we need to understand Distrobuilder source code.
Registry edits are controlled by templates like this one: distrobuilder/windows/driver_vioscsi.go at main · lxc/distrobuilder · GitHub
Majority of it is static, few variables are populated on runtime. I needed to find if anything changes depending on Windows version bering repacked.
Used variables: distrobuilder/windows/repack_util.go at eb79e943082325eda4b3b747ff33506bfd65ad9b · lxc/distrobuilder · GitHub

I found out all variables are either the same or defined by virtio driver files.
driverName is defined here: distrobuilder/windows/drivers.go at eb79e943082325eda4b3b747ff33506bfd65ad9b · lxc/distrobuilder · GitHub
classGuid is defined in virtio driver .inf file. Win11 and Win10 have the same for any particular virtio driver. I didnt check older Windows.
packageName is defined in template itself.
infFile is generated here: distrobuilder/windows/repack_util.go at eb79e943082325eda4b3b747ff33506bfd65ad9b · lxc/distrobuilder · GitHub

This part of code executes the command to edit the registry: distrobuilder/windows/repack_util.go at eb79e943082325eda4b3b747ff33506bfd65ad9b · lxc/distrobuilder · GitHub
You can see it uses hivexregedit.
But we only need to extract driversRegistry, systemRegistry and softwareRegistry variables that contain the final processed templates.
I just complied the source and added lines like this to save it to a file:
err = os.WriteFile("driversRegistry.txt", []byte(driversRegistry), 0644)

Ok, I again recompiled and ran it. I got three almost-reg files.
These files have keys like:
[\ControlSet001\Services\VirtRng] and then hivexregedit adds prefix like HKEY_LOCAL_MACHINE\\SYSTEM defined in command: distrobuilder/windows/repack_util.go at eb79e943082325eda4b3b747ff33506bfd65ad9b · lxc/distrobuilder · GitHub

We need to include this prefix in the file to have valid .reg files. That easy in Notepad++. Just find and replace every beginning of the key in particular file with the same prefix.

One this is done you have basically the same .reg files I included in the zip above. Just remember its not entirely deterministic and the keys get mixed on every build. It can be confusing when diffing to compare. The keys are the same but in different places in the file.

Thats basically it.

In summary. For virtio drivers I just put them in the same positions as Distrobuilder does inside the ISO. Just needs to be careful to use correct version of the drivers.
And for registry I saved the input of hivexregedit (processed template) and added prefixes into .reg files.

Special thanks to ChatGPT and Golang for being actually readable language.

3 Likes