[Libguestfs] [PATCH 3/3] v2v: windows: Use '*.inf' files to control how Windows drivers are installed.

Richard W.M. Jones rjones at redhat.com
Tue Nov 17 22:03:25 UTC 2015


Instead of trying to split and parse elements from virtio-win paths,
use the '*.inf' files supplied with the drivers to control how Windows
drivers are installed.

The following emails best explain how this works:

https://www.redhat.com/archives/libguestfs/2015-October/msg00352.html
https://www.redhat.com/archives/libguestfs/2015-November/msg00065.html

Currently the product variant (eg. client or server) is ignored.
---
 v2v/v2v_unit_tests.ml | 623 ++++++++------------------------------------------
 v2v/windows.ml        | 289 +++++++++++++----------
 v2v/windows.mli       |   2 +-
 3 files changed, 265 insertions(+), 649 deletions(-)

diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml
index 169eea9..5cc1f3e 100644
--- a/v2v/v2v_unit_tests.ml
+++ b/v2v/v2v_unit_tests.ml
@@ -225,7 +225,7 @@ let test_windows_inf_of_string ctx =
   assert_equal ~printer expected sections
 
 (* Test the code which matches [*.inf] files to Windows guests. *)
-let test_virtio_iso_path_matches_guest_os ctx =
+let test_virtio_inf_matches_guest_os ctx =
   (* Windows OSes fake inspection data. *)
   let make_win name major minor variant arch = {
     inspect_defaults with
@@ -262,591 +262,149 @@ let test_virtio_iso_path_matches_guest_os ctx =
   ] in
 
   let paths = [
-    (* Paths from the virtio-win 1.7.4 ISO. *)
-    "Balloon/2k12/amd64/WdfCoInstaller01011.dll", None;
-    "Balloon/2k12/amd64/balloon.cat", Some win2k12_64;
-    "Balloon/2k12/amd64/balloon.inf", Some win2k12_64;
-    "Balloon/2k12/amd64/balloon.pdb", Some win2k12_64;
-    "Balloon/2k12/amd64/balloon.sys", Some win2k12_64;
-    "Balloon/2k12/amd64/blnsvr.exe", None;
-    "Balloon/2k12/amd64/blnsvr.pdb", Some win2k12_64;
-    "Balloon/2k12R2/amd64/WdfCoInstaller01011.dll", None;
-    "Balloon/2k12R2/amd64/balloon.cat", Some win2k12r2_64;
-    "Balloon/2k12R2/amd64/balloon.inf", Some win2k12r2_64;
-    "Balloon/2k12R2/amd64/balloon.pdb", Some win2k12r2_64;
-    "Balloon/2k12R2/amd64/balloon.sys", Some win2k12r2_64;
-    "Balloon/2k12R2/amd64/blnsvr.exe", None;
-    "Balloon/2k12R2/amd64/blnsvr.pdb", Some win2k12r2_64;
-    "Balloon/2k3/amd64/WdfCoInstaller01009.dll", None;
-    "Balloon/2k3/amd64/balloon.cat", Some win2k3_64;
-    "Balloon/2k3/amd64/balloon.inf", Some win2k3_64;
-    "Balloon/2k3/amd64/balloon.pdb", Some win2k3_64;
-    "Balloon/2k3/amd64/balloon.sys", Some win2k3_64;
-    "Balloon/2k3/amd64/blnsvr.exe", None;
-    "Balloon/2k3/amd64/blnsvr.pdb", Some win2k3_64;
-    "Balloon/2k3/x86/WdfCoInstaller01009.dll", None;
-    "Balloon/2k3/x86/balloon.cat", Some win2k3_32;
-    "Balloon/2k3/x86/balloon.inf", Some win2k3_32;
-    "Balloon/2k3/x86/balloon.pdb", Some win2k3_32;
-    "Balloon/2k3/x86/balloon.sys", Some win2k3_32;
-    "Balloon/2k3/x86/blnsvr.exe", None;
-    "Balloon/2k3/x86/blnsvr.pdb", Some win2k3_32;
-    "Balloon/2k8/amd64/WdfCoInstaller01009.dll", None;
-    "Balloon/2k8/amd64/balloon.cat", Some win2k8_64;
-    "Balloon/2k8/amd64/balloon.inf", Some win2k8_64;
-    "Balloon/2k8/amd64/balloon.pdb", Some win2k8_64;
-    "Balloon/2k8/amd64/balloon.sys", Some win2k8_64;
-    "Balloon/2k8/amd64/blnsvr.exe", None;
-    "Balloon/2k8/amd64/blnsvr.pdb", Some win2k8_64;
-    "Balloon/2k8/x86/WdfCoInstaller01009.dll", None;
-    "Balloon/2k8/x86/balloon.cat", Some win2k8_32;
-    "Balloon/2k8/x86/balloon.inf", Some win2k8_32;
-    "Balloon/2k8/x86/balloon.pdb", Some win2k8_32;
-    "Balloon/2k8/x86/balloon.sys", Some win2k8_32;
-    "Balloon/2k8/x86/blnsvr.exe", None;
-    "Balloon/2k8/x86/blnsvr.pdb", Some win2k8_32;
-    "Balloon/2k8R2/amd64/WdfCoInstaller01009.dll", None;
-    "Balloon/2k8R2/amd64/balloon.cat", Some win2k8r2_64;
-    "Balloon/2k8R2/amd64/balloon.inf", Some win2k8r2_64;
-    "Balloon/2k8R2/amd64/balloon.pdb", Some win2k8r2_64;
-    "Balloon/2k8R2/amd64/balloon.sys", Some win2k8r2_64;
-    "Balloon/2k8R2/amd64/blnsvr.exe", None;
-    "Balloon/2k8R2/amd64/blnsvr.pdb", Some win2k8r2_64;
-    "Balloon/w7/amd64/WdfCoInstaller01009.dll", None;
-    "Balloon/w7/amd64/balloon.cat", Some win7_64;
-    "Balloon/w7/amd64/balloon.inf", Some win7_64;
-    "Balloon/w7/amd64/balloon.pdb", Some win7_64;
-    "Balloon/w7/amd64/balloon.sys", Some win7_64;
-    "Balloon/w7/amd64/blnsvr.exe", None;
-    "Balloon/w7/amd64/blnsvr.pdb", Some win7_64;
-    "Balloon/w7/x86/WdfCoInstaller01009.dll", None;
-    "Balloon/w7/x86/balloon.cat", Some win7_32;
-    "Balloon/w7/x86/balloon.inf", Some win7_32;
-    "Balloon/w7/x86/balloon.pdb", Some win7_32;
-    "Balloon/w7/x86/balloon.sys", Some win7_32;
-    "Balloon/w7/x86/blnsvr.exe", None;
-    "Balloon/w7/x86/blnsvr.pdb", Some win7_32;
-    "Balloon/w8.1/amd64/WdfCoInstaller01011.dll", None;
-    "Balloon/w8.1/amd64/balloon.cat", Some win8_1_64;
-    "Balloon/w8.1/amd64/balloon.inf", Some win8_1_64;
-    "Balloon/w8.1/amd64/balloon.pdb", Some win8_1_64;
-    "Balloon/w8.1/amd64/balloon.sys", Some win8_1_64;
-    "Balloon/w8.1/amd64/blnsvr.exe", None;
-    "Balloon/w8.1/amd64/blnsvr.pdb", Some win8_1_64;
-    "Balloon/w8.1/x86/WdfCoInstaller01011.dll", None;
-    "Balloon/w8.1/x86/balloon.cat", Some win8_1_32;
-    "Balloon/w8.1/x86/balloon.inf", Some win8_1_32;
-    "Balloon/w8.1/x86/balloon.pdb", Some win8_1_32;
-    "Balloon/w8.1/x86/balloon.sys", Some win8_1_32;
-    "Balloon/w8.1/x86/blnsvr.exe", None;
-    "Balloon/w8.1/x86/blnsvr.pdb", Some win8_1_32;
-    "Balloon/w8/amd64/WdfCoInstaller01011.dll", None;
-    "Balloon/w8/amd64/balloon.cat", Some win8_64;
-    "Balloon/w8/amd64/balloon.inf", Some win8_64;
-    "Balloon/w8/amd64/balloon.pdb", Some win8_64;
-    "Balloon/w8/amd64/balloon.sys", Some win8_64;
-    "Balloon/w8/amd64/blnsvr.exe", None;
-    "Balloon/w8/amd64/blnsvr.pdb", Some win8_64;
-    "Balloon/w8/x86/WdfCoInstaller01011.dll", None;
-    "Balloon/w8/x86/balloon.cat", Some win8_32;
-    "Balloon/w8/x86/balloon.inf", Some win8_32;
-    "Balloon/w8/x86/balloon.pdb", Some win8_32;
-    "Balloon/w8/x86/balloon.sys", Some win8_32;
-    "Balloon/w8/x86/blnsvr.exe", None;
-    "Balloon/w8/x86/blnsvr.pdb", Some win8_32;
-    "Balloon/xp/x86/WdfCoInstaller01009.dll", None;
-    "Balloon/xp/x86/balloon.cat", Some winxp_32;
-    "Balloon/xp/x86/balloon.inf", Some winxp_32;
-    "Balloon/xp/x86/balloon.pdb", Some winxp_32;
-    "Balloon/xp/x86/balloon.sys", Some winxp_32;
-    "Balloon/xp/x86/blnsvr.exe", None;
-    "Balloon/xp/x86/blnsvr.pdb", Some winxp_32;
-    "NetKVM/2k12/amd64/netkvm.cat", Some win2k12_64;
-    "NetKVM/2k12/amd64/netkvm.inf", Some win2k12_64;
-    "NetKVM/2k12/amd64/netkvm.pdb", Some win2k12_64;
-    "NetKVM/2k12/amd64/netkvm.sys", Some win2k12_64;
-    "NetKVM/2k12/amd64/netkvmco.dll", None;
-    "NetKVM/2k12/amd64/readme.doc", None;
-    "NetKVM/2k12R2/amd64/netkvm.cat", Some win2k12r2_64;
-    "NetKVM/2k12R2/amd64/netkvm.inf", Some win2k12r2_64;
-    "NetKVM/2k12R2/amd64/netkvm.pdb", Some win2k12r2_64;
-    "NetKVM/2k12R2/amd64/netkvm.sys", Some win2k12r2_64;
-    "NetKVM/2k12R2/amd64/netkvmco.dll", None;
-    "NetKVM/2k12R2/amd64/readme.doc", None;
-    "NetKVM/2k3/amd64/netkvm.cat", Some win2k3_64;
-    "NetKVM/2k3/amd64/netkvm.inf", Some win2k3_64;
-    "NetKVM/2k3/amd64/netkvm.pdb", Some win2k3_64;
-    "NetKVM/2k3/amd64/netkvm.sys", Some win2k3_64;
-    "NetKVM/2k3/x86/netkvm.cat", Some win2k3_32;
-    "NetKVM/2k3/x86/netkvm.inf", Some win2k3_32;
-    "NetKVM/2k3/x86/netkvm.pdb", Some win2k3_32;
-    "NetKVM/2k3/x86/netkvm.sys", Some win2k3_32;
-    "NetKVM/2k8/amd64/netkvm.cat", Some win2k8_64;
-    "NetKVM/2k8/amd64/netkvm.inf", Some win2k8_64;
-    "NetKVM/2k8/amd64/netkvm.pdb", Some win2k8_64;
-    "NetKVM/2k8/amd64/netkvm.sys", Some win2k8_64;
-    "NetKVM/2k8/amd64/netkvmco.dll", None;
-    "NetKVM/2k8/amd64/readme.doc", None;
-    "NetKVM/2k8/x86/netkvm.cat", Some win2k8_32;
-    "NetKVM/2k8/x86/netkvm.inf", Some win2k8_32;
-    "NetKVM/2k8/x86/netkvm.pdb", Some win2k8_32;
-    "NetKVM/2k8/x86/netkvm.sys", Some win2k8_32;
-    "NetKVM/2k8/x86/netkvmco.dll", None;
-    "NetKVM/2k8/x86/readme.doc", None;
-    "NetKVM/2k8R2/amd64/netkvm.cat", Some win2k8r2_64;
-    "NetKVM/2k8R2/amd64/netkvm.inf", Some win2k8r2_64;
-    "NetKVM/2k8R2/amd64/netkvm.pdb", Some win2k8r2_64;
-    "NetKVM/2k8R2/amd64/netkvm.sys", Some win2k8r2_64;
-    "NetKVM/2k8R2/amd64/netkvmco.dll", None;
-    "NetKVM/2k8R2/amd64/readme.doc", None;
-    "NetKVM/w7/amd64/netkvm.cat", Some win7_64;
-    "NetKVM/w7/amd64/netkvm.inf", Some win7_64;
-    "NetKVM/w7/amd64/netkvm.pdb", Some win7_64;
-    "NetKVM/w7/amd64/netkvm.sys", Some win7_64;
-    "NetKVM/w7/amd64/netkvmco.dll", None;
-    "NetKVM/w7/amd64/readme.doc", None;
-    "NetKVM/w7/x86/netkvm.cat", Some win7_32;
-    "NetKVM/w7/x86/netkvm.inf", Some win7_32;
-    "NetKVM/w7/x86/netkvm.pdb", Some win7_32;
-    "NetKVM/w7/x86/netkvm.sys", Some win7_32;
-    "NetKVM/w7/x86/netkvmco.dll", None;
-    "NetKVM/w7/x86/readme.doc", None;
-    "NetKVM/w8.1/amd64/netkvm.cat", Some win8_1_64;
-    "NetKVM/w8.1/amd64/netkvm.inf", Some win8_1_64;
-    "NetKVM/w8.1/amd64/netkvm.pdb", Some win8_1_64;
-    "NetKVM/w8.1/amd64/netkvm.sys", Some win8_1_64;
-    "NetKVM/w8.1/amd64/netkvmco.dll", None;
-    "NetKVM/w8.1/amd64/readme.doc", None;
-    "NetKVM/w8.1/x86/netkvm.cat", Some win8_1_32;
-    "NetKVM/w8.1/x86/netkvm.inf", Some win8_1_32;
-    "NetKVM/w8.1/x86/netkvm.pdb", Some win8_1_32;
-    "NetKVM/w8.1/x86/netkvm.sys", Some win8_1_32;
-    "NetKVM/w8.1/x86/netkvmco.dll", None;
-    "NetKVM/w8.1/x86/readme.doc", None;
-    "NetKVM/w8/amd64/netkvm.cat", Some win8_64;
-    "NetKVM/w8/amd64/netkvm.inf", Some win8_64;
-    "NetKVM/w8/amd64/netkvm.pdb", Some win8_64;
-    "NetKVM/w8/amd64/netkvm.sys", Some win8_64;
-    "NetKVM/w8/amd64/netkvmco.dll", None;
-    "NetKVM/w8/amd64/readme.doc", None;
-    "NetKVM/w8/x86/netkvm.cat", Some win8_32;
-    "NetKVM/w8/x86/netkvm.inf", Some win8_32;
-    "NetKVM/w8/x86/netkvm.pdb", Some win8_32;
-    "NetKVM/w8/x86/netkvm.sys", Some win8_32;
-    "NetKVM/w8/x86/netkvmco.dll", None;
-    "NetKVM/w8/x86/readme.doc", None;
-    "NetKVM/xp/x86/netkvm.cat", Some winxp_32;
-    "NetKVM/xp/x86/netkvm.inf", Some winxp_32;
-    "NetKVM/xp/x86/netkvm.pdb", Some winxp_32;
-    "NetKVM/xp/x86/netkvm.sys", Some winxp_32;
-    "guest-agent/qemu-ga-x64.msi", None;
-    "guest-agent/qemu-ga-x86.msi", None;
-    "qemupciserial/qemupciserial.inf", None;
-    "viorng/2k12/amd64/WdfCoInstaller01011.dll", None;
-    "viorng/2k12/amd64/viorng.cat", Some win2k12_64;
-    "viorng/2k12/amd64/viorng.inf", Some win2k12_64;
-    "viorng/2k12/amd64/viorng.pdb", Some win2k12_64;
-    "viorng/2k12/amd64/viorng.sys", Some win2k12_64;
-    "viorng/2k12/amd64/viorngci.dll", None;
-    "viorng/2k12/amd64/viorngum.dll", None;
-    "viorng/2k12R2/amd64/WdfCoInstaller01011.dll", None;
-    "viorng/2k12R2/amd64/viorng.cat", Some win2k12r2_64;
-    "viorng/2k12R2/amd64/viorng.inf", Some win2k12r2_64;
-    "viorng/2k12R2/amd64/viorng.pdb", Some win2k12r2_64;
-    "viorng/2k12R2/amd64/viorng.sys", Some win2k12r2_64;
-    "viorng/2k12R2/amd64/viorngci.dll", None;
-    "viorng/2k12R2/amd64/viorngum.dll", None;
-    "viorng/2k8/amd64/WdfCoInstaller01009.dll", None;
-    "viorng/2k8/amd64/viorng.cat", Some win2k8_64;
-    "viorng/2k8/amd64/viorng.inf", Some win2k8_64;
-    "viorng/2k8/amd64/viorng.pdb", Some win2k8_64;
-    "viorng/2k8/amd64/viorng.sys", Some win2k8_64;
-    "viorng/2k8/amd64/viorngci.dll", None;
-    "viorng/2k8/amd64/viorngum.dll", None;
-    "viorng/2k8/x86/WdfCoInstaller01009.dll", None;
-    "viorng/2k8/x86/viorng.cat", Some win2k8_32;
-    "viorng/2k8/x86/viorng.inf", Some win2k8_32;
-    "viorng/2k8/x86/viorng.pdb", Some win2k8_32;
-    "viorng/2k8/x86/viorng.sys", Some win2k8_32;
-    "viorng/2k8/x86/viorngci.dll", None;
-    "viorng/2k8/x86/viorngum.dll", None;
-    "viorng/2k8R2/amd64/WdfCoInstaller01009.dll", None;
-    "viorng/2k8R2/amd64/viorng.cat", Some win2k8r2_64;
-    "viorng/2k8R2/amd64/viorng.inf", Some win2k8r2_64;
-    "viorng/2k8R2/amd64/viorng.pdb", Some win2k8r2_64;
-    "viorng/2k8R2/amd64/viorng.sys", Some win2k8r2_64;
-    "viorng/2k8R2/amd64/viorngci.dll", None;
-    "viorng/2k8R2/amd64/viorngum.dll", None;
-    "viorng/w7/amd64/WdfCoInstaller01009.dll", None;
-    "viorng/w7/amd64/viorng.cat", Some win7_64;
-    "viorng/w7/amd64/viorng.inf", Some win7_64;
-    "viorng/w7/amd64/viorng.pdb", Some win7_64;
-    "viorng/w7/amd64/viorng.sys", Some win7_64;
-    "viorng/w7/amd64/viorngci.dll", None;
-    "viorng/w7/amd64/viorngum.dll", None;
-    "viorng/w7/x86/WdfCoInstaller01009.dll", None;
-    "viorng/w7/x86/viorng.cat", Some win7_32;
-    "viorng/w7/x86/viorng.inf", Some win7_32;
-    "viorng/w7/x86/viorng.pdb", Some win7_32;
-    "viorng/w7/x86/viorng.sys", Some win7_32;
-    "viorng/w7/x86/viorngci.dll", None;
-    "viorng/w7/x86/viorngum.dll", None;
-    "viorng/w8.1/amd64/WdfCoInstaller01011.dll", None;
-    "viorng/w8.1/amd64/viorng.cat", Some win8_1_64;
-    "viorng/w8.1/amd64/viorng.inf", Some win8_1_64;
-    "viorng/w8.1/amd64/viorng.pdb", Some win8_1_64;
-    "viorng/w8.1/amd64/viorng.sys", Some win8_1_64;
-    "viorng/w8.1/amd64/viorngci.dll", None;
-    "viorng/w8.1/amd64/viorngum.dll", None;
-    "viorng/w8.1/x86/WdfCoInstaller01011.dll", None;
-    "viorng/w8.1/x86/viorng.cat", Some win8_1_32;
-    "viorng/w8.1/x86/viorng.inf", Some win8_1_32;
-    "viorng/w8.1/x86/viorng.pdb", Some win8_1_32;
-    "viorng/w8.1/x86/viorng.sys", Some win8_1_32;
-    "viorng/w8.1/x86/viorngci.dll", None;
-    "viorng/w8.1/x86/viorngum.dll", None;
-    "viorng/w8/amd64/WdfCoInstaller01011.dll", None;
-    "viorng/w8/amd64/viorng.cat", Some win8_64;
-    "viorng/w8/amd64/viorng.inf", Some win8_64;
-    "viorng/w8/amd64/viorng.pdb", Some win8_64;
-    "viorng/w8/amd64/viorng.sys", Some win8_64;
-    "viorng/w8/amd64/viorngci.dll", None;
-    "viorng/w8/amd64/viorngum.dll", None;
-    "viorng/w8/x86/WdfCoInstaller01011.dll", None;
-    "viorng/w8/x86/viorng.cat", Some win8_32;
-    "viorng/w8/x86/viorng.inf", Some win8_32;
-    "viorng/w8/x86/viorng.pdb", Some win8_32;
-    "viorng/w8/x86/viorng.sys", Some win8_32;
-    "viorng/w8/x86/viorngci.dll", None;
-    "viorng/w8/x86/viorngum.dll", None;
-    "vioscsi/2k12/amd64/vioscsi.cat", Some win2k12_64;
-    "vioscsi/2k12/amd64/vioscsi.inf", Some win2k12_64;
-    "vioscsi/2k12/amd64/vioscsi.pdb", Some win2k12_64;
-    "vioscsi/2k12/amd64/vioscsi.sys", Some win2k12_64;
-    "vioscsi/2k12R2/amd64/vioscsi.cat", Some win2k12r2_64;
-    "vioscsi/2k12R2/amd64/vioscsi.inf", Some win2k12r2_64;
-    "vioscsi/2k12R2/amd64/vioscsi.pdb", Some win2k12r2_64;
-    "vioscsi/2k12R2/amd64/vioscsi.sys", Some win2k12r2_64;
-    "vioscsi/2k8/amd64/vioscsi.cat", Some win2k8_64;
-    "vioscsi/2k8/amd64/vioscsi.inf", Some win2k8_64;
-    "vioscsi/2k8/amd64/vioscsi.pdb", Some win2k8_64;
-    "vioscsi/2k8/amd64/vioscsi.sys", Some win2k8_64;
-    "vioscsi/2k8/x86/vioscsi.cat", Some win2k8_32;
-    "vioscsi/2k8/x86/vioscsi.inf", Some win2k8_32;
-    "vioscsi/2k8/x86/vioscsi.pdb", Some win2k8_32;
-    "vioscsi/2k8/x86/vioscsi.sys", Some win2k8_32;
-    "vioscsi/2k8R2/amd64/vioscsi.cat", Some win2k8r2_64;
-    "vioscsi/2k8R2/amd64/vioscsi.inf", Some win2k8r2_64;
-    "vioscsi/2k8R2/amd64/vioscsi.pdb", Some win2k8r2_64;
-    "vioscsi/2k8R2/amd64/vioscsi.sys", Some win2k8r2_64;
-    "vioscsi/w7/amd64/vioscsi.cat", Some win7_64;
-    "vioscsi/w7/amd64/vioscsi.inf", Some win7_64;
-    "vioscsi/w7/amd64/vioscsi.pdb", Some win7_64;
-    "vioscsi/w7/amd64/vioscsi.sys", Some win7_64;
-    "vioscsi/w7/x86/vioscsi.cat", Some win7_32;
-    "vioscsi/w7/x86/vioscsi.inf", Some win7_32;
-    "vioscsi/w7/x86/vioscsi.pdb", Some win7_32;
-    "vioscsi/w7/x86/vioscsi.sys", Some win7_32;
-    "vioscsi/w8.1/amd64/vioscsi.cat", Some win8_1_64;
-    "vioscsi/w8.1/amd64/vioscsi.inf", Some win8_1_64;
-    "vioscsi/w8.1/amd64/vioscsi.pdb", Some win8_1_64;
-    "vioscsi/w8.1/amd64/vioscsi.sys", Some win8_1_64;
-    "vioscsi/w8.1/x86/vioscsi.cat", Some win8_1_32;
-    "vioscsi/w8.1/x86/vioscsi.inf", Some win8_1_32;
-    "vioscsi/w8.1/x86/vioscsi.pdb", Some win8_1_32;
-    "vioscsi/w8.1/x86/vioscsi.sys", Some win8_1_32;
-    "vioscsi/w8/amd64/vioscsi.cat", Some win8_64;
-    "vioscsi/w8/amd64/vioscsi.inf", Some win8_64;
-    "vioscsi/w8/amd64/vioscsi.pdb", Some win8_64;
-    "vioscsi/w8/amd64/vioscsi.sys", Some win8_64;
-    "vioscsi/w8/x86/vioscsi.cat", Some win8_32;
-    "vioscsi/w8/x86/vioscsi.inf", Some win8_32;
-    "vioscsi/w8/x86/vioscsi.pdb", Some win8_32;
-    "vioscsi/w8/x86/vioscsi.sys", Some win8_32;
-    "vioserial/2k12/amd64/WdfCoInstaller01011.dll", None;
-    "vioserial/2k12/amd64/vioser.cat", Some win2k12_64;
-    "vioserial/2k12/amd64/vioser.inf", Some win2k12_64;
-    "vioserial/2k12/amd64/vioser.pdb", Some win2k12_64;
-    "vioserial/2k12/amd64/vioser.sys", Some win2k12_64;
-    "vioserial/2k12R2/amd64/WdfCoInstaller01011.dll", None;
-    "vioserial/2k12R2/amd64/vioser.cat", Some win2k12r2_64;
-    "vioserial/2k12R2/amd64/vioser.inf", Some win2k12r2_64;
-    "vioserial/2k12R2/amd64/vioser.pdb", Some win2k12r2_64;
-    "vioserial/2k12R2/amd64/vioser.sys", Some win2k12r2_64;
-    "vioserial/2k3/amd64/WdfCoInstaller01009.dll", None;
-    "vioserial/2k3/amd64/vioser.cat", Some win2k3_64;
-    "vioserial/2k3/amd64/vioser.inf", Some win2k3_64;
-    "vioserial/2k3/amd64/vioser.pdb", Some win2k3_64;
-    "vioserial/2k3/amd64/vioser.sys", Some win2k3_64;
-    "vioserial/2k3/x86/WdfCoInstaller01009.dll", None;
-    "vioserial/2k3/x86/vioser.cat", Some win2k3_32;
-    "vioserial/2k3/x86/vioser.inf", Some win2k3_32;
-    "vioserial/2k3/x86/vioser.pdb", Some win2k3_32;
-    "vioserial/2k3/x86/vioser.sys", Some win2k3_32;
-    "vioserial/2k8/amd64/WdfCoInstaller01009.dll", None;
-    "vioserial/2k8/amd64/vioser.cat", Some win2k8_64;
-    "vioserial/2k8/amd64/vioser.inf", Some win2k8_64;
-    "vioserial/2k8/amd64/vioser.pdb", Some win2k8_64;
-    "vioserial/2k8/amd64/vioser.sys", Some win2k8_64;
-    "vioserial/2k8/x86/WdfCoInstaller01009.dll", None;
-    "vioserial/2k8/x86/vioser.cat", Some win2k8_32;
-    "vioserial/2k8/x86/vioser.inf", Some win2k8_32;
-    "vioserial/2k8/x86/vioser.pdb", Some win2k8_32;
-    "vioserial/2k8/x86/vioser.sys", Some win2k8_32;
-    "vioserial/2k8R2/amd64/WdfCoInstaller01009.dll", None;
-    "vioserial/2k8R2/amd64/vioser.cat", Some win2k8r2_64;
-    "vioserial/2k8R2/amd64/vioser.inf", Some win2k8r2_64;
-    "vioserial/2k8R2/amd64/vioser.pdb", Some win2k8r2_64;
-    "vioserial/2k8R2/amd64/vioser.sys", Some win2k8r2_64;
-    "vioserial/w7/amd64/WdfCoInstaller01009.dll", None;
-    "vioserial/w7/amd64/vioser.cat", Some win7_64;
-    "vioserial/w7/amd64/vioser.inf", Some win7_64;
-    "vioserial/w7/amd64/vioser.pdb", Some win7_64;
-    "vioserial/w7/amd64/vioser.sys", Some win7_64;
-    "vioserial/w7/x86/WdfCoInstaller01009.dll", None;
-    "vioserial/w7/x86/vioser.cat", Some win7_32;
-    "vioserial/w7/x86/vioser.inf", Some win7_32;
-    "vioserial/w7/x86/vioser.pdb", Some win7_32;
-    "vioserial/w7/x86/vioser.sys", Some win7_32;
-    "vioserial/w8.1/amd64/WdfCoInstaller01011.dll", None;
-    "vioserial/w8.1/amd64/vioser.cat", Some win8_1_64;
-    "vioserial/w8.1/amd64/vioser.inf", Some win8_1_64;
-    "vioserial/w8.1/amd64/vioser.pdb", Some win8_1_64;
-    "vioserial/w8.1/amd64/vioser.sys", Some win8_1_64;
-    "vioserial/w8.1/x86/WdfCoInstaller01011.dll", None;
-    "vioserial/w8.1/x86/vioser.cat", Some win8_1_32;
-    "vioserial/w8.1/x86/vioser.inf", Some win8_1_32;
-    "vioserial/w8.1/x86/vioser.pdb", Some win8_1_32;
-    "vioserial/w8.1/x86/vioser.sys", Some win8_1_32;
-    "vioserial/w8/amd64/WdfCoInstaller01011.dll", None;
-    "vioserial/w8/amd64/vioser.cat", Some win8_64;
-    "vioserial/w8/amd64/vioser.inf", Some win8_64;
-    "vioserial/w8/amd64/vioser.pdb", Some win8_64;
-    "vioserial/w8/amd64/vioser.sys", Some win8_64;
-    "vioserial/w8/x86/WdfCoInstaller01011.dll", None;
-    "vioserial/w8/x86/vioser.cat", Some win8_32;
-    "vioserial/w8/x86/vioser.inf", Some win8_32;
-    "vioserial/w8/x86/vioser.pdb", Some win8_32;
-    "vioserial/w8/x86/vioser.sys", Some win8_32;
-    "vioserial/xp/x86/WdfCoInstaller01009.dll", None;
-    "vioserial/xp/x86/vioser.cat", Some winxp_32;
-    "vioserial/xp/x86/vioser.inf", Some winxp_32;
-    "vioserial/xp/x86/vioser.pdb", Some winxp_32;
-    "vioserial/xp/x86/vioser.sys", Some winxp_32;
-    "viostor/2k12/amd64/viostor.cat", Some win2k12_64;
-    "viostor/2k12/amd64/viostor.inf", Some win2k12_64;
-    "viostor/2k12/amd64/viostor.pdb", Some win2k12_64;
-    "viostor/2k12/amd64/viostor.sys", Some win2k12_64;
-    "viostor/2k12R2/amd64/viostor.cat", Some win2k12r2_64;
-    "viostor/2k12R2/amd64/viostor.inf", Some win2k12r2_64;
-    "viostor/2k12R2/amd64/viostor.pdb", Some win2k12r2_64;
-    "viostor/2k12R2/amd64/viostor.sys", Some win2k12r2_64;
-    "viostor/2k3/amd64/viostor.cat", Some win2k3_64;
-    "viostor/2k3/amd64/viostor.inf", Some win2k3_64;
-    "viostor/2k3/amd64/viostor.pdb", Some win2k3_64;
-    "viostor/2k3/amd64/viostor.sys", Some win2k3_64;
-    "viostor/2k3/x86/viostor.cat", Some win2k3_32;
-    "viostor/2k3/x86/viostor.inf", Some win2k3_32;
-    "viostor/2k3/x86/viostor.pdb", Some win2k3_32;
-    "viostor/2k3/x86/viostor.sys", Some win2k3_32;
-    "viostor/2k8/amd64/viostor.cat", Some win2k8_64;
-    "viostor/2k8/amd64/viostor.inf", Some win2k8_64;
-    "viostor/2k8/amd64/viostor.pdb", Some win2k8_64;
-    "viostor/2k8/amd64/viostor.sys", Some win2k8_64;
-    "viostor/2k8/x86/viostor.cat", Some win2k8_32;
-    "viostor/2k8/x86/viostor.inf", Some win2k8_32;
-    "viostor/2k8/x86/viostor.pdb", Some win2k8_32;
-    "viostor/2k8/x86/viostor.sys", Some win2k8_32;
-    "viostor/2k8R2/amd64/viostor.cat", Some win2k8r2_64;
-    "viostor/2k8R2/amd64/viostor.inf", Some win2k8r2_64;
-    "viostor/2k8R2/amd64/viostor.pdb", Some win2k8r2_64;
-    "viostor/2k8R2/amd64/viostor.sys", Some win2k8r2_64;
-    "viostor/w7/amd64/viostor.cat", Some win7_64;
-    "viostor/w7/amd64/viostor.inf", Some win7_64;
-    "viostor/w7/amd64/viostor.pdb", Some win7_64;
-    "viostor/w7/amd64/viostor.sys", Some win7_64;
-    "viostor/w7/x86/viostor.cat", Some win7_32;
-    "viostor/w7/x86/viostor.inf", Some win7_32;
-    "viostor/w7/x86/viostor.pdb", Some win7_32;
-    "viostor/w7/x86/viostor.sys", Some win7_32;
-    "viostor/w8.1/amd64/viostor.cat", Some win8_1_64;
-    "viostor/w8.1/amd64/viostor.inf", Some win8_1_64;
-    "viostor/w8.1/amd64/viostor.pdb", Some win8_1_64;
-    "viostor/w8.1/amd64/viostor.sys", Some win8_1_64;
-    "viostor/w8.1/x86/viostor.cat", Some win8_1_32;
-    "viostor/w8.1/x86/viostor.inf", Some win8_1_32;
-    "viostor/w8.1/x86/viostor.pdb", Some win8_1_32;
-    "viostor/w8.1/x86/viostor.sys", Some win8_1_32;
-    "viostor/w8/amd64/viostor.cat", Some win8_64;
-    "viostor/w8/amd64/viostor.inf", Some win8_64;
-    "viostor/w8/amd64/viostor.pdb", Some win8_64;
-    "viostor/w8/amd64/viostor.sys", Some win8_64;
-    "viostor/w8/x86/viostor.cat", Some win8_32;
-    "viostor/w8/x86/viostor.inf", Some win8_32;
-    "viostor/w8/x86/viostor.pdb", Some win8_32;
-    "viostor/w8/x86/viostor.sys", Some win8_32;
-    "viostor/xp/x86/viostor.cat", Some winxp_32;
-    "viostor/xp/x86/viostor.inf", Some winxp_32;
-    "viostor/xp/x86/viostor.pdb", Some winxp_32;
-    "viostor/xp/x86/viostor.sys", Some winxp_32;
-    "virtio-win-1.7.4_amd64.vfd", None;
-    "virtio-win-1.7.4_x86.vfd", None;
-    "virtio-win_license.txt", None;
+    (* Paths relative to $srcdir/test-data/fake-virtio-win. *)
+    "cd/Balloon/2k12/amd64/balloon.inf", Some win2k12_64;
+    "cd/Balloon/2k12R2/amd64/balloon.inf", Some win2k12r2_64;
+    "cd/Balloon/2k3/amd64/balloon.inf", Some win2k3_64;
+    "cd/Balloon/2k3/x86/balloon.inf", Some win2k3_32;
+    "cd/Balloon/2k8/amd64/balloon.inf", Some win2k8_64;
+    "cd/Balloon/2k8/x86/balloon.inf", Some win2k8_32;
+    "cd/Balloon/2k8R2/amd64/balloon.inf", Some win2k8r2_64;
+    "cd/Balloon/w7/amd64/balloon.inf", Some win7_64;
+    "cd/Balloon/w7/x86/balloon.inf", Some win7_32;
+    "cd/Balloon/w8.1/amd64/balloon.inf", Some win8_1_64;
+    "cd/Balloon/w8.1/x86/balloon.inf", Some win8_1_32;
+    "cd/Balloon/w8/amd64/balloon.inf", Some win8_64;
+    "cd/Balloon/w8/x86/balloon.inf", Some win8_32;
+    "cd/Balloon/xp/x86/balloon.inf", Some winxp_32;
+    "cd/NetKVM/2k12/amd64/netkvm.inf", Some win2k12_64;
+    "cd/NetKVM/2k12R2/amd64/netkvm.inf", Some win2k12r2_64;
+    "cd/NetKVM/2k3/amd64/netkvm.inf", Some win2k3_64;
+    "cd/NetKVM/2k3/x86/netkvm.inf", Some win2k3_32;
+    "cd/NetKVM/2k8/amd64/netkvm.inf", Some win2k8_64;
+    "cd/NetKVM/2k8/x86/netkvm.inf", Some win2k8_32;
+    "cd/NetKVM/2k8R2/amd64/netkvm.inf", Some win2k8r2_64;
+    "cd/NetKVM/w7/amd64/netkvm.inf", Some win7_64;
+    "cd/NetKVM/w7/x86/netkvm.inf", Some win7_32;
+    "cd/NetKVM/w8.1/amd64/netkvm.inf", Some win8_1_64;
+    "cd/NetKVM/w8.1/x86/netkvm.inf", Some win8_1_32;
+    "cd/NetKVM/w8/amd64/netkvm.inf", Some win8_64;
+    "cd/NetKVM/w8/x86/netkvm.inf", Some win8_32;
+    "cd/NetKVM/xp/x86/netkvm.inf", Some winxp_32;
+    "cd/qemupciserial/qemupciserial.inf", None;
+    "cd/viorng/2k12/amd64/viorng.inf", Some win2k12_64;
+    "cd/viorng/2k12R2/amd64/viorng.inf", Some win2k12r2_64;
+    "cd/viorng/2k8/amd64/viorng.inf", Some win2k8_64;
+    "cd/viorng/2k8/x86/viorng.inf", Some win2k8_32;
+    "cd/viorng/2k8R2/amd64/viorng.inf", Some win2k8r2_64;
+    "cd/viorng/w7/amd64/viorng.inf", Some win7_64;
+    "cd/viorng/w7/x86/viorng.inf", Some win7_32;
+    "cd/viorng/w8.1/amd64/viorng.inf", Some win8_1_64;
+    "cd/viorng/w8.1/x86/viorng.inf", Some win8_1_32;
+    "cd/viorng/w8/amd64/viorng.inf", Some win8_64;
+    "cd/viorng/w8/x86/viorng.inf", Some win8_32;
+    "cd/vioscsi/2k12/amd64/vioscsi.inf", Some win2k12_64;
+    "cd/vioscsi/2k12R2/amd64/vioscsi.inf", Some win2k12r2_64;
+    "cd/vioscsi/2k8/amd64/vioscsi.inf", Some win2k8_64;
+    "cd/vioscsi/2k8/x86/vioscsi.inf", Some win2k8_32;
+    "cd/vioscsi/2k8R2/amd64/vioscsi.inf", Some win2k8r2_64;
+    "cd/vioscsi/w7/amd64/vioscsi.inf", Some win7_64;
+    "cd/vioscsi/w7/x86/vioscsi.inf", Some win7_32;
+    "cd/vioscsi/w8.1/amd64/vioscsi.inf", Some win8_1_64;
+    "cd/vioscsi/w8.1/x86/vioscsi.inf", Some win8_1_32;
+    "cd/vioscsi/w8/amd64/vioscsi.inf", Some win8_64;
+    "cd/vioscsi/w8/x86/vioscsi.inf", Some win8_32;
+    "cd/vioserial/2k12/amd64/vioser.inf", Some win2k12_64;
+    "cd/vioserial/2k12R2/amd64/vioser.inf", Some win2k12r2_64;
+    "cd/vioserial/2k3/amd64/vioser.inf", Some win2k3_64;
+    "cd/vioserial/2k3/x86/vioser.inf", Some win2k3_32;
+    "cd/vioserial/2k8/amd64/vioser.inf", Some win2k8_64;
+    "cd/vioserial/2k8/x86/vioser.inf", Some win2k8_32;
+    "cd/vioserial/2k8R2/amd64/vioser.inf", Some win2k8r2_64;
+    "cd/vioserial/w7/amd64/vioser.inf", Some win7_64;
+    "cd/vioserial/w7/x86/vioser.inf", Some win7_32;
+    "cd/vioserial/w8.1/amd64/vioser.inf", Some win8_1_64;
+    "cd/vioserial/w8.1/x86/vioser.inf", Some win8_1_32;
+    "cd/vioserial/w8/amd64/vioser.inf", Some win8_64;
+    "cd/vioserial/w8/x86/vioser.inf", Some win8_32;
+    "cd/vioserial/w8/x86/vioser.pdb", Some win8_32;
+    "cd/vioserial/xp/x86/vioser.inf", Some winxp_32;
+    "cd/viostor/2k12/amd64/viostor.inf", Some win2k12_64;
+    "cd/viostor/2k12R2/amd64/viostor.inf", Some win2k12r2_64;
+    "cd/viostor/2k3/amd64/viostor.inf", Some win2k3_64;
+    "cd/viostor/2k3/x86/viostor.inf", Some win2k3_32;
+    "cd/viostor/2k8/amd64/viostor.inf", Some win2k8_64;
+    "cd/viostor/2k8/x86/viostor.inf", Some win2k8_32;
+    "cd/viostor/2k8R2/amd64/viostor.inf", Some win2k8r2_64;
+    "cd/viostor/w7/amd64/viostor.inf", Some win7_64;
+    "cd/viostor/w7/x86/viostor.inf", Some win7_32;
+    "cd/viostor/w8.1/amd64/viostor.inf", Some win8_1_64;
+    "cd/viostor/w8.1/x86/viostor.inf", Some win8_1_32;
+    "cd/viostor/w8/amd64/viostor.inf", Some win8_64;
+    "cd/viostor/w8/x86/viostor.inf", Some win8_32;
+    "cd/viostor/xp/x86/viostor.inf", Some winxp_32;
 
-    (* Paths from the unpacked virtio-win 1.7.4 directory. *)
-    "virtio-win-1.7.4.iso", None;
-    "virtio-win-1.7.4_amd64.vfd", None;
-    "guest-agent/qemu-ga-x86.msi", None;
-    "guest-agent/qemu-ga-x64.msi", None;
     "drivers/i386/Win8.1/viostor.inf", Some win8_1_32;
-    "drivers/i386/Win8.1/viostor.sys", Some win8_1_32;
-    "drivers/i386/Win8.1/vioscsi.cat", Some win8_1_32;
     "drivers/i386/Win8.1/netkvm.inf", Some win8_1_32;
-    "drivers/i386/Win8.1/netkvm.sys", Some win8_1_32;
-    "drivers/i386/Win8.1/viostor.cat", Some win8_1_32;
-    "drivers/i386/Win8.1/vioscsi.sys", Some win8_1_32;
-    "drivers/i386/Win8.1/netkvm.cat", Some win8_1_32;
     "drivers/i386/Win8.1/vioscsi.inf", Some win8_1_32;
     "drivers/i386/Win2008/viostor.inf", Some win2k8_32;
-    "drivers/i386/Win2008/viostor.sys", Some win2k8_32;
-    "drivers/i386/Win2008/vioscsi.cat", Some win2k8_32;
     "drivers/i386/Win2008/netkvm.inf", Some win2k8_32;
-    "drivers/i386/Win2008/netkvm.sys", Some win2k8_32;
-    "drivers/i386/Win2008/viostor.cat", Some win2k8_32;
-    "drivers/i386/Win2008/vioscsi.sys", Some win2k8_32;
-    "drivers/i386/Win2008/netkvm.cat", Some win2k8_32;
     "drivers/i386/Win2008/vioscsi.inf", Some win2k8_32;
     "drivers/i386/Win7/viostor.inf", Some win7_32;
-    "drivers/i386/Win7/viostor.sys", Some win7_32;
-    "drivers/i386/Win7/qxldd.dll", None;
-    "drivers/i386/Win7/qxl.sys", Some win7_32;
-    "drivers/i386/Win7/vioscsi.cat", Some win7_32;
     "drivers/i386/Win7/netkvm.inf", Some win7_32;
-    "drivers/i386/Win7/netkvm.sys", Some win7_32;
-    "drivers/i386/Win7/viostor.cat", Some win7_32;
     "drivers/i386/Win7/qxl.inf", Some win7_32;
-    "drivers/i386/Win7/vioscsi.sys", Some win7_32;
-    "drivers/i386/Win7/qxl.cat", Some win7_32;
-    "drivers/i386/Win7/netkvm.cat", Some win7_32;
     "drivers/i386/Win7/vioscsi.inf", Some win7_32;
     "drivers/i386/Win2003/viostor.inf", Some win2k3_32;
-    "drivers/i386/Win2003/viostor.sys", Some win2k3_32;
     "drivers/i386/Win2003/netkvm.inf", Some win2k3_32;
-    "drivers/i386/Win2003/netkvm.sys", Some win2k3_32;
-    "drivers/i386/Win2003/viostor.cat", Some win2k3_32;
-    "drivers/i386/Win2003/netkvm.cat", Some win2k3_32;
     "drivers/i386/Win8/viostor.inf", Some win8_32;
-    "drivers/i386/Win8/viostor.sys", Some win8_32;
-    "drivers/i386/Win8/vioscsi.cat", Some win8_32;
     "drivers/i386/Win8/netkvm.inf", Some win8_32;
-    "drivers/i386/Win8/netkvm.sys", Some win8_32;
-    "drivers/i386/Win8/viostor.cat", Some win8_32;
-    "drivers/i386/Win8/vioscsi.sys", Some win8_32;
-    "drivers/i386/Win8/netkvm.cat", Some win8_32;
     "drivers/i386/Win8/vioscsi.inf", Some win8_32;
     "drivers/i386/WinXP/viostor.inf", Some winxp_32;
-    "drivers/i386/WinXP/viostor.sys", Some winxp_32;
-    "drivers/i386/WinXP/qxldd.dll", None;
-    "drivers/i386/WinXP/qxl.sys", Some winxp_32;
     "drivers/i386/WinXP/netkvm.inf", Some winxp_32;
-    "drivers/i386/WinXP/netkvm.sys", Some winxp_32;
-    "drivers/i386/WinXP/viostor.cat", Some winxp_32;
     "drivers/i386/WinXP/qxl.inf", Some winxp_32;
-    "drivers/i386/WinXP/qxl.cat", Some winxp_32;
-    "drivers/i386/WinXP/netkvm.cat", Some winxp_32;
     "drivers/amd64/Win8.1/viostor.inf", Some win8_1_64;
-    "drivers/amd64/Win8.1/viostor.sys", Some win8_1_64;
-    "drivers/amd64/Win8.1/vioscsi.cat", Some win8_1_64;
     "drivers/amd64/Win8.1/netkvm.inf", Some win8_1_64;
-    "drivers/amd64/Win8.1/netkvm.sys", Some win8_1_64;
-    "drivers/amd64/Win8.1/viostor.cat", Some win8_1_64;
-    "drivers/amd64/Win8.1/vioscsi.sys", Some win8_1_64;
-    "drivers/amd64/Win8.1/netkvm.cat", Some win8_1_64;
     "drivers/amd64/Win8.1/vioscsi.inf", Some win8_1_64;
     "drivers/amd64/Win2008/viostor.inf", Some win2k8_64;
-    "drivers/amd64/Win2008/viostor.sys", Some win2k8_64;
-    "drivers/amd64/Win2008/vioscsi.cat", Some win2k8_64;
     "drivers/amd64/Win2008/netkvm.inf", Some win2k8_64;
-    "drivers/amd64/Win2008/netkvm.sys", Some win2k8_64;
-    "drivers/amd64/Win2008/viostor.cat", Some win2k8_64;
-    "drivers/amd64/Win2008/vioscsi.sys", Some win2k8_64;
-    "drivers/amd64/Win2008/netkvm.cat", Some win2k8_64;
     "drivers/amd64/Win2008/vioscsi.inf", Some win2k8_64;
     "drivers/amd64/Win7/viostor.inf", Some win7_64;
-    "drivers/amd64/Win7/viostor.sys", Some win7_64;
-    "drivers/amd64/Win7/qxldd.dll", None;
-    "drivers/amd64/Win7/qxl.sys", Some win7_64;
-    "drivers/amd64/Win7/vioscsi.cat", Some win7_64;
     "drivers/amd64/Win7/netkvm.inf", Some win7_64;
-    "drivers/amd64/Win7/netkvm.sys", Some win7_64;
-    "drivers/amd64/Win7/viostor.cat", Some win7_64;
     "drivers/amd64/Win7/qxl.inf", Some win7_64;
-    "drivers/amd64/Win7/vioscsi.sys", Some win7_64;
-    "drivers/amd64/Win7/qxl.cat", Some win7_64;
-    "drivers/amd64/Win7/netkvm.cat", Some win7_64;
     "drivers/amd64/Win7/vioscsi.inf", Some win7_64;
     "drivers/amd64/Win2003/viostor.inf", Some win2k3_64;
-    "drivers/amd64/Win2003/viostor.sys", Some win2k3_64;
     "drivers/amd64/Win2003/netkvm.inf", Some win2k3_64;
-    "drivers/amd64/Win2003/netkvm.sys", Some win2k3_64;
-    "drivers/amd64/Win2003/viostor.cat", Some win2k3_64;
-    "drivers/amd64/Win2003/netkvm.cat", Some win2k3_64;
     "drivers/amd64/Win8/viostor.inf", Some win8_64;
-    "drivers/amd64/Win8/viostor.sys", Some win8_64;
-    "drivers/amd64/Win8/vioscsi.cat", Some win8_64;
     "drivers/amd64/Win8/netkvm.inf", Some win8_64;
-    "drivers/amd64/Win8/netkvm.sys", Some win8_64;
-    "drivers/amd64/Win8/viostor.cat", Some win8_64;
-    "drivers/amd64/Win8/vioscsi.sys", Some win8_64;
-    "drivers/amd64/Win8/netkvm.cat", Some win8_64;
     "drivers/amd64/Win8/vioscsi.inf", Some win8_64;
     "drivers/amd64/Win2012/viostor.inf", Some win2k12_64;
-    "drivers/amd64/Win2012/viostor.sys", Some win2k12_64;
-    "drivers/amd64/Win2012/vioscsi.cat", Some win2k12_64;
     "drivers/amd64/Win2012/netkvm.inf", Some win2k12_64;
-    "drivers/amd64/Win2012/netkvm.sys", Some win2k12_64;
-    "drivers/amd64/Win2012/viostor.cat", Some win2k12_64;
-    "drivers/amd64/Win2012/vioscsi.sys", Some win2k12_64;
-    "drivers/amd64/Win2012/netkvm.cat", Some win2k12_64;
     "drivers/amd64/Win2012/vioscsi.inf", Some win2k12_64;
     "drivers/amd64/Win2008R2/viostor.inf", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/viostor.sys", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/qxldd.dll", None;
-    "drivers/amd64/Win2008R2/qxl.sys", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/vioscsi.cat", Some win2k8r2_64;
     "drivers/amd64/Win2008R2/netkvm.inf", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/netkvm.sys", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/viostor.cat", Some win2k8r2_64;
     "drivers/amd64/Win2008R2/qxl.inf", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/vioscsi.sys", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/qxl.cat", Some win2k8r2_64;
-    "drivers/amd64/Win2008R2/netkvm.cat", Some win2k8r2_64;
     "drivers/amd64/Win2008R2/vioscsi.inf", Some win2k8r2_64;
     "drivers/amd64/Win2012R2/viostor.inf", Some win2k12r2_64;
-    "drivers/amd64/Win2012R2/viostor.sys", Some win2k12r2_64;
-    "drivers/amd64/Win2012R2/vioscsi.cat", Some win2k12r2_64;
     "drivers/amd64/Win2012R2/netkvm.inf", Some win2k12r2_64;
-    "drivers/amd64/Win2012R2/netkvm.sys", Some win2k12r2_64;
-    "drivers/amd64/Win2012R2/viostor.cat", Some win2k12r2_64;
-    "drivers/amd64/Win2012R2/vioscsi.sys", Some win2k12r2_64;
-    "drivers/amd64/Win2012R2/netkvm.cat", Some win2k12r2_64;
     "drivers/amd64/Win2012R2/vioscsi.inf", Some win2k12r2_64;
-    "virtio-win-1.7.4_x86.vfd", None;
   ] in
 
