[PATCH 0/2] Reset the graphics mode in UEFI BCD
Guest tools for Windows in Parallels / Virtuozzo Server 6 contain a paravirtualized video driver, which wants to take full control of the video mode. To avoid excessive video mode switches in UEFI VMs it executes "bcdedit /set {current} graphicsmodedisabled true". When such a VM is imported into a QEMU/KVM-based hypervisor, the standard video drivers in Windows do not set the video mode as they expect it to have already been configured by the bootloader. As a result, the VM runs with black screen. To solve this issue, we need to try to lead the BCD to the default state. Pavel Butsykin (2): v2v: fill the list of the EFI system partitions v2v: remove the 'graphicsmodedisabled' entry in ESP BCD v2v/convert_linux.ml | 2 +- v2v/convert_windows.ml | 41 +++++++++++++++++++++++++++++++++++++++++ v2v/inspect_source.ml | 29 +++++++++++++++++++++-------- v2v/types.ml | 4 ++-- v2v/types.mli | 3 ++- v2v/v2v.ml | 2 +- v2v/v2v_unit_tests.ml | 2 +- 7 files changed, 69 insertions(+), 14 deletions(-) -- 2.8.3
Store the list of EFI system partitions on the inspect object in order to be able to tune their contents later in the process. Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> --- v2v/convert_linux.ml | 2 +- v2v/inspect_source.ml | 29 +++++++++++++++++++++-------- v2v/types.ml | 4 ++-- v2v/types.mli | 3 ++- v2v/v2v.ml | 2 +- v2v/v2v_unit_tests.ml | 2 +- 6 files changed, 28 insertions(+), 14 deletions(-) diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml index 08b27d6..2de5e42 100644 --- a/v2v/convert_linux.ml +++ b/v2v/convert_linux.ml @@ -97,7 +97,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps = "/boot/grub/grub.conf", `Grub1; ] in let locations = - if inspect.i_uefi then + if inspect.i_uefi <> None then ("/boot/efi/EFI/redhat/grub.cfg", `Grub2) :: locations else locations in diff --git a/v2v/inspect_source.ml b/v2v/inspect_source.ml index 65dcb88..7a7674a 100644 --- a/v2v/inspect_source.ml +++ b/v2v/inspect_source.ml @@ -68,7 +68,7 @@ let rec inspect_source root_choice g = (* See if this guest could use UEFI to boot. It should use GPT and * it should have an EFI System Partition (ESP). *) - let uefi = has_uefi_bootable_device g in + let uefi = get_uefi_bootable_device g in let inspect = { i_root = root; @@ -153,10 +153,12 @@ and reject_if_not_installed_image g root = if fmt <> "installed" then error (f_"libguestfs thinks this is not an installed operating system (it might be, for example, an installer disk or live CD). If this is wrong, it is probably a bug in libguestfs. root=%s fmt=%s") root fmt -and has_uefi_bootable_device g = +and get_uefi_bootable_device g = let rec uefi_ESP_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" and is_uefi_ESP dev { G.part_num = partnum } = g#part_get_gpt_type dev (Int32.to_int partnum) = uefi_ESP_guid + and part_dev_name dev { G.part_num = partnum } = + sprintf "%s%d" dev (Int32.to_int partnum) and parttype_is_gpt dev = try g#part_get_parttype dev = "gpt" with G.Error msg as exn -> @@ -164,14 +166,25 @@ and has_uefi_bootable_device g = if g#last_errno () <> G.Errno.errno_EINVAL then raise exn; debug "%s (ignored)" msg; false - and is_uefi_bootable_device dev = - parttype_is_gpt dev && ( - let partitions = Array.to_list (g#part_list dev) in - List.exists (is_uefi_ESP dev) partitions - ) + and is_uefi_bootable_part dev part = + parttype_is_gpt dev && is_uefi_ESP dev part in let devices = Array.to_list (g#list_devices ()) in - List.exists is_uefi_bootable_device devices + let uefi_list = ref [] in + + List.iter ( + fun dev -> + Array.iter ( + fun part -> + if (is_uefi_bootable_part dev part) then ( + uefi_list := (part_dev_name dev part) :: !uefi_list + ) + ) (g#part_list dev) + ) devices; + + match !uefi_list with + | [] -> None + | list -> Some list (* If some inspection fields are "unknown", then that indicates a * failure in inspection, and we shouldn't continue. For an example diff --git a/v2v/types.ml b/v2v/types.ml index 08e1631..7f8a9b3 100644 --- a/v2v/types.ml +++ b/v2v/types.ml @@ -315,7 +315,7 @@ type inspect = { i_mountpoints : (string * string) list; i_apps : Guestfs.application2 list; i_apps_map : Guestfs.application2 list StringMap.t; - i_uefi : bool; + i_uefi : string list option; } let string_of_inspect inspect = @@ -341,7 +341,7 @@ i_uefi = %b inspect.i_package_management inspect.i_product_name inspect.i_product_variant - inspect.i_uefi + (inspect.i_uefi <> None) type mpstat = { mp_dev : string; diff --git a/v2v/types.mli b/v2v/types.mli index dacc991..a0a8399 100644 --- a/v2v/types.mli +++ b/v2v/types.mli @@ -221,7 +221,8 @@ type inspect = { (** This is a map from the app name to the application object. Since RPM allows multiple packages with the same name to be installed, the value is a list. *) - i_uefi : bool; (** True if the guest could boot with UEFI. *) + i_uefi : string list option; + (** Some list if the guest could boot with UEFI. *) } (** Inspection information. *) diff --git a/v2v/v2v.ml b/v2v/v2v.ml index fe81df5..2527633 100644 --- a/v2v/v2v.ml +++ b/v2v/v2v.ml @@ -555,7 +555,7 @@ and get_target_firmware inspect guestcaps source output = | BIOS -> TargetBIOS | UEFI -> TargetUEFI | UnknownFirmware -> - if inspect.i_uefi then TargetUEFI else TargetBIOS in + if inspect.i_uefi = None then TargetBIOS else TargetUEFI in let supported_firmware = output#supported_firmware in if not (List.mem target_firmware supported_firmware) then error (f_"this guest cannot run on the target, because the target does not support %s firmware (supported firmware on target: %s)") diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml index 95d8430..874cd48 100644 --- a/v2v/v2v_unit_tests.ml +++ b/v2v/v2v_unit_tests.ml @@ -30,7 +30,7 @@ let inspect_defaults = { i_major_version = 0; i_minor_version = 0; i_root = ""; i_package_format = ""; i_package_management = ""; i_product_name = ""; i_product_variant = ""; i_mountpoints = []; - i_apps = []; i_apps_map = StringMap.empty; i_uefi = false + i_apps = []; i_apps_map = StringMap.empty; i_uefi = None } let test_get_ostype ctx = -- 2.8.3
On Fri, Jun 10, 2016 at 05:07:02PM +0300, Pavel Butsykin wrote:
Store the list of EFI system partitions on the inspect object in order to be able to tune their contents later in the process.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> --- v2v/convert_linux.ml | 2 +- v2v/inspect_source.ml | 29 +++++++++++++++++++++-------- v2v/types.ml | 4 ++-- v2v/types.mli | 3 ++- v2v/v2v.ml | 2 +- v2v/v2v_unit_tests.ml | 2 +- 6 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml index 08b27d6..2de5e42 100644 --- a/v2v/convert_linux.ml +++ b/v2v/convert_linux.ml @@ -97,7 +97,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps = "/boot/grub/grub.conf", `Grub1; ] in let locations = - if inspect.i_uefi then + if inspect.i_uefi <> None then ("/boot/efi/EFI/redhat/grub.cfg", `Grub2) :: locations else locations in diff --git a/v2v/inspect_source.ml b/v2v/inspect_source.ml index 65dcb88..7a7674a 100644 --- a/v2v/inspect_source.ml +++ b/v2v/inspect_source.ml @@ -68,7 +68,7 @@ let rec inspect_source root_choice g = (* See if this guest could use UEFI to boot. It should use GPT and * it should have an EFI System Partition (ESP). *) - let uefi = has_uefi_bootable_device g in + let uefi = get_uefi_bootable_device g in
let inspect = { i_root = root; @@ -153,10 +153,12 @@ and reject_if_not_installed_image g root = if fmt <> "installed" then error (f_"libguestfs thinks this is not an installed operating system (it might be, for example, an installer disk or live CD). If this is wrong, it is probably a bug in libguestfs. root=%s fmt=%s") root fmt
-and has_uefi_bootable_device g = +and get_uefi_bootable_device g = let rec uefi_ESP_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" and is_uefi_ESP dev { G.part_num = partnum } = g#part_get_gpt_type dev (Int32.to_int partnum) = uefi_ESP_guid + and part_dev_name dev { G.part_num = partnum } = + sprintf "%s%d" dev (Int32.to_int partnum) and parttype_is_gpt dev = try g#part_get_parttype dev = "gpt" with G.Error msg as exn -> @@ -164,14 +166,25 @@ and has_uefi_bootable_device g = if g#last_errno () <> G.Errno.errno_EINVAL then raise exn; debug "%s (ignored)" msg; false - and is_uefi_bootable_device dev = - parttype_is_gpt dev && ( - let partitions = Array.to_list (g#part_list dev) in - List.exists (is_uefi_ESP dev) partitions - ) + and is_uefi_bootable_part dev part = + parttype_is_gpt dev && is_uefi_ESP dev part in let devices = Array.to_list (g#list_devices ()) in - List.exists is_uefi_bootable_device devices + let uefi_list = ref [] in + + List.iter ( + fun dev -> + Array.iter ( + fun part -> + if (is_uefi_bootable_part dev part) then ( + uefi_list := (part_dev_name dev part) :: !uefi_list + ) + ) (g#part_list dev) + ) devices; + + match !uefi_list with + | [] -> None + | list -> Some list
(* If some inspection fields are "unknown", then that indicates a * failure in inspection, and we shouldn't continue. For an example diff --git a/v2v/types.ml b/v2v/types.ml index 08e1631..7f8a9b3 100644 --- a/v2v/types.ml +++ b/v2v/types.ml @@ -315,7 +315,7 @@ type inspect = { i_mountpoints : (string * string) list; i_apps : Guestfs.application2 list; i_apps_map : Guestfs.application2 list StringMap.t; - i_uefi : bool; + i_uefi : string list option;
I think what you really want is for the type to be "string list" (not option), and for empty list to mean BIOS. (Assuming that UEFI cannot have zero system partitions -- as far as I understand UEFI, that's true). Alternately you could write something like: type i_firmware = | BIOS | UEFI of string list ... i_firmware : i_firmware; which is quite nice, I think, because it's explicit about the meaning.
}
let string_of_inspect inspect = @@ -341,7 +341,7 @@ i_uefi = %b inspect.i_package_management inspect.i_product_name inspect.i_product_variant - inspect.i_uefi + (inspect.i_uefi <> None)
We should print the list here, so: "...i_uefi = [%s]" ... (String.concat ", " inspect.i_uefi) or if using the i_firmware type above: "...i_firmware = %s" ... (match inspect.i_firmware with | BIOS -> "BIOS" | UEFI devices -> sprintf "UEFI [%s]" (String.concat ", " devices) )
type mpstat = { mp_dev : string; diff --git a/v2v/types.mli b/v2v/types.mli index dacc991..a0a8399 100644 --- a/v2v/types.mli +++ b/v2v/types.mli @@ -221,7 +221,8 @@ type inspect = { (** This is a map from the app name to the application object. Since RPM allows multiple packages with the same name to be installed, the value is a list. *) - i_uefi : bool; (** True if the guest could boot with UEFI. *) + i_uefi : string list option; + (** Some list if the guest could boot with UEFI. *)
This comment needs to document what are the strings in this list.
} (** Inspection information. *)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml index fe81df5..2527633 100644 --- a/v2v/v2v.ml +++ b/v2v/v2v.ml @@ -555,7 +555,7 @@ and get_target_firmware inspect guestcaps source output = | BIOS -> TargetBIOS | UEFI -> TargetUEFI | UnknownFirmware -> - if inspect.i_uefi then TargetUEFI else TargetBIOS in + if inspect.i_uefi = None then TargetBIOS else TargetUEFI in let supported_firmware = output#supported_firmware in if not (List.mem target_firmware supported_firmware) then error (f_"this guest cannot run on the target, because the target does not support %s firmware (supported firmware on target: %s)") diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml index 95d8430..874cd48 100644 --- a/v2v/v2v_unit_tests.ml +++ b/v2v/v2v_unit_tests.ml @@ -30,7 +30,7 @@ let inspect_defaults = { i_major_version = 0; i_minor_version = 0; i_root = ""; i_package_format = ""; i_package_management = ""; i_product_name = ""; i_product_variant = ""; i_mountpoints = []; - i_apps = []; i_apps_map = StringMap.empty; i_uefi = false + i_apps = []; i_apps_map = StringMap.empty; i_uefi = None }
Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com Fedora Windows cross-compiler. Compile Windows programs, test, and build Windows installers. Over 100 libraries supported. http://fedoraproject.org/wiki/MinGW
On 10.06.2016 18:02, Richard W.M. Jones wrote:
On Fri, Jun 10, 2016 at 05:07:02PM +0300, Pavel Butsykin wrote:
Store the list of EFI system partitions on the inspect object in order to be able to tune their contents later in the process.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> --- v2v/convert_linux.ml | 2 +- v2v/inspect_source.ml | 29 +++++++++++++++++++++-------- v2v/types.ml | 4 ++-- v2v/types.mli | 3 ++- v2v/v2v.ml | 2 +- v2v/v2v_unit_tests.ml | 2 +- 6 files changed, 28 insertions(+), 14 deletions(-)
diff --git a/v2v/convert_linux.ml b/v2v/convert_linux.ml index 08b27d6..2de5e42 100644 --- a/v2v/convert_linux.ml +++ b/v2v/convert_linux.ml @@ -97,7 +97,7 @@ let rec convert ~keep_serial_console (g : G.guestfs) inspect source rcaps = "/boot/grub/grub.conf", `Grub1; ] in let locations = - if inspect.i_uefi then + if inspect.i_uefi <> None then ("/boot/efi/EFI/redhat/grub.cfg", `Grub2) :: locations else locations in diff --git a/v2v/inspect_source.ml b/v2v/inspect_source.ml index 65dcb88..7a7674a 100644 --- a/v2v/inspect_source.ml +++ b/v2v/inspect_source.ml @@ -68,7 +68,7 @@ let rec inspect_source root_choice g = (* See if this guest could use UEFI to boot. It should use GPT and * it should have an EFI System Partition (ESP). *) - let uefi = has_uefi_bootable_device g in + let uefi = get_uefi_bootable_device g in
let inspect = { i_root = root; @@ -153,10 +153,12 @@ and reject_if_not_installed_image g root = if fmt <> "installed" then error (f_"libguestfs thinks this is not an installed operating system (it might be, for example, an installer disk or live CD). If this is wrong, it is probably a bug in libguestfs. root=%s fmt=%s") root fmt
-and has_uefi_bootable_device g = +and get_uefi_bootable_device g = let rec uefi_ESP_guid = "C12A7328-F81F-11D2-BA4B-00A0C93EC93B" and is_uefi_ESP dev { G.part_num = partnum } = g#part_get_gpt_type dev (Int32.to_int partnum) = uefi_ESP_guid + and part_dev_name dev { G.part_num = partnum } = + sprintf "%s%d" dev (Int32.to_int partnum) and parttype_is_gpt dev = try g#part_get_parttype dev = "gpt" with G.Error msg as exn -> @@ -164,14 +166,25 @@ and has_uefi_bootable_device g = if g#last_errno () <> G.Errno.errno_EINVAL then raise exn; debug "%s (ignored)" msg; false - and is_uefi_bootable_device dev = - parttype_is_gpt dev && ( - let partitions = Array.to_list (g#part_list dev) in - List.exists (is_uefi_ESP dev) partitions - ) + and is_uefi_bootable_part dev part = + parttype_is_gpt dev && is_uefi_ESP dev part in let devices = Array.to_list (g#list_devices ()) in - List.exists is_uefi_bootable_device devices + let uefi_list = ref [] in + + List.iter ( + fun dev -> + Array.iter ( + fun part -> + if (is_uefi_bootable_part dev part) then ( + uefi_list := (part_dev_name dev part) :: !uefi_list + ) + ) (g#part_list dev) + ) devices; + + match !uefi_list with + | [] -> None + | list -> Some list
(* If some inspection fields are "unknown", then that indicates a * failure in inspection, and we shouldn't continue. For an example diff --git a/v2v/types.ml b/v2v/types.ml index 08e1631..7f8a9b3 100644 --- a/v2v/types.ml +++ b/v2v/types.ml @@ -315,7 +315,7 @@ type inspect = { i_mountpoints : (string * string) list; i_apps : Guestfs.application2 list; i_apps_map : Guestfs.application2 list StringMap.t; - i_uefi : bool; + i_uefi : string list option;
I think what you really want is for the type to be "string list" (not option), and for empty list to mean BIOS. (Assuming that UEFI cannot have zero system partitions -- as far as I understand UEFI, that's true).
I really wanted to use just "string list", but then I was confused by the abundance of "list option" :)
Alternately you could write something like:
type i_firmware = | BIOS | UEFI of string list
... i_firmware : i_firmware;
which is quite nice, I think, because it's explicit about the meaning.
}
let string_of_inspect inspect = @@ -341,7 +341,7 @@ i_uefi = %b inspect.i_package_management inspect.i_product_name inspect.i_product_variant - inspect.i_uefi + (inspect.i_uefi <> None)
We should print the list here, so:
"...i_uefi = [%s]" ... (String.concat ", " inspect.i_uefi)
or if using the i_firmware type above:
"...i_firmware = %s" ... (match inspect.i_firmware with | BIOS -> "BIOS" | UEFI devices -> sprintf "UEFI [%s]" (String.concat ", " devices) )
type mpstat = { mp_dev : string; diff --git a/v2v/types.mli b/v2v/types.mli index dacc991..a0a8399 100644 --- a/v2v/types.mli +++ b/v2v/types.mli @@ -221,7 +221,8 @@ type inspect = { (** This is a map from the app name to the application object. Since RPM allows multiple packages with the same name to be installed, the value is a list. *) - i_uefi : bool; (** True if the guest could boot with UEFI. *) + i_uefi : string list option; + (** Some list if the guest could boot with UEFI. *)
This comment needs to document what are the strings in this list.
} (** Inspection information. *)
diff --git a/v2v/v2v.ml b/v2v/v2v.ml index fe81df5..2527633 100644 --- a/v2v/v2v.ml +++ b/v2v/v2v.ml @@ -555,7 +555,7 @@ and get_target_firmware inspect guestcaps source output = | BIOS -> TargetBIOS | UEFI -> TargetUEFI | UnknownFirmware -> - if inspect.i_uefi then TargetUEFI else TargetBIOS in + if inspect.i_uefi = None then TargetBIOS else TargetUEFI in let supported_firmware = output#supported_firmware in if not (List.mem target_firmware supported_firmware) then error (f_"this guest cannot run on the target, because the target does not support %s firmware (supported firmware on target: %s)") diff --git a/v2v/v2v_unit_tests.ml b/v2v/v2v_unit_tests.ml index 95d8430..874cd48 100644 --- a/v2v/v2v_unit_tests.ml +++ b/v2v/v2v_unit_tests.ml @@ -30,7 +30,7 @@ let inspect_defaults = { i_major_version = 0; i_minor_version = 0; i_root = ""; i_package_format = ""; i_package_management = ""; i_product_name = ""; i_product_variant = ""; i_mountpoints = []; - i_apps = []; i_apps_map = StringMap.empty; i_uefi = false + i_apps = []; i_apps_map = StringMap.empty; i_uefi = None }
Rich.
Thanks for the good explanation!
Guest tools for Windows in Parallels / Virtuozzo Server 6 contain a paravirtualized video driver, which wants to take full control of the video mode. To avoid excessive video mode switches in UEFI VMs it executes "bcdedit /set {current} graphicsmodedisabled true". When such a VM is imported into a QEMU/KVM-based hypervisor, the standard video drivers in Windows do not set the video mode as they expect it to have already been configured by the bootloader. As a result, the VM runs with black screen. So patch the BCD store (which is a Windows registry hive with a special structure, located on the EFI system partition) to clear this setting. Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> --- v2v/convert_windows.ml | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml index 62bb536..8579240 100644 --- a/v2v/convert_windows.ml +++ b/v2v/convert_windows.ml @@ -466,6 +466,45 @@ if errorlevel 3010 exit /b 0 ignore (g#pwrite_device rootpart bytes 0x1a_L) ) ) + + and fix_win_esp () = + let fix_win_uefi_bcd esp_path = + try + let bcd_path = "/EFI/Microsoft/Boot/BCD" in + Windows.with_hive_write g (esp_path ^ bcd_path) ( + (* Remove the 'graphicsmodedisabled' key in BCD *) + fun root -> + let path = ["Objects"; "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"; + "Elements"; "23000003"] in + let boot_mgr_default_link = + match Windows.get_node g root path with + | None -> raise Not_found + | Some node -> node in + let current_boot_entry = g#hivex_value_utf8 ( + g#hivex_node_get_value boot_mgr_default_link "Element") in + let path = ["Objects"; current_boot_entry; "Elements"; "16000046"] in + match Windows.get_node g root path with + | None -> raise Not_found + | Some graphics_mode_disabled -> + g#hivex_node_delete_child graphics_mode_disabled + ); + with + Not_found -> () + in + + let esp_temp_path = g#mkdtemp "/Windows/Temp/ESP_XXXXXX" in + + match inspect.i_uefi with + | None -> () + | Some uefi_list -> + List.iter ( + fun dev_path -> + g#mount dev_path esp_temp_path; + fix_win_uefi_bcd esp_temp_path; + g#umount esp_temp_path; + ) uefi_list; + + g#rmdir esp_temp_path; in (* Firstboot configuration. *) @@ -480,6 +519,8 @@ if errorlevel 3010 exit /b 0 fix_ntfs_heads (); + fix_win_esp (); + (* Warn if installation of virtio block drivers might conflict with * group policy or AV software causing a boot 0x7B error (RHBZ#1260689). *) -- 2.8.3
On Fri, Jun 10, 2016 at 05:07:03PM +0300, Pavel Butsykin wrote:
Guest tools for Windows in Parallels / Virtuozzo Server 6 contain a paravirtualized video driver, which wants to take full control of the video mode. To avoid excessive video mode switches in UEFI VMs it executes "bcdedit /set {current} graphicsmodedisabled true".
When such a VM is imported into a QEMU/KVM-based hypervisor, the standard video drivers in Windows do not set the video mode as they expect it to have already been configured by the bootloader. As a result, the VM runs with black screen.
So patch the BCD store (which is a Windows registry hive with a special structure, located on the EFI system partition) to clear this setting.
Signed-off-by: Pavel Butsykin <pbutsykin@virtuozzo.com> --- v2v/convert_windows.ml | 41 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
diff --git a/v2v/convert_windows.ml b/v2v/convert_windows.ml index 62bb536..8579240 100644 --- a/v2v/convert_windows.ml +++ b/v2v/convert_windows.ml @@ -466,6 +466,45 @@ if errorlevel 3010 exit /b 0 ignore (g#pwrite_device rootpart bytes 0x1a_L) ) ) + + and fix_win_esp () = + let fix_win_uefi_bcd esp_path = + try + let bcd_path = "/EFI/Microsoft/Boot/BCD" in + Windows.with_hive_write g (esp_path ^ bcd_path) ( + (* Remove the 'graphicsmodedisabled' key in BCD *) + fun root -> + let path = ["Objects"; "{9dea862c-5cdd-4e70-acc1-f32b344d4795}"; + "Elements"; "23000003"] in + let boot_mgr_default_link = + match Windows.get_node g root path with + | None -> raise Not_found + | Some node -> node in + let current_boot_entry = g#hivex_value_utf8 ( + g#hivex_node_get_value boot_mgr_default_link "Element") in + let path = ["Objects"; current_boot_entry; "Elements"; "16000046"] in + match Windows.get_node g root path with + | None -> raise Not_found + | Some graphics_mode_disabled -> + g#hivex_node_delete_child graphics_mode_disabled + ); + with + Not_found -> () + in + + let esp_temp_path = g#mkdtemp "/Windows/Temp/ESP_XXXXXX" in + + match inspect.i_uefi with + | None -> () + | Some uefi_list -> + List.iter ( + fun dev_path -> + g#mount dev_path esp_temp_path; + fix_win_uefi_bcd esp_temp_path; + g#umount esp_temp_path; + ) uefi_list; + + g#rmdir esp_temp_path; in
(* Firstboot configuration. *) @@ -480,6 +519,8 @@ if errorlevel 3010 exit /b 0
fix_ntfs_heads ();
+ fix_win_esp (); +
This patch looks OK to me. Thanks, Rich. -- Richard Jones, Virtualization Group, Red Hat http://people.redhat.com/~rjones Read my programming and virtualization blog: http://rwmj.wordpress.com virt-df lists disk usage of guests without needing to install any software inside the virtual machine. Supports Linux and Windows. http://people.redhat.com/~rjones/virt-df/
participants (2)
-
Pavel Butsykin -
Richard W.M. Jones