[client,common] fixed winpr clipboard locking

This commit is contained in:
Armin Novak
2023-02-28 11:37:42 +01:00
committed by akallabeth
parent 6d2e7b91c7
commit 46f1d141c1
3 changed files with 77 additions and 34 deletions

View File

@@ -778,15 +778,17 @@ wlf_cliprdr_server_format_data_request(CliprdrClientContext* context,
goto fail;
}
ClipboardLock(clipboard->system);
const BOOL res = ClipboardSetData(clipboard->system, localFormatId, data, size);
free(data);
data = NULL;
if (!res)
goto fail;
UINT32 len = 0;
data = ClipboardGetData(clipboard->system, formatId, &len);
if (!data)
data = NULL;
if (res)
data = ClipboardGetData(clipboard->system, formatId, &len);
ClipboardUnlock(clipboard->system);
if (!res || !data)
goto fail;
if (fileFormatId == formatId)
@@ -867,9 +869,9 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context,
ClipboardGetFormatId(clipboard->system, type_FileGroupDescriptorW);
dstFormatId = ClipboardGetFormatId(clipboard->system, request->responseMime);
if (!cliprdr_file_context_update_base(clipboard->file, clipboard->system))
if (!cliprdr_file_context_update_server_data(clipboard->file, data, size))
goto unlock;
else if (!cliprdr_file_context_update_server_data(clipboard->file, data, size))
else if (!cliprdr_file_context_update_base(clipboard->file, clipboard->system))
goto unlock;
}
else if (strcmp(type_HtmlFormat, name) == 0)
@@ -882,12 +884,15 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context,
break;
}
if (!ClipboardSetData(clipboard->system, srcFormatId, data, size))
goto unlock;
ClipboardLock(clipboard->system);
UINT32 len = 0;
data = ClipboardGetData(clipboard->system, dstFormatId, &len);
if (!data)
const BOOL sres = ClipboardSetData(clipboard->system, srcFormatId, data, size);
if (sres)
data = ClipboardGetData(clipboard->system, dstFormatId, &len);
ClipboardUnlock(clipboard->system);
if (!sres || !data)
goto unlock;
if (request->responseFile)

View File

