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