channels: cliprdr: improved common cliprdr api
This commit is contained in:
parent
d2f73136d3
commit
d75c5eec04
@ -64,25 +64,6 @@ CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr)
|
||||
return pInterface;
|
||||
}
|
||||
|
||||
static wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags,
|
||||
UINT32 dataLen)
|
||||
{
|
||||
wStream* s;
|
||||
s = Stream_New(NULL, dataLen + 8);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, msgType);
|
||||
Stream_Write_UINT16(s, msgFlags);
|
||||
/* Write actual length after the entire packet has been constructed. */
|
||||
Stream_Seek(s, 4);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@ -622,122 +603,15 @@ static UINT cliprdr_client_format_list(CliprdrClientContext* context,
|
||||
const CLIPRDR_FORMAT_LIST* formatList)
|
||||
{
|
||||
wStream* s;
|
||||
UINT32 index;
|
||||
UINT32 length = 0;
|
||||
int cchWideChar;
|
||||
LPWSTR lpWideCharStr;
|
||||
size_t formatNameSize;
|
||||
size_t formatNameLength;
|
||||
char* szFormatName;
|
||||
WCHAR* wszFormatName;
|
||||
BOOL asciiNames = FALSE;
|
||||
CLIPRDR_FORMAT* format;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
|
||||
if (!cliprdr->useLongFormatNames)
|
||||
{
|
||||
length = formatList->numFormats * 36;
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length);
|
||||
|
||||
s = cliprdr_packet_format_list_new(formatList, cliprdr->useLongFormatNames);
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_format_list_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
for (index = 0; index < formatList->numFormats; index++)
|
||||
{
|
||||
format = (CLIPRDR_FORMAT*) & (formatList->formats[index]);
|
||||
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
|
||||
formatNameSize = 0;
|
||||
formatNameLength = 0;
|
||||
szFormatName = format->formatName;
|
||||
|
||||
if (asciiNames)
|
||||
{
|
||||
if (szFormatName)
|
||||
formatNameLength = strlen(szFormatName);
|
||||
|
||||
if (formatNameLength > 31)
|
||||
formatNameLength = 31;
|
||||
|
||||
Stream_Write(s, szFormatName, formatNameLength);
|
||||
Stream_Zero(s, 32 - formatNameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
wszFormatName = NULL;
|
||||
|
||||
if (szFormatName)
|
||||
{
|
||||
int rc = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName, 0);
|
||||
|
||||
if (rc < 0)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
formatNameSize = (size_t)rc;
|
||||
}
|
||||
|
||||
if (formatNameSize > 15)
|
||||
formatNameSize = 15;
|
||||
|
||||
if (wszFormatName)
|
||||
Stream_Write(s, wszFormatName, formatNameSize * 2);
|
||||
|
||||
Stream_Zero(s, 32 - (formatNameSize * 2));
|
||||
free(wszFormatName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for (index = 0; index < formatList->numFormats; index++)
|
||||
{
|
||||
format = (CLIPRDR_FORMAT*) & (formatList->formats[index]);
|
||||
length += 4;
|
||||
formatNameSize = 2;
|
||||
|
||||
if (format->formatName)
|
||||
{
|
||||
int rc = MultiByteToWideChar(CP_UTF8, 0, format->formatName, -1, NULL, 0);
|
||||
|
||||
if (rc < 0)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
formatNameSize = (size_t)rc * 2;
|
||||
}
|
||||
|
||||
length += formatNameSize;
|
||||
}
|
||||
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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: %"PRIu32"",
|
||||
formatList->numFormats);
|
||||
return cliprdr_packet_send(cliprdr, s);
|
||||
@ -774,10 +648,9 @@ static UINT cliprdr_client_format_list_response(CliprdrClientContext* context,
|
||||
static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context,
|
||||
const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4);
|
||||
s = cliprdr_packet_lock_clipdata_new(lockClipboardData);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
@ -785,17 +658,10 @@ static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context,
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_lock_clipdata(s, lockClipboardData)))
|
||||
goto fail;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG,
|
||||
"ClientLockClipboardData: clipDataId: 0x%08"PRIX32"",
|
||||
lockClipboardData->clipDataId);
|
||||
return cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -806,10 +672,9 @@ fail:
|
||||
static UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context,
|
||||
const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4);
|
||||
s = cliprdr_packet_unlock_clipdata_new(unlockClipboardData);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
@ -817,18 +682,10 @@ static UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context,
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_unlock_clipdata(s, unlockClipboardData)))
|
||||
goto fail;
|
||||
|
||||
Stream_Write_UINT32(s, unlockClipboardData->clipDataId); /* clipDataId (4 bytes) */
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG,
|
||||
"ClientUnlockClipboardData: clipDataId: 0x%08"PRIX32"",
|
||||
unlockClipboardData->clipDataId);
|
||||
return cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -889,29 +746,21 @@ static UINT cliprdr_client_format_data_response(CliprdrClientContext* context,
|
||||
static UINT cliprdr_client_file_contents_request(CliprdrClientContext* context,
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
|
||||
s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 28);
|
||||
s = cliprdr_packet_file_contents_request_new(fileContentsRequest);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_file_contents_request_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_file_contents_request(s, fileContentsRequest)))
|
||||
goto fail;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG,
|
||||
"ClientFileContentsRequest: streamId: 0x%08"PRIX32"",
|
||||
fileContentsRequest->streamId);
|
||||
return cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -922,11 +771,9 @@ fail:
|
||||
static UINT cliprdr_client_file_contents_response(CliprdrClientContext* context,
|
||||
const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
|
||||
s = cliprdr_packet_new(CB_FILECONTENTS_RESPONSE, fileContentsResponse->msgFlags,
|
||||
4 + fileContentsResponse->cbRequested);
|
||||
s = cliprdr_packet_file_contents_response_new(fileContentsResponse);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
@ -934,17 +781,10 @@ static UINT cliprdr_client_file_contents_response(CliprdrClientContext* context,
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_file_contents_response(s, fileContentsResponse)))
|
||||
goto fail;
|
||||
|
||||
WLog_Print(cliprdr->log, WLOG_DEBUG,
|
||||
"ClientFileContentsResponse: streamId: 0x%08"PRIX32"",
|
||||
fileContentsResponse->streamId);
|
||||
return cliprdr_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -58,7 +58,26 @@ static BOOL cliprdr_validate_file_contents_request(const CLIPRDR_FILE_CONTENTS_R
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
UINT cliprdr_write_file_contents_request(wStream* s, const CLIPRDR_FILE_CONTENTS_REQUEST* request)
|
||||
wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags,
|
||||
UINT32 dataLen)
|
||||
{
|
||||
wStream* s;
|
||||
s = Stream_New(NULL, dataLen + 8);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, msgType);
|
||||
Stream_Write_UINT16(s, msgFlags);
|
||||
/* Write actual length after the entire packet has been constructed. */
|
||||
Stream_Seek(s, 4);
|
||||
return s;
|
||||
}
|
||||
|
||||
static void cliprdr_write_file_contents_request(wStream* s, const CLIPRDR_FILE_CONTENTS_REQUEST* request)
|
||||
{
|
||||
Stream_Write_UINT32(s, request->streamId); /* streamId (4 bytes) */
|
||||
Stream_Write_UINT32(s, request->listIndex); /* listIndex (4 bytes) */
|
||||
@ -69,35 +88,224 @@ UINT cliprdr_write_file_contents_request(wStream* s, const CLIPRDR_FILE_CONTENTS
|
||||
|
||||
if (request->haveClipDataId)
|
||||
Stream_Write_UINT32(s, request->clipDataId); /* clipDataId (4 bytes) */
|
||||
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
static INLINE UINT cliprdr_write_lock_unlock_clipdata(wStream* s, UINT32 clipDataId)
|
||||
static INLINE void cliprdr_write_lock_unlock_clipdata(wStream* s, UINT32 clipDataId)
|
||||
{
|
||||
Stream_Write_UINT32(s, clipDataId);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
UINT cliprdr_write_lock_clipdata(wStream* s, const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
|
||||
static void cliprdr_write_lock_clipdata(wStream* s, const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
|
||||
{
|
||||
return cliprdr_write_lock_unlock_clipdata(s, lockClipboardData->clipDataId);
|
||||
cliprdr_write_lock_unlock_clipdata(s, lockClipboardData->clipDataId);
|
||||
}
|
||||
|
||||
UINT cliprdr_write_unlock_clipdata(wStream* s,
|
||||
static void cliprdr_write_unlock_clipdata(wStream* s,
|
||||
const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
|
||||
{
|
||||
return cliprdr_write_lock_unlock_clipdata(s, unlockClipboardData->clipDataId);
|
||||
cliprdr_write_lock_unlock_clipdata(s, unlockClipboardData->clipDataId);
|
||||
}
|
||||
|
||||
UINT cliprdr_write_file_contents_response(wStream* s,
|
||||
static void cliprdr_write_file_contents_response(wStream* s,
|
||||
const CLIPRDR_FILE_CONTENTS_RESPONSE* response)
|
||||
{
|
||||
Stream_Write_UINT32(s, response->streamId); /* streamId (4 bytes) */
|
||||
Stream_Write(s, response->requestedData, response->cbRequested);
|
||||
return CHANNEL_RC_OK;
|
||||
}
|
||||
|
||||
wStream* cliprdr_packet_lock_clipdata_new(const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
if (!lockClipboardData)
|
||||
return NULL;
|
||||
|
||||
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
cliprdr_write_lock_clipdata(s, lockClipboardData);
|
||||
return s;
|
||||
}
|
||||
|
||||
wStream* cliprdr_packet_unlock_clipdata_new(const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
if (!unlockClipboardData)
|
||||
return NULL;
|
||||
|
||||
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
cliprdr_write_unlock_clipdata(s, unlockClipboardData);
|
||||
return s;
|
||||
}
|
||||
|
||||
wStream* cliprdr_packet_file_contents_request_new(const CLIPRDR_FILE_CONTENTS_REQUEST* request)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
if (!request)
|
||||
return NULL;
|
||||
|
||||
s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 28);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
cliprdr_write_file_contents_request(s, request);
|
||||
return s;
|
||||
}
|
||||
|
||||
wStream* cliprdr_packet_file_contents_response_new(const CLIPRDR_FILE_CONTENTS_RESPONSE* response)
|
||||
{
|
||||
wStream* s;
|
||||
|
||||
if (!response)
|
||||
return NULL;
|
||||
|
||||
s = cliprdr_packet_new(CB_FILECONTENTS_RESPONSE, response->msgFlags,
|
||||
4 + response->cbRequested);
|
||||
|
||||
if (!s)
|
||||
return NULL;
|
||||
|
||||
cliprdr_write_file_contents_response(s, response);
|
||||
return s;
|
||||
}
|
||||
|
||||
wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, BOOL useLongFormatNames)
|
||||
{
|
||||
wStream* s;
|
||||
UINT32 index;
|
||||
int cchWideChar;
|
||||
LPWSTR lpWideCharStr;
|
||||
int formatNameSize;
|
||||
char* szFormatName;
|
||||
WCHAR* wszFormatName;
|
||||
BOOL asciiNames = FALSE;
|
||||
CLIPRDR_FORMAT* format;
|
||||
|
||||
if (formatList->msgType != CB_FORMAT_LIST)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatList->msgType);
|
||||
|
||||
if (!useLongFormatNames)
|
||||
{
|
||||
UINT32 length = formatList->numFormats * 36;
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (index = 0; index < formatList->numFormats; index++)
|
||||
{
|
||||
size_t formatNameLength = 0;
|
||||
format = (CLIPRDR_FORMAT*) & (formatList->formats[index]);
|
||||
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
|
||||
formatNameSize = 0;
|
||||
|
||||
szFormatName = format->formatName;
|
||||
|
||||
if (asciiNames)
|
||||
{
|
||||
if (szFormatName)
|
||||
formatNameLength = strlen(szFormatName);
|
||||
|
||||
if (formatNameLength > 31)
|
||||
formatNameLength = 31;
|
||||
|
||||
Stream_Write(s, szFormatName, formatNameLength);
|
||||
Stream_Zero(s, 32 - formatNameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
wszFormatName = NULL;
|
||||
|
||||
if (szFormatName)
|
||||
formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName,
|
||||
0);
|
||||
|
||||
if (formatNameSize < 0)
|
||||
return NULL;
|
||||
|
||||
if (formatNameSize > 15)
|
||||
formatNameSize = 15;
|
||||
|
||||
/* size in bytes instead of wchar */
|
||||
formatNameSize *= 2;
|
||||
|
||||
if (wszFormatName)
|
||||
Stream_Write(s, wszFormatName, (size_t)formatNameSize);
|
||||
|
||||
Stream_Zero(s, (size_t)(32 - formatNameSize));
|
||||
free(wszFormatName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 length = 0;
|
||||
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;
|
||||
|
||||
if (formatNameSize < 0)
|
||||
return NULL;
|
||||
|
||||
length += (UINT32)formatNameSize;
|
||||
}
|
||||
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const size_t cap = Stream_Capacity(s);
|
||||
const size_t pos = Stream_GetPosition(s);
|
||||
const size_t rem = cap - pos;
|
||||
if ((cap < pos) || ((rem / 2) > INT_MAX))
|
||||
return NULL;
|
||||
|
||||
lpWideCharStr = (LPWSTR) Stream_Pointer(s);
|
||||
cchWideChar = (int)(rem / 2);
|
||||
formatNameSize = MultiByteToWideChar(CP_UTF8, 0,
|
||||
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
|
||||
if (formatNameSize < 0)
|
||||
return NULL;
|
||||
Stream_Seek(s, (size_t)formatNameSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream_Write_UINT16(s, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return s;
|
||||
}
|
||||
UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
|
||||
{
|
||||
if (Stream_GetRemainingLength(s) < 4)
|
||||
|
@ -29,10 +29,12 @@
|
||||
#include <freerdp/channels/cliprdr.h>
|
||||
#include <freerdp/api.h>
|
||||
|
||||
FREERDP_LOCAL UINT cliprdr_write_lock_clipdata(wStream* s, const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);
|
||||
FREERDP_LOCAL UINT cliprdr_write_unlock_clipdata(wStream* s, const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData);
|
||||
FREERDP_LOCAL UINT cliprdr_write_file_contents_request(wStream* s, const CLIPRDR_FILE_CONTENTS_REQUEST* request);
|
||||
FREERDP_LOCAL UINT cliprdr_write_file_contents_response(wStream* s, const CLIPRDR_FILE_CONTENTS_RESPONSE* response);
|
||||
FREERDP_LOCAL wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen);
|
||||
FREERDP_LOCAL wStream* cliprdr_packet_lock_clipdata_new(const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);
|
||||
FREERDP_LOCAL wStream* cliprdr_packet_unlock_clipdata_new(const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData);
|
||||
FREERDP_LOCAL wStream* cliprdr_packet_file_contents_request_new(const CLIPRDR_FILE_CONTENTS_REQUEST* request);
|
||||
FREERDP_LOCAL wStream* cliprdr_packet_file_contents_response_new(const CLIPRDR_FILE_CONTENTS_RESPONSE* response);
|
||||
FREERDP_LOCAL wStream* cliprdr_packet_format_list_new(const CLIPRDR_FORMAT_LIST* formatList, BOOL useLongFormatNames);
|
||||
|
||||
FREERDP_LOCAL UINT cliprdr_read_lock_clipdata(wStream* s, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);
|
||||
FREERDP_LOCAL UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData);
|
||||
|
@ -66,25 +66,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
wStream* cliprdr_server_packet_new(UINT16 msgType, UINT16 msgFlags,
|
||||
UINT32 dataLen)
|
||||
{
|
||||
wStream* s;
|
||||
s = Stream_New(NULL, dataLen + 8);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "Stream_New failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Stream_Write_UINT16(s, msgType);
|
||||
Stream_Write_UINT16(s, msgFlags);
|
||||
/* Write actual length after the entire packet has been constructed. */
|
||||
Stream_Seek(s, 4);
|
||||
return s;
|
||||
}
|
||||
|
||||
/**
|
||||
* Function description
|
||||
*
|
||||
@ -145,11 +126,11 @@ static UINT cliprdr_server_capabilities(CliprdrServerContext* context,
|
||||
return ERROR_INVALID_PARAMETER;
|
||||
}
|
||||
|
||||
s = cliprdr_server_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);
|
||||
s = cliprdr_packet_new(CB_CLIP_CAPS, 0, 4 + CB_CAPSTYPE_GENERAL_LEN);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -200,12 +181,12 @@ static UINT cliprdr_server_monitor_ready(CliprdrServerContext* context, const CL
|
||||
if (monitorReady->msgType != CB_MONITOR_READY)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, monitorReady->msgType);
|
||||
|
||||
s = cliprdr_server_packet_new(CB_MONITOR_READY,
|
||||
s = cliprdr_packet_new(CB_MONITOR_READY,
|
||||
monitorReady->msgFlags, monitorReady->dataLen);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -222,130 +203,15 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context,
|
||||
const CLIPRDR_FORMAT_LIST* formatList)
|
||||
{
|
||||
wStream* s;
|
||||
UINT32 index;
|
||||
int cchWideChar;
|
||||
LPWSTR lpWideCharStr;
|
||||
int formatNameSize;
|
||||
char* szFormatName;
|
||||
WCHAR* wszFormatName;
|
||||
BOOL asciiNames = FALSE;
|
||||
CLIPRDR_FORMAT* format;
|
||||
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
|
||||
|
||||
if (formatList->msgType != CB_FORMAT_LIST)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatList->msgType);
|
||||
|
||||
if (!context->useLongFormatNames)
|
||||
{
|
||||
UINT32 length = formatList->numFormats * 36;
|
||||
s = cliprdr_server_packet_new(CB_FORMAT_LIST, 0, length);
|
||||
|
||||
s = cliprdr_packet_format_list_new(formatList, context->useLongFormatNames);
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_format_list_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
for (index = 0; index < formatList->numFormats; index++)
|
||||
{
|
||||
size_t formatNameLength = 0;
|
||||
format = (CLIPRDR_FORMAT*) & (formatList->formats[index]);
|
||||
Stream_Write_UINT32(s, format->formatId); /* formatId (4 bytes) */
|
||||
formatNameSize = 0;
|
||||
|
||||
szFormatName = format->formatName;
|
||||
|
||||
if (asciiNames)
|
||||
{
|
||||
if (szFormatName)
|
||||
formatNameLength = strlen(szFormatName);
|
||||
|
||||
if (formatNameLength > 31)
|
||||
formatNameLength = 31;
|
||||
|
||||
Stream_Write(s, szFormatName, formatNameLength);
|
||||
Stream_Zero(s, 32 - formatNameLength);
|
||||
}
|
||||
else
|
||||
{
|
||||
wszFormatName = NULL;
|
||||
|
||||
if (szFormatName)
|
||||
formatNameSize = ConvertToUnicode(CP_UTF8, 0, szFormatName, -1, &wszFormatName,
|
||||
0);
|
||||
|
||||
if (formatNameSize < 0)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
if (formatNameSize > 15)
|
||||
formatNameSize = 15;
|
||||
|
||||
/* size in bytes instead of wchar */
|
||||
formatNameSize *= 2;
|
||||
|
||||
if (wszFormatName)
|
||||
Stream_Write(s, wszFormatName, (size_t)formatNameSize);
|
||||
|
||||
Stream_Zero(s, (size_t)(32 - formatNameSize));
|
||||
free(wszFormatName);
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
UINT32 length = 0;
|
||||
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;
|
||||
|
||||
if (formatNameSize < 0)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
length += (UINT32)formatNameSize;
|
||||
}
|
||||
|
||||
s = cliprdr_server_packet_new(CB_FORMAT_LIST, 0, length);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
const size_t cap = Stream_Capacity(s);
|
||||
const size_t pos = Stream_GetPosition(s);
|
||||
const size_t rem = cap - pos;
|
||||
if ((cap < pos) || ((rem / 2) > INT_MAX))
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
|
||||
lpWideCharStr = (LPWSTR) Stream_Pointer(s);
|
||||
cchWideChar = (int)(rem / 2);
|
||||
formatNameSize = MultiByteToWideChar(CP_UTF8, 0,
|
||||
format->formatName, -1, lpWideCharStr, cchWideChar) * 2;
|
||||
if (formatNameSize < 0)
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
Stream_Seek(s, (size_t)formatNameSize);
|
||||
}
|
||||
else
|
||||
{
|
||||
Stream_Write_UINT16(s, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
WLog_DBG(TAG, "ServerFormatList: numFormats: %"PRIu32"",
|
||||
formatList->numFormats);
|
||||
return cliprdr_server_packet_send(cliprdr, s);
|
||||
@ -364,12 +230,12 @@ static UINT cliprdr_server_format_list_response(CliprdrServerContext* context,
|
||||
if (formatListResponse->msgType != CB_FORMAT_LIST_RESPONSE)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatListResponse->msgType);
|
||||
|
||||
s = cliprdr_server_packet_new(CB_FORMAT_LIST_RESPONSE,
|
||||
s = cliprdr_packet_new(CB_FORMAT_LIST_RESPONSE,
|
||||
formatListResponse->msgFlags, formatListResponse->dataLen);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -385,29 +251,21 @@ static UINT cliprdr_server_format_list_response(CliprdrServerContext* context,
|
||||
static UINT cliprdr_server_lock_clipboard_data(CliprdrServerContext* context,
|
||||
const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
|
||||
if (lockClipboardData->msgType != CB_LOCK_CLIPDATA)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, lockClipboardData->msgType);
|
||||
s = cliprdr_server_packet_new(CB_LOCK_CLIPDATA, 0, 4);
|
||||
|
||||
s = cliprdr_packet_lock_clipdata_new(lockClipboardData);
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_lock_clipdata_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_lock_clipdata(s, lockClipboardData)))
|
||||
goto fail;
|
||||
|
||||
WLog_DBG(TAG, "ServerLockClipboardData: clipDataId: 0x%08"PRIX32"",
|
||||
lockClipboardData->clipDataId);
|
||||
return cliprdr_server_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -418,30 +276,22 @@ fail:
|
||||
static UINT cliprdr_server_unlock_clipboard_data(CliprdrServerContext* context,
|
||||
const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
|
||||
if (unlockClipboardData->msgType != CB_UNLOCK_CLIPDATA)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, unlockClipboardData->msgType);
|
||||
|
||||
s = cliprdr_server_packet_new(CB_UNLOCK_CLIPDATA, 0, 4);
|
||||
s = cliprdr_packet_unlock_clipdata_new(unlockClipboardData);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_unlock_clipdata_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_unlock_clipdata(s, unlockClipboardData)))
|
||||
goto fail;
|
||||
|
||||
WLog_DBG(TAG, "ServerUnlockClipboardData: clipDataId: 0x%08"PRIX32"",
|
||||
unlockClipboardData->clipDataId);
|
||||
return cliprdr_server_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -457,12 +307,12 @@ static UINT cliprdr_server_format_data_request(CliprdrServerContext* context,
|
||||
if (formatDataRequest->msgType != CB_FORMAT_DATA_REQUEST)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatDataRequest->msgType);
|
||||
|
||||
s = cliprdr_server_packet_new(CB_FORMAT_DATA_REQUEST,
|
||||
s = cliprdr_packet_new(CB_FORMAT_DATA_REQUEST,
|
||||
formatDataRequest->msgFlags, formatDataRequest->dataLen);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -486,12 +336,12 @@ static UINT cliprdr_server_format_data_response(CliprdrServerContext* context,
|
||||
if (formatDataResponse->msgType != CB_FORMAT_DATA_RESPONSE)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatDataResponse->msgType);
|
||||
|
||||
s = cliprdr_server_packet_new(CB_FORMAT_DATA_RESPONSE,
|
||||
s = cliprdr_packet_new(CB_FORMAT_DATA_RESPONSE,
|
||||
formatDataResponse->msgFlags, formatDataResponse->dataLen);
|
||||
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
@ -509,31 +359,22 @@ static UINT cliprdr_server_format_data_response(CliprdrServerContext* context,
|
||||
static UINT cliprdr_server_file_contents_request(CliprdrServerContext* context,
|
||||
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
|
||||
|
||||
if (fileContentsRequest->msgType != CB_FILECONTENTS_REQUEST)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, fileContentsRequest->msgType);
|
||||
|
||||
s = cliprdr_server_packet_new(CB_FILECONTENTS_REQUEST, 0, 28);
|
||||
|
||||
s = cliprdr_packet_file_contents_request_new(fileContentsRequest);
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_file_contents_request_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_file_contents_request(s, fileContentsRequest)))
|
||||
goto fail;
|
||||
|
||||
WLog_DBG(TAG, "ServerFileContentsRequest: streamId: 0x%08"PRIX32"",
|
||||
fileContentsRequest->streamId);
|
||||
return cliprdr_server_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
@ -544,32 +385,22 @@ fail:
|
||||
static UINT cliprdr_server_file_contents_response(CliprdrServerContext* context,
|
||||
const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
|
||||
{
|
||||
UINT error = CHANNEL_RC_OK;
|
||||
wStream* s;
|
||||
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
|
||||
|
||||
if (fileContentsResponse->msgType != CB_FILECONTENTS_RESPONSE)
|
||||
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, fileContentsResponse->msgType);
|
||||
|
||||
s = cliprdr_server_packet_new(CB_FILECONTENTS_RESPONSE, fileContentsResponse->msgFlags,
|
||||
4 + fileContentsResponse->cbRequested);
|
||||
|
||||
s = cliprdr_packet_file_contents_response_new(fileContentsResponse);
|
||||
if (!s)
|
||||
{
|
||||
WLog_ERR(TAG, "cliprdr_server_packet_new failed!");
|
||||
WLog_ERR(TAG, "cliprdr_packet_file_contents_response_new failed!");
|
||||
return ERROR_INTERNAL_ERROR;
|
||||
}
|
||||
|
||||
if ((error = cliprdr_write_file_contents_response(s, fileContentsResponse)))
|
||||
goto fail;
|
||||
|
||||
WLog_DBG(TAG, "ServerFileContentsResponse: streamId: 0x%08"PRIX32"",
|
||||
fileContentsResponse->streamId);
|
||||
return cliprdr_server_packet_send(cliprdr, s);
|
||||
|
||||
fail:
|
||||
Stream_Free(s, TRUE);
|
||||
return error;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user