/brz/remove-bazaar

To get this branch, use:
bzr branch http://gegoxaren.bato24.eu/bzr/brz/remove-bazaar
4988.10.3 by John Arbash Meinel
Merge bzr.dev 5007, resolve conflict, update NEWS
1
# Copyright (C) 2005-2010 Canonical Ltd
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
2
#
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
3
# This program is free software; you can redistribute it and/or modify
4
# it under the terms of the GNU General Public License as published by
5
# the Free Software Foundation; either version 2 of the License, or
6
# (at your option) any later version.
7
#
8
# This program is distributed in the hope that it will be useful,
9
# but WITHOUT ANY WARRANTY; without even the implied warranty of
10
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
11
# GNU General Public License for more details.
12
#
13
# You should have received a copy of the GNU General Public License
14
# along with this program; if not, write to the Free Software
4183.7.1 by Sabin Iacob
update FSF mailing address
15
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
2052.3.1 by John Arbash Meinel
Add tests to cleanup the copyright of all source files
16
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
17
"""Win32-specific helper functions
18
19
Only one dependency: ctypes should be installed.
20
"""
21
6379.6.7 by Jelmer Vernooij
Move importing from future until after doc string, otherwise the doc string will disappear.
22
from __future__ import absolute_import
23
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
24
import glob
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
25
import os
1185.16.86 by mbp at sourcefrog
- win32 get_console_size from Alexander
26
import struct
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
27
import sys
28
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
29
from breezy import (
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
30
    cmdline,
31
    )
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
32
from breezy.i18n import gettext
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
33
7341.1.1 by Martin
Remove win32 code using pywin32 library
34
has_ctypes_win32 = False
35
if sys.platform == 'win32':
36
    try:
37
        import ctypes
38
    except ImportError:
39
        has_ctypes_win32 = False
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
40
41
42
# Special Win32 API constants
43
# Handles of std streams
1704.2.3 by Martin Pool
(win32) Detect terminal width using GetConsoleScreenBufferInfo (Alexander)
44
WIN32_STDIN_HANDLE = -10
45
WIN32_STDOUT_HANDLE = -11
46
WIN32_STDERR_HANDLE = -12
47
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
48
# CSIDL constants (from MSDN 2003)
49
CSIDL_APPDATA = 0x001A      # Application Data folder
7143.15.2 by Jelmer Vernooij
Run autopep8.
50
# <user name>\Local Settings\Application Data (non roaming)
51
CSIDL_LOCAL_APPDATA = 0x001c
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
52
CSIDL_PERSONAL = 0x0005     # My Documents folder
53
54
# from winapi C headers
55
MAX_PATH = 260
56
UNLEN = 256
57
MAX_COMPUTERNAME_LENGTH = 31
58
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
59
# Registry data type ids
60
REG_SZ = 1
61
REG_EXPAND_SZ = 2
62
1704.2.3 by Martin Pool
(win32) Detect terminal width using GetConsoleScreenBufferInfo (Alexander)
63
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
64
def debug_memory_win32api(message='', short=True):
65
    """Use trace.note() to dump the running memory info."""
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
66
    from breezy import trace
7341.1.1 by Martin
Remove win32 code using pywin32 library
67
    if has_ctypes_win32:
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
68
        class PROCESS_MEMORY_COUNTERS_EX(ctypes.Structure):
69
            """Used by GetProcessMemoryInfo"""
70
            _fields_ = [('cb', ctypes.c_ulong),
71
                        ('PageFaultCount', ctypes.c_ulong),
72
                        ('PeakWorkingSetSize', ctypes.c_size_t),
73
                        ('WorkingSetSize', ctypes.c_size_t),
74
                        ('QuotaPeakPagedPoolUsage', ctypes.c_size_t),
75
                        ('QuotaPagedPoolUsage', ctypes.c_size_t),
76
                        ('QuotaPeakNonPagedPoolUsage', ctypes.c_size_t),
77
                        ('QuotaNonPagedPoolUsage', ctypes.c_size_t),
78
                        ('PagefileUsage', ctypes.c_size_t),
79
                        ('PeakPagefileUsage', ctypes.c_size_t),
80
                        ('PrivateUsage', ctypes.c_size_t),
7143.15.2 by Jelmer Vernooij
Run autopep8.
81
                        ]
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
82
        cur_process = ctypes.windll.kernel32.GetCurrentProcess()
