Beispiel #1
0
void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event)
{
	int i;
	wStream* s;

	DEBUG_CLIPRDR("Sending Clipboard Format List");

	if (cb_event->raw_format_data)
	{
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, cb_event->raw_format_data_size);
		Stream_Write(s, cb_event->raw_format_data, cb_event->raw_format_data_size);
	}
	else
	{
		wStream* body = Stream_New(NULL, 64);
		
		for (i = 0; i < cb_event->num_formats; i++)
		{
			const char* name;
			int name_length;

			switch (cb_event->formats[i])
			{
				case CB_FORMAT_HTML:
					name = CFSTR_HTML; name_length = sizeof(CFSTR_HTML);
					break;
				case CB_FORMAT_PNG:
					name = CFSTR_PNG; name_length = sizeof(CFSTR_PNG);
					break;
				case CB_FORMAT_JPEG:
					name = CFSTR_JPEG; name_length = sizeof(CFSTR_JPEG);
					break;
				case CB_FORMAT_GIF:
					name = CFSTR_GIF; name_length = sizeof(CFSTR_GIF);
					break;
				default:
					name = "\0\0";
					name_length = 2;
					break;
			}
			
			if (!cliprdr->use_long_format_names)
				name_length = 32;
			
			Stream_EnsureRemainingCapacity(body, Stream_Capacity(body) + 4 + name_length);

			Stream_Write_UINT32(body, cb_event->formats[i]);
			Stream_Write(body, name, name_length);
		}
				
		s = cliprdr_packet_new(CB_FORMAT_LIST, 0, Stream_Capacity(body));
		Stream_Write(s, Stream_Buffer(body), Stream_Capacity(body));
		Stream_Free(body, TRUE);
	}

	cliprdr_packet_send(cliprdr, s);
}
Beispiel #2
0
static void* tf_debug_channel_thread_func(void* arg)
{
	void* fd;
	wStream* s;
	void* buffer;
	DWORD BytesReturned = 0;
	testPeerContext* context = (testPeerContext*) arg;

	if (WTSVirtualChannelQuery(context->debug_channel, WTSVirtualFileHandle, &buffer, &BytesReturned) == TRUE)
	{
		fd = *((void**) buffer);
		WTSFreeMemory(buffer);

		context->event = CreateWaitObjectEvent(NULL, TRUE, FALSE, fd);
	}

	s = Stream_New(NULL, 4096);

	WTSVirtualChannelWrite(context->debug_channel, (PCHAR) "test1", 5, NULL);

	while (1)
	{
		WaitForSingleObject(context->event, INFINITE);

		if (WaitForSingleObject(context->stopEvent, 0) == WAIT_OBJECT_0)
			break;

		Stream_SetPosition(s, 0);

		if (WTSVirtualChannelRead(context->debug_channel, 0, (PCHAR) Stream_Buffer(s),
			Stream_Capacity(s), &BytesReturned) == FALSE)
		{
			if (BytesReturned == 0)
				break;

			Stream_EnsureRemainingCapacity(s, BytesReturned);

			if (WTSVirtualChannelRead(context->debug_channel, 0, (PCHAR) Stream_Buffer(s),
				Stream_Capacity(s), &BytesReturned) == FALSE)
			{
				/* should not happen */
				break;
			}
		}

		Stream_SetPosition(s, BytesReturned);

		printf("got %lu bytes\n", BytesReturned);
	}

	Stream_Free(s, TRUE);

	return 0;
}
Beispiel #3
0
wStream* StreamPool_Take(wStreamPool* pool, size_t size)
{
	int index;
	int foundIndex;
	wStream* s = NULL;

	if (pool->synchronized)
		EnterCriticalSection(&pool->lock);

	if (size == 0)
		size = pool->defaultSize;

	foundIndex = -1;

	for (index = 0; index < pool->aSize; index++)
	{
		s = pool->aArray[index];

		if (Stream_Capacity(s) >= size)
		{
			foundIndex = index;
			break;
		}
	}

	if (foundIndex < 0)
	{
		s = Stream_New(NULL, size);
		if (!s)
			goto out_fail;
	}
	else
	{
		Stream_SetPosition(s, 0);
		Stream_SetLength(s, Stream_Capacity(s));
		StreamPool_ShiftAvailable(pool, foundIndex, -1);
	}

	if (s)
	{
		s->pool = pool;
		s->count = 1;
		StreamPool_AddUsed(pool, s);
	}

out_fail:
	if (pool->synchronized)
		LeaveCriticalSection(&pool->lock);

	return s;
}
Beispiel #4
0
int dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr, UINT32 ChannelId, wStream* data)
{
	int status = 0;
	DVCMAN_CHANNEL* channel;
	UINT32 dataSize = Stream_GetRemainingLength(data);

	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)
	{
		/* Fragmented data */
		if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity(channel->dvc_data))
		{
			DEBUG_WARN("data exceeding declared length!");
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
			return 1;
		}

		Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize);

		if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data))
		{
			Stream_SealLength(channel->dvc_data);
			Stream_SetPosition(channel->dvc_data, 0);
			status = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data);
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
		}
	}
	else
	{
		status = channel->channel_callback->OnDataReceived(channel->channel_callback, data);
	}

	return status;
}
Beispiel #5
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rail_virtual_channel_event_data_received(railPlugin* rail,
        void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
	wStream* data_in;

	if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
	{
		return CHANNEL_RC_OK;
	}

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (rail->data_in)
			Stream_Free(rail->data_in, TRUE);

		rail->data_in = Stream_New(NULL, totalLength);

		if (!rail->data_in)
		{
			WLog_ERR(TAG, "Stream_New failed!");
			return CHANNEL_RC_NO_MEMORY;
		}
	}

	data_in = rail->data_in;

	if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
	{
		WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	Stream_Write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
		{
			WLog_ERR(TAG,  "rail_plugin_process_received: read error");
			return ERROR_INTERNAL_ERROR;
		}

		rail->data_in = NULL;
		Stream_SealLength(data_in);
		Stream_SetPosition(data_in, 0);

		if (!MessageQueue_Post(rail->queue, NULL, 0, (void*) data_in, NULL))
		{
			WLog_ERR(TAG, "MessageQueue_Post failed!");
			return ERROR_INTERNAL_ERROR;
		}
	}

	return CHANNEL_RC_OK;
}
Beispiel #6
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT drdynvc_virtual_channel_event_data_received(drdynvcPlugin* drdynvc,
        void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
	wStream* data_in;

	if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
	{
		return CHANNEL_RC_OK;
	}

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (drdynvc->data_in)
			Stream_Free(drdynvc->data_in, TRUE);

		drdynvc->data_in = Stream_New(NULL, totalLength);
	}

	if (!(data_in = drdynvc->data_in))
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_New failed!");
		return CHANNEL_RC_NO_MEMORY;
	}

	if (!Stream_EnsureRemainingCapacity(data_in, dataLength))
	{
		WLog_Print(drdynvc->log, WLOG_ERROR, "Stream_EnsureRemainingCapacity failed!");
		Stream_Free(drdynvc->data_in, TRUE);
		drdynvc->data_in = NULL;
		return ERROR_INTERNAL_ERROR;
	}

	Stream_Write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "drdynvc_plugin_process_received: read error");
			return ERROR_INVALID_DATA;
		}

		drdynvc->data_in = NULL;
		Stream_SealLength(data_in);
		Stream_SetPosition(data_in, 0);

		if (!MessageQueue_Post(drdynvc->queue, NULL, 0, (void*) data_in, NULL))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "MessageQueue_Post failed!");
			return ERROR_INTERNAL_ERROR;
		}
	}

	return CHANNEL_RC_OK;
}
Beispiel #7
0
int dvcman_receive_channel_data(IWTSVirtualChannelManager *pChannelMgr, UINT32 ChannelId, BYTE *data, UINT32 data_size)
{
	int error = 0;
	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)
	{
		/* Fragmented data */
		if (Stream_GetPosition(channel->dvc_data) + data_size > (UINT32) Stream_Capacity(channel->dvc_data))
		{
			DEBUG_WARN("data exceeding declared length!");
			Stream_Free(channel->dvc_data, TRUE);
			channel->dvc_data = NULL;
			return 1;
		}

		Stream_Write(channel->dvc_data, data, data_size);

		if (((size_t) Stream_GetPosition(channel->dvc_data)) >= Stream_Capacity(channel->dvc_data))
		{
			error = channel->channel_callback->OnDataReceived(channel->channel_callback,
					Stream_Capacity(channel->dvc_data), Stream_Buffer(channel->dvc_data));
			Stream_Free(channel->dvc_data, TRUE);
			channel->dvc_data = NULL;
		}
	}
	else
	{
		assert(channel->channel_callback);
		assert(channel->channel_callback->OnDataReceived);
		error = channel->channel_callback->OnDataReceived(channel->channel_callback, data_size, data);
	}

	return error;
}
Beispiel #8
0
wStream* rdg_receive_packet(rdpRdg* rdg)
{
	int status;
	wStream* s;
	RdgPacketHeader* packet;
	UINT32 readCount = 0;

	s = Stream_New(NULL, 1024);

	if (!s)
		return NULL;

	packet = (RdgPacketHeader*) Stream_Buffer(s);

	while (readCount < sizeof(RdgPacketHeader))
	{
		status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), sizeof(RdgPacketHeader) - readCount);

		if (status < 0)
		{
			continue;
		}

		readCount += status;
		Stream_Seek(s, readCount);
	}

	if (Stream_Capacity(s) < packet->packetLength)
	{
		if (!Stream_EnsureCapacity(s, packet->packetLength))
		{
			Stream_Free(s, TRUE);
			return NULL;
		}
		packet = (RdgPacketHeader*) Stream_Buffer(s);
	}

	while (readCount < packet->packetLength)
	{
		status = BIO_read(rdg->tlsOut->bio, Stream_Pointer(s), packet->packetLength - readCount);

		if (status < 0)
		{
			continue;
		}

		readCount += status;
		Stream_Seek(s, readCount);
	}

	Stream_SealLength(s);

	return s;
}
Beispiel #9
0
void tf_peer_dump_rfx(freerdp_peer* client)
{
	wStream* s;
	UINT32 prev_seconds;
	UINT32 prev_useconds;
	rdpUpdate* update;
	rdpPcap* pcap_rfx;
	pcap_record record;

	s = Stream_New(NULL, 512);
	update = client->update;
	client->update->pcap_rfx = pcap_open(test_pcap_file, FALSE);
	pcap_rfx = client->update->pcap_rfx;

	if (pcap_rfx == NULL)
		return;

	prev_seconds = prev_useconds = 0;

	while (pcap_has_next_record(pcap_rfx))
	{
		pcap_get_next_record_header(pcap_rfx, &record);

		Stream_Buffer(s) = realloc(Stream_Buffer(s), record.length);
		record.data = Stream_Buffer(s);
		Stream_Capacity(s) = record.length;

		pcap_get_next_record_content(pcap_rfx, &record);
		Stream_Pointer(s) = Stream_Buffer(s) + Stream_Capacity(s);

		if (test_dump_rfx_realtime && test_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec, record.header.ts_usec) == FALSE)
			break;

		update->SurfaceCommand(update->context, s);

		if (client->CheckFileDescriptor(client) != TRUE)
			break;
	}
}
Beispiel #10
0
int cliprdr_client_format_list(CliprdrClientContext* context, CLIPRDR_FORMAT_LIST* formatList)
{
	wStream* s;
	UINT32 index;
	int length = 0;
	int formatNameSize;
	CLIPRDR_FORMAT* format;
	cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;

	for (index = 0; index < formatList->numFormats; index++)
	{
		format = (CLIPRDR_FORMAT*) &(formatList->formats[index]);
		length += 4;
		formatNameSize = 2;

		if (format->formatName)
			formatNameSize = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, 0) * 2;

		length += formatNameSize;
	}

	s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length);

	for (index = 0; index < formatList->numFormats; index++)
	{
		format = (CLIPRDR_FORMAT*) &(formatList->formats[index]);
		Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */

		if (format->formatName)
		{
			int cchWideChar;
			LPWSTR lpWideCharStr;
			lpWideCharStr = (LPWSTR) Stream_Pointer(s);
			cchWideChar = (Stream_Capacity(s) - Stream_GetPosition(s)) / 2;
			formatNameSize = MultiByteToWideChar(CP_UTF8, 0,
				format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
			Stream_Seek(s, formatNameSize);
		}
		else
		{
			Stream_Write_UINT16(s, 0);
		}
	}

	WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatList: numFormats: %d",
			formatList->numFormats);
	cliprdr_packet_send(cliprdr, s);

	return 0;
}
Beispiel #11
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT dvcman_receive_channel_data(drdynvcPlugin* drdynvc,
                                        IWTSVirtualChannelManager* pChannelMgr,
                                        UINT32 ChannelId, wStream* data)
{
	UINT status = CHANNEL_RC_OK;
	DVCMAN_CHANNEL* channel;
	size_t dataSize = Stream_GetRemainingLength(data);
	channel = (DVCMAN_CHANNEL*) dvcman_find_channel_by_id(pChannelMgr, ChannelId);

	if (!channel)
	{
		/* Windows 8.1 tries to open channels not created.
				 * Ignore cases like this. */
		WLog_Print(drdynvc->log, WLOG_ERROR, "ChannelId %"PRIu32" not found!", ChannelId);
		return CHANNEL_RC_OK;
	}

	if (channel->dvc_data)
	{
		/* Fragmented data */
		if (Stream_GetPosition(channel->dvc_data) + dataSize > Stream_Capacity(channel->dvc_data))
		{
			WLog_Print(drdynvc->log, WLOG_ERROR, "data exceeding declared length!");
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
			return ERROR_INVALID_DATA;
		}

		Stream_Copy(data, channel->dvc_data, dataSize);

		if (Stream_GetPosition(channel->dvc_data) >= channel->dvc_data_length)
		{
			Stream_SealLength(channel->dvc_data);
			Stream_SetPosition(channel->dvc_data, 0);
			status = channel->channel_callback->OnDataReceived(channel->channel_callback,
			         channel->dvc_data);
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
		}
	}
	else
	{
		status = channel->channel_callback->OnDataReceived(channel->channel_callback,
		         data);
	}

	return status;
}
Beispiel #12
0
wStream* StreamPool_Take(wStreamPool* pool, size_t size)
{
	int index;
	int foundIndex;
	wStream* s = NULL;
	BOOL found = FALSE;

	if (pool->synchronized)
		WaitForSingleObject(pool->mutex, INFINITE);

	if (size == 0)
		size = pool->defaultSize;

	for (index = 0; index < pool->aSize; index++)
	{
		s = pool->aArray[index];

		if (Stream_Capacity(s) >= size)
		{
			foundIndex = index;
			found = TRUE;
			break;
		}
	}

	if (!found)
	{
		s = Stream_New(NULL, size);
	}
	else
	{
		StreamPool_ShiftAvailable(pool, foundIndex, -1);

		Stream_EnsureCapacity(s, size);
		Stream_Pointer(s) = Stream_Buffer(s);
	}

	s->pool = pool;
	s->count = 1;

	StreamPool_AddUsed(pool, s);

	if (pool->synchronized)
		ReleaseMutex(pool->mutex);

	return s;
}
Beispiel #13
0
wStream* StreamPool_Take(wStreamPool* pool, size_t size)
{
	int index;
	int foundIndex;
	wStream* s = NULL;
	BOOL found = FALSE;

	if (pool->synchronized)
		EnterCriticalSection(&pool->lock);

	if (size == 0)
		size = pool->defaultSize;

	for (index = 0; index < pool->aSize; index++)
	{
		s = pool->aArray[index];

		if (Stream_Capacity(s) >= size)
		{
			foundIndex = index;
			found = TRUE;
			break;
		}
	}

	if (!found)
	{
		s = Stream_New(NULL, size);
	}
	else
	{
		StreamPool_ShiftAvailable(pool, foundIndex, -1);

		Stream_EnsureCapacity(s, size);
		Stream_Pointer(s) = Stream_Buffer(s);
	}

	s->pool = pool;
	s->count = 1;

	StreamPool_AddUsed(pool, s);

	if (pool->synchronized)
		LeaveCriticalSection(&pool->lock);

	return s;
}
Beispiel #14
0
BOOL tf_peer_dump_rfx(freerdp_peer* client)
{
	wStream* s;
	UINT32 prev_seconds;
	UINT32 prev_useconds;
	rdpUpdate* update;
	rdpPcap* pcap_rfx;
	pcap_record record;
	s = Stream_New(NULL, 512);

	if (!s)
		return FALSE;

	update = client->update;

	if (!(pcap_rfx = pcap_open(test_pcap_file, FALSE)))
		return FALSE;

	prev_seconds = prev_useconds = 0;

	while (pcap_has_next_record(pcap_rfx))
	{
		if (!pcap_get_next_record_header(pcap_rfx, &record))
			break;

		if (!Stream_EnsureCapacity(s, record.length))
			break;

		record.data = Stream_Buffer(s);
		pcap_get_next_record_content(pcap_rfx, &record);
		Stream_SetPointer(s, Stream_Buffer(s) + Stream_Capacity(s));

		if (test_dump_rfx_realtime
		    && test_sleep_tsdiff(&prev_seconds, &prev_useconds, record.header.ts_sec,
		                         record.header.ts_usec) == FALSE)
			break;

		update->SurfaceCommand(update->context, s);

		if (client->CheckFileDescriptor(client) != TRUE)
			break;
	}

	Stream_Free(s, TRUE);
	pcap_close(pcap_rfx);
	return TRUE;
}
Beispiel #15
0
static void rail_virtual_channel_event_data_received(railPlugin* rail,
        void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
    wStream* data_in;

    if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
    {
        return;
    }

    if (dataFlags & CHANNEL_FLAG_FIRST)
    {
        if (rail->data_in)
            Stream_Free(rail->data_in, TRUE);

        rail->data_in = Stream_New(NULL, totalLength);
        if (!rail->data_in)
        {
            WLog_ERR(TAG, "%s: unable to allocate data_in", __FUNCTION__);
            return;
        }
    }

    data_in = rail->data_in;
    if (!Stream_EnsureRemainingCapacity(data_in, (int) dataLength))
    {
        WLog_ERR(TAG, "%s: unable to grow data_in to %d", __FUNCTION__, dataLength);
        return;
    }
    Stream_Write(data_in, pData, dataLength);

    if (dataFlags & CHANNEL_FLAG_LAST)
    {
        if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
        {
            WLog_ERR(TAG,  "rail_plugin_process_received: read error");
        }

        rail->data_in = NULL;
        Stream_SealLength(data_in);
        Stream_SetPosition(data_in, 0);

        MessageQueue_Post(rail->queue, NULL, 0, (void*) data_in, NULL);
    }
}
Beispiel #16
0
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT dvcman_receive_channel_data(IWTSVirtualChannelManager* pChannelMgr,
					UINT32 ChannelId, wStream* data)
{
	UINT status = CHANNEL_RC_OK;
	DVCMAN_CHANNEL* channel;
	size_t dataSize = Stream_GetRemainingLength(data);

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

	if (!channel)
	{
		WLog_ERR(TAG, "ChannelId %d not found!", ChannelId);
		return ERROR_INTERNAL_ERROR;
	}

	if (channel->dvc_data)
	{
		/* Fragmented data */
		if (Stream_GetPosition(channel->dvc_data) + dataSize > (UINT32) Stream_Capacity(channel->dvc_data))
		{
			WLog_ERR(TAG, "data exceeding declared length!");
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
			return ERROR_INVALID_DATA;
		}

		Stream_Write(channel->dvc_data, Stream_Pointer(data), dataSize);

		if (((size_t) Stream_GetPosition(channel->dvc_data)) >= channel->dvc_data_length)
		{
			Stream_SealLength(channel->dvc_data);
			Stream_SetPosition(channel->dvc_data, 0);
			status = channel->channel_callback->OnDataReceived(channel->channel_callback, channel->dvc_data);
			Stream_Release(channel->dvc_data);
			channel->dvc_data = NULL;
		}
	}
	else
	{
		status = channel->channel_callback->OnDataReceived(channel->channel_callback, data);
	}

	return status;
}
Beispiel #17
0
static void svc_plugin_process_received(rdpSvcPlugin* plugin, void* pData, UINT32 dataLength,
	UINT32 totalLength, UINT32 dataFlags)
{
	wStream* s;
	
	if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
	{
		/*
		 * According to MS-RDPBCGR 2.2.6.1, "All virtual channel traffic MUST be suspended.
		 * This flag is only valid in server-to-client virtual channel traffic. It MUST be
		 * ignored in client-to-server data." Thus it would be best practice to cease data
		 * transmission. However, simply returning here avoids a crash.
		 */
		return;
	}

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (plugin->data_in != NULL)
			Stream_Free(plugin->data_in, TRUE);

		plugin->data_in = Stream_New(NULL, totalLength);
	}

	s = plugin->data_in;
	Stream_EnsureRemainingCapacity(s, (int) dataLength);
	Stream_Write(s, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (Stream_Capacity(s) != Stream_GetPosition(s))
		{
			fprintf(stderr, "svc_plugin_process_received: read error\n");
		}

		plugin->data_in = NULL;
		Stream_SealLength(s);
		Stream_SetPosition(s, 0);

		MessageQueue_Post(plugin->MsgPipe->In, NULL, 0, (void*) s, NULL);
	}
}
Beispiel #18
0
wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr)
{
	int index;
	wStream* s = NULL;
	BOOL found = FALSE;

	WaitForSingleObject(pool->mutex, INFINITE);

	for (index = 0; index < pool->uSize; index++)
	{
		s = pool->uArray[index];

		if ((ptr >= Stream_Buffer(s)) && (ptr < (Stream_Buffer(s) + Stream_Capacity(s))))
		{
			found = TRUE;
			break;
		}
	}

	ReleaseMutex(pool->mutex);

	return (found) ? s : NULL;
}
Beispiel #19
0
wStream* StreamPool_Find(wStreamPool* pool, BYTE* ptr)
{
	int index;
	wStream* s = NULL;
	BOOL found = FALSE;

	EnterCriticalSection(&pool->lock);

	for (index = 0; index < pool->uSize; index++)
	{
		s = pool->uArray[index];

		if ((ptr >= Stream_Buffer(s)) && (ptr < (Stream_Buffer(s) + Stream_Capacity(s))))
		{
			found = TRUE;
			break;
		}
	}

	LeaveCriticalSection(&pool->lock);

	return (found) ? s : NULL;
}
Beispiel #20
0
static void remdesk_virtual_channel_event_data_received(remdeskPlugin* remdesk,
		void* pData, UINT32 dataLength, UINT32 totalLength, UINT32 dataFlags)
{
	wStream* data_in;

	if ((dataFlags & CHANNEL_FLAG_SUSPEND) || (dataFlags & CHANNEL_FLAG_RESUME))
	{
		return;
	}

	if (dataFlags & CHANNEL_FLAG_FIRST)
	{
		if (remdesk->data_in)
			Stream_Free(remdesk->data_in, TRUE);

		remdesk->data_in = Stream_New(NULL, totalLength);
	}

	data_in = remdesk->data_in;
	Stream_EnsureRemainingCapacity(data_in, (int) dataLength);
	Stream_Write(data_in, pData, dataLength);

	if (dataFlags & CHANNEL_FLAG_LAST)
	{
		if (Stream_Capacity(data_in) != Stream_GetPosition(data_in))
		{
			WLog_ERR(TAG,  "read error");
		}

		remdesk->data_in = NULL;
		Stream_SealLength(data_in);
		Stream_SetPosition(data_in, 0);

		MessageQueue_Post(remdesk->MsgPipe->In, NULL, 0, (void*) data_in, NULL);
	}
}
Beispiel #21
0
/**
 * Function description
 * Write RDPGFX_CMDID_WIRETOSURFACE_1 or RDPGFX_CMDID_WIRETOSURFACE_2
 * to the stream according to RDPGFX_SURFACE_COMMAND message
 *
 * @return 0 on success, otherwise a Win32 error code
 */
