eryksun added the comment: The default function pointer restype is c_int, and the default integer argument conversion is also c_int. However, the handle returned by FindFirstVolume is a pointer to a private structure that it uses for the volume enumeration, so you must set restype to a pointer type. Similarly, if restype is a simple type that gets converted to a Python integer (e.g. wintypes.HANDLE), then you must either set FindNextVolumeW.argtypes or manually wrap the handle value (e.g. vhandle = wintypes.HANDLE(vhandle)). The default c_int conversions will only work if the address happens to fit in a 32-bit int.
Don't forget to call FindVolumeClose if the process is expected to continue. Otherwise you're leaking memory. Also, if you're defining function pointer prototypes for a library, please do not use ctypes.cdll or ctypes.windll. The loaders are global to ctypes and by design cache the loaded library, which by design caches function pointers. Projects such as pyreadline and colorama have demonstrated the problems that this creates due to inconsistent prototype definitions, especially for commonly used Win32 APIs. Here is one way to rewrite your code to have it work more reliably: import ctypes from ctypes import wintypes kernel32 = ctypes.WinDLL('kernel32', use_last_error=True) kernel32.FindFirstVolumeW.restype = wintypes.HANDLE kernel32.FindNextVolumeW.argtypes = (wintypes.HANDLE, wintypes.LPWSTR, wintypes.DWORD) kernel32.FindVolumeClose.argtypes = (wintypes.HANDLE,) INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value ERROR_NO_MORE_FILES = 18 def list_volumes(): vname = ctypes.create_unicode_buffer(wintypes.MAX_PATH) vhandle = kernel32.FindFirstVolumeW(vname, len(vname)) if vhandle == INVALID_HANDLE_VALUE: raise ctypes.WinError(ctypes.get_last_error()) volumes = [] try: while True: volumes.append(vname.value) if not kernel32.FindNextVolumeW(vhandle, vname, len(vname)): last_error = ctypes.get_last_error() if last_error == ERROR_NO_MORE_FILES: break else: raise ctypes.WinError(last_error) finally: if not kernel32.FindVolumeClose(vhandle): raise ctypes.WinError(ctypes.get_last_error()) return volumes if __name__ == '__main__': for volume in list_volumes(): print(volume) ---------- nosy: +eryksun resolution: -> not a bug stage: -> resolved status: open -> closed _______________________________________ Python tracker <rep...@bugs.python.org> <http://bugs.python.org/issue25241> _______________________________________ _______________________________________________ Python-bugs-list mailing list Unsubscribe: https://mail.python.org/mailman/options/python-bugs-list/archive%40mail-archive.com