On Mon, Sep 25, 2023 at 05:58:00PM +0200, Laszlo Ersek wrote:
On 9/25/23 16:04, Richard W.M. Jones wrote:
> Read HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation key
> "RealTimeIsUniversal" to see if the Windows guest is expecting BIOS
> set to localtime (not present) or UTC (present and set to 1).
>
> See:
https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows
> See:
https://listman.redhat.com/archives/libguestfs/2023-September/thread.html...
> Reported-by: Lee Garrett
> ---
> convert/convert_windows.ml | 38 +++++++++++++++++++++++++++++++++++++-
> tests/test-v2v-i-ova.xml | 2 +-
> 2 files changed, 38 insertions(+), 2 deletions(-)
>
> diff --git a/convert/convert_windows.ml b/convert/convert_windows.ml
> index f6e039be7e..84e8f7b7d3 100644
> --- a/convert/convert_windows.ml
> +++ b/convert/convert_windows.ml
> @@ -103,6 +103,42 @@ let convert (g : G.guestfs) _ inspect i_firmware block_driver _
static_ips =
> (* If the Windows guest has AV installed. *)
> let has_antivirus = Windows.detect_antivirus inspect in
>
> + (* Does the guest expect the BIOS to be set to UTC or localtime?
> + * See
https://wiki.archlinux.org/title/System_time#UTC_in_Microsoft_Windows
> + * Note this might be a QWORD on 64 bit Windows instances.
> + *)
> + let bios_utc =
> + Registry.with_hive_readonly g inspect.i_windows_system_hive
> + (fun reg ->
> + try
> + let key_path = [ "Control"; "TimeZoneInformation" ]
in
> + let path = inspect.i_windows_current_control_set :: key_path in
> + let node =
> + match Registry.get_node reg path with
> + | None -> raise Not_found
> + | Some node -> node in
> + let valueh = g#hivex_node_get_value node "RealTimeIsUniversal"
in
> + if valueh = 0L then raise Not_found;
> + let t = g#hivex_value_type valueh in
> + let data = g#hivex_value_value valueh in
> + let is_utc =
> + match t with
> + | 0_L (* REG_NONE *) -> false (* localtime *)
> + | 4_L (* REG_DWORD *) -> data = "\001\000\000\000"
> + | 11_L (* REG_QWORD *) -> data =
"\001\000\000\000\000\000\000\000"
> + | _ (* who knows ... *) ->
> + warning (f_"unknown CurrentControlSet\\Control\\\
> + TimeZoneInformation key RealTimeIsUniversal \
> + type 0x%Lx, assuming BIOS set to UTC") t;
> + true in
[*]
> + is_utc
> + with Not_found ->
> + (* If the key is not found then by default we assume
> + * that Windows is expecting the BIOS to be set to localtime.
> + *)
> + false
> + ) in
> +
> (* Open the software hive (readonly) and find the Xen PV uninstaller,
> * if it exists.
> *)
[*] Just guessing, but I'm not sure if assuming UTC is right when the
key is found but its type is unrecognized, in light of determining
localtime when the key is absent or has type REG_NONE.
Either way, the warning is honest about it!
I don't know - I would need to examine lots of Windows machines to
find out what they really do. But I expect that this field only ever
contains dword:1 or hex(b):1 [qword:1], or is absent.
> @@ -275,7 +311,7 @@ let convert (g : G.guestfs) _ inspect
i_firmware block_driver _ static_ips =
> gcaps_arch = Utils.kvm_arch inspect.i_arch;
> gcaps_arch_min_version = 0;
> gcaps_virtio_1_0 = virtio_win_installed.Inject_virtio_win.virtio_1_0;
> - gcaps_bios_utc = true;
> + gcaps_bios_utc = bios_utc;
> } in
>
> guestcaps
> diff --git a/tests/test-v2v-i-ova.xml b/tests/test-v2v-i-ova.xml
> index a41827bfd5..fa7b4dbfc5 100644
> --- a/tests/test-v2v-i-ova.xml
> +++ b/tests/test-v2v-i-ova.xml
> @@ -18,7 +18,7 @@
> <os>
> <type arch='x86_64' machine='q35'>hvm</type>
> </os>
> - <clock offset='utc'/>
> + <clock offset='localtime'/>
> <on_poweroff>destroy</on_poweroff>
> <on_reboot>restart</on_reboot>
> <on_crash>restart</on_crash>
With the BIOS -> RTC typo (?) fixed everywhere:
series
Reviewed-by: Laszlo Ersek <lersek(a)redhat.com>
Thanks, I'll post v2 anyway since I've written it now.
Rich.
--
Richard Jones, Virtualization Group, Red Hat
http://people.redhat.com/~rjones
Read my programming and virtualization blog:
http://rwmj.wordpress.com
libguestfs lets you edit virtual machines. Supports shell scripting,
bindings from many languages.
http://libguestfs.org