+ def _enable_os_monitor(self):
+ """Add a script in the registry that will send a random string to the
+ first serial port when the windows image finishes booting.
+ """
+
+ token = "".join(random.choice(string.ascii_letters) for x in range(16))
+
+ path = self._registry_file_path('SOFTWARE')
+ softwarefd, software = tempfile.mkstemp()
+ try:
+ os.close(softwarefd)
+ self.image.g.download(path, software)
+
+ h = hivex.Hivex(software, write=True)
+
+ # Enable automatic logon.
+ # This is needed because we need to execute a script that we add in
+ # the RunOnce registry entry and those programs only get executed
+ # when a user logs on. There is a RunServicesOnce registry entry
+ # whose keys get executed in the background when the logon dialog
+ # box first appears, but they seem to only work with services and
+ # not arbitrary command line expressions :-(
+ #
+ # Instructions on how to turn on automatic logon in Windows can be
+ # found here: http://support.microsoft.com/kb/324737
+ #
+ # Warning: Registry change will not work if the “Logon Banner” is
+ # defined on the server either by a Group Policy object (GPO) or by
+ # a local policy.
+
+ winlogon = h.root()
+ for child in ('Microsoft', 'Windows NT', 'CurrentVersion',
+ 'Winlogon'):
+ winlogon = h.node_get_child(winlogon, child)
+
+ h.node_set_value(
+ winlogon,
+ {'key': 'DefaultUserName', 't': 1,
+ 'value': "Administrator".encode('utf-16le')})
+ h.node_set_value(
+ winlogon,
+ {'key': 'DefaultPassword', 't': 1,
+ 'value': self.sysprep_params['password'].encode('utf-16le')})
+ h.node_set_value(
+ winlogon,
+ {'key': 'AutoAdminLogon', 't': 1,
+ 'value': "1".encode('utf-16le')})
+
+ key = h.root()
+ for child in ('Microsoft', 'Windows', 'CurrentVersion'):
+ key = h.node_get_child(key, child)
+
+ runonce = h.node_get_child(key, "RunOnce")
+ if runonce is None:
+ runonce = h.node_add_child(key, "RunOnce")
+
+ value = (
+ r'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe '
+ r'-ExecutionPolicy RemoteSigned '
+ r'"&{$port=new-Object System.IO.Ports.SerialPort COM1,9600,'
+ r'None,8,one;$port.open();$port.WriteLine(\"' + token + r'\");'
+ r'$port.Close()}"').encode('utf-16le')
+
+ h.node_set_value(runonce,
+ {'key': "BootMonitor", 't': 1, 'value': value})
+
+ value = (
+ r'REG ADD HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion'
+ r'\policies\system /v LocalAccountTokenFilterPolicy'
+ r' /t REG_DWORD /d 1 /f').encode('utf-16le')
+
+ h.node_set_value(runonce,
+ {'key': "UpdateRegistry", 't': 1, 'value': value})
+
+ h.commit(None)
+
+ self.image.g.upload(software, path)
+ finally:
+ os.unlink(software)
+
+ return token
+
+ def _update_firewalls(self, domain, public, standard):
+ """Enables or disables the firewall for the Domain, the Public and the
+ Standard profile. Returns a triplete with the old values.
+
+ 1 will enable a firewall and 0 will disable it
+ """
+
+ if domain not in (0, 1):
+ raise ValueError("Valid values for domain parameter are 0 and 1")
+
+ if public not in (0, 1):
+ raise ValueError("Valid values for public parameter are 0 and 1")
+
+ if standard not in (0, 1):
+ raise ValueError("Valid values for standard parameter are 0 and 1")
+
+ path = self._registry_file_path("SYSTEM")
+ systemfd, system = tempfile.mkstemp()
+ try:
+ os.close(systemfd)
+ self.image.g.download(path, system)
+
+ h = hivex.Hivex(system, write=True)
+
+ select = h.node_get_child(h.root(), 'Select')
+ current_value = h.node_get_value(select, 'Current')
+
+ # expecting a little endian dword
+ assert h.value_type(current_value)[1] == 4
+ current = "%03d" % h.value_dword(current_value)
+
+ firewall_policy = h.root()
+ for child in ('ControlSet%s' % current, 'services', 'SharedAccess',
+ 'Parameters', 'FirewallPolicy'):
+ firewall_policy = h.node_get_child(firewall_policy, child)
+
+ old_values = []
+ new_values = [domain, public, standard]
+ for profile in ('Domain', 'Public', 'Standard'):
+ node = h.node_get_child(firewall_policy, '%sProfile' % profile)
+
+ old_value = h.node_get_value(node, 'EnableFirewall')
+
+ # expecting a little endian dword
+ assert h.value_type(old_value)[1] == 4
+ old_values.append(h.value_dword(old_value))
+
+ h.node_set_value(
+ node, {'key': 'EnableFirewall', 't': 4L,
+ 'value': struct.pack("<I", new_values.pop(0))})
+
+ h.commit(None)
+ self.image.g.upload(system, path)
+
+ finally:
+ os.unlink(system)
+
+ return old_values
+