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