remove wClipboardDelegate

This commit is contained in:
Armin Novak 2023-02-25 16:46:12 +01:00 committed by akallabeth
parent 7c4a774e4e
commit d521c7fa74
3 changed files with 131 additions and 475 deletions

View File

@ -60,7 +60,6 @@ struct wlf_clipboard
UwacSeat* seat;
wClipboard* system;
wClipboardDelegate* delegate;
size_t numClientFormats;
CLIPRDR_FORMAT* clientFormats;
@ -767,193 +766,6 @@ wlf_cliprdr_server_format_data_response(CliprdrClientContext* context,
return rc;
}
static UINT
wlf_cliprdr_server_file_size_request(wfClipboard* clipboard,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
wClipboardFileSizeRequest request = { 0 };
WINPR_ASSERT(fileContentsRequest);
request.streamId = fileContentsRequest->streamId;
request.listIndex = fileContentsRequest->listIndex;
if (fileContentsRequest->cbRequested != sizeof(UINT64))
{
WLog_Print(clipboard->log, WLOG_WARN,
"unexpected FILECONTENTS_SIZE request: %" PRIu32 " bytes",
fileContentsRequest->cbRequested);
}
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->delegate);
WINPR_ASSERT(clipboard->delegate->ClientRequestFileSize);
return clipboard->delegate->ClientRequestFileSize(clipboard->delegate, &request);
}
static UINT
wlf_cliprdr_server_file_range_request(wfClipboard* clipboard,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
wClipboardFileRangeRequest request = { 0 };
WINPR_ASSERT(fileContentsRequest);
request.streamId = fileContentsRequest->streamId;
request.listIndex = fileContentsRequest->listIndex;
request.nPositionLow = fileContentsRequest->nPositionLow;
request.nPositionHigh = fileContentsRequest->nPositionHigh;
request.cbRequested = fileContentsRequest->cbRequested;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->delegate);
WINPR_ASSERT(clipboard->delegate->ClientRequestFileRange);
return clipboard->delegate->ClientRequestFileRange(clipboard->delegate, &request);
}
static UINT
wlf_cliprdr_send_file_contents_failure(CliprdrClientContext* context,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
WINPR_ASSERT(fileContentsRequest);
response.common.msgFlags = CB_RESPONSE_FAIL;
response.streamId = fileContentsRequest->streamId;
WINPR_ASSERT(context);
WINPR_ASSERT(context->ClientFileContentsResponse);
return context->ClientFileContentsResponse(context, &response);
}
static UINT
wlf_cliprdr_server_file_contents_request(CliprdrClientContext* context,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
UINT error = NO_ERROR;
wfClipboard* clipboard;
WINPR_ASSERT(context);
WINPR_ASSERT(fileContentsRequest);
clipboard = context->custom;
WINPR_ASSERT(clipboard);
/*
* MS-RDPECLIP 2.2.5.3 File Contents Request PDU (CLIPRDR_FILECONTENTS_REQUEST):
* The FILECONTENTS_SIZE and FILECONTENTS_RANGE flags MUST NOT be set at the same time.
*/
if ((fileContentsRequest->dwFlags & (FILECONTENTS_SIZE | FILECONTENTS_RANGE)) ==
(FILECONTENTS_SIZE | FILECONTENTS_RANGE))
{
WLog_Print(clipboard->log, WLOG_ERROR, "invalid CLIPRDR_FILECONTENTS_REQUEST.dwFlags");
return wlf_cliprdr_send_file_contents_failure(context, fileContentsRequest);
}
if (fileContentsRequest->dwFlags & FILECONTENTS_SIZE)
error = wlf_cliprdr_server_file_size_request(clipboard, fileContentsRequest);
if (fileContentsRequest->dwFlags & FILECONTENTS_RANGE)
error = wlf_cliprdr_server_file_range_request(clipboard, fileContentsRequest);
if (error)
{
WLog_Print(clipboard->log, WLOG_ERROR,
"failed to handle CLIPRDR_FILECONTENTS_REQUEST: 0x%08X", error);
return wlf_cliprdr_send_file_contents_failure(context, fileContentsRequest);
}
return CHANNEL_RC_OK;
}
static UINT wlf_cliprdr_clipboard_file_size_success(wClipboardDelegate* delegate,
const wClipboardFileSizeRequest* request,
UINT64 fileSize)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
wfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
response.common.msgFlags = CB_RESPONSE_OK;
response.streamId = request->streamId;
response.cbRequested = sizeof(UINT64);
response.requestedData = (BYTE*)&fileSize;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static UINT wlf_cliprdr_clipboard_file_size_failure(wClipboardDelegate* delegate,
const wClipboardFileSizeRequest* request,
UINT errorCode)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
wfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
WINPR_UNUSED(errorCode);
response.common.msgFlags = CB_RESPONSE_FAIL;
response.streamId = request->streamId;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static UINT wlf_cliprdr_clipboard_file_range_success(wClipboardDelegate* delegate,
const wClipboardFileRangeRequest* request,
const BYTE* data, UINT32 size)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
wfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
WINPR_ASSERT(data || (size == 0));
response.common.msgFlags = CB_RESPONSE_OK;
response.streamId = request->streamId;
response.cbRequested = size;
response.requestedData = (const BYTE*)data;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static UINT wlf_cliprdr_clipboard_file_range_failure(wClipboardDelegate* delegate,
const wClipboardFileRangeRequest* request,
UINT errorCode)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
wfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
WINPR_UNUSED(errorCode);
response.common.msgFlags = CB_RESPONSE_FAIL;
response.streamId = request->streamId;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
wfClipboard* wlf_clipboard_new(wlfContext* wfc)
{
rdpChannels* channels;
@ -974,18 +786,6 @@ wfClipboard* wlf_clipboard_new(wlfContext* wfc)
clipboard->system = ClipboardCreate();
if (!clipboard->system)
goto fail;
clipboard->delegate = ClipboardGetDelegate(clipboard->system);
if (!clipboard->delegate)
goto fail;
clipboard->delegate->custom = clipboard;
/* TODO: set up a filesystem base path for local URI */
/* clipboard->delegate->basePath = "file:///tmp/foo/bar/gaga"; */
clipboard->delegate->ClipboardFileSizeSuccess = wlf_cliprdr_clipboard_file_size_success;
clipboard->delegate->ClipboardFileSizeFailure = wlf_cliprdr_clipboard_file_size_failure;
clipboard->delegate->ClipboardFileRangeSuccess = wlf_cliprdr_clipboard_file_range_success;
clipboard->delegate->ClipboardFileRangeFailure = wlf_cliprdr_clipboard_file_range_failure;
return clipboard;
fail:
@ -1022,8 +822,8 @@ BOOL wlf_cliprdr_init(wfClipboard* clipboard, CliprdrClientContext* cliprdr)
cliprdr->ServerFormatList = wlf_cliprdr_server_format_list;
cliprdr->ServerFormatListResponse = wlf_cliprdr_server_format_list_response;
cliprdr->ServerFormatDataRequest = wlf_cliprdr_server_format_data_request;
cliprdr->ServerFormatDataResponse = wlf_cliprdr_server_format_data_response;
cliprdr->ServerFileContentsRequest = wlf_cliprdr_server_file_contents_request;
cliprdr->ServerFormatDataResponse = wlf_cliprdr_server_format_data_response;
return TRUE;
}

