Beispiel #1
0
    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)
Beispiel #2
0
    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
Beispiel #3
0
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)
Beispiel #4
0
 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()
Beispiel #5
0
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()
Beispiel #6
0
def rebuild_pipe_connection(dh, readable, writable):
    handle = dh.detach()
    return PipeConnection(handle, readable, writable)