On Sun, Mar 5, 2017 at 12:16 AM, Kurt Eilander <web...@totalrewind.com> wrote: > > I'm having another problem. I'm wanting to get the size of a dll resource, > but... > > When I do: > try: > hLib=win32api.GetModuleHandle(fileName) > except: > hLib=win32api.LoadLibrary(fileName) > if hLib==None: > raise WindowsError('File not found, '+fileName) > hResInfo=ctypes.windll.kernel32.FindResourceW(hLib,index,type) > size=ctypes.windll.kernel32.SizeofResource(hLib,hResInfo) > > It throws: > hResInfo=ctypes.windll.kernel32.FindResourceW(hLib,index,type) > ctypes.ArgumentError: argument 1: <type 'exceptions.OverflowError'>: > long int too long to convert > > Almost like ctypes doesn't like the win32api handle. > > My machine is 64 bit. Is that what ctypes is not liking? Is there a way > around it?
The default conversion for integer arguments is to a 32-bit C int. The implementation calls PyLong_AsLong, for which a 64-bit address can raise an overflow exception on Windows since a C long is always 32-bit on this platform. You're lucky to get an exception. The problem is worse on Unix systems that have a 64-bit C long. The conversion doesn't overflow, but ctypes itself silently casts the address to a 32-bit int. Invariably this causes a segfault, either directly or indirectly due to stack or heap corruption. It looks like you're also not setting restype to a pointer type for FindResourceW. Like with parameters, the default integer conversion type for a function result is a 32-bit C int. A 64-bit result will be silently truncated on Windows as well. Kernel and User handles never exceed 32-bit values, but don't assume that's true of all handles. HMODULE handles break this rule, as do others. Always assume a handle type requires the full range of a pointer. Here are some general suggestions. Use ctypes.WinDLL instead of ctypes.windll (the latter was a bad design for multiple reasons). Load the library with the option use_last_error=True, unless you're working with NT or COM libraries that return NTSTATUS or HRESULT values. Always set the function prototype -- at least argtypes; restype if the function returns a pointer type; and preferably an errcheck function that raises idiomatic exceptions. For example: import winerror import win32api import ctypes from ctypes import wintypes kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) def _check_zero(result, func, args): if not result: raise ctypes.WinError(ctypes.get_last_error()) return args kernel32.FindResourceW.errcheck = _check_zero kernel32.FindResourceW.restype = wintypes.HRSRC kernel32.FindResourceW.argtypes = ( wintypes.HMODULE, # _In_opt_ hModule wintypes.LPCWSTR, # _In_ lpName wintypes.LPCWSTR) # _In_ lpType kernel32.LoadResource.errcheck = _check_zero kernel32.LoadResource.restype = wintypes.HGLOBAL kernel32.LoadResource.argtypes = ( wintypes.HMODULE, # _In_opt_ hModule wintypes.HRSRC) # _In_ hResInfo kernel32.SizeofResource.errcheck = _check_zero kernel32.SizeofResource.restype = wintypes.DWORD kernel32.SizeofResource.argtypes = ( wintypes.HMODULE, # _In_opt_ hModule wintypes.HRSRC) # _In_ hResInfo kernel32.LockResource.restype = wintypes.LPVOID kernel32.LockResource.argtypes = ( wintypes.HGLOBAL,) # _In_ hResData def get_resource(filename, index, rtype): try: hLib = win32api.GetModuleHandle(filename) except win32api.error as e: if e.winerror != winerror.ERROR_MOD_NOT_FOUND: raise hLib = win32api.LoadLibrary(filename) index = wintypes.LPCWSTR(index) # MAKEINTRESOURCE rtype = wintypes.LPCWSTR(rtype) hResInfo = kernel32.FindResourceW(hLib, index, rtype) hRes = kernel32.LoadResource(hLib, hResInfo) size = kernel32.SizeofResource(hLib, hResInfo) addr = kernel32.LockResource(hRes) return ctypes.string_at(addr, size) if __name__ == '__main__': RT_MANIFEST = 24 manifest = get_resource(None, 1, RT_MANIFEST).decode('utf-8') print(manifest) The above demo prints the embedded manifest from python.exe. Of course, it would be a lot simpler to use win32api.LoadResource [1]: manifest = win32api.LoadResource(None, RT_MANIFEST, 1).decode('utf-8') [1]: http://docs.activestate.com/activepython/3.4/pywin32/win32api__LoadResource_meth.html _______________________________________________ python-win32 mailing list python-win32@python.org https://mail.python.org/mailman/listinfo/python-win32