/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar

« back to all changes in this revision

Viewing changes to bzrlib/win32utils.py

Merge bzr.dev, update to use new hooks.

Show diffs side-by-side

added added

removed removed

Lines of Context:
25
25
import sys
26
26
 
27
27
from bzrlib import cmdline
 
28
from bzrlib.i18n import gettext
28
29
 
29
30
# Windows version
30
31
if sys.platform == 'win32':
67
68
        create_buffer = ctypes.create_unicode_buffer
68
69
        suffix = 'W'
69
70
try:
70
 
    import win32file
71
71
    import pywintypes
72
 
    has_win32file = True
73
 
except ImportError:
74
 
    has_win32file = False
75
 
try:
76
 
    import win32api
77
 
    has_win32api = True
78
 
except ImportError:
79
 
    has_win32api = False
 
72
    has_pywintypes = True
 
73
except ImportError:
 
74
    has_pywintypes = has_win32file = has_win32api = False
 
75
else:
 
76
    try:
 
77
        import win32file
 
78
        has_win32file = True
 
79
    except ImportError:
 
80
        has_win32file = False
 
81
    try:
 
82
        import win32api
 
83
        has_win32api = True
 
84
    except ImportError:
 
85
        has_win32api = False
80
86
 
81
87
# pulling in win32com.shell is a bit of overhead, and normally we don't need
82
88
# it as ctypes is preferred and common.  lazy_imports and "optional"
128
134
            ctypes.byref(mem_struct),
129
135
            ctypes.sizeof(mem_struct))
130
136
        if not ret:
131
 
            trace.note('Failed to GetProcessMemoryInfo()')
 
137
            trace.note(gettext('Failed to GetProcessMemoryInfo()'))
132
138
            return
