1 /*
2 * Win32 functions used by multiprocessing package
3 *
4 * win32_functions.c
5 *
6 * Copyright (c) 2006-2008, R Oudkerk --- see COPYING.txt
7 */
8
9 #include "multiprocessing.h"
10
11
12 #define WIN32_FUNCTION(func) \
13 {#func, (PyCFunction)win32_ ## func, METH_VARARGS | METH_STATIC, ""}
14
15 #define WIN32_CONSTANT(fmt, con) \
16 PyDict_SetItemString(Win32Type.tp_dict, #con, Py_BuildValue(fmt, con))
17
18
19 static PyObject *
win32_CloseHandle(PyObject * self,PyObject * args)20 win32_CloseHandle(PyObject *self, PyObject *args)
21 {
22 HANDLE hObject;
23 BOOL success;
24
25 if (!PyArg_ParseTuple(args, F_HANDLE, &hObject))
26 return NULL;
27
28 Py_BEGIN_ALLOW_THREADS
29 success = CloseHandle(hObject);
30 Py_END_ALLOW_THREADS
31
32 if (!success)
33 return PyErr_SetFromWindowsErr(0);
34
35 Py_RETURN_NONE;
36 }
37
38 static PyObject *
win32_ConnectNamedPipe(PyObject * self,PyObject * args)39 win32_ConnectNamedPipe(PyObject *self, PyObject *args)
40 {
41 HANDLE hNamedPipe;
42 LPOVERLAPPED lpOverlapped;
43 BOOL success;
44
45 if (!PyArg_ParseTuple(args, F_HANDLE F_POINTER,
46 &hNamedPipe, &lpOverlapped))
47 return NULL;
48
49 Py_BEGIN_ALLOW_THREADS
50 success = ConnectNamedPipe(hNamedPipe, lpOverlapped);
51 Py_END_ALLOW_THREADS
52
53 if (!success)
54 return PyErr_SetFromWindowsErr(0);
55
56 Py_RETURN_NONE;
57 }
58
59 static PyObject *
win32_CreateFile(PyObject * self,PyObject * args)60 win32_CreateFile(PyObject *self, PyObject *args)
61 {
62 LPCTSTR lpFileName;
63 DWORD dwDesiredAccess;
64 DWORD dwShareMode;
65 LPSECURITY_ATTRIBUTES lpSecurityAttributes;
66 DWORD dwCreationDisposition;
67 DWORD dwFlagsAndAttributes;
68 HANDLE hTemplateFile;
69 HANDLE handle;
70
71 if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_POINTER
72 F_DWORD F_DWORD F_HANDLE,
73 &lpFileName, &dwDesiredAccess, &dwShareMode,
74 &lpSecurityAttributes, &dwCreationDisposition,
75 &dwFlagsAndAttributes, &hTemplateFile))
76 return NULL;
77
78 Py_BEGIN_ALLOW_THREADS
79 handle = CreateFile(lpFileName, dwDesiredAccess,
80 dwShareMode, lpSecurityAttributes,
81 dwCreationDisposition,
82 dwFlagsAndAttributes, hTemplateFile);
83 Py_END_ALLOW_THREADS
84
85 if (handle == INVALID_HANDLE_VALUE)
86 return PyErr_SetFromWindowsErr(0);
87
88 return Py_BuildValue(F_HANDLE, handle);
89 }
90
91 static PyObject *
win32_CreateNamedPipe(PyObject * self,PyObject * args)92 win32_CreateNamedPipe(PyObject *self, PyObject *args)
93 {
94 LPCTSTR lpName;
95 DWORD dwOpenMode;
96 DWORD dwPipeMode;
97 DWORD nMaxInstances;
98 DWORD nOutBufferSize;
99 DWORD nInBufferSize;
100 DWORD nDefaultTimeOut;
101 LPSECURITY_ATTRIBUTES lpSecurityAttributes;
102 HANDLE handle;
103
104 if (!PyArg_ParseTuple(args, "s" F_DWORD F_DWORD F_DWORD
105 F_DWORD F_DWORD F_DWORD F_POINTER,
106 &lpName, &dwOpenMode, &dwPipeMode,
107 &nMaxInstances, &nOutBufferSize,
108 &nInBufferSize, &nDefaultTimeOut,
109 &lpSecurityAttributes))
110 return NULL;
111
112 Py_BEGIN_ALLOW_THREADS
113 handle = CreateNamedPipe(lpName, dwOpenMode, dwPipeMode,
114 nMaxInstances, nOutBufferSize,
115 nInBufferSize, nDefaultTimeOut,
116 lpSecurityAttributes);
117 Py_END_ALLOW_THREADS
118
119 if (handle == INVALID_HANDLE_VALUE)
120 return PyErr_SetFromWindowsErr(0);
121
122 return Py_BuildValue(F_HANDLE, handle);
123 }
124
125 static PyObject *
win32_ExitProcess(PyObject * self,PyObject * args)126 win32_ExitProcess(PyObject *self, PyObject *args)
127 {
128 UINT uExitCode;
129
130 if (!PyArg_ParseTuple(args, "I", &uExitCode))
131 return NULL;
132
133 #if defined(Py_DEBUG)
134 SetErrorMode(SEM_FAILCRITICALERRORS|SEM_NOALIGNMENTFAULTEXCEPT|SEM_NOGPFAULTERRORBOX|SEM_NOOPENFILEERRORBOX);
135 _CrtSetReportMode(_CRT_ASSERT, _CRTDBG_MODE_DEBUG);
136 #endif
137
138
139 ExitProcess(uExitCode);
140
141 return NULL;
142 }
143
144 static PyObject *
win32_GetLastError(PyObject * self,PyObject * args)145 win32_GetLastError(PyObject *self, PyObject *args)
146 {
147 return Py_BuildValue(F_DWORD, GetLastError());
148 }
149
150 static PyObject *
win32_OpenProcess(PyObject * self,PyObject * args)151 win32_OpenProcess(PyObject *self, PyObject *args)
152 {
153 DWORD dwDesiredAccess;
154 BOOL bInheritHandle;
155 DWORD dwProcessId;
156 HANDLE handle;
157
158 if (!PyArg_ParseTuple(args, F_DWORD "i" F_DWORD,
159 &dwDesiredAccess, &bInheritHandle, &dwProcessId))
160 return NULL;
161
162 handle = OpenProcess(dwDesiredAccess, bInheritHandle, dwProcessId);
163 if (handle == NULL)
164 return PyErr_SetFromWindowsErr(0);
165
166 return Py_BuildValue(F_HANDLE, handle);
167 }
168
169 static PyObject *
win32_SetNamedPipeHandleState(PyObject * self,PyObject * args)170 win32_SetNamedPipeHandleState(PyObject *self, PyObject *args)
171 {
172 HANDLE hNamedPipe;
173 PyObject *oArgs[3];
174 DWORD dwArgs[3], *pArgs[3] = {NULL, NULL, NULL};
175 int i;
176
177 if (!PyArg_ParseTuple(args, F_HANDLE "OOO",
178 &hNamedPipe, &oArgs[0], &oArgs[1], &oArgs[2]))
179 return NULL;
180
181 PyErr_Clear();
182
183 for (i = 0 ; i < 3 ; i++) {
184 if (oArgs[i] != Py_None) {
185 dwArgs[i] = PyInt_AsUnsignedLongMask(oArgs[i]);
186 if (PyErr_Occurred())
187 return NULL;
188 pArgs[i] = &dwArgs[i];
189 }
190 }
191
192 if (!SetNamedPipeHandleState(hNamedPipe, pArgs[0], pArgs[1], pArgs[2]))
193 return PyErr_SetFromWindowsErr(0);
194
195 Py_RETURN_NONE;
196 }
197
198 static PyObject *
win32_WaitNamedPipe(PyObject * self,PyObject * args)199 win32_WaitNamedPipe(PyObject *self, PyObject *args)
200 {
201 LPCTSTR lpNamedPipeName;
202 DWORD nTimeOut;
203 BOOL success;
204
205 if (!PyArg_ParseTuple(args, "s" F_DWORD, &lpNamedPipeName, &nTimeOut))
206 return NULL;
207
208 Py_BEGIN_ALLOW_THREADS
209 success = WaitNamedPipe(lpNamedPipeName, nTimeOut);
210 Py_END_ALLOW_THREADS
211
212 if (!success)
213 return PyErr_SetFromWindowsErr(0);
214
215 Py_RETURN_NONE;
216 }
217
218 static PyMethodDef win32_methods[] = {
219 WIN32_FUNCTION(CloseHandle),
220 WIN32_FUNCTION(GetLastError),
221 WIN32_FUNCTION(OpenProcess),
222 WIN32_FUNCTION(ExitProcess),
223 WIN32_FUNCTION(ConnectNamedPipe),
224 WIN32_FUNCTION(CreateFile),
225 WIN32_FUNCTION(CreateNamedPipe),
226 WIN32_FUNCTION(SetNamedPipeHandleState),
227 WIN32_FUNCTION(WaitNamedPipe),
228 {NULL}
229 };
230
231
232 PyTypeObject Win32Type = {
233 PyVarObject_HEAD_INIT(NULL, 0)
234 };
235
236
237 PyObject *
create_win32_namespace(void)238 create_win32_namespace(void)
239 {
240 Win32Type.tp_name = "_multiprocessing.win32";
241 Win32Type.tp_methods = win32_methods;
242 if (PyType_Ready(&Win32Type) < 0)
243 return NULL;
244 Py_INCREF(&Win32Type);
245
246 WIN32_CONSTANT(F_DWORD, ERROR_ALREADY_EXISTS);
247 WIN32_CONSTANT(F_DWORD, ERROR_NO_DATA);
248 WIN32_CONSTANT(F_DWORD, ERROR_PIPE_BUSY);
249 WIN32_CONSTANT(F_DWORD, ERROR_PIPE_CONNECTED);
250 WIN32_CONSTANT(F_DWORD, ERROR_SEM_TIMEOUT);
251 WIN32_CONSTANT(F_DWORD, GENERIC_READ);
252 WIN32_CONSTANT(F_DWORD, GENERIC_WRITE);
253 WIN32_CONSTANT(F_DWORD, INFINITE);
254 WIN32_CONSTANT(F_DWORD, NMPWAIT_WAIT_FOREVER);
255 WIN32_CONSTANT(F_DWORD, OPEN_EXISTING);
256 WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_DUPLEX);
257 WIN32_CONSTANT(F_DWORD, PIPE_ACCESS_INBOUND);
258 WIN32_CONSTANT(F_DWORD, PIPE_READMODE_MESSAGE);
259 WIN32_CONSTANT(F_DWORD, PIPE_TYPE_MESSAGE);
260 WIN32_CONSTANT(F_DWORD, PIPE_UNLIMITED_INSTANCES);
261 WIN32_CONSTANT(F_DWORD, PIPE_WAIT);
262 WIN32_CONSTANT(F_DWORD, PROCESS_ALL_ACCESS);
263
264 WIN32_CONSTANT("i", NULL);
265
266 return (PyObject*)&Win32Type;
267 }
268