Ejemplo n.º 1
0
wStream* transport_send_stream_init(rdpTransport* transport, int size)
{
	wStream* s;
	if (!(s = StreamPool_Take(transport->ReceivePool, size)))
		return NULL;
	if (!Stream_EnsureCapacity(s, size))
	{
		Stream_Release(s);
		return NULL;
	}
	Stream_SetPosition(s, 0);
	return s;
}
Ejemplo n.º 2
0
rdpTransport* transport_new(rdpContext* context)
{
	rdpTransport* transport;

	transport = (rdpTransport*) calloc(1, sizeof(rdpTransport));

	if (!transport)
		return NULL;

	transport->context = context;
	transport->settings = context->settings;

	transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);

	if (!transport->ReceivePool)
		goto out_free_transport;

	/* receive buffer for non-blocking read. */
	transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);

	if (!transport->ReceiveBuffer)
		goto out_free_receivepool;

	transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

	if (!transport->connectedEvent || transport->connectedEvent == INVALID_HANDLE_VALUE)
		goto out_free_receivebuffer;

	transport->blocking = TRUE;
	transport->GatewayEnabled = FALSE;
	transport->layer = TRANSPORT_LAYER_TCP;

	if (!InitializeCriticalSectionAndSpinCount(&(transport->ReadLock), 4000))
		goto out_free_connectedEvent;

	if (!InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000))
		goto out_free_readlock;

	return transport;
out_free_readlock:
	DeleteCriticalSection(&(transport->ReadLock));
out_free_connectedEvent:
	CloseHandle(transport->connectedEvent);
out_free_receivebuffer:
	StreamPool_Return(transport->ReceivePool, transport->ReceiveBuffer);
out_free_receivepool:
	StreamPool_Free(transport->ReceivePool);
out_free_transport:
	free(transport);
	return NULL;
}
Ejemplo n.º 3
0
rdpTransport* transport_new(rdpSettings* settings)
{
	rdpTransport* transport;

	transport = (rdpTransport*) malloc(sizeof(rdpTransport));

	if (transport != NULL)
	{
		ZeroMemory(transport, sizeof(rdpTransport));

		transport->TcpIn = tcp_new(settings);

		transport->settings = settings;

		/* a small 0.1ms delay when transport is blocking. */
		transport->SleepInterval = 100;

		transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);

		/* receive buffer for non-blocking read. */
		transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
		transport->ReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		/* buffers for blocking read/write */
		transport->ReceiveStream = StreamPool_Take(transport->ReceivePool, 0);
		transport->SendStream = Stream_New(NULL, BUFFER_SIZE);

		transport->blocking = TRUE;

		transport->layer = TRANSPORT_LAYER_TCP;
	}

	return transport;
}
Ejemplo n.º 4
0
int dvcman_receive_channel_data_first(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, UINT32 length)
{
	DVCMAN_CHANNEL* channel;

	channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId);

	if (!channel)
	{
		DEBUG_WARN("ChannelId %d not found!", ChannelId);
		return 1;
	}

	if (channel->dvc_data)
		Stream_Release(channel->dvc_data);

	channel->dvc_data = StreamPool_Take(channel->dvcman->pool, length);
	Stream_AddRef(channel->dvc_data);

	return 0;
}
Ejemplo n.º 5
0
rdpTransport* transport_new(rdpSettings* settings)
{
	rdpTransport* transport;

	transport = (rdpTransport*) malloc(sizeof(rdpTransport));

	if (transport)
	{
		ZeroMemory(transport, sizeof(rdpTransport));

		WLog_Init();
		transport->log = WLog_Get("com.freerdp.core.transport");

		transport->TcpIn = tcp_new(settings);

		transport->settings = settings;

		/* a small 0.1ms delay when transport is blocking. */
		transport->SleepInterval = 100;

		transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);

		/* receive buffer for non-blocking read. */
		transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
		transport->ReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);

		transport->blocking = TRUE;

		transport->ReadMutex = CreateMutex(NULL, FALSE, NULL);
		transport->WriteMutex = CreateMutex(NULL, FALSE, NULL);

		transport->layer = TRANSPORT_LAYER_TCP;
	}

	return transport;
}
Ejemplo n.º 6
0
/** Creates a new connection based on the settings found in the "instance" parameter
 *  It will use the callbacks registered on the structure to process the pre/post connect operations
 *  that the caller requires.
 *  @see struct rdp_freerdp in freerdp.h
 *
 *  @param instance - pointer to a rdp_freerdp structure that contains base information to establish the connection.
 *  				  On return, this function will be initialized with the new connection's settings.
 *
 *  @return TRUE if successful. FALSE otherwise.
 *
 */