-  (* Test each path against each version of Windows. *)
+  (* Test each inf file against each version of Windows. *)
   let printer = string_of_bool in
 
   List.iter (
     fun (path, correct_windows) ->
+      let path = srcdir // ".." // "test-data" // "fake-virtio-win" // path in
+
       match correct_windows with
       | None ->
          List.iter (
            fun win ->
              let msg = sprintf "path %s should not match %s"
                                path win.i_product_name in
+             let content = read_whole_file path in
              assert_equal ~printer ~msg false
-               (Windows.UNIT_TESTS.virtio_iso_path_matches_guest_os path win)
+               (Windows.UNIT_TESTS.virtio_inf_matches_guest_os content path win)
          ) all_windows
       | Some correct_windows ->
          List.iter (
@@ -859,8 +417,9 @@ let test_virtio_iso_path_matches_guest_os ctx =
                else
                  sprintf "path %s should not match %s"
                          path win.i_product_name in
+             let content = read_whole_file path in
              assert_equal ~printer ~msg expected
-               (Windows.UNIT_TESTS.virtio_iso_path_matches_guest_os path win)
+               (Windows.UNIT_TESTS.virtio_inf_matches_guest_os content path win)
          ) all_windows
   ) paths
 
@@ -872,8 +431,8 @@ let suite =
       "Utils.drive_name" >:: test_drive_name;
       "Utils.drive_index" >:: test_drive_index;
       "Windows_inf.of_string" >:: test_windows_inf_of_string;
