Branch data Line data Source code
1 : : /*
2 : : * History: First version dated from 3/97, derived from my SCMLIB version
3 : : * for win16.
4 : : */
5 : : /*
6 : : * Related Work:
7 : : * - calldll http://www.nightmare.com/software.html
8 : : * - libffi http://sourceware.cygnus.com/libffi/
9 : : * - ffcall http://clisp.cons.org/~haible/packages-ffcall.html
10 : : * and, of course, Don Beaudry's MESS package, but this is more ctypes
11 : : * related.
12 : : */
13 : :
14 : :
15 : : /*
16 : : How are functions called, and how are parameters converted to C ?
17 : :
18 : : 1. _ctypes.c::PyCFuncPtr_call receives an argument tuple 'inargs' and a
19 : : keyword dictionary 'kwds'.
20 : :
21 : : 2. After several checks, _build_callargs() is called which returns another
22 : : tuple 'callargs'. This may be the same tuple as 'inargs', a slice of
23 : : 'inargs', or a completely fresh tuple, depending on several things (is it a
24 : : COM method?, are 'paramflags' available?).
25 : :
26 : : 3. _build_callargs also calculates bitarrays containing indexes into
27 : : the callargs tuple, specifying how to build the return value(s) of
28 : : the function.
29 : :
30 : : 4. _ctypes_callproc is then called with the 'callargs' tuple. _ctypes_callproc first
31 : : allocates two arrays. The first is an array of 'struct argument' items, the
32 : : second array has 'void *' entries.
33 : :
34 : : 5. If 'converters' are present (converters is a sequence of argtypes'
35 : : from_param methods), for each item in 'callargs' converter is called and the
36 : : result passed to ConvParam. If 'converters' are not present, each argument
37 : : is directly passed to ConvParm.
38 : :
39 : : 6. For each arg, ConvParam stores the contained C data (or a pointer to it,
40 : : for structures) into the 'struct argument' array.
41 : :
42 : : 7. Finally, a loop fills the 'void *' array so that each item points to the
43 : : data contained in or pointed to by the 'struct argument' array.
44 : :
45 : : 8. The 'void *' argument array is what _call_function_pointer
46 : : expects. _call_function_pointer then has very little to do - only some
47 : : libffi specific stuff, then it calls ffi_call.
48 : :
49 : : So, there are 4 data structures holding processed arguments:
50 : : - the inargs tuple (in PyCFuncPtr_call)
51 : : - the callargs tuple (in PyCFuncPtr_call)
52 : : - the 'struct arguments' array
53 : : - the 'void *' array
54 : :
55 : : */
56 : :
57 : : #ifndef Py_BUILD_CORE_BUILTIN
58 : : # define Py_BUILD_CORE_MODULE 1
59 : : #endif
60 : :
61 : : #include "Python.h"
62 : : #include "structmember.h" // PyMemberDef
63 : :
64 : : #include <stdbool.h>
65 : :
66 : : #ifdef MS_WIN32
67 : : #include <windows.h>
68 : : #include <tchar.h>
69 : : #else
70 : : #include <dlfcn.h>
71 : : #endif
72 : :
73 : : #ifdef __APPLE__
74 : : #include <mach-o/dyld.h>
75 : : #endif
76 : :
77 : : #ifdef MS_WIN32
78 : : #include <malloc.h>
79 : : #endif
80 : :
81 : : #include <ffi.h>
82 : : #include "ctypes.h"
83 : : #ifdef HAVE_ALLOCA_H
84 : : /* AIX needs alloca.h for alloca() */
85 : : #include <alloca.h>
86 : : #endif
87 : :
88 : : #ifdef _Py_MEMORY_SANITIZER
89 : : #include <sanitizer/msan_interface.h>
90 : : #endif
91 : :
92 : : #if defined(_DEBUG) || defined(__MINGW32__)
93 : : /* Don't use structured exception handling on Windows if this is defined.
94 : : MingW, AFAIK, doesn't support it.
95 : : */
96 : : #define DONT_USE_SEH
97 : : #endif
98 : :
99 : : #include "pycore_runtime.h" // _PyRuntime
100 : : #include "pycore_global_objects.h" // _Py_ID()
101 : :
102 : : #define CTYPES_CAPSULE_NAME_PYMEM "_ctypes pymem"
103 : :
104 : :
105 : 0 : static void pymem_destructor(PyObject *ptr)
106 : : {
107 : 0 : void *p = PyCapsule_GetPointer(ptr, CTYPES_CAPSULE_NAME_PYMEM);
108 [ # # ]: 0 : if (p) {
109 : 0 : PyMem_Free(p);
110 : : }
111 : 0 : }
112 : :
113 : : /*
114 : : ctypes maintains thread-local storage that has space for two error numbers:
115 : : private copies of the system 'errno' value and, on Windows, the system error code
116 : : accessed by the GetLastError() and SetLastError() api functions.
117 : :
118 : : Foreign functions created with CDLL(..., use_errno=True), when called, swap
119 : : the system 'errno' value with the private copy just before the actual
120 : : function call, and swapped again immediately afterwards. The 'use_errno'
121 : : parameter defaults to False, in this case 'ctypes_errno' is not touched.
122 : :
123 : : On Windows, foreign functions created with CDLL(..., use_last_error=True) or
124 : : WinDLL(..., use_last_error=True) swap the system LastError value with the
125 : : ctypes private copy.
126 : :
127 : : The values are also swapped immediately before and after ctypes callback
128 : : functions are called, if the callbacks are constructed using the new
129 : : optional use_errno parameter set to True: CFUNCTYPE(..., use_errno=TRUE) or
130 : : WINFUNCTYPE(..., use_errno=True).
131 : :
132 : : New ctypes functions are provided to access the ctypes private copies from
133 : : Python:
134 : :
135 : : - ctypes.set_errno(value) and ctypes.set_last_error(value) store 'value' in
136 : : the private copy and returns the previous value.
137 : :
138 : : - ctypes.get_errno() and ctypes.get_last_error() returns the current ctypes
139 : : private copies value.
140 : : */
141 : :
142 : : /*
143 : : This function creates and returns a thread-local Python object that has
144 : : space to store two integer error numbers; once created the Python object is
145 : : kept alive in the thread state dictionary as long as the thread itself.
146 : : */
147 : : PyObject *
148 : 0 : _ctypes_get_errobj(int **pspace)
149 : : {
150 : 0 : PyObject *dict = PyThreadState_GetDict();
151 : : PyObject *errobj;
152 : : static PyObject *error_object_name;
153 [ # # ]: 0 : if (dict == NULL) {
154 : 0 : PyErr_SetString(PyExc_RuntimeError,
155 : : "cannot get thread state");
156 : 0 : return NULL;
157 : : }
158 [ # # ]: 0 : if (error_object_name == NULL) {
159 : 0 : error_object_name = PyUnicode_InternFromString("ctypes.error_object");
160 [ # # ]: 0 : if (error_object_name == NULL)
161 : 0 : return NULL;
162 : : }
163 : 0 : errobj = PyDict_GetItemWithError(dict, error_object_name);
164 [ # # ]: 0 : if (errobj) {
165 [ # # ]: 0 : if (!PyCapsule_IsValid(errobj, CTYPES_CAPSULE_NAME_PYMEM)) {
166 : 0 : PyErr_SetString(PyExc_RuntimeError,
167 : : "ctypes.error_object is an invalid capsule");
168 : 0 : return NULL;
169 : : }
170 : 0 : Py_INCREF(errobj);
171 : : }
172 [ # # ]: 0 : else if (!PyErr_Occurred()) {
173 : 0 : void *space = PyMem_Calloc(2, sizeof(int));
174 [ # # ]: 0 : if (space == NULL)
175 : 0 : return NULL;
176 : 0 : errobj = PyCapsule_New(space, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
177 [ # # ]: 0 : if (errobj == NULL) {
178 : 0 : PyMem_Free(space);
179 : 0 : return NULL;
180 : : }
181 [ # # ]: 0 : if (-1 == PyDict_SetItem(dict, error_object_name,
182 : : errobj)) {
183 : 0 : Py_DECREF(errobj);
184 : 0 : return NULL;
185 : : }
186 : : }
187 : : else {
188 : 0 : return NULL;
189 : : }
190 : 0 : *pspace = (int *)PyCapsule_GetPointer(errobj, CTYPES_CAPSULE_NAME_PYMEM);
191 : 0 : return errobj;
192 : : }
193 : :
194 : : static PyObject *
195 : 0 : get_error_internal(PyObject *self, PyObject *args, int index)
196 : : {
197 : : int *space;
198 : 0 : PyObject *errobj = _ctypes_get_errobj(&space);
199 : : PyObject *result;
200 : :
201 [ # # ]: 0 : if (errobj == NULL)
202 : 0 : return NULL;
203 : 0 : result = PyLong_FromLong(space[index]);
204 : 0 : Py_DECREF(errobj);
205 : 0 : return result;
206 : : }
207 : :
208 : : static PyObject *
209 : 0 : set_error_internal(PyObject *self, PyObject *args, int index)
210 : : {
211 : : int new_errno, old_errno;
212 : : PyObject *errobj;
213 : : int *space;
214 : :
215 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "i", &new_errno)) {
216 : 0 : return NULL;
217 : : }
218 : 0 : errobj = _ctypes_get_errobj(&space);
219 [ # # ]: 0 : if (errobj == NULL)
220 : 0 : return NULL;
221 : 0 : old_errno = space[index];
222 : 0 : space[index] = new_errno;
223 : 0 : Py_DECREF(errobj);
224 : 0 : return PyLong_FromLong(old_errno);
225 : : }
226 : :
227 : : static PyObject *
228 : 0 : get_errno(PyObject *self, PyObject *args)
229 : : {
230 [ # # ]: 0 : if (PySys_Audit("ctypes.get_errno", NULL) < 0) {
231 : 0 : return NULL;
232 : : }
233 : 0 : return get_error_internal(self, args, 0);
234 : : }
235 : :
236 : : static PyObject *
237 : 0 : set_errno(PyObject *self, PyObject *args)
238 : : {
239 [ # # ]: 0 : if (PySys_Audit("ctypes.set_errno", "O", args) < 0) {
240 : 0 : return NULL;
241 : : }
242 : 0 : return set_error_internal(self, args, 0);
243 : : }
244 : :
245 : : #ifdef MS_WIN32
246 : :
247 : : static PyObject *
248 : : get_last_error(PyObject *self, PyObject *args)
249 : : {
250 : : if (PySys_Audit("ctypes.get_last_error", NULL) < 0) {
251 : : return NULL;
252 : : }
253 : : return get_error_internal(self, args, 1);
254 : : }
255 : :
256 : : static PyObject *
257 : : set_last_error(PyObject *self, PyObject *args)
258 : : {
259 : : if (PySys_Audit("ctypes.set_last_error", "O", args) < 0) {
260 : : return NULL;
261 : : }
262 : : return set_error_internal(self, args, 1);
263 : : }
264 : :
265 : : static WCHAR *FormatError(DWORD code)
266 : : {
267 : : WCHAR *lpMsgBuf;
268 : : DWORD n;
269 : : n = FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
270 : : FORMAT_MESSAGE_FROM_SYSTEM |
271 : : FORMAT_MESSAGE_IGNORE_INSERTS,
272 : : NULL,
273 : : code,
274 : : MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), /* Default language */
275 : : (LPWSTR) &lpMsgBuf,
276 : : 0,
277 : : NULL);
278 : : if (n) {
279 : : while (iswspace(lpMsgBuf[n-1]))
280 : : --n;
281 : : lpMsgBuf[n] = L'\0'; /* rstrip() */
282 : : }
283 : : return lpMsgBuf;
284 : : }
285 : :
286 : : #ifndef DONT_USE_SEH
287 : : static void SetException(DWORD code, EXCEPTION_RECORD *pr)
288 : : {
289 : : if (PySys_Audit("ctypes.set_exception", "I", code) < 0) {
290 : : /* An exception was set by the audit hook */
291 : : return;
292 : : }
293 : :
294 : : /* The 'code' is a normal win32 error code so it could be handled by
295 : : PyErr_SetFromWindowsErr(). However, for some errors, we have additional
296 : : information not included in the error code. We handle those here and
297 : : delegate all others to the generic function. */
298 : : switch (code) {
299 : : case EXCEPTION_ACCESS_VIOLATION:
300 : : /* The thread attempted to read from or write
301 : : to a virtual address for which it does not
302 : : have the appropriate access. */
303 : : if (pr->ExceptionInformation[0] == 0)
304 : : PyErr_Format(PyExc_OSError,
305 : : "exception: access violation reading %p",
306 : : pr->ExceptionInformation[1]);
307 : : else
308 : : PyErr_Format(PyExc_OSError,
309 : : "exception: access violation writing %p",
310 : : pr->ExceptionInformation[1]);
311 : : break;
312 : :
313 : : case EXCEPTION_BREAKPOINT:
314 : : /* A breakpoint was encountered. */
315 : : PyErr_SetString(PyExc_OSError,
316 : : "exception: breakpoint encountered");
317 : : break;
318 : :
319 : : case EXCEPTION_DATATYPE_MISALIGNMENT:
320 : : /* The thread attempted to read or write data that is
321 : : misaligned on hardware that does not provide
322 : : alignment. For example, 16-bit values must be
323 : : aligned on 2-byte boundaries, 32-bit values on
324 : : 4-byte boundaries, and so on. */
325 : : PyErr_SetString(PyExc_OSError,
326 : : "exception: datatype misalignment");
327 : : break;
328 : :
329 : : case EXCEPTION_SINGLE_STEP:
330 : : /* A trace trap or other single-instruction mechanism
331 : : signaled that one instruction has been executed. */
332 : : PyErr_SetString(PyExc_OSError,
333 : : "exception: single step");
334 : : break;
335 : :
336 : : case EXCEPTION_ARRAY_BOUNDS_EXCEEDED:
337 : : /* The thread attempted to access an array element
338 : : that is out of bounds, and the underlying hardware
339 : : supports bounds checking. */
340 : : PyErr_SetString(PyExc_OSError,
341 : : "exception: array bounds exceeded");
342 : : break;
343 : :
344 : : case EXCEPTION_FLT_DENORMAL_OPERAND:
345 : : /* One of the operands in a floating-point operation
346 : : is denormal. A denormal value is one that is too
347 : : small to represent as a standard floating-point
348 : : value. */
349 : : PyErr_SetString(PyExc_OSError,
350 : : "exception: floating-point operand denormal");
351 : : break;
352 : :
353 : : case EXCEPTION_FLT_DIVIDE_BY_ZERO:
354 : : /* The thread attempted to divide a floating-point
355 : : value by a floating-point divisor of zero. */
356 : : PyErr_SetString(PyExc_OSError,
357 : : "exception: float divide by zero");
358 : : break;
359 : :
360 : : case EXCEPTION_FLT_INEXACT_RESULT:
361 : : /* The result of a floating-point operation cannot be
362 : : represented exactly as a decimal fraction. */
363 : : PyErr_SetString(PyExc_OSError,
364 : : "exception: float inexact");
365 : : break;
366 : :
367 : : case EXCEPTION_FLT_INVALID_OPERATION:
368 : : /* This exception represents any floating-point
369 : : exception not included in this list. */
370 : : PyErr_SetString(PyExc_OSError,
371 : : "exception: float invalid operation");
372 : : break;
373 : :
374 : : case EXCEPTION_FLT_OVERFLOW:
375 : : /* The exponent of a floating-point operation is
376 : : greater than the magnitude allowed by the
377 : : corresponding type. */
378 : : PyErr_SetString(PyExc_OSError,
379 : : "exception: float overflow");
380 : : break;
381 : :
382 : : case EXCEPTION_FLT_STACK_CHECK:
383 : : /* The stack overflowed or underflowed as the result
384 : : of a floating-point operation. */
385 : : PyErr_SetString(PyExc_OSError,
386 : : "exception: stack over/underflow");
387 : : break;
388 : :
389 : : case EXCEPTION_STACK_OVERFLOW:
390 : : /* The stack overflowed or underflowed as the result
391 : : of a floating-point operation. */
392 : : PyErr_SetString(PyExc_OSError,
393 : : "exception: stack overflow");
394 : : break;
395 : :
396 : : case EXCEPTION_FLT_UNDERFLOW:
397 : : /* The exponent of a floating-point operation is less
398 : : than the magnitude allowed by the corresponding
399 : : type. */
400 : : PyErr_SetString(PyExc_OSError,
401 : : "exception: float underflow");
402 : : break;
403 : :
404 : : case EXCEPTION_INT_DIVIDE_BY_ZERO:
405 : : /* The thread attempted to divide an integer value by
406 : : an integer divisor of zero. */
407 : : PyErr_SetString(PyExc_OSError,
408 : : "exception: integer divide by zero");
409 : : break;
410 : :
411 : : case EXCEPTION_INT_OVERFLOW:
412 : : /* The result of an integer operation caused a carry
413 : : out of the most significant bit of the result. */
414 : : PyErr_SetString(PyExc_OSError,
415 : : "exception: integer overflow");
416 : : break;
417 : :
418 : : case EXCEPTION_PRIV_INSTRUCTION:
419 : : /* The thread attempted to execute an instruction
420 : : whose operation is not allowed in the current
421 : : machine mode. */
422 : : PyErr_SetString(PyExc_OSError,
423 : : "exception: privileged instruction");
424 : : break;
425 : :
426 : : case EXCEPTION_NONCONTINUABLE_EXCEPTION:
427 : : /* The thread attempted to continue execution after a
428 : : noncontinuable exception occurred. */
429 : : PyErr_SetString(PyExc_OSError,
430 : : "exception: nocontinuable");
431 : : break;
432 : :
433 : : default:
434 : : PyErr_SetFromWindowsErr(code);
435 : : break;
436 : : }
437 : : }
438 : :
439 : : static DWORD HandleException(EXCEPTION_POINTERS *ptrs,
440 : : DWORD *pdw, EXCEPTION_RECORD *record)
441 : : {
442 : : *pdw = ptrs->ExceptionRecord->ExceptionCode;
443 : : *record = *ptrs->ExceptionRecord;
444 : : /* We don't want to catch breakpoint exceptions, they are used to attach
445 : : * a debugger to the process.
446 : : */
447 : : if (*pdw == EXCEPTION_BREAKPOINT)
448 : : return EXCEPTION_CONTINUE_SEARCH;
449 : : return EXCEPTION_EXECUTE_HANDLER;
450 : : }
451 : : #endif
452 : :
453 : : static PyObject *
454 : : check_hresult(PyObject *self, PyObject *args)
455 : : {
456 : : HRESULT hr;
457 : : if (!PyArg_ParseTuple(args, "i", &hr))
458 : : return NULL;
459 : : if (FAILED(hr))
460 : : return PyErr_SetFromWindowsErr(hr);
461 : : return PyLong_FromLong(hr);
462 : : }
463 : :
464 : : #endif
465 : :
466 : : /**************************************************************/
467 : :
468 : : PyCArgObject *
469 : 0 : PyCArgObject_new(void)
470 : : {
471 : : PyCArgObject *p;
472 : 0 : p = PyObject_New(PyCArgObject, &PyCArg_Type);
473 [ # # ]: 0 : if (p == NULL)
474 : 0 : return NULL;
475 : 0 : p->pffi_type = NULL;
476 : 0 : p->tag = '\0';
477 : 0 : p->obj = NULL;
478 : 0 : memset(&p->value, 0, sizeof(p->value));
479 : 0 : return p;
480 : : }
481 : :
482 : : static void
483 : 0 : PyCArg_dealloc(PyCArgObject *self)
484 : : {
485 : 0 : Py_XDECREF(self->obj);
486 : 0 : PyObject_Free(self);
487 : 0 : }
488 : :
489 : : static int
490 : 0 : is_literal_char(unsigned char c)
491 : : {
492 [ # # # # : 0 : return c < 128 && _PyUnicode_IsPrintable(c) && c != '\\' && c != '\'';
# # # # ]
493 : : }
494 : :
495 : : static PyObject *
496 : 0 : PyCArg_repr(PyCArgObject *self)
497 : : {
498 [ # # # # : 0 : switch(self->tag) {
# # # #
# ]
499 : 0 : case 'b':
500 : : case 'B':
501 : 0 : return PyUnicode_FromFormat("<cparam '%c' (%d)>",
502 : 0 : self->tag, self->value.b);
503 : 0 : case 'h':
504 : : case 'H':
505 : 0 : return PyUnicode_FromFormat("<cparam '%c' (%d)>",
506 : 0 : self->tag, self->value.h);
507 : 0 : case 'i':
508 : : case 'I':
509 : 0 : return PyUnicode_FromFormat("<cparam '%c' (%d)>",
510 : 0 : self->tag, self->value.i);
511 : 0 : case 'l':
512 : : case 'L':
513 : 0 : return PyUnicode_FromFormat("<cparam '%c' (%ld)>",
514 : 0 : self->tag, self->value.l);
515 : :
516 : 0 : case 'q':
517 : : case 'Q':
518 : 0 : return PyUnicode_FromFormat("<cparam '%c' (%lld)>",
519 : 0 : self->tag, self->value.q);
520 : 0 : case 'd':
521 : : case 'f': {
522 [ # # ]: 0 : PyObject *f = PyFloat_FromDouble((self->tag == 'f') ? self->value.f : self->value.d);
523 [ # # ]: 0 : if (f == NULL) {
524 : 0 : return NULL;
525 : : }
526 : 0 : PyObject *result = PyUnicode_FromFormat("<cparam '%c' (%R)>", self->tag, f);
527 : 0 : Py_DECREF(f);
528 : 0 : return result;
529 : : }
530 : 0 : case 'c':
531 [ # # ]: 0 : if (is_literal_char((unsigned char)self->value.c)) {
532 : 0 : return PyUnicode_FromFormat("<cparam '%c' ('%c')>",
533 : 0 : self->tag, self->value.c);
534 : : }
535 : : else {
536 : 0 : return PyUnicode_FromFormat("<cparam '%c' ('\\x%02x')>",
537 : 0 : self->tag, (unsigned char)self->value.c);
538 : : }
539 : :
540 : : /* Hm, are these 'z' and 'Z' codes useful at all?
541 : : Shouldn't they be replaced by the functionality of create_string_buffer()
542 : : and c_wstring() ?
543 : : */
544 : 0 : case 'z':
545 : : case 'Z':
546 : : case 'P':
547 : 0 : return PyUnicode_FromFormat("<cparam '%c' (%p)>",
548 : 0 : self->tag, self->value.p);
549 : : break;
550 : :
551 : 0 : default:
552 [ # # ]: 0 : if (is_literal_char((unsigned char)self->tag)) {
553 : 0 : return PyUnicode_FromFormat("<cparam '%c' at %p>",
554 : 0 : (unsigned char)self->tag, (void *)self);
555 : : }
556 : : else {
557 : 0 : return PyUnicode_FromFormat("<cparam 0x%02x at %p>",
558 : 0 : (unsigned char)self->tag, (void *)self);
559 : : }
560 : : }
561 : : }
562 : :
563 : : static PyMemberDef PyCArgType_members[] = {
564 : : { "_obj", T_OBJECT,
565 : : offsetof(PyCArgObject, obj), READONLY,
566 : : "the wrapped object" },
567 : : { NULL },
568 : : };
569 : :
570 : : PyTypeObject PyCArg_Type = {
571 : : PyVarObject_HEAD_INIT(NULL, 0)
572 : : "CArgObject",
573 : : sizeof(PyCArgObject),
574 : : 0,
575 : : (destructor)PyCArg_dealloc, /* tp_dealloc */
576 : : 0, /* tp_vectorcall_offset */
577 : : 0, /* tp_getattr */
578 : : 0, /* tp_setattr */
579 : : 0, /* tp_as_async */
580 : : (reprfunc)PyCArg_repr, /* tp_repr */
581 : : 0, /* tp_as_number */
582 : : 0, /* tp_as_sequence */
583 : : 0, /* tp_as_mapping */
584 : : 0, /* tp_hash */
585 : : 0, /* tp_call */
586 : : 0, /* tp_str */
587 : : 0, /* tp_getattro */
588 : : 0, /* tp_setattro */
589 : : 0, /* tp_as_buffer */
590 : : Py_TPFLAGS_DEFAULT, /* tp_flags */
591 : : 0, /* tp_doc */
592 : : 0, /* tp_traverse */
593 : : 0, /* tp_clear */
594 : : 0, /* tp_richcompare */
595 : : 0, /* tp_weaklistoffset */
596 : : 0, /* tp_iter */
597 : : 0, /* tp_iternext */
598 : : 0, /* tp_methods */
599 : : PyCArgType_members, /* tp_members */
600 : : };
601 : :
602 : : /****************************************************************/
603 : : /*
604 : : * Convert a PyObject * into a parameter suitable to pass to an
605 : : * C function call.
606 : : *
607 : : * 1. Python integers are converted to C int and passed by value.
608 : : * Py_None is converted to a C NULL pointer.
609 : : *
610 : : * 2. 3-tuples are expected to have a format character in the first
611 : : * item, which must be 'i', 'f', 'd', 'q', or 'P'.
612 : : * The second item will have to be an integer, float, double, long long
613 : : * or integer (denoting an address void *), will be converted to the
614 : : * corresponding C data type and passed by value.
615 : : *
616 : : * 3. Other Python objects are tested for an '_as_parameter_' attribute.
617 : : * The value of this attribute must be an integer which will be passed
618 : : * by value, or a 2-tuple or 3-tuple which will be used according
619 : : * to point 2 above. The third item (if any), is ignored. It is normally
620 : : * used to keep the object alive where this parameter refers to.
621 : : * XXX This convention is dangerous - you can construct arbitrary tuples
622 : : * in Python and pass them. Would it be safer to use a custom container
623 : : * datatype instead of a tuple?
624 : : *
625 : : * 4. Other Python objects cannot be passed as parameters - an exception is raised.
626 : : *
627 : : * 5. ConvParam will store the converted result in a struct containing format
628 : : * and value.
629 : : */
630 : :
631 : : union result {
632 : : char c;
633 : : char b;
634 : : short h;
635 : : int i;
636 : : long l;
637 : : long long q;
638 : : long double D;
639 : : double d;
640 : : float f;
641 : : void *p;
642 : : };
643 : :
644 : : struct argument {
645 : : ffi_type *ffi_type;
646 : : PyObject *keep;
647 : : union result value;
648 : : };
649 : :
650 : : /*
651 : : * Convert a single Python object into a PyCArgObject and return it.
652 : : */
653 : 0 : static int ConvParam(PyObject *obj, Py_ssize_t index, struct argument *pa)
654 : : {
655 : : StgDictObject *dict;
656 : 0 : pa->keep = NULL; /* so we cannot forget it later */
657 : :
658 : 0 : dict = PyObject_stgdict(obj);
659 [ # # ]: 0 : if (dict) {
660 : : PyCArgObject *carg;
661 : : assert(dict->paramfunc);
662 : : /* If it has an stgdict, it is a CDataObject */
663 : 0 : carg = dict->paramfunc((CDataObject *)obj);
664 [ # # ]: 0 : if (carg == NULL)
665 : 0 : return -1;
666 : 0 : pa->ffi_type = carg->pffi_type;
667 : 0 : memcpy(&pa->value, &carg->value, sizeof(pa->value));
668 : 0 : pa->keep = (PyObject *)carg;
669 : 0 : return 0;
670 : : }
671 : :
672 [ # # ]: 0 : if (PyCArg_CheckExact(obj)) {
673 : 0 : PyCArgObject *carg = (PyCArgObject *)obj;
674 : 0 : pa->ffi_type = carg->pffi_type;
675 : 0 : pa->keep = Py_NewRef(obj);
676 : 0 : memcpy(&pa->value, &carg->value, sizeof(pa->value));
677 : 0 : return 0;
678 : : }
679 : :
680 : : /* check for None, integer, string or unicode and use directly if successful */
681 [ # # ]: 0 : if (obj == Py_None) {
682 : 0 : pa->ffi_type = &ffi_type_pointer;
683 : 0 : pa->value.p = NULL;
684 : 0 : return 0;
685 : : }
686 : :
687 [ # # ]: 0 : if (PyLong_Check(obj)) {
688 : 0 : pa->ffi_type = &ffi_type_sint;
689 : 0 : pa->value.i = (long)PyLong_AsUnsignedLong(obj);
690 [ # # # # ]: 0 : if (pa->value.i == -1 && PyErr_Occurred()) {
691 : 0 : PyErr_Clear();
692 : 0 : pa->value.i = PyLong_AsLong(obj);
693 [ # # # # ]: 0 : if (pa->value.i == -1 && PyErr_Occurred()) {
694 : 0 : PyErr_SetString(PyExc_OverflowError,
695 : : "int too long to convert");
696 : 0 : return -1;
697 : : }
698 : : }
699 : 0 : return 0;
700 : : }
701 : :
702 [ # # ]: 0 : if (PyBytes_Check(obj)) {
703 : 0 : pa->ffi_type = &ffi_type_pointer;
704 : 0 : pa->value.p = PyBytes_AsString(obj);
705 : 0 : pa->keep = Py_NewRef(obj);
706 : 0 : return 0;
707 : : }
708 : :
709 [ # # ]: 0 : if (PyUnicode_Check(obj)) {
710 : 0 : pa->ffi_type = &ffi_type_pointer;
711 : 0 : pa->value.p = PyUnicode_AsWideCharString(obj, NULL);
712 [ # # ]: 0 : if (pa->value.p == NULL)
713 : 0 : return -1;
714 : 0 : pa->keep = PyCapsule_New(pa->value.p, CTYPES_CAPSULE_NAME_PYMEM, pymem_destructor);
715 [ # # ]: 0 : if (!pa->keep) {
716 : 0 : PyMem_Free(pa->value.p);
717 : 0 : return -1;
718 : : }
719 : 0 : return 0;
720 : : }
721 : :
722 : : {
723 : : PyObject *arg;
724 [ # # ]: 0 : if (_PyObject_LookupAttr(obj, &_Py_ID(_as_parameter_), &arg) < 0) {
725 : 0 : return -1;
726 : : }
727 : : /* Which types should we exactly allow here?
728 : : integers are required for using Python classes
729 : : as parameters (they have to expose the '_as_parameter_'
730 : : attribute)
731 : : */
732 [ # # ]: 0 : if (arg) {
733 : : int result;
734 : 0 : result = ConvParam(arg, index, pa);
735 : 0 : Py_DECREF(arg);
736 : 0 : return result;
737 : : }
738 : 0 : PyErr_Format(PyExc_TypeError,
739 : : "Don't know how to convert parameter %d",
740 : : Py_SAFE_DOWNCAST(index, Py_ssize_t, int));
741 : 0 : return -1;
742 : : }
743 : : }
744 : :
745 : : #if defined(MS_WIN32) && !defined(_WIN32_WCE)
746 : : /*
747 : : Per: https://msdn.microsoft.com/en-us/library/7572ztz4.aspx
748 : : To be returned by value in RAX, user-defined types must have a length
749 : : of 1, 2, 4, 8, 16, 32, or 64 bits
750 : : */
751 : : int can_return_struct_as_int(size_t s)
752 : : {
753 : : return s == 1 || s == 2 || s == 4;
754 : : }
755 : :
756 : : int can_return_struct_as_sint64(size_t s)
757 : : {
758 : : #ifdef _M_ARM
759 : : // 8 byte structs cannot be returned in a register on ARM32
760 : : return 0;
761 : : #else
762 : : return s == 8;
763 : : #endif
764 : : }
765 : : #endif
766 : :
767 : :
768 : 0 : ffi_type *_ctypes_get_ffi_type(PyObject *obj)
769 : : {
770 : : StgDictObject *dict;
771 [ # # ]: 0 : if (obj == NULL)
772 : 0 : return &ffi_type_sint;
773 : 0 : dict = PyType_stgdict(obj);
774 [ # # ]: 0 : if (dict == NULL)
775 : 0 : return &ffi_type_sint;
776 : : #if defined(MS_WIN32) && !defined(_WIN32_WCE)
777 : : /* This little trick works correctly with MSVC.
778 : : It returns small structures in registers
779 : : */
780 : : if (dict->ffi_type_pointer.type == FFI_TYPE_STRUCT) {
781 : : if (can_return_struct_as_int(dict->ffi_type_pointer.size))
782 : : return &ffi_type_sint32;
783 : : else if (can_return_struct_as_sint64 (dict->ffi_type_pointer.size))
784 : : return &ffi_type_sint64;
785 : : }
786 : : #endif
787 : 0 : return &dict->ffi_type_pointer;
788 : : }
789 : :
790 : :
791 : : /*
792 : : * libffi uses:
793 : : *
794 : : * ffi_status ffi_prep_cif(ffi_cif *cif, ffi_abi abi,
795 : : * unsigned int nargs,
796 : : * ffi_type *rtype,
797 : : * ffi_type **atypes);
798 : : *
799 : : * and then
800 : : *
801 : : * void ffi_call(ffi_cif *cif, void *fn, void *rvalue, void **avalues);
802 : : */
803 : 0 : static int _call_function_pointer(int flags,
804 : : PPROC pProc,
805 : : void **avalues,
806 : : ffi_type **atypes,
807 : : ffi_type *restype,
808 : : void *resmem,
809 : : int argcount,
810 : : int argtypecount)
811 : : {
812 : 0 : PyThreadState *_save = NULL; /* For Py_BLOCK_THREADS and Py_UNBLOCK_THREADS */
813 : 0 : PyObject *error_object = NULL;
814 : : int *space;
815 : : ffi_cif cif;
816 : : int cc;
817 : : #if defined(MS_WIN32) && !defined(DONT_USE_SEH)
818 : : DWORD dwExceptionCode = 0;
819 : : EXCEPTION_RECORD record;
820 : : #endif
821 : : /* XXX check before here */
822 [ # # ]: 0 : if (restype == NULL) {
823 : 0 : PyErr_SetString(PyExc_RuntimeError,
824 : : "No ffi_type for result");
825 : 0 : return -1;
826 : : }
827 : :
828 : 0 : cc = FFI_DEFAULT_ABI;
829 : : #if defined(MS_WIN32) && !defined(MS_WIN64) && !defined(_WIN32_WCE) && !defined(_M_ARM)
830 : : if ((flags & FUNCFLAG_CDECL) == 0)
831 : : cc = FFI_STDCALL;
832 : : #endif
833 : :
834 : : # ifdef USING_APPLE_OS_LIBFFI
835 : : # ifdef HAVE_BUILTIN_AVAILABLE
836 : : # define HAVE_FFI_PREP_CIF_VAR_RUNTIME __builtin_available(macos 10.15, ios 13, watchos 6, tvos 13, *)
837 : : # else
838 : : # define HAVE_FFI_PREP_CIF_VAR_RUNTIME (ffi_prep_cif_var != NULL)
839 : : # endif
840 : : # elif HAVE_FFI_PREP_CIF_VAR
841 : : # define HAVE_FFI_PREP_CIF_VAR_RUNTIME true
842 : : # else
843 : : # define HAVE_FFI_PREP_CIF_VAR_RUNTIME false
844 : : # endif
845 : :
846 : : /* Even on Apple-arm64 the calling convention for variadic functions coincides
847 : : * with the standard calling convention in the case that the function called
848 : : * only with its fixed arguments. Thus, we do not need a special flag to be
849 : : * set on variadic functions. We treat a function as variadic if it is called
850 : : * with a nonzero number of variadic arguments */
851 [ # # # # ]: 0 : bool is_variadic = (argtypecount != 0 && argcount > argtypecount);
852 : : (void) is_variadic;
853 : :
854 : : #if defined(__APPLE__) && defined(__arm64__)
855 : : if (is_variadic) {
856 : : if (HAVE_FFI_PREP_CIF_VAR_RUNTIME) {
857 : : } else {
858 : : PyErr_SetString(PyExc_NotImplementedError, "ffi_prep_cif_var() is missing");
859 : : return -1;
860 : : }
861 : : }
862 : : #endif
863 : :
864 : : #if HAVE_FFI_PREP_CIF_VAR
865 [ # # ]: 0 : if (is_variadic) {
866 : : if (HAVE_FFI_PREP_CIF_VAR_RUNTIME) {
867 [ # # ]: 0 : if (FFI_OK != ffi_prep_cif_var(&cif,
868 : : cc,
869 : : argtypecount,
870 : : argcount,
871 : : restype,
872 : : atypes)) {
873 : 0 : PyErr_SetString(PyExc_RuntimeError,
874 : : "ffi_prep_cif_var failed");
875 : 0 : return -1;
876 : : }
877 : : } else {
878 : : if (FFI_OK != ffi_prep_cif(&cif,
879 : : cc,
880 : : argcount,
881 : : restype,
882 : : atypes)) {
883 : : PyErr_SetString(PyExc_RuntimeError,
884 : : "ffi_prep_cif failed");
885 : : return -1;
886 : : }
887 : : }
888 : : } else
889 : : #endif
890 : :
891 : : {
892 [ # # ]: 0 : if (FFI_OK != ffi_prep_cif(&cif,
893 : : cc,
894 : : argcount,
895 : : restype,
896 : : atypes)) {
897 : 0 : PyErr_SetString(PyExc_RuntimeError,
898 : : "ffi_prep_cif failed");
899 : 0 : return -1;
900 : : }
901 : : }
902 : :
903 [ # # ]: 0 : if (flags & (FUNCFLAG_USE_ERRNO | FUNCFLAG_USE_LASTERROR)) {
904 : 0 : error_object = _ctypes_get_errobj(&space);
905 [ # # ]: 0 : if (error_object == NULL)
906 : 0 : return -1;
907 : : }
908 [ # # ]: 0 : if ((flags & FUNCFLAG_PYTHONAPI) == 0)
909 : 0 : Py_UNBLOCK_THREADS
910 [ # # ]: 0 : if (flags & FUNCFLAG_USE_ERRNO) {
911 : 0 : int temp = space[0];
912 : 0 : space[0] = errno;
913 : 0 : errno = temp;
914 : : }
915 : : #ifdef MS_WIN32
916 : : if (flags & FUNCFLAG_USE_LASTERROR) {
917 : : int temp = space[1];
918 : : space[1] = GetLastError();
919 : : SetLastError(temp);
920 : : }
921 : : #ifndef DONT_USE_SEH
922 : : __try {
923 : : #endif
924 : : #endif
925 : 0 : ffi_call(&cif, (void *)pProc, resmem, avalues);
926 : : #ifdef MS_WIN32
927 : : #ifndef DONT_USE_SEH
928 : : }
929 : : __except (HandleException(GetExceptionInformation(),
930 : : &dwExceptionCode, &record)) {
931 : : ;
932 : : }
933 : : #endif
934 : : if (flags & FUNCFLAG_USE_LASTERROR) {
935 : : int temp = space[1];
936 : : space[1] = GetLastError();
937 : : SetLastError(temp);
938 : : }
939 : : #endif
940 [ # # ]: 0 : if (flags & FUNCFLAG_USE_ERRNO) {
941 : 0 : int temp = space[0];
942 : 0 : space[0] = errno;
943 : 0 : errno = temp;
944 : : }
945 [ # # ]: 0 : if ((flags & FUNCFLAG_PYTHONAPI) == 0)
946 : 0 : Py_BLOCK_THREADS
947 : 0 : Py_XDECREF(error_object);
948 : : #ifdef MS_WIN32
949 : : #ifndef DONT_USE_SEH
950 : : if (dwExceptionCode) {
951 : : SetException(dwExceptionCode, &record);
952 : : return -1;
953 : : }
954 : : #endif
955 : : #endif
956 [ # # # # ]: 0 : if ((flags & FUNCFLAG_PYTHONAPI) && PyErr_Occurred())
957 : 0 : return -1;
958 : 0 : return 0;
959 : : }
960 : :
961 : : /*
962 : : * Convert the C value in result into a Python object, depending on restype.
963 : : *
964 : : * - If restype is NULL, return a Python integer.
965 : : * - If restype is None, return None.
966 : : * - If restype is a simple ctypes type (c_int, c_void_p), call the type's getfunc,
967 : : * pass the result to checker and return the result.
968 : : * - If restype is another ctypes type, return an instance of that.
969 : : * - Otherwise, call restype and return the result.
970 : : */
971 : 0 : static PyObject *GetResult(PyObject *restype, void *result, PyObject *checker)
972 : : {
973 : : StgDictObject *dict;
974 : : PyObject *retval, *v;
975 : :
976 [ # # ]: 0 : if (restype == NULL)
977 : 0 : return PyLong_FromLong(*(int *)result);
978 : :
979 [ # # ]: 0 : if (restype == Py_None) {
980 : 0 : Py_RETURN_NONE;
981 : : }
982 : :
983 : 0 : dict = PyType_stgdict(restype);
984 [ # # ]: 0 : if (dict == NULL)
985 : 0 : return PyObject_CallFunction(restype, "i", *(int *)result);
986 : :
987 [ # # # # ]: 0 : if (dict->getfunc && !_ctypes_simple_instance(restype)) {
988 : 0 : retval = dict->getfunc(result, dict->size);
989 : : /* If restype is py_object (detected by comparing getfunc with
990 : : O_get), we have to call Py_DECREF because O_get has already
991 : : called Py_INCREF.
992 : : */
993 [ # # ]: 0 : if (dict->getfunc == _ctypes_get_fielddesc("O")->getfunc) {
994 : 0 : Py_DECREF(retval);
995 : : }
996 : : } else
997 : 0 : retval = PyCData_FromBaseObj(restype, NULL, 0, result);
998 : :
999 [ # # # # ]: 0 : if (!checker || !retval)
1000 : 0 : return retval;
1001 : :
1002 : 0 : v = PyObject_CallOneArg(checker, retval);
1003 [ # # ]: 0 : if (v == NULL)
1004 : 0 : _PyTraceback_Add("GetResult", "_ctypes/callproc.c", __LINE__-2);
1005 : 0 : Py_DECREF(retval);
1006 : 0 : return v;
1007 : : }
1008 : :
1009 : : /*
1010 : : * Raise a new exception 'exc_class', adding additional text to the original
1011 : : * exception string.
1012 : : */
1013 : 0 : void _ctypes_extend_error(PyObject *exc_class, const char *fmt, ...)
1014 : : {
1015 : : va_list vargs;
1016 : :
1017 : 0 : va_start(vargs, fmt);
1018 : 0 : PyObject *s = PyUnicode_FromFormatV(fmt, vargs);
1019 : 0 : va_end(vargs);
1020 [ # # ]: 0 : if (s == NULL) {
1021 : 0 : return;
1022 : : }
1023 : :
1024 : : assert(PyErr_Occurred());
1025 : 0 : PyObject *exc = PyErr_GetRaisedException();
1026 : : assert(exc != NULL);
1027 : 0 : PyObject *cls_str = PyType_GetName(Py_TYPE(exc));
1028 [ # # ]: 0 : if (cls_str) {
1029 : 0 : PyUnicode_AppendAndDel(&s, cls_str);
1030 : 0 : PyUnicode_AppendAndDel(&s, PyUnicode_FromString(": "));
1031 [ # # ]: 0 : if (s == NULL) {
1032 : 0 : goto error;
1033 : : }
1034 : : }
1035 : : else {
1036 : 0 : PyErr_Clear();
1037 : : }
1038 : :
1039 : 0 : PyObject *msg_str = PyObject_Str(exc);
1040 [ # # ]: 0 : if (msg_str) {
1041 : 0 : PyUnicode_AppendAndDel(&s, msg_str);
1042 : : }
1043 : : else {
1044 : 0 : PyErr_Clear();
1045 : 0 : PyUnicode_AppendAndDel(&s, PyUnicode_FromString("???"));
1046 : : }
1047 [ # # ]: 0 : if (s == NULL) {
1048 : 0 : goto error;
1049 : : }
1050 : 0 : PyErr_SetObject(exc_class, s);
1051 : 0 : error:
1052 : 0 : Py_XDECREF(exc);
1053 : 0 : Py_XDECREF(s);
1054 : : }
1055 : :
1056 : :
1057 : : #ifdef MS_WIN32
1058 : :
1059 : : static PyObject *
1060 : : GetComError(HRESULT errcode, GUID *riid, IUnknown *pIunk)
1061 : : {
1062 : : HRESULT hr;
1063 : : ISupportErrorInfo *psei = NULL;
1064 : : IErrorInfo *pei = NULL;
1065 : : BSTR descr=NULL, helpfile=NULL, source=NULL;
1066 : : GUID guid;
1067 : : DWORD helpcontext=0;
1068 : : LPOLESTR progid;
1069 : : PyObject *obj;
1070 : : LPOLESTR text;
1071 : :
1072 : : /* We absolutely have to release the GIL during COM method calls,
1073 : : otherwise we may get a deadlock!
1074 : : */
1075 : : Py_BEGIN_ALLOW_THREADS
1076 : :
1077 : : hr = pIunk->lpVtbl->QueryInterface(pIunk, &IID_ISupportErrorInfo, (void **)&psei);
1078 : : if (FAILED(hr))
1079 : : goto failed;
1080 : :
1081 : : hr = psei->lpVtbl->InterfaceSupportsErrorInfo(psei, riid);
1082 : : psei->lpVtbl->Release(psei);
1083 : : if (FAILED(hr))
1084 : : goto failed;
1085 : :
1086 : : hr = GetErrorInfo(0, &pei);
1087 : : if (hr != S_OK)
1088 : : goto failed;
1089 : :
1090 : : pei->lpVtbl->GetDescription(pei, &descr);
1091 : : pei->lpVtbl->GetGUID(pei, &guid);
1092 : : pei->lpVtbl->GetHelpContext(pei, &helpcontext);
1093 : : pei->lpVtbl->GetHelpFile(pei, &helpfile);
1094 : : pei->lpVtbl->GetSource(pei, &source);
1095 : :
1096 : : pei->lpVtbl->Release(pei);
1097 : :
1098 : : failed:
1099 : : Py_END_ALLOW_THREADS
1100 : :
1101 : : progid = NULL;
1102 : : ProgIDFromCLSID(&guid, &progid);
1103 : :
1104 : : text = FormatError(errcode);
1105 : : obj = Py_BuildValue(
1106 : : "iu(uuuiu)",
1107 : : errcode,
1108 : : text,
1109 : : descr, source, helpfile, helpcontext,
1110 : : progid);
1111 : : if (obj) {
1112 : : PyErr_SetObject(ComError, obj);
1113 : : Py_DECREF(obj);
1114 : : }
1115 : : LocalFree(text);
1116 : :
1117 : : if (descr)
1118 : : SysFreeString(descr);
1119 : : if (helpfile)
1120 : : SysFreeString(helpfile);
1121 : : if (source)
1122 : : SysFreeString(source);
1123 : :
1124 : : return NULL;
1125 : : }
1126 : : #endif
1127 : :
1128 : : #if (defined(__x86_64__) && (defined(__MINGW64__) || defined(__CYGWIN__))) || \
1129 : : defined(__aarch64__) || defined(__riscv)
1130 : : #define CTYPES_PASS_BY_REF_HACK
1131 : : #define POW2(x) (((x & ~(x - 1)) == x) ? x : 0)
1132 : : #define IS_PASS_BY_REF(x) (x > 8 || !POW2(x))
1133 : : #endif
1134 : :
1135 : : /*
1136 : : * Requirements, must be ensured by the caller:
1137 : : * - argtuple is tuple of arguments
1138 : : * - argtypes is either NULL, or a tuple of the same size as argtuple
1139 : : *
1140 : : * - XXX various requirements for restype, not yet collected
1141 : : */
1142 : 0 : PyObject *_ctypes_callproc(PPROC pProc,
1143 : : PyObject *argtuple,
1144 : : #ifdef MS_WIN32
1145 : : IUnknown *pIunk,
1146 : : GUID *iid,
1147 : : #endif
1148 : : int flags,
1149 : : PyObject *argtypes, /* misleading name: This is a tuple of
1150 : : methods, not types: the .from_param
1151 : : class methods of the types */
1152 : : PyObject *restype,
1153 : : PyObject *checker)
1154 : : {
1155 : : Py_ssize_t i, n, argcount, argtype_count;
1156 : : void *resbuf;
1157 : : struct argument *args, *pa;
1158 : : ffi_type **atypes;
1159 : : ffi_type *rtype;
1160 : : void **avalues;
1161 : 0 : PyObject *retval = NULL;
1162 : :
1163 : 0 : n = argcount = PyTuple_GET_SIZE(argtuple);
1164 : : #ifdef MS_WIN32
1165 : : /* an optional COM object this pointer */
1166 : : if (pIunk)
1167 : : ++argcount;
1168 : : #endif
1169 : :
1170 [ # # ]: 0 : if (argcount > CTYPES_MAX_ARGCOUNT)
1171 : : {
1172 : 0 : PyErr_Format(PyExc_ArgError, "too many arguments (%zi), maximum is %i",
1173 : : argcount, CTYPES_MAX_ARGCOUNT);
1174 : 0 : return NULL;
1175 : : }
1176 : :
1177 : 0 : args = alloca(sizeof(struct argument) * argcount);
1178 : 0 : memset(args, 0, sizeof(struct argument) * argcount);
1179 [ # # ]: 0 : argtype_count = argtypes ? PyTuple_GET_SIZE(argtypes) : 0;
1180 : : #ifdef MS_WIN32
1181 : : if (pIunk) {
1182 : : args[0].ffi_type = &ffi_type_pointer;
1183 : : args[0].value.p = pIunk;
1184 : : pa = &args[1];
1185 : : } else
1186 : : #endif
1187 : 0 : pa = &args[0];
1188 : :
1189 : : /* Convert the arguments */
1190 [ # # ]: 0 : for (i = 0; i < n; ++i, ++pa) {
1191 : : PyObject *converter;
1192 : : PyObject *arg;
1193 : : int err;
1194 : :
1195 : 0 : arg = PyTuple_GET_ITEM(argtuple, i); /* borrowed ref */
1196 : : /* For cdecl functions, we allow more actual arguments
1197 : : than the length of the argtypes tuple.
1198 : : This is checked in _ctypes::PyCFuncPtr_Call
1199 : : */
1200 [ # # # # ]: 0 : if (argtypes && argtype_count > i) {
1201 : : PyObject *v;
1202 : 0 : converter = PyTuple_GET_ITEM(argtypes, i);
1203 : 0 : v = PyObject_CallOneArg(converter, arg);
1204 [ # # ]: 0 : if (v == NULL) {
1205 : 0 : _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1);
1206 : 0 : goto cleanup;
1207 : : }
1208 : :
1209 : 0 : err = ConvParam(v, i+1, pa);
1210 : 0 : Py_DECREF(v);
1211 [ # # ]: 0 : if (-1 == err) {
1212 : 0 : _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1);
1213 : 0 : goto cleanup;
1214 : : }
1215 : : } else {
1216 : 0 : err = ConvParam(arg, i+1, pa);
1217 [ # # ]: 0 : if (-1 == err) {
1218 : 0 : _ctypes_extend_error(PyExc_ArgError, "argument %zd: ", i+1);
1219 : 0 : goto cleanup; /* leaking ? */
1220 : : }
1221 : : }
1222 : : }
1223 : :
1224 [ # # ]: 0 : if (restype == Py_None) {
1225 : 0 : rtype = &ffi_type_void;
1226 : : } else {
1227 : 0 : rtype = _ctypes_get_ffi_type(restype);
1228 : : }
1229 : :
1230 : 0 : resbuf = alloca(max(rtype->size, sizeof(ffi_arg)));
1231 : :
1232 : : #ifdef _Py_MEMORY_SANITIZER
1233 : : /* ffi_call actually initializes resbuf, but from asm, which
1234 : : * MemorySanitizer can't detect. Avoid false positives from MSan. */
1235 : : if (resbuf != NULL) {
1236 : : __msan_unpoison(resbuf, max(rtype->size, sizeof(ffi_arg)));
1237 : : }
1238 : : #endif
1239 : 0 : avalues = (void **)alloca(sizeof(void *) * argcount);
1240 : 0 : atypes = (ffi_type **)alloca(sizeof(ffi_type *) * argcount);
1241 [ # # # # : 0 : if (!resbuf || !avalues || !atypes) {
# # ]
1242 : 0 : PyErr_NoMemory();
1243 : 0 : goto cleanup;
1244 : : }
1245 [ # # ]: 0 : for (i = 0; i < argcount; ++i) {
1246 : 0 : atypes[i] = args[i].ffi_type;
1247 : : #ifdef CTYPES_PASS_BY_REF_HACK
1248 : : size_t size = atypes[i]->size;
1249 : : if (IS_PASS_BY_REF(size)) {
1250 : : void *tmp = alloca(size);
1251 : : if (atypes[i]->type == FFI_TYPE_STRUCT)
1252 : : memcpy(tmp, args[i].value.p, size);
1253 : : else
1254 : : memcpy(tmp, (void*)&args[i].value, size);
1255 : :
1256 : : avalues[i] = tmp;
1257 : : }
1258 : : else
1259 : : #endif
1260 [ # # ]: 0 : if (atypes[i]->type == FFI_TYPE_STRUCT)
1261 : 0 : avalues[i] = (void *)args[i].value.p;
1262 : : else
1263 : 0 : avalues[i] = (void *)&args[i].value;
1264 : : }
1265 : :
1266 [ # # ]: 0 : if (-1 == _call_function_pointer(flags, pProc, avalues, atypes,
1267 : : rtype, resbuf,
1268 : : Py_SAFE_DOWNCAST(argcount, Py_ssize_t, int),
1269 : : Py_SAFE_DOWNCAST(argtype_count, Py_ssize_t, int)))
1270 : 0 : goto cleanup;
1271 : :
1272 : : #ifdef WORDS_BIGENDIAN
1273 : : /* libffi returns the result in a buffer with sizeof(ffi_arg). This
1274 : : causes problems on big endian machines, since the result buffer
1275 : : address cannot simply be used as result pointer, instead we must
1276 : : adjust the pointer value:
1277 : : */
1278 : : /*
1279 : : XXX I should find out and clarify why this is needed at all,
1280 : : especially why adjusting for ffi_type_float must be avoided on
1281 : : 64-bit platforms.
1282 : : */
1283 : : if (rtype->type != FFI_TYPE_FLOAT
1284 : : && rtype->type != FFI_TYPE_STRUCT
1285 : : && rtype->size < sizeof(ffi_arg))
1286 : : {
1287 : : resbuf = (char *)resbuf + sizeof(ffi_arg) - rtype->size;
1288 : : }
1289 : : #endif
1290 : :
1291 : : #ifdef MS_WIN32
1292 : : if (iid && pIunk) {
1293 : : if (*(int *)resbuf & 0x80000000)
1294 : : retval = GetComError(*(HRESULT *)resbuf, iid, pIunk);
1295 : : else
1296 : : retval = PyLong_FromLong(*(int *)resbuf);
1297 : : } else if (flags & FUNCFLAG_HRESULT) {
1298 : : if (*(int *)resbuf & 0x80000000)
1299 : : retval = PyErr_SetFromWindowsErr(*(int *)resbuf);
1300 : : else
1301 : : retval = PyLong_FromLong(*(int *)resbuf);
1302 : : } else
1303 : : #endif
1304 : 0 : retval = GetResult(restype, resbuf, checker);
1305 : 0 : cleanup:
1306 [ # # ]: 0 : for (i = 0; i < argcount; ++i)
1307 : 0 : Py_XDECREF(args[i].keep);
1308 : 0 : return retval;
1309 : : }
1310 : :
1311 : : static int
1312 : 0 : _parse_voidp(PyObject *obj, void **address)
1313 : : {
1314 : 0 : *address = PyLong_AsVoidPtr(obj);
1315 [ # # ]: 0 : if (*address == NULL)
1316 : 0 : return 0;
1317 : 0 : return 1;
1318 : : }
1319 : :
1320 : : #ifdef MS_WIN32
1321 : :
1322 : : PyDoc_STRVAR(format_error_doc,
1323 : : "FormatError([integer]) -> string\n\
1324 : : \n\
1325 : : Convert a win32 error code into a string. If the error code is not\n\
1326 : : given, the return value of a call to GetLastError() is used.\n");
1327 : : static PyObject *format_error(PyObject *self, PyObject *args)
1328 : : {
1329 : : PyObject *result;
1330 : : wchar_t *lpMsgBuf;
1331 : : DWORD code = 0;
1332 : : if (!PyArg_ParseTuple(args, "|i:FormatError", &code))
1333 : : return NULL;
1334 : : if (code == 0)
1335 : : code = GetLastError();
1336 : : lpMsgBuf = FormatError(code);
1337 : : if (lpMsgBuf) {
1338 : : result = PyUnicode_FromWideChar(lpMsgBuf, wcslen(lpMsgBuf));
1339 : : LocalFree(lpMsgBuf);
1340 : : } else {
1341 : : result = PyUnicode_FromString("<no description>");
1342 : : }
1343 : : return result;
1344 : : }
1345 : :
1346 : : PyDoc_STRVAR(load_library_doc,
1347 : : "LoadLibrary(name, load_flags) -> handle\n\
1348 : : \n\
1349 : : Load an executable (usually a DLL), and return a handle to it.\n\
1350 : : The handle may be used to locate exported functions in this\n\
1351 : : module. load_flags are as defined for LoadLibraryEx in the\n\
1352 : : Windows API.\n");
1353 : : static PyObject *load_library(PyObject *self, PyObject *args)
1354 : : {
1355 : : PyObject *nameobj;
1356 : : int load_flags = 0;
1357 : : HMODULE hMod;
1358 : : DWORD err;
1359 : :
1360 : : if (!PyArg_ParseTuple(args, "U|i:LoadLibrary", &nameobj, &load_flags))
1361 : : return NULL;
1362 : :
1363 : : if (PySys_Audit("ctypes.dlopen", "O", nameobj) < 0) {
1364 : : return NULL;
1365 : : }
1366 : :
1367 : : WCHAR *name = PyUnicode_AsWideCharString(nameobj, NULL);
1368 : : if (!name)
1369 : : return NULL;
1370 : :
1371 : : Py_BEGIN_ALLOW_THREADS
1372 : : /* bpo-36085: Limit DLL search directories to avoid pre-loading
1373 : : * attacks and enable use of the AddDllDirectory function.
1374 : : */
1375 : : hMod = LoadLibraryExW(name, NULL, (DWORD)load_flags);
1376 : : err = hMod ? 0 : GetLastError();
1377 : : Py_END_ALLOW_THREADS
1378 : :
1379 : : PyMem_Free(name);
1380 : : if (err == ERROR_MOD_NOT_FOUND) {
1381 : : PyErr_Format(PyExc_FileNotFoundError,
1382 : : ("Could not find module '%.500S' (or one of its "
1383 : : "dependencies). Try using the full path with "
1384 : : "constructor syntax."),
1385 : : nameobj);
1386 : : return NULL;
1387 : : } else if (err) {
1388 : : return PyErr_SetFromWindowsErr(err);
1389 : : }
1390 : : #ifdef _WIN64
1391 : : return PyLong_FromVoidPtr(hMod);
1392 : : #else
1393 : : return Py_BuildValue("i", hMod);
1394 : : #endif
1395 : : }
1396 : :
1397 : : PyDoc_STRVAR(free_library_doc,
1398 : : "FreeLibrary(handle) -> void\n\
1399 : : \n\
1400 : : Free the handle of an executable previously loaded by LoadLibrary.\n");
1401 : : static PyObject *free_library(PyObject *self, PyObject *args)
1402 : : {
1403 : : void *hMod;
1404 : : BOOL result;
1405 : : DWORD err;
1406 : : if (!PyArg_ParseTuple(args, "O&:FreeLibrary", &_parse_voidp, &hMod))
1407 : : return NULL;
1408 : :
1409 : : Py_BEGIN_ALLOW_THREADS
1410 : : result = FreeLibrary((HMODULE)hMod);
1411 : : err = result ? 0 : GetLastError();
1412 : : Py_END_ALLOW_THREADS
1413 : :
1414 : : if (!result) {
1415 : : return PyErr_SetFromWindowsErr(err);
1416 : : }
1417 : : Py_RETURN_NONE;
1418 : : }
1419 : :
1420 : : PyDoc_STRVAR(copy_com_pointer_doc,
1421 : : "CopyComPointer(src, dst) -> HRESULT value\n");
1422 : :
1423 : : static PyObject *
1424 : : copy_com_pointer(PyObject *self, PyObject *args)
1425 : : {
1426 : : PyObject *p1, *p2, *r = NULL;
1427 : : struct argument a, b;
1428 : : IUnknown *src, **pdst;
1429 : : if (!PyArg_ParseTuple(args, "OO:CopyComPointer", &p1, &p2))
1430 : : return NULL;
1431 : : a.keep = b.keep = NULL;
1432 : :
1433 : : if (-1 == ConvParam(p1, 0, &a) || -1 == ConvParam(p2, 1, &b))
1434 : : goto done;
1435 : : src = (IUnknown *)a.value.p;
1436 : : pdst = (IUnknown **)b.value.p;
1437 : :
1438 : : if (pdst == NULL)
1439 : : r = PyLong_FromLong(E_POINTER);
1440 : : else {
1441 : : if (src)
1442 : : src->lpVtbl->AddRef(src);
1443 : : *pdst = src;
1444 : : r = PyLong_FromLong(S_OK);
1445 : : }
1446 : : done:
1447 : : Py_XDECREF(a.keep);
1448 : : Py_XDECREF(b.keep);
1449 : : return r;
1450 : : }
1451 : : #else
1452 : : #ifdef __APPLE__
1453 : : #ifdef HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH
1454 : : # ifdef HAVE_BUILTIN_AVAILABLE
1455 : : # define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \
1456 : : __builtin_available(macOS 11.0, iOS 14.0, tvOS 14.0, watchOS 7.0, *)
1457 : : # else
1458 : : # define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \
1459 : : (_dyld_shared_cache_contains_path != NULL)
1460 : : # endif
1461 : : #else
1462 : : // Support the deprecated case of compiling on an older macOS version
1463 : : static void *libsystem_b_handle;
1464 : : static bool (*_dyld_shared_cache_contains_path)(const char *path);
1465 : :
1466 : : __attribute__((constructor)) void load_dyld_shared_cache_contains_path(void) {
1467 : : libsystem_b_handle = dlopen("/usr/lib/libSystem.B.dylib", RTLD_LAZY);
1468 : : if (libsystem_b_handle != NULL) {
1469 : : _dyld_shared_cache_contains_path = dlsym(libsystem_b_handle, "_dyld_shared_cache_contains_path");
1470 : : }
1471 : : }
1472 : :
1473 : : __attribute__((destructor)) void unload_dyld_shared_cache_contains_path(void) {
1474 : : if (libsystem_b_handle != NULL) {
1475 : : dlclose(libsystem_b_handle);
1476 : : }
1477 : : }
1478 : : #define HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME \
1479 : : _dyld_shared_cache_contains_path != NULL
1480 : : #endif
1481 : :
1482 : : static PyObject *py_dyld_shared_cache_contains_path(PyObject *self, PyObject *args)
1483 : : {
1484 : : PyObject *name, *name2;
1485 : : char *name_str;
1486 : :
1487 : : if (HAVE_DYLD_SHARED_CACHE_CONTAINS_PATH_RUNTIME) {
1488 : : int r;
1489 : :
1490 : : if (!PyArg_ParseTuple(args, "O", &name))
1491 : : return NULL;
1492 : :
1493 : : if (name == Py_None)
1494 : : Py_RETURN_FALSE;
1495 : :
1496 : : if (PyUnicode_FSConverter(name, &name2) == 0)
1497 : : return NULL;
1498 : : name_str = PyBytes_AS_STRING(name2);
1499 : :
1500 : : r = _dyld_shared_cache_contains_path(name_str);
1501 : : Py_DECREF(name2);
1502 : :
1503 : : if (r) {
1504 : : Py_RETURN_TRUE;
1505 : : } else {
1506 : : Py_RETURN_FALSE;
1507 : : }
1508 : :
1509 : : } else {
1510 : : PyErr_SetString(PyExc_NotImplementedError, "_dyld_shared_cache_contains_path symbol is missing");
1511 : : return NULL;
1512 : : }
1513 : :
1514 : : }
1515 : : #endif
1516 : :
1517 : 1 : static PyObject *py_dl_open(PyObject *self, PyObject *args)
1518 : : {
1519 : : PyObject *name, *name2;
1520 : : const char *name_str;
1521 : : void * handle;
1522 : : #if HAVE_DECL_RTLD_LOCAL
1523 : 1 : int mode = RTLD_NOW | RTLD_LOCAL;
1524 : : #else
1525 : : /* cygwin doesn't define RTLD_LOCAL */
1526 : : int mode = RTLD_NOW;
1527 : : #endif
1528 [ - + ]: 1 : if (!PyArg_ParseTuple(args, "O|i:dlopen", &name, &mode))
1529 : 0 : return NULL;
1530 : 1 : mode |= RTLD_NOW;
1531 [ - + ]: 1 : if (name != Py_None) {
1532 [ # # ]: 0 : if (PyUnicode_FSConverter(name, &name2) == 0)
1533 : 0 : return NULL;
1534 : 0 : name_str = PyBytes_AS_STRING(name2);
1535 : : } else {
1536 : 1 : name_str = NULL;
1537 : 1 : name2 = NULL;
1538 : : }
1539 [ - + ]: 1 : if (PySys_Audit("ctypes.dlopen", "O", name) < 0) {
1540 : 0 : return NULL;
1541 : : }
1542 : 1 : handle = dlopen(name_str, mode);
1543 : 1 : Py_XDECREF(name2);
1544 [ - + ]: 1 : if (!handle) {
1545 : 0 : const char *errmsg = dlerror();
1546 [ # # ]: 0 : if (!errmsg)
1547 : 0 : errmsg = "dlopen() error";
1548 : 0 : PyErr_SetString(PyExc_OSError,
1549 : : errmsg);
1550 : 0 : return NULL;
1551 : : }
1552 : 1 : return PyLong_FromVoidPtr(handle);
1553 : : }
1554 : :
1555 : 0 : static PyObject *py_dl_close(PyObject *self, PyObject *args)
1556 : : {
1557 : : void *handle;
1558 : :
1559 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "O&:dlclose", &_parse_voidp, &handle))
1560 : 0 : return NULL;
1561 [ # # ]: 0 : if (dlclose(handle)) {
1562 : 0 : PyErr_SetString(PyExc_OSError,
1563 : 0 : dlerror());
1564 : 0 : return NULL;
1565 : : }
1566 : 0 : Py_RETURN_NONE;
1567 : : }
1568 : :
1569 : 0 : static PyObject *py_dl_sym(PyObject *self, PyObject *args)
1570 : : {
1571 : : char *name;
1572 : : void *handle;
1573 : : void *ptr;
1574 : :
1575 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "O&s:dlsym",
1576 : : &_parse_voidp, &handle, &name))
1577 : 0 : return NULL;
1578 [ # # ]: 0 : if (PySys_Audit("ctypes.dlsym/handle", "O", args) < 0) {
1579 : 0 : return NULL;
1580 : : }
1581 : 0 : ptr = dlsym((void*)handle, name);
1582 [ # # ]: 0 : if (!ptr) {
1583 : 0 : PyErr_SetString(PyExc_OSError,
1584 : 0 : dlerror());
1585 : 0 : return NULL;
1586 : : }
1587 : 0 : return PyLong_FromVoidPtr(ptr);
1588 : : }
1589 : : #endif
1590 : :
1591 : : /*
1592 : : * Only for debugging so far: So that we can call CFunction instances
1593 : : *
1594 : : * XXX Needs to accept more arguments: flags, argtypes, restype
1595 : : */
1596 : : static PyObject *
1597 : 0 : call_function(PyObject *self, PyObject *args)
1598 : : {
1599 : : void *func;
1600 : : PyObject *arguments;
1601 : : PyObject *result;
1602 : :
1603 [ # # ]: 0 : if (!PyArg_ParseTuple(args,
1604 : : "O&O!",
1605 : : &_parse_voidp, &func,
1606 : : &PyTuple_Type, &arguments))
1607 : 0 : return NULL;
1608 [ # # ]: 0 : if (PySys_Audit("ctypes.call_function", "nO",
1609 : : (Py_ssize_t)func, arguments) < 0) {
1610 : 0 : return NULL;
1611 : : }
1612 : :
1613 : 0 : result = _ctypes_callproc((PPROC)func,
1614 : : arguments,
1615 : : #ifdef MS_WIN32
1616 : : NULL,
1617 : : NULL,
1618 : : #endif
1619 : : 0, /* flags */
1620 : : NULL, /* self->argtypes */
1621 : : NULL, /* self->restype */
1622 : : NULL); /* checker */
1623 : 0 : return result;
1624 : : }
1625 : :
1626 : : /*
1627 : : * Only for debugging so far: So that we can call CFunction instances
1628 : : *
1629 : : * XXX Needs to accept more arguments: flags, argtypes, restype
1630 : : */
1631 : : static PyObject *
1632 : 0 : call_cdeclfunction(PyObject *self, PyObject *args)
1633 : : {
1634 : : void *func;
1635 : : PyObject *arguments;
1636 : : PyObject *result;
1637 : :
1638 [ # # ]: 0 : if (!PyArg_ParseTuple(args,
1639 : : "O&O!",
1640 : : &_parse_voidp, &func,
1641 : : &PyTuple_Type, &arguments))
1642 : 0 : return NULL;
1643 [ # # ]: 0 : if (PySys_Audit("ctypes.call_function", "nO",
1644 : : (Py_ssize_t)func, arguments) < 0) {
1645 : 0 : return NULL;
1646 : : }
1647 : :
1648 : 0 : result = _ctypes_callproc((PPROC)func,
1649 : : arguments,
1650 : : #ifdef MS_WIN32
1651 : : NULL,
1652 : : NULL,
1653 : : #endif
1654 : : FUNCFLAG_CDECL, /* flags */
1655 : : NULL, /* self->argtypes */
1656 : : NULL, /* self->restype */
1657 : : NULL); /* checker */
1658 : 0 : return result;
1659 : : }
1660 : :
1661 : : /*****************************************************************
1662 : : * functions
1663 : : */
1664 : : PyDoc_STRVAR(sizeof_doc,
1665 : : "sizeof(C type) -> integer\n"
1666 : : "sizeof(C instance) -> integer\n"
1667 : : "Return the size in bytes of a C instance");
1668 : :
1669 : : static PyObject *
1670 : 38 : sizeof_func(PyObject *self, PyObject *obj)
1671 : : {
1672 : : StgDictObject *dict;
1673 : :
1674 : 38 : dict = PyType_stgdict(obj);
1675 [ + - ]: 38 : if (dict)
1676 : 38 : return PyLong_FromSsize_t(dict->size);
1677 : :
1678 [ # # ]: 0 : if (CDataObject_Check(obj))
1679 : 0 : return PyLong_FromSsize_t(((CDataObject *)obj)->b_size);
1680 : 0 : PyErr_SetString(PyExc_TypeError,
1681 : : "this type has no size");
1682 : 0 : return NULL;
1683 : : }
1684 : :
1685 : : PyDoc_STRVAR(alignment_doc,
1686 : : "alignment(C type) -> integer\n"
1687 : : "alignment(C instance) -> integer\n"
1688 : : "Return the alignment requirements of a C instance");
1689 : :
1690 : : static PyObject *
1691 : 0 : align_func(PyObject *self, PyObject *obj)
1692 : : {
1693 : : StgDictObject *dict;
1694 : :
1695 : 0 : dict = PyType_stgdict(obj);
1696 [ # # ]: 0 : if (dict)
1697 : 0 : return PyLong_FromSsize_t(dict->align);
1698 : :
1699 : 0 : dict = PyObject_stgdict(obj);
1700 [ # # ]: 0 : if (dict)
1701 : 0 : return PyLong_FromSsize_t(dict->align);
1702 : :
1703 : 0 : PyErr_SetString(PyExc_TypeError,
1704 : : "no alignment info");
1705 : 0 : return NULL;
1706 : : }
1707 : :
1708 : : PyDoc_STRVAR(byref_doc,
1709 : : "byref(C instance[, offset=0]) -> byref-object\n"
1710 : : "Return a pointer lookalike to a C instance, only usable\n"
1711 : : "as function argument");
1712 : :
1713 : : /*
1714 : : * We must return something which can be converted to a parameter,
1715 : : * but still has a reference to self.
1716 : : */
1717 : : static PyObject *
1718 : 0 : byref(PyObject *self, PyObject *args)
1719 : : {
1720 : : PyCArgObject *parg;
1721 : : PyObject *obj;
1722 : 0 : PyObject *pyoffset = NULL;
1723 : 0 : Py_ssize_t offset = 0;
1724 : :
1725 [ # # ]: 0 : if (!PyArg_UnpackTuple(args, "byref", 1, 2,
1726 : : &obj, &pyoffset))
1727 : 0 : return NULL;
1728 [ # # ]: 0 : if (pyoffset) {
1729 : 0 : offset = PyNumber_AsSsize_t(pyoffset, NULL);
1730 [ # # # # ]: 0 : if (offset == -1 && PyErr_Occurred())
1731 : 0 : return NULL;
1732 : : }
1733 [ # # ]: 0 : if (!CDataObject_Check(obj)) {
1734 : 0 : PyErr_Format(PyExc_TypeError,
1735 : : "byref() argument must be a ctypes instance, not '%s'",
1736 : 0 : Py_TYPE(obj)->tp_name);
1737 : 0 : return NULL;
1738 : : }
1739 : :
1740 : 0 : parg = PyCArgObject_new();
1741 [ # # ]: 0 : if (parg == NULL)
1742 : 0 : return NULL;
1743 : :
1744 : 0 : parg->tag = 'P';
1745 : 0 : parg->pffi_type = &ffi_type_pointer;
1746 : 0 : parg->obj = Py_NewRef(obj);
1747 : 0 : parg->value.p = (char *)((CDataObject *)obj)->b_ptr + offset;
1748 : 0 : return (PyObject *)parg;
1749 : : }
1750 : :
1751 : : PyDoc_STRVAR(addressof_doc,
1752 : : "addressof(C instance) -> integer\n"
1753 : : "Return the address of the C instance internal buffer");
1754 : :
1755 : : static PyObject *
1756 : 0 : addressof(PyObject *self, PyObject *obj)
1757 : : {
1758 [ # # ]: 0 : if (!CDataObject_Check(obj)) {
1759 : 0 : PyErr_SetString(PyExc_TypeError,
1760 : : "invalid type");
1761 : 0 : return NULL;
1762 : : }
1763 [ # # ]: 0 : if (PySys_Audit("ctypes.addressof", "(O)", obj) < 0) {
1764 : 0 : return NULL;
1765 : : }
1766 : 0 : return PyLong_FromVoidPtr(((CDataObject *)obj)->b_ptr);
1767 : : }
1768 : :
1769 : : static int
1770 : 0 : converter(PyObject *obj, void **address)
1771 : : {
1772 : 0 : *address = PyLong_AsVoidPtr(obj);
1773 : 0 : return *address != NULL;
1774 : : }
1775 : :
1776 : : static PyObject *
1777 : 0 : My_PyObj_FromPtr(PyObject *self, PyObject *args)
1778 : : {
1779 : : PyObject *ob;
1780 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "O&:PyObj_FromPtr", converter, &ob)) {
1781 : 0 : return NULL;
1782 : : }
1783 [ # # ]: 0 : if (PySys_Audit("ctypes.PyObj_FromPtr", "(O)", ob) < 0) {
1784 : 0 : return NULL;
1785 : : }
1786 : 0 : return Py_NewRef(ob);
1787 : : }
1788 : :
1789 : : static PyObject *
1790 : 0 : My_Py_INCREF(PyObject *self, PyObject *arg)
1791 : : {
1792 : 0 : Py_INCREF(arg); /* that's what this function is for */
1793 : 0 : Py_INCREF(arg); /* that for returning it */
1794 : 0 : return arg;
1795 : : }
1796 : :
1797 : : static PyObject *
1798 : 0 : My_Py_DECREF(PyObject *self, PyObject *arg)
1799 : : {
1800 : 0 : Py_DECREF(arg); /* that's what this function is for */
1801 : 0 : Py_INCREF(arg); /* that's for returning it */
1802 : 0 : return arg;
1803 : : }
1804 : :
1805 : : static PyObject *
1806 : 0 : resize(PyObject *self, PyObject *args)
1807 : : {
1808 : : CDataObject *obj;
1809 : : StgDictObject *dict;
1810 : : Py_ssize_t size;
1811 : :
1812 [ # # ]: 0 : if (!PyArg_ParseTuple(args,
1813 : : "On:resize",
1814 : : &obj, &size))
1815 : 0 : return NULL;
1816 : :
1817 : 0 : dict = PyObject_stgdict((PyObject *)obj);
1818 [ # # ]: 0 : if (dict == NULL) {
1819 : 0 : PyErr_SetString(PyExc_TypeError,
1820 : : "excepted ctypes instance");
1821 : 0 : return NULL;
1822 : : }
1823 [ # # ]: 0 : if (size < dict->size) {
1824 : 0 : PyErr_Format(PyExc_ValueError,
1825 : : "minimum size is %zd",
1826 : : dict->size);
1827 : 0 : return NULL;
1828 : : }
1829 [ # # ]: 0 : if (obj->b_needsfree == 0) {
1830 : 0 : PyErr_Format(PyExc_ValueError,
1831 : : "Memory cannot be resized because this object doesn't own it");
1832 : 0 : return NULL;
1833 : : }
1834 [ # # ]: 0 : if ((size_t)size <= sizeof(obj->b_value)) {
1835 : : /* internal default buffer is large enough */
1836 : 0 : obj->b_size = size;
1837 : 0 : goto done;
1838 : : }
1839 [ # # ]: 0 : if (!_CDataObject_HasExternalBuffer(obj)) {
1840 : : /* We are currently using the objects default buffer, but it
1841 : : isn't large enough any more. */
1842 : 0 : void *ptr = PyMem_Calloc(1, size);
1843 [ # # ]: 0 : if (ptr == NULL)
1844 : 0 : return PyErr_NoMemory();
1845 : 0 : memmove(ptr, obj->b_ptr, obj->b_size);
1846 : 0 : obj->b_ptr = ptr;
1847 : 0 : obj->b_size = size;
1848 : : } else {
1849 : 0 : void * ptr = PyMem_Realloc(obj->b_ptr, size);
1850 [ # # ]: 0 : if (ptr == NULL)
1851 : 0 : return PyErr_NoMemory();
1852 : 0 : obj->b_ptr = ptr;
1853 : 0 : obj->b_size = size;
1854 : : }
1855 : 0 : done:
1856 : 0 : Py_RETURN_NONE;
1857 : : }
1858 : :
1859 : : static PyObject *
1860 : 0 : unpickle(PyObject *self, PyObject *args)
1861 : : {
1862 : : PyObject *typ, *state, *meth, *obj, *result;
1863 : :
1864 [ # # ]: 0 : if (!PyArg_ParseTuple(args, "OO!", &typ, &PyTuple_Type, &state))
1865 : 0 : return NULL;
1866 : 0 : obj = PyObject_CallMethodOneArg(typ, &_Py_ID(__new__), typ);
1867 [ # # ]: 0 : if (obj == NULL)
1868 : 0 : return NULL;
1869 : :
1870 : 0 : meth = PyObject_GetAttr(obj, &_Py_ID(__setstate__));
1871 [ # # ]: 0 : if (meth == NULL) {
1872 : 0 : goto error;
1873 : : }
1874 : :
1875 : 0 : result = PyObject_Call(meth, state, NULL);
1876 : 0 : Py_DECREF(meth);
1877 [ # # ]: 0 : if (result == NULL) {
1878 : 0 : goto error;
1879 : : }
1880 : 0 : Py_DECREF(result);
1881 : :
1882 : 0 : return obj;
1883 : :
1884 : 0 : error:
1885 : 0 : Py_DECREF(obj);
1886 : 0 : return NULL;
1887 : : }
1888 : :
1889 : : static PyObject *
1890 : 4 : POINTER(PyObject *self, PyObject *cls)
1891 : : {
1892 : : PyObject *result;
1893 : : PyTypeObject *typ;
1894 : : PyObject *key;
1895 : :
1896 : 4 : result = PyDict_GetItemWithError(_ctypes_ptrtype_cache, cls);
1897 [ - + ]: 4 : if (result) {
1898 : 0 : return Py_NewRef(result);
1899 : : }
1900 [ - + ]: 4 : else if (PyErr_Occurred()) {
1901 : 0 : return NULL;
1902 : : }
1903 [ - + ]: 4 : if (PyUnicode_CheckExact(cls)) {
1904 : 0 : PyObject *name = PyUnicode_FromFormat("LP_%U", cls);
1905 : 0 : result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
1906 : : "N(O){}",
1907 : : name,
1908 : : &PyCPointer_Type);
1909 [ # # ]: 0 : if (result == NULL)
1910 : 0 : return result;
1911 : 0 : key = PyLong_FromVoidPtr(result);
1912 [ # # ]: 0 : if (key == NULL) {
1913 : 0 : Py_DECREF(result);
1914 : 0 : return NULL;
1915 : : }
1916 [ + - ]: 4 : } else if (PyType_Check(cls)) {
1917 : 4 : typ = (PyTypeObject *)cls;
1918 : 4 : PyObject *name = PyUnicode_FromFormat("LP_%s", typ->tp_name);
1919 : 4 : result = PyObject_CallFunction((PyObject *)Py_TYPE(&PyCPointer_Type),
1920 : : "N(O){sO}",
1921 : : name,
1922 : : &PyCPointer_Type,
1923 : : "_type_", cls);
1924 [ - + ]: 4 : if (result == NULL)
1925 : 0 : return result;
1926 : 4 : key = Py_NewRef(cls);
1927 : : } else {
1928 : 0 : PyErr_SetString(PyExc_TypeError, "must be a ctypes type");
1929 : 0 : return NULL;
1930 : : }
1931 [ - + ]: 4 : if (-1 == PyDict_SetItem(_ctypes_ptrtype_cache, key, result)) {
1932 : 0 : Py_DECREF(result);
1933 : 0 : Py_DECREF(key);
1934 : 0 : return NULL;
1935 : : }
1936 : 4 : Py_DECREF(key);
1937 : 4 : return result;
1938 : : }
1939 : :
1940 : : static PyObject *
1941 : 0 : pointer(PyObject *self, PyObject *arg)
1942 : : {
1943 : : PyObject *result;
1944 : : PyObject *typ;
1945 : :
1946 : 0 : typ = PyDict_GetItemWithError(_ctypes_ptrtype_cache, (PyObject *)Py_TYPE(arg));
1947 [ # # ]: 0 : if (typ) {
1948 : 0 : return PyObject_CallOneArg(typ, arg);
1949 : : }
1950 [ # # ]: 0 : else if (PyErr_Occurred()) {
1951 : 0 : return NULL;
1952 : : }
1953 : 0 : typ = POINTER(NULL, (PyObject *)Py_TYPE(arg));
1954 [ # # ]: 0 : if (typ == NULL)
1955 : 0 : return NULL;
1956 : 0 : result = PyObject_CallOneArg(typ, arg);
1957 : 0 : Py_DECREF(typ);
1958 : 0 : return result;
1959 : : }
1960 : :
1961 : : static PyObject *
1962 : 0 : buffer_info(PyObject *self, PyObject *arg)
1963 : : {
1964 : 0 : StgDictObject *dict = PyType_stgdict(arg);
1965 : : PyObject *shape;
1966 : : Py_ssize_t i;
1967 : :
1968 [ # # ]: 0 : if (dict == NULL)
1969 : 0 : dict = PyObject_stgdict(arg);
1970 [ # # ]: 0 : if (dict == NULL) {
1971 : 0 : PyErr_SetString(PyExc_TypeError,
1972 : : "not a ctypes type or object");
1973 : 0 : return NULL;
1974 : : }
1975 : 0 : shape = PyTuple_New(dict->ndim);
1976 [ # # ]: 0 : if (shape == NULL)
1977 : 0 : return NULL;
1978 [ # # ]: 0 : for (i = 0; i < (int)dict->ndim; ++i)
1979 : 0 : PyTuple_SET_ITEM(shape, i, PyLong_FromSsize_t(dict->shape[i]));
1980 : :
1981 [ # # ]: 0 : if (PyErr_Occurred()) {
1982 : 0 : Py_DECREF(shape);
1983 : 0 : return NULL;
1984 : : }
1985 : 0 : return Py_BuildValue("siN", dict->format, dict->ndim, shape);
1986 : : }
1987 : :
1988 : :
1989 : :
1990 : : PyMethodDef _ctypes_module_methods[] = {
1991 : : {"get_errno", get_errno, METH_NOARGS},
1992 : : {"set_errno", set_errno, METH_VARARGS},
1993 : : {"POINTER", POINTER, METH_O },
1994 : : {"pointer", pointer, METH_O },
1995 : : {"_unpickle", unpickle, METH_VARARGS },
1996 : : {"buffer_info", buffer_info, METH_O, "Return buffer interface information"},
1997 : : {"resize", resize, METH_VARARGS, "Resize the memory buffer of a ctypes instance"},
1998 : : #ifdef MS_WIN32
1999 : : {"get_last_error", get_last_error, METH_NOARGS},
2000 : : {"set_last_error", set_last_error, METH_VARARGS},
2001 : : {"CopyComPointer", copy_com_pointer, METH_VARARGS, copy_com_pointer_doc},
2002 : : {"FormatError", format_error, METH_VARARGS, format_error_doc},
2003 : : {"LoadLibrary", load_library, METH_VARARGS, load_library_doc},
2004 : : {"FreeLibrary", free_library, METH_VARARGS, free_library_doc},
2005 : : {"_check_HRESULT", check_hresult, METH_VARARGS},
2006 : : #else
2007 : : {"dlopen", py_dl_open, METH_VARARGS,
2008 : : "dlopen(name, flag={RTLD_GLOBAL|RTLD_LOCAL}) open a shared library"},
2009 : : {"dlclose", py_dl_close, METH_VARARGS, "dlclose a library"},
2010 : : {"dlsym", py_dl_sym, METH_VARARGS, "find symbol in shared library"},
2011 : : #endif
2012 : : #ifdef __APPLE__
2013 : : {"_dyld_shared_cache_contains_path", py_dyld_shared_cache_contains_path, METH_VARARGS, "check if path is in the shared cache"},
2014 : : #endif
2015 : : {"alignment", align_func, METH_O, alignment_doc},
2016 : : {"sizeof", sizeof_func, METH_O, sizeof_doc},
2017 : : {"byref", byref, METH_VARARGS, byref_doc},
2018 : : {"addressof", addressof, METH_O, addressof_doc},
2019 : : {"call_function", call_function, METH_VARARGS },
2020 : : {"call_cdeclfunction", call_cdeclfunction, METH_VARARGS },
2021 : : {"PyObj_FromPtr", My_PyObj_FromPtr, METH_VARARGS },
2022 : : {"Py_INCREF", My_Py_INCREF, METH_O },
2023 : : {"Py_DECREF", My_Py_DECREF, METH_O },
2024 : : {NULL, NULL} /* Sentinel */
2025 : : };
2026 : :
2027 : : /*
2028 : : Local Variables:
2029 : : compile-command: "cd .. && python setup.py -q build -g && python setup.py -q build install --home ~"
2030 : : End:
2031 : : */
|