예제 #1
0
파일: tsmf_ifman.c 프로젝트: artemh/FreeRDP
/**
 * Function description
 *
 * @return 0 on success, otherwise a Win32 error code
 */
UINT tsmf_ifman_notify_preroll(TSMF_IFMAN* ifman)
{
	DEBUG_TSMF("");
	tsmf_ifman_on_playback_paused(ifman);
	ifman->output_pending = TRUE;
	return CHANNEL_RC_OK;
}
예제 #2
0
static int tsmf_on_data_received(IWTSVirtualChannelCallback* pChannelCallback,
	uint32 cbSize,
	uint8* pBuffer)
{
	int length;
	STREAM* input;
	STREAM* output;
	int error = -1;
	TSMF_IFMAN ifman;
	uint32 MessageId;
	uint32 FunctionId;
	uint32 InterfaceId;
	TSMF_CHANNEL_CALLBACK* callback = (TSMF_CHANNEL_CALLBACK*) pChannelCallback;

	/* 2.2.1 Shared Message Header (SHARED_MSG_HEADER) */
	if (cbSize < 12)
	{
		DEBUG_WARN("invalid size. cbSize=%d", cbSize);
		return 1;
	}
	input = stream_new(0);
	stream_attach(input, (uint8*) pBuffer, cbSize);
	output = stream_new(256);
	stream_seek(output, 8);

	stream_read_uint32(input, InterfaceId);
	stream_read_uint32(input, MessageId);
	stream_read_uint32(input, FunctionId);
	DEBUG_DVC("cbSize=%d InterfaceId=0x%X MessageId=0x%X FunctionId=0x%X",
		cbSize, InterfaceId, MessageId, FunctionId);

	memset(&ifman, 0, sizeof(TSMF_IFMAN));
	ifman.channel_callback = pChannelCallback;
	ifman.decoder_name = ((TSMF_PLUGIN*) callback->plugin)->decoder_name;
	ifman.audio_name = ((TSMF_PLUGIN*) callback->plugin)->audio_name;
	ifman.audio_device = ((TSMF_PLUGIN*) callback->plugin)->audio_device;
	memcpy(ifman.presentation_id, callback->presentation_id, 16);
	ifman.stream_id = callback->stream_id;
	ifman.message_id = MessageId;
	ifman.input = input;
	ifman.input_size = cbSize - 12;
	ifman.output = output;
	ifman.output_pending = false;
	ifman.output_interface_id = InterfaceId;

	switch (InterfaceId)
	{
		case TSMF_INTERFACE_CAPABILITIES | STREAM_ID_NONE:

			switch (FunctionId)
			{
				case RIM_EXCHANGE_CAPABILITY_REQUEST:
					error = tsmf_ifman_rim_exchange_capability_request(&ifman);
					break;

				default:
					break;
			}
			break;

		case TSMF_INTERFACE_DEFAULT | STREAM_ID_PROXY:

			switch (FunctionId)
			{
				case SET_CHANNEL_PARAMS:
					memcpy(callback->presentation_id, stream_get_tail(input), 16);
					stream_seek(input, 16);
					stream_read_uint32(input, callback->stream_id);
					DEBUG_DVC("SET_CHANNEL_PARAMS StreamId=%d", callback->stream_id);
					ifman.output_pending = true;
					error = 0;
					break;

				case EXCHANGE_CAPABILITIES_REQ:
					error = tsmf_ifman_exchange_capability_request(&ifman);
					break;

				case CHECK_FORMAT_SUPPORT_REQ:
					error = tsmf_ifman_check_format_support_request(&ifman);
					break;

				case ON_NEW_PRESENTATION:
					error = tsmf_ifman_on_new_presentation(&ifman);
					break;

				case ADD_STREAM:
					error = tsmf_ifman_add_stream(&ifman);
					break;

				case SET_TOPOLOGY_REQ:
					error = tsmf_ifman_set_topology_request(&ifman);
					break;

				case REMOVE_STREAM:
					error = tsmf_ifman_remove_stream(&ifman);
					break;

				case SHUTDOWN_PRESENTATION_REQ:
					error = tsmf_ifman_shutdown_presentation(&ifman);
					break;

				case ON_STREAM_VOLUME:
					error = tsmf_ifman_on_stream_volume(&ifman);
					break;

				case ON_CHANNEL_VOLUME:
					error = tsmf_ifman_on_channel_volume(&ifman);
					break;

				case SET_VIDEO_WINDOW:
					error = tsmf_ifman_set_video_window(&ifman);
					break;

				case UPDATE_GEOMETRY_INFO:
					error = tsmf_ifman_update_geometry_info(&ifman);
					break;

				case SET_ALLOCATOR:
					error = tsmf_ifman_set_allocator(&ifman);
					break;

				case NOTIFY_PREROLL:
					error = tsmf_ifman_notify_preroll(&ifman);
					break;

				case ON_SAMPLE:
					error = tsmf_ifman_on_sample(&ifman);
					break;

				case ON_FLUSH:
					error = tsmf_ifman_on_flush(&ifman);
					break;

				case ON_END_OF_STREAM:
					error = tsmf_ifman_on_end_of_stream(&ifman);
					break;

				case ON_PLAYBACK_STARTED:
					error = tsmf_ifman_on_playback_started(&ifman);
					break;

				case ON_PLAYBACK_PAUSED:
					error = tsmf_ifman_on_playback_paused(&ifman);
					break;

				case ON_PLAYBACK_RESTARTED:
					error = tsmf_ifman_on_playback_restarted(&ifman);
					break;

				case ON_PLAYBACK_STOPPED:
					error = tsmf_ifman_on_playback_stopped(&ifman);
					break;

				case ON_PLAYBACK_RATE_CHANGED:
					error = tsmf_ifman_on_playback_rate_changed(&ifman);
					break;

				default:
					break;
			}
			break;

		default:
			break;
	}

	stream_detach(input);
	stream_free(input);
	input = NULL;
	ifman.input = NULL;

	if (error == -1)
	{
		switch (FunctionId)
		{
			case RIMCALL_RELEASE:
				/* [MS-RDPEXPS] 2.2.2.2 Interface Release (IFACE_RELEASE)
				   This message does not require a reply. */
				error = 0;
				ifman.output_pending = 1;
				break;

			case RIMCALL_QUERYINTERFACE:
				/* [MS-RDPEXPS] 2.2.2.1.2 Query Interface Response (QI_RSP)
				   This message is not supported in this channel. */
				error = 0;
				break;
		}

		if (error == -1)
		{
			DEBUG_WARN("InterfaceId 0x%X FunctionId 0x%X not processed.",
				InterfaceId, FunctionId);
			/* When a request is not implemented we return empty response indicating error */
		}
		error = 0;
	}

	if (error == 0 && !ifman.output_pending)
	{
		/* Response packet does not have FunctionId */
		length = stream_get_length(output);
		stream_set_pos(output, 0);
		stream_write_uint32(output, ifman.output_interface_id);
		stream_write_uint32(output, MessageId);

		DEBUG_DVC("response size %d", length);
		error = callback->channel->Write(callback->channel, length, stream_get_head(output), NULL);
		if (error)
		{
			DEBUG_WARN("response error %d", error);
		}
	}

	stream_free(output);

	return error;
}