linux uses version libc 9 should not exist crt is no longer directly loadable see issue23606 for the discussion about alternative approaches self assertisnotnonelibcname embedded null character we load the same function both via ordinal and name addressof gets the address where the function pointer is stored on winxp 64bit advapi32 loads at an address that does not fit into a 32bit integer freelibrary must be able to accept this address these are tests for https bugs python orgissue1703286 since on winxp 64bit advapi32 loads like described above the arbitrarily selected closeeventlog function also has a high address callfunction should accept addresses so large calling closeeventlog with a null argument should fail but the call should not segfault or so this is the real test call the function via callfunction bpo34816 shouldn t raise oserror we copy two files and load sqlite3 dll formerly pyd which has a dependency on sqlite3 dll then we test loading it in subprocesses to avoid it starting in memory for each test default load should not find this in cwd relative path but not just filename should succeed insecure load flags should succeed clear the dll directory to avoid safe search settings propagating full path load without dllloaddir shouldn t find dependency full path load with dllloaddir should succeed userspecified directory should succeed linux uses version libc 9 should not exist crt is no longer directly loadable see issue23606 for the discussion about alternative approaches self assertisnotnone libc_name embedded null character we load the same function both via ordinal and name addressof gets the address where the function pointer is stored on winxp 64 bit advapi32 loads at an address that does not fit into a 32 bit integer freelibrary must be able to accept this address these are tests for https bugs python org issue1703286 since on winxp 64 bit advapi32 loads like described above the arbitrarily selected closeeventlog function also has a high address call_function should accept addresses so large calling closeeventlog with a null argument should fail but the call should not segfault or so this is the real test call the function via call_function bpo 34816 shouldn t raise oserror we copy two files and load _sqlite3 dll formerly pyd which has a dependency on sqlite3 dll then we test loading it in subprocesses to avoid it starting in memory for each test default load should not find this in cwd relative path but not just filename should succeed insecure load flags should succeed clear the dll directory to avoid safe search settings propagating full path load without dll_load_dir shouldn t find dependency full path load with dll_load_dir should succeed user specified directory should succeed
import _ctypes
import _ctypes_test
import ctypes
import os
import shutil
import subprocess
import sys
import test.support
import unittest
from ctypes import CDLL, cdll, addressof, c_void_p, c_char_p
from ctypes.util import find_library
from test.support import import_helper, os_helper


libc_name = None


def setUpModule():
    global libc_name
    if os.name == "nt":
        libc_name = find_library("c")
    elif sys.platform == "cygwin":
        libc_name = "cygwin1.dll"
    else:
        libc_name = find_library("c")

    if test.support.verbose:
        print("libc_name is", libc_name)


