Merge pull request #6601 from akallabeth/clip_file

Fixed support for huge files in clipboard
This commit is contained in:
Martin Fleisz 2021-01-25 10:26:30 +01:00 committed by GitHub
commit bddeece00c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
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, UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count, BYTE** format_data, UINT32 file_descriptor_count, BYTE** format_data,
UINT32* format_data_length) 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; UINT result = NO_ERROR;
UINT32 i; 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) if (!file_descriptor_array || !format_data || !format_data_length)
return ERROR_BAD_ARGUMENTS; 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); s = Stream_New(NULL, 4 + file_descriptor_count * CLIPRDR_FILEDESCRIPTOR_SIZE);
if (!s) if (!s)
return ERROR_NOT_ENOUGH_MEMORY; return ERROR_NOT_ENOUGH_MEMORY;
@ -318,11 +332,14 @@ UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
* *
* https://support.microsoft.com/en-us/help/2258090 * https://support.microsoft.com/en-us/help/2258090
*/ */
if ((file->nFileSizeHigh > 0) || (file->nFileSizeLow >= CLIPRDR_MAX_FILE_SIZE)) if ((flags & CB_HUGE_FILE_SUPPORT_ENABLED) == 0)
{ {
WLog_ERR(TAG, "cliprdr does not support files over 2 GB"); if ((file->nFileSizeHigh > 0) || (file->nFileSizeLow >= CLIPRDR_MAX_FILE_SIZE))
result = ERROR_FILE_TOO_LARGE; {
goto error; 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_Write_UINT32(s, file->dwFlags); /* flags (4 bytes) */

View File

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

View File

@ -171,6 +171,7 @@ struct xf_clipboard
/* File clipping */ /* File clipping */
BOOL streams_supported; BOOL streams_supported;
BOOL file_formats_registered; BOOL file_formats_registered;
UINT32 file_capability_flags;
#ifdef WITH_FUSE #ifdef WITH_FUSE
/* FUSE related**/ /* FUSE related**/
HANDLE fuse_thread; HANDLE fuse_thread;
@ -697,7 +698,8 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
UINT32 file_count = DstSize / sizeof(FILEDESCRIPTORW); UINT32 file_count = DstSize / sizeof(FILEDESCRIPTORW);
pDstData = NULL; pDstData = NULL;
DstSize = 0; 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) if (error)
WLog_ERR(TAG, "failed to serialize CLIPRDR_FILELIST: 0x%08X", 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 |= generalCapabilitySet.generalFlags |=
CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS | CB_HUGE_FILE_SUPPORT_ENABLED; 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); 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, FREERDP_API UINT cliprdr_serialize_file_list(const FILEDESCRIPTORW* file_descriptor_array,
UINT32 file_descriptor_count, BYTE** format_data, UINT32 file_descriptor_count, BYTE** format_data,
UINT32* format_data_length); 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 #ifdef __cplusplus
} }

View File

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

View File

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