Richard W.M. Jones
2015-Nov-17 22:03 UTC
[Libguestfs] [PATCH 0/3] v2v: windows: Use '*.inf' files to control how Windows drivers are installed.
https://github.com/rwmjones/libguestfs/tree/rewrite-virtio-copy-drivers 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 (see email I sent earlier today). There's actually a fourth patch which I didn't include, which just adds the content of all of the *.inf files from the virtio-win 1.7.4 ISO and directory, to test-data/fake-virtio-win. I didn't include it because it's a big patch that's not very interesting, but you can get it from the repo above. Rich.
Richard W.M. Jones
2015-Nov-17 22:03 UTC
[Libguestfs] [PATCH 1/3] mllib: Add sort_uniq function.
This is copied from supermin. --- mllib/common_utils.ml | 16 ++++++++++++++++ mllib/common_utils.mli | 6 ++++++ 2 files changed, 22 insertions(+) diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml index 13e9256..5fb7183 100644 --- a/mllib/common_utils.ml +++ b/mllib/common_utils.ml @@ -267,6 +267,22 @@ let rec assoc ?(cmp = compare) ~default x = function | (y, y') :: _ when cmp x y = 0 -> y' | _ :: ys -> assoc ~cmp ~default x ys +let uniq ?(cmp = Pervasives.compare) xs + let rec loop acc = function + | [] -> acc + | [x] -> x :: acc + | x :: (y :: _ as xs) when cmp x y = 0 -> + loop acc xs + | x :: (y :: _ as xs) -> + loop (x :: acc) xs + in + List.rev (loop [] xs) + +let sort_uniq ?(cmp = Pervasives.compare) xs + let xs = List.sort cmp xs in + let xs = uniq ~cmp xs in + xs + let may f = function | None -> () | Some x -> f x diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli index 44b8c93..68f7988 100644 --- a/mllib/common_utils.mli +++ b/mllib/common_utils.mli @@ -124,6 +124,12 @@ val assoc : ?cmp:('a -> 'a -> int) -> default:'b -> 'a -> ('a * 'b) list -> 'b (** Like {!List.assoc} but with a user-defined comparison function, and instead of raising [Not_found], it returns the [~default] value. *) +val uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list + (** Uniquify a list (the list must be sorted first). *) + +val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list + (** Sort and uniquify a list. *) + val may : ('a -> unit) -> 'a option -> unit (** [may f (Some x)] runs [f x]. [may f None] does nothing. *) -- 2.5.0
Richard W.M. Jones
2015-Nov-17 22:03 UTC
[Libguestfs] [PATCH 2/3] v2v: windows: Add a Windows '*.inf' file parser.
This simple parser has (limited) understanding of the Windows '*.inf' file format. This is a Windows config file with some peculiarities. This commit also has a unit test. --- po/POTFILES-ml | 1 + v2v/Makefile.am | 5 +- v2v/v2v_unit_tests.ml | 104 +++++++++++++++++++++++++++++++++++- v2v/windows_inf.ml | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++ v2v/windows_inf.mli | 58 ++++++++++++++++++++ 5 files changed, 308 insertions(+), 3 deletions(-) create mode 100644 v2v/windows_inf.ml create mode 100644 v2v/windows_inf.mli diff --git a/po/POTFILES-ml b/po/POTFILES-ml index c02ffc0..88db39b 100644 --- a/po/POTFILES-ml +++ b/po/POTFILES-ml @@ -127,4 +127,5 @@ v2v/v2v.ml v2v/v2v_unit_tests.ml v2v/vCenter.ml v2v/windows.ml +v2v/windows_inf.ml v2v/xml.ml diff --git a/v2v/Makefile.am b/v2v/Makefile.am index 5dfef6e..c46594c 100644 --- a/v2v/Makefile.am +++ b/v2v/Makefile.am @@ -69,6 +69,7 @@ SOURCES_MLI = \ utils.mli \ vCenter.mli \ windows.mli \ + windows_inf.mli \ xml.mli SOURCES_ML = \ @@ -82,8 +83,9 @@ SOURCES_ML = \ DOM.ml \ changeuid.ml \ OVF.ml \ - linux.ml \ + windows_inf.ml \ windows.ml \ + linux.ml \ modules_list.ml \ input_disk.ml \ input_libvirtxml.ml \ @@ -309,6 +311,7 @@ v2v_unit_tests_BOBJECTS = \ utils.cmo \ DOM.cmo \ OVF.cmo \ + windows_inf.cmo \ windows.cmo \ v2v_unit_tests.cmo v2v_unit_tests_XOBJECTS = $(v2v_unit_tests_BOBJECTS:.cmo=.cmx) diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml index a2dca32..169eea9 100644 --- a/v2v/v2v_unit_tests.ml +++ b/v2v/v2v_unit_tests.ml @@ -18,13 +18,21 @@ (* This file tests individual virt-v2v functions. *) +open Printf open OUnit2 + +open Common_utils + open Types -open Printf - external identity : 'a -> 'a = "%identity" +let (//) = Filename.concat + +let srcdir + try Sys.getenv "srcdir" + with Not_found -> failwith "environment variable $srcdir must be set" + let inspect_defaults = { i_type = ""; i_distro = ""; i_arch = ""; i_major_version = 0; i_minor_version = 0; @@ -126,6 +134,97 @@ let test_drive_index ctx assert_raises exn (fun () -> Utils.drive_index "Z"); assert_raises exn (fun () -> Utils.drive_index "aB") +(* Test parsing a [*.inf] file. *) +let test_windows_inf_of_string ctx + let printer = Windows_inf.to_string in + + (* There is nothing special about this choice. It is just a driver + * [*.inf] file picked at random. + *) + let path = srcdir // ".." // "test-data" // "fake-virtio-win" // + "cd" // "Balloon" // "2k12" // "amd64" // "balloon.inf" in + + let sections = Windows_inf.load path in + + let expected = [ + "version", [ + "signature", "\"$WINDOWS NT$\""; + "class", "System"; + "classguid", "{4d36e97d-e325-11ce-bfc1-08002be10318}"; + "provider", "%RHEL%"; + "driverver", "12/04/2014,62.71.104.9600"; + "catalogfile", "Balloon.cat"; + "driverpackagetype", "PlugAndPlay"; + "driverpackagedisplayname", "%BALLOON.DeviceDesc%"; + "pnplockdown", "1"; + ]; + "destinationdirs", [ + "defaultdestdir", "12"; + ]; + "sourcedisksnames", [ + "1", "%DiskId1%,,,\"\""; + ]; + "sourcedisksfiles", [ + "balloon.sys", "1,,"; + ]; + "manufacturer", [ + "%rhel%", "Standard,NTamd64"; + ]; + "standard", [ + "%balloon.devicedesc%", "BALLOON_Device, PCI\\VEN_1AF4&DEV_1002&SUBSYS_00051AF4&REV_00"; + ]; + "standard.ntamd64", [ + "%balloon.devicedesc%", "BALLOON_Device, PCI\\VEN_1AF4&DEV_1002&SUBSYS_00051AF4&REV_00"; + ]; + "balloon_device.nt", [ + "copyfiles", "Drivers_Dir"; + ]; + "drivers_dir", []; + "balloon_device.nt.services", [ + "addservice", "BALLOON,%SPSVCINST_ASSOCSERVICE%, BALLOON_Service_Inst, BALLOON_Logging_Inst"; + ]; + "balloon_service_inst", [ + "displayname", "%BALLOON.SVCDESC%"; + "servicetype", "1"; + "starttype", "3"; + "errorcontrol", "1"; + "servicebinary", "%12%\\balloon.sys"; + ]; + "balloon_logging_inst", [ + "addreg", "BALLOON_Logging_Inst_AddReg"; + ]; + "balloon_logging_inst_addreg", []; + "destinationdirs", [ + "balloon_device_coinstaller_copyfiles", "11"; + ]; + "balloon_device.nt.coinstallers", [ + "addreg", "BALLOON_Device_CoInstaller_AddReg"; + "copyfiles", "BALLOON_Device_CoInstaller_CopyFiles"; + ]; + "balloon_device_coinstaller_addreg", []; + "balloon_device_coinstaller_copyfiles", []; + "sourcedisksfiles", [ + "wdfcoinstaller01011.dll", "1"; + ]; + "balloon_device.nt.wdf", [ + "kmdfservice", "BALLOON, BALLOON_wdfsect"; + ]; + "balloon_wdfsect", [ + "kmdflibraryversion", "1.11"; + ]; + "strings", [ + "spsvcinst_assocservice", "0x00000002"; + "rhel", "\"Red Hat, Inc.\""; + "diskid1", "\"VirtIO Balloon Installation Disk #1\""; + "balloon.devicedesc", "\"VirtIO Balloon Driver\""; + "balloon.svcdesc", "\"VirtIO Balloon Service\""; + "classname", "\"VirtIO Balloon Device\""; + ]; + ] in + + assert_equal ~printer expected sections + +(* Test the code which matches [*.inf] files to Windows guests. *) let test_virtio_iso_path_matches_guest_os ctx (* Windows OSes fake inspection data. *) let make_win name major minor variant arch = { @@ -772,6 +871,7 @@ let suite "OVF.get_ostype" >:: test_get_ostype; "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; ] diff --git a/v2v/windows_inf.ml b/v2v/windows_inf.ml new file mode 100644 index 0000000..2066a2e --- /dev/null +++ b/v2v/windows_inf.ml @@ -0,0 +1,143 @@ +(* virt-v2v + * Copyright (C) 2015 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *) + +open Printf + +open Common_utils + +type t = section list +and section = string * data list +and data = string * string + +let crlf_rex = Str.regexp "\r?\n" + +(* Match [[header]] in a Windows [*.inf] file. *) +let section_header_rex + Str.regexp "^[ \t]*\\[[ \t]*\\(.*\\)[ \t]*\\][ \t]*$" + +let match_section_header line = Str.string_match section_header_rex line 0 +let not_section_header line = not (match_section_header line) + +(* Match [key = value] in a Windows [*.inf] file. *) +let key_value_rex + Str.regexp_case_fold + "^[ \t]*\\([a-z0-9%_.]+\\)[ \t]*=[ \t]*\\(.*\\)[ \t]*$" + +(* Match comment preceeded by whitespace (so comments can be removed). *) +let comment_rex = Str.regexp "[ \t]*;.*" + +(* Parse a Windows [*.inf] file into headers and section lines. *) +let of_string content + (* Split up the inf file (possibly with DOS line endings) into lines. *) + let lines = Str.split crlf_rex content in + + (* Split the file into section headers + section content. *) + let rec loop = function + | [] -> [] + | header :: xs when match_section_header header -> + let header = Str.matched_group 1 header in + let lines = takewhile not_section_header xs in + let ys = dropwhile not_section_header xs in + (header, lines) :: loop ys + | xs -> + (* Put all initial lines before the first section into a + * section with no name. + *) + let lines = takewhile not_section_header xs in + let ys = dropwhile not_section_header xs in + ("", lines) :: loop ys + in + let sections = loop lines in + + (* Split the lines that match "key = value" into [(key, value)] pairs. + * Ignore any other lines. + *) + let sections = List.map ( + fun (header, lines) -> + let lines = filter_map ( + fun line -> + if Str.string_match key_value_rex line 0 then ( + let key = Str.matched_group 1 line in + let value = Str.matched_group 2 line in + Some (key, value) + ) + else None (* ignore the non-matching line *) + ) lines in + header, lines + ) sections in + + (* If the dummy section at the beginning is now completely empty, + * remove it. + *) + let sections + match sections with + | ("", []) :: sections -> sections + | sections -> sections in + + (* Remove any comments from values, conservatively though because + * we don't really understand the value format. + *) + let sections = List.map ( + fun (header, lines) -> + let lines = List.map ( + fun (key, value) -> + let value + if String.contains value '"' then value + else Str.replace_first comment_rex "" value in + key, value + ) lines in + header, lines + ) sections in + + (* Normalize (by lowercasing) the section headers and keys (but not + * the values). + *) + let sections = List.map ( + fun (header, lines) -> + let header = String.lowercase_ascii header in + let lines = List.map ( + fun (key, value) -> + String.lowercase_ascii key, value + ) lines in + header, lines + ) sections in + + sections + +let find_section t section_name + let section_name = String.lowercase_ascii section_name in + List.assoc section_name t + +let find_key t section_name key_name + let data = find_section t section_name in + let key_name = String.lowercase_ascii key_name in + List.assoc key_name data + +let load filename + of_string (read_whole_file filename) + +let rec to_string sections + String.concat "\n" (List.map string_of_section sections) + +and string_of_section (header, body) + let header = sprintf "[%s]" header in + let body = List.map string_of_key_value body in + String.concat "\n" (header :: body) + +and string_of_key_value (key, value) + sprintf "%s = %s" key value diff --git a/v2v/windows_inf.mli b/v2v/windows_inf.mli new file mode 100644 index 0000000..1cb8040 --- /dev/null +++ b/v2v/windows_inf.mli @@ -0,0 +1,58 @@ +(* virt-v2v + * Copyright (C) 2009-2015 Red Hat Inc. + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. + *) + +(** Handle Windows driver [*.inf] files. *) + +type t = section list +(** Type of a parsed Windows driver [*.inf] file. *) + +and section = string * data list +(** A single section consists of a header and a list of lines. If + the file doesn't start with a section header, then the initial + section has a dummy header name [""]. + + The section header is always normalized to lowercase ASCII. *) + +and data = string * string +(** A [key = value] pair appearing within a section body. The key + (but {i not} the value) is always normalized to lowercase ASCII. *) + +val of_string : string -> t +(** Parse an [*.inf] file from the string. No parse errors are + possible since this parser accepts anything as a possible [*.inf] + file. *) + +val load : string -> t +(** Same as {!of_string} except we load the content from + a host file. *) + +val to_string : t -> string +(** Convert an inf file back to a string. This should probably only + be used for debugging, since we don't preserve comments and it's + not tested that Windows would be able to parse what we write out. *) + +val find_section : t -> string -> data list +(** [find_section t section_name] finds and returns a section by name. + + Raises [Not_found] if not found. *) + +val find_key : t -> string -> string -> string +(** [find_key t section_name key_name] finds and returns a key within + a particular section. + + Raises [Not_found] if not found. *) -- 2.5.0
Richard W.M. Jones
2015-Nov-17 22:03 UTC
[Libguestfs] [PATCH 3/3] v2v: windows: Use '*.inf' files to control how Windows drivers are installed.
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
Denis V. Lunev
2015-Nov-18 08:04 UTC
Re: [Libguestfs] [PATCH 0/3] v2v: windows: Use '*.inf' files to control how Windows drivers are installed.
On 11/18/2015 01:03 AM, Richard W.M. Jones wrote:> https://github.com/rwmjones/libguestfs/tree/rewrite-virtio-copy-drivers > > 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 (see > email I sent earlier today). > > There's actually a fourth patch which I didn't include, which just > adds the content of all of the *.inf files from the virtio-win 1.7.4 > ISO and directory, to test-data/fake-virtio-win. I didn't include it > because it's a big patch that's not very interesting, but you can get > it from the repo above. > > Rich. >adding roman to CC:
Denis V. Lunev
2015-Nov-18 08:05 UTC
Re: [Libguestfs] [PATCH 1/3] mllib: Add sort_uniq function.
On 11/18/2015 01:03 AM, Richard W.M. Jones wrote:> This is copied from supermin. > --- > mllib/common_utils.ml | 16 ++++++++++++++++ > mllib/common_utils.mli | 6 ++++++ > 2 files changed, 22 insertions(+) > > diff --git a/mllib/common_utils.ml b/mllib/common_utils.ml > index 13e9256..5fb7183 100644 > --- a/mllib/common_utils.ml > +++ b/mllib/common_utils.ml > @@ -267,6 +267,22 @@ let rec assoc ?(cmp = compare) ~default x = function > | (y, y') :: _ when cmp x y = 0 -> y' > | _ :: ys -> assoc ~cmp ~default x ys > > +let uniq ?(cmp = Pervasives.compare) xs > + let rec loop acc = function > + | [] -> acc > + | [x] -> x :: acc > + | x :: (y :: _ as xs) when cmp x y = 0 -> > + loop acc xs > + | x :: (y :: _ as xs) -> > + loop (x :: acc) xs > + in > + List.rev (loop [] xs) > + > +let sort_uniq ?(cmp = Pervasives.compare) xs > + let xs = List.sort cmp xs in > + let xs = uniq ~cmp xs in > + xs > + > let may f = function > | None -> () > | Some x -> f x > diff --git a/mllib/common_utils.mli b/mllib/common_utils.mli > index 44b8c93..68f7988 100644 > --- a/mllib/common_utils.mli > +++ b/mllib/common_utils.mli > @@ -124,6 +124,12 @@ val assoc : ?cmp:('a -> 'a -> int) -> default:'b -> 'a -> ('a * 'b) list -> 'b > (** Like {!List.assoc} but with a user-defined comparison function, and > instead of raising [Not_found], it returns the [~default] value. *) > > +val uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list > + (** Uniquify a list (the list must be sorted first). *) > + > +val sort_uniq : ?cmp:('a -> 'a -> int) -> 'a list -> 'a list > + (** Sort and uniquify a list. *) > + > val may : ('a -> unit) -> 'a option -> unit > (** [may f (Some x)] runs [f x]. [may f None] does nothing. *) >adding roman to CC:
Denis V. Lunev
2015-Nov-18 08:05 UTC
Re: [Libguestfs] [PATCH 2/3] v2v: windows: Add a Windows '*.inf' file parser.
On 11/18/2015 01:03 AM, Richard W.M. Jones wrote:> This simple parser has (limited) understanding of the Windows '*.inf' > file format. This is a Windows config file with some peculiarities. > > This commit also has a unit test. > --- > po/POTFILES-ml | 1 + > v2v/Makefile.am | 5 +- > v2v/v2v_unit_tests.ml | 104 +++++++++++++++++++++++++++++++++++- > v2v/windows_inf.ml | 143 ++++++++++++++++++++++++++++++++++++++++++++++++++ > v2v/windows_inf.mli | 58 ++++++++++++++++++++ > 5 files changed, 308 insertions(+), 3 deletions(-) > create mode 100644 v2v/windows_inf.ml > create mode 100644 v2v/windows_inf.mli > > diff --git a/po/POTFILES-ml b/po/POTFILES-ml > index c02ffc0..88db39b 100644 > --- a/po/POTFILES-ml > +++ b/po/POTFILES-ml > @@ -127,4 +127,5 @@ v2v/v2v.ml > v2v/v2v_unit_tests.ml > v2v/vCenter.ml > v2v/windows.ml > +v2v/windows_inf.ml > v2v/xml.ml > diff --git a/v2v/Makefile.am b/v2v/Makefile.am > index 5dfef6e..c46594c 100644 > --- a/v2v/Makefile.am > +++ b/v2v/Makefile.am > @@ -69,6 +69,7 @@ SOURCES_MLI = \ > utils.mli \ > vCenter.mli \ > windows.mli \ > + windows_inf.mli \ > xml.mli > > SOURCES_ML = \ > @@ -82,8 +83,9 @@ SOURCES_ML = \ > DOM.ml \ > changeuid.ml \ > OVF.ml \ > - linux.ml \ > + windows_inf.ml \ > windows.ml \ > + linux.ml \ > modules_list.ml \ > input_disk.ml \ > input_libvirtxml.ml \ > @@ -309,6 +311,7 @@ v2v_unit_tests_BOBJECTS = \ > utils.cmo \ > DOM.cmo \ > OVF.cmo \ > + windows_inf.cmo \ > windows.cmo \ > v2v_unit_tests.cmo > v2v_unit_tests_XOBJECTS = $(v2v_unit_tests_BOBJECTS:.cmo=.cmx) > diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml > index a2dca32..169eea9 100644 > --- a/v2v/v2v_unit_tests.ml > +++ b/v2v/v2v_unit_tests.ml > @@ -18,13 +18,21 @@ > > (* This file tests individual virt-v2v functions. *) > > +open Printf > open OUnit2 > + > +open Common_utils > + > open Types > > -open Printf > - > external identity : 'a -> 'a = "%identity" > > +let (//) = Filename.concat > + > +let srcdir > + try Sys.getenv "srcdir" > + with Not_found -> failwith "environment variable $srcdir must be set" > + > let inspect_defaults = { > i_type = ""; i_distro = ""; i_arch = ""; > i_major_version = 0; i_minor_version = 0; > @@ -126,6 +134,97 @@ let test_drive_index ctx > assert_raises exn (fun () -> Utils.drive_index "Z"); > assert_raises exn (fun () -> Utils.drive_index "aB") > > +(* Test parsing a [*.inf] file. *) > +let test_windows_inf_of_string ctx > + let printer = Windows_inf.to_string in > + > + (* There is nothing special about this choice. It is just a driver > + * [*.inf] file picked at random. > + *) > + let path = srcdir // ".." // "test-data" // "fake-virtio-win" // > + "cd" // "Balloon" // "2k12" // "amd64" // "balloon.inf" in > + > + let sections = Windows_inf.load path in > + > + let expected = [ > + "version", [ > + "signature", "\"$WINDOWS NT$\""; > + "class", "System"; > + "classguid", "{4d36e97d-e325-11ce-bfc1-08002be10318}"; > + "provider", "%RHEL%"; > + "driverver", "12/04/2014,62.71.104.9600"; > + "catalogfile", "Balloon.cat"; > + "driverpackagetype", "PlugAndPlay"; > + "driverpackagedisplayname", "%BALLOON.DeviceDesc%"; > + "pnplockdown", "1"; > + ]; > + "destinationdirs", [ > + "defaultdestdir", "12"; > + ]; > + "sourcedisksnames", [ > + "1", "%DiskId1%,,,\"\""; > + ]; > + "sourcedisksfiles", [ > + "balloon.sys", "1,,"; > + ]; > + "manufacturer", [ > + "%rhel%", "Standard,NTamd64"; > + ]; > + "standard", [ > + "%balloon.devicedesc%", "BALLOON_Device, PCI\\VEN_1AF4&DEV_1002&SUBSYS_00051AF4&REV_00"; > + ]; > + "standard.ntamd64", [ > + "%balloon.devicedesc%", "BALLOON_Device, PCI\\VEN_1AF4&DEV_1002&SUBSYS_00051AF4&REV_00"; > + ]; > + "balloon_device.nt", [ > + "copyfiles", "Drivers_Dir"; > + ]; > + "drivers_dir", []; > + "balloon_device.nt.services", [ > + "addservice", "BALLOON,%SPSVCINST_ASSOCSERVICE%, BALLOON_Service_Inst, BALLOON_Logging_Inst"; > + ]; > + "balloon_service_inst", [ > + "displayname", "%BALLOON.SVCDESC%"; > + "servicetype", "1"; > + "starttype", "3"; > + "errorcontrol", "1"; > + "servicebinary", "%12%\\balloon.sys"; > + ]; > + "balloon_logging_inst", [ > + "addreg", "BALLOON_Logging_Inst_AddReg"; > + ]; > + "balloon_logging_inst_addreg", []; > + "destinationdirs", [ > + "balloon_device_coinstaller_copyfiles", "11"; > + ]; > + "balloon_device.nt.coinstallers", [ > + "addreg", "BALLOON_Device_CoInstaller_AddReg"; > + "copyfiles", "BALLOON_Device_CoInstaller_CopyFiles"; > + ]; > + "balloon_device_coinstaller_addreg", []; > + "balloon_device_coinstaller_copyfiles", []; > + "sourcedisksfiles", [ > + "wdfcoinstaller01011.dll", "1"; > + ]; > + "balloon_device.nt.wdf", [ > + "kmdfservice", "BALLOON, BALLOON_wdfsect"; > + ]; > + "balloon_wdfsect", [ > + "kmdflibraryversion", "1.11"; > + ]; > + "strings", [ > + "spsvcinst_assocservice", "0x00000002"; > + "rhel", "\"Red Hat, Inc.\""; > + "diskid1", "\"VirtIO Balloon Installation Disk #1\""; > + "balloon.devicedesc", "\"VirtIO Balloon Driver\""; > + "balloon.svcdesc", "\"VirtIO Balloon Service\""; > + "classname", "\"VirtIO Balloon Device\""; > + ]; > + ] in > + > + assert_equal ~printer expected sections > + > +(* Test the code which matches [*.inf] files to Windows guests. *) > let test_virtio_iso_path_matches_guest_os ctx > (* Windows OSes fake inspection data. *) > let make_win name major minor variant arch = { > @@ -772,6 +871,7 @@ let suite > "OVF.get_ostype" >:: test_get_ostype; > "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; > ] > diff --git a/v2v/windows_inf.ml b/v2v/windows_inf.ml > new file mode 100644 > index 0000000..2066a2e > --- /dev/null > +++ b/v2v/windows_inf.ml > @@ -0,0 +1,143 @@ > +(* virt-v2v > + * Copyright (C) 2015 Red Hat Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + *) > + > +open Printf > + > +open Common_utils > + > +type t = section list > +and section = string * data list > +and data = string * string > + > +let crlf_rex = Str.regexp "\r?\n" > + > +(* Match [[header]] in a Windows [*.inf] file. *) > +let section_header_rex > + Str.regexp "^[ \t]*\\[[ \t]*\\(.*\\)[ \t]*\\][ \t]*$" > + > +let match_section_header line = Str.string_match section_header_rex line 0 > +let not_section_header line = not (match_section_header line) > + > +(* Match [key = value] in a Windows [*.inf] file. *) > +let key_value_rex > + Str.regexp_case_fold > + "^[ \t]*\\([a-z0-9%_.]+\\)[ \t]*=[ \t]*\\(.*\\)[ \t]*$" > + > +(* Match comment preceeded by whitespace (so comments can be removed). *) > +let comment_rex = Str.regexp "[ \t]*;.*" > + > +(* Parse a Windows [*.inf] file into headers and section lines. *) > +let of_string content > + (* Split up the inf file (possibly with DOS line endings) into lines. *) > + let lines = Str.split crlf_rex content in > + > + (* Split the file into section headers + section content. *) > + let rec loop = function > + | [] -> [] > + | header :: xs when match_section_header header -> > + let header = Str.matched_group 1 header in > + let lines = takewhile not_section_header xs in > + let ys = dropwhile not_section_header xs in > + (header, lines) :: loop ys > + | xs -> > + (* Put all initial lines before the first section into a > + * section with no name. > + *) > + let lines = takewhile not_section_header xs in > + let ys = dropwhile not_section_header xs in > + ("", lines) :: loop ys > + in > + let sections = loop lines in > + > + (* Split the lines that match "key = value" into [(key, value)] pairs. > + * Ignore any other lines. > + *) > + let sections = List.map ( > + fun (header, lines) -> > + let lines = filter_map ( > + fun line -> > + if Str.string_match key_value_rex line 0 then ( > + let key = Str.matched_group 1 line in > + let value = Str.matched_group 2 line in > + Some (key, value) > + ) > + else None (* ignore the non-matching line *) > + ) lines in > + header, lines > + ) sections in > + > + (* If the dummy section at the beginning is now completely empty, > + * remove it. > + *) > + let sections > + match sections with > + | ("", []) :: sections -> sections > + | sections -> sections in > + > + (* Remove any comments from values, conservatively though because > + * we don't really understand the value format. > + *) > + let sections = List.map ( > + fun (header, lines) -> > + let lines = List.map ( > + fun (key, value) -> > + let value > + if String.contains value '"' then value > + else Str.replace_first comment_rex "" value in > + key, value > + ) lines in > + header, lines > + ) sections in > + > + (* Normalize (by lowercasing) the section headers and keys (but not > + * the values). > + *) > + let sections = List.map ( > + fun (header, lines) -> > + let header = String.lowercase_ascii header in > + let lines = List.map ( > + fun (key, value) -> > + String.lowercase_ascii key, value > + ) lines in > + header, lines > + ) sections in > + > + sections > + > +let find_section t section_name > + let section_name = String.lowercase_ascii section_name in > + List.assoc section_name t > + > +let find_key t section_name key_name > + let data = find_section t section_name in > + let key_name = String.lowercase_ascii key_name in > + List.assoc key_name data > + > +let load filename > + of_string (read_whole_file filename) > + > +let rec to_string sections > + String.concat "\n" (List.map string_of_section sections) > + > +and string_of_section (header, body) > + let header = sprintf "[%s]" header in > + let body = List.map string_of_key_value body in > + String.concat "\n" (header :: body) > + > +and string_of_key_value (key, value) > + sprintf "%s = %s" key value > diff --git a/v2v/windows_inf.mli b/v2v/windows_inf.mli > new file mode 100644 > index 0000000..1cb8040 > --- /dev/null > +++ b/v2v/windows_inf.mli > @@ -0,0 +1,58 @@ > +(* virt-v2v > + * Copyright (C) 2009-2015 Red Hat Inc. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + * > + * You should have received a copy of the GNU General Public License along > + * with this program; if not, write to the Free Software Foundation, Inc., > + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. > + *) > + > +(** Handle Windows driver [*.inf] files. *) > + > +type t = section list > +(** Type of a parsed Windows driver [*.inf] file. *) > + > +and section = string * data list > +(** A single section consists of a header and a list of lines. If > + the file doesn't start with a section header, then the initial > + section has a dummy header name [""]. > + > + The section header is always normalized to lowercase ASCII. *) > + > +and data = string * string > +(** A [key = value] pair appearing within a section body. The key > + (but {i not} the value) is always normalized to lowercase ASCII. *) > + > +val of_string : string -> t > +(** Parse an [*.inf] file from the string. No parse errors are > + possible since this parser accepts anything as a possible [*.inf] > + file. *) > + > +val load : string -> t > +(** Same as {!of_string} except we load the content from > + a host file. *) > + > +val to_string : t -> string > +(** Convert an inf file back to a string. This should probably only > + be used for debugging, since we don't preserve comments and it's > + not tested that Windows would be able to parse what we write out. *) > + > +val find_section : t -> string -> data list > +(** [find_section t section_name] finds and returns a section by name. > + > + Raises [Not_found] if not found. *) > + > +val find_key : t -> string -> string -> string > +(** [find_key t section_name key_name] finds and returns a key within > + a particular section. > + > + Raises [Not_found] if not found. *)adding roman to CC:
Denis V. Lunev
2015-Nov-18 08:05 UTC
Re: [Libguestfs] [PATCH 3/3] v2v: windows: Use '*.inf' files to control how Windows drivers are installed.
On 11/18/2015 01:03 AM, Richard W.M. Jones wrote:> 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 > endadding roman to CC:
Roman Kagan
2015-Nov-18 18:33 UTC
Re: [Libguestfs] [PATCH 0/3] v2v: windows: Use '*.inf' files to control how Windows drivers are installed.
On Tue, Nov 17, 2015 at 10:03:22PM +0000, Richard W.M. Jones wrote:> 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.I think it's a bit premature at this point. AFAICS at least drivers for 6.0 (2k8) and 6.1 (7, 2k8r2) are identical, while the .cat files are not: the ones for 2k8 have "Server2008X64" in the .cat, while 7/2k8r2 have "7X64,Server2008R2X64" (can be seen with 'openssl asn1parse -in xxx.cat -inform der -i -dump' and digging through the output, and no, I don't know yet if it can be done reliably). So your code is not unlikely to find a driver with a matching .inf but a non-matching .cat. I've no idea how critical this is but I think we need to figure it out first. Roman.
Reasonably Related Threads
- [PATCH v3 4/8] mllib: Add some imperative list manipulation functions.
- [PATCH 1/2] mllib: move remove_duplicates from v2v
- [PATCH v6 04/41] mllib: Split ‘Common_utils’ into ‘Std_utils’ + ‘Common_utils’.
- [PATCH 4/4] mllib, v2v: Allow open_guestfs to set the handle identifier.
- [PATCH] generator: Share Common_utils code.