10a8c90248264a8b26970b4473770bcc3df8515fJosh Gao# Windows specific tests
20a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
30a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom ctypes import *
40a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom ctypes.test import is_resource_enabled
50a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport unittest, sys
60a8c90248264a8b26970b4473770bcc3df8515fJosh Gaofrom test import test_support as support
70a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
80a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoimport _ctypes_test
90a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
100a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif sys.platform == "win32" and sizeof(c_void_p) == sizeof(c_int):
110a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    # Only windows 32-bit has different calling conventions.
120a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
130a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    class WindowsTestCase(unittest.TestCase):
140a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def test_callconv_1(self):
150a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Testing stdcall function
160a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
170a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            IsWindow = windll.user32.IsWindow
180a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # ValueError: Procedure probably called with not enough arguments (4 bytes missing)
190a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, IsWindow)
200a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
210a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # This one should succeed...
220a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(0, IsWindow(0))
230a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
240a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # ValueError: Procedure probably called with too many arguments (8 bytes in excess)
250a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, IsWindow, 0, 0, 0)
260a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
270a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def test_callconv_2(self):
280a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # Calling stdcall function as cdecl
290a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
300a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            IsWindow = cdll.user32.IsWindow
310a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
320a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # ValueError: Procedure called with not enough arguments (4 bytes missing)
330a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # or wrong calling convention
340a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertRaises(ValueError, IsWindow, None)
350a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
360a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif sys.platform == "win32":
370a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    class FunctionCallTestCase(unittest.TestCase):
380a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
390a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        if is_resource_enabled("SEH"):
400a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            def test_SEH(self):
410a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # Call functions with invalid arguments, and make sure
420a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # that access violations are trapped and raise an
430a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                # exception.
440a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertRaises(WindowsError, windll.kernel32.GetModuleHandleA, 32)
450a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
460a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def test_noargs(self):
470a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            # This is a special case on win32 x64
480a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            windll.user32.GetDesktopWindow()
490a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
500a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    class TestWintypes(unittest.TestCase):
510a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def test_HWND(self):
520a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            from ctypes import wintypes
530a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(sizeof(wintypes.HWND), sizeof(c_void_p))
540a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
550a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def test_PARAM(self):
560a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            from ctypes import wintypes
570a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(sizeof(wintypes.WPARAM),
580a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 sizeof(c_void_p))
590a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(sizeof(wintypes.LPARAM),
600a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 sizeof(c_void_p))
610a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
620a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        def test_COMError(self):
630a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            from _ctypes import COMError
640a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            if support.HAVE_DOCSTRINGS:
650a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                self.assertEqual(COMError.__doc__,
660a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                                 "Raised when a COM method call failed.")
670a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
680a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            ex = COMError(-1, "text", ("details",))
690a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(ex.hresult, -1)
700a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(ex.text, "text")
710a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            self.assertEqual(ex.details, ("details",))
720a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
730a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoclass Structures(unittest.TestCase):
740a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
750a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    def test_struct_by_value(self):
760a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class POINT(Structure):
770a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _fields_ = [("x", c_long),
780a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        ("y", c_long)]
790a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
800a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        class RECT(Structure):
810a8c90248264a8b26970b4473770bcc3df8515fJosh Gao            _fields_ = [("left", c_long),
820a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        ("top", c_long),
830a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        ("right", c_long),
840a8c90248264a8b26970b4473770bcc3df8515fJosh Gao                        ("bottom", c_long)]
850a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
860a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        dll = CDLL(_ctypes_test.__file__)
870a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
880a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        pt = POINT(10, 10)
890a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        rect = RECT(0, 0, 20, 20)
900a8c90248264a8b26970b4473770bcc3df8515fJosh Gao        self.assertEqual(1, dll.PointInRect(byref(rect), pt))
910a8c90248264a8b26970b4473770bcc3df8515fJosh Gao
920a8c90248264a8b26970b4473770bcc3df8515fJosh Gaoif __name__ == '__main__':
930a8c90248264a8b26970b4473770bcc3df8515fJosh Gao    unittest.main()
94