83
        mem_struct = PROCESS_MEMORY_COUNTERS_EX()
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
84
        ret = ctypes.windll.psapi.GetProcessMemoryInfo(
85
            cur_process, ctypes.byref(mem_struct), ctypes.sizeof(mem_struct))
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
86
        if not ret:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
87
            trace.note(gettext('Failed to GetProcessMemoryInfo()'))
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
88
            return
89
        info = {'PageFaultCount': mem_struct.PageFaultCount,
90
                'PeakWorkingSetSize': mem_struct.PeakWorkingSetSize,
91
                'WorkingSetSize': mem_struct.WorkingSetSize,
92
                'QuotaPeakPagedPoolUsage': mem_struct.QuotaPeakPagedPoolUsage,
93
                'QuotaPagedPoolUsage': mem_struct.QuotaPagedPoolUsage,
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
94
                'QuotaPeakNonPagedPoolUsage':
95
                    mem_struct.QuotaPeakNonPagedPoolUsage,
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
96
                'QuotaNonPagedPoolUsage': mem_struct.QuotaNonPagedPoolUsage,
97
                'PagefileUsage': mem_struct.PagefileUsage,
98
                'PeakPagefileUsage': mem_struct.PeakPagefileUsage,
99
                'PrivateUsage': mem_struct.PrivateUsage,
7143.15.2 by Jelmer Vernooij
Run autopep8.
100
                }
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
101
    else:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
102
        trace.note(gettext('Cannot debug memory on win32 without ctypes'
7143.15.2 by Jelmer Vernooij
Run autopep8.
103
                           ' or win32process'))
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
104
        return
4163.1.1 by John Arbash Meinel
Some small fixes for the win32 'trace.debug_mem()' code.
105
    if short:
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
106
        # using base-2 units (see HACKING.txt).
6147.1.1 by Jonathan Riddell
use .format() instead of % for string formatting where there are multiple formats in one string to allow for translations
107
        trace.note(gettext('WorkingSize {0:>7}KiB'
7143.15.2 by Jelmer Vernooij
Run autopep8.
108
                           '\tPeakWorking {1:>7}KiB\t{2}').format(
4163.1.1 by John Arbash Meinel
Some small fixes for the win32 'trace.debug_mem()' code.
109
                   info['WorkingSetSize'] / 1024,
110
                   info['PeakWorkingSetSize'] / 1024,
6147.1.1 by Jonathan Riddell
use .format() instead of % for string formatting where there are multiple formats in one string to allow for translations
111
                   message))
4163.1.1 by John Arbash Meinel
Some small fixes for the win32 'trace.debug_mem()' code.
112
        return
113
    if message:
114
        trace.note('%s', message)
7143.15.2 by Jelmer Vernooij
Run autopep8.
115
    trace.note(gettext('WorkingSize       %8d KiB'),
116
               info['WorkingSetSize'] / 1024)
117
    trace.note(gettext('PeakWorking       %8d KiB'),
118
               info['PeakWorkingSetSize'] / 1024)
119
    trace.note(gettext('PagefileUsage     %8d KiB'),
120
               info.get('PagefileUsage', 0) / 1024)
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
121
    trace.note(gettext('PeakPagefileUsage %8d KiB'),
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
122
               info.get('PeakPagefileUsage', 0) / 1024)
7143.15.2 by Jelmer Vernooij
Run autopep8.
123
    trace.note(gettext('PrivateUsage      %8d KiB'),
124
               info.get('PrivateUsage', 0) / 1024)
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
125
    trace.note(gettext('PageFaultCount    %8d'), info.get('PageFaultCount', 0))
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
126
127
1185.16.86 by mbp at sourcefrog
- win32 get_console_size from Alexander
128
def get_console_size(defaultx=80, defaulty=25):
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
129
    """Return size of current console.
130
131
    This function try to determine actual size of current working
132
    console window and return tuple (sizex, sizey) if success,
133
    or default size (defaultx, defaulty) otherwise.
134
    """
