channels: cliprdr: improved common cliprdr api

This commit is contained in:
kubistika 2019-10-17 18:59:07 +03:00 committed by akallabeth
parent d2f73136d3
commit d75c5eec04
4 changed files with 257 additions and 376 deletions

View File

@ -64,25 +64,6 @@ CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr)
return pInterface; 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 * Function description
* *
@ -622,120 +603,13 @@ static UINT cliprdr_client_format_list(CliprdrClientContext* context,
const CLIPRDR_FORMAT_LIST* formatList) const CLIPRDR_FORMAT_LIST* formatList)
{ {
wStream* s; 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; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
if (!cliprdr->useLongFormatNames) s = cliprdr_packet_format_list_new(formatList, cliprdr->useLongFormatNames);
if (!s)
{ {
length = formatList->numFormats * 36; WLog_ERR(TAG, "cliprdr_packet_format_list_new failed!");
s = cliprdr_packet_new(CB_FORMAT_LIST, 0, length); return ERROR_INTERNAL_ERROR;
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) */
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"", WLog_Print(cliprdr->log, WLOG_DEBUG, "ClientFormatList: numFormats: %"PRIu32"",
@ -774,10 +648,9 @@ static UINT cliprdr_client_format_list_response(CliprdrClientContext* context,
static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context, static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context,
const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_LOCK_CLIPDATA, 0, 4); s = cliprdr_packet_lock_clipdata_new(lockClipboardData);
if (!s) if (!s)
{ {
@ -785,17 +658,10 @@ static UINT cliprdr_client_lock_clipboard_data(CliprdrClientContext* context,
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
if ((error = cliprdr_write_lock_clipdata(s, lockClipboardData)))
goto fail;
WLog_Print(cliprdr->log, WLOG_DEBUG, WLog_Print(cliprdr->log, WLOG_DEBUG,
"ClientLockClipboardData: clipDataId: 0x%08"PRIX32"", "ClientLockClipboardData: clipDataId: 0x%08"PRIX32"",
lockClipboardData->clipDataId); lockClipboardData->clipDataId);
return cliprdr_packet_send(cliprdr, s); 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, static UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context,
const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_UNLOCK_CLIPDATA, 0, 4); s = cliprdr_packet_unlock_clipdata_new(unlockClipboardData);
if (!s) if (!s)
{ {
@ -817,18 +682,10 @@ static UINT cliprdr_client_unlock_clipboard_data(CliprdrClientContext* context,
return ERROR_INTERNAL_ERROR; 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, WLog_Print(cliprdr->log, WLOG_DEBUG,
"ClientUnlockClipboardData: clipDataId: 0x%08"PRIX32"", "ClientUnlockClipboardData: clipDataId: 0x%08"PRIX32"",
unlockClipboardData->clipDataId); unlockClipboardData->clipDataId);
return cliprdr_packet_send(cliprdr, s); 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, static UINT cliprdr_client_file_contents_request(CliprdrClientContext* context,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_FILECONTENTS_REQUEST, 0, 28); s = cliprdr_packet_file_contents_request_new(fileContentsRequest);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_file_contents_request_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
if ((error = cliprdr_write_file_contents_request(s, fileContentsRequest)))
goto fail;
WLog_Print(cliprdr->log, WLOG_DEBUG, WLog_Print(cliprdr->log, WLOG_DEBUG,
"ClientFileContentsRequest: streamId: 0x%08"PRIX32"", "ClientFileContentsRequest: streamId: 0x%08"PRIX32"",
fileContentsRequest->streamId); fileContentsRequest->streamId);
return cliprdr_packet_send(cliprdr, s); 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, static UINT cliprdr_client_file_contents_response(CliprdrClientContext* context,
const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle; cliprdrPlugin* cliprdr = (cliprdrPlugin*) context->handle;
s = cliprdr_packet_new(CB_FILECONTENTS_RESPONSE, fileContentsResponse->msgFlags, s = cliprdr_packet_file_contents_response_new(fileContentsResponse);
4 + fileContentsResponse->cbRequested);
if (!s) if (!s)
{ {
@ -934,17 +781,10 @@ static UINT cliprdr_client_file_contents_response(CliprdrClientContext* context,
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
if ((error = cliprdr_write_file_contents_response(s, fileContentsResponse)))
goto fail;
WLog_Print(cliprdr->log, WLOG_DEBUG, WLog_Print(cliprdr->log, WLOG_DEBUG,
"ClientFileContentsResponse: streamId: 0x%08"PRIX32"", "ClientFileContentsResponse: streamId: 0x%08"PRIX32"",
fileContentsResponse->streamId); fileContentsResponse->streamId);
return cliprdr_packet_send(cliprdr, s); return cliprdr_packet_send(cliprdr, s);
fail:
Stream_Free(s, TRUE);
return error;
} }
/** /**

View File

@ -58,7 +58,26 @@ static BOOL cliprdr_validate_file_contents_request(const CLIPRDR_FILE_CONTENTS_R
return TRUE; 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->streamId); /* streamId (4 bytes) */
Stream_Write_UINT32(s, request->listIndex); /* listIndex (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) if (request->haveClipDataId)
Stream_Write_UINT32(s, request->clipDataId); /* clipDataId (4 bytes) */ 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); 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) 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) const CLIPRDR_FILE_CONTENTS_RESPONSE* response)
{ {
Stream_Write_UINT32(s, response->streamId); /* streamId (4 bytes) */ Stream_Write_UINT32(s, response->streamId); /* streamId (4 bytes) */
Stream_Write(s, response->requestedData, response->cbRequested); 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) UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
{ {
if (Stream_GetRemainingLength(s) < 4) if (Stream_GetRemainingLength(s) < 4)

View File

@ -29,10 +29,12 @@
#include <freerdp/channels/cliprdr.h> #include <freerdp/channels/cliprdr.h>
#include <freerdp/api.h> #include <freerdp/api.h>
FREERDP_LOCAL UINT cliprdr_write_lock_clipdata(wStream* s, const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData); FREERDP_LOCAL wStream* cliprdr_packet_new(UINT16 msgType, UINT16 msgFlags, UINT32 dataLen);
FREERDP_LOCAL UINT cliprdr_write_unlock_clipdata(wStream* s, const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData); FREERDP_LOCAL wStream* cliprdr_packet_lock_clipdata_new(const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);
FREERDP_LOCAL UINT cliprdr_write_file_contents_request(wStream* s, const CLIPRDR_FILE_CONTENTS_REQUEST* request); FREERDP_LOCAL wStream* cliprdr_packet_unlock_clipdata_new(const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData);
FREERDP_LOCAL UINT cliprdr_write_file_contents_response(wStream* s, const CLIPRDR_FILE_CONTENTS_RESPONSE* response); 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_lock_clipdata(wStream* s, CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData);
FREERDP_LOCAL UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData); FREERDP_LOCAL UINT cliprdr_read_unlock_clipdata(wStream* s, CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData);

View File

@ -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 * Function description
* *
@ -145,11 +126,11 @@ static UINT cliprdr_server_capabilities(CliprdrServerContext* context,
return ERROR_INVALID_PARAMETER; 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) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
@ -200,12 +181,12 @@ static UINT cliprdr_server_monitor_ready(CliprdrServerContext* context, const CL
if (monitorReady->msgType != CB_MONITOR_READY) if (monitorReady->msgType != CB_MONITOR_READY)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, monitorReady->msgType); 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); monitorReady->msgFlags, monitorReady->dataLen);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
@ -222,128 +203,13 @@ static UINT cliprdr_server_format_list(CliprdrServerContext* context,
const CLIPRDR_FORMAT_LIST* formatList) const CLIPRDR_FORMAT_LIST* formatList)
{ {
wStream* s; 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; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
if (formatList->msgType != CB_FORMAT_LIST) s = cliprdr_packet_format_list_new(formatList, context->useLongFormatNames);
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatList->msgType); if (!s)
if (!context->useLongFormatNames)
{ {
UINT32 length = formatList->numFormats * 36; WLog_ERR(TAG, "cliprdr_packet_format_list_new failed!");
s = cliprdr_server_packet_new(CB_FORMAT_LIST, 0, length); return ERROR_INTERNAL_ERROR;
if (!s)
{
WLog_ERR(TAG, "cliprdr_server_packet_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"", WLog_DBG(TAG, "ServerFormatList: numFormats: %"PRIu32"",
@ -364,12 +230,12 @@ static UINT cliprdr_server_format_list_response(CliprdrServerContext* context,
if (formatListResponse->msgType != CB_FORMAT_LIST_RESPONSE) if (formatListResponse->msgType != CB_FORMAT_LIST_RESPONSE)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatListResponse->msgType); 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); formatListResponse->msgFlags, formatListResponse->dataLen);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_new failed!");
return ERROR_INTERNAL_ERROR; 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, static UINT cliprdr_server_lock_clipboard_data(CliprdrServerContext* context,
const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData) const CLIPRDR_LOCK_CLIPBOARD_DATA* lockClipboardData)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
if (lockClipboardData->msgType != CB_LOCK_CLIPDATA) if (lockClipboardData->msgType != CB_LOCK_CLIPDATA)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, lockClipboardData->msgType); 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) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_lock_clipdata_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
if ((error = cliprdr_write_lock_clipdata(s, lockClipboardData)))
goto fail;
WLog_DBG(TAG, "ServerLockClipboardData: clipDataId: 0x%08"PRIX32"", WLog_DBG(TAG, "ServerLockClipboardData: clipDataId: 0x%08"PRIX32"",
lockClipboardData->clipDataId); lockClipboardData->clipDataId);
return cliprdr_server_packet_send(cliprdr, s); 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, static UINT cliprdr_server_unlock_clipboard_data(CliprdrServerContext* context,
const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData) const CLIPRDR_UNLOCK_CLIPBOARD_DATA* unlockClipboardData)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
if (unlockClipboardData->msgType != CB_UNLOCK_CLIPDATA) if (unlockClipboardData->msgType != CB_UNLOCK_CLIPDATA)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, unlockClipboardData->msgType); 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) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_unlock_clipdata_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
if ((error = cliprdr_write_unlock_clipdata(s, unlockClipboardData)))
goto fail;
WLog_DBG(TAG, "ServerUnlockClipboardData: clipDataId: 0x%08"PRIX32"", WLog_DBG(TAG, "ServerUnlockClipboardData: clipDataId: 0x%08"PRIX32"",
unlockClipboardData->clipDataId); unlockClipboardData->clipDataId);
return cliprdr_server_packet_send(cliprdr, s); 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) if (formatDataRequest->msgType != CB_FORMAT_DATA_REQUEST)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatDataRequest->msgType); 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); formatDataRequest->msgFlags, formatDataRequest->dataLen);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
@ -486,12 +336,12 @@ static UINT cliprdr_server_format_data_response(CliprdrServerContext* context,
if (formatDataResponse->msgType != CB_FORMAT_DATA_RESPONSE) if (formatDataResponse->msgType != CB_FORMAT_DATA_RESPONSE)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, formatDataResponse->msgType); 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); formatDataResponse->msgFlags, formatDataResponse->dataLen);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_new failed!");
return ERROR_INTERNAL_ERROR; 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, static UINT cliprdr_server_file_contents_request(CliprdrServerContext* context,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest) const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
if (fileContentsRequest->msgType != CB_FILECONTENTS_REQUEST) if (fileContentsRequest->msgType != CB_FILECONTENTS_REQUEST)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, fileContentsRequest->msgType); 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) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_file_contents_request_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
if ((error = cliprdr_write_file_contents_request(s, fileContentsRequest)))
goto fail;
WLog_DBG(TAG, "ServerFileContentsRequest: streamId: 0x%08"PRIX32"", WLog_DBG(TAG, "ServerFileContentsRequest: streamId: 0x%08"PRIX32"",
fileContentsRequest->streamId); fileContentsRequest->streamId);
return cliprdr_server_packet_send(cliprdr, s); 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, static UINT cliprdr_server_file_contents_response(CliprdrServerContext* context,
const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse) const CLIPRDR_FILE_CONTENTS_RESPONSE* fileContentsResponse)
{ {
UINT error = CHANNEL_RC_OK;
wStream* s; wStream* s;
CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle; CliprdrServerPrivate* cliprdr = (CliprdrServerPrivate*) context->handle;
if (fileContentsResponse->msgType != CB_FILECONTENTS_RESPONSE) if (fileContentsResponse->msgType != CB_FILECONTENTS_RESPONSE)
WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, fileContentsResponse->msgType); WLog_WARN(TAG, "[%s] called with invalid type %08"PRIx32, __FUNCTION__, fileContentsResponse->msgType);
s = cliprdr_server_packet_new(CB_FILECONTENTS_RESPONSE, fileContentsResponse->msgFlags, s = cliprdr_packet_file_contents_response_new(fileContentsResponse);
4 + fileContentsResponse->cbRequested);
if (!s) if (!s)
{ {
WLog_ERR(TAG, "cliprdr_server_packet_new failed!"); WLog_ERR(TAG, "cliprdr_packet_file_contents_response_new failed!");
return ERROR_INTERNAL_ERROR; return ERROR_INTERNAL_ERROR;
} }
if ((error = cliprdr_write_file_contents_response(s, fileContentsResponse))) WLog_DBG(TAG, "ServerFileContentsResponse: streamId: 0x%08"PRIX32"",
goto fail;
WLog_DBG(TAG, "ServerFileContentsResponse: streamId: 0x%08" PRIX32 "",
fileContentsResponse->streamId); fileContentsResponse->streamId);
return cliprdr_server_packet_send(cliprdr, s); return cliprdr_server_packet_send(cliprdr, s);
fail:
Stream_Free(s, TRUE);
return error;
} }
/** /**