static UINT rdpgfx_write_surface_command(wStream* s,
        RDPGFX_SURFACE_COMMAND* cmd)
{
	UINT error = CHANNEL_RC_OK;
	RDPGFX_AVC420_BITMAP_STREAM* havc420 = NULL;
	RDPGFX_AVC444_BITMAP_STREAM* havc444 = NULL;
	UINT32 bitmapDataStart = 0;
	UINT32 bitmapDataLength = 0;
	UINT8 pixelFormat = 0;

	switch (cmd->format)
	{
		case PIXEL_FORMAT_BGRX32:
			pixelFormat = GFX_PIXEL_FORMAT_XRGB_8888;
			break;

		case PIXEL_FORMAT_BGRA32:
			pixelFormat = GFX_PIXEL_FORMAT_ARGB_8888;
			break;

		default:
			WLog_ERR(TAG, "Format %s not supported!", GetColorFormatName(cmd->format));
			return ERROR_INVALID_DATA;
	}

	if (cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE ||
	    cmd->codecId == RDPGFX_CODECID_CAPROGRESSIVE_V2)
	{
		/* Write RDPGFX_CMDID_WIRETOSURFACE_2 format for CAPROGRESSIVE */
		Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */
		Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */
		Stream_Write_UINT32(s, cmd->contextId); /* codecContextId (4 bytes) */
		Stream_Write_UINT8(s, pixelFormat); /* pixelFormat (1 byte) */
		Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */
		Stream_Write(s, cmd->data, cmd->length);
	}
	else
	{
		/* Write RDPGFX_CMDID_WIRETOSURFACE_1 format for others */
		Stream_Write_UINT16(s, cmd->surfaceId); /* surfaceId (2 bytes) */
		Stream_Write_UINT16(s, cmd->codecId); /* codecId (2 bytes) */
		Stream_Write_UINT8(s, pixelFormat); /* pixelFormat (1 byte) */
		Stream_Write_UINT16(s, cmd->left); /* left (2 bytes) */
		Stream_Write_UINT16(s, cmd->top); /* top (2 bytes) */
		Stream_Write_UINT16(s, cmd->right); /* right (2 bytes) */
		Stream_Write_UINT16(s, cmd->bottom); /* bottom (2 bytes) */
		Stream_Write_UINT32(s, cmd->length); /* bitmapDataLength (4 bytes) */
		bitmapDataStart = Stream_GetPosition(s);

		if (cmd->codecId == RDPGFX_CODECID_AVC420)
		{
			havc420 = (RDPGFX_AVC420_BITMAP_STREAM*)cmd->extra;
			error = rdpgfx_write_h264_avc420(s, havc420);

			if (error != CHANNEL_RC_OK)
			{
				WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!");
				return error;
			}
		}
		else if (cmd->codecId == RDPGFX_CODECID_AVC444)
		{
			havc444 = (RDPGFX_AVC444_BITMAP_STREAM*)cmd->extra;
			havc420 = &(havc444->bitstream[0]);
			/* avc420EncodedBitstreamInfo (4 bytes) */
			Stream_Write_UINT32(s, havc420->length | (havc444->LC << 30UL));
			/* avc420EncodedBitstream1 */
			error = rdpgfx_write_h264_avc420(s, havc420);

			if (error != CHANNEL_RC_OK)
			{
				WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!");
				return error;
			}

			/* avc420EncodedBitstream2 */
			if (havc444->LC == 0)
			{
				havc420 = &(havc444->bitstream[0]);
				error = rdpgfx_write_h264_avc420(s, havc420);

				if (error != CHANNEL_RC_OK)
				{
					WLog_ERR(TAG, "rdpgfx_write_h264_avc420 failed!");
					return error;
				}
			}
		}
		else
		{
			Stream_Write(s, cmd->data, cmd->length);
		}

		assert(Stream_GetPosition(s) <= Stream_Capacity(s));
		/* Fill actual bitmap data length */
		bitmapDataLength = Stream_GetPosition(s) - bitmapDataStart;
		Stream_SetPosition(s, bitmapDataStart - sizeof(UINT32));
		Stream_Write_UINT32(s, bitmapDataLength); /* bitmapDataLength (4 bytes) */
		Stream_Seek(s, bitmapDataLength);
	}

	return error;
}
Beispiel #22
0
static void* rdpdr_server_thread(void* arg)
{
	wStream* s;
	DWORD status;
	DWORD nCount;
	void* buffer;
	int position;
	HANDLE events[8];
	RDPDR_HEADER header;
	HANDLE ChannelEvent;
	DWORD BytesReturned;
	RdpdrServerContext* context;
	context = (RdpdrServerContext*) arg;
	buffer = NULL;
	BytesReturned = 0;
	ChannelEvent = NULL;
	s = Stream_New(NULL, 4096);

	if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}

	nCount = 0;
	events[nCount++] = ChannelEvent;
	events[nCount++] = context->priv->StopEvent;
	rdpdr_server_send_announce_request(context);

	while (1)
	{
		BytesReturned = 0;
		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
		{
			break;
		}

		WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);

		if (BytesReturned < 1)
			continue;

		Stream_EnsureRemainingCapacity(s, BytesReturned);

		if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
								   (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
		{
			break;
		}

		if (Stream_GetPosition(s) >= RDPDR_HEADER_LENGTH)
		{
			position = Stream_GetPosition(s);
			Stream_SetPosition(s, 0);
			Stream_Read_UINT16(s, header.Component); /* Component (2 bytes) */
			Stream_Read_UINT16(s, header.PacketId); /* PacketId (2 bytes) */
			Stream_SetPosition(s, position);
			Stream_SealLength(s);
			Stream_SetPosition(s, RDPDR_HEADER_LENGTH);
			rdpdr_server_receive_pdu(context, s, &header);
			Stream_SetPosition(s, 0);
		}
	}

	Stream_Free(s, TRUE);
	return NULL;
}
Beispiel #23
0
static void* encomsp_server_thread(void* arg)
{
	wStream* s;
	DWORD nCount;
	void* buffer;
	HANDLE events[8];
	HANDLE ChannelEvent;
	DWORD BytesReturned;
	ENCOMSP_ORDER_HEADER* header;
	EncomspServerContext* context;
	UINT error = CHANNEL_RC_OK;
	DWORD status;
	context = (EncomspServerContext*) arg;

	buffer = NULL;
	BytesReturned = 0;
	ChannelEvent = NULL;
	s = Stream_New(NULL, 4096);

	if (!s)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		error = CHANNEL_RC_NO_MEMORY;
		goto out;
	}

	if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle,
	                           &buffer, &BytesReturned) == TRUE)
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}

	nCount = 0;
	events[nCount++] = ChannelEvent;
	events[nCount++] = context->priv->StopEvent;

	while (1)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %u", error);
			break;
		}

		status = WaitForSingleObject(context->priv->StopEvent, 0);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForSingleObject failed with error %u", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
		{
			break;
		}

		WTSVirtualChannelRead(context->priv->ChannelHandle, 0, NULL, 0, &BytesReturned);

		if (BytesReturned < 1)
			continue;

		if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
		{
			WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
			error = CHANNEL_RC_NO_MEMORY;
			break;
		}

		if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
		                           (PCHAR) Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
		{
			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}

		if (Stream_GetPosition(s) >= ENCOMSP_ORDER_HEADER_SIZE)
		{
			header = (ENCOMSP_ORDER_HEADER*) Stream_Buffer(s);

			if (header->Length >= Stream_GetPosition(s))
			{
				Stream_SealLength(s);
				Stream_SetPosition(s, 0);

				if ((error = encomsp_server_receive_pdu(context, s)))
				{
					WLog_ERR(TAG, "encomsp_server_receive_pdu failed with error %u!", error);
					break;
				}

				Stream_SetPosition(s, 0);
			}
		}
	}

	Stream_Free(s, TRUE);