View File

@ -77,7 +77,6 @@ struct xf_clipboard
CliprdrClientContext* context;
wClipboard* system;
wClipboardDelegate* delegate;
Window root_window;
Atom clipboard_atom;
@ -1998,48 +1997,6 @@ xf_cliprdr_server_format_data_response(CliprdrClientContext* context,
return CHANNEL_RC_OK;
}
static UINT
xf_cliprdr_server_file_size_request(xfClipboard* clipboard,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
wClipboardFileSizeRequest request = { 0 };
WINPR_ASSERT(clipboard);
WINPR_ASSERT(fileContentsRequest);
request.streamId = fileContentsRequest->streamId;
request.listIndex = fileContentsRequest->listIndex;
if (fileContentsRequest->cbRequested != sizeof(UINT64))
{
WLog_WARN(TAG, "unexpected FILECONTENTS_SIZE request: %" PRIu32 " bytes",
fileContentsRequest->cbRequested);
}
WINPR_ASSERT(clipboard->delegate);
WINPR_ASSERT(clipboard->delegate->ClientRequestFileSize);
return clipboard->delegate->ClientRequestFileSize(clipboard->delegate, &request);
}
static UINT
xf_cliprdr_server_file_range_request(xfClipboard* clipboard,
const CLIPRDR_FILE_CONTENTS_REQUEST* fileContentsRequest)
{
wClipboardFileRangeRequest request = { 0 };
WINPR_ASSERT(fileContentsRequest);
request.streamId = fileContentsRequest->streamId;
request.listIndex = fileContentsRequest->listIndex;
request.nPositionLow = fileContentsRequest->nPositionLow;
request.nPositionHigh = fileContentsRequest->nPositionHigh;
request.cbRequested = fileContentsRequest->cbRequested;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->delegate);
WINPR_ASSERT(clipboard->delegate->ClientRequestFileRange);
return clipboard->delegate->ClientRequestFileRange(clipboard->delegate, &request);
}
static UINT
xf_cliprdr_send_file_contents_failure(CliprdrClientContext* context,
@ -2096,92 +2053,6 @@ xf_cliprdr_server_file_contents_request(CliprdrClientContext* context,
return CHANNEL_RC_OK;
}
static UINT xf_cliprdr_clipboard_file_size_success(wClipboardDelegate* delegate,
const wClipboardFileSizeRequest* request,
UINT64 fileSize)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
xfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
response.common.msgFlags = CB_RESPONSE_OK;
response.streamId = request->streamId;
response.cbRequested = sizeof(UINT64);
response.requestedData = (BYTE*)&fileSize;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static UINT xf_cliprdr_clipboard_file_size_failure(wClipboardDelegate* delegate,
const wClipboardFileSizeRequest* request,
UINT errorCode)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
xfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
WINPR_UNUSED(errorCode);
response.common.msgFlags = CB_RESPONSE_FAIL;
response.streamId = request->streamId;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static UINT xf_cliprdr_clipboard_file_range_success(wClipboardDelegate* delegate,
const wClipboardFileRangeRequest* request,
const BYTE* data, UINT32 size)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
xfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
response.common.msgFlags = CB_RESPONSE_OK;
response.streamId = request->streamId;
response.cbRequested = size;
response.requestedData = (const BYTE*)data;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static UINT xf_cliprdr_clipboard_file_range_failure(wClipboardDelegate* delegate,
const wClipboardFileRangeRequest* request,
UINT errorCode)
{
CLIPRDR_FILE_CONTENTS_RESPONSE response = { 0 };
xfClipboard* clipboard;
WINPR_ASSERT(delegate);
WINPR_ASSERT(request);
WINPR_UNUSED(errorCode);
response.common.msgFlags = CB_RESPONSE_FAIL;
response.streamId = request->streamId;
clipboard = delegate->custom;
WINPR_ASSERT(clipboard);
WINPR_ASSERT(clipboard->context);
WINPR_ASSERT(clipboard->context->ClientFileContentsResponse);
return clipboard->context->ClientFileContentsResponse(clipboard->context, &response);
}
static BOOL xf_cliprdr_clipboard_is_valid_unix_filename(LPCWSTR filename)
{
LPCWSTR c;
@ -2372,24 +2243,11 @@ xfClipboard* xf_clipboard_new(xfContext* xfc, BOOL relieveFilenameRestriction)
clipboard->targets[0] = XInternAtom(xfc->display, "TIMESTAMP", FALSE);
clipboard->targets[1] = XInternAtom(xfc->display, "TARGETS", FALSE);
clipboard->numTargets = 2;
clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
clipboard->delegate = ClipboardGetDelegate(clipboard->system);
clipboard->delegate->custom = clipboard;
clipboard->incr_atom = XInternAtom(xfc->display, "INCR", FALSE);
clipboard->file = cliprdr_file_context_new(clipboard);
if (!clipboard->file)
goto fail;
clipboard->delegate->basePath = cliprdr_file_context_base_path(clipboard->file);
clipboard->delegate->ClipboardFileSizeSuccess = xf_cliprdr_clipboard_file_size_success;
clipboard->delegate->ClipboardFileSizeFailure = xf_cliprdr_clipboard_file_size_failure;
clipboard->delegate->ClipboardFileRangeSuccess = xf_cliprdr_clipboard_file_range_success;
clipboard->delegate->ClipboardFileRangeFailure = xf_cliprdr_clipboard_file_range_failure;
if (relieveFilenameRestriction)
{
WLog_DBG(TAG, "Relieving CLIPRDR filename restriction");
clipboard->delegate->IsFileNameComponentValid = xf_cliprdr_clipboard_is_valid_unix_filename;
}
goto fail;
return clipboard;

View File

@ -621,136 +621,7 @@ static DWORD WINAPI cliprdr_file_fuse_thread(LPVOID arg)
ExitThread(0);
return 0;
}
#endif
void cliprdr_file_session_terminate(CliprdrFileContext* file)
{
if (!file)
return;
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
if (file->fuse_sess)
fuse_session_exit(file->fuse_sess);
#endif
/* not elegant but works for umounting FUSE
fuse_chan must receieve a oper buf to unblock fuse_session_receive_buf function.
*/
winpr_PathFileExists(file->path);
}
void cliprdr_file_context_free(CliprdrFileContext* file)
{
if (!file)
return;
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
if (file->fuse_thread)
{
cliprdr_file_session_terminate(file);
WaitForSingleObject(file->fuse_thread, INFINITE);
CloseHandle(file->fuse_thread);
}
// fuse related
ArrayList_Free(file->stream_list);
ArrayList_Free(file->ino_list);
#endif
winpr_RemoveDirectory(file->path);
free(file->path);
free(file);
}
static BOOL create_base_path(CliprdrFileContext* file)
{
WINPR_ASSERT(file);
char base[64] = { 0 };
_snprintf(base, sizeof(base), "/.xfreerdp.cliprdr.%" PRIu32, GetCurrentProcessId());
file->path = GetKnownSubPath(KNOWN_PATH_TEMP, base);
if (!file->path)
return FALSE;
if (!winpr_PathFileExists(file->path) && !winpr_PathMakePath(file->path, 0))
{
WLog_ERR(TAG, "Failed to create directory '%s'", file->path);
return FALSE;
}
return TRUE;
}
CliprdrFileContext* cliprdr_file_context_new(void* context)
{
CliprdrFileContext* file = calloc(1, sizeof(CliprdrFileContext));
if (!file)
return NULL;
file->clipboard = context;
if (!create_base_path(file))
goto fail;
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
file->current_stream_id = 0;
file->stream_list = ArrayList_New(TRUE);
if (!file->stream_list)
{
WLog_ERR(TAG, "failed to allocate stream_list");
goto fail;
}
wObject* obj = ArrayList_Object(file->stream_list);
obj->fnObjectFree = free;
file->ino_list = ArrayList_New(TRUE);
if (!file->ino_list)
{
WLog_ERR(TAG, "failed to allocate stream_list");
goto fail;
}
obj = ArrayList_Object(file->ino_list);
obj->fnObjectFree = cliprdr_file_fuse_inode_free;
if (!xf_fuse_repopulate(file->ino_list))
goto fail;
if (!(file->fuse_thread = CreateThread(NULL, 0, cliprdr_file_fuse_thread, file, 0, NULL)))
{
goto fail;
}
#endif
return file;
fail:
cliprdr_file_context_free(file);
return NULL;
}
BOOL cliprdr_file_context_clear(CliprdrFileContext* file)
{
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
if (file->stream_list)
{
size_t index;
size_t count;
CliprdrFuseStream* stream;
ArrayList_Lock(file->stream_list);
file->current_stream_id = 0;
/* reply error to all req first don't care request type*/
count = ArrayList_Count(file->stream_list);
for (index = 0; index < count; index++)
{
stream = (CliprdrFuseStream*)ArrayList_GetItem(file->stream_list, index);
fuse_reply_err(stream->req, EIO);
}
ArrayList_Unlock(file->stream_list);
ArrayList_Clear(file->stream_list);
}
xf_fuse_repopulate(file->ino_list);
#endif
}
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
static CliprdrFuseInode* cliprdr_file_fuse_create_root_node(void)
{
CliprdrFuseInode* rootNode = (CliprdrFuseInode*)calloc(1, sizeof(CliprdrFuseInode));
@ -1235,3 +1106,130 @@ const char* cliprdr_file_context_base_path(CliprdrFileContext* file)
WINPR_ASSERT(file);
return file->path;
}
void cliprdr_file_session_terminate(CliprdrFileContext* file)
{
if (!file)
return;
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
if (file->fuse_sess)
fuse_session_exit(file->fuse_sess);
#endif
/* not elegant but works for umounting FUSE
fuse_chan must receieve a oper buf to unblock fuse_session_receive_buf function.
*/
winpr_PathFileExists(file->path);
}
void cliprdr_file_context_free(CliprdrFileContext* file)
{
if (!file)
return;
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
if (file->fuse_thread)
{
cliprdr_file_session_terminate(file);
WaitForSingleObject(file->fuse_thread, INFINITE);
CloseHandle(file->fuse_thread);
}
// fuse related
ArrayList_Free(file->stream_list);
ArrayList_Free(file->ino_list);
#endif
winpr_RemoveDirectory(file->path);
free(file->path);
free(file);
}
static BOOL create_base_path(CliprdrFileContext* file)
{
WINPR_ASSERT(file);
char base[64] = { 0 };
_snprintf(base, sizeof(base), "/.xfreerdp.cliprdr.%" PRIu32, GetCurrentProcessId());
file->path = GetKnownSubPath(KNOWN_PATH_TEMP, base);
if (!file->path)
return FALSE;
if (!winpr_PathFileExists(file->path) && !winpr_PathMakePath(file->path, 0))
{
WLog_ERR(TAG, "Failed to create directory '%s'", file->path);
return FALSE;
}
return TRUE;
}
CliprdrFileContext* cliprdr_file_context_new(void* context)
{
CliprdrFileContext* file = calloc(1, sizeof(CliprdrFileContext));
if (!file)
return NULL;
file->clipboard = context;
if (!create_base_path(file))
goto fail;
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
file->current_stream_id = 0;
file->stream_list = ArrayList_New(TRUE);
if (!file->stream_list)
{
WLog_ERR(TAG, "failed to allocate stream_list");
goto fail;
}
wObject* obj = ArrayList_Object(file->stream_list);
obj->fnObjectFree = free;
file->ino_list = ArrayList_New(TRUE);
if (!file->ino_list)
{
WLog_ERR(TAG, "failed to allocate stream_list");
goto fail;
}
obj = ArrayList_Object(file->ino_list);
obj->fnObjectFree = cliprdr_file_fuse_inode_free;
if (!xf_fuse_repopulate(file->ino_list))
goto fail;
if (!(file->fuse_thread = CreateThread(NULL, 0, cliprdr_file_fuse_thread, file, 0, NULL)))
{
goto fail;
}
#endif
return file;
fail:
cliprdr_file_context_free(file);
return NULL;
}
BOOL cliprdr_file_context_clear(CliprdrFileContext* file)
{
#if defined(WITH_FUSE2) || defined(WITH_FUSE3)
if (file->stream_list)
{
size_t index;
size_t count;
CliprdrFuseStream* stream;
ArrayList_Lock(file->stream_list);
file->current_stream_id = 0;
/* reply error to all req first don't care request type*/
count = ArrayList_Count(file->stream_list);
for (index = 0; index < count; index++)
{
stream = (CliprdrFuseStream*)ArrayList_GetItem(file->stream_list, index);
fuse_reply_err(stream->req, EIO);
}
ArrayList_Unlock(file->stream_list);
ArrayList_Clear(file->stream_list);
}
xf_fuse_repopulate(file->ino_list);
#endif
}