133
139
        info = {'PageFaultCount': mem_struct.PageFaultCount,
134
140
                'PeakWorkingSetSize': mem_struct.PeakWorkingSetSize,
149
155
        proc = win32process.GetCurrentProcess()
150
156
        info = win32process.GetProcessMemoryInfo(proc)
151
157
    else:
152
 
        trace.note('Cannot debug memory on win32 without ctypes'
153
 
                   ' or win32process')
 
158
        trace.note(gettext('Cannot debug memory on win32 without ctypes'
 
159
                   ' or win32process'))
154
160
        return
155
161
    if short:
156
162
        # using base-2 units (see HACKING.txt).
157
 
        trace.note('WorkingSize %7dKiB'
158
 
                   '\tPeakWorking %7dKiB\t%s',
 
163
        trace.note(gettext('WorkingSize {0:>7}KiB'
 
164
                   '\tPeakWorking {1:>7}KiB\t{2}').format(
159
165
                   info['WorkingSetSize'] / 1024,
160
166
                   info['PeakWorkingSetSize'] / 1024,
161
 
                   message)
 
167
                   message))
162
168
        return
163
169
    if message:
164
170
        trace.note('%s', message)
165
 
    trace.note('WorkingSize       %8d KiB', info['WorkingSetSize'] / 1024)
166
 
    trace.note('PeakWorking       %8d KiB', info['PeakWorkingSetSize'] / 1024)
167
 
    trace.note('PagefileUsage     %8d KiB', info.get('PagefileUsage', 0) / 1024)
168
 
    trace.note('PeakPagefileUsage %8d KiB',
 
171
    trace.note(gettext('WorkingSize       %8d KiB'), info['WorkingSetSize'] / 1024)
 
172
    trace.note(gettext('PeakWorking       %8d KiB'), info['PeakWorkingSetSize'] / 1024)
 
173
    trace.note(gettext('PagefileUsage     %8d KiB'), info.get('PagefileUsage', 0) / 1024)
 
174
    trace.note(gettext('PeakPagefileUsage %8d KiB'),
169
175
               info.get('PeakPagefileUsage', 0) / 1024)
170
 
    trace.note('PrivateUsage      %8d KiB', info.get('PrivateUsage', 0) / 1024)
171
 
    trace.note('PageFaultCount    %8d', info.get('PageFaultCount', 0))
 
176
    trace.note(gettext('PrivateUsage      %8d KiB'), info.get('PrivateUsage', 0) / 1024)
 
177
    trace.note(gettext('PageFaultCount    %8d'), info.get('PageFaultCount', 0))
172
178
 
173
179
 
174
180
def get_console_size(defaultx=80, defaulty=25):
468
474
 
469
475
 
470
476
def get_app_path(appname):
471
 
    """Look up in Windows registry for full path to application executable.
 
477
    r"""Look up in Windows registry for full path to application executable.
472
478
    Typically, applications create subkey with their basename
473
479
    in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\
474
480
 
522
528
            trace.mutter('Unable to set hidden attribute on %r: %s', path, e)
523
529
 
524
530
 
525
 
def _command_line_to_argv(command_line, single_quotes_allowed=False):
 
531
def _command_line_to_argv(command_line, argv, single_quotes_allowed=False):
526
532
    """Convert a Unicode command line into a list of argv arguments.
527
533
 
528
534
    It performs wildcard expansion to make wildcards act closer to how they
535
541
                                  default.
536
542
    :return: A list of unicode strings.
537
543
    """
 
544
    # First, spit the command line
538
545
    s = cmdline.Splitter(command_line, single_quotes_allowed=single_quotes_allowed)
539
 
    # Now that we've split the content, expand globs if necessary
 
546
    
 
547
    # Bug #587868 Now make sure that the length of s agrees with sys.argv 
 
548
    # we do this by simply counting the number of arguments in each. The counts should 
 
549
    # agree no matter what encoding sys.argv is in (AFAIK) 
 
550
    # len(arguments) < len(sys.argv) should be an impossibility since python gets 
 
551
    # args from the very same PEB as does GetCommandLineW
 
552
    arguments = list(s)
 
553
    
 
554
    # Now shorten the command line we get from GetCommandLineW to match sys.argv
 
555
    if len(arguments) < len(argv):
 
556
        raise AssertionError("Split command line can't be shorter than argv")
 
557
    arguments = arguments[len(arguments) - len(argv):]
 
558
    
 
559
    # Carry on to process globs (metachars) in the command line
 
560
    # expand globs if necessary
540
561
    # TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
541
562
    #       '**/' style globs
542
563
    args = []
543
 
    for is_quoted, arg in s:
 
564
    for is_quoted, arg in arguments:
544
565
        if is_quoted or not glob.has_magic(arg):
545
566
            args.append(arg)
546
567
        else:
548
569
    return args
549
570
 
550
571
 
551
 
if has_ctypes and winver != 'Windows 98':
 
572
if has_ctypes and winver == 'Windows NT':
552
573
    def get_unicode_argv():
553
574
        prototype = ctypes.WINFUNCTYPE(ctypes.c_wchar_p)
554
575
        GetCommandLineW = prototype(("GetCommandLineW",
557
578
        if command_line is None:
558
579
            raise ctypes.WinError()
559
580
        # Skip the first argument, since we only care about parameters
560
 
        argv = _command_line_to_argv(command_line)[1:]
561
 
        if getattr(sys, 'frozen', None) is None:
562
 
            # Invoked via 'python.exe' which takes the form:
563
 
            #   python.exe [PYTHON_OPTIONS] C:\Path\bzr [BZR_OPTIONS]
564
 
            # we need to get only BZR_OPTIONS part,
565
 
            # We already removed 'python.exe' so we remove everything up to and
566
 
            # including the first non-option ('-') argument.
567
 
            for idx in xrange(len(argv)):
568
 
                if argv[idx][:1] != '-':
569
 
                    break
570
 
            argv = argv[idx+1:]
 
581
        argv = _command_line_to_argv(command_line, sys.argv)[1:]
571
582
        return argv
 
583
    
 
584
 
 
585
    def get_environ_unicode(key, default=None):
 
586
        """Get `key` from environment as unicode or `default` if unset
 
587
 
 
588
        A large enough buffer will be allocated to retrieve the value, though
 
589
        it may take two calls to the underlying library function.
 
590
 
 
591
        This needs ctypes because pywin32 does not expose the wide version.
 
592
        """
 
593
        cfunc = getattr(get_environ_unicode, "_c_function", None)
 
594
        if cfunc is None:
 
595
            from ctypes.wintypes import DWORD, LPCWSTR, LPWSTR
 
596
            cfunc = ctypes.WINFUNCTYPE(DWORD, LPCWSTR, LPWSTR, DWORD)(
 
597
                ("GetEnvironmentVariableW", ctypes.windll.kernel32))
 
598
            get_environ_unicode._c_function = cfunc
 
599
        buffer_size = 256 # heuristic, 256 characters often enough
 
600
        while True:
 
601
            buffer = ctypes.create_unicode_buffer(buffer_size)
 
602
            length = cfunc(key, buffer, buffer_size)
 
603
            if not length:
 
604
                code = ctypes.GetLastError()
 
605
                if code == 203: # ERROR_ENVVAR_NOT_FOUND
 
606
                    return default
 
607
                raise ctypes.WinError(code)
 
608
            if buffer_size > length:
 
609
                return buffer[:length]
 
610
            buffer_size = length
572
611
else:
573
 
    get_unicode_argv = None
 
612
    get_unicode_argv = get_environ_unicode = None
 
613
 
 
614
 
 
615
if has_win32api:
 
616
    def _pywin32_is_local_pid_dead(pid):
 
617
        """True if pid doesn't correspond to live process on this machine"""
 
618
        try:
 
619
            handle = win32api.OpenProcess(1, False, pid) # PROCESS_TERMINATE
 
620
        except pywintypes.error, e:
 
621
            if e[0] == 5: # ERROR_ACCESS_DENIED
 
622
                # Probably something alive we're not allowed to kill
 
623
                return False
 
624
            elif e[0] == 87: # ERROR_INVALID_PARAMETER
 
625
                return True
 
626
            raise
 
627
        handle.close()
 
628
        return False
 
629
    is_local_pid_dead = _pywin32_is_local_pid_dead
 
630
elif has_ctypes and sys.platform == 'win32':
 
631
    from ctypes.wintypes import BOOL, DWORD, HANDLE
 
632
    _kernel32 = ctypes.windll.kernel32
 
633
    _CloseHandle = ctypes.WINFUNCTYPE(BOOL, HANDLE)(
 
634
        ("CloseHandle", _kernel32))
 
635
    _OpenProcess = ctypes.WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)(
 
636
        ("OpenProcess", _kernel32))
 
637
    def _ctypes_is_local_pid_dead(pid):
 
638
        """True if pid doesn't correspond to live process on this machine"""
 
639
        handle = _OpenProcess(1, False, pid) # PROCESS_TERMINATE
 
640
        if not handle:
 
641
            errorcode = ctypes.GetLastError()
 
642
            if errorcode == 5: # ERROR_ACCESS_DENIED
 
643
                # Probably something alive we're not allowed to kill
 
644
                return False
 
645
            elif errorcode == 87: # ERROR_INVALID_PARAMETER
 
646
                return True
 
647
            raise ctypes.WinError(errorcode)
 
648
        _CloseHandle(handle)
 
649
        return False
 
650
    is_local_pid_dead = _ctypes_is_local_pid_dead
 
651
 
 
652
 
 
653
def _is_pywintypes_error(evalue):
 
654
    """True if exception instance is an error from pywin32"""
 
655
    if has_pywintypes and isinstance(evalue, pywintypes.error):
 
656
        return True
 
657
    return False