2011-07-12 19:06:39 +04:00
|
|
|
/**
|
|
|
|
* FreeRDP: A Remote Desktop Protocol client.
|
|
|
|
* Clipboard Virtual Channel
|
|
|
|
*
|
|
|
|
* Copyright 2009-2011 Jay Sorg
|
|
|
|
* Copyright 2010-2011 Vic Lee
|
|
|
|
*
|
|
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
|
|
* you may not use this file except in compliance with the License.
|
|
|
|
* You may obtain a copy of the License at
|
|
|
|
*
|
|
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
*
|
|
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
|
|
* See the License for the specific language governing permissions and
|
|
|
|
* limitations under the License.
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <freerdp/constants.h>
|
|
|
|
#include <freerdp/types.h>
|
|
|
|
#include <freerdp/utils/memory.h>
|
|
|
|
#include <freerdp/utils/svc_plugin.h>
|
2011-08-11 07:07:03 +04:00
|
|
|
#include <freerdp/plugins/cliprdr.h>
|
2011-07-12 19:06:39 +04:00
|
|
|
|
|
|
|
#include "cliprdr_constants.h"
|
|
|
|
#include "cliprdr_main.h"
|
|
|
|
#include "cliprdr_format.h"
|
|
|
|
|
2011-07-12 19:13:30 +04:00
|
|
|
#define CFSTR_HTML "H\0T\0M\0L\0 \0F\0o\0r\0m\0a\0t\0\0"
|
|
|
|
#define CFSTR_PNG "P\0N\0G\0\0"
|
|
|
|
#define CFSTR_JPEG "J\0F\0I\0F\0\0"
|
|
|
|
#define CFSTR_GIF "G\0I\0F\0\0"
|
2011-07-12 19:06:39 +04:00
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
void cliprdr_process_format_list_event(cliprdrPlugin* cliprdr, RDP_CB_FORMAT_LIST_EVENT* cb_event)
|
2011-07-12 19:06:39 +04:00
|
|
|
{
|
2011-09-23 07:37:17 +04:00
|
|
|
STREAM* s;
|
2011-07-12 19:06:39 +04:00
|
|
|
int i;
|
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
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
|
2011-07-12 19:06:39 +04:00
|
|
|
{
|
2011-09-23 07:37:17 +04:00
|
|
|
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, 36 * cb_event->num_formats);
|
|
|
|
|
|
|
|
for (i = 0; i < cb_event->num_formats; i++)
|
2011-07-12 19:06:39 +04:00
|
|
|
{
|
2011-09-23 07:37:17 +04:00
|
|
|
stream_write_uint32(s, cb_event->formats[i]);
|
|
|
|
switch (cb_event->formats[i])
|
|
|
|
{
|
|
|
|
case CB_FORMAT_HTML:
|
|
|
|
memcpy(stream_get_tail(s), CFSTR_HTML, sizeof(CFSTR_HTML));
|
|
|
|
break;
|
|
|
|
case CB_FORMAT_PNG:
|
|
|
|
memcpy(stream_get_tail(s), CFSTR_PNG, sizeof(CFSTR_PNG));
|
|
|
|
break;
|
|
|
|
case CB_FORMAT_JPEG:
|
|
|
|
memcpy(stream_get_tail(s), CFSTR_JPEG, sizeof(CFSTR_JPEG));
|
|
|
|
break;
|
|
|
|
case CB_FORMAT_GIF:
|
|
|
|
memcpy(stream_get_tail(s), CFSTR_GIF, sizeof(CFSTR_GIF));
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
stream_seek(s, 32);
|
2011-07-12 19:06:39 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
cliprdr_packet_send(cliprdr, s);
|
2011-07-12 19:06:39 +04:00
|
|
|
}
|
2011-07-12 19:53:54 +04:00
|
|
|
|
|
|
|
static void cliprdr_send_format_list_response(cliprdrPlugin* cliprdr)
|
|
|
|
{
|
2011-09-23 07:37:17 +04:00
|
|
|
STREAM* s;
|
2011-07-12 19:53:54 +04:00
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
s = cliprdr_packet_new(CB_FORMAT_LIST_RESPONSE, CB_RESPONSE_OK, 0);
|
|
|
|
cliprdr_packet_send(cliprdr, s);
|
2011-07-12 19:53:54 +04:00
|
|
|
}
|
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
void cliprdr_process_format_list(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen)
|
2011-07-12 19:53:54 +04:00
|
|
|
{
|
2011-08-18 01:28:26 +04:00
|
|
|
RDP_CB_FORMAT_LIST_EVENT* cb_event;
|
2011-07-12 19:53:54 +04:00
|
|
|
uint32 format;
|
|
|
|
int num_formats;
|
|
|
|
int supported;
|
|
|
|
int i;
|
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
cb_event = (RDP_CB_FORMAT_LIST_EVENT*)freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR,
|
|
|
|
RDP_EVENT_TYPE_CB_FORMAT_LIST, NULL, NULL);
|
2011-09-23 07:37:17 +04:00
|
|
|
|
2011-07-12 19:53:54 +04:00
|
|
|
num_formats = dataLen / 36;
|
|
|
|
cb_event->formats = (uint32*)xmalloc(sizeof(uint32) * num_formats);
|
|
|
|
cb_event->num_formats = 0;
|
2011-09-23 07:37:17 +04:00
|
|
|
if (dataLen > 0)
|
|
|
|
{
|
|
|
|
cb_event->raw_format_data = (uint8*) xmalloc(dataLen);
|
|
|
|
memcpy(cb_event->raw_format_data, stream_get_tail(s), dataLen);
|
|
|
|
cb_event->raw_format_data_size = dataLen;
|
|
|
|
}
|
|
|
|
|
2011-07-12 19:53:54 +04:00
|
|
|
if (num_formats * 36 != dataLen)
|
2011-07-15 19:41:26 +04:00
|
|
|
DEBUG_WARN("dataLen %d not devided by 36!", dataLen);
|
2011-09-23 07:37:17 +04:00
|
|
|
|
2011-07-12 19:53:54 +04:00
|
|
|
for (i = 0; i < num_formats; i++)
|
|
|
|
{
|
2011-09-23 07:37:17 +04:00
|
|
|
stream_read_uint32(s, format);
|
2011-07-12 19:53:54 +04:00
|
|
|
supported = 1;
|
|
|
|
switch (format)
|
|
|
|
{
|
|
|
|
case CB_FORMAT_TEXT:
|
|
|
|
case CB_FORMAT_DIB:
|
|
|
|
case CB_FORMAT_UNICODETEXT:
|
|
|
|
break;
|
|
|
|
|
|
|
|
default:
|
2011-09-23 07:37:17 +04:00
|
|
|
if (memcmp(stream_get_tail(s), CFSTR_HTML, sizeof(CFSTR_HTML)) == 0)
|
2011-07-12 19:53:54 +04:00
|
|
|
{
|
|
|
|
format = CB_FORMAT_HTML;
|
|
|
|
break;
|
|
|
|
}
|
2011-09-23 07:37:17 +04:00
|
|
|
if (memcmp(stream_get_tail(s), CFSTR_PNG, sizeof(CFSTR_PNG)) == 0)
|
2011-07-12 19:53:54 +04:00
|
|
|
{
|
|
|
|
format = CB_FORMAT_PNG;
|
|
|
|
break;
|
|
|
|
}
|
2011-09-23 07:37:17 +04:00
|
|
|
if (memcmp(stream_get_tail(s), CFSTR_JPEG, sizeof(CFSTR_JPEG)) == 0)
|
2011-07-12 19:53:54 +04:00
|
|
|
{
|
|
|
|
format = CB_FORMAT_JPEG;
|
|
|
|
break;
|
|
|
|
}
|
2011-09-23 07:37:17 +04:00
|
|
|
if (memcmp(stream_get_tail(s), CFSTR_GIF, sizeof(CFSTR_GIF)) == 0)
|
2011-07-12 19:53:54 +04:00
|
|
|
{
|
|
|
|
format = CB_FORMAT_GIF;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
supported = 0;
|
|
|
|
break;
|
|
|
|
}
|
2011-09-23 07:37:17 +04:00
|
|
|
stream_seek(s, 32);
|
2011-07-12 19:53:54 +04:00
|
|
|
|
|
|
|
if (supported)
|
|
|
|
cb_event->formats[cb_event->num_formats++] = format;
|
|
|
|
}
|
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
svc_plugin_send_event((rdpSvcPlugin*)cliprdr, (RDP_EVENT*)cb_event);
|
2011-07-12 19:53:54 +04:00
|
|
|
cliprdr_send_format_list_response(cliprdr);
|
|
|
|
}
|
2011-07-12 20:30:25 +04:00
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
void cliprdr_process_format_list_response(cliprdrPlugin* cliprdr, uint16 msgFlags)
|
|
|
|
{
|
|
|
|
RDP_EVENT* event;
|
|
|
|
|
|
|
|
if ((msgFlags & CB_RESPONSE_FAIL) != 0)
|
|
|
|
{
|
|
|
|
event = freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR, RDP_EVENT_TYPE_CB_SYNC, NULL, NULL);
|
|
|
|
svc_plugin_send_event((rdpSvcPlugin*)cliprdr, event);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
void cliprdr_process_format_data_request(cliprdrPlugin* cliprdr, STREAM* s)
|
2011-07-12 20:30:25 +04:00
|
|
|
{
|
2011-08-18 01:28:26 +04:00
|
|
|
RDP_CB_DATA_REQUEST_EVENT* cb_event;
|
2011-07-12 20:30:25 +04:00
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
cb_event = (RDP_CB_DATA_REQUEST_EVENT*)freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR,
|
|
|
|
RDP_EVENT_TYPE_CB_DATA_REQUEST, NULL, NULL);
|
2011-09-23 07:37:17 +04:00
|
|
|
stream_read_uint32(s, cb_event->format);
|
2011-08-18 01:28:26 +04:00
|
|
|
svc_plugin_send_event((rdpSvcPlugin*)cliprdr, (RDP_EVENT*)cb_event);
|
2011-07-12 20:30:25 +04:00
|
|
|
}
|
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
void cliprdr_process_format_data_response_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_RESPONSE_EVENT* cb_event)
|
2011-07-12 20:30:25 +04:00
|
|
|
{
|
2011-09-23 07:37:17 +04:00
|
|
|
STREAM* s;
|
2011-07-12 20:30:25 +04:00
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
if (cb_event->size > 0)
|
|
|
|
{
|
|
|
|
s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_OK, cb_event->size);
|
|
|
|
stream_write(s, cb_event->data, cb_event->size);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE, CB_RESPONSE_FAIL, 0);
|
|
|
|
}
|
|
|
|
cliprdr_packet_send(cliprdr, s);
|
2011-07-12 20:30:25 +04:00
|
|
|
}
|
2011-07-12 20:50:00 +04:00
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
void cliprdr_process_format_data_request_event(cliprdrPlugin* cliprdr, RDP_CB_DATA_REQUEST_EVENT* cb_event)
|
2011-07-12 20:50:00 +04:00
|
|
|
{
|
2011-09-23 07:37:17 +04:00
|
|
|
STREAM* s;
|
2011-07-12 20:50:00 +04:00
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
s = cliprdr_packet_new(CB_FORMAT_DATA_REQUEST, 0, 4);
|
|
|
|
stream_write_uint32(s, cb_event->format);
|
|
|
|
cliprdr_packet_send(cliprdr, s);
|
2011-07-12 20:50:00 +04:00
|
|
|
}
|
|
|
|
|
2011-09-23 07:37:17 +04:00
|
|
|
void cliprdr_process_format_data_response(cliprdrPlugin* cliprdr, STREAM* s, uint32 dataLen)
|
2011-07-12 20:50:00 +04:00
|
|
|
{
|
2011-08-18 01:28:26 +04:00
|
|
|
RDP_CB_DATA_RESPONSE_EVENT* cb_event;
|
2011-07-12 20:50:00 +04:00
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
cb_event = (RDP_CB_DATA_RESPONSE_EVENT*)freerdp_event_new(RDP_EVENT_CLASS_CLIPRDR,
|
|
|
|
RDP_EVENT_TYPE_CB_DATA_RESPONSE, NULL, NULL);
|
2011-09-23 07:37:17 +04:00
|
|
|
|
|
|
|
if (dataLen > 0)
|
|
|
|
{
|
|
|
|
cb_event->size = dataLen;
|
|
|
|
cb_event->data = (uint8*)xmalloc(dataLen);
|
|
|
|
memcpy(cb_event->data, stream_get_tail(s), dataLen);
|
|
|
|
}
|
|
|
|
|
2011-08-18 01:28:26 +04:00
|
|
|
svc_plugin_send_event((rdpSvcPlugin*)cliprdr, (RDP_EVENT*)cb_event);
|
2011-07-12 20:50:00 +04:00
|
|
|
}
|