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 19static PyObject * 20win32_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 38static PyObject * 39win32_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 59static PyObject * 60win32_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 91static PyObject * 92win32_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 125static PyObject * 126win32_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 144static PyObject * 145win32_GetLastError(PyObject *self, PyObject *args) 146{ 147 return Py_BuildValue(F_DWORD, GetLastError()); 148} 149 150static PyObject * 151win32_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 169static PyObject * 170win32_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 198static PyObject * 199win32_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 218static 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 232PyTypeObject Win32Type = { 233 PyVarObject_HEAD_INIT(NULL, 0) 234}; 235 236 237PyObject * 238create_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