Mercurial > public > mercurial-scm > hg
comparison mercurial/win32.py @ 16806:186049f70026
win32: use Python's _winreg again
This is a partial backout of f1fa8f481c7c.
f1fa8f481c7c switched win32.py to using ctypes with the intention to get rid
of the dependency on the pywin32 package.
But f1fa8f481c7c replaced the usage of the Python standard module _winreg in
lookup_reg as well, which was uneeded (note that lookup_reg was later renamed
into lookupreg).
Basically, we're switching back to the previous _winreg-based implementation,
which uses _winreg.QueryValueEx(). QueryValueEx returns a unicode code string.
See also: issue3467
author | Adrian Buehlmann <adrian@cadifra.com> |
---|---|
date | Sun, 27 May 2012 11:29:45 +0200 |
parents | 07741a5d6608 |
children | 80142f385af9 |
comparison
equal
deleted
inserted
replaced
16804:a455a18bfdac | 16806:186049f70026 |
---|---|
3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others | 3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others |
4 # | 4 # |
5 # This software may be used and distributed according to the terms of the | 5 # This software may be used and distributed according to the terms of the |
6 # GNU General Public License version 2 or any later version. | 6 # GNU General Public License version 2 or any later version. |
7 | 7 |
8 import ctypes, errno, os, struct, subprocess, random | 8 import encoding |
9 import ctypes, errno, os, subprocess, random, _winreg | |
9 | 10 |
10 _kernel32 = ctypes.windll.kernel32 | 11 _kernel32 = ctypes.windll.kernel32 |
11 _advapi32 = ctypes.windll.advapi32 | 12 _advapi32 = ctypes.windll.advapi32 |
12 _user32 = ctypes.windll.user32 | 13 _user32 = ctypes.windll.user32 |
13 | 14 |
66 # Process Security and Access Rights | 67 # Process Security and Access Rights |
67 _PROCESS_QUERY_INFORMATION = 0x0400 | 68 _PROCESS_QUERY_INFORMATION = 0x0400 |
68 | 69 |
69 # GetExitCodeProcess | 70 # GetExitCodeProcess |
70 _STILL_ACTIVE = 259 | 71 _STILL_ACTIVE = 259 |
71 | |
72 # registry | |
73 _HKEY_CURRENT_USER = 0x80000001L | |
74 _HKEY_LOCAL_MACHINE = 0x80000002L | |
75 _KEY_READ = 0x20019 | |
76 _REG_SZ = 1 | |
77 _REG_DWORD = 4 | |
78 | 72 |
79 class _STARTUPINFO(ctypes.Structure): | 73 class _STARTUPINFO(ctypes.Structure): |
80 _fields_ = [('cb', _DWORD), | 74 _fields_ = [('cb', _DWORD), |
81 ('lpReserved', _LPSTR), | 75 ('lpReserved', _LPSTR), |
82 ('lpDesktop', _LPSTR), | 76 ('lpDesktop', _LPSTR), |
177 _kernel32.GetStdHandle.restype = _HANDLE | 171 _kernel32.GetStdHandle.restype = _HANDLE |
178 | 172 |
179 _kernel32.GetConsoleScreenBufferInfo.argtypes = [_HANDLE, ctypes.c_void_p] | 173 _kernel32.GetConsoleScreenBufferInfo.argtypes = [_HANDLE, ctypes.c_void_p] |
180 _kernel32.GetConsoleScreenBufferInfo.restype = _BOOL | 174 _kernel32.GetConsoleScreenBufferInfo.restype = _BOOL |
181 | 175 |
182 _advapi32.RegOpenKeyExA.argtypes = [_HANDLE, _LPCSTR, _DWORD, _DWORD, | |
183 ctypes.c_void_p] | |
184 _advapi32.RegOpenKeyExA.restype = _LONG | |
185 | |
186 _advapi32.RegQueryValueExA.argtypes = [_HANDLE, _LPCSTR, ctypes.c_void_p, | |
187 ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p] | |
188 _advapi32.RegQueryValueExA.restype = _LONG | |
189 | |
190 _advapi32.RegCloseKey.argtypes = [_HANDLE] | |
191 _advapi32.RegCloseKey.restype = _LONG | |
192 | |
193 _advapi32.GetUserNameA.argtypes = [ctypes.c_void_p, ctypes.c_void_p] | 176 _advapi32.GetUserNameA.argtypes = [ctypes.c_void_p, ctypes.c_void_p] |
194 _advapi32.GetUserNameA.restype = _BOOL | 177 _advapi32.GetUserNameA.restype = _BOOL |
195 | 178 |
196 _user32.GetWindowThreadProcessId.argtypes = [_HANDLE, ctypes.c_void_p] | 179 _user32.GetWindowThreadProcessId.argtypes = [_HANDLE, ctypes.c_void_p] |
197 _user32.GetWindowThreadProcessId.restype = _DWORD | 180 _user32.GetWindowThreadProcessId.restype = _DWORD |
268 is used. | 251 is used. |
269 scope: optionally specify scope for registry lookup, this can be | 252 scope: optionally specify scope for registry lookup, this can be |
270 a sequence of scopes to look up in order. Default (CURRENT_USER, | 253 a sequence of scopes to look up in order. Default (CURRENT_USER, |
271 LOCAL_MACHINE). | 254 LOCAL_MACHINE). |
272 ''' | 255 ''' |
273 byref = ctypes.byref | |
274 if scope is None: | 256 if scope is None: |
275 scope = (_HKEY_CURRENT_USER, _HKEY_LOCAL_MACHINE) | 257 scope = (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE) |
276 elif not isinstance(scope, (list, tuple)): | 258 elif not isinstance(scope, (list, tuple)): |
277 scope = (scope,) | 259 scope = (scope,) |
278 for s in scope: | 260 for s in scope: |
279 kh = _HANDLE() | |
280 res = _advapi32.RegOpenKeyExA(s, key, 0, _KEY_READ, ctypes.byref(kh)) | |
281 if res != _ERROR_SUCCESS: | |
282 continue | |
283 try: | 261 try: |
284 size = _DWORD(600) | 262 val = _winreg.QueryValueEx(_winreg.OpenKey(s, key), valname)[0] |
285 type = _DWORD() | 263 # never let a Unicode string escape into the wild |
286 buf = ctypes.create_string_buffer(size.value + 1) | 264 return encoding.tolocal(val.encode('UTF-8')) |
287 res = _advapi32.RegQueryValueExA(kh.value, valname, None, | 265 except EnvironmentError: |
288 byref(type), buf, byref(size)) | 266 pass |
289 if res != _ERROR_SUCCESS: | |
290 continue | |
291 if type.value == _REG_SZ: | |
292 # string is in ANSI code page, aka local encoding | |
293 return buf.value | |
294 elif type.value == _REG_DWORD: | |
295 fmt = '<L' | |
296 s = ctypes.string_at(byref(buf), struct.calcsize(fmt)) | |
297 return struct.unpack(fmt, s)[0] | |
298 finally: | |
299 _advapi32.RegCloseKey(kh.value) | |
300 | 267 |
301 def executablepath(): | 268 def executablepath(): |
302 '''return full path of hg.exe''' | 269 '''return full path of hg.exe''' |
303 size = 600 | 270 size = 600 |
304 buf = ctypes.create_string_buffer(size + 1) | 271 buf = ctypes.create_string_buffer(size + 1) |