~bzr-pqm/bzr/bzr.dev

« back to all changes in this revision

Viewing changes to bzrlib/win32utils.py

  • Committer: Canonical.com Patch Queue Manager
  • Date: 2008-09-03 20:58:40 UTC
  • mfrom: (3626.1.6 unicode_hostname)
  • Revision ID: pqm@pqm.ubuntu.com-20080903205840-mteswj8dfvld7vo3
(Mark Hammond) Fix bug #256550 by using a Unicode api on Windows for
        the host name.

Show diffs side-by-side

added added

removed removed

Lines of Context:
69
69
    has_win32file = True
70
70
except ImportError:
71
71
    has_win32file = False
 
72
try:
 
73
    import win32api
 
74
    has_win32api = True
 
75
except ImportError:
 
76
    has_win32api = False
72
77
 
73
78
 
74
79
# Special Win32 API constants
202
207
    return os.environ.get('USERNAME', None)
203
208
 
204
209
 
 
210
# 1 == ComputerNameDnsHostname, which returns "The DNS host name of the local
 
211
# computer or the cluster associated with the local computer."
 
212
_WIN32_ComputerNameDnsHostname = 1
 
213
 
205
214
def get_host_name():
206
215
    """Return host machine name.
207
216
    If name cannot be obtained return None.
208
217
 
209
 
    Returned value can be unicode or plain sring.
210
 
    To convert plain string to unicode use
211
 
    s.decode(bzrlib.user_encoding)
 
218
    :return: A unicode string representing the host name. On win98, this may be
 
219
        a plain string as win32 api doesn't support unicode.
212
220
    """
 
221
    if has_win32api:
 
222
        try:
 
223
            return win32api.GetComputerNameEx(_WIN32_ComputerNameDnsHostname)
 
224
        except (NotImplementedError, win32api.error):
 
225
            # NotImplemented will happen on win9x...
 
226
            pass
213
227
    if has_ctypes:
214
228
        try:
215
229
            kernel32 = ctypes.windll.kernel32
216
 
            GetComputerName = getattr(kernel32, 'GetComputerName'+suffix)
217
230
        except AttributeError:
218
 
            pass
 
231
            pass # Missing the module we need
219
232
        else:
220
233
            buf = create_buffer(MAX_COMPUTERNAME_LENGTH+1)
221
234
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
222
 
            if GetComputerName(buf, ctypes.byref(n)):
223
 
                return buf.value
224
 
    # otherwise try env variables
225
 
    return os.environ.get('COMPUTERNAME', None)
 
235
 
 
236
            # Try GetComputerNameEx which gives a proper Unicode hostname
 
237
            GetComputerNameEx = getattr(kernel32, 'GetComputerNameEx'+suffix,
 
238
                                        None)
 
239
            if (GetComputerNameEx is not None
 
240
                and GetComputerNameEx(_WIN32_ComputerNameDnsHostname,
 
241
                                      buf, ctypes.byref(n))):
 
242
                return buf.value
 
243
 
 
244
            # Try GetComputerName in case GetComputerNameEx wasn't found
 
245
            # It returns the NETBIOS name, which isn't as good, but still ok.
 
246
            # The first GetComputerNameEx might have changed 'n', so reset it
 
247
            n = ctypes.c_int(MAX_COMPUTERNAME_LENGTH+1)
 
248
            GetComputerName = getattr(kernel32, 'GetComputerName'+suffix,
 
249
                                      None)
 
250
            if (GetComputerName is not None
 
251
                and GetComputerName(buf, ctypes.byref(n))):
 
252
                return buf.value
 
253
    # otherwise try env variables, which will be 'mbcs' encoded
 
254
    # on Windows (Python doesn't expose the native win32 unicode environment)
 
255
    # According to this:
 
256
    # http://msdn.microsoft.com/en-us/library/aa246807.aspx
 
257
    # environment variables should always be encoded in 'mbcs'.
 
258
    try:
 
259
        return os.environ['COMPUTERNAME'].decode("mbcs")
 
260
    except KeyError:
 
261
        return None
226
262
 
227
263
 
228
264
def _ensure_unicode(s):
230
266
        import bzrlib
231
267
        s = s.decode(bzrlib.user_encoding)
232
268
    return s
233
 
    
 
269
 
234
270
 
235
271
def get_appdata_location_unicode():
236
272
    return _ensure_unicode(get_appdata_location())