def find_files(spec): """ A pythonic wrapper around the FindFirstFile/FindNextFile win32 api. >>> root_files = tuple(find_files(r'c:\*')) >>> len(root_files) > 1 True >>> root_files[0].filename == root_files[1].filename False This test might fail on a non-standard installation >>> 'Windows' in (fd.filename for fd in root_files) True """ fd = api.WIN32_FIND_DATA() handle = api.FindFirstFile(spec, byref(fd)) while True: if handle == api.INVALID_HANDLE_VALUE: raise WindowsError() yield fd fd = api.WIN32_FIND_DATA() res = api.FindNextFile(handle, byref(fd)) if res == 0: # error error = WindowsError() if error.code == api.ERROR_NO_MORE_FILES: break else: raise error # todo: how to close handle when generator is destroyed? # hint: catch GeneratorExit windll.kernel32.FindClose(handle)
def readlink(link): """ readlink(link) -> target Return a string representing the path to which the symbolic link points. """ handle = api.CreateFile( link, 0, 0, None, api.OPEN_EXISTING, api.FILE_FLAG_OPEN_REPARSE_POINT | api.FILE_FLAG_BACKUP_SEMANTICS, None, ) if handle == api.INVALID_HANDLE_VALUE: raise WindowsError() res = reparse.DeviceIoControl(handle, api.FSCTL_GET_REPARSE_POINT, None, 10240) bytes = create_string_buffer(res) p_rdb = cast(bytes, POINTER(api.REPARSE_DATA_BUFFER)) rdb = p_rdb.contents if not rdb.tag == api.IO_REPARSE_TAG_SYMLINK: raise RuntimeError("Expected IO_REPARSE_TAG_SYMLINK, but got %d" % rdb.tag) handle_nonzero_success(api.CloseHandle(handle)) return rdb.get_substitute_name()
def get_file_info(path): # open the file the same way CPython does in posixmodule.c desired_access = api.FILE_READ_ATTRIBUTES share_mode = 0 security_attributes = None creation_disposition = api.OPEN_EXISTING flags_and_attributes = (api.FILE_ATTRIBUTE_NORMAL | api.FILE_FLAG_BACKUP_SEMANTICS | api.FILE_FLAG_OPEN_REPARSE_POINT) template_file = None handle = api.CreateFile( path, desired_access, share_mode, security_attributes, creation_disposition, flags_and_attributes, template_file, ) if handle == api.INVALID_HANDLE_VALUE: raise WindowsError() info = api.BY_HANDLE_FILE_INFORMATION() res = api.GetFileInformationByHandle(handle, info) handle_nonzero_success(res) handle_nonzero_success(api.CloseHandle(handle)) return info
def AddConnection(remote_name, type=net.RESOURCETYPE_ANY, local_name=None, provider_name=None, user=None, password=None, flags=0): resource = net.NETRESOURCE( type=type, remote_name=remote_name, local_name=local_name, provider_name=provider_name, # WNetAddConnection2 ignores the other members of NETRESOURCE ) result = net.WNetAddConnection2( resource, password, user, flags, ) if result != 0: raise WindowsError(result)
def SetClipboardData(type, content): """ Modeled after http://msdn.microsoft.com/en-us/library/ms649016%28VS.85%29.aspx#_win32_Copying_Information_to_the_Clipboard """ allocators = { clipboard.CF_TEXT: ctypes.create_string_buffer, clipboard.CF_UNICODETEXT: ctypes.create_unicode_buffer, } if not type in allocators: raise NotImplementedError("Only text types are supported at this time") # allocate the memory for the data content = allocators[type](content) flags = memory.GMEM_MOVEABLE size = ctypes.sizeof(content) handle_to_copy = windll.kernel32.GlobalAlloc(flags, size) with LockedMemory(handle_to_copy) as lm: ctypes.memmove(lm.data_ptr, content, size) result = clipboard.SetClipboardData(type, handle_to_copy) if result is None: raise WindowsError()
def get_final_path(path): r""" For a given path, determine the ultimate location of that path. Useful for resolving symlink targets. This functions wraps the GetFinalPathNameByHandle from the Windows SDK. Note, this function fails if a handle cannot be obtained (such as for C:\Pagefile.sys on a stock windows system). Consider using trace_symlink_target instead. """ desired_access = api.NULL share_mode = (api.FILE_SHARE_READ | api.FILE_SHARE_WRITE | api.FILE_SHARE_DELETE) security_attributes = api.LPSECURITY_ATTRIBUTES() # NULL pointer hFile = api.CreateFile( path, desired_access, share_mode, security_attributes, api.OPEN_EXISTING, api.FILE_FLAG_BACKUP_SEMANTICS, api.NULL, ) if hFile == api.INVALID_HANDLE_VALUE: raise WindowsError() buf_size = api.GetFinalPathNameByHandle(hFile, LPWSTR(), 0, api.VOLUME_NAME_DOS) handle_nonzero_success(buf_size) buf = create_unicode_buffer(buf_size) result_length = api.GetFinalPathNameByHandle(hFile, buf, len(buf), api.VOLUME_NAME_DOS) assert result_length < len(buf) handle_nonzero_success(result_length) handle_nonzero_success(api.CloseHandle(hFile)) return buf[:result_length]
def GetFileAttributes(filepath): attrs = api.GetFileAttributes(filepath) if attrs == api.INVALID_FILE_ATTRIBUTES: raise WindowsError() return FileAttributes(attrs)