x11/cliprdr: negotiate file streaming support

Now that we've got everything in place to handle files it's time to tell
the server that we can actually do this.

MS-RDPECLIP 3.2.5.1.3 Sending a Client Clipboard Capabilities PDU asks
us politely to not advertise file clipping support if the server did not
do that itself. Thus we need to parse the capabilities sent by the
server and take a note whether it supports file clipping.

There is also no point in advertising file clipping support if
wClipboard failed to initalize any local file subsystem, in which case
we cannot handle files for real. Take a note of this as well when we
register the file formats.

If everthing is really in place and the stars shine upon us then we are
allowed to set CB_STREAM_FILECLIP_ENABLED in the capabilities. There is
no command line switch to disable file clipping (and there is little
reason to), so we always support it if we can.

We also set an additional flag CB_FILECLIP_NO_FILE_PATHS flag in the
capabilities because it seems to be necessary for the server to send the
"FileGroupDescriptorW" format to us. Otherwise the server will only send
the old CF_HDROP format which can't be handled well without enabled disk
drive redirection and a properly negotiated server-side temporary
directory.
This commit is contained in:
ilammy 2017-04-09 02:29:51 +03:00
parent 401bf8b0af
commit b9ab82214a
1 changed files with 35 additions and 1 deletions

View File

@ -104,6 +104,10 @@ struct xf_clipboard
int xfixes_event_base;
int xfixes_error_base;
BOOL xfixes_supported;
/* File clipping */
BOOL streams_supported;
BOOL file_formats_registered;
};
UINT xf_cliprdr_send_client_format_list(xfClipboard* clipboard);
@ -1072,6 +1076,11 @@ UINT xf_cliprdr_send_client_capabilities(xfClipboard* clipboard)
generalCapabilitySet.capabilitySetLength = 12;
generalCapabilitySet.version = CB_CAPS_VERSION_2;
generalCapabilitySet.generalFlags = CB_USE_LONG_FORMAT_NAMES;
if (clipboard->streams_supported && clipboard->file_formats_registered)
generalCapabilitySet.generalFlags |=
CB_STREAM_FILECLIP_ENABLED | CB_FILECLIP_NO_FILE_PATHS;
return clipboard->context->ClientCapabilities(clipboard->context,
&capabilities);
}
@ -1167,7 +1176,31 @@ static UINT xf_cliprdr_monitor_ready(CliprdrClientContext* context,
static UINT xf_cliprdr_server_capabilities(CliprdrClientContext* context,
CLIPRDR_CAPABILITIES* capabilities)
{
//xfClipboard* clipboard = (xfClipboard*) context->custom;
UINT32 i;
const CLIPRDR_CAPABILITY_SET* caps;
const CLIPRDR_GENERAL_CAPABILITY_SET* generalCaps;
const BYTE* capsPtr = (const BYTE*) capabilities->capabilitySets;
xfClipboard* clipboard = (xfClipboard*) context->custom;
clipboard->streams_supported = FALSE;
for (i = 0; i < capabilities->cCapabilitiesSets; i++)
{
caps = (const CLIPRDR_CAPABILITY_SET*) capsPtr;
if (caps->capabilitySetType == CB_CAPSTYPE_GENERAL)
{
generalCaps = (const CLIPRDR_GENERAL_CAPABILITY_SET*) caps;
if (generalCaps->generalFlags & CB_STREAM_FILECLIP_ENABLED)
{
clipboard->streams_supported = TRUE;
}
}
capsPtr += caps->capabilitySetLength;
}
return CHANNEL_RC_OK;
}
@ -1677,6 +1710,7 @@ xfClipboard* xf_clipboard_new(xfContext* xfc)
*/
if (ClipboardGetFormatId(clipboard->system, "text/uri-list"))
{
clipboard->file_formats_registered = TRUE;
clipboard->clientFormats[n].atom = XInternAtom(xfc->display, "text/uri-list", False);
clipboard->clientFormats[n].formatId = CB_FORMAT_TEXTURILIST;
clipboard->clientFormats[n].formatName = _strdup("FileGroupDescriptorW");