[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.
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
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:
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
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:
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
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 end adding roman to CC:
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:
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.
participants (3)
-
Denis V. Lunev -
Richard W.M. Jones -
Roman Kagan