VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.4/cliprdr.c@ 83298

Last change on this file since 83298 was 76779, checked in by vboxsync, 6 years ago

RDP: add client-1.8.4.
bugref:9356: Update rdesktop-vrdp to 1.8.4
client-1.8.4 is a Subversion copy of 1.8.3 with the upstream 1.8.3 to 1.8.4
patch applied and a couple of fixes and changes after review, namely:

  • Stopped disabling the new pointer data format for our build, as this is no

longer needed.

  • Adjusted some snprintf buffers to make GCC happy.
  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.5 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - Clipboard functions
4 Copyright 2003 Erik Forsberg <forsberg@cendio.se> for Cendio AB
5 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 2003-2008
6
7 This program is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program. If not, see <http://www.gnu.org/licenses/>.
19*/
20
21/*
22 * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
23 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
24 * the General Public License version 2 (GPLv2) at this time for any software where
25 * a choice of GPL license versions is made available with the language indicating
26 * that GPLv2 or any later version may be used, or where a choice of which version
27 * of the GPL is applied is otherwise unspecified.
28 */
29
30#include "rdesktop.h"
31
32#define CLIPRDR_CONNECT 1
33#define CLIPRDR_FORMAT_ANNOUNCE 2
34#define CLIPRDR_FORMAT_ACK 3
35#define CLIPRDR_DATA_REQUEST 4
36#define CLIPRDR_DATA_RESPONSE 5
37
38#define CLIPRDR_REQUEST 0
39#define CLIPRDR_RESPONSE 1
40#define CLIPRDR_ERROR 2
41
42static VCHANNEL *cliprdr_channel;
43
44static uint8 *last_formats = NULL;
45static uint32 last_formats_length = 0;
46
47static void
48cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
49{
50 STREAM s;
51
52 DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length));
53
54 s = channel_init(cliprdr_channel, length + 12);
55 out_uint16_le(s, type);
56 out_uint16_le(s, status);
57 out_uint32_le(s, length);
58 out_uint8p(s, data, length);
59 out_uint32(s, 0); /* pad? */
60 s_mark_end(s);
61 channel_send(s, cliprdr_channel);
62}
63
64/* Helper which announces our readiness to supply clipboard data
65 in a single format (such as CF_TEXT) to the RDP side.
66 To announce more than one format at a time, use
67 cliprdr_send_native_format_announce.
68 */
69void
70cliprdr_send_simple_native_format_announce(uint32 format)
71{
72 uint8 buffer[36];
73
74 DEBUG_CLIPBOARD(("cliprdr_send_simple_native_format_announce\n"));
75
76 buf_out_uint32(buffer, format);
77 memset(buffer + 4, 0, sizeof(buffer) - 4); /* description */
78 cliprdr_send_native_format_announce(buffer, sizeof(buffer));
79}
80
81/* Announces our readiness to supply clipboard data in multiple
82 formats, each denoted by a 36-byte format descriptor of
83 [ uint32 format + 32-byte description ].
84 */
85void
86cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length)
87{
88 DEBUG_CLIPBOARD(("cliprdr_send_native_format_announce\n"));
89
90 cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, formats_data,
91 formats_data_length);
92
93 if (formats_data != last_formats)
94 {
95 if (last_formats)
96 xfree(last_formats);
97
98 last_formats = xmalloc(formats_data_length);
99 memcpy(last_formats, formats_data, formats_data_length);
100 last_formats_length = formats_data_length;
101 }
102}
103
104void
105cliprdr_send_data_request(uint32 format)
106{
107 uint8 buffer[4];
108
109 DEBUG_CLIPBOARD(("cliprdr_send_data_request\n"));
110 buf_out_uint32(buffer, format);
111 cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
112}
113
114void
115cliprdr_send_data(uint8 * data, uint32 length)
116{
117 DEBUG_CLIPBOARD(("cliprdr_send_data\n"));
118 cliprdr_send_packet(CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, length);
119}
120
121static void
122cliprdr_process(STREAM s)
123{
124 uint16 type, status;
125 uint32 length, format;
126 uint8 *data;
127 struct stream packet = *s;
128
129 in_uint16_le(s, type);
130 in_uint16_le(s, status);
131 in_uint32_le(s, length);
132 data = s->p;
133
134 DEBUG_CLIPBOARD(("CLIPRDR recv: type=%d, status=%d, length=%d\n", type, status, length));
135
136 if (!s_check_rem(s, length))
137 {
138 rdp_protocol_error("cliprdr_process(), consume of packet from stream would overrun", &packet);
139 }
140
141 if (status == CLIPRDR_ERROR)
142 {
143 switch (type)
144 {
145 case CLIPRDR_FORMAT_ACK:
146 /* FIXME: We seem to get this when we send an announce while the server is
147 still processing a paste. Try sending another announce. */
148 cliprdr_send_native_format_announce(last_formats,
149 last_formats_length);
150 break;
151 case CLIPRDR_DATA_RESPONSE:
152 ui_clip_request_failed();
153 break;
154 default:
155 DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type));
156 }
157
158 return;
159 }
160
161 switch (type)
162 {
163 case CLIPRDR_CONNECT:
164 ui_clip_sync();
165 break;
166 case CLIPRDR_FORMAT_ANNOUNCE:
167 ui_clip_format_announce(data, length);
168 cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
169 return;
170 case CLIPRDR_FORMAT_ACK:
171 break;
172 case CLIPRDR_DATA_REQUEST:
173 in_uint32_le(s, format);
174 ui_clip_request_data(format);
175 break;
176 case CLIPRDR_DATA_RESPONSE:
177 ui_clip_handle_data(data, length);
178 break;
179 case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */
180 break;
181 default:
182 unimpl("CLIPRDR packet type %d\n", type);
183 }
184}
185
186void
187cliprdr_set_mode(const char *optarg)
188{
189 ui_clip_set_mode(optarg);
190}
191
192RD_BOOL
193cliprdr_init(void)
194{
195 cliprdr_channel =
196 channel_register("cliprdr",
197 CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
198 CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
199 cliprdr_process);
200 return (cliprdr_channel != NULL);
201}
Note: See TracBrowser for help on using the repository browser.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette