VirtualBox

source: vbox/trunk/src/VBox/RDP/client/cliprdr.c@ 50174

Last change on this file since 50174 was 37224, checked in by vboxsync, 13 years ago

RDP/client: fix OSE

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 5.4 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Protocol services - Clipboard functions
4 Copyright (C) Erik Forsberg <forsberg@cendio.se> 2003
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
128 in_uint16_le(s, type);
129 in_uint16_le(s, status);
130 in_uint32_le(s, length);
131 data = s->p;
132
133 DEBUG_CLIPBOARD(("CLIPRDR recv: type=%d, status=%d, length=%d\n", type, status, length));
134
135 if (status == CLIPRDR_ERROR)
136 {
137 switch (type)
138 {
139 case CLIPRDR_FORMAT_ACK:
140 /* FIXME: We seem to get this when we send an announce while the server is
141 still processing a paste. Try sending another announce. */
142 cliprdr_send_native_format_announce(last_formats,
143 last_formats_length);
144 break;
145 case CLIPRDR_DATA_RESPONSE:
146 ui_clip_request_failed();
147 break;
148 default:
149 DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type));
150 }
151
152 return;
153 }
154
155 switch (type)
156 {
157 case CLIPRDR_CONNECT:
158 ui_clip_sync();
159 break;
160 case CLIPRDR_FORMAT_ANNOUNCE:
161 ui_clip_format_announce(data, length);
162 cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
163 return;
164 case CLIPRDR_FORMAT_ACK:
165 break;
166 case CLIPRDR_DATA_REQUEST:
167 in_uint32_le(s, format);
168 ui_clip_request_data(format);
169 break;
170 case CLIPRDR_DATA_RESPONSE:
171 ui_clip_handle_data(data, length);
172 break;
173 case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */
174 break;
175 default:
176 unimpl("CLIPRDR packet type %d\n", type);
177 }
178}
179
180void
181cliprdr_set_mode(const char *optarg)
182{
183 ui_clip_set_mode(optarg);
184}
185
186RD_BOOL
187cliprdr_init(void)
188{
189 cliprdr_channel =
190 channel_register("cliprdr",
191 CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
192 CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
193 cliprdr_process);
194 return (cliprdr_channel != NULL);
195}
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