out:

	if (error && context->rdpcontext)
		setChannelError(context->rdpcontext, error,
		                "encomsp_server_thread reported an error");

	ExitThread((DWORD)error);
	return NULL;
}
Beispiel #24
0
BOOL rdp_decrypt(rdpRdp* rdp, wStream* s, int length, UINT16 securityFlags)
{
	BYTE cmac[8];
	BYTE wmac[8];

	if (rdp->settings->EncryptionMethods == ENCRYPTION_METHOD_FIPS)
	{
		UINT16 len;
		BYTE version, pad;
		BYTE* sig;

		if (Stream_GetRemainingLength(s) < 12)
			return FALSE;

		Stream_Read_UINT16(s, len); /* 0x10 */
		Stream_Read_UINT8(s, version); /* 0x1 */
		Stream_Read_UINT8(s, pad);

		sig = Stream_Pointer(s);
		Stream_Seek(s, 8);	/* signature */

		length -= 12;

		if (!security_fips_decrypt(Stream_Pointer(s), length, rdp))
		{
			fprintf(stderr, "FATAL: cannot decrypt\n");
			return FALSE; /* TODO */
		}

		if (!security_fips_check_signature(Stream_Pointer(s), length - pad, sig, rdp))
		{
			fprintf(stderr, "FATAL: invalid packet signature\n");
			return FALSE; /* TODO */
		}

		/* is this what needs adjusting? */
		Stream_Capacity(s) -= pad;
		return TRUE;
	}

	if (Stream_GetRemainingLength(s) < 8)
		return FALSE;

	Stream_Read(s, wmac, sizeof(wmac));
	length -= sizeof(wmac);

	if (!security_decrypt(Stream_Pointer(s), length, rdp))
		return FALSE;

	if (securityFlags & SEC_SECURE_CHECKSUM)
		security_salted_mac_signature(rdp, Stream_Pointer(s), length, FALSE, cmac);
	else
		security_mac_signature(rdp, Stream_Pointer(s), length, cmac);

	if (memcmp(wmac, cmac, sizeof(wmac)) != 0)
	{
		fprintf(stderr, "WARNING: invalid packet signature\n");
		/*
		 * Because Standard RDP Security is totally broken,
		 * and cannot protect against MITM, don't treat signature
		 * verification failure as critical. This at least enables
		 * us to work with broken RDP clients and servers that
		 * generate invalid signatures.
		 */
		//return FALSE;
	}

	return TRUE;
}
Beispiel #25
0
static BOOL TestStream_Verify(wStream* s, int mincap, int len, size_t pos)
{
	if (Stream_Buffer(s) == NULL)
	{
		printf("stream buffer is null\n");
		return FALSE;
	}
	if (Stream_Pointer(s) == NULL)
	{
		printf("stream pointer is null\n");
		return FALSE;
	}
	if (Stream_Pointer(s) < Stream_Buffer(s))
	{
		printf("stream pointer (%p) or buffer (%p) is invalid\n",
			(void*) Stream_Pointer(s), (void*) Stream_Buffer(s));
		return FALSE;
	}
	if (Stream_Capacity(s) < mincap) {
		printf("stream capacity is %"PRIuz" but minimum expected value is %d\n",
			Stream_Capacity(s), mincap);
		return FALSE;
	}
	if (Stream_Length(s) != len) {
		printf("stream has unexpected length (%"PRIuz" instead of %d)\n",
			Stream_Length(s), len);
		return FALSE;
	}
	if (Stream_GetPosition(s) != pos)
	{
		printf("stream has unexpected position (%"PRIuz" instead of %d)\n",
			Stream_GetPosition(s), pos);
		return FALSE;
	}
	if (Stream_GetPosition(s) > Stream_Length(s))
	{
		printf("stream position (%"PRIuz") exceeds length (%"PRIuz")\n",
			Stream_GetPosition(s), Stream_Length(s));
		return FALSE;
	}
	if (Stream_GetPosition(s) > Stream_Capacity(s))
	{
		printf("stream position (%"PRIuz") exceeds capacity (%"PRIuz")\n",
			Stream_GetPosition(s), Stream_Capacity(s));
		return FALSE;
	}
	if (Stream_Length(s) > Stream_Capacity(s))
	{
		printf("stream length (%"PRIuz") exceeds capacity (%"PRIuz")\n",
			Stream_Length(s), Stream_Capacity(s));
		return FALSE;
	}
	if (Stream_GetRemainingLength(s) != len - pos)
	{
		printf("stream remaining length (%"PRIuz" instead of %d)\n",
			Stream_GetRemainingLength(s), len - pos);
		return FALSE;
	}

	return TRUE;
}
Beispiel #26
0
static void* echo_server_thread_func(void* arg)
{
	wStream* s;
	void* buffer;
	DWORD nCount;
	HANDLE events[8];
	BOOL ready = FALSE;
	HANDLE ChannelEvent;
	DWORD BytesReturned = 0;
	echo_server* echo = (echo_server*) arg;
	UINT error;
	DWORD status;

	if ((error = echo_server_open_channel(echo)))
	{
		UINT error2 = 0;
		WLog_ERR(TAG, "echo_server_open_channel failed with error %lu!", error);
		IFCALLRET(echo->context.OpenResult, error2, &echo->context,
		          ECHO_SERVER_OPEN_RESULT_NOTSUPPORTED);

		if (error2)
			WLog_ERR(TAG, "echo server's OpenResult callback failed with error %lu",
			         error2);

		goto out;
	}

	buffer = NULL;
	BytesReturned = 0;
	ChannelEvent = NULL;

	if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualEventHandle, &buffer,
	                           &BytesReturned) == TRUE)
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}

	nCount = 0;
	events[nCount++] = echo->stopEvent;
	events[nCount++] = ChannelEvent;

	/* Wait for the client to confirm that the Graphics Pipeline dynamic channel is ready */

	while (1)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, 100);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
		{
			IFCALLRET(echo->context.OpenResult, error, &echo->context,
			          ECHO_SERVER_OPEN_RESULT_CLOSED);

			if (error)
				WLog_ERR(TAG, "OpenResult failed with error %lu!", error);

			break;
		}

		if (WTSVirtualChannelQuery(echo->echo_channel, WTSVirtualChannelReady, &buffer,
		                           &BytesReturned) == FALSE)
		{
			IFCALLRET(echo->context.OpenResult, error, &echo->context,
			          ECHO_SERVER_OPEN_RESULT_ERROR);

			if (error)
				WLog_ERR(TAG, "OpenResult failed with error %lu!", error);

			break;
		}

		ready = *((BOOL*) buffer);
		WTSFreeMemory(buffer);

		if (ready)
		{
			IFCALLRET(echo->context.OpenResult, error, &echo->context,
			          ECHO_SERVER_OPEN_RESULT_OK);

			if (error)
				WLog_ERR(TAG, "OpenResult failed with error %lu!", error);

			break;
		}
	}

	s = Stream_New(NULL, 4096);

	if (!s)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		WTSVirtualChannelClose(echo->echo_channel);
		ExitThread((DWORD)ERROR_NOT_ENOUGH_MEMORY);
		return NULL;
	}

	while (ready)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (status == WAIT_FAILED)
		{
			error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
			break;
		}

		if (status == WAIT_OBJECT_0)
			break;

		Stream_SetPosition(s, 0);
		WTSVirtualChannelRead(echo->echo_channel, 0, NULL, 0, &BytesReturned);

		if (BytesReturned < 1)
			continue;

		if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
		{
			WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
			error = CHANNEL_RC_NO_MEMORY;
			break;
		}

		if (WTSVirtualChannelRead(echo->echo_channel, 0, (PCHAR) Stream_Buffer(s),
		                          (ULONG) Stream_Capacity(s), &BytesReturned) == FALSE)
		{
			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}

		IFCALLRET(echo->context.Response, error, &echo->context,
		          (BYTE*) Stream_Buffer(s), BytesReturned);

		if (error)
		{
			WLog_ERR(TAG, "Response failed with error %lu!", error);
			break;
		}
	}

	Stream_Free(s, TRUE);
	WTSVirtualChannelClose(echo->echo_channel);
	echo->echo_channel = NULL;