7341.1.1 by Martin
Remove win32 code using pywin32 library
135
    if not has_ctypes_win32:
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
136
        # no ctypes is found
137
        return (defaultx, defaulty)
138
139
    # To avoid problem with redirecting output via pipe
4747.3.6 by Vincent Ladeuil
terminal_width can now returns None.
140
    # we need to use stderr instead of stdout
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
141
    h = ctypes.windll.kernel32.GetStdHandle(WIN32_STDERR_HANDLE)
142
    csbi = ctypes.create_string_buffer(22)
143
    res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
144
145
    if res:
146
        (bufx, bufy, curx, cury, wattr,
7143.15.2 by Jelmer Vernooij
Run autopep8.
147
         left, top, right, bottom, maxx, maxy) = struct.unpack(
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
148
            "hhhhHhhhhhh", csbi.raw)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
149
        sizex = right - left + 1
150
        sizey = bottom - top + 1
151
        return (sizex, sizey)
152
    else:
153
        return (defaultx, defaulty)
154
155
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
156
def _get_sh_special_folder_path(csidl):
157
    """Call SHGetSpecialFolderPathW if available, or return None.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
158
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
159
    Result is always unicode (or None).
160
    """
7341.1.1 by Martin
Remove win32 code using pywin32 library
161
    if has_ctypes_win32:
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
162
        try:
163
            SHGetSpecialFolderPath = \
164
                ctypes.windll.shell32.SHGetSpecialFolderPathW
165
        except AttributeError:
166
            pass
167
        else:
168
            buf = ctypes.create_unicode_buffer(MAX_PATH)
6809.1.1 by Martin
Apply 2to3 ws_comma fixer
169
            if SHGetSpecialFolderPath(None, buf, csidl, 0):
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
170
                return buf.value
171
    return None
172
173
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
174
def get_appdata_location():
175
    """Return Application Data location.
176
    Return None if we cannot obtain location.
177
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
178
    Windows defines two 'Application Data' folders per user - a 'roaming'
179
    one that moves with the user as they logon to different machines, and
180
    a 'local' one that stays local to the machine.  This returns the 'roaming'
181
    directory, and thus is suitable for storing user-preferences, etc.
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
182
    """
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
183
    appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
184
    if appdata:
185
        return appdata
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
186
    # Use APPDATA if defined, will return None if not
187
    return get_environ_unicode('APPDATA')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
188
189
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
190
def get_local_appdata_location():
191
    """Return Local Application Data location.
192
    Return the same as get_appdata_location() if we cannot obtain location.
193
194
    Windows defines two 'Application Data' folders per user - a 'roaming'
195
    one that moves with the user as they logon to different machines, and
196
    a 'local' one that stays local to the machine.  This returns the 'local'
197
    directory, and thus is suitable for caches, temp files and other things
198
    which don't need to move with the user.
199
    """
200
    local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
201
    if local:
202
        return local
203
    # Vista supplies LOCALAPPDATA, but XP and earlier do not.
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
204
    local = get_environ_unicode('LOCALAPPDATA')
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
205
    if local:
206
        return local
207
    return get_appdata_location()
208
209
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
210
def get_home_location():
211
    """Return user's home location.
212
    Assume on win32 it's the <My Documents> folder.
213
    If location cannot be obtained return system drive root,
214
    i.e. C:\
215
    """
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
216
    home = _get_sh_special_folder_path(CSIDL_PERSONAL)
217
    if home:
218
        return home
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
219
    home = get_environ_unicode('HOME')
220
    if home is not None:
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
221
        return home
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
222
    homepath = get_environ_unicode('HOMEPATH')
223
    if homepath is not None:
224
        return os.path.join(get_environ_unicode('HOMEDIR', ''), home)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
225
    # at least return windows root directory
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
226
    windir = get_environ_unicode('WINDIR')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
227
    if windir:
2610.1.1 by Martin Pool
Fix get_home_location on Win98 (gzlist,r=john,r=alexander)
228
        return os.path.splitdrive(windir)[0] + '/'
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
229
    # otherwise C:\ is good enough for 98% users
