Example #1
0
    def connect(self, timeout=0, buf_sz=0):
        if self.transport == Pipe.Transport.ASYNCHRONOUS:
            if timeout == 0:
                event_timeout = w32ev.INFINITE
            stream = self.__getOverlappedStruct()
            # Asynchronous named pipes return immediately!
            status_code = w32p.ConnectNamedPipe(
                self.__hPipe, stream
            )
            if status_code != werr.ERROR_IO_PENDING:
                raise PipeError(
                    'Failed to create unsynchronous named pipe connection!',
                    'status_code',
                    status_code
                )
            self.__waitForEvent(stream, event_timeout)
        else:
            status_code = w32p.ConnectNamedPipe(self.__hPipe, None)
            if status_code != 0:
                raise PipeError(
                    'Failed to create synchronous named pipe connection!',
                    'status_code',
                    status_code
                )

        return 0
Example #2
0
 def __waitForEvent(self, stream, event_timeout):
     # Asynchronous I/O operations may complete in the
     # blink of an eye giving the false impression that
     # it completed as a synchronous I/O. As such, we
     # have to wait for the event to be signaled by the
     # read operation.
     # This is also required if GetOverlappedResult does
     # not wait for data to become available (bWait is
     # set to False) otherwise it will complain that the
     # event handler is in a non-signaled state.
     event_code = w32ev.WaitForSingleObject(
         stream.hEvent, event_timeout
     )
     if event_code == w32ev.WAIT_TIMEOUT:
         raise PipeTimeoutError(
                 'Connection timeout while awaiting pipe activity!',
                 'event_timeout',
                 event_timeout,
                 'event_code',
                 event_code
         )
     elif event_code != w32ev.WAIT_OBJECT_0:
         raise PipeError(
             'Unexpected pipe signal code event!',
             'event_code',
             event_code
         )
Example #3
0
 def read(self, timeout=0, buf_sz=0):
     if self.transport == Pipe.Transport.ASYNCHRONOUS:
         if timeout is None:
             evTimeout = 50  # 50ms is the default value per MSDN docs.
         elif int(timeout) == 0:
             evTimeout = 50  # 50ms is the default value per MSDN docs.
         else:
             evTimeout = int(timeout)
         stream = self._getOverlappedStruct()
         if buf_sz <= 0:
             buf_sz = 2048
         ov_buf = w32f.AllocateReadBuffer(buf_sz)
         pipe_data = ''
         while True:
             try:
                 pipe_status, pipe_buffer = w32f.ReadFile(
                     self.__hPipe, ov_buf, stream
                 )
             except WinT.error, e:
                 if e.args[0] == werr.ERROR_BROKEN_PIPE:
                     return 1, stream.Offset, pipe_data
                 else:
                     raise
             if pipe_status == 0 or \
                pipe_status == werr.ERROR_IO_PENDING:
                 #TODO: Return stream and then prompt user to fetch data.
                 if pipe_status == werr.ERROR_IO_PENDING:
                     self.__waitForEvent(stream, evTimeout)
                 try:
                     read_bytes = w32f.GetOverlappedResult(
                         self.__hPipe, stream, False
                     )
                 except WinT.error, e:
                     if e.args[0] == werr.ERROR_MORE_DATA:
                         ov_buf = self.__expandBufferPipe(buf_sz)
                         stream.Offset += len(pipe_buffer)
                         pipe_data += pipe_buffer
                         continue
                     elif e.args[0] == werr.ERROR_BROKEN_PIPE:
                         return 1, stream.Offset, pipe_data
                     else:
                         raise
             elif pipe_status == werr.ERROR_MORE_DATA:
                 ov_buf = self.__expandBufferPipe(buf_sz)
                 stream.Offset += len(pipe_buffer)
                 pipe_data += pipe_buffer
                 continue
             else:
                 raise PipeError(
                     'Pipe encountered a fatal error!',
                     'error_code',
                     w32api.GetLastError()
                 )
             stream.Offset += read_bytes
             pipe_data += pipe_buffer[:read_bytes]
             if read_bytes < len(pipe_buffer):
                 return 0, stream.Offset, pipe_data
Example #4
0
 def _listen(self, policy=POLICY.RW, repeat=True):
     status_code = self.connect()
     if status_code == 0:
         pipe_status, pipe_bytes, pipe_content = self.read()
         self.close()
     else:
         raise PipeError(
             'Pipe encountered an error while attempting a connection!',
             'status_code', status_code)
     return status_code, pipe_status, pipe_bytes, pipe_content
Example #5
0
 def connect(self, timeout=0, buf_sz=0, ev_aware=True):
     if self.transport == Pipe.Transport.ASYNCHRONOUS:
         if int(timeout) == 0:
             evTimeout = w32ev.INFINITE
         else:
             evTimeout = int(timeout)
         stream = self._getOverlappedStruct()
         # Asynchronous named pipes return immediately!
         status_code = w32p.ConnectNamedPipe(
             self.__hPipe, stream
         )
         # From the MSDN docs:
         #   https://msdn.microsoft.com/en-us/library/windows/desktop/aa365146(v=vs.85).aspx
         # If a client connects before the function is called (i.e.
         # the timeframe between CreateNamedPipe and ConnectNamedPipe, the
         # latter function returns zero and GetLastError returns
         # ERROR_PIPE_CONNECTED.
         if status_code == werr.ERROR_PIPE_CONNECTED:
             w32ev.SetEvent(stream.hEvent)
             if ev_aware:
                 return stream
         elif status_code != werr.ERROR_IO_PENDING:
             raise PipeError(
                 'Failed to create unsynchronous named pipe connection!',
                 'status_code',
                 status_code
             )
         else:
             if ev_aware:
                 self.__waitForEvent(stream, evTimeout)
             else:
                 return stream
     else:
         status_code = w32p.ConnectNamedPipe(self.__hPipe, None)
         if status_code != 0:
             raise PipeError(
                 'Failed to create synchronous named pipe connection!',
                 'status_code',
                 status_code
             )
     return 0
Example #6
0
 def _listen(self, timeout=0, policy=POLICY.RW):
     status_code = self.connect()
     if status_code == 0:
         status_code, written_bytes = self.write("Hello CRAPI client! :)",
                                                 timeout=timeout)
         print("Payload status code (W): ", end="")
         print(status_code)
         print("# of bytes written (W): ", end="")
         print(written_bytes)
         pipe_status, pipe_bytes, pipe_content = self.read(timeout=timeout)
         self.close()
     else:
         raise PipeError(
             'Pipe encountered an error while attempting a connection!',
             'status_code', status_code)
     return status_code, pipe_status, pipe_bytes, pipe_content