1
2
3
4
5
6 import logging
7 import _winreg
8
9 from ctypes import windll, POINTER, byref, Structure, pointer
10 from ctypes import c_ushort, c_wchar_p, c_void_p, create_string_buffer
11 from ctypes.wintypes import HANDLE, DWORD, LPCWSTR, ULONG, LONG
12
13 log = logging.getLogger(__name__)
14
16 _fields_ = [
17 ("Length", c_ushort),
18 ("MaximumLength", c_ushort),
19 ("Buffer", c_wchar_p),
20 ]
21
22 RegOpenKeyExW = windll.advapi32.RegOpenKeyExW
23 RegOpenKeyExW.argtypes = HANDLE, LPCWSTR, DWORD, ULONG, POINTER(HANDLE)
24 RegOpenKeyExW.restype = LONG
25
26 RegCreateKeyExW = windll.advapi32.RegCreateKeyExW
27 RegCreateKeyExW.argtypes = (
28 HANDLE, LPCWSTR, DWORD, LPCWSTR, DWORD, DWORD,
29 DWORD, POINTER(HANDLE), POINTER(DWORD),
30 )
31 RegCreateKeyExW.restype = LONG
32
33 RegQueryValueExW = windll.advapi32.RegQueryValueExW
34 RegQueryValueExW.argtypes = \
35 HANDLE, LPCWSTR, POINTER(DWORD), POINTER(DWORD), c_void_p, POINTER(DWORD)
36 RegQueryValueExW.restype = LONG
37
38 RegSetValueExW = windll.advapi32.RegSetValueExW
39 RegSetValueExW.argtypes = HANDLE, LPCWSTR, DWORD, DWORD, c_void_p, DWORD
40 RegSetValueExW.restype = LONG
41
42 NtRenameKey = windll.ntdll.NtRenameKey
43 NtRenameKey.argtypes = HANDLE, POINTER(UNICODE_STRING)
44
45 RegCloseKey = windll.advapi32.RegCloseKey
46 RegCloseKey.argtypes = HANDLE,
47
48 _rootkeys = {
49 "HKEY_LOCAL_MACHINE": _winreg.HKEY_LOCAL_MACHINE,
50 "HKEY_CURRENT_USER": _winreg.HKEY_CURRENT_USER,
51 }
52
53 _regtypes = {
54 "REG_DWORD": _winreg.REG_DWORD,
55 "REG_SZ": _winreg.REG_SZ,
56 "REG_BINARY": _winreg.REG_BINARY,
57 }
58
60 """Rename an entire tree of values in the registry.
61 Function by Thorsten Sick."""
62 res_handle = HANDLE()
63 options = DWORD(0)
64 res = RegOpenKeyExW(
65 skey, ssubkey, options, _winreg.KEY_ALL_ACCESS, byref(res_handle)
66 )
67 if not res:
68 bsize = c_ushort(len(dsubkey) * 2)
69 us = UNICODE_STRING()
70 us.Buffer = c_wchar_p(dsubkey)
71 us.Length = bsize
72 us.MaximumLength = bsize
73
74 res = NtRenameKey(res_handle, pointer(us))
75 if res:
76 log.warning("Error renaming %s\\%s to %s (0x%x)",
77 skey, ssubkey, dsubkey, res % 2**32)
78
79 if res_handle:
80 RegCloseKey(res_handle)
81
83 res_handle = HANDLE()
84 res = RegOpenKeyExW(
85 rootkey, subkey, 0, _winreg.KEY_QUERY_VALUE, byref(res_handle)
86 )
87 RegCloseKey(res_handle)
88 return not res
89
90 -def set_regkey(rootkey, subkey, name, type_, value):
91 if type_ == _winreg.REG_SZ:
92 value = unicode(value)
93 if type_ == _winreg.REG_MULTI_SZ:
94 value = u"\u0000".join(value) + u"\u0000\u0000"
95
96 res_handle = HANDLE()
97 res = RegCreateKeyExW(
98 rootkey, subkey, 0, None, 0, _winreg.KEY_ALL_ACCESS,
99 0, byref(res_handle), None
100 )
101 if not res:
102 RegSetValueExW(res_handle, name, 0, type_, value, len(value))
103 RegCloseKey(res_handle)
104
106 components = regkey.split("\\")
107 rootkey, subkey, name = components[0], components[1:-1], components[-1]
108 if rootkey not in _rootkeys:
109 log.warning("Unknown root key for registry key: %s", rootkey)
110 return
111
112 set_regkey(
113 _rootkeys[rootkey], "\\".join(subkey), name,
114 _regtypes.get(type_, type_), value
115 )
116
118 res_handle = HANDLE()
119 type_ = DWORD()
120 value = create_string_buffer(1024 * 1024)
121 length = DWORD(1024 * 1024)
122
123 res = RegOpenKeyExW(
124 rootkey, subkey, 0, _winreg.KEY_QUERY_VALUE, byref(res_handle)
125 )
126 if not res:
127 res = RegQueryValueExW(
128 res_handle, name, None, byref(type_), value, byref(length)
129 )
130 RegCloseKey(res_handle)
131
132 if not res:
133 if type_.value == _winreg.REG_SZ:
134 return value.raw[:length.value].decode("utf16").rstrip("\x00")
135 if type_.value == _winreg.REG_MULTI_SZ:
136 value = value.raw[:length.value].decode("utf16")
137 return value.rstrip(u"\u0000").split(u"\u0000")
138 return value.raw[:length.value]
139