def __init__(self, ipc_socket, callback=None, quit_callback=None): """Create the wrapper. *ipc_socket* is the pipe name. (Not including \\\\.\\pipe\\) *callback(json_data)* is the function for recieving events. *quit_callback* is called when the socket connection dies. """ ipc_socket = "\\\\.\\pipe\\" + ipc_socket self.callback = callback self.quit_callback = quit_callback access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE limit = 5 # Connection may fail at first. Try 5 times. for _ in range(limit): try: pipe_handle = _winapi.CreateFile(ipc_socket, access, 0, _winapi.NULL, _winapi.OPEN_EXISTING, _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL) break except OSError: time.sleep(1) else: raise MPVError("Cannot connect to pipe.") self.socket = PipeConnection(pipe_handle) if self.callback is None: self.callback = lambda data: None threading.Thread.__init__(self)
def steal_pipe(self, pid, read_handle, write_handle): read_handle = steal_handle(pid, read_handle) write_handle = steal_handle(pid, write_handle) reader = PipeConnection(read_handle, writable=False) writer = PipeConnection(write_handle, readable=False) return reader, writer
def PipeServerConnection(address, readable, writable, timeout=nDefaultTimeOut.NMPWAIT_WAIT_FOREVER): open_mode = (0x00000000 | dwOpenMode.FILE_FLAG_OVERLAPPED | dwOpenMode.FILE_FLAG_FIRST_PIPE_INSTANCE | (readable and dwOpenMode.PIPE_ACCESS_INBOUND or 0x00000000) | (writable and dwOpenMode.PIPE_ACCESS_OUTBOUND or 0x00000000)) pipe_mode = (0x00000000 | (readable and dwPipeMode.PIPE_READMODE_BYTE or 0x00000000) | (writable and dwPipeMode.PIPE_TYPE_BYTE or 0x00000000) | dwPipeMode.PIPE_WAIT) # https://msdn.microsoft.com/en-US/library/windows/desktop/aa365150.aspx handle = _winapi.CreateNamedPipe(address, open_mode, pipe_mode, 1, BUFSIZE, BUFSIZE, timeout, 0x0) overlapped = _winapi.ConnectNamedPipe(handle, overlapped=True) if (nDefaultTimeOut.NMPWAIT_USE_DEFAULT_WAIT < timeout < nDefaultTimeOut.NMPWAIT_WAIT_FOREVER): timer = TimeoutTimer(timeout / 1000, overlapped.cancel) else: timer = TimeoutTimer(0, lambda: None) with timer: _, err = overlapped.GetOverlappedResult(True) # Can block forever assert err == 0 return PipeConnection(handle, readable=readable, writable=writable)
def _launch_single_enc_dec(self, enc: bool, remove_old: bool, path: EncPath, sema: Semaphore, send_msg: connection.PipeConnection): f_orig_path = path.real_path res = "" try: res = path.encrypt(self.enc_dec) if enc else path.decrypt( self.enc_dec) if path.is_file and res and remove_old and res != f_orig_path: os.remove(legalize_path(f_orig_path)) except ValueError as e: print(f"Bad Password for file: {f_orig_path}") finally: if send_msg: send_msg.send(res) if sema: sema.release()
class WindowsSocket(threading.Thread): """ Wraps a Windows named pipe in a high-level interface. (Internal) Data is automatically encoded and decoded as JSON. The callback function will be called for each inbound message. """ def __init__(self, ipc_socket, callback=None, quit_callback=None): """Create the wrapper. *ipc_socket* is the pipe name. (Not including \\\\.\\pipe\\) *callback(json_data)* is the function for recieving events. *quit_callback* is called when the socket connection dies. """ ipc_socket = "\\\\.\\pipe\\" + ipc_socket self.callback = callback self.quit_callback = quit_callback access = _winapi.GENERIC_READ | _winapi.GENERIC_WRITE limit = 5 # Connection may fail at first. Try 5 times. for _ in range(limit): try: pipe_handle = _winapi.CreateFile(ipc_socket, access, 0, _winapi.NULL, _winapi.OPEN_EXISTING, _winapi.FILE_FLAG_OVERLAPPED, _winapi.NULL) break except OSError: time.sleep(1) else: raise MPVError("Cannot connect to pipe.") self.socket = PipeConnection(pipe_handle) if self.callback is None: self.callback = lambda data: None threading.Thread.__init__(self) def stop(self, join=True): """Terminate the thread.""" if self.socket is not None: self.socket.close() if join: self.join() def send(self, data): """Send *data* to the pipe, encoded as JSON.""" try: self.socket.send_bytes(json.dumps(data).encode('utf-8') + b'\n') except OSError as ex: if len(ex.args) == 1 and ex.args[0] == "handle is closed": raise BrokenPipeError("handle is closed") raise ex def run(self): """Process pipe events. Do not run this directly. Use *start*.""" data = b'' try: while True: current_data = self.socket.recv_bytes(2048) if current_data == b'': break data += current_data if data[-1] != 10: continue data = data.decode('utf-8', 'ignore').encode('utf-8') for item in data.split(b'\n'): if item == b'': continue json_data = json.loads(item) self.callback(json_data) data = b'' except EOFError: if self.quit_callback: self.quit_callback() except Exception as ex: log.error("Pipe connection died.", exc_info=1) if self.quit_callback: self.quit_callback()
def rebuild_pipe_connection(dh, readable, writable): handle = dh.detach() return PipeConnection(handle, readable, writable)