class LoaderTest(unittest.TestCase):

    unknowndll = "xxrandomnamexx"

    def test_load(self):
        if libc_name is not None:
            test_lib = libc_name
        else:
            if os.name == "nt":
                test_lib = _ctypes_test.__file__
            else:
                self.skipTest('could not find library to load')
        CDLL(test_lib)
        CDLL(os.path.basename(test_lib))
        class CTypesTestPathLikeCls:
            def __fspath__(self):
                return test_lib
        CDLL(CTypesTestPathLikeCls())
        self.assertRaises(OSError, CDLL, self.unknowndll)

    def test_load_version(self):
        if libc_name is None:
            self.skipTest('could not find libc')
        if os.path.basename(libc_name) != 'libc.so.6':
            self.skipTest('wrong libc path for test')
        cdll.LoadLibrary("libc.so.6")
        
        self.assertRaises(OSError, cdll.LoadLibrary, "libc.so.9")
        self.assertRaises(OSError, cdll.LoadLibrary, self.unknowndll)

    def test_find(self):
        for name in ("c", "m"):
            lib = find_library(name)
            if lib:
                cdll.LoadLibrary(lib)
                CDLL(lib)

    @unittest.skipUnless(os.name == "nt",
                         'test specific to Windows')
    def test_load_library(self):
        
        
        
        if test.support.verbose:
            print(find_library("kernel32"))
            print(find_library("user32"))

        if os.name == "nt":
            ctypes.windll.kernel32.GetModuleHandleW
            ctypes.windll["kernel32"].GetModuleHandleW
            ctypes.windll.LoadLibrary("kernel32").GetModuleHandleW
            ctypes.WinDLL("kernel32").GetModuleHandleW
            
            self.assertRaises(ValueError, ctypes.windll.LoadLibrary, "kernel32\0")

    @unittest.skipUnless(os.name == "nt",
                         'test specific to Windows')
    def test_load_ordinal_functions(self):
        dll = ctypes.WinDLL(_ctypes_test.__file__)
        
        func_ord = dll[2]
        func_name = dll.GetString
        
        a_ord = addressof(func_ord)
        a_name = addressof(func_name)
        f_ord_addr = c_void_p.from_address(a_ord).value
        f_name_addr = c_void_p.from_address(a_name).value
        self.assertEqual(hex(f_ord_addr), hex(f_name_addr))

        self.assertRaises(AttributeError, dll.__getitem__, 1234)

    @unittest.skipUnless(os.name == "nt", 'Windows-specific test')
    def test_1703286_A(self):
        
        
        

        
        handle = _ctypes.LoadLibrary("advapi32")
        _ctypes.FreeLibrary(handle)

    @unittest.skipUnless(os.name == "nt", 'Windows-specific test')
    def test_1703286_B(self):
        
        
        
        

        advapi32 = ctypes.windll.advapi32
        
        
        self.assertEqual(0, advapi32.CloseEventLog(None))

        kernel32 = ctypes.windll.kernel32
        kernel32.GetProcAddress.argtypes = c_void_p, c_char_p
        kernel32.GetProcAddress.restype = c_void_p
        proc = kernel32.GetProcAddress(advapi32._handle, b"CloseEventLog")
        self.assertTrue(proc)

        
        self.assertEqual(0, _ctypes.call_function(proc, (None,)))

    @unittest.skipUnless(os.name == "nt",
                         'test specific to Windows')
    def test_load_hasattr(self):
        
        self.assertFalse(hasattr(ctypes.windll, 'test'))

    @unittest.skipUnless(os.name == "nt",
                         'test specific to Windows')
    def test_load_dll_with_flags(self):
        _sqlite3 = import_helper.import_module("_sqlite3")
        src = _sqlite3.__file__
        if src.lower().endswith("_d.pyd"):
            ext = "_d.dll"
        else:
            ext = ".dll"

        with os_helper.temp_dir() as tmp:
            
            
            
            
            target = os.path.join(tmp, "_sqlite3.dll")
            shutil.copy(src, target)
            shutil.copy(os.path.join(os.path.dirname(src), "sqlite3" + ext),
                        os.path.join(tmp, "sqlite3" + ext))

            def should_pass(command):
                with self.subTest(command):
                    subprocess.check_output(
                        [sys.executable, "-c",
                         "from ctypes import *; import nt;" + command],
                        cwd=tmp
                    )

            def should_fail(command):
                with self.subTest(command):
                    with self.assertRaises(subprocess.CalledProcessError):
                        subprocess.check_output(
                            [sys.executable, "-c",
                             "from ctypes import *; import nt;" + command],
                            cwd=tmp, stderr=subprocess.STDOUT,
                        )

            
            should_fail("WinDLL('_sqlite3.dll')")

            
            should_pass("WinDLL('./_sqlite3.dll')")

            
            
            should_pass("windll.kernel32.SetDllDirectoryW(None); WinDLL('_sqlite3.dll', winmode=0)")

            
            should_fail("WinDLL(nt._getfullpathname('_sqlite3.dll'), " +
                        "winmode=nt._LOAD_LIBRARY_SEARCH_SYSTEM32)")

            
            should_pass("WinDLL(nt._getfullpathname('_sqlite3.dll'), " +
                        "winmode=nt._LOAD_LIBRARY_SEARCH_SYSTEM32|" +
                        "nt._LOAD_LIBRARY_SEARCH_DLL_LOAD_DIR)")

            
            should_pass("import os; p = os.add_dll_directory(os.getcwd());" +
                        "WinDLL('_sqlite3.dll'); p.close()")


if __name__ == "__main__":
    unittest.main()