BOOL freerdp_connect(freerdp* instance)
{
	rdpRdp* rdp;
	rdpSettings* settings;
	BOOL status = FALSE;
	ConnectionResultEventArgs e;

	/* We always set the return code to 0 before we start the connect sequence*/
	connectErrorCode = 0;

	rdp = instance->context->rdp;
	settings = instance->settings;

	IFCALLRET(instance->PreConnect, status, instance);

	if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002)
	{
		settings->KeyboardType = 7;
		settings->KeyboardSubType = 2;
		settings->KeyboardFunctionKey = 12;
	}

	extension_load_and_init_plugins(rdp->extension);
	extension_pre_connect(rdp->extension);

	if (!status)
	{
		if (!connectErrorCode)
		{
			connectErrorCode = PREECONNECTERROR;
		}
		fprintf(stderr, "%s:%d: freerdp_pre_connect failed\n", __FILE__, __LINE__);

		goto freerdp_connect_finally;
	}

	status = rdp_client_connect(rdp);

	/* --authonly tests the connection without a UI */
	if (instance->settings->AuthenticationOnly)
	{
		fprintf(stderr, "%s:%d: Authentication only, exit status %d\n", __FILE__, __LINE__, !status);
		goto freerdp_connect_finally;
	}

	if (status)
	{
		if (instance->settings->DumpRemoteFx)
		{
			instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE);
			if (instance->update->pcap_rfx)
				instance->update->dump_rfx = TRUE;
		}

		extension_post_connect(rdp->extension);

		IFCALLRET(instance->PostConnect, status, instance);
		update_post_connect(instance->update);

		if (!status)
		{
			fprintf(stderr, "freerdp_post_connect failed\n");

			if (!connectErrorCode)
			{
				connectErrorCode = POSTCONNECTERROR;
			}

			goto freerdp_connect_finally;
		}

		if (instance->settings->PlayRemoteFx)
		{
			wStream* s;
			rdpUpdate* update;
			pcap_record record;

			update = instance->update;

			update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);

			if (!update->pcap_rfx)
			{
				status = FALSE;
				goto freerdp_connect_finally;
			}
			else
			{
				update->play_rfx = TRUE;
			}

			while (pcap_has_next_record(update->pcap_rfx))
			{

				pcap_get_next_record_header(update->pcap_rfx, &record);

				s = StreamPool_Take(rdp->transport->ReceivePool, record.length);
				record.data = Stream_Buffer(s);

				pcap_get_next_record_content(update->pcap_rfx, &record);
				Stream_SetLength(s,record.length);
				Stream_SetPosition(s, 0);

				update->BeginPaint(update->context);
				update_recv_surfcmds(update, Stream_Length(s) , s);
				update->EndPaint(update->context);
				Stream_Release(s);
			
				StreamPool_Return(rdp->transport->ReceivePool, s);
			}

			pcap_close(update->pcap_rfx);
			update->pcap_rfx = NULL;
			status = TRUE;
			goto freerdp_connect_finally;
		}
	}

	if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
	{
		connectErrorCode = INSUFFICIENTPRIVILEGESERROR;
	}

	if (!connectErrorCode)
	{
		connectErrorCode = UNDEFINEDCONNECTERROR;
	}

	SetEvent(rdp->transport->connectedEvent);

	freerdp_connect_finally:

	EventArgsInit(&e, "freerdp");
	e.result = status ? 0 : -1;
	PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e);

	return status;
}
Ejemplo n.º 7
0
int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s)
{
    BYTE type;
    wStream* cs;
    UINT16 length;
    UINT32 shareId;
    BYTE compressedType;
    UINT16 compressedLength;

    if (!rdp_read_share_data_header(s, &length, &type, &shareId, &compressedType, &compressedLength))
        return -1;

    cs = s;

    if (compressedType & PACKET_COMPRESSED)
    {
        UINT32 DstSize = 0;
        BYTE* pDstData = NULL;
        UINT32 SrcSize = compressedLength - 18;

        if (Stream_GetRemainingLength(s) < (size_t) SrcSize)
        {
            DEBUG_WARN( "bulk_decompress: not enough bytes for compressedLength %d\n", compressedLength);
            return -1;
        }

        if (bulk_decompress(rdp->bulk, Stream_Pointer(s), SrcSize, &pDstData, &DstSize, compressedType))
        {
            cs = StreamPool_Take(rdp->transport->ReceivePool, DstSize);

            Stream_SetPosition(cs, 0);
            Stream_Write(cs, pDstData, DstSize);
            Stream_SealLength(cs);
            Stream_SetPosition(cs, 0);
        }
        else
        {
            DEBUG_WARN( "bulk_decompress() failed\n");
            return -1;
        }

        Stream_Seek(s, SrcSize);
    }

#ifdef WITH_DEBUG_RDP
    DEBUG_MSG("recv %s Data PDU (0x%02X), length: %d\n",
              type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length);
#endif

    switch (type)
    {
    case DATA_PDU_TYPE_UPDATE:
        if (!update_recv(rdp->update, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_CONTROL:
        if (!rdp_recv_server_control_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_POINTER:
        if (!update_recv_pointer(rdp->update, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_SYNCHRONIZE:
        if (!rdp_recv_synchronize_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_PLAY_SOUND:
        if (!update_recv_play_sound(rdp->update, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_SHUTDOWN_DENIED:
        if (!rdp_recv_server_shutdown_denied_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_SAVE_SESSION_INFO:
        if (!rdp_recv_save_session_info(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_FONT_MAP:
        if (!rdp_recv_font_map_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
        if (!rdp_recv_server_set_keyboard_indicators_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS:
        if (!rdp_recv_server_set_keyboard_ime_status_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_SET_ERROR_INFO:
        if (!rdp_recv_set_error_info_data_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_ARC_STATUS:
        if (!rdp_recv_server_auto_reconnect_status_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_STATUS_INFO:
        if (!rdp_recv_server_status_info_pdu(rdp, cs))
            return -1;
        break;

    case DATA_PDU_TYPE_MONITOR_LAYOUT:
        if (!rdp_recv_monitor_layout_pdu(rdp, cs))
            return -1;
        break;

    default:
        break;
    }

    if (cs != s)
        Stream_Release(cs);

    return 0;
}
Ejemplo n.º 8
0
rdpTransport* transport_new(rdpSettings* settings)
{
	rdpTransport* transport;

	transport = (rdpTransport *)calloc(1, sizeof(rdpTransport));
	if (!transport)
		return NULL;

	WLog_Init();
	transport->log = WLog_Get("com.freerdp.core.transport");
	if (!transport->log)
		goto out_free;

	transport->TcpIn = tcp_new(settings);
	if (!transport->TcpIn)
		goto out_free;

	transport->settings = settings;

	/* a small 0.1ms delay when transport is blocking. */
	transport->SleepInterval = 100;

	transport->ReceivePool = StreamPool_New(TRUE, BUFFER_SIZE);
	if (!transport->ReceivePool)
		goto out_free_tcpin;

	/* receive buffer for non-blocking read. */
	transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
	if (!transport->ReceiveBuffer)
		goto out_free_receivepool;

	transport->ReceiveEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (!transport->ReceiveEvent || transport->ReceiveEvent == INVALID_HANDLE_VALUE)
		goto out_free_receivebuffer;

	transport->connectedEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
	if (!transport->connectedEvent || transport->connectedEvent == INVALID_HANDLE_VALUE)
		goto out_free_receiveEvent;

	transport->blocking = TRUE;
	transport->GatewayEnabled = FALSE;
	transport->layer = TRANSPORT_LAYER_TCP;

	if (!InitializeCriticalSectionAndSpinCount(&(transport->ReadLock), 4000))
		goto out_free_connectedEvent;
	if (!InitializeCriticalSectionAndSpinCount(&(transport->WriteLock), 4000))
		goto out_free_readlock;

	return transport;

out_free_readlock:
	DeleteCriticalSection(&(transport->ReadLock));
out_free_connectedEvent:
	CloseHandle(transport->connectedEvent);
out_free_receiveEvent:
	CloseHandle(transport->ReceiveEvent);
out_free_receivebuffer:
	StreamPool_Return(transport->ReceivePool, transport->ReceiveBuffer);
out_free_receivepool:
	StreamPool_Free(transport->ReceivePool);
out_free_tcpin:
	tcp_free(transport->TcpIn);
out_free:
	free(transport);
	return NULL;
}
Ejemplo n.º 9
0
int transport_check_fds(rdpTransport* transport)
{
	int status;
	int recv_status;
	wStream* received;

	if (!transport)
		return -1;

#ifdef _WIN32
	WSAResetEvent(transport->TcpIn->wsa_event);
#endif
	ResetEvent(transport->ReceiveEvent);

	/**
	 * Loop through and read all available PDUs.  Since multiple
	 * PDUs can exist, it's important to deliver them all before
	 * returning.  Otherwise we run the risk of having a thread
	 * wait for a socket to get signaled that data is available
	 * (which may never happen).
	 */
	for (;;)
	{
		/**
		 * Note: transport_read_pdu tries to read one PDU from
		 * the transport layer.
		 * The ReceiveBuffer might have a position > 0 in case of a non blocking
		 * transport. If transport_read_pdu returns 0 the pdu couldn't be read at
		 * this point.
		 * Note that transport->ReceiveBuffer is replaced after each iteration
		 * of this loop with a fresh stream instance from a pool.
		 */

		if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0)
		{
			return status;
		}

		received = transport->ReceiveBuffer;
		transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);
		/**
		 * status:
		 * 	-1: error
		 * 	 0: success
		 * 	 1: redirection
		 */

		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);

		if (recv_status == 1)
		{
			return 1; /* session redirection */
		}
		Stream_Release(received);

		if (recv_status < 0)
			return -1;
	}

	return 0;
}
Ejemplo n.º 10
0
int rdp_recv_data_pdu(rdpRdp* rdp, wStream* s)
{
	BYTE type;
	UINT32 roff;
	UINT32 rlen;
	wStream* cs;
	BYTE* buffer;
	UINT16 length;
	UINT32 share_id;
	BYTE compressed_type;
	UINT16 compressed_len;

	if (!rdp_read_share_data_header(s, &length, &type, &share_id, &compressed_type, &compressed_len))
		return -1;

	cs = s;

	if (compressed_type & PACKET_COMPRESSED)
	{
		if (Stream_GetRemainingLength(s) < compressed_len - 18)
		{
			fprintf(stderr, "decompress_rdp: not enough bytes for compressed_len=%d\n", compressed_len);
			return -1;	
		}

		if (decompress_rdp(rdp->mppc_dec, Stream_Pointer(s), compressed_len - 18, compressed_type, &roff, &rlen))
		{
			buffer = rdp->mppc_dec->history_buf + roff;
			cs = StreamPool_Take(rdp->transport->ReceivePool, rlen);

			Stream_SetPosition(cs, 0);
			Stream_Write(cs, buffer, rlen);
			Stream_SealLength(cs);
			Stream_SetPosition(cs, 0);
		}
		else
		{
			fprintf(stderr, "decompress_rdp() failed\n");
			return -1;
		}

		Stream_Seek(s, compressed_len - 18);
	}

#ifdef WITH_DEBUG_RDP
	/* if (type != DATA_PDU_TYPE_UPDATE) */
		DEBUG_RDP("recv %s Data PDU (0x%02X), length:%d",
				type < ARRAYSIZE(DATA_PDU_TYPE_STRINGS) ? DATA_PDU_TYPE_STRINGS[type] : "???", type, length);
#endif

	switch (type)
	{
		case DATA_PDU_TYPE_UPDATE:
			if (!update_recv(rdp->update, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_CONTROL:
			if (!rdp_recv_server_control_pdu(rdp, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_POINTER:
			if (!update_recv_pointer(rdp->update, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_INPUT:
			break;

		case DATA_PDU_TYPE_SYNCHRONIZE:
			if (!rdp_recv_synchronize_pdu(rdp, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_REFRESH_RECT:
			break;

		case DATA_PDU_TYPE_PLAY_SOUND:
			if (!update_recv_play_sound(rdp->update, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_SUPPRESS_OUTPUT:
			break;

		case DATA_PDU_TYPE_SHUTDOWN_REQUEST:
			break;

		case DATA_PDU_TYPE_SHUTDOWN_DENIED:
			break;

		case DATA_PDU_TYPE_SAVE_SESSION_INFO:
			if (!rdp_recv_save_session_info(rdp, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_FONT_LIST:
			break;

		case DATA_PDU_TYPE_FONT_MAP:
			if (!rdp_recv_font_map_pdu(rdp, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_SET_KEYBOARD_INDICATORS:
			break;

		case DATA_PDU_TYPE_BITMAP_CACHE_PERSISTENT_LIST:
			break;

		case DATA_PDU_TYPE_BITMAP_CACHE_ERROR:
			break;

		case DATA_PDU_TYPE_SET_KEYBOARD_IME_STATUS:
			break;

		case DATA_PDU_TYPE_OFFSCREEN_CACHE_ERROR:
			break;

		case DATA_PDU_TYPE_SET_ERROR_INFO:
			if (!rdp_recv_set_error_info_data_pdu(rdp, cs))
				return -1;
			break;

		case DATA_PDU_TYPE_DRAW_NINEGRID_ERROR:
			break;

		case DATA_PDU_TYPE_DRAW_GDIPLUS_ERROR:
			break;

		case DATA_PDU_TYPE_ARC_STATUS:
			break;

		case DATA_PDU_TYPE_STATUS_INFO:
			break;

		case DATA_PDU_TYPE_MONITOR_LAYOUT:
			break;

		default:
			break;
	}

	if (cs != s)
		Stream_Release(cs);

	return 0;
}
Ejemplo n.º 11
0
/** Creates a new connection based on the settings found in the "instance" parameter
 *  It will use the callbacks registered on the structure to process the pre/post connect operations
 *  that the caller requires.
 *  @see struct rdp_freerdp in freerdp.h
 *
 *  @param instance - pointer to a rdp_freerdp structure that contains base information to establish the connection.
 *  				  On return, this function will be initialized with the new connection's settings.
 *
 *  @return TRUE if successful. FALSE otherwise.
 *
 */
BOOL freerdp_connect(freerdp* instance)
{
	rdpRdp* rdp;
	BOOL status = TRUE;
	rdpSettings* settings;
	ConnectionResultEventArgs e;

	/* We always set the return code to 0 before we start the connect sequence*/
	connectErrorCode = 0;
	freerdp_set_last_error(instance->context, FREERDP_ERROR_SUCCESS);

	rdp = instance->context->rdp;
	settings = instance->settings;
	instance->context->codecs = codecs_new(instance->context);
	IFCALLRET(instance->PreConnect, status, instance);

	if (settings->KeyboardLayout == KBD_JAPANESE_INPUT_SYSTEM_MS_IME2002)
	{
		settings->KeyboardType = 7;
		settings->KeyboardSubType = 2;
		settings->KeyboardFunctionKey = 12;
	}

	if (!status)
	{
		if (!freerdp_get_last_error(rdp->context))
			freerdp_set_last_error(instance->context, FREERDP_ERROR_PRE_CONNECT_FAILED);

		WLog_ERR(TAG, "freerdp_pre_connect failed");
		goto freerdp_connect_finally;
	}

	status = rdp_client_connect(rdp);

	/* --authonly tests the connection without a UI */
	if (instance->settings->AuthenticationOnly)
	{
		WLog_ERR(TAG, "Authentication only, exit status %d", !status);
		goto freerdp_connect_finally;
	}

	if (status)
	{
		if (instance->settings->DumpRemoteFx)
		{
			instance->update->pcap_rfx = pcap_open(instance->settings->DumpRemoteFxFile, TRUE);
			if (instance->update->pcap_rfx)
				instance->update->dump_rfx = TRUE;
		}

		IFCALLRET(instance->PostConnect, status, instance);

		if (!status || !update_post_connect(instance->update))
		{
			WLog_ERR(TAG, "freerdp_post_connect failed");

			if (!freerdp_get_last_error(rdp->context))
				freerdp_set_last_error(instance->context, FREERDP_ERROR_POST_CONNECT_FAILED);

			goto freerdp_connect_finally;
		}

		if (instance->settings->PlayRemoteFx)
		{
			wStream* s;
			rdpUpdate* update;
			pcap_record record;

			update = instance->update;

			update->pcap_rfx = pcap_open(settings->PlayRemoteFxFile, FALSE);

			if (!update->pcap_rfx)
			{
				status = FALSE;
				goto freerdp_connect_finally;
			}
			else
			{
				update->play_rfx = TRUE;
			}

			while (pcap_has_next_record(update->pcap_rfx))
			{

				pcap_get_next_record_header(update->pcap_rfx, &record);

				if (!(s = StreamPool_Take(rdp->transport->ReceivePool, record.length)))
					break;

				record.data = Stream_Buffer(s);

				pcap_get_next_record_content(update->pcap_rfx, &record);
				Stream_SetLength(s,record.length);
				Stream_SetPosition(s, 0);

				update->BeginPaint(update->context);
				update_recv_surfcmds(update, Stream_Length(s) , s);
				update->EndPaint(update->context);
				Stream_Release(s);
			}

			pcap_close(update->pcap_rfx);
			update->pcap_rfx = NULL;
			status = TRUE;
			goto freerdp_connect_finally;
		}
	}

	if (rdp->errorInfo == ERRINFO_SERVER_INSUFFICIENT_PRIVILEGES)
		freerdp_set_last_error(instance->context, FREERDP_ERROR_INSUFFICIENT_PRIVILEGES);

	SetEvent(rdp->transport->connectedEvent);
freerdp_connect_finally:
	EventArgsInit(&e, "freerdp");
	e.result = status ? 0 : -1;
	PubSub_OnConnectionResult(instance->context->pubSub, instance->context, &e);

	return status;
}
Ejemplo n.º 12
0
int transport_check_fds(rdpTransport* transport)
{
	int status;
	int recv_status;
	wStream* received;
	DWORD now = GetTickCount();
	DWORD dueDate = 0;

	if (!transport)
		return -1;

	dueDate = now + transport->settings->MaxTimeInCheckLoop;

	if (transport->haveMoreBytesToRead)
	{
		transport->haveMoreBytesToRead = FALSE;
		ResetEvent(transport->rereadEvent);
	}

	while (now < dueDate)
	{
		if (freerdp_shall_disconnect(transport->context->instance))
		{
			return -1;
		}

		/**
		 * Note: transport_read_pdu tries to read one PDU from
		 * the transport layer.
		 * The ReceiveBuffer might have a position > 0 in case of a non blocking
		 * transport. If transport_read_pdu returns 0 the pdu couldn't be read at
		 * this point.
		 * Note that transport->ReceiveBuffer is replaced after each iteration
		 * of this loop with a fresh stream instance from a pool.
		 */
		if ((status = transport_read_pdu(transport, transport->ReceiveBuffer)) <= 0)
		{
			if (status < 0)
				WLog_Print(transport->log, WLOG_DEBUG, "transport_check_fds: transport_read_pdu() - %i", status);

			return status;
		}

		received = transport->ReceiveBuffer;

		if (!(transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0)))
			return -1;

		/**
		 * status:
		 * 	-1: error
		 * 	 0: success
		 * 	 1: redirection
		 */
		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);
		Stream_Release(received);

		/* session redirection or activation */
		if (recv_status == 1 || recv_status == 2)
		{
			return recv_status;
		}

		if (recv_status < 0)
		{
			WLog_Print(transport->log, WLOG_ERROR, "transport_check_fds: transport->ReceiveCallback() - %i",
			           recv_status);
			return -1;
		}

		now = GetTickCount();
	}

	if (now >= dueDate)
	{
		SetEvent(transport->rereadEvent);
		transport->haveMoreBytesToRead = TRUE;
	}

	return 0;
}
Ejemplo n.º 13
0
int transport_check_fds(rdpTransport* transport)
{
	int pos;
	int status;
	UINT16 length;
	int recv_status;
	wStream* received;

	if (!transport)
		return -1;

#ifdef _WIN32
	WSAResetEvent(transport->TcpIn->wsa_event);
#endif
	ResetEvent(transport->ReceiveEvent);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0)
	{
		Stream_SetPosition(transport->ReceiveBuffer, 0);

		if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = tpkt_read_header(transport->ReceiveBuffer);
		}
		else if (nla_verify_header(transport->ReceiveBuffer))
		{
			/* TSRequest */

			/* Ensure the TSRequest header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* TSRequest header can be 2, 3 or 4 bytes long */
			length = nla_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = nla_read_header(transport->ReceiveBuffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = fastpath_read_header(NULL, transport->ReceiveBuffer);
		}

		if (length == 0)
		{
			fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos);
			return -1;
		}

		if (pos < length)
		{
			Stream_SetPosition(transport->ReceiveBuffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		received = transport->ReceiveBuffer;
		transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);

		Stream_SetPosition(received, length);
		Stream_SealLength(received);
		Stream_SetPosition(received, 0);

		/**
		 * status:
		 * 	-1: error
		 * 	 0: success
		 * 	 1: redirection
		 */

		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);

		if (recv_status == 1)
		{
			/**
			 * Last call to ReceiveCallback resulted in a session redirection,
			 * which means the current rdpTransport* transport pointer has been freed.
			 * Return 0 for success, the rest of this function is meant for non-redirected cases.
			 */
			return 0;
		}

		Stream_Release(received);

		if (recv_status < 0)
			status = -1;

		if (status < 0)
			return status;
	}

	return 0;
}
Ejemplo n.º 14
0
int transport_check_fds(rdpTransport** ptransport)
{
	int pos;
	int status;
	UINT16 length;
	int recv_status;
	wStream* received;
	rdpTransport* transport = *ptransport;

#ifdef _WIN32
	WSAResetEvent(transport->TcpIn->wsa_event);
#endif
	ResetEvent(transport->ReceiveEvent);

	status = transport_read_nonblocking(transport);

	if (status < 0)
		return status;

	while ((pos = Stream_GetPosition(transport->ReceiveBuffer)) > 0)
	{
		Stream_SetPosition(transport->ReceiveBuffer, 0);

		if (tpkt_verify_header(transport->ReceiveBuffer)) /* TPKT */
		{
			/* Ensure the TPKT header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = tpkt_read_header(transport->ReceiveBuffer);
		}
		else if (nla_verify_header(transport->ReceiveBuffer))
		{
			/* TSRequest */

			/* Ensure the TSRequest header is available. */
			if (pos <= 4)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* TSRequest header can be 2, 3 or 4 bytes long */
			length = nla_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = nla_read_header(transport->ReceiveBuffer);
		}
		else /* Fast Path */
		{
			/* Ensure the Fast Path header is available. */
			if (pos <= 2)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			/* Fastpath header can be two or three bytes long. */
			length = fastpath_header_length(transport->ReceiveBuffer);

			if (pos < length)
			{
				Stream_SetPosition(transport->ReceiveBuffer, pos);
				return 0;
			}

			length = fastpath_read_header(NULL, transport->ReceiveBuffer);
		}

		if (length == 0)
		{
			fprintf(stderr, "transport_check_fds: protocol error, not a TPKT or Fast Path header.\n");
			winpr_HexDump(Stream_Buffer(transport->ReceiveBuffer), pos);
			return -1;
		}

		if (pos < length)
		{
			Stream_SetPosition(transport->ReceiveBuffer, pos);
			return 0; /* Packet is not yet completely received. */
		}

		received = transport->ReceiveBuffer;
		transport->ReceiveBuffer = StreamPool_Take(transport->ReceivePool, 0);

		Stream_SetPosition(received, length);
		Stream_SealLength(received);
		Stream_SetPosition(received, 0);

		recv_status = transport->ReceiveCallback(transport, received, transport->ReceiveExtra);

		if (transport == *ptransport)
			/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
			/* so only release if still valid */
			Stream_Release(received);
			

		if (recv_status < 0)
			status = -1;

		if (status < 0)
			return status;

		/* transport might now have been freed by rdp_client_redirect and a new rdp->transport created */
		transport = *ptransport;
	}

	return 0;
}