/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 breezy/win32utils.py

  • Committer: Jelmer Vernooij
  • Date: 2019-03-04 00:16:27 UTC
  • mfrom: (7293 work)
  • mto: This revision was merged to the branch mainline in revision 7318.
  • Revision ID: jelmer@jelmer.uk-20190304001627-v6u7o6pf97tukhek
Merge trunk.

Show diffs side-by-side

added added

removed removed

Lines of Context:
62
62
# pulling in win32com.shell is a bit of overhead, and normally we don't need
63
63
# it as ctypes is preferred and common.  lazy_imports and "optional"
64
64
# modules don't work well, so we do our own lazy thing...
65
 
has_win32com_shell = None # Set to True or False once we know for sure...
 
65
has_win32com_shell = None  # Set to True or False once we know for sure...
66
66
 
67
67
# Special Win32 API constants
68
68
# Handles of std streams
72
72
 
73
73
# CSIDL constants (from MSDN 2003)
74
74
CSIDL_APPDATA = 0x001A      # Application Data folder
75
 
CSIDL_LOCAL_APPDATA = 0x001c# <user name>\Local Settings\Application Data (non roaming)
 
75
# <user name>\Local Settings\Application Data (non roaming)
 
76
CSIDL_LOCAL_APPDATA = 0x001c
76
77
CSIDL_PERSONAL = 0x0005     # My Documents folder
77
78
 
78
79
# from winapi C headers
102
103
                        ('PagefileUsage', ctypes.c_size_t),
103
104
                        ('PeakPagefileUsage', ctypes.c_size_t),
104
105
                        ('PrivateUsage', ctypes.c_size_t),
105
 
                       ]
 
106
                        ]
106
107
        cur_process = ctypes.windll.kernel32.GetCurrentProcess()
107
108
        mem_struct = PROCESS_MEMORY_COUNTERS_EX()
108
 
        ret = ctypes.windll.psapi.GetProcessMemoryInfo(cur_process,
109
 
            ctypes.byref(mem_struct),
110
 
            ctypes.sizeof(mem_struct))
 
109
        ret = ctypes.windll.psapi.GetProcessMemoryInfo(
 
110
            cur_process, ctypes.byref(mem_struct), ctypes.sizeof(mem_struct))
111
111
        if not ret:
112
112
            trace.note(gettext('Failed to GetProcessMemoryInfo()'))
113
113
            return
122
122
                'PagefileUsage': mem_struct.PagefileUsage,
123
123
                'PeakPagefileUsage': mem_struct.PeakPagefileUsage,
124
124
                'PrivateUsage': mem_struct.PrivateUsage,
125
 
               }
 
125
                }
126
126
    elif has_win32api:
127
127
        import win32process
128
128
        # win32process does not return PrivateUsage, because it doesn't use
131
131
        info = win32process.GetProcessMemoryInfo(proc)
132
132
    else:
133
133
        trace.note(gettext('Cannot debug memory on win32 without ctypes'
134
 
                   ' or win32process'))
 
134
                           ' or win32process'))
135
135
        return
136
136
    if short:
137
137
        # using base-2 units (see HACKING.txt).
138
138
        trace.note(gettext('WorkingSize {0:>7}KiB'
139
 
                   '\tPeakWorking {1:>7}KiB\t{2}').format(
 
139
                           '\tPeakWorking {1:>7}KiB\t{2}').format(
140
140
                   info['WorkingSetSize'] / 1024,
141
141
                   info['PeakWorkingSetSize'] / 1024,
142
142
                   message))
143
143
        return
144
144
    if message:
145
145
        trace.note('%s', message)
146
 
    trace.note(gettext('WorkingSize       %8d KiB'), info['WorkingSetSize'] / 1024)
147
 
    trace.note(gettext('PeakWorking       %8d KiB'), info['PeakWorkingSetSize'] / 1024)
148
 
    trace.note(gettext('PagefileUsage     %8d KiB'), info.get('PagefileUsage', 0) / 1024)
 
146
    trace.note(gettext('WorkingSize       %8d KiB'),
 
147
               info['WorkingSetSize'] / 1024)
 
148
    trace.note(gettext('PeakWorking       %8d KiB'),
 
149
               info['PeakWorkingSetSize'] / 1024)
 
150
    trace.note(gettext('PagefileUsage     %8d KiB'),
 
151
               info.get('PagefileUsage', 0) / 1024)