out:

	if (error && echo->context.rdpcontext)
		setChannelError(echo->context.rdpcontext, error,
		                "echo_server_thread_func reported an error");

	ExitThread((DWORD)error);
	return NULL;
}
Beispiel #27
0
void Stream_EnsureRemainingCapacity(wStream* s, size_t size)
{
	if (Stream_GetPosition(s) + size > Stream_Capacity(s))
		Stream_EnsureCapacity(s, Stream_Capacity(s) + size);
}
Beispiel #28
0
static void* rdpsnd_server_thread(void* arg)
{
	wStream* s;
	DWORD status;
	DWORD nCount;
	void* buffer;
	BYTE msgType;
	UINT16 BodySize;
	HANDLE events[8];
	HANDLE ChannelEvent;
	DWORD BytesReturned;
	RdpsndServerContext* context;
	BOOL doRun;

	context = (RdpsndServerContext *)arg;

	buffer = NULL;
	BytesReturned = 0;
	ChannelEvent = NULL;

	s = Stream_New(NULL, 4096);
	if (!s)
		return NULL;

	if (WTSVirtualChannelQuery(context->priv->ChannelHandle, WTSVirtualEventHandle, &buffer, &BytesReturned))
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}

	nCount = 0;
	if (ChannelEvent)
		events[nCount++] = ChannelEvent;
	events[nCount++] = context->priv->StopEvent;

	if (!rdpsnd_server_send_formats(context, s))
		goto out;

	doRun = TRUE;
	while (doRun)
	{
		status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE);

		if (WaitForSingleObject(context->priv->StopEvent, 0) == WAIT_OBJECT_0)
			break;

		Stream_SetPosition(s, 0);

		if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s),
									Stream_Capacity(s), &BytesReturned))
		{
			if (!BytesReturned)
				break;

			Stream_EnsureRemainingCapacity(s, BytesReturned);

			if (!WTSVirtualChannelRead(context->priv->ChannelHandle, 0, (PCHAR)Stream_Buffer(s),
										Stream_Capacity(s), &BytesReturned))
				break;
		}

		if (Stream_GetRemainingLength(s) < 4)
			break;

		Stream_Read_UINT8(s, msgType);
		Stream_Seek_UINT8(s); /* bPad */
		Stream_Read_UINT16(s, BodySize);

		if (Stream_GetRemainingLength(s) < BodySize)
			break;

		switch (msgType)
		{
			case SNDC_WAVECONFIRM:
				doRun = rdpsnd_server_recv_waveconfirm(context, s);
				break;

			case SNDC_QUALITYMODE:
				doRun = rdpsnd_server_recv_quality_mode(context, s);
				break;

			case SNDC_FORMATS:
				doRun = rdpsnd_server_recv_formats(context, s);
				if (doRun)
				{
					IFCALL(context->Activated, context);
				}
				break;

			default:
				fprintf(stderr, "%s: UNKOWN MESSAGE TYPE!! (%#0X)\n\n", __FUNCTION__, msgType);
				break;
		}
	}

