Read HKLM\SYSTEM\CurrentControlSet\Control\TimeZoneInformation key "RealTimeIsUniversal" to see if the Windows guest is expecting RTC 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#32556 Reported-by: Lee Garrett Reviewed-by: Laszlo Ersek <ler...@redhat.com> --- 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 7e3aa8d789..34cf341b8e 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 RTC 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 rtc_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 RTC 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 RTC to be set to localtime. + *) + false + ) in + (* Open the software hive (readonly) and find the Xen PV uninstaller, * if it exists. *) @@ -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_rtc_utc = true; + gcaps_rtc_utc = rtc_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> -- 2.41.0 _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs