~bzr-pqm/bzr/bzr.dev

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
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
22
import glob
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
23
import operator
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
24
import os
1185.16.86 by mbp at sourcefrog
- win32 get_console_size from Alexander
25
import struct
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
26
import sys
27
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
28
from bzrlib import (
29
    cmdline,
30
    symbol_versioning,
31
    )
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
32
from bzrlib.i18n import gettext
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
33
34
# Windows version
35
if sys.platform == 'win32':
36
    _major,_minor,_build,_platform,_text = sys.getwindowsversion()
2245.4.11 by Alexander Belchenko
Small fixes after John's review; added NEWS entry
37
    # from MSDN:
38
    # dwPlatformId
39
    #   The operating system platform.
40
    #   This member can be one of the following values.
41
    #   ==========================  ======================================
42
    #   Value                       Meaning
43
    #   --------------------------  --------------------------------------
44
    #   VER_PLATFORM_WIN32_NT       The operating system is Windows Vista,
45
    #   2                           Windows Server "Longhorn",
46
    #                               Windows Server 2003, Windows XP,
47
    #                               Windows 2000, or Windows NT.
48
    #
49
    #   VER_PLATFORM_WIN32_WINDOWS  The operating system is Windows Me,
50
    #   1                           Windows 98, or Windows 95.
51
    #   ==========================  ======================================
52
    if _platform == 2:
53
        winver = 'Windows NT'
54
    else:
55
        # don't care about real Windows name, just to force safe operations
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
56
        winver = 'Windows 98'
57
else:
58
    winver = None
59
1185.16.86 by mbp at sourcefrog
- win32 get_console_size from Alexander
60
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
61
# We can cope without it; use a separate variable to help pyflakes
1185.16.86 by mbp at sourcefrog
- win32 get_console_size from Alexander
62
try:
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
63
    import ctypes
64
    has_ctypes = True
1185.16.86 by mbp at sourcefrog
- win32 get_console_size from Alexander
65
except ImportError:
1773.4.1 by Martin Pool
Add pyflakes makefile target; fix many warnings
66
    has_ctypes = False
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
67
else:
68
    if winver == 'Windows 98':
69
        create_buffer = ctypes.create_string_buffer
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
70
        def extract_buffer(buf):
6362.2.5 by Martin Packman
Tweaks including those suggested by vila in review
71
            return buf.value.decode("mbcs")
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
72
        suffix = 'A'
73
    else:
74
        create_buffer = ctypes.create_unicode_buffer
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
75
        extract_buffer = operator.attrgetter("value")
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
76
        suffix = 'W'
3023.1.2 by Alexander Belchenko
Martin's review.
77
try:
4505.2.1 by Alexander Belchenko
Set hidden attribute on .bzr directory below unicode path should never fail with error. The operation should succeed even if bzr unable to set the attribute. (related to bug #335362).
78
    import pywintypes
6336.2.2 by Martin Packman
Tweak how pywin32 is imported in win32utils to fix test failure edge case
79
    has_pywintypes = True
80
except ImportError:
6336.2.3 by Martin Packman
Set all has_win32* to False if pywintypes can't be imported
81
    has_pywintypes = has_win32file = has_win32api = False
6336.2.2 by Martin Packman
Tweak how pywin32 is imported in win32utils to fix test failure edge case
82
else:
83
    try:
84
        import win32file
85
        has_win32file = True
86
    except ImportError:
87
        has_win32file = False
88
    try:
89
        import win32api
90
        has_win32api = True
91
    except ImportError:
92
        has_win32api = False
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
93
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
94
# pulling in win32com.shell is a bit of overhead, and normally we don't need
95
# it as ctypes is preferred and common.  lazy_imports and "optional"
96
# modules don't work well, so we do our own lazy thing...
97
has_win32com_shell = None # Set to True or False once we know for sure...
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
98
99
# Special Win32 API constants
100
# Handles of std streams
1704.2.3 by Martin Pool
(win32) Detect terminal width using GetConsoleScreenBufferInfo (Alexander)
101
WIN32_STDIN_HANDLE = -10
102
WIN32_STDOUT_HANDLE = -11
103
WIN32_STDERR_HANDLE = -12
104
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
105
# CSIDL constants (from MSDN 2003)
106
CSIDL_APPDATA = 0x001A      # Application Data folder
3638.4.10 by Aaron Bentley
Correct spelling of 'Application Data'
107
CSIDL_LOCAL_APPDATA = 0x001c# <user name>\Local Settings\Application Data (non roaming)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
108
CSIDL_PERSONAL = 0x0005     # My Documents folder
109
110
# from winapi C headers
111
MAX_PATH = 260
112
UNLEN = 256
113
MAX_COMPUTERNAME_LENGTH = 31
114
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
115
# Registry data type ids
116
REG_SZ = 1
117
REG_EXPAND_SZ = 2
118
1704.2.3 by Martin Pool
(win32) Detect terminal width using GetConsoleScreenBufferInfo (Alexander)
119
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
120
def debug_memory_win32api(message='', short=True):
121
    """Use trace.note() to dump the running memory info."""
122
    from bzrlib import trace
4011.1.2 by John Arbash Meinel
Fix some small bugs, and prefer the ctypes form.
123
    if has_ctypes:
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
124
        class PROCESS_MEMORY_COUNTERS_EX(ctypes.Structure):
125
            """Used by GetProcessMemoryInfo"""
126
            _fields_ = [('cb', ctypes.c_ulong),
127
                        ('PageFaultCount', ctypes.c_ulong),
128
                        ('PeakWorkingSetSize', ctypes.c_size_t),
129
                        ('WorkingSetSize', ctypes.c_size_t),
130
                        ('QuotaPeakPagedPoolUsage', ctypes.c_size_t),
131
                        ('QuotaPagedPoolUsage', ctypes.c_size_t),
132
                        ('QuotaPeakNonPagedPoolUsage', ctypes.c_size_t),
133
                        ('QuotaNonPagedPoolUsage', ctypes.c_size_t),
134
                        ('PagefileUsage', ctypes.c_size_t),
135
                        ('PeakPagefileUsage', ctypes.c_size_t),
136
                        ('PrivateUsage', ctypes.c_size_t),
137
                       ]
138
        cur_process = ctypes.windll.kernel32.GetCurrentProcess()
139
        mem_struct = PROCESS_MEMORY_COUNTERS_EX()
140
        ret = ctypes.windll.psapi.GetProcessMemoryInfo(cur_process,
141
            ctypes.byref(mem_struct),
142
            ctypes.sizeof(mem_struct))
143
        if not ret:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
144
            trace.note(gettext('Failed to GetProcessMemoryInfo()'))
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
145
            return
146
        info = {'PageFaultCount': mem_struct.PageFaultCount,
147
                'PeakWorkingSetSize': mem_struct.PeakWorkingSetSize,
148
                'WorkingSetSize': mem_struct.WorkingSetSize,
149
                'QuotaPeakPagedPoolUsage': mem_struct.QuotaPeakPagedPoolUsage,
150
                'QuotaPagedPoolUsage': mem_struct.QuotaPagedPoolUsage,
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
151
                'QuotaPeakNonPagedPoolUsage':
152
                    mem_struct.QuotaPeakNonPagedPoolUsage,
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
153
                'QuotaNonPagedPoolUsage': mem_struct.QuotaNonPagedPoolUsage,
154
                'PagefileUsage': mem_struct.PagefileUsage,
155
                'PeakPagefileUsage': mem_struct.PeakPagefileUsage,
156
                'PrivateUsage': mem_struct.PrivateUsage,
157
               }
4011.1.2 by John Arbash Meinel
Fix some small bugs, and prefer the ctypes form.
158
    elif has_win32api:
159
        import win32process
160
        # win32process does not return PrivateUsage, because it doesn't use
161
        # PROCESS_MEMORY_COUNTERS_EX (it uses the one without _EX).
162
        proc = win32process.GetCurrentProcess()
163
        info = win32process.GetProcessMemoryInfo(proc)
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
164
    else:
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
165
        trace.note(gettext('Cannot debug memory on win32 without ctypes'
166
                   ' or win32process'))
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
167
        return
4163.1.1 by John Arbash Meinel
Some small fixes for the win32 'trace.debug_mem()' code.
168
    if short:
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
169
        # 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
170
        trace.note(gettext('WorkingSize {0:>7}KiB'
171
                   '\tPeakWorking {1:>7}KiB\t{2}').format(
4163.1.1 by John Arbash Meinel
Some small fixes for the win32 'trace.debug_mem()' code.
172
                   info['WorkingSetSize'] / 1024,
173
                   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
174
                   message))
4163.1.1 by John Arbash Meinel
Some small fixes for the win32 'trace.debug_mem()' code.
175
        return
176
    if message:
177
        trace.note('%s', message)
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
178
    trace.note(gettext('WorkingSize       %8d KiB'), info['WorkingSetSize'] / 1024)
179
    trace.note(gettext('PeakWorking       %8d KiB'), info['PeakWorkingSetSize'] / 1024)
180
    trace.note(gettext('PagefileUsage     %8d KiB'), info.get('PagefileUsage', 0) / 1024)
181
    trace.note(gettext('PeakPagefileUsage %8d KiB'),
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
182
               info.get('PeakPagefileUsage', 0) / 1024)
6138.3.4 by Jonathan Riddell
add gettext() to uses of trace.note()
183
    trace.note(gettext('PrivateUsage      %8d KiB'), info.get('PrivateUsage', 0) / 1024)
184
    trace.note(gettext('PageFaultCount    %8d'), info.get('PageFaultCount', 0))
4011.1.1 by John Arbash Meinel
Implement -Dmemory for win32
185
186
1185.16.86 by mbp at sourcefrog
- win32 get_console_size from Alexander
187
def get_console_size(defaultx=80, defaulty=25):
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
188
    """Return size of current console.
189
190
    This function try to determine actual size of current working
191
    console window and return tuple (sizex, sizey) if success,
192
    or default size (defaultx, defaulty) otherwise.
193
    """
194
    if not has_ctypes:
195
        # no ctypes is found
196
        return (defaultx, defaulty)
197
198
    # To avoid problem with redirecting output via pipe
4747.3.6 by Vincent Ladeuil
terminal_width can now returns None.
199
    # we need to use stderr instead of stdout
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
200
    h = ctypes.windll.kernel32.GetStdHandle(WIN32_STDERR_HANDLE)
201
    csbi = ctypes.create_string_buffer(22)
202
    res = ctypes.windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
203
204
    if res:
205
        (bufx, bufy, curx, cury, wattr,
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
206
        left, top, right, bottom, maxx, maxy) = struct.unpack(
207
            "hhhhHhhhhhh", csbi.raw)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
208
        sizex = right - left + 1
209
        sizey = bottom - top + 1
210
        return (sizex, sizey)
211
    else:
212
        return (defaultx, defaulty)
213
214
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
215
def _get_sh_special_folder_path(csidl):
216
    """Call SHGetSpecialFolderPathW if available, or return None.
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
217
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
218
    Result is always unicode (or None).
219
    """
220
    if has_ctypes:
221
        try:
222
            SHGetSpecialFolderPath = \
223
                ctypes.windll.shell32.SHGetSpecialFolderPathW
224
        except AttributeError:
225
            pass
226
        else:
227
            buf = ctypes.create_unicode_buffer(MAX_PATH)
228
            if SHGetSpecialFolderPath(None,buf,csidl,0):
229
                return buf.value
230
231
    global has_win32com_shell
232
    if has_win32com_shell is None:
233
        try:
234
            from win32com.shell import shell
235
            has_win32com_shell = True
236
        except ImportError:
237
            has_win32com_shell = False
238
    if has_win32com_shell:
239
        # still need to bind the name locally, but this is fast.
240
        from win32com.shell import shell
241
        try:
242
            return shell.SHGetSpecialFolderPath(0, csidl, 0)
243
        except shell.error:
244
            # possibly E_NOTIMPL meaning we can't load the function pointer,
245
            # or E_FAIL meaning the function failed - regardless, just ignore it
246
            pass
247
    return None
248
249
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
250
def get_appdata_location():
251
    """Return Application Data location.
252
    Return None if we cannot obtain location.
253
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
254
    Windows defines two 'Application Data' folders per user - a 'roaming'
255
    one that moves with the user as they logon to different machines, and
256
    a 'local' one that stays local to the machine.  This returns the 'roaming'
257
    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
258
    """
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
259
    appdata = _get_sh_special_folder_path(CSIDL_APPDATA)
260
    if appdata:
261
        return appdata
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
262
    # Use APPDATA if defined, will return None if not
263
    return get_environ_unicode('APPDATA')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
264
265
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
266
def get_local_appdata_location():
267
    """Return Local Application Data location.
268
    Return the same as get_appdata_location() if we cannot obtain location.
269
270
    Windows defines two 'Application Data' folders per user - a 'roaming'
271
    one that moves with the user as they logon to different machines, and
272
    a 'local' one that stays local to the machine.  This returns the 'local'
273
    directory, and thus is suitable for caches, temp files and other things
274
    which don't need to move with the user.
275
    """
276
    local = _get_sh_special_folder_path(CSIDL_LOCAL_APPDATA)
277
    if local:
278
        return local
279
    # 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
280
    local = get_environ_unicode('LOCALAPPDATA')
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
281
    if local:
282
        return local
283
    return get_appdata_location()
284
285
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
286
def get_home_location():
287
    """Return user's home location.
288
    Assume on win32 it's the <My Documents> folder.
289
    If location cannot be obtained return system drive root,
290
    i.e. C:\
291
    """
3638.4.1 by Mark Hammond
Add win32utils.get_local_appdata_location() so bzr and plugins can
292
    home = _get_sh_special_folder_path(CSIDL_PERSONAL)
293
    if home:
294
        return home
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
295
    home = get_environ_unicode('HOME')
296
    if home is not None:
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
297
        return home
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
298
    homepath = get_environ_unicode('HOMEPATH')
299
    if homepath is not None:
300
        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
301
    # at least return windows root directory
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
302
    windir = get_environ_unicode('WINDIR')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
303
    if windir:
2610.1.1 by Martin Pool
Fix get_home_location on Win98 (gzlist,r=john,r=alexander)
304
        return os.path.splitdrive(windir)[0] + '/'
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
305
    # otherwise C:\ is good enough for 98% users
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
306
    return unicode('C:/')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
307
308
309
def get_user_name():
310
    """Return user name as login name.
311
    If name cannot be obtained return None.
312
    """
313
    if has_ctypes:
314
        try:
315
            advapi32 = ctypes.windll.advapi32
316
            GetUserName = getattr(advapi32, 'GetUserName'+suffix)
317
        except AttributeError:
318
            pass
319
        else:
320
            buf = create_buffer(UNLEN+1)
321
            n = ctypes.c_int(UNLEN+1)
322
            if GetUserName(buf, ctypes.byref(n)):
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
323
                return extract_buffer(buf)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
324
    # otherwise try env variables
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
325
    return get_environ_unicode('USERNAME')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
326
327
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
328
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
329
# computer or the cluster associated with the local computer."
330
_WIN32_ComputerNameDnsHostname = 1
331
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
332
def get_host_name():
333
    """Return host machine name.
334
    If name cannot be obtained return None.
335
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
336
    :return: A unicode string representing the host name.
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
337
    """
3626.1.2 by skip
win32utils.get_host_name() uses 'mbcs' encoding when decoding env vars
338
    if has_win32api:
339
        try:
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
340
            return win32api.GetComputerNameEx(_WIN32_ComputerNameDnsHostname)
3626.1.2 by skip
win32utils.get_host_name() uses 'mbcs' encoding when decoding env vars
341
        except (NotImplementedError, win32api.error):
342
            # NotImplemented will happen on win9x...
343
            pass
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
344
    if has_ctypes:
345
        try:
346
            kernel32 = ctypes.windll.kernel32
347
        except AttributeError:
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
348
            pass # Missing the module we need
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
349
        else:
350
            buf = create_buffer(MAX_COMPUTERNAME_LENGTH+1)
351
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
352
353
            # Try GetComputerNameEx which gives a proper Unicode hostname
354
            GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx'+suffix,
355
                                        None)
356
            if (GetComputerNameEx is not None
357
                and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
358
                                      buf, ctypes.byref(n))):
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
359
                return extract_buffer(buf)
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
360
361
            # Try GetComputerName in case GetComputerNameEx wasn't found
362
            # It returns the NETBIOS name, which isn't as good, but still ok.
363
            # The first GetComputerNameEx might have changed 'n', so reset it
364
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
365
            GetComputerName = getattr(kernel32, 'GetComputerName'+suffix,
366
                                      None)
367
            if (GetComputerName is not None
368
                and GetComputerName(buf, ctypes.byref(n))):
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
369
                return extract_buffer(buf)
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
370
    return get_environ_unicode('COMPUTERNAME')
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
371
372
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
373
@symbol_versioning.deprecated_method(
374
    symbol_versioning.deprecated_in((2, 5, 0)))
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
375
def _ensure_unicode(s):
376
    if s and type(s) != unicode:
3788.1.1 by John Arbash Meinel
Fix a missing import
377
        from bzrlib import osutils
3224.5.4 by Andrew Bennetts
Fix test suite, mainly weeding out uses of bzrlib.user_encoding.
378
        s = s.decode(osutils.get_user_encoding())
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
379
    return s
3626.1.3 by John Arbash Meinel
Use GetComputerNameEx from ctypes when available.
380
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
381
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
382
get_appdata_location_unicode = symbol_versioning.deprecated_method(
383
    symbol_versioning.deprecated_in((2, 5, 0)))(get_appdata_location)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
384
6362.2.2 by Martin Packman
Use get_environ_unicode throughout win32utils and always return unicode paths
385
get_home_location_unicode = symbol_versioning.deprecated_method(
386
    symbol_versioning.deprecated_in((2, 5, 0)))(get_home_location)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
387
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
388
get_user_name_unicode = symbol_versioning.deprecated_method(
389
    symbol_versioning.deprecated_in((2, 5, 0)))(get_user_name)
2245.4.1 by Alexander Belchenko
win32utils: Windows-specific functions that use Win32 API via ctypes
390
6362.2.3 by Martin Packman
Always return username and hostname as unicode in win32utils
391
get_host_name_unicode = symbol_versioning.deprecated_method(
392
    symbol_versioning.deprecated_in((2, 5, 0)))(get_host_name)
2568.2.2 by Robert Collins
* New method ``_glob_expand_file_list_if_needed`` on the ``Command`` class
393
394
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
395
def _ensure_with_dir(path):
4989.1.6 by Vincent Ladeuil
Add comments and update HACKING.txt about which units should be used.
396
    if (not os.path.split(path)[0] or path.startswith(u'*')
397
        or path.startswith(u'?')):
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
398
        return u'./' + path, True
399
    else:
400
        return path, False
3943.8.1 by Marius Kruger
remove all trailing whitespace from bzr source
401
2617.5.8 by Kuno Meyer
Extended tests for unicode chars outside of the iso-8859-* range
402
def _undo_ensure_with_dir(path, corrected):
403
    if corrected:
404
        return path[2:]
405
    else:
406
        return path
407
408
4786.1.2 by John Arbash Meinel
Refactor the glob_expand code a bit, making the inner function more reusable.
409
def glob_one(possible_glob):
410
    """Same as glob.glob().
411
412
    work around bugs in glob.glob()
413
    - Python bug #1001604 ("glob doesn't return unicode with ...")
414
    - failing expansion for */* with non-iso-8859-* chars
415
    """
416
    corrected_glob, corrected = _ensure_with_dir(possible_glob)
417
    glob_files = glob.glob(corrected_glob)
418
419
    if not glob_files:
420
        # special case to let the normal code path handle
421
        # files that do not exist, etc.
422
        glob_files = [possible_glob]
423
    elif corrected:
424
        glob_files = [_undo_ensure_with_dir(elem, corrected)
425
                      for elem in glob_files]
426
    return [elem.replace(u'\\', u'/') for elem in glob_files]
427
428
2598.3.1 by Kuno Meyer
fix method rename glob_expand_for_win32 -> win32utils.glob_expand
429
def glob_expand(file_list):
2568.2.2 by Robert Collins
* New method ``_glob_expand_file_list_if_needed`` on the ``Command`` class
430
    """Replacement for glob expansion by the shell.
431
432
    Win32's cmd.exe does not do glob expansion (eg ``*.py``), so we do our own
433
    here.
434
435
    :param file_list: A list of filenames which may include shell globs.
436
    :return: An expanded list of filenames.
437
438
    Introduced in bzrlib 0.18.
439
    """
440
    if not file_list:
441
        return []
442
    expanded_file_list = []
443
    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.
444
        expanded_file_list.extend(glob_one(possible_glob))
445
    return expanded_file_list
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
446
447
448
def get_app_path(appname):
5891.1.2 by Andrew Bennetts
Fix a bunch of docstring formatting nits, making pydoctor a bit happier.
449
    r"""Look up in Windows registry for full path to application executable.
4031.3.1 by Frank Aspell
Fixing various typos
450
    Typically, applications create subkey with their basename
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
451
    in HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\App Paths\
452
453
    :param  appname:    name of application (if no filename extension
454
                        is specified, .exe used)
455
    :return:    full path to aplication executable from registry,
456
                or appname itself if nothing found.
457
    """
2681.4.3 by Alexander Belchenko
move import _winreg into function get_app_path to avoid ImportError on non-win32 platforms
458
    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).
459
460
    basename = appname
461
    if not os.path.splitext(basename)[1]:
462
        basename = appname + '.exe'
463
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
464
    try:
465
        hkey = _winreg.OpenKey(_winreg.HKEY_LOCAL_MACHINE,
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
466
            'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\App Paths\\' +
467
            basename)
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
468
    except EnvironmentError:
469
        return appname
470
471
    try:
472
        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).
473
            path, type_id = _winreg.QueryValueEx(hkey, '')
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
474
        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).
475
            return appname
2681.4.1 by Alexander Belchenko
win32: looking for full path of mail client executable in registry
476
    finally:
477
        _winreg.CloseKey(hkey)
478
4476.2.1 by Alexander Belchenko
win32utils.py: get_app_path() can read path for wordpad.exe (data type_id is REG_EXPAND_SZ).
479
    if type_id == REG_SZ:
480
        return path
481
    if type_id == REG_EXPAND_SZ and has_win32api:
482
        fullpath = win32api.ExpandEnvironmentStrings(path)
4476.2.2 by Alexander Belchenko
remove quotes around value only if there is pair of quotes (igc review)
483
        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).
484
            fullpath = fullpath[1:-1]   # remove quotes around value
485
        return fullpath
486
    return appname
3023.1.2 by Alexander Belchenko
Martin's review.
487
488
489
def set_file_attr_hidden(path):
490
    """Set file attributes to hidden if possible"""
491
    if has_win32file:
4505.2.1 by Alexander Belchenko
Set hidden attribute on .bzr directory below unicode path should never fail with error. The operation should succeed even if bzr unable to set the attribute. (related to bug #335362).
492
        if winver != 'Windows 98':
493
            SetFileAttributes = win32file.SetFileAttributesW
494
        else:
495
            SetFileAttributes = win32file.SetFileAttributes
496
        try:
497
            SetFileAttributes(path, win32file.FILE_ATTRIBUTE_HIDDEN)
498
        except pywintypes.error, e:
4505.2.2 by Alexander Belchenko
forgotten import
499
            from bzrlib import trace
4505.2.1 by Alexander Belchenko
Set hidden attribute on .bzr directory below unicode path should never fail with error. The operation should succeed even if bzr unable to set the attribute. (related to bug #335362).
500
            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.
501
502
5274.4.12 by Martin
Change interface of _command_line_to_argv so old tests can still be used with new stripping logic
503
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.
504
    """Convert a Unicode command line into a list of argv arguments.
505
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.
506
    It performs wildcard expansion to make wildcards act closer to how they
507
    work in posix shells, versus how they work by default on Windows. Quoted
508
    arguments are left untouched.
4913.5.2 by Gordon Tyler
Changed shlex_split_unicode to prevent wildcard expansion in the win32 codepath.
509
510
    :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).
511
    :param single_quotes_allowed: Whether single quotes are accepted as quoting
512
                                  characters like double quotes. False by
513
                                  default.
4913.5.2 by Gordon Tyler
Changed shlex_split_unicode to prevent wildcard expansion in the win32 codepath.
514
    :return: A list of unicode strings.
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
515
    """
5274.4.1 by Jason Spashett
Initial Fix for 587868
516
    # First, spit the command line
4913.5.23 by Gordon Tyler
Renamed cmdline.Parser to Splitter to better match its usage.
517
    s = cmdline.Splitter(command_line, single_quotes_allowed=single_quotes_allowed)
5274.4.1 by Jason Spashett
Initial Fix for 587868
518
    
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
519
    # Bug #587868 Now make sure that the length of s agrees with sys.argv 
520
    # we do this by simply counting the number of arguments in each. The counts should 
521
    # agree no matter what encoding sys.argv is in (AFAIK) 
522
    # len(arguments) < len(sys.argv) should be an impossibility since python gets 
523
    # args from the very same PEB as does GetCommandLineW
524
    arguments = list(s)
525
    
526
    # 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
527
    if len(arguments) < len(argv):
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
528
        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
529
    arguments = arguments[len(arguments) - len(argv):]
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
530
    
5274.4.2 by Jason Spashett
Tidied up fix for 587868. Put assert in for impossible case in command line lengths.
531
    # Carry on to process globs (metachars) in the command line
5274.4.1 by Jason Spashett
Initial Fix for 587868
532
    # expand globs if necessary
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
533
    # TODO: Use 'globbing' instead of 'glob.glob', this gives us stuff like
534
    #       '**/' style globs
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
535
    args = []
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
536
    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.
537
        if is_quoted or not glob.has_magic(arg):
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
538
            args.append(arg)
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
539
        else:
5274.4.11 by Martin
Minor cleanup, use plain AssertionError and revert needless variable rename
540
            args.extend(glob_one(arg))
541
    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.
542
4786.1.1 by John Arbash Meinel
Work on doing globbing, etc for all commands on Windows.
543
6339.2.4 by Martin Packman
Bind name get_environ_unicode to None if function is unsupported
544
if has_ctypes and winver == 'Windows NT':
4355.2.1 by Alexander Belchenko
Using unicode Windows API to obtain command-line arguments.
545
    def get_unicode_argv():
4913.5.15 by Gordon Tyler
Python < 2.6 doesn't support use_last_error.
546
        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.
547
        GetCommandLineW = prototype(("GetCommandLineW",
548
                                     ctypes.windll.kernel32))
549
        command_line = GetCommandLineW()
550
        if command_line is None:
551
            raise ctypes.WinError()
5274.4.8 by Jason Spashett
Reverse merge -r 5280..5279
552
        # 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
553
        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.
554
        return argv
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
555
    
556
6339.2.3 by Martin Packman
Remove ability to specify a maximum buffer size as it serves no particular purpose
557
    def get_environ_unicode(key, default=None):
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
558
        """Get `key` from environment as unicode or `default` if unset
559
6362.2.5 by Martin Packman
Tweaks including those suggested by vila in review
560
        The environment is natively unicode on modern windows versions but
561
        Python 2 only accesses it through the legacy bytestring api.
562
563
        Environmental variable names are case insenstive on Windows.
564
6339.2.3 by Martin Packman
Remove ability to specify a maximum buffer size as it serves no particular purpose
565
        A large enough buffer will be allocated to retrieve the value, though
566
        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
567
568
        This needs ctypes because pywin32 does not expose the wide version.
569
        """
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
570
        cfunc = getattr(get_environ_unicode, "_c_function", None)
571
        if cfunc is None:
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
572
            from ctypes.wintypes import DWORD, LPCWSTR, LPWSTR
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
573
            cfunc = ctypes.WINFUNCTYPE(DWORD, LPCWSTR, LPWSTR, DWORD)(
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
574
                ("GetEnvironmentVariableW", ctypes.windll.kernel32))
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
575
            get_environ_unicode._c_function = cfunc
6339.2.3 by Martin Packman
Remove ability to specify a maximum buffer size as it serves no particular purpose
576
        buffer_size = 256 # heuristic, 256 characters often enough
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
577
        while True:
578
            buffer = ctypes.create_unicode_buffer(buffer_size)
6339.2.2 by Martin Packman
Variable name changes and docstring fix suggested by vila in review
579
            length = cfunc(key, buffer, buffer_size)
6339.2.1 by Martin Packman
Add wrapper for GetEnvironmentVariableW on windows for unicode environ access
580
            if not length:
581
                code = ctypes.GetLastError()
582
                if code == 203: # ERROR_ENVVAR_NOT_FOUND
583
                    return default
584
                raise ctypes.WinError(code)
585
            if buffer_size > length:
586
                return buffer[:length]
587
            buffer_size = length
4355.2.2 by Alexander Belchenko
osutils.py: get_unicode_argv function (to obtain unicode command line arguments from sys.argv) moved to the beginning of module based on suggestions from review of John Meinel.
588
else:
6362.2.1 by Martin Packman
Add path_from_environ function for getting unicode paths from envvars
589
    get_unicode_argv = None
590
    def get_environ_unicode(key, default=None):
591
        """Get `key` from environment as unicode or `default` if unset
592
593
        Fallback version that should basically never be needed.
594
        """
595
        try:
596
            return os.environ[key].decode("mbcs")
597
        except KeyError:
598
            return default
5425.5.5 by Martin
Quick implementation of dead process detection on win32
599
600
601
if has_win32api:
602
    def _pywin32_is_local_pid_dead(pid):
603
        """True if pid doesn't correspond to live process on this machine"""
604
        try:
605
            handle = win32api.OpenProcess(1, False, pid) # PROCESS_TERMINATE
606
        except pywintypes.error, e:
5425.5.7 by Martin
Get the code for ERROR_ACCESS_DENIED right
607
            if e[0] == 5: # ERROR_ACCESS_DENIED
5425.5.5 by Martin
Quick implementation of dead process detection on win32
608
                # Probably something alive we're not allowed to kill
609
                return False
610
            elif e[0] == 87: # ERROR_INVALID_PARAMETER
611
                return True
612
            raise
613
        handle.close()
614
        return False
615
    is_local_pid_dead = _pywin32_is_local_pid_dead
5425.4.29 by Martin Pool
Don't try to get ctypes access to OpenProcess on non-win32 platforms
616
elif has_ctypes and sys.platform == 'win32':
5425.5.5 by Martin
Quick implementation of dead process detection on win32
617
    from ctypes.wintypes import BOOL, DWORD, HANDLE
618
    _kernel32 = ctypes.windll.kernel32
619
    _CloseHandle = ctypes.WINFUNCTYPE(BOOL, HANDLE)(
620
        ("CloseHandle", _kernel32))
621
    _OpenProcess = ctypes.WINFUNCTYPE(HANDLE, DWORD, BOOL, DWORD)(
622
        ("OpenProcess", _kernel32))
623
    def _ctypes_is_local_pid_dead(pid):
624
        """True if pid doesn't correspond to live process on this machine"""
625
        handle = _OpenProcess(1, False, pid) # PROCESS_TERMINATE
626
        if not handle:
627
            errorcode = ctypes.GetLastError()
5425.5.7 by Martin
Get the code for ERROR_ACCESS_DENIED right
628
            if errorcode == 5: # ERROR_ACCESS_DENIED
5425.5.5 by Martin
Quick implementation of dead process detection on win32
629
                # Probably something alive we're not allowed to kill
630
                return False
631
            elif errorcode == 87: # ERROR_INVALID_PARAMETER
632
                return True
633
            raise ctypes.WinError(errorcode)
634
        _CloseHandle(handle)
635
        return False
636
    is_local_pid_dead = _ctypes_is_local_pid_dead
6336.2.1 by Martin Packman
Add is_environment_error() and switch trace to using it
637
638
639
def _is_pywintypes_error(evalue):
6336.2.2 by Martin Packman
Tweak how pywin32 is imported in win32utils to fix test failure edge case
640
    """True if exception instance is an error from pywin32"""
641
    if has_pywintypes and isinstance(evalue, pywintypes.error):
6336.2.1 by Martin Packman
Add is_environment_error() and switch trace to using it
642
        return True
643
    return False