out:
	Stream_Free(s, TRUE);
	return NULL;
}
Beispiel #29
0
static void* audin_server_thread_func(void* arg)
{
	wStream* s;
	void* buffer;
	DWORD nCount;
	BYTE MessageId;
	HANDLE events[8];
	BOOL ready = FALSE;
	HANDLE ChannelEvent;
	DWORD BytesReturned = 0;
	audin_server* audin = (audin_server*) arg;
	UINT error = CHANNEL_RC_OK;
	DWORD status;

	buffer = NULL;
	BytesReturned = 0;
	ChannelEvent = NULL;

	if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualEventHandle, &buffer, &BytesReturned) == TRUE)
	{
		if (BytesReturned == sizeof(HANDLE))
			CopyMemory(&ChannelEvent, buffer, sizeof(HANDLE));

		WTSFreeMemory(buffer);
	}
	else
	{
		WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
		error = ERROR_INTERNAL_ERROR;
		goto out;
	}

	nCount = 0;
	events[nCount++] = audin->stopEvent;
	events[nCount++] = ChannelEvent;

	/* Wait for the client to confirm that the Audio Input dynamic channel is ready */

	while (1)
	{
		if ((status = WaitForMultipleObjects(nCount, events, FALSE, 100)) == WAIT_OBJECT_0)
			goto out;

		if (status == WAIT_FAILED)
		{
            error = GetLastError();
			WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
			goto out;
		}

		if (WTSVirtualChannelQuery(audin->audin_channel, WTSVirtualChannelReady, &buffer, &BytesReturned) == FALSE)
		{
			WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
			error = ERROR_INTERNAL_ERROR;
			goto out;
		}

		ready = *((BOOL*) buffer);

		WTSFreeMemory(buffer);

		if (ready)
			break;
	}

	s = Stream_New(NULL, 4096);
	if (!s)
	{
		WLog_ERR(TAG, "Stream_New failed!");
		error = CHANNEL_RC_NO_MEMORY;
		goto out;
	}


	if (ready)
	{
		if ((error = audin_server_send_version(audin, s)))
		{
			WLog_ERR(TAG, "audin_server_send_version failed with error %lu!", error);
			goto out_capacity;
		}
	}

	while (ready)
	{
		if ((status = WaitForMultipleObjects(nCount, events, FALSE, INFINITE)) == WAIT_OBJECT_0)
			break;

		if (status == WAIT_FAILED)
		{
            error = GetLastError();
            WLog_ERR(TAG, "WaitForMultipleObjects failed with error %lu", error);
            goto out;
		}

		Stream_SetPosition(s, 0);

		if (!WTSVirtualChannelRead(audin->audin_channel, 0, NULL, 0, &BytesReturned))
		{
			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}
		if (BytesReturned < 1)
			continue;
		if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
			break;
		if (WTSVirtualChannelRead(audin->audin_channel, 0, (PCHAR) Stream_Buffer(s),
			Stream_Capacity(s), &BytesReturned) == FALSE)
		{
			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			error = ERROR_INTERNAL_ERROR;
			break;
		}

		Stream_Read_UINT8(s, MessageId);
		BytesReturned--;

		switch (MessageId)
		{
			case MSG_SNDIN_VERSION:
				if ((error = audin_server_recv_version(audin, s, BytesReturned)))
				{
                    WLog_ERR(TAG, "audin_server_recv_version failed with error %lu!", error);
                    goto out_capacity;
                }
				if ((error = audin_server_send_formats(audin, s)))
				{
					WLog_ERR(TAG, "audin_server_send_formats failed with error %lu!", error);
					goto out_capacity;
				}
				break;

			case MSG_SNDIN_FORMATS:
				if ((error = audin_server_recv_formats(audin, s, BytesReturned)))
				{
					WLog_ERR(TAG, "audin_server_recv_formats failed with error %lu!", error);
					goto out_capacity;
				}
				if ((error = audin_server_send_open(audin, s)))
				{
					WLog_ERR(TAG, "audin_server_send_open failed with error %lu!", error);
					goto out_capacity;
				}
				break;

			case MSG_SNDIN_OPEN_REPLY:
				if ((error = audin_server_recv_open_reply(audin, s, BytesReturned)))
				{
					WLog_ERR(TAG, "audin_server_recv_open_reply failed with error %lu!", error);
					goto out_capacity;
				}
				break;

			case MSG_SNDIN_DATA_INCOMING:
				break;

			case MSG_SNDIN_DATA:
				if ((error = audin_server_recv_data(audin, s, BytesReturned)))
				{
					WLog_ERR(TAG, "audin_server_recv_data failed with error %lu!", error);
					goto out_capacity;
				};
				break;

			case MSG_SNDIN_FORMATCHANGE:
				break;

			default:
				WLog_ERR(TAG, "audin_server_thread_func: unknown MessageId %d", MessageId);
				break;
		}
	}

