[PATCH 1 of 3] win32: use Python's _winreg again

Adrian Buehlmann adrian at cadifra.com
Sun May 27 05:35:43 CDT 2012


# HG changeset patch
# User Adrian Buehlmann <adrian at cadifra.com>
# Date 1338110985 -7200
# Node ID f3bcd104db1e8f6e867f40447461f961d59b22fe
# Parent  2ac08d8b21aa7b6e0a062afed5a3f357ccef67f9
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

diff --git a/mercurial/win32.py b/mercurial/win32.py
--- a/mercurial/win32.py
+++ b/mercurial/win32.py
@@ -5,7 +5,8 @@
 # This software may be used and distributed according to the terms of the
 # GNU General Public License version 2 or any later version.
 
-import ctypes, errno, os, struct, subprocess, random
+import encoding
+import ctypes, errno, os, subprocess, random, _winreg
 
 _kernel32 = ctypes.windll.kernel32
 _advapi32 = ctypes.windll.advapi32
@@ -69,13 +70,6 @@
 # GetExitCodeProcess
 _STILL_ACTIVE = 259
 
-# registry
-_HKEY_CURRENT_USER = 0x80000001L
-_HKEY_LOCAL_MACHINE = 0x80000002L
-_KEY_READ = 0x20019
-_REG_SZ = 1
-_REG_DWORD = 4
-
 class _STARTUPINFO(ctypes.Structure):
     _fields_ = [('cb', _DWORD),
                 ('lpReserved', _LPSTR),
@@ -179,17 +173,6 @@
 _kernel32.GetConsoleScreenBufferInfo.argtypes = [_HANDLE, ctypes.c_void_p]
 _kernel32.GetConsoleScreenBufferInfo.restype = _BOOL
 
-_advapi32.RegOpenKeyExA.argtypes = [_HANDLE, _LPCSTR, _DWORD, _DWORD,
-    ctypes.c_void_p]
-_advapi32.RegOpenKeyExA.restype = _LONG
-
-_advapi32.RegQueryValueExA.argtypes = [_HANDLE, _LPCSTR, ctypes.c_void_p,
-    ctypes.c_void_p, ctypes.c_void_p, ctypes.c_void_p]
-_advapi32.RegQueryValueExA.restype = _LONG
-
-_advapi32.RegCloseKey.argtypes = [_HANDLE]
-_advapi32.RegCloseKey.restype = _LONG
-
 _advapi32.GetUserNameA.argtypes = [ctypes.c_void_p, ctypes.c_void_p]
 _advapi32.GetUserNameA.restype = _BOOL
 
@@ -270,33 +253,17 @@
     a sequence of scopes to look up in order. Default (CURRENT_USER,
     LOCAL_MACHINE).
     '''
-    byref = ctypes.byref
     if scope is None:
-        scope = (_HKEY_CURRENT_USER, _HKEY_LOCAL_MACHINE)
+        scope = (_winreg.HKEY_CURRENT_USER, _winreg.HKEY_LOCAL_MACHINE)
     elif not isinstance(scope, (list, tuple)):
         scope = (scope,)
     for s in scope:
-        kh = _HANDLE()
-        res = _advapi32.RegOpenKeyExA(s, key, 0, _KEY_READ, ctypes.byref(kh))
-        if res != _ERROR_SUCCESS:
-            continue
         try:
-            size = _DWORD(600)
-            type = _DWORD()
-            buf = ctypes.create_string_buffer(size.value + 1)
-            res = _advapi32.RegQueryValueExA(kh.value, valname, None,
-                                       byref(type), buf, byref(size))
-            if res != _ERROR_SUCCESS:
-                continue
-            if type.value == _REG_SZ:
-                # string is in ANSI code page, aka local encoding
-                return buf.value
-            elif type.value == _REG_DWORD:
-                fmt = '<L'
-                s = ctypes.string_at(byref(buf), struct.calcsize(fmt))
-                return struct.unpack(fmt, s)[0]
-        finally:
-            _advapi32.RegCloseKey(kh.value)
+            val = _winreg.QueryValueEx(_winreg.OpenKey(s, key), valname)[0]
+            # never let a Unicode string escape into the wild
+            return encoding.tolocal(val.encode('UTF-8'))
+        except EnvironmentError:
+            pass
 
 def executablepath():
     '''return full path of hg.exe'''


More information about the Mercurial-devel mailing list