149
152
    trace.note(gettext('PeakPagefileUsage %8d KiB'),
150
153
               info.get('PeakPagefileUsage', 0) / 1024)
151
 
    trace.note(gettext('PrivateUsage      %8d KiB'), info.get('PrivateUsage', 0) / 1024)
 
154
    trace.note(gettext('PrivateUsage      %8d KiB'),
 
155
               info.get('PrivateUsage', 0) / 1024)
152
156
    trace.note(gettext('PageFaultCount    %8d'), info.get('PageFaultCount', 0))
153
157
 
154
158
 
171
175
 
172
176
    if res:
173
177
        (bufx, bufy, curx, cury, wattr,
174
 
        left, top, right, bottom, maxx, maxy) = struct.unpack(
 
178
         left, top, right, bottom, maxx, maxy) = struct.unpack(
175
179
            "hhhhHhhhhhh", csbi.raw)
176
180
        sizex = right - left + 1
177
181
        sizey = bottom - top + 1
281
285
    if has_ctypes:
282
286
        try:
283
287
            advapi32 = ctypes.windll.advapi32
284
 
            GetUserName = getattr(advapi32, 'GetUserName'+suffix)
 
288
            GetUserName = getattr(advapi32, 'GetUserName' + suffix)
285
289
        except AttributeError:
286
290
            pass
287
291
        else:
288
 
            buf = create_buffer(UNLEN+1)
289
 
            n = ctypes.c_int(UNLEN+1)
 
292
            buf = create_buffer(UNLEN + 1)
 
293
            n = ctypes.c_int(UNLEN + 1)
290
294
            if GetUserName(buf, ctypes.byref(n)):
291
295
                return extract_buffer(buf)
292
296
    # otherwise try env variables
297
301
# computer or the cluster associated with the local computer."
298
302
_WIN32_ComputerNameDnsHostname = 1
299
303
 
 
304
 
300
305
def get_host_name():
301
306
    """Return host machine name.
302
307
    If name cannot be obtained return None.
313
318
        try:
314
319
            kernel32 = ctypes.windll.kernel32
315
320
        except AttributeError:
316
 
            pass # Missing the module we need
 
321
            pass  # Missing the module we need
317
322
        else:
318
 
            buf = create_buffer(MAX_COMPUTERNAME_LENGTH+1)
319
 
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
 
323
            buf = create_buffer(MAX_COMPUTERNAME_LENGTH + 1)
 
324
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH + 1)
320
325
 
321
326
            # Try GetComputerNameEx which gives a proper Unicode hostname
322
 
            GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx'+suffix,
 
327
            GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx' + suffix,
323
328
                                        None)
324
329
            if (GetComputerNameEx is not None
325
330
                and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
329
334
            # Try GetComputerName in case GetComputerNameEx wasn't found
330
335
            # It returns the NETBIOS name, which isn't as good, but still ok.
331
336
            # The first GetComputerNameEx might have changed 'n', so reset it
332
 
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
333
 
            GetComputerName = getattr(kernel32, 'GetComputerName'+suffix,
 
337
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH + 1)
 
338
            GetComputerName = getattr(kernel32, 'GetComputerName' + suffix,
334
339
                                      None)
335
340
            if (GetComputerName is not None
336
 
                and GetComputerName(buf, ctypes.byref(n))):
 
341
                    and GetComputerName(buf, ctypes.byref(n))):
337
342
                return extract_buffer(buf)
338
343
    return get_environ_unicode('COMPUTERNAME')
339
344
 
340
345
 
341
346
def _ensure_with_dir(path):
342
347
    if (not os.path.split(path)[0] or path.startswith(u'*')
343
 
        or path.startswith(u'?')):
 
348
            or path.startswith(u'?')):
344
349
        return u'./' + path, True
345
350
    else:
346
351
        return path, False
347
352
 
 
353
 
348
354
def _undo_ensure_with_dir(path, corrected):
349
355
    if corrected:
350
356
        return path[2:]
409
415
 
410
416
    try:
411
417
        hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
412
 
            'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' +
413
 
            basename)
 
418
                               'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' +
 
419
                               basename)
414
420
    except EnvironmentError:
415
421
        return appname
416
422
 
457
463
    :return: A list of unicode strings.
458
464
    """
459
465
    # First, split the command line
460
 
    s = cmdline.Splitter(command_line, single_quotes_allowed=single_quotes_allowed)
461
 
    
462
 
    # Bug #587868 Now make sure that the length of s agrees with sys.argv 