6973.6.4 by Jelmer Vernooij
Avoid text_type()
230
    return u'C:/'
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
231
232
233
def get_user_name():
234
    """Return user name as login name.
235
    If name cannot be obtained return None.
236
    """
7341.1.1 by Martin
Remove win32 code using pywin32 library
237
    if has_ctypes_win32:
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
238
        try:
239
            advapi32 = ctypes.windll.advapi32
7341.1.1 by Martin
Remove win32 code using pywin32 library
240
            GetUserName = getattr(advapi32, 'GetUserNameW')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
241
        except AttributeError:
242
            pass
243
        else:
7341.1.1 by Martin
Remove win32 code using pywin32 library
244
            buf = ctypes.create_unicode_buffer(UNLEN + 1)
7143.15.2 by Jelmer Vernooij
Run autopep8.
245
            n = ctypes.c_int(UNLEN + 1)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
246
            if GetUserName(buf, ctypes.byref(n)):
7341.1.1 by Martin
Remove win32 code using pywin32 library
247
                return buf.value
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
248
    # otherwise try env variables
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
249
    return get_environ_unicode('USERNAME')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
250
251
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
252
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
253
# computer or the cluster associated with the local computer."
254
_WIN32_ComputerNameDnsHostname = 1
255
7143.15.2 by Jelmer Vernooij
Run autopep8.
256
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
257
def get_host_name():
258
    """Return host machine name.
259
    If name cannot be obtained return None.
260
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
261
    :return: A unicode string representing the host name.
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
262
    """
7341.1.1 by Martin
Remove win32 code using pywin32 library
263
    if has_ctypes_win32:
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
264
        try:
265
            kernel32 = ctypes.windll.kernel32
266
        except AttributeError:
7143.15.2 by Jelmer Vernooij
Run autopep8.
267
            pass  # Missing the module we need
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
268
        else:
7341.1.1 by Martin
Remove win32 code using pywin32 library
269
            buf = ctypes.create_unicode_buffer(MAX_COMPUTERNAME_LENGTH + 1)
7143.15.2 by Jelmer Vernooij
Run autopep8.
270
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH + 1)
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
271
272
            # Try GetComputerNameEx which gives a proper Unicode hostname
7341.1.1 by Martin
Remove win32 code using pywin32 library
273
            GetComputerNameEx = getattr(kernel32, 'GetComputerNameExW', None)
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
274
            if (GetComputerNameEx is not None
275
                and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
7143.15.5 by Jelmer Vernooij
More PEP8 fixes.
276
                                      buf, ctypes.byref(n))):
7341.1.1 by Martin
Remove win32 code using pywin32 library
277
                return buf.value
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
278
    return get_environ_unicode('COMPUTERNAME')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
279
280
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
281
def _ensure_with_dir(path):
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
282
    if (not os.path.split(path)[0] or path.startswith(u'*')
7143.15.2 by Jelmer Vernooij
Run autopep8.
283
            or path.startswith(u'?')):
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
284
        return u'./' + path, True
285
    else:
286
        return path, False
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
287
7143.15.2 by Jelmer Vernooij
Run autopep8.
288
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
289
def _undo_ensure_with_dir(path, corrected):
290
    if corrected:
291
        return path[2:]
292
    else:
293
        return path
294
295
4786.1.2 by John Arbash Meinel
Refactor the glob_expand code a bit, making the inner function more reusable.
296
def glob_one(possible_glob):
297
    """Same as glob.glob().
298
299
    work around bugs in glob.glob()
300
    - Python bug #1001604 ("glob doesn't return unicode with ...")
301
    - failing expansion for */* with non-iso-8859-* chars
302
    """
303
    corrected_glob, corrected = _ensure_with_dir(possible_glob)
304
    glob_files = glob.glob(corrected_glob)
305
306
    if not glob_files:
307
        # special case to let the normal code path handle
308
        # files that do not exist, etc.
309
        glob_files = [possible_glob]
310
    elif corrected:
311
        glob_files = [_undo_ensure_with_dir(elem, corrected)
312
                      for elem in glob_files]
313
    return [elem.replace(u'\\', u'/') for elem in glob_files]
