def from_named_pipe(cls, name, buffer_size=4096, default_timeout=100, max_instances=5): handle = m_k32.CreateNamedPipeW( '\\\\.\\pipe\\' + name, # _In_ LPCTSTR lpName PIPE_ACCESS_DUPLEX | FILE_FLAG_OVERLAPPED, # _In_ DWORD dwOpenMode PIPE_TYPE_MESSAGE | PIPE_READMODE_MESSAGE, # _In_ DWORD dwPipeMode max_instances, # _In_ DWORD nMaxInstances buffer_size, # _In_ DWORD nInBufferSize buffer_size, # _In_ DWORD nOutBufferSize default_timeout, # _In_ DWORD nDefaultTimeout None # _In_opt_ LPSECURITY_ATTRIBUTES lpSecurityAttributes ) if handle == INVALID_HANDLE_VALUE: raise ctypes.WinError() success = lambda: cls(handle, buffer_size=buffer_size) overlapped = wintypes.OVERLAPPED() overlapped.hEvent = m_k32.CreateEventW(None, True, False, None) if m_k32.ConnectNamedPipe(handle, ctypes.byref(overlapped)): m_k32.CloseHandle(overlapped.hEvent) return success() error = m_k32.GetLastError() if error == ERROR_IO_PENDING and _wait_overlapped_io(overlapped, default_timeout): m_k32.CloseHandle(overlapped.hEvent) return success() m_k32.CloseHandle(overlapped.hEvent) if error == ERROR_PIPE_CONNECTED: return success() m_k32.CloseHandle(handle) raise ctypes.WinError()
def read(self): ctarray = (ctypes.c_byte * self.buffer_size)() bytes_read = wintypes.DWORD(0) overlapped = wintypes.OVERLAPPED() overlapped.hEvent = m_k32.CreateEventW(None, True, False, None) if m_k32.ReadFile(self.handle, ctypes.byref(ctarray), self.buffer_size, ctypes.byref(bytes_read), ctypes.byref(overlapped)): return utilities.ctarray_to_bytes(ctarray)[:bytes_read.value] error = m_k32.GetLastError() if error == ERROR_IO_PENDING and _wait_overlapped_io(overlapped): return utilities.ctarray_to_bytes(ctarray)[:overlapped.InternalHigh] if error == ERROR_BROKEN_PIPE: return None raise ctypes.WinError()