~0x44/nova/bug838466

« back to all changes in this revision

Viewing changes to vendor/Twisted-10.0.0/twisted/python/win32.py

  • Committer: Jesse Andrews
  • Date: 2010-05-28 06:05:26 UTC
  • Revision ID: git-v1:bf6e6e718cdc7488e2da87b21e258ccc065fe499
initial commit

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
# -*- test-case-name: twisted.python.test.test_win32 -*-
 
2
# Copyright (c) 2001-2010 Twisted Matrix Laboratories.
 
3
# See LICENSE for details.
 
4
 
 
5
"""
 
6
Win32 utilities.
 
7
 
 
8
See also twisted.python.shortcut.
 
9
"""
 
10
 
 
11
import re
 
12
import exceptions
 
13
import os
 
14
 
 
15
try:
 
16
    import win32api
 
17
    import win32con
 
18
except ImportError:
 
19
    pass
 
20
 
 
21
from twisted.python.runtime import platform
 
22
 
 
23
# http://msdn.microsoft.com/library/default.asp?url=/library/en-us/debug/base/system_error_codes.asp
 
24
ERROR_FILE_NOT_FOUND = 2
 
25
ERROR_PATH_NOT_FOUND = 3
 
26
ERROR_INVALID_NAME = 123
 
27
ERROR_DIRECTORY = 267
 
28
 
 
29
def _determineWindowsError():
 
30
    """
 
31
    Determine which WindowsError name to export.
 
32
    """
 
33
    return getattr(exceptions, 'WindowsError', FakeWindowsError)
 
34
 
 
35
class FakeWindowsError(OSError):
 
36
    """
 
37
    Stand-in for sometimes-builtin exception on platforms for which it
 
38
    is missing.
 
39
    """
 
40
 
 
41
WindowsError = _determineWindowsError()
 
42
 
 
43
# XXX fix this to use python's builtin _winreg?
 
44
 
 
45
def getProgramsMenuPath():
 
46
    """Get the path to the Programs menu.
 
47
 
 
48
    Probably will break on non-US Windows.
 
49
 
 
50
    @returns: the filesystem location of the common Start Menu->Programs.
 
51
    """
 
52
    if not platform.isWinNT():
 
53
        return "C:\\Windows\\Start Menu\\Programs"
 
54
    keyname = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders'
 
55
    hShellFolders = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE,
 
56
                                          keyname, 0, win32con.KEY_READ)
 
57
    return win32api.RegQueryValueEx(hShellFolders, 'Common Programs')[0]
 
58
 
 
59
 
 
60
def getProgramFilesPath():
 
61
    """Get the path to the Program Files folder."""
 
62
    keyname = 'SOFTWARE\\Microsoft\\Windows\\CurrentVersion'
 
63
    currentV = win32api.RegOpenKeyEx(win32con.HKEY_LOCAL_MACHINE,
 
64
                                     keyname, 0, win32con.KEY_READ)
 
65
    return win32api.RegQueryValueEx(currentV, 'ProgramFilesDir')[0]
 
66
 
 
67
_cmdLineQuoteRe = re.compile(r'(\\*)"')
 
68
_cmdLineQuoteRe2 = re.compile(r'(\\+)\Z')
 
69
def cmdLineQuote(s):
 
70
    """
 
71
    Internal method for quoting a single command-line argument.
 
72
 
 
73
    @param s: an unquoted string that you want to quote so that something that
 
74
        does cmd.exe-style unquoting will interpret it as a single argument,
 
75
        even if it contains spaces.
 
76
    @type s: C{str}
 
77
 
 
78
    @return: a quoted string.
 
79
    @rtype: C{str}
 
80
    """
 
81
    quote = ((" " in s) or ("\t" in s) or ('"' in s) or s == '') and '"' or ''
 
82
    return quote + _cmdLineQuoteRe2.sub(r"\1\1", _cmdLineQuoteRe.sub(r'\1\1\\"', s)) + quote
 
83
 
 
84
def quoteArguments(arguments):
 
85
    """
 
86
    Quote an iterable of command-line arguments for passing to CreateProcess or
 
87
    a similar API.  This allows the list passed to C{reactor.spawnProcess} to
 
88
    match the child process's C{sys.argv} properly.
 
89
 
 
90
    @param arglist: an iterable of C{str}, each unquoted.
 
91
 
 
92
    @return: a single string, with the given sequence quoted as necessary.
 
93
    """
 
94
    return ' '.join([cmdLineQuote(a) for a in arguments])
 
95
 
 
96
 
 
97
class _ErrorFormatter(object):
 
98
    """
 
99
    Formatter for Windows error messages.
 
100
 
 
101
    @ivar winError: A callable which takes one integer error number argument
 
102
        and returns an L{exceptions.WindowsError} instance for that error (like
 
103
        L{ctypes.WinError}).
 
104
 
 
105
    @ivar formatMessage: A callable which takes one integer error number
 
106
        argument and returns a C{str} giving the message for that error (like
 
107
        L{win32api.FormatMessage}).
 
108
 
 
109
    @ivar errorTab: A mapping from integer error numbers to C{str} messages
 
110
        which correspond to those erorrs (like L{socket.errorTab}).
 
111
    """
 
112
    def __init__(self, WinError, FormatMessage, errorTab):
 
113
        self.winError = WinError
 
114
        self.formatMessage = FormatMessage
 
115
        self.errorTab = errorTab
 
116
 
 
117
    def fromEnvironment(cls):
 
118
        """
 
119
        Get as many of the platform-specific error translation objects as
 
120
        possible and return an instance of C{cls} created with them.
 
121
        """
 
122
        try:
 
123
            from ctypes import WinError
 
124
        except ImportError:
 
125
            WinError = None
 
126
        try:
 
127
            from win32api import FormatMessage
 
128
        except ImportError:
 
129
            FormatMessage = None
 
130
        try:
 
131
            from socket import errorTab
 
132
        except ImportError:
 
133
            errorTab = None
 
134
        return cls(WinError, FormatMessage, errorTab)
 
135
    fromEnvironment = classmethod(fromEnvironment)
 
136
 
 
137
 
 
138
    def formatError(self, errorcode):
 
139
        """
 
140
        Returns the string associated with a Windows error message, such as the
 
141
        ones found in socket.error.
 
142
 
 
143
        Attempts direct lookup against the win32 API via ctypes and then
 
144
        pywin32 if available), then in the error table in the socket module,
 
145
        then finally defaulting to C{os.strerror}.
 
146
 
 
147
        @param errorcode: the Windows error code
 
148
        @type errorcode: C{int}
 
149
 
 
150
        @return: The error message string
 
151
        @rtype: C{str}
 
152
        """
 
153
        if self.winError is not None:
 
154
            return self.winError(errorcode)[1]
 
155
        if self.formatMessage is not None:
 
156
            return self.formatMessage(errorcode)
 
157
        if self.errorTab is not None:
 
158
            result = self.errorTab.get(errorcode)
 
159
            if result is not None:
 
160
                return result
 
161
        return os.strerror(errorcode)
 
162
 
 
163
formatError = _ErrorFormatter.fromEnvironment().formatError