1# Windows specific tests 2 3from ctypes import * 4import unittest, sys 5from test import support 6 7import _ctypes_test 8 9@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') 10class FunctionCallTestCase(unittest.TestCase): 11 @unittest.skipUnless('MSC' in sys.version, "SEH only supported by MSC") 12 @unittest.skipIf(sys.executable.lower().endswith('_d.exe'), 13 "SEH not enabled in debug builds") 14 def test_SEH(self): 15 # Disable faulthandler to prevent logging the warning: 16 # "Windows fatal exception: access violation" 17 with support.disable_faulthandler(): 18 # Call functions with invalid arguments, and make sure 19 # that access violations are trapped and raise an 20 # exception. 21 self.assertRaises(OSError, windll.kernel32.GetModuleHandleA, 32) 22 23 def test_noargs(self): 24 # This is a special case on win32 x64 25 windll.user32.GetDesktopWindow() 26 27 28@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') 29class ReturnStructSizesTestCase(unittest.TestCase): 30 def test_sizes(self): 31 dll = CDLL(_ctypes_test.__file__) 32 for i in range(1, 11): 33 fields = [ (f"f{f}", c_char) for f in range(1, i + 1)] 34 class S(Structure): 35 _fields_ = fields 36 f = getattr(dll, f"TestSize{i}") 37 f.restype = S 38 res = f() 39 for i, f in enumerate(fields): 40 value = getattr(res, f[0]) 41 expected = bytes([ord('a') + i]) 42 self.assertEqual(value, expected) 43 44 45 46@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') 47class TestWintypes(unittest.TestCase): 48 def test_HWND(self): 49 from ctypes import wintypes 50 self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p)) 51 52 def test_PARAM(self): 53 from ctypes import wintypes 54 self.assertEqual(sizeof(wintypes.WPARAM), 55 sizeof(c_void_p)) 56 self.assertEqual(sizeof(wintypes.LPARAM), 57 sizeof(c_void_p)) 58 59 def test_COMError(self): 60 from _ctypes import COMError 61 if support.HAVE_DOCSTRINGS: 62 self.assertEqual(COMError.__doc__, 63 "Raised when a COM method call failed.") 64 65 ex = COMError(-1, "text", ("details",)) 66 self.assertEqual(ex.hresult, -1) 67 self.assertEqual(ex.text, "text") 68 self.assertEqual(ex.details, ("details",)) 69 70@unittest.skipUnless(sys.platform == "win32", 'Windows-specific test') 71class TestWinError(unittest.TestCase): 72 def test_winerror(self): 73 # see Issue 16169 74 import errno 75 ERROR_INVALID_PARAMETER = 87 76 msg = FormatError(ERROR_INVALID_PARAMETER).strip() 77 args = (errno.EINVAL, msg, None, ERROR_INVALID_PARAMETER) 78 79 e = WinError(ERROR_INVALID_PARAMETER) 80 self.assertEqual(e.args, args) 81 self.assertEqual(e.errno, errno.EINVAL) 82 self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) 83 84 windll.kernel32.SetLastError(ERROR_INVALID_PARAMETER) 85 try: 86 raise WinError() 87 except OSError as exc: 88 e = exc 89 self.assertEqual(e.args, args) 90 self.assertEqual(e.errno, errno.EINVAL) 91 self.assertEqual(e.winerror, ERROR_INVALID_PARAMETER) 92 93class Structures(unittest.TestCase): 94 def test_struct_by_value(self): 95 class POINT(Structure): 96 _fields_ = [("x", c_long), 97 ("y", c_long)] 98 99 class RECT(Structure): 100 _fields_ = [("left", c_long), 101 ("top", c_long), 102 ("right", c_long), 103 ("bottom", c_long)] 104 105 dll = CDLL(_ctypes_test.__file__) 106 107 pt = POINT(15, 25) 108 left = c_long.in_dll(dll, 'left') 109 top = c_long.in_dll(dll, 'top') 110 right = c_long.in_dll(dll, 'right') 111 bottom = c_long.in_dll(dll, 'bottom') 112 rect = RECT(left, top, right, bottom) 113 PointInRect = dll.PointInRect 114 PointInRect.argtypes = [POINTER(RECT), POINT] 115 self.assertEqual(1, PointInRect(byref(rect), pt)) 116 117 ReturnRect = dll.ReturnRect 118 ReturnRect.argtypes = [c_int, RECT, POINTER(RECT), POINT, RECT, 119 POINTER(RECT), POINT, RECT] 120 ReturnRect.restype = RECT 121 for i in range(4): 122 ret = ReturnRect(i, rect, pointer(rect), pt, rect, 123 byref(rect), pt, rect) 124 # the c function will check and modify ret if something is 125 # passed in improperly 126 self.assertEqual(ret.left, left.value) 127 self.assertEqual(ret.right, right.value) 128 self.assertEqual(ret.top, top.value) 129 self.assertEqual(ret.bottom, bottom.value) 130 131 # to not leak references, we must clean _pointer_type_cache 132 from ctypes import _pointer_type_cache 133 del _pointer_type_cache[RECT] 134 135if __name__ == '__main__': 136 unittest.main() 137