eggs/mercurial-1.7.3-py2.6-linux-x86_64.egg/mercurial/win32.py
changeset 69 c6bca38c1cbf
equal deleted inserted replaced
68:5ff1fc726848 69:c6bca38c1cbf
       
     1 # win32.py - utility functions that use win32 API
       
     2 #
       
     3 # Copyright 2005-2009 Matt Mackall <mpm@selenic.com> and others
       
     4 #
       
     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.
       
     7 
       
     8 """Utility functions that use win32 API.
       
     9 
       
    10 Mark Hammond's win32all package allows better functionality on
       
    11 Windows. This module overrides definitions in util.py. If not
       
    12 available, import of this module will fail, and generic code will be
       
    13 used.
       
    14 """
       
    15 
       
    16 import win32api
       
    17 
       
    18 import errno, os, sys, pywintypes, win32con, win32file, win32process
       
    19 import winerror, win32gui, win32console
       
    20 import osutil, encoding
       
    21 from win32com.shell import shell, shellcon
       
    22 
       
    23 def os_link(src, dst):
       
    24     try:
       
    25         win32file.CreateHardLink(dst, src)
       
    26     except pywintypes.error:
       
    27         raise OSError(errno.EINVAL, 'target implements hardlinks improperly')
       
    28     except NotImplementedError: # Another fake error win Win98
       
    29         raise OSError(errno.EINVAL, 'Hardlinking not supported')
       
    30 
       
    31 def _getfileinfo(pathname):
       
    32     """Return number of hardlinks for the given file."""
       
    33     try:
       
    34         fh = win32file.CreateFile(pathname,
       
    35             win32file.GENERIC_READ, win32file.FILE_SHARE_READ,
       
    36             None, win32file.OPEN_EXISTING, 0, None)
       
    37     except pywintypes.error:
       
    38         raise OSError(errno.ENOENT, 'The system cannot find the file specified')
       
    39     try:
       
    40         return win32file.GetFileInformationByHandle(fh)
       
    41     finally:
       
    42         fh.Close()
       
    43 
       
    44 def nlinks(pathname):
       
    45     """Return number of hardlinks for the given file."""
       
    46     return _getfileinfo(pathname)[7]
       
    47 
       
    48 def samefile(fpath1, fpath2):
       
    49     """Returns whether fpath1 and fpath2 refer to the same file. This is only
       
    50     guaranteed to work for files, not directories."""
       
    51     res1 = _getfileinfo(fpath1)
       
    52     res2 = _getfileinfo(fpath2)
       
    53     # Index 4 is the volume serial number, and 8 and 9 contain the file ID
       
    54     return res1[4] == res2[4] and res1[8] == res2[8] and res1[9] == res2[9]
       
    55 
       
    56 def samedevice(fpath1, fpath2):
       
    57     """Returns whether fpath1 and fpath2 are on the same device. This is only
       
    58     guaranteed to work for files, not directories."""
       
    59     res1 = _getfileinfo(fpath1)
       
    60     res2 = _getfileinfo(fpath2)
       
    61     return res1[4] == res2[4]
       
    62 
       
    63 def testpid(pid):
       
    64     '''return True if pid is still running or unable to
       
    65     determine, False otherwise'''
       
    66     try:
       
    67         handle = win32api.OpenProcess(
       
    68             win32con.PROCESS_QUERY_INFORMATION, False, pid)
       
    69         if handle:
       
    70             status = win32process.GetExitCodeProcess(handle)
       
    71             return status == win32con.STILL_ACTIVE
       
    72     except pywintypes.error, details:
       
    73         return details[0] != winerror.ERROR_INVALID_PARAMETER
       
    74     return True
       
    75 
       
    76 def lookup_reg(key, valname=None, scope=None):
       
    77     ''' Look up a key/value name in the Windows registry.
       
    78 
       
    79     valname: value name. If unspecified, the default value for the key
       
    80     is used.
       
    81     scope: optionally specify scope for registry lookup, this can be
       
    82     a sequence of scopes to look up in order. Default (CURRENT_USER,
       
    83     LOCAL_MACHINE).
       
    84     '''
       
    85     try:
       
    86         from _winreg import HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE, \
       
    87             QueryValueEx, OpenKey
       
    88     except ImportError:
       
    89         return None
       
    90 
       
    91     if scope is None:
       
    92         scope = (HKEY_CURRENT_USER, HKEY_LOCAL_MACHINE)
       
    93     elif not isinstance(scope, (list, tuple)):
       
    94         scope = (scope,)
       
    95     for s in scope:
       
    96         try:
       
    97             val = QueryValueEx(OpenKey(s, key), valname)[0]
       
    98             # never let a Unicode string escape into the wild
       
    99             return encoding.tolocal(val.encode('UTF-8'))
       
   100         except EnvironmentError:
       
   101             pass
       
   102 
       
   103 def system_rcpath_win32():
       
   104     '''return default os-specific hgrc search path'''
       
   105     filename = win32api.GetModuleFileName(0)
       
   106     # Use mercurial.ini found in directory with hg.exe
       
   107     progrc = os.path.join(os.path.dirname(filename), 'mercurial.ini')
       
   108     if os.path.isfile(progrc):
       
   109         return [progrc]
       
   110     # Use hgrc.d found in directory with hg.exe
       
   111     progrcd = os.path.join(os.path.dirname(filename), 'hgrc.d')
       
   112     if os.path.isdir(progrcd):
       
   113         rcpath = []
       
   114         for f, kind in osutil.listdir(progrcd):
       
   115             if f.endswith('.rc'):
       
   116                 rcpath.append(os.path.join(progrcd, f))
       
   117         return rcpath
       
   118     # else look for a system rcpath in the registry
       
   119     try:
       
   120         value = win32api.RegQueryValue(
       
   121                 win32con.HKEY_LOCAL_MACHINE, 'SOFTWARE\\Mercurial')
       
   122         rcpath = []
       
   123         for p in value.split(os.pathsep):
       
   124             if p.lower().endswith('mercurial.ini'):
       
   125                 rcpath.append(p)
       
   126             elif os.path.isdir(p):
       
   127                 for f, kind in osutil.listdir(p):
       
   128                     if f.endswith('.rc'):
       
   129                         rcpath.append(os.path.join(p, f))
       
   130         return rcpath
       
   131     except pywintypes.error:
       
   132         return []
       
   133 
       
   134 def user_rcpath_win32():
       
   135     '''return os-specific hgrc search path to the user dir'''
       
   136     userdir = os.path.expanduser('~')
       
   137     if sys.getwindowsversion()[3] != 2 and userdir == '~':
       
   138         # We are on win < nt: fetch the APPDATA directory location and use
       
   139         # the parent directory as the user home dir.
       
   140         appdir = shell.SHGetPathFromIDList(
       
   141             shell.SHGetSpecialFolderLocation(0, shellcon.CSIDL_APPDATA))
       
   142         userdir = os.path.dirname(appdir)
       
   143     return [os.path.join(userdir, 'mercurial.ini'),
       
   144             os.path.join(userdir, '.hgrc')]
       
   145 
       
   146 def getuser():
       
   147     '''return name of current user'''
       
   148     return win32api.GetUserName()
       
   149 
       
   150 def set_signal_handler_win32():
       
   151     """Register a termination handler for console events including
       
   152     CTRL+C. python signal handlers do not work well with socket
       
   153     operations.
       
   154     """
       
   155     def handler(event):
       
   156         win32process.ExitProcess(1)
       
   157     win32api.SetConsoleCtrlHandler(handler)
       
   158 
       
   159 def hidewindow():
       
   160     def callback(*args, **kwargs):
       
   161         hwnd, pid = args
       
   162         wpid = win32process.GetWindowThreadProcessId(hwnd)[1]
       
   163         if pid == wpid:
       
   164             win32gui.ShowWindow(hwnd, win32con.SW_HIDE)
       
   165 
       
   166     pid =  win32process.GetCurrentProcessId()
       
   167     win32gui.EnumWindows(callback, pid)
       
   168 
       
   169 def termwidth():
       
   170     try:
       
   171         # Query stderr to avoid problems with redirections
       
   172         screenbuf = win32console.GetStdHandle(win32console.STD_ERROR_HANDLE)
       
   173         try:
       
   174             window = screenbuf.GetConsoleScreenBufferInfo()['Window']
       
   175             width = window.Right - window.Left
       
   176             return width
       
   177         finally:
       
   178             screenbuf.Detach()
       
   179     except pywintypes.error:
       
   180         return 79