314
315
2598.3.1 by Kuno Meyer
fix method rename glob_expand_for_win32 -> win32utils.glob_expand
316
def glob_expand(file_list):
2568.2.2 by Robert Collins
* New method ``_glob_expand_file_list_if_needed`` on the ``Command`` class
317
    """Replacement for glob expansion by the shell.
318
319
    Win32's cmd.exe does not do glob expansion (eg ``*.py``), so we do our own
320
    here.
321
322
    :param file_list: A list of filenames which may include shell globs.
323
    :return: An expanded list of filenames.
324
6622.1.34 by Jelmer Vernooij
Rename brzlib => breezy.
325
    Introduced in breezy 0.18.
2568.2.2 by Robert Collins
* New method ``_glob_expand_file_list_if_needed`` on the ``Command`` class
326
    """
327
    if not file_list:
328
        return []
329
    expanded_file_list = []
330
    for possible_glob in file_list:
4786.1.2 by John Arbash Meinel
Refactor the glob_expand code a bit, making the inner function more reusable.
331
        expanded_file_list.extend(glob_one(possible_glob))
332
    return expanded_file_list
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
333
334
335
def get_app_path(appname):
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
336
    r"""Look up in Windows registry for full path to application executable.
4031.3.1 by Frank Aspell
Fixing various typos
337
    Typically, applications create subkey with their basename
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
338
    in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\
339
340
    :param  appname:    name of application (if no filename extension
341
                        is specified, .exe used)
342
    :return:    full path to aplication executable from registry,
343
                or appname itself if nothing found.
344
    """
2681.4.3 by Alexander Belchenko
move import _winreg into function get_app_path to avoid ImportError on non-win32 platforms
345
    import _winreg
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
346
347
    basename = appname
348
    if not os.path.splitext(basename)[1]:
349
        basename = appname + '.exe'
350
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
351
    try:
352
        hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
7143.15.2 by Jelmer Vernooij
Run autopep8.
353
                               'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' +
354
                               basename)
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
355
    except EnvironmentError:
356
        return appname
357
358
    try:
359
        try:
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
360
            path, type_id = _winreg.QueryValueEx(hkey, '')
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
361
        except WindowsError:
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
362
            return appname
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
363
    finally:
364
        _winreg.CloseKey(hkey)
365
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
366
    if type_id == REG_SZ:
367
        return path
368
    if type_id == REG_EXPAND_SZ and has_win32api:
369
        fullpath = win32api.ExpandEnvironmentStrings(path)
4476.2.2 by Alexander Belchenko
remove quotes around value only if there is pair of quotes (igc review)
370
        if len(fullpath) > 1 and fullpath[0] == '"' and fullpath[-1] == '"':
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
371
            fullpath = fullpath[1:-1]   # remove quotes around value
372
        return fullpath
373
    return appname
3023.1.2 by Alexander Belchenko
Martin's review.
374
375
376
def set_file_attr_hidden(path):
377
    """Set file attributes to hidden if possible"""
7341.1.1 by Martin
Remove win32 code using pywin32 library
378
    if not has_ctypes_win32:
379
        return
380
    from ctypes.wintypes import BOOL, DWORD, LPCWSTR
381
    _kernel32 = ctypes.windll.kernel32
382
    # <https://docs.microsoft.com/windows/desktop/api/fileapi/nf-fileapi-setfileattributesw>
383
    _SetFileAttributesW = ctypes.WINFUNCTYPE(BOOL, LPCWSTR, DWORD)(
384
        ("SetFileAttributesW", _kernel32))
385
    FILE_ATTRIBUTE_HIDDEN = 2
386
    if not SetFileAttributes(path, FILE_ATTRIBUTE_HIDDEN):
387
        e = ctypes.WinError()
388
        from . import trace
389
        trace.mutter('Unable to set hidden attribute on %r: %s', path, e)
4355.2.1 by Alexander Belchenko
Using unicode Windows API to obtain command-line arguments.
390
391
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
392
def _command_line_to_argv(command_line, argv, single_quotes_allowed=False):
4913.5.2 by Gordon Tyler
Changed shlex_split_unicode to prevent wildcard expansion in the win32 codepath.
393
    """Convert a Unicode command line into a list of argv arguments.
394
4913.5.25 by Gordon Tyler
Simplified win32utils.command_line_to_argv and made it private since it's no longer used outside of the module.
395
    It performs wildcard expansion to make wildcards act closer to how they
396
    work in posix shells, versus how they work by default on Windows. Quoted
397
    arguments are left untouched.
4913.5.2 by Gordon Tyler
Changed shlex_split_unicode to prevent wildcard expansion in the win32 codepath.
398
399
    :param command_line: The unicode string to split into an arg list.
4913.5.11 by Gordon Tyler
Added optional single quote support to UnicodeShlex and thus command_line_to_argv (defaults to disabled).
400
    :param single_quotes_allowed: Whether single quotes are accepted as quoting
401
                                  characters like double quotes. False by
402
                                  default.
4913.5.2 by Gordon Tyler
Changed shlex_split_unicode to prevent wildcard expansion in the win32 codepath.
403
    :return: A list of unicode strings.
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
404
    """
6437.65.1 by Scanferlato
Fix two typos in docs and comment
405
    # First, split the command line
7143.15.2 by Jelmer Vernooij
Run autopep8.
406
    s = cmdline.Splitter(
407
        command_line, single_quotes_allowed=single_quotes_allowed)
408
409
    # Bug #587868 Now make sure that the length of s agrees with sys.argv
410
    # we do this by simply counting the number of arguments in each. The counts should
411
    # agree no matter what encoding sys.argv is in (AFAIK)
412
    # len(arguments) < len(sys.argv) should be an impossibility since python gets
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
413
    # args from the very same PEB as does GetCommandLineW
414
    arguments = list(s)
7143.15.2 by Jelmer Vernooij
Run autopep8.
415
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
416
    # Now shorten the command line we get from GetCommandLineW to match sys.argv
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
417
    if len(arguments) < len(argv):
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
418
        raise AssertionError("Split command line can't be shorter than argv")
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
419
    arguments = arguments[len(arguments) - len(argv):]
7143.15.2 by Jelmer Vernooij
Run autopep8.
420
5274.4.2 by Jason Spashett
Tidied up fix for 587868. Put assert in for impossible case in command line lengths.
421
    # Carry on to process globs (metachars) in the command line
5274.4.1 by Jason Spashett
Initial Fix for 587868
422
    # expand globs if necessary
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
423
    # TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
424
    #       '**/' style globs
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
425
    args = []
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
426
    for is_quoted, arg in arguments:
4913.5.25 by Gordon Tyler
Simplified win32utils.command_line_to_argv and made it private since it's no longer used outside of the module.
427
        if is_quoted or not glob.has_magic(arg):
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
428
            args.append(arg)
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
429
        else:
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
430
            args.extend(glob_one(arg))
431
    return args
5274.4.3 by Jason Spashett
Merge from lp:bzr. Remove code for fix 588277 (revs 5274.3.1 - 5274.3.2) as this bug also fixes that issue. Make changes as per code review.
432
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
433
7341.1.1 by Martin
Remove win32 code using pywin32 library
434
if has_ctypes_win32:
4355.2.1 by Alexander Belchenko
Using unicode Windows API to obtain command-line arguments.
435
    def get_unicode_argv():
4913.5.15 by Gordon Tyler
Python < 2.6 doesn't support use_last_error.
436
        prototype = ctypes.WINFUNCTYPE(ctypes.c_wchar_p)
4913.5.1 by Gordon Tyler
Changed shlex_split_unicode in commands.py to use win32utils.command_line_to_argv on win32 and cleaned up win32utils.get_unicode_argv.
437
        GetCommandLineW = prototype(("GetCommandLineW",
438
                                     ctypes.windll.kernel32))
439
        command_line = GetCommandLineW()
440
        if command_line is None:
441
            raise ctypes.WinError()
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
442
        # Skip the first argument, since we only care about parameters
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
443
        argv = _command_line_to_argv(command_line, sys.argv)[1:]
4355.2.1 by Alexander Belchenko
Using unicode Windows API to obtain command-line arguments.
444
        return argv