-      "Windows.virtio_iso_path_matches_guest_os" >::
-        test_virtio_iso_path_matches_guest_os;
+      "Windows.virtio_inf_matches_guest_os" >::
+        test_virtio_inf_matches_guest_os;
     ]
 
 let () =
diff --git a/v2v/windows.ml b/v2v/windows.ml
index 6503b57..2e18307 100644
--- a/v2v/windows.ml
+++ b/v2v/windows.ml
@@ -50,128 +50,185 @@ and (=~) str rex =
 (* Copy the matching drivers to the driverdir; return true if any have
  * been copied.
  *)
+type virtio_win_source =
+  | Virtio_Win_Directory
+  | Virtio_Win_ISO of Guestfs.guestfs
+
 let rec copy_virtio_drivers g inspect virtio_win driverdir =
-  let ret = ref false in
-  if is_directory virtio_win then (
-    let cmd = sprintf "cd %s && find -type f" (quote virtio_win) in
-    let paths = external_command cmd in
-    List.iter (
-      fun path ->
-        if virtio_iso_path_matches_guest_os path inspect then (
-          let source = virtio_win // path in
-          let target = driverdir //
-                         String.lowercase_ascii (Filename.basename path) in
-          if verbose () then
-            printf "Copying virtio driver bits: 'host:%s' -> '%s'\n"
-                   source target;
-
-          g#write target (read_whole_file source);
-          ret := true
-        )
-      ) paths
-  )
-  else if is_regular_file virtio_win then (
-    try
-      let g2 = open_guestfs ~identifier:"virtio_win" () in
-      g2#add_drive_opts virtio_win ~readonly:true;
-      g2#launch ();
-      let vio_root = "/" in
-      g2#mount_ro "/dev/sda" vio_root;
-      let paths = g2#find vio_root in
-      Array.iter (
-        fun path ->
-          let source = vio_root // path in
-          if g2#is_file source ~followsymlinks:false &&
-               virtio_iso_path_matches_guest_os path inspect then (
-            let target = driverdir //
-                           String.lowercase_ascii (Filename.basename path) in
-            if verbose () then
-              printf "Copying virtio driver bits: '%s:%s' -> '%s'\n"
-                     virtio_win path target;
-
-            g#write target (g2#read_file source);
-            ret := true
-          )
-        ) paths;
-      g2#close()
-    with Guestfs.Error msg ->
-      error (f_"%s: cannot open virtio-win ISO file: %s") virtio_win msg
-  );
-  !ret
-
-(* Given a path of a file relative to the root of the directory tree
- * with virtio-win drivers, figure out if it's suitable for the
- * specific Windows flavor of the current guest.
+  (* Does $VIRTIO_WIN point to a directory or an ISO file? *)
+  let virtio_win_source =
+    if is_directory virtio_win then
+      Some Virtio_Win_Directory
+    else if is_regular_file virtio_win then (
+      try
+        let g2 = open_guestfs ~identifier:"virtio_win" () in
+        g2#add_drive_opts virtio_win ~readonly:true;
+        g2#launch ();
+        g2#mount_ro "/dev/sda" "/";
+        Some (Virtio_Win_ISO g2)
+      with Guestfs.Error msg ->
+        error (f_"%s: cannot open virtio-win ISO file: %s") virtio_win msg
+    ) else
+      None in
+
+  match virtio_win_source with
+  | None ->
+     (* [$VIRTIO_WIN] does not point to a directory or regular file.  This
+      * is not an error, but at the same time, no drivers were copied
+      * so we return [false] here.
+      *)
+     false
+
+  | Some virtio_win_source ->
+     (* Find and load all the *.inf files from the virtio-win directory
+      * or ISO.  Returns a list of pairs [(inf_content, inf_name, directory)]
+      * where [inf_content] is the unparsed inf file, [inf_name] is a debug
+      * string we can use in error messages to refer to the inf file,
+      * and [directory] is a string used to track the directory containing
+      * the inf file.
+      *)
+     let inf_files : (string * string * string) list =
+       match virtio_win_source with
+       | Virtio_Win_Directory ->
+          let cmd =
+            sprintf "find %s -name '*.inf' -type f" (quote virtio_win) in
+          let paths = external_command cmd in
+          List.map (fun path ->
+                      read_whole_file path, path, Filename.dirname path) paths
+       | Virtio_Win_ISO g2 ->
+          let paths = g2#find "/" in
+          let paths = Array.to_list paths in
+          let paths =
+            List.filter (
+              fun path ->
+                String.is_suffix path ".inf" &&
+                  g2#is_file path ~followsymlinks:false
+            ) paths in
+          List.map (
+            fun path ->
+              let path = "/" ^ path in
+              let i = String.rindex path '/' in
+              let dir = String.sub path 0 i in
+              g2#read_file path, sprintf "%s:%s" virtio_win path, dir
+          ) paths in
+
+     (* Get only the *.inf files which match the operating system. *)
+     let inf_files =
+       List.filter (
+         fun (inf_content, inf_name, directory) ->
+           virtio_inf_matches_guest_os inf_content inf_name inspect
+       ) inf_files in
+
+     (* If a directory contains any matching *.inf file, then we will
+      * copy all the files from that directory.  So get the unique list
+      * of directories that we will copy.
+      *)
+     let directories = List.map (fun (_,_,dir) -> dir) inf_files in
+     let directories = sort_uniq directories in
+
+     (* Copy the directories. *)
+     List.iter (
+       fun dir ->
+         match virtio_win_source with
+         | Virtio_Win_Directory -> copy_host_directory dir g driverdir
+         | Virtio_Win_ISO g2 -> copy_iso_directory g2 dir g driverdir
+     ) directories;
+
+     (* Return true if some drivers were copied. *)
+     directories <> []
+
+(* Copy host files in same directory as inf_path to driverdir. *)
+and copy_host_directory dir g driverdir =
+  g#copy_in dir driverdir
+
+(* Copy files from ISO in same directory as inf_path to driverdir. *)
+and copy_iso_directory g2 dir g driverdir =
+  let files = g2#find dir in
+  let files = Array.to_list files in
+  assert (files <> []); (* at least the .inf file must be here *)
+
+  List.iter (
+    fun filename ->
+      let content = g2#read_file (dir ^ filename) in
+      g#write (driverdir ^ "/" ^ filename) content
+  ) files
+
+(* Given the content of a [*.inf] file from the virtio-win drivers,
+ * figure out if it's suitable for the specific Windows flavor of the
+ * current guest.
+ *)
+and virtio_inf_matches_guest_os inf_content inf_name inspect =
+  let sections = Windows_inf.of_string inf_content in
+
+  (* Try to find the [Version] / DriverVer. *)
+  let driver_ver = parse_driver_ver inf_name sections in
+
+  (* Try to find the [Manufacturer] line. *)
+  let driver_arch = parse_manufacturer inf_name sections in
+
+  (* If we got both, we can continue, else give up. *)
+  match driver_ver, driver_arch with
+  | None, None | Some _, None | None, Some _ -> false
+  | Some driver_ver, Some driver_arch ->
+     (* XXX This ignores i_product_variant.  However that may not matter.
+      * There appears to be no material difference in the inf file.
+      *)
+     let { Types.i_major_version = major; i_minor_version = minor;
+           i_arch = arch } = inspect in
+
+     let ver = major * 10 + minor in
+
+     driver_ver = ver && driver_arch = arch
+
+(* Find the [Version] section in the [*.inf] file, and find the
+ * [DriverVer] from that, and parse it.  Returns [None] if we couldn't
+ * find / parse it.
+ * Reference: https://www.redhat.com/archives/libguestfs/2015-October/msg00352.html
  *)
-and virtio_iso_path_matches_guest_os path inspect =
-  let { Types.i_major_version = os_major; i_minor_version = os_minor;
-        i_arch = arch; i_product_variant = os_variant } = inspect in
+and parse_driver_ver inf_name sections =
   try
-    (* Lowercased path, since the ISO may contain upper or lowercase path
-     * elements.
-     *)
-    let lc_path = String.lowercase_ascii path in
-    let lc_basename = Filename.basename path in
-
-    let extension =
-      match last_part_of lc_basename '.' with
-      | Some x -> x
-      | None -> raise Not_found
-    in
-
-    (* Skip files without specific extensions. *)
-    let extensions = ["cat"; "inf"; "pdb"; "sys"] in
-    if not (List.mem extension extensions) then raise Not_found;
-
-    (* Using the full path, work out what version of Windows
-     * this driver is for.  Paths can be things like:
-     * "NetKVM/2k12R2/amd64/netkvm.sys" or
-     * "./drivers/amd64/Win2012R2/netkvm.sys".
-     * Note we check lowercase paths.
-     *)
-    let pathelem elem = String.find lc_path ("/" ^ elem ^ "/") >= 0 in
-    let p_arch =
-      if pathelem "x86" || pathelem "i386" then "i386"
-      else if pathelem "amd64" then "x86_64"
-      else raise Not_found in
-
-    let is_client os_variant = os_variant = "Client"
-    and not_client os_variant = os_variant <> "Client"
-    and any_variant os_variant = true in
-    let p_os_major, p_os_minor, match_os_variant =
-      if pathelem "xp" || pathelem "winxp" then
-        (5, 1, any_variant)
-      else if pathelem "2k3" || pathelem "win2003" then
-        (5, 2, any_variant)
-      else if pathelem "vista" then
-        (6, 0, is_client)
-      else if pathelem "2k8" || pathelem "win2008" then
-        (6, 0, not_client)
-      else if pathelem "w7" || pathelem "win7" then
-        (6, 1, is_client)
-      else if pathelem "2k8r2" || pathelem "win2008r2" then
-        (6, 1, not_client)
-      else if pathelem "w8" || pathelem "win8" then
-        (6, 2, is_client)
-      else if pathelem "2k12" || pathelem "win2012" then
-        (6, 2, not_client)
-      else if pathelem "w8.1" || pathelem "win8.1" then
-        (6, 3, is_client)
-      else if pathelem "2k12r2" || pathelem "win2012r2" then
-        (6, 3, not_client)
-      else if pathelem "w10" || pathelem "win10" then
-        (10, 0, is_client)
-      else
-        raise Not_found in
-
-    arch = p_arch && os_major = p_os_major && os_minor = p_os_minor &&
-      match_os_variant os_variant
-
-  with Not_found -> false
+    let driver_ver = Windows_inf.find_key sections "Version" "DriverVer" in
+    if Str.string_match driver_ver_rex driver_ver 0 then
+      Some (int_of_string (Str.matched_group 1 driver_ver))
+    else
+      raise Not_found
+  with
+    Not_found ->
+      warning (f_"%s: could not find or parse the [Version] DriverVer key in the Windows inf file")
+              inf_name;
+      None
+
+and driver_ver_rex =
+  Str.regexp "[0-9/]+,\\([0-9]+\\)"
+
+(* Find the [Manufacturer] section and try to find the first line.
+ * There is no consistent naming of this line unfortunately.
+ * Reference: https://www.redhat.com/archives/libguestfs/2015-November/msg00065.html
+ *)
+and parse_manufacturer inf_name sections =
+  try
+    let lines = Windows_inf.find_section sections "Manufacturer" in
+    match lines with
+    | [] -> raise Not_found
+    | (_, manufacturer) :: _ ->
+       if Str.string_match manufacturer_rex manufacturer 0 then (
+         let arch = Str.matched_group 1 manufacturer in
+         if arch = "x86" || arch = "X86" then Some "i386" else Some "x86_64"
+       )
+       else
+         raise Not_found
+  with
+    Not_found ->
+      warning (f_"%s: could not find or parse the [Manufacturer] section in the Windows inf file")
+              inf_name;
+      None
+
+and manufacturer_rex =
+  Str.regexp_case_fold ".*,NT\\(x86\\|amd64\\)"
 
 (* The following function is only exported for unit tests. *)
 module UNIT_TESTS = struct
-  let virtio_iso_path_matches_guest_os = virtio_iso_path_matches_guest_os
+  let virtio_inf_matches_guest_os = virtio_inf_matches_guest_os
 end
 
 (* This is a wrapper that handles opening and closing the hive
diff --git a/v2v/windows.mli b/v2v/windows.mli
index 863a605..4098b27 100644
--- a/v2v/windows.mli
+++ b/v2v/windows.mli
@@ -45,5 +45,5 @@ val get_node : Guestfs.guestfs -> int64 -> string list -> int64 option
 
 (* The following function is only exported for unit tests. *)
 module UNIT_TESTS : sig
-  val virtio_iso_path_matches_guest_os : string -> Types.inspect -> bool
+  val virtio_inf_matches_guest_os : string -> string -> Types.inspect -> bool
 end
-- 
2.5.0




More information about the Libguestfs mailing list