mirror of https://github.com/FreeRDP/FreeRDP
channels/cliprdr: implement initialization of server-side cliprdr
This commit is contained in:
parent
bca442a477
commit
af93bee5d2
|
@ -27,6 +27,7 @@
|
|||
#include <string.h>
|
||||
|
||||
#include <winpr/crt.h>
|
||||
#include <winpr/print.h>
|
||||
|
||||
#include <freerdp/types.h>
|
||||
#include <freerdp/constants.h>
|
||||
|
@ -76,6 +77,11 @@ void cliprdr_packet_send(cliprdrPlugin* cliprdr, wStream* s)
|
|||
Stream_Write_UINT32(s, dataLen);
|
||||
Stream_SetPosition(s, pos);
|
||||
|
||||
#ifdef WITH_DEBUG_CLIPRDR
|
||||
printf("Cliprdr Sending (%d bytes)\n", dataLen + 8);
|
||||
winpr_HexDump(Stream_Buffer(s), dataLen + 8);
|
||||
#endif
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) cliprdr, s);
|
||||
}
|
||||
|
||||
|
@ -206,6 +212,10 @@ static void cliprdr_process_receive(rdpSvcPlugin* plugin, wStream* s)
|
|||
DEBUG_CLIPRDR("msgType: %s (%d), msgFlags: %d dataLen: %d",
|
||||
CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);
|
||||
|
||||
#ifdef WITH_DEBUG_CLIPRDR
|
||||
winpr_HexDump(Stream_Buffer(s), dataLen + 8);
|
||||
#endif
|
||||
|
||||
switch (msgType)
|
||||
{
|
||||
case CB_CLIP_CAPS:
|
||||
|
|
|
@ -40,6 +40,28 @@
|
|||
*
|
||||
*/
|
||||
|
||||
/**
|
||||
* Data Transfer Sequences\n
|
||||
* Shared Local\n
|
||||
* Clipboard Owner Clipboard Owner\n
|
||||
* | |\n
|
||||
* |-------------------------------------------------------------------------|\n _
|
||||
* |-------------------------------Format List PDU-------------------------->|\n |
|
||||
* |<--------------------------Format List Response PDU----------------------|\n _| Copy Sequence
|
||||
* |<---------------------Lock Clipboard Data PDU (Optional)-----------------|\n
|
||||
* |-------------------------------------------------------------------------|\n
|
||||
* |-------------------------------------------------------------------------|\n _
|
||||
* |<--------------------------Format Data Request PDU-----------------------|\n | Paste Sequence Palette,
|
||||
* |---------------------------Format Data Response PDU--------------------->|\n _| Metafile, File List Data
|
||||
* |-------------------------------------------------------------------------|\n
|
||||
* |-------------------------------------------------------------------------|\n _
|
||||
* |<------------------------Format Contents Request PDU---------------------|\n | Paste Sequence
|
||||
* |-------------------------Format Contents Response PDU------------------->|\n _| File Stream Data
|
||||
* |<---------------------Lock Clipboard Data PDU (Optional)-----------------|\n
|
||||
* |-------------------------------------------------------------------------|\n
|
||||
*
|
||||
*/
|
||||
|
||||
static int cliprdr_server_send_capabilities(CliprdrServerContext* context)
|
||||
{
|
||||
wStream* s;
|
||||
|
@ -51,14 +73,14 @@ static int cliprdr_server_send_capabilities(CliprdrServerContext* context)
|
|||
|
||||
header.msgType = CB_CLIP_CAPS;
|
||||
header.msgFlags = 0;
|
||||
header.dataLen = 24;
|
||||
header.dataLen = 16;
|
||||
|
||||
generalFlags = 0;
|
||||
|
||||
if (context->priv->UseLongFormatNames)
|
||||
generalFlags |= CB_USE_LONG_FORMAT_NAMES;
|
||||
|
||||
s = Stream_New(NULL, header.dataLen);
|
||||
s = Stream_New(NULL, header.dataLen + CLIPRDR_HEADER_LENGTH);
|
||||
|
||||
Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */
|
||||
Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */
|
||||
|
@ -91,9 +113,9 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context)
|
|||
|
||||
header.msgType = CB_MONITOR_READY;
|
||||
header.msgFlags = 0;
|
||||
header.dataLen = 8;
|
||||
header.dataLen = 0;
|
||||
|
||||
s = Stream_New(NULL, header.dataLen);
|
||||
s = Stream_New(NULL, header.dataLen + CLIPRDR_HEADER_LENGTH);
|
||||
|
||||
Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */
|
||||
Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */
|
||||
|
@ -110,6 +132,28 @@ static int cliprdr_server_send_monitor_ready(CliprdrServerContext* context)
|
|||
|
||||
static int cliprdr_server_send_format_list_response(CliprdrServerContext* context)
|
||||
{
|
||||
wStream* s;
|
||||
BOOL status;
|
||||
CLIPRDR_HEADER header;
|
||||
|
||||
printf("CliprdrServerSendFormatListResponse\n");
|
||||
|
||||
header.msgType = CB_FORMAT_LIST_RESPONSE;
|
||||
header.msgFlags = CB_RESPONSE_OK;
|
||||
header.dataLen = 0;
|
||||
|
||||
s = Stream_New(NULL, header.dataLen + CLIPRDR_HEADER_LENGTH);
|
||||
|
||||
Stream_Write_UINT16(s, header.msgType); /* msgType (2 bytes) */
|
||||
Stream_Write_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */
|
||||
Stream_Write_UINT32(s, header.dataLen); /* dataLen (4 bytes) */
|
||||
|
||||
Stream_SealLength(s);
|
||||
|
||||
status = WTSVirtualChannelWrite(context->priv->ChannelHandle, Stream_Buffer(s), Stream_Length(s), NULL);
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -163,6 +207,21 @@ int cliprdr_wcslen(const WCHAR* str, const WCHAR* end)
|
|||
return (p - str);
|
||||
}
|
||||
|
||||
static void cliprdr_free_format_list(UINT32 count, CLIPRDR_FORMAT_NAME* formatNames)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (formatNames)
|
||||
{
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
free(formatNames[i].name);
|
||||
}
|
||||
|
||||
free(formatNames);
|
||||
}
|
||||
}
|
||||
|
||||
static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
|
||||
{
|
||||
int i;
|
||||
|
@ -171,11 +230,13 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context
|
|||
int position;
|
||||
|
||||
position = Stream_GetPosition(s);
|
||||
end = (WCHAR*) &(Stream_Buffer(s)[Stream_Length(s)]);
|
||||
|
||||
winpr_HexDump(Stream_Buffer(s), Stream_Length(s));
|
||||
Stream_SetPosition(s, Stream_Length(s));
|
||||
end = (WCHAR*) Stream_Pointer(s);
|
||||
Stream_SetPosition(s, position);
|
||||
|
||||
cliprdr_free_format_list(context->priv->ClientFormatNameCount, context->priv->ClientFormatNames);
|
||||
context->priv->ClientFormatNameCount = 0;
|
||||
context->priv->ClientFormatNames = NULL;
|
||||
|
||||
while (Stream_GetRemainingLength(s) >= 6)
|
||||
{
|
||||
|
@ -188,7 +249,7 @@ static int cliprdr_server_receive_long_format_list(CliprdrServerContext* context
|
|||
|
||||
Stream_Seek(s, (length + 1) * 2); /* wszFormatName */
|
||||
|
||||
context->priv->ClientFormatNameCount = 0;
|
||||
context->priv->ClientFormatNameCount++;
|
||||
}
|
||||
|
||||
context->priv->ClientFormatNames = (CLIPRDR_FORMAT_NAME*)
|
||||
|
@ -235,31 +296,27 @@ static int cliprdr_server_receive_format_list(CliprdrServerContext* context, wSt
|
|||
status = cliprdr_server_receive_short_format_list(context, s, header);
|
||||
}
|
||||
|
||||
cliprdr_server_send_format_list_response(context);
|
||||
|
||||
return status;
|
||||
}
|
||||
|
||||
static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s)
|
||||
static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s, CLIPRDR_HEADER* header)
|
||||
{
|
||||
CLIPRDR_HEADER header;
|
||||
|
||||
Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */
|
||||
Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */
|
||||
Stream_Read_UINT32(s, header.dataLen); /* dataLen (4 bytes) */
|
||||
|
||||
printf("CliprdrServerReceivePdu: msgType: %d msgFlags: 0x%08X dataLen: %d\n",
|
||||
header.msgType, header.msgFlags, header.dataLen);
|
||||
header->msgType, header->msgFlags, header->dataLen);
|
||||
|
||||
switch (header.msgType)
|
||||
switch (header->msgType)
|
||||
{
|
||||
case CB_CLIP_CAPS:
|
||||
cliprdr_server_receive_capabilities(context, s, &header);
|
||||
cliprdr_server_receive_capabilities(context, s, header);
|
||||
break;
|
||||
|
||||
case CB_TEMP_DIRECTORY:
|
||||
break;
|
||||
|
||||
case CB_FORMAT_LIST:
|
||||
cliprdr_server_receive_format_list(context, s, &header);
|
||||
cliprdr_server_receive_format_list(context, s, header);
|
||||
break;
|
||||
|
||||
case CB_FORMAT_LIST_RESPONSE:
|
||||
|
@ -284,7 +341,7 @@ static int cliprdr_server_receive_pdu(CliprdrServerContext* context, wStream* s)
|
|||
break;
|
||||
|
||||
default:
|
||||
printf("Unexpected clipboard PDU type: %d\n", header.msgType);
|
||||
printf("Unexpected clipboard PDU type: %d\n", header->msgType);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -297,9 +354,11 @@ static void* cliprdr_server_thread(void* arg)
|
|||
DWORD status;
|
||||
DWORD nCount;
|
||||
void* buffer;
|
||||
int position;
|
||||
HANDLE events[8];
|
||||
HANDLE ChannelEvent;
|
||||
UINT32 BytesReturned;
|
||||
CLIPRDR_HEADER header;
|
||||
CliprdrServerContext* context;
|
||||
|
||||
context = (CliprdrServerContext*) arg;
|
||||
|
@ -322,8 +381,8 @@ static void* cliprdr_server_thread(void* arg)
|
|||
events[nCount++] = ChannelEvent;
|
||||
events[nCount++] = context->priv->StopEvent;
|
||||
|
||||
context->SendCapabilities(context);
|
||||
context->SendMonitorReady(context);
|
||||
cliprdr_server_send_capabilities(context);
|
||||
cliprdr_server_send_monitor_ready(context);
|
||||
|
||||
while (1)
|
||||
{
|
||||
|
@ -335,26 +394,36 @@ static void* cliprdr_server_thread(void* arg)
|
|||
}
|
||||
|
||||
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
|
||||
Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE)
|
||||
Stream_Buffer(s), Stream_Capacity(s), &BytesReturned))
|
||||
{
|
||||
if (BytesReturned)
|
||||
Stream_Seek(s, BytesReturned);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!BytesReturned)
|
||||
break;
|
||||
|
||||
Stream_EnsureRemainingCapacity(s, BytesReturned);
|
||||
|
||||
if (WTSVirtualChannelRead(context->priv->ChannelHandle, 0,
|
||||
Stream_Buffer(s), Stream_Capacity(s), &BytesReturned) == FALSE)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
Stream_Seek(s, BytesReturned);
|
||||
}
|
||||
|
||||
Stream_SealLength(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
if (Stream_GetPosition(s) >= CLIPRDR_HEADER_LENGTH)
|
||||
{
|
||||
position = Stream_GetPosition(s);
|
||||
Stream_SetPosition(s, 0);
|
||||
|
||||
cliprdr_server_receive_pdu(context, s);
|
||||
Stream_Read_UINT16(s, header.msgType); /* msgType (2 bytes) */
|
||||
Stream_Read_UINT16(s, header.msgFlags); /* msgFlags (2 bytes) */
|
||||
Stream_Read_UINT32(s, header.dataLen); /* dataLen (4 bytes) */
|
||||
|
||||
Stream_SetPosition(s, position);
|
||||
|
||||
if (Stream_GetPosition(s) >= (header.dataLen + CLIPRDR_HEADER_LENGTH))
|
||||
{
|
||||
Stream_SealLength(s);
|
||||
Stream_SetPosition(s, CLIPRDR_HEADER_LENGTH);
|
||||
|
||||
cliprdr_server_receive_pdu(context, s, &header);
|
||||
Stream_SetPosition(s, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Stream_Free(s, TRUE);
|
||||
|
@ -402,10 +471,6 @@ CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm)
|
|||
context->Start = cliprdr_server_start;
|
||||
context->Stop = cliprdr_server_stop;
|
||||
|
||||
context->SendCapabilities = cliprdr_server_send_capabilities;
|
||||
context->SendMonitorReady = cliprdr_server_send_monitor_ready;
|
||||
context->SendFormatListResponse = cliprdr_server_send_format_list_response;
|
||||
|
||||
context->priv = (CliprdrServerPrivate*) malloc(sizeof(CliprdrServerPrivate));
|
||||
|
||||
if (context->priv)
|
||||
|
@ -413,6 +478,9 @@ CliprdrServerContext* cliprdr_server_context_new(WTSVirtualChannelManager* vcm)
|
|||
ZeroMemory(context->priv, sizeof(CliprdrServerPrivate));
|
||||
|
||||
context->priv->UseLongFormatNames = TRUE;
|
||||
context->priv->StreamFileClipEnabled = TRUE;
|
||||
context->priv->FileClipNoFilePaths = TRUE;
|
||||
context->priv->CanLockClipData = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -26,6 +26,8 @@
|
|||
|
||||
#include <freerdp/server/cliprdr.h>
|
||||
|
||||
#define CLIPRDR_HEADER_LENGTH 8
|
||||
|
||||
struct _CLIPRDR_HEADER
|
||||
{
|
||||
UINT16 msgType;
|
||||
|
@ -39,10 +41,12 @@ struct _cliprdr_server_private
|
|||
HANDLE Thread;
|
||||
HANDLE StopEvent;
|
||||
void* ChannelHandle;
|
||||
|
||||
BOOL UseLongFormatNames;
|
||||
BOOL StreamFileClipEnabled;
|
||||
BOOL FileClipNoFilePaths;
|
||||
BOOL CanLockClipData;
|
||||
|
||||
UINT32 ClientFormatNameCount;
|
||||
CLIPRDR_FORMAT_NAME* ClientFormatNames;
|
||||
};
|
||||
|
|
|
@ -749,7 +749,7 @@ BOOL WTSVirtualChannelRead(
|
|||
|
||||
item = (wts_data_item*) list_peek(channel->receive_queue);
|
||||
|
||||
if (item == NULL)
|
||||
if (!item)
|
||||
{
|
||||
ResetEvent(channel->receive_event);
|
||||
*pBytesRead = 0;
|
||||
|
@ -771,7 +771,7 @@ BOOL WTSVirtualChannelRead(
|
|||
ReleaseMutex(channel->mutex);
|
||||
|
||||
CopyMemory(Buffer, item->buffer, item->length);
|
||||
wts_data_item_free(item) ;
|
||||
wts_data_item_free(item);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
|
|
@ -35,10 +35,6 @@ typedef struct _cliprdr_server_private CliprdrServerPrivate;
|
|||
typedef int (*psCliprdrStart)(CliprdrServerContext* context);
|
||||
typedef int (*psCliprdrStop)(CliprdrServerContext* context);
|
||||
|
||||
typedef int (*psCliprdrSendCapabilities)(CliprdrServerContext* context);
|
||||
typedef int (*psCliprdrSendMonitorReady)(CliprdrServerContext* context);
|
||||
typedef int (*psCliprdrSendFormatListResponse)(CliprdrServerContext* context);
|
||||
|
||||
struct _cliprdr_server_context
|
||||
{
|
||||
WTSVirtualChannelManager* vcm;
|
||||
|
@ -46,10 +42,6 @@ struct _cliprdr_server_context
|
|||
psCliprdrStart Start;
|
||||
psCliprdrStop Stop;
|
||||
|
||||
psCliprdrSendCapabilities SendCapabilities;
|
||||
psCliprdrSendMonitorReady SendMonitorReady;
|
||||
psCliprdrSendFormatListResponse SendFormatListResponse;
|
||||
|
||||
CliprdrServerPrivate* priv;
|
||||
};
|
||||
|
||||
|
|
Loading…
Reference in New Issue