From adbf02d170701d418ea47b73b442183bb2131099 Mon Sep 17 00:00:00 2001 From: Alejandro Sirgo Rica Date: Thu, 25 Jul 2024 16:34:35 +0200 Subject: utils: add set_windows_hostname Add function to redefine the hostname of a Windows install. Windows hostnames can't be larger than 15 characters due to legacy heritage. Hostname modification is done by modifying 3 registry values in the ControlSetXXX entry of the SYSTEM hive. ControlSet001 is generally the entry to be edited but one must query the value of the 'Current' key in the 'Select' entry of the SYSTEM hive to retrieve the active ControlSet. The hostname has to be introduced in the following entries: path = 'ControlSetXX/Control/ComputerName/ComputerName' key = 'ComputerName' path = 'ControlSetXXX/Services/Tcpip/Parameters' key = 'HostName' key = 'NV Hostname' The value to store in those keys is of tipe SZ and has to be encoded in UCS-2 Little Endian (utf-16-le). --- src/utils/postinstall.py | 47 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 47 insertions(+) diff --git a/src/utils/postinstall.py b/src/utils/postinstall.py index f6332b0..7fef437 100644 --- a/src/utils/postinstall.py +++ b/src/utils/postinstall.py @@ -22,6 +22,50 @@ from socket import gethostname CONFIGUREOS_LEGACY_ENABLED = False +def set_windows_hostname(disk, partition, name): + logging.info(f'Configuring hostname') + + if len(name) > 15: + logging.warning(f'Windows does nor permit hostnames that exceed 15 characters. Truncating {name}') + name = name[0:15] + + byte_name = name.encode(WINDOWS_HIVE_ENCODING) + + device = get_partition_device(disk, partition) + mountpoint = device.replace('dev', 'mnt') + + if not mount_mkdir(device, mountpoint): + raise OgError(f'Unable to mount {device} into {mountpoint}') + + try: + hive_path = mountpoint + WINDOWS_HIVE_SYSTEM + hive = hive_handler_open(hive_path, write=True) + root = hive.root() + + select_node = get_node_child_from_path(hive, root, 'Select') + current_control_set_number = get_value_from_node(hive, select_node, 'Current') + + control_set = f'ControlSet{current_control_set_number:03}' + + computer_name_node = get_node_child_from_path(hive, root, f'{control_set}/Control/ComputerName/ComputerName') + name_value = {'key': 'ComputerName', 't': RegistryType.SZ.value, 'value': byte_name} + hive.node_set_value(computer_name_node, name_value) + + parameters_node = get_node_child_from_path(hive, root, f'{control_set}/Services/Tcpip/Parameters') + + hostname_value = {'key': 'HostName', 't': RegistryType.SZ.value, 'value': byte_name} + hive.node_set_value(parameters_node, hostname_value) + + nvhostname_value = {'key': 'NV Hostname', 't': RegistryType.SZ.value, 'value': byte_name} + hive.node_set_value(parameters_node, nvhostname_value) + + hive.commit(hive_path) + except Exception as e: + raise OgError(f'Unable to configure Windows hostname: {e}') from e + finally: + umount(mountpoint) + + def configure_os_custom(disk, partition): if not shutil.which('configureOsCustom'): raise OgError('configureOsCustom not found') @@ -115,6 +159,9 @@ def configure_os_linux(disk, partition): def configure_os_windows(disk, partition): + hostname = gethostname() + set_windows_hostname(disk, partition, hostname) + if is_uefi_supported(): restore_windows_efi_bootloader(disk, partition) -- cgit v1.2.3-18-g5258