6658.6.1 by Martin
Remove winver, win98 support code, and deprecated code
445
6339.2.3 by Martin Packman
Remove ability to specify a maximum buffer size as it serves no particular purpose
446
    def get_environ_unicode(key, default=None):
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
447
        """Get `key` from environment as unicode or `default` if unset
448
6362.2.5 by Martin Packman
Tweaks including those suggested by vila in review
449
        The environment is natively unicode on modern windows versions but
450
        Python 2 only accesses it through the legacy bytestring api.
451
452
        Environmental variable names are case insenstive on Windows.
453
6339.2.3 by Martin Packman
Remove ability to specify a maximum buffer size as it serves no particular purpose
454
        A large enough buffer will be allocated to retrieve the value, though
455
        it may take two calls to the underlying library function.
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
456
        """
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
457
        cfunc = getattr(get_environ_unicode, "_c_function", None)
458
        if cfunc is None:
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
459
            from ctypes.wintypes import DWORD, LPCWSTR, LPWSTR
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
460
            cfunc = ctypes.WINFUNCTYPE(DWORD, LPCWSTR, LPWSTR, DWORD)(
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
461
                ("GetEnvironmentVariableW", ctypes.windll.kernel32))
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
462
            get_environ_unicode._c_function = cfunc
7143.15.2 by Jelmer Vernooij
Run autopep8.
463
        buffer_size = 256  # heuristic, 256 characters often enough
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
464
        while True:
7341.1.1 by Martin
Remove win32 code using pywin32 library
465
            buf = ctypes.create_unicode_buffer(buffer_size)
466
            length = cfunc(key, buf, buffer_size)
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
467
            if not length:
468
                code = ctypes.GetLastError()
7143.15.2 by Jelmer Vernooij
Run autopep8.
469
                if code == 203:  # ERROR_ENVVAR_NOT_FOUND
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
470
                    return default
471
                raise ctypes.WinError(code)
472
            if buffer_size > length:
7341.1.1 by Martin
Remove win32 code using pywin32 library
473
                return buf[:length]
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
474
            buffer_size = length
5425.5.5 by Martin
Quick implementation of dead process detection on win32
475
476
7341.1.1 by Martin
Remove win32 code using pywin32 library
477
if has_ctypes_win32:
5425.5.5 by Martin
Quick implementation of dead process detection on win32
478
    from ctypes.wintypes import BOOL, DWORD, HANDLE
479
    _kernel32 = ctypes.windll.kernel32
480
    _CloseHandle = ctypes.WINFUNCTYPE(BOOL, HANDLE)(
481
        ("CloseHandle", _kernel32))
482
    _OpenProcess = ctypes.WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)(
483
        ("OpenProcess", _kernel32))
7143.15.2 by Jelmer Vernooij
Run autopep8.
484
5425.5.5 by Martin
Quick implementation of dead process detection on win32
485
    def _ctypes_is_local_pid_dead(pid):
486
        """True if pid doesn't correspond to live process on this machine"""
7143.15.2 by Jelmer Vernooij
Run autopep8.
487
        handle = _OpenProcess(1, False, pid)  # PROCESS_TERMINATE
5425.5.5 by Martin
Quick implementation of dead process detection on win32
488
        if not handle:
489
            errorcode = ctypes.GetLastError()
7143.15.2 by Jelmer Vernooij
Run autopep8.
490
            if errorcode == 5:  # ERROR_ACCESS_DENIED
5425.5.5 by Martin
Quick implementation of dead process detection on win32
491
                # Probably something alive we're not allowed to kill
492
                return False
7143.15.2 by Jelmer Vernooij
Run autopep8.
493
            elif errorcode == 87:  # ERROR_INVALID_PARAMETER
5425.5.5 by Martin
Quick implementation of dead process detection on win32
494
                return True
495
            raise ctypes.WinError(errorcode)
496
        _CloseHandle(handle)
497
        return False
7341.1.1 by Martin
Remove win32 code using pywin32 library
498
5425.5.5 by Martin
Quick implementation of dead process detection on win32
499
    is_local_pid_dead = _ctypes_is_local_pid_dead