out_capacity:
	Stream_Free(s, TRUE);
out:
	WTSVirtualChannelClose(audin->audin_channel);
	audin->audin_channel = NULL;
	if (error && audin->context.rdpcontext)
		setChannelError(audin->context.rdpcontext, error, "audin_server_thread_func reported an error");

	ExitThread((DWORD)error);
	return NULL;
}
Beispiel #30
0
/*
 * Handle rpdgfx messages - server side
 *
 * @param Server side context
 *
 * @return 0 on success
 *         ERROR_NO_DATA if no data could be read this time
 *         otherwise a Win32 error code
 */
UINT rdpgfx_server_handle_messages(RdpgfxServerContext* context)
{
	DWORD BytesReturned;
	void* buffer;
	UINT ret = CHANNEL_RC_OK;
	RdpgfxServerPrivate* priv = context->priv;
	wStream* s = priv->input_stream;

	/* Check whether the dynamic channel is ready */
	if (!priv->isReady)
	{
		if (WTSVirtualChannelQuery(priv->rdpgfx_channel,
		                           WTSVirtualChannelReady,
		                           &buffer, &BytesReturned) == FALSE)
		{
			if (GetLastError() == ERROR_NO_DATA)
				return ERROR_NO_DATA;

			WLog_ERR(TAG, "WTSVirtualChannelQuery failed");
			return ERROR_INTERNAL_ERROR;
		}

		priv->isReady = *((BOOL*) buffer);
		WTSFreeMemory(buffer);
	}

	/* Consume channel event only after the gfx dynamic channel is ready */
	if (priv->isReady)
	{
		Stream_SetPosition(s, 0);

		if (!WTSVirtualChannelRead(priv->rdpgfx_channel,
		                           0, NULL, 0, &BytesReturned))
		{
			if (GetLastError() == ERROR_NO_DATA)
				return ERROR_NO_DATA;

			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			return ERROR_INTERNAL_ERROR;
		}

		if (BytesReturned < 1)
			return CHANNEL_RC_OK;

		if (!Stream_EnsureRemainingCapacity(s, BytesReturned))
		{
			WLog_ERR(TAG, "Stream_EnsureRemainingCapacity failed!");
			return CHANNEL_RC_NO_MEMORY;
		}

		if (WTSVirtualChannelRead(priv->rdpgfx_channel, 0,
		                          (PCHAR) Stream_Buffer(s),
		                          Stream_Capacity(s), &BytesReturned) == FALSE)
		{
			WLog_ERR(TAG, "WTSVirtualChannelRead failed!");
			return ERROR_INTERNAL_ERROR;
		}

		Stream_SetLength(s, BytesReturned);
		Stream_SetPosition(s, 0);

		while (((size_t) Stream_GetPosition(s)) < Stream_Length(s))
		{
			if ((ret = rdpgfx_server_receive_pdu(context, s)))
			{
				WLog_ERR(TAG, "rdpgfx_server_receive_pdu "
				         "failed with error %u!", ret);
				return ret;
			}
		}
	}

	return ret;
}