예제 #1
0
static DWORD
AsyncPipeOp (async_op_t op, HANDLE pipe, LPVOID buffer, DWORD size, DWORD count, LPHANDLE events)
{
  int i;
  BOOL success;
  HANDLE io_event;
  DWORD res, bytes = 0;
  OVERLAPPED overlapped;
  LPHANDLE handles = NULL;

  io_event = InitOverlapped (&overlapped);
  if (!io_event)
    goto out;

  handles = malloc ((count + 1) * sizeof (HANDLE));
  if (!handles)
    goto out;

  if (op == write)
    success = WriteFile (pipe, buffer, size, NULL, &overlapped);
  else
    success = ReadFile (pipe, buffer, size, NULL, &overlapped);
  if (!success && GetLastError () != ERROR_IO_PENDING && GetLastError () != ERROR_MORE_DATA)
    goto out;

  handles[0] = io_event;
  for (i = 0; i < count; i++)
    handles[i + 1] = events[i];

  res = WaitForMultipleObjects (count + 1, handles, FALSE,
                                op == peek ? INFINITE : IO_TIMEOUT);
  if (res != WAIT_OBJECT_0)
    {
      CancelIo (pipe);
      goto out;
    }

  if (op == peek)
    PeekNamedPipe (pipe, NULL, 0, NULL, &bytes, NULL);
  else
    GetOverlappedResult (pipe, &overlapped, &bytes, TRUE);

out:
  CloseHandleEx (&io_event);
  free (handles);
  return bytes;
}
예제 #2
0
//
// Begin accepting a connection to an existing port.  Used by server.
// For synchronous port, blocks until a connection is made (returns TRUE)
// or an error occurs (returns FALSE).  For asynchronous port, returns 
// immediately.  Returns TRUE for success or FALSE if any error occurs.
//		Call IsAcceptComplete() to determine if it has completed, 
//		and GetAcceptResult() to get result.
//
BOOL PortPipe::Accept()
{
	if ( synchronous )
	{
		#if PORT_DETAILS || _DETAILS
			cout << "Waiting to accept connection to " << name << "." << endl;
		#endif
		
		return ( ConnectNamedPipe( p, NULL ) );
	}
	else
	{
		#if PORT_DETAILS || _DETAILS
			cout << "Starting to accept connection to " << name << "." << endl;
		#endif

		if ( !InitOverlapped( &accept_overlapped ) )
		{
			return FALSE;
		}
		
		if ( ConnectNamedPipe( p, &accept_overlapped ) )
		{
			#if PORT_DETAILS || _DETAILS
				cout << "Connection accepted." << endl;
			#endif
			return TRUE;
		}
		else
		{
			if ( GetLastError() == ERROR_IO_PENDING ) // Read started OK...
			{
				return TRUE;
			}
			else
			{
				*errmsg << "*** ConnectNamedPipe() failed in PortPipe::Accept()." << ends;
				OutputErrMsg();
				return FALSE;
			}
		}
	}
}
예제 #3
0
//
// Call which sends data to a connected port.  Blocking call for synchronous 
// port; non-blocking call for asynchronous port.  Note that a process will
// not send data to itself.
//
DWORDLONG PortPipe::Send( LPVOID msg, DWORD size )
{
	DWORD bytes_written;
	OVERLAPPED *olap;

	if ( synchronous )
	{
		olap = NULL;
	}
	else
	{
		if ( !InitOverlapped( &send_overlapped ) )
		{
			return PORT_ERROR;
		}
		olap = &send_overlapped;
	}

	if ( WriteFile( p, msg, size, &bytes_written, olap ) )
	{
		#if PORT_DETAILS || _DETAILS
			cout << "Sent " << bytes_written << " of " << size 
				 << " bytes to port " << name << "." << endl;
		#endif
		return (DWORDLONG) bytes_written;
	}
	else
	{
		// Did asynchronous write started OK?
		if ( !synchronous && (GetLastError() == ERROR_IO_PENDING) )
		{
			return 0;	// not an error code, but no bytes read yet
		}

		*errmsg << "*** Error " << GetLastError() << " sending " << size 
				<< " bytes to port " << name << " in PortPipe::Send()." << ends;
		OutputErrMsg();
		return PORT_ERROR;
	}
}
예제 #4
0
//
// Call which receives data from a connected port.  Blocking call for
// synchronous port; non-blocking call for asynchronous port.  
// Note that a receive call will not receive data from itself.
//
DWORDLONG PortPipe::Receive( LPVOID msg, DWORD size )
{
	DWORD bytes_read;
	OVERLAPPED *olap;

	if ( synchronous )
	{
		olap = NULL;
	}
	else
	{
		if ( !InitOverlapped( &receive_overlapped ) )
		{
			return PORT_ERROR;
		}
		olap = &receive_overlapped;
	}

	if ( ReadFile( p, msg, size, &bytes_read, olap ) )
	{
		#if PORT_DETAILS || _DETAILS
			cout << "Received " << bytes_read << " of " << size 
				 << " bytes from port " << name << "." << endl;
		#endif

		return (DWORDLONG) bytes_read;
	}
	else
	{
		if ( !synchronous && (GetLastError() == ERROR_IO_PENDING) ) // Asynchronous read started OK...
		{
			return 0;	// not an error code, but no bytes read yet
		}

		*errmsg << "*** Error receiving " << size << " bytes from port " 
				<< name << " in PortPipe::Receive()." << ends;
		OutputErrMsg();
		return PORT_ERROR;
	}
}
예제 #5
0
//
// Begin accepting a connection to an existing port.  Used by server.
// For synchronous port, blocks until a connection is made (returns TRUE) or an error occurs (returns FALSE).
// For asynchronous port, returns immediately.  Returns TRUE for success or FALSE if any error occurs.
//     Call IsAcceptComplete() to determine if it has completed, and GetAcceptResult() to get result.
//
BOOL PortTCP::Accept()
{
	//
	// Listen to socket.
	//

#if PORT_DETAILS || _DETAILS
	cout << "Listening to socket " << name << "." << endl;
	WSASetLastError(0);
#endif

	if (listen(server_socket, 0) != 0)	// allow at most one connection at a time
	{
		*errmsg << "===> ERROR: Listening to socket " << name << " failed." << endl
		    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl
		    << "     errno = " << WSAGetLastError() << ends;
		OutputErrMsg();
		return FALSE;
	}
	//
	// Accept connections to socket.
	//

#if PORT_DETAILS || _DETAILS
	cout << "Accepting connections to socket " << name << "." << endl;
	WSASetLastError(0);
#endif

	if (synchronous) {
		// don't need any info about who we're talking to
		client_socket = accept(server_socket, NULL, NULL);

		if (client_socket == (int)INVALID_SOCKET) {
			*errmsg << "===> ERROR: Accepting connection to socket " << name << " failed." << endl
			    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		} else {
			return TRUE;
		}
	}
#if defined(IOMTR_OS_WIN32) || defined(IOMTR_OS_WIN64)
	else {
		DWORD bytes_received;

		if (!InitOverlapped(&accept_overlapped)) {
			*errmsg << "===> ERROR: Creating OVERLAPPED structure for socket " << name << " failed." << endl
			    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << ends;
			OutputErrMsg();
			return FALSE;
		}

		//
		// Create client socket.
		//

#if PORT_DETAILS || _DETAILS
		cout << "Creating client socket for " << name << "." << endl;
		WSASetLastError(0);
#endif

		client_socket = WSASocket(AF_INET, SOCK_STREAM, PF_UNSPEC, NULL, 0, WSA_FLAG_OVERLAPPED);

		if (client_socket == INVALID_SOCKET) {
			*errmsg << "===> ERROR: Creating client socket for " << name << " failed." << endl
			    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << endl
			    << "     errno = " << WSAGetLastError() << ends;
			OutputErrMsg();
			return FALSE;
		}
		//
		// Accept connections to socket.
		//
		if (AcceptEx(server_socket, client_socket, accept_ex_buffer, 0,	// read no data, only the two addresses, into accept_ex_buffer
			     sizeof(struct sockaddr_in) + 16, sizeof(struct sockaddr_in) + 16,
			     &bytes_received, &accept_overlapped)) {
#if PORT_DETAILS || _DETAILS
			cout << "Connection accepted." << endl;
#endif

			return TRUE;
		} else {
			if (WSAGetLastError() == WSA_IO_PENDING)	// Read started OK...
			{
				return TRUE;
			} else {
				*errmsg << "===> ERROR: AcceptEx() failed." << endl
				    << "     [PortTCP::Accept() in " << __FILE__ << " line " << __LINE__ << "]" << ends;
				OutputErrMsg();
				return FALSE;
			}
		}
	}
#elif defined(IOMTR_OS_LINUX) || defined(IOMTR_OS_NETWARE) || defined(IOMTR_OS_OSX) || defined(IOMTR_OS_SOLARIS)
	else {