@@ -834,6 +834,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
return;
}
ClipboardLock(clipboard->system);
SrcSize = (UINT32)size;
bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize);
@@ -842,6 +843,7 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
DstSize = 0;
pDstData = (BYTE*)ClipboardGetData(clipboard->system, format->formatToRequest, &DstSize);
}
ClipboardUnlock(clipboard->system);
if (!pDstData)
{
@@ -874,7 +876,9 @@ static void xf_cliprdr_process_requested_data(xfClipboard* clipboard, BOOL hasDa
UINT32 formatId = ClipboardGetFormatId(clipboard->system, mime_uri_list);
UINT32 url_size = 0;
ClipboardLock(clipboard->system);
char* url = ClipboardGetData(clipboard->system, formatId, &url_size);
ClipboardUnlock(clipboard->system);
cliprdr_file_context_update_client_data(clipboard->file, url, url_size);
free(url);
@@ -1257,7 +1261,10 @@ static BOOL xf_cliprdr_process_selection_request(xfClipboard* clipboard,
/* Cached converted clipboard data available. Send it now */
respond->property = xevent->property;
ClipboardLock(clipboard->system);
void* data = ClipboardGetData(clipboard->system, cformat->localFormat, &DstSize);
ClipboardUnlock(clipboard->system);
xf_cliprdr_provide_data(clipboard, respond, data, DstSize);
free(data);
}
@@ -1881,11 +1888,11 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
if (strcmp(clipboard->requestedFormat->formatName, type_FileGroupDescriptorW) == 0)
{
if (!cliprdr_file_context_update_base(clipboard->file, clipboard->system))
if (!cliprdr_file_context_update_server_data(clipboard->file, data, size))
WLog_WARN(TAG, "failed to update file descriptors");
else if (!cliprdr_file_context_update_base(clipboard->file, clipboard->system))
{
}
else if (!cliprdr_file_context_update_server_data(clipboard->file, data, size))
WLog_WARN(TAG, "failed to update file descriptors");
srcFormatId = ClipboardGetFormatId(clipboard->system, type_FileGroupDescriptorW);
const xfCliprdrFormat* dstTargetFormat =
@@ -1933,8 +1940,11 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
format->formatToRequest, ClipboardGetFormatIdString(format->formatToRequest),
format->localFormat, format->formatName);
SrcSize = (UINT32)size;
ClipboardLock(clipboard->system);
bSuccess = ClipboardSetData(clipboard->system, srcFormatId, data, SrcSize);
BOOL willQuit = FALSE;
if (bSuccess)
{
if (SrcSize == 0)
@@ -1942,25 +1952,30 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
WLog_DBG(TAG, "skipping, empty data detected!");
free(clipboard->respond);
clipboard->respond = NULL;
return CHANNEL_RC_OK;
willQuit = TRUE;
}
pDstData = (BYTE*)ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
if (!pDstData)
else
{
WLog_WARN(TAG, "failed to get clipboard data in format %s [source format %s]",
ClipboardGetFormatName(clipboard->system, dstFormatId),
ClipboardGetFormatName(clipboard->system, srcFormatId));
}
pDstData = (BYTE*)ClipboardGetData(clipboard->system, dstFormatId, &DstSize);
if (nullTerminated && pDstData)
{
BYTE* nullTerminator = memchr(pDstData, '\0', DstSize);
if (nullTerminator)
DstSize = nullTerminator - pDstData;
if (!pDstData)
{
WLog_WARN(TAG, "failed to get clipboard data in format %s [source format %s]",
ClipboardGetFormatName(clipboard->system, dstFormatId),
ClipboardGetFormatName(clipboard->system, srcFormatId));
}
if (nullTerminated && pDstData)
{
BYTE* nullTerminator = memchr(pDstData, '\0', DstSize);
if (nullTerminator)
DstSize = nullTerminator - pDstData;
}
}
}
ClipboardUnlock(clipboard->system);
if (willQuit)
return CHANNEL_RC_OK;
/* Cache converted and original data to avoid doing a possibly costly
* conversion again on subsequent requests */

View File

@@ -147,6 +147,7 @@ struct cliprdr_file_context
CliprdrClientContext* context;
char* path;
char* current_path;
char* exposed_path;
BYTE server_data_hash[WINPR_SHA256_DIGEST_LENGTH];
BYTE client_data_hash[WINPR_SHA256_DIGEST_LENGTH];
};
@@ -922,6 +923,8 @@ struct stream_node_arg
CliprdrFuseInode* root;
};
static BOOL update_sub_path(CliprdrFileContext* file, UINT32 lockID);
static BOOL add_stream_node(const void* key, void* value, void* arg)
{
const CliprdrFuseStreamLock* stream = value;
@@ -933,6 +936,12 @@ static BOOL add_stream_node(const void* key, void* value, void* arg)
char name[10] = { 0 };
_snprintf(name, sizeof(name), "%08" PRIx32, stream->lockId);
if ((cliprdr_file_context_current_flags(stream->context) & CB_CAN_LOCK_CLIPDATA) == 0)
{
if (!update_sub_path(stream->context, stream->lockId))
return FALSE;
}
const size_t idx = ArrayList_Count(node_arg->list);
CliprdrFuseInode* node = cliprdr_file_fuse_node_new(
stream->lockId, idx, FUSE_ROOT_ID + 1 + stream->lockId, FUSE_ROOT_ID, name, S_IFDIR | 0700);
@@ -1583,9 +1592,12 @@ static BOOL update_sub_path(CliprdrFileContext* file, UINT32 lockID)
char lockstr[32] = { 0 };
_snprintf(lockstr, sizeof(lockstr), "%08" PRIx32, lockID);
HashTable_Lock(file->remote_streams);
free(file->current_path);
file->current_path = GetCombinedPath(file->path, lockstr);
return file->current_path != NULL;
const BOOL res = file->current_path != NULL;
HashTable_Unlock(file->remote_streams);
return res;
}
static UINT change_lock(CliprdrFileContext* file, UINT32 lockId, BOOL lock)
@@ -1823,6 +1835,7 @@ void cliprdr_file_context_free(CliprdrFileContext* file)
winpr_RemoveDirectory(file->path);
free(file->path);
free(file->current_path);
free(file->exposed_path);
free(file);
}
@@ -2092,8 +2105,6 @@ CliprdrFileContext* cliprdr_file_context_new(void* context)
file->log = WLog_Get(CLIENT_TAG("common.cliprdr.file"));
file->clipboard = context;
if (!create_base_path(file))
goto fail;
file->local_streams = HashTable_New(FALSE);
if (!file->local_streams)
@@ -2150,7 +2161,12 @@ CliprdrFileContext* cliprdr_file_context_new(void* context)
}
obj = ArrayList_Object(file->ino_list);
obj->fnObjectFree = cliprdr_file_fuse_node_free;
#endif
if (!create_base_path(file))
goto fail;
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
if (!cliprdr_fuse_repopulate(file, file->ino_list))
goto fail;
@@ -2275,8 +2291,15 @@ BOOL cliprdr_file_context_update_base(CliprdrFileContext* file, wClipboard* clip
wClipboardDelegate* delegate = ClipboardGetDelegate(clip);
if (!delegate)
return FALSE;
delegate->basePath = file->current_path;
return TRUE;
ClipboardLock(clip);
HashTable_Lock(file->remote_streams);
free(file->exposed_path);
file->exposed_path = _strdup(file->current_path);
HashTable_Unlock(file->remote_streams);
delegate->basePath = (file->exposed_path);
ClipboardUnlock(clip);
return delegate->basePath != NULL;
}
BOOL cliprdr_file_context_has_local_support(CliprdrFileContext* file)