Hi,
I am trying to create a windows installer that has the virtio drivers builtin, for fully automatic and unattended installation.
In particular I am trying to inject the driver vioscsi into boot.wim and then install.wim
I can unpack and repack the iso.
I can inject actual driver files into the wim files
I think all that is left is to create the registery keys in the registery hive files,
The keys that need to be created, if I had a "reg add" command
But I would like to create cleaner, more reusable shell function for adding each node/key/values
Here is an untested attempt of ths reg_add shellfunction
So we might then have a single shell function to just add vioscsi to a specified hive
I have created a shell function which can inject drivers files to all "image indexes" in the wim file
Shell function not fully tested
then I repack the iso
create_windows_iso /mnt/iso/template/win10-repack/iso-master /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64_unattended-2025-1-10.iso
shell function not fully tested
And now putting it all together
I am trying to create a windows installer that has the virtio drivers builtin, for fully automatic and unattended installation.
In particular I am trying to inject the driver vioscsi into boot.wim and then install.wim
I can unpack and repack the iso.
I can inject actual driver files into the wim files
I think all that is left is to create the registery keys in the registery hive files,
The keys that need to be created, if I had a "reg add" command
Code:
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v Start /t REG_DWORD /d 0 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v Type /t REG_DWORD /d 1 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v ErrorControl /t REG_DWORD /d 1 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v ImagePath /t REG_EXPAND_SZ /d System32\drivers\vioscsi.sys /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi" /v LoadOrderGroup /t REG_SZ /d "SCSI miniport" /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi" /v EventMessageFile /t REG_EXPAND_SZ /d %SystemRoot%\System32\IoLogMsg.dll /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi" /v TypesSupported /t REG_DWORD /d 7 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters" /v BusType /t REG_DWORD /d 10 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\PnpInterface" /v 5 /t REG_DWORD /d 1 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties" /v MSISupported /t REG_DWORD /d 1 /f
REG ADD "HKLM\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties" /v MessageNumberLimit /t REG_DWORD /d 258 /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys" /v Class /t REG_DWORD /d 5 /f
### REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys" /v Owners /t REG_BINARY /d <hex_value_of_inf_file> /f
REG ADD "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys" /v Source /t REG_EXPAND_SZ /d %SystemRoot%\System32\DriverStore\FileRepository\vioscsi.inf_amd64 /f
REG ADD "HKLM\SYSTEM\DriverDatabase" /v OemInfMap /t REG_BINARY /d e0 /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004" /v vioscsi.inf /t REG_BINARY /d 02FF0000 /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048" /v vioscsi.inf /t REG_BINARY /d 02FF0000 /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Catalog /t REG_SZ /d vioscsi.cat /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v InfName /t REG_SZ /d vioscsi.inf /f
### REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v OemPath /t REG_SZ /d C:\Users\<username>\Downloads\drivers /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Provider /t REG_SZ /d "Red Hat, Inc." /f
###REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v SignerName /t REG_SZ /d "<signature_info>" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v SignerScore /t REG_DWORD /d 218103812 /f
###REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Version /t REG_BINARY /d <binary_version_data> /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Class /t REG_SZ /d "SCSIAdapter" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v ClassGUID /t REG_SZ /d "{4D36E97B-E325-11CE-BFC1-08002BE10318}" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v DriverVer /t REG_SZ /d "07/15/2024,100.95.104.26200" /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06" /v Provider /t REG_SZ /d "Red Hat, Inc." /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00" /v vioscsi.inf /t REG_BINARY /d 01FF0000 /f
REG ADD "HKLM\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048&SUBSYS_11001AF4&REV_01" /v vioscsi.inf /t REG_BINARY /d 01FF0000 /f
But I would like to create cleaner, more reusable shell function for adding each node/key/values
Here is an untested attempt of ths reg_add shellfunction
Code:
reg_add() {
local hive_file="$1"
local registry_path="$2"
local value_name="$3"
local value_type="$4"
local value_data="$5"
if [[ -z "$hive_file" || -z "$registry_path" || -z "$value_name" || -z "$value_type" || -z "$value_data" ]]; then
echo "Usage: reg_add /path/to/hive/file \"[registry_path]\" value_name value_type value_data"
return 1
fi
# Convert the registry path for hivexsh
local hive_path
hive_path=$(echo "$registry_path" | sed -e 's/^\[//' -e 's/\]$//' -e 's|\\|/|g')
# Run hivexsh commands
hivexsh -w "$hive_file" <<EOF
cd $hive_path
setval 1
$value_name
$value_type:$value_data
commit
exit
EOF
if [[ $? -eq 0 ]]; then
echo "Successfully added \"$value_name\" to \"$registry_path\" in \"$hive_file\"."
else
echo "Failed to add \"$value_name\" to \"$registry_path\" in \"$hive_file\"."
return 1
fi
}
So we might then have a single shell function to just add vioscsi to a specified hive
Code:
#!/bin/bash
# Function to add vioscsi-related registry entries to a hive file
add_vioscsi_to_hive() {
local hive_file="$1"
if [[ -z "$hive_file" ]]; then
echo "Usage: add_vioscsi_to_hive /path/to/hive"
return 1
fi
if [[ ! -f "$hive_file" ]]; then
echo "Hive file '$hive_file' not found."
return 1
fi
echo "Adding vioscsi keys to hive: $hive_file"
# SYSTEM\CurrentControlSet\Services\vioscsi
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" Start dword "00000000"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" Type dword "00000001"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" ErrorControl dword "00000001"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" ImagePath hex(2) "53,79,73,74,65,6d,33,32,5c,64,72,69,76,65,72,73,5c,76,69,6f,73,63,73,69,2e,73,79,73"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi]" LoadOrderGroup string "SCSI miniport"
# SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi]" EventMessageFile hex(2) "25,53,79,73,74,65,6d,52,6f,6f,74,25,5c,53,79,73,74,65,6d,33,32,5c,49,6f,4c,6f,67,4d,73,67,2e,64,6c,6c"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\EventLog\System\vioscsi]" TypesSupported dword "00000007"
# SYSTEM\CurrentControlSet\Services\vioscsi\Parameters
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters]" BusType dword "0000000A"
# SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\PnpInterface
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\PnpInterface]" 5 dword "00000001"
# SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties]" MSISupported dword "00000001"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\vioscsi\Parameters\Interrupt Management\MessageSignaledInterruptProperties]" MessageNumberLimit dword "00000102"
# SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys]" Class dword "00000005"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Setup\PnpLockdownFiles\%SystemRoot%/System32/drivers/vioscsi.sys]" Source hex(2) "25,53,79,73,74,65,6d,52,6f,6f,74,25,5c,53,79,73,74,65,6d,33,32,5c,44,72,69,76,65,72,53,74,6f,72,65,5c,46,69,6c,65,52,65,70,6f,73,69,74,6f,72,79,5c,76,69,6f,73,63,73,69,2e,69,6e,66,5f,61,6d,64,36,34"
# SYSTEM\DriverDatabase
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase]" OemInfMap hex "e0"
# SYSTEM\DriverDatabase\DeviceIds
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004]" vioscsi.inf hex "02FF0000"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048]" vioscsi.inf hex "02FF0000"
# SYSTEM\DriverDatabase\DriverPackages
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" Catalog string "vioscsi.cat"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" InfName string "vioscsi.inf"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" Provider string "Red Hat, Inc."
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" SignerScore dword "0D000004"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" Class string "SCSIAdapter"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" ClassGUID string "{4D36E97B-E325-11CE-BFC1-08002BE10318}"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DriverPackages\vioscsi.inf_amd64_78d23e29bdcf3e06]" DriverVer string "07/15/2024,100.95.104.26200"
# SYSTEM\DriverDatabase\DeviceIds\PCI with SUBSYS
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1004&SUBSYS_00081AF4&REV_00]" vioscsi.inf hex "01FF0000"
reg_add "$hive_file" "[HKEY_LOCAL_MACHINE\SYSTEM\DriverDatabase\DeviceIds\PCI\VEN_1AF4&DEV_1048&SUBSYS_11001AF4&REV_01]" vioscsi.inf hex "01FF0000"
echo "Finished adding vioscsi keys to hive: $hive_file"
}
I have created a shell function which can inject drivers files to all "image indexes" in the wim file
Code:
inject_filesandfolders_to_all_wim_images iso-master/sources/boot.wim \
virtio-unzipped/vioscsi/w10/amd64/vioscsi.cat /windows/inf \
virtio-unzipped/vioscsi/w10/amd64/vioscsi.inf /windows/inf \
virtio-unzipped/vioscsi/w10/amd64/vioscsi.sys /windows/system32/drivers
Shell function not fully tested
Code:
inject_filesandfolders_to_all_wim_images() { local wim_file="$1"; shift; local dest_folder="/"; local sources=(); for arg in "$@"; do [ -e "$arg" ] && sources+=("$arg") || { [ ${#sources[@]} -gt 0 ] && { dest_folder="$arg"; for source in "${sources[@]}"; do for i in $(seq 1 "$(wimlib-imagex info "$wim_file" | grep -i "Image Count" | awk '{print $NF}')"); do [ -d "$source" ] && echo "Injecting folder $source into image index $i at $dest_folder..." && wimlib-imagex update "$wim_file" $i --command="add $source $dest_folder" || [ -f "$source" ] && echo "Injecting file $source into image index $i at $dest_folder/$(basename "$source")..." && wimlib-imagex update "$wim_file" $i --command="add $source $dest_folder/$(basename "$source")"; done; done; sources=(); }; dest_folder="$arg"; }; done; [ ${#sources[@]} -gt 0 ] && { for source in "${sources[@]}"; do for i in $(seq 1 "$(wimlib-imagex info "$wim_file" | grep -i "Image Count" | awk '{print $NF}')"); do [ -d "$source" ] && echo "Injecting folder $source into image index $i at /..." && wimlib-imagex update "$wim_file" $i --command="add $source /" || [ -f "$source" ] && echo "Injecting file $source into image index $i at /$(basename "$source")..." && wimlib-imagex update "$wim_file" $i --command="add $source /$(basename "$source")"; done; done; }; }
then I repack the iso
create_windows_iso /mnt/iso/template/win10-repack/iso-master /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64_unattended-2025-1-10.iso
shell function not fully tested
Code:
create_windows_iso() { local src_folder="$1" out_iso="$2"; xorriso -as mkisofs -iso-level 3 -full-iso9660-filenames -volid "CCCOMA_X64FRE_EN-GB_DV9" -output "$out_iso" -eltorito-boot boot/etfsboot.com -eltorito-catalog boot/boot.cat -no-emul-boot -boot-load-size 8 -boot-info-table -eltorito-alt-boot -e efi/microsoft/boot/efisys.bin -no-emul-boot -boot-load-size 1 -isohybrid-gpt-basdat "$src_folder"; }
Code:
get_wim_image_count() { wimlib-imagex info "$1" | grep -i "Image Count" | awk '{print $NF}'; }
mount_wim_image() { local wim_file="$1" index="$2" mount_point="$3/$index"; [ -d "$mount_point" ] && [ "$(ls -A "$mount_point" 2>/dev/null)" ] && { echo "Error: Mount point $mount_point is not empty"; return 1; }; mkdir -p "$mount_point"; wimlib-imagex mount "$wim_file" "$index" "$mount_point" --rw; }
mount_wim_image() { local wim_file="$1" index="$2" mount_point="$3/$index"; [ -d "$mount_point" ] && [ "$(ls -A "$mount_point" 2>/dev/null)" ] && { echo "Error: Mount point $mount_point is not empty"; return 1; }; mkdir -p "$mount_point"; wimlib-imagex mount "$wim_file" "$index" "$mount_point" --rw; }
And now putting it all together
Code:
unpack_iso /mnt/iso/template/iso/virtio-win-0.1.262.iso /mnt/iso/template/win10-repack/virtio-unzipped
unpack_iso /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64.iso /mnt/iso/template/win10-repack/iso-master
inject_filesandfolders_to_all_wim_images iso-master/sources/boot.wim virtio-unzipped/vioscsi/w10/amd64/vioscsi.cat /windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.inf windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.sys /windows/system32/drivers
inject_filesandfolders_to_all_wim_images iso-master/sources/install.wim virtio-unzipped/vioscsi/w10/amd64/vioscsi.cat /windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.inf windows/inf virtio-unzipped/vioscsi/w10/amd64/vioscsi.sys /windows/system32/drivers
for i in $(seq 1 "$(get_wim_image_count iso-master/sources/boot.wim)"); do
mount_wim_image iso-master/sources/boot.wim $i /mnt/iso/template/win10-repack/wim-mounts/boot/
add_vioscsi_to_hive wim-mounts/boot/windows/System32/Config/SYSTEM
unmount_wim_image iso-master/sources/boot.wim $i /mnt/iso/template/win10-repack/wim-mounts/boot/
done
for i in $(seq 1 "$(get_wim_image_count iso-master/sources/install.wim)"); do
mount_wim_image iso-master/sources/install.wim $i /mnt/iso/template/win10-repack/wim-mounts/install/
add_vioscsi_to_hive wim-mounts/install/windows/System32/Config/SYSTEM
unmount_wim_image iso-master/sources/install.wim $i /mnt/iso/template/win10-repack/wim-mounts/install/
done
create_windows_iso /mnt/iso/template/win10-repack/iso-master /mnt/iso/template/iso/Win10_22H2_EnglishInternational_x64_unattended-2025-1-10.iso