463
 
    # we do this by simply counting the number of arguments in each. The counts should 
464
 
    # agree no matter what encoding sys.argv is in (AFAIK) 
465
 
    # len(arguments) < len(sys.argv) should be an impossibility since python gets 
 
466
    s = cmdline.Splitter(
 
467
        command_line, single_quotes_allowed=single_quotes_allowed)
 
468
 
 
469
    # Bug #587868 Now make sure that the length of s agrees with sys.argv
 
470
    # we do this by simply counting the number of arguments in each. The counts should
 
471
    # agree no matter what encoding sys.argv is in (AFAIK)
 
472
    # len(arguments) < len(sys.argv) should be an impossibility since python gets
466
473
    # args from the very same PEB as does GetCommandLineW
467
474
    arguments = list(s)
468
 
    
 
475
 
469
476
    # Now shorten the command line we get from GetCommandLineW to match sys.argv
470
477
    if len(arguments) < len(argv):
471
478
        raise AssertionError("Split command line can't be shorter than argv")
472
479
    arguments = arguments[len(arguments) - len(argv):]
473
 
    
 
480
 
474
481
    # Carry on to process globs (metachars) in the command line
475
482
    # expand globs if necessary
476
483
    # TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
496
503
        argv = _command_line_to_argv(command_line, sys.argv)[1:]
497
504
        return argv
498
505
 
499
 
 
500
506
    def get_environ_unicode(key, default=None):
501
507
        """Get `key` from environment as unicode or `default` if unset
502
508
 
516
522
            cfunc = ctypes.WINFUNCTYPE(DWORD, LPCWSTR, LPWSTR, DWORD)(
517
523
                ("GetEnvironmentVariableW", ctypes.windll.kernel32))
518
524
            get_environ_unicode._c_function = cfunc
519
 
        buffer_size = 256 # heuristic, 256 characters often enough
 
525
        buffer_size = 256  # heuristic, 256 characters often enough
520
526
        while True:
521
527
            buffer = ctypes.create_unicode_buffer(buffer_size)
522
528
            length = cfunc(key, buffer, buffer_size)
523
529
            if not length:
524
530
                code = ctypes.GetLastError()
525
 
                if code == 203: # ERROR_ENVVAR_NOT_FOUND
 
531
                if code == 203:  # ERROR_ENVVAR_NOT_FOUND
526
532
                    return default
527
533
                raise ctypes.WinError(code)
528
534
            if buffer_size > length:
534
540
    def _pywin32_is_local_pid_dead(pid):
535
541
        """True if pid doesn't correspond to live process on this machine"""
536
542
        try:
537
 
            handle = win32api.OpenProcess(1, False, pid) # PROCESS_TERMINATE
 
543
            handle = win32api.OpenProcess(1, False, pid)  # PROCESS_TERMINATE
538
544
        except pywintypes.error as e:
539
 
            if e[0] == 5: # ERROR_ACCESS_DENIED
 
545
            if e[0] == 5:  # ERROR_ACCESS_DENIED
540
546
                # Probably something alive we're not allowed to kill
541
547
                return False
542
 
            elif e[0] == 87: # ERROR_INVALID_PARAMETER
 
548
            elif e[0] == 87:  # ERROR_INVALID_PARAMETER
543
549
                return True
544
550
            raise
545
551
        handle.close()
552
558
        ("CloseHandle", _kernel32))
553
559
    _OpenProcess = ctypes.WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)(
554
560
        ("OpenProcess", _kernel32))
 
561
 
555
562
    def _ctypes_is_local_pid_dead(pid):
556
563
        """True if pid doesn't correspond to live process on this machine"""
557
 
        handle = _OpenProcess(1, False, pid) # PROCESS_TERMINATE
 
564
        handle = _OpenProcess(1, False, pid)  # PROCESS_TERMINATE
558
565
        if not handle:
559
566
            errorcode = ctypes.GetLastError()
560
 
            if errorcode == 5: # ERROR_ACCESS_DENIED
 
567
            if errorcode == 5:  # ERROR_ACCESS_DENIED
561
568
                # Probably something alive we're not allowed to kill
562
569
                return False
563
 
            elif errorcode == 87: # ERROR_INVALID_PARAMETER
 
570
            elif errorcode == 87:  # ERROR_INVALID_PARAMETER
564
571
                return True
565
572
            raise ctypes.WinError(errorcode)
566
573
        _CloseHandle(handle)