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)