Fixed support for huge files in clipboard

This commit is contained in:
akallabeth 2020-11-24 11:00:13 +01:00
parent 43691d59ee
commit f3dad4106a
6 changed files with 63 additions and 29 deletions

View File

@ -291,6 +291,14 @@ out:
UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count, BYTE** format_data,
UINT32* format_data_length)
{
return cliprdr_serialize_file_list_ex(CB_STREAM_FILECLIP_ENABLED, file_descriptor_array,
file_descriptor_count, format_data, format_data_length);
}
UINT cliprdr_serialize_file_list_ex(UINT32 flags, const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count, BYTE** format_data,
UINT32* format_data_length)
{
UINT result = NO_ERROR;
UINT32 i;
@ -299,6 +307,12 @@ UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
if (!file_descriptor_array || !format_data || !format_data_length)
return ERROR_BAD_ARGUMENTS;
if ((flags & CB_STREAM_FILECLIP_ENABLED) == 0)
{
WLog_WARN(TAG, "No file clipboard support annouonced!");
return ERROR_BAD_ARGUMENTS;
}
s = Stream_New(NULL, 4 + file_descriptor_count * CLIPRDR_FILEDESCRIPTOR_SIZE);
if (!s)
return ERROR_NOT_ENOUGH_MEMORY;
@ -318,12 +332,15 @@ UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
*
* https://support.microsoft.com/en-us/help/2258090
*/
if ((flags & CB_HUGE_FILE_SUPPORT_ENABLED) == 0)
{
if ((file->nFileSizeHigh > 0) || (file->nFileSizeLow >= CLIPRDR_MAX_FILE_SIZE))
{
WLog_ERR(TAG, "cliprdr does not support files over 2 GB");
result = ERROR_FILE_TOO_LARGE;
goto error;
}
}
Stream_Write_UINT32(s, file->dwFlags); /* flags (4 bytes) */
Stream_Zero(s, 32); /* reserved1 (32 bytes) */

View File

@ -37,18 +37,36 @@
#include "../cliprdr_common.h"
#ifdef WITH_DEBUG_CLIPRDR
static const char* const CB_MSG_TYPE_STRINGS[] = { "",
"CB_MONITOR_READY",
"CB_FORMAT_LIST",
"CB_FORMAT_LIST_RESPONSE",
"CB_FORMAT_DATA_REQUEST",
"CB_FORMAT_DATA_RESPONSE",
"CB_TEMP_DIRECTORY",
"CB_CLIP_CAPS",
"CB_FILECONTENTS_REQUEST",
"CB_FILECONTENTS_RESPONSE",
"CB_LOCK_CLIPDATA",
"CB_UNLOCK_CLIPDATA" };
static const char* CB_MSG_TYPE_STRINGS(UINT32 type)
{
switch (type)
{
case CB_MONITOR_READY:
return "CB_MONITOR_READY";
case CB_FORMAT_LIST:
return "CB_FORMAT_LIST";
case CB_FORMAT_LIST_RESPONSE:
return "CB_FORMAT_LIST_RESPONSE";
case CB_FORMAT_DATA_REQUEST:
return "CB_FORMAT_DATA_REQUEST";
case CB_FORMAT_DATA_RESPONSE:
return "CB_FORMAT_DATA_RESPONSE";
case CB_TEMP_DIRECTORY:
return "CB_TEMP_DIRECTORY";
case CB_CLIP_CAPS:
return "CB_CLIP_CAPS";
case CB_FILECONTENTS_REQUEST:
return "CB_FILECONTENTS_REQUEST";
case CB_FILECONTENTS_RESPONSE:
return "CB_FILECONTENTS_RESPONSE";
case CB_LOCK_CLIPDATA:
return "CB_LOCK_CLIPDATA";
case CB_UNLOCK_CLIPDATA:
return "CB_UNLOCK_CLIPDATA";
default:
return "UNKNOWN";
}
}
#endif
CliprdrClientContext* cliprdr_get_client_interface(cliprdrPlugin* cliprdr)
@ -446,7 +464,7 @@ static UINT cliprdr_order_recv(cliprdrPlugin* cliprdr, wStream* s)
#ifdef WITH_DEBUG_CLIPRDR
WLog_DBG(TAG, "msgType: %s (%" PRIu16 "), msgFlags: %" PRIu16 " dataLen: %" PRIu32 "",
CB_MSG_TYPE_STRINGS[msgType], msgType, msgFlags, dataLen);
CB_MSG_TYPE_STRINGS(msgType), msgType, msgFlags, dataLen);
winpr_HexDump(TAG, WLOG_DEBUG, Stream_Buffer(s), dataLen + 8);
#endif

View File

@ -171,6 +171,7 @@ struct xf_clipboard
/* File clipping */
BOOL streams_supported;
BOOL file_formats_registered;
UINT32 file_capability_flags;
#ifdef WITH_FUSE
/* FUSE related**/
HANDLE fuse_thread;
@ -697,7 +698,8 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
UINT32 file_count = DstSize / sizeof(FILEDESCRIPTORW);
pDstData = NULL;
DstSize = 0;
error = cliprdr_serialize_file_list(file_array, file_count, &pDstData, &DstSize);
error = cliprdr_serialize_file_list_ex(clipboard->file_capability_flags, file_array,
file_count, &pDstData, &DstSize);
if (error)
WLog_ERR(TAG, "failed to serialize CLIPRDR_FILELIST: 0x%08X", error);
@ -1189,6 +1191,7 @@ static UINT xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
generalCapabilitySet.generalFlags |=
CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS | CB_HUGE_FILE_SUPPORT_ENABLED;
clipboard->file_capability_flags = generalCapabilitySet.generalFlags;
return clipboard->context->ClientCapabilities(clipboard->context, &capabilities);
}

View File

@ -101,6 +101,10 @@ extern "C"
FREERDP_API UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count, BYTE** format_data,
UINT32* format_data_length);
FREERDP_API UINT cliprdr_serialize_file_list_ex(UINT32 flags,
const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count,
BYTE** format_data, UINT32* format_data_length);
#ifdef __cplusplus
}

View File

@ -317,7 +317,6 @@ static BOOL fastpath_recv_update_common(rdpFastPath* fastpath, wStream* s)
return FALSE;
Stream_Read_UINT16(s, updateType); /* updateType (2 bytes) */
switch (updateType)
{
case UPDATE_TYPE_BITMAP:

View File

@ -54,20 +54,13 @@ char* _strdup(const char* strSource)
WCHAR* _wcsdup(const WCHAR* strSource)
{
size_t len = _wcslen(strSource);
WCHAR* strDestination;
if (strSource == NULL)
return NULL;
#if defined(__APPLE__) && defined(__MACH__) || defined(ANDROID) || defined(sun)
strDestination = malloc(wcslen((wchar_t*)strSource));
strDestination = calloc(len + 1, sizeof(WCHAR));
if (strDestination != NULL)
wcscpy((wchar_t*)strDestination, (const wchar_t*)strSource);
#else
strDestination = (WCHAR*)wcsdup((wchar_t*)strSource);
#endif
memcpy(strDestination, strSource, len * sizeof(WCHAR));
if (strDestination == NULL)
WLog_ERR(TAG, "wcsdup");