mercurial/win32.py
changeset 16806 186049f70026
parent 16761 07741a5d6608
child 16807 80142f385af9
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)