1
# -*- test-case-name: twisted.python.test.test_win32 -*-
2
# Copyright (c) 2001-2010 Twisted Matrix Laboratories.
3
# See LICENSE for details.
8
See also twisted.python.shortcut.
21
from twisted.python.runtime import platform
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
29
def _determineWindowsError():
31
Determine which WindowsError name to export.
33
return getattr(exceptions, 'WindowsError', FakeWindowsError)
35
class FakeWindowsError(OSError):
37
Stand-in for sometimes-builtin exception on platforms for which it
41
WindowsError = _determineWindowsError()
43
# XXX fix this to use python's builtin _winreg?
45
def getProgramsMenuPath():
46
"""Get the path to the Programs menu.
48
Probably will break on non-US Windows.
50
@returns: the filesystem location of the common Start Menu->Programs.
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]
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]
67
_cmdLineQuoteRe = re.compile(r'(\\*)"')
68
_cmdLineQuoteRe2 = re.compile(r'(\\+)\Z')
71
Internal method for quoting a single command-line argument.
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.
78
@return: a quoted string.
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
84
def quoteArguments(arguments):
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.
90
@param arglist: an iterable of C{str}, each unquoted.
92
@return: a single string, with the given sequence quoted as necessary.
94
return ' '.join([cmdLineQuote(a) for a in arguments])
97
class _ErrorFormatter(object):
99
Formatter for Windows error messages.
101
@ivar winError: A callable which takes one integer error number argument
102
and returns an L{exceptions.WindowsError} instance for that error (like
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}).
109
@ivar errorTab: A mapping from integer error numbers to C{str} messages
110
which correspond to those erorrs (like L{socket.errorTab}).
112
def __init__(self, WinError, FormatMessage, errorTab):
113
self.winError = WinError
114
self.formatMessage = FormatMessage
115
self.errorTab = errorTab
117
def fromEnvironment(cls):
119
Get as many of the platform-specific error translation objects as
120
possible and return an instance of C{cls} created with them.
123
from ctypes import WinError
127
from win32api import FormatMessage
131
from socket import errorTab
134
return cls(WinError, FormatMessage, errorTab)
135
fromEnvironment = classmethod(fromEnvironment)
138
def formatError(self, errorcode):
140
Returns the string associated with a Windows error message, such as the
141
ones found in socket.error.
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}.
147
@param errorcode: the Windows error code
148
@type errorcode: C{int}
150
@return: The error message string
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:
161
return os.strerror(errorcode)
163
formatError = _ErrorFormatter.fromEnvironment().formatError