VirtualBox

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

Last change on this file since 17610 was 11982, checked in by vboxsync, 16 years ago

All: license header changes for 2.0 (OSE headers, add Sun GPL/LGPL disclaimer)

  • 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 2003-2007
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 2 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, write to the Free Software
19 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20*/
21
22/*
23 * Sun GPL Disclaimer: For the avoidance of doubt, except that if any license choice
24 * other than GPL or LGPL is available it will apply instead, Sun elects to use only
25 * the General Public License version 2 (GPLv2) at this time for any software where
26 * a choice of GPL license versions is made available with the language indicating
27 * that GPLv2 or any later version may be used, or where a choice of which version
28 * of the GPL is applied is otherwise unspecified.
29 */
30
31#include "rdesktop.h"
32
33#define CLIPRDR_CONNECT 1
34#define CLIPRDR_FORMAT_ANNOUNCE 2
35#define CLIPRDR_FORMAT_ACK 3
36#define CLIPRDR_DATA_REQUEST 4
37#define CLIPRDR_DATA_RESPONSE 5
38
39#define CLIPRDR_REQUEST 0
40#define CLIPRDR_RESPONSE 1
41#define CLIPRDR_ERROR 2
42
43static VCHANNEL *cliprdr_channel;
44
45static uint8 *last_formats = NULL;
46static uint32 last_formats_length = 0;
47
48static void
49cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
50{
51 STREAM s;
52
53 DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length));
54
55 s = channel_init(cliprdr_channel, length + 12);
56 out_uint16_le(s, type);
57 out_uint16_le(s, status);
58 out_uint32_le(s, length);
59 out_uint8p(s, data, length);
60 out_uint32(s, 0); /* pad? */
61 s_mark_end(s);
62 channel_send(s, cliprdr_channel);
63}
64
65/* Helper which announces our readiness to supply clipboard data
66 in a single format (such as CF_TEXT) to the RDP side.
67 To announce more than one format at a time, use
68 cliprdr_send_native_format_announce.
69 */
70void
71cliprdr_send_simple_native_format_announce(uint32 format)
72{
73 uint8 buffer[36];
74
75 DEBUG_CLIPBOARD(("cliprdr_send_simple_native_format_announce\n"));
76
77 buf_out_uint32(buffer, format);
78 memset(buffer + 4, 0, sizeof(buffer) - 4); /* description */
79 cliprdr_send_native_format_announce(buffer, sizeof(buffer));
80}
81
82/* Announces our readiness to supply clipboard data in multiple
83 formats, each denoted by a 36-byte format descriptor of
84 [ uint32 format + 32-byte description ].
85 */
86void
87cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length)
88{
89 DEBUG_CLIPBOARD(("cliprdr_send_native_format_announce\n"));
90
91 cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, formats_data,
92 formats_data_length);
93
94 if (formats_data != last_formats)
95 {
96 if (last_formats)
97 xfree(last_formats);
98
99 last_formats = xmalloc(formats_data_length);
100 memcpy(last_formats, formats_data, formats_data_length);
101 last_formats_length = formats_data_length;
102 }
103}
104
105void
106cliprdr_send_data_request(uint32 format)
107{
108 uint8 buffer[4];
109
110 DEBUG_CLIPBOARD(("cliprdr_send_data_request\n"));
111 buf_out_uint32(buffer, format);
112 cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
113}
114
115void
116cliprdr_send_data(uint8 * data, uint32 length)
117{
118 DEBUG_CLIPBOARD(("cliprdr_send_data\n"));
119 cliprdr_send_packet(CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, length);
120}
121
122static void
123cliprdr_process(STREAM s)
124{
125 uint16 type, status;
126 uint32 length, format;
127 uint8 *data;
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 (status == CLIPRDR_ERROR)
137 {
138 switch (type)
139 {
140 case CLIPRDR_FORMAT_ACK:
141 /* FIXME: We seem to get this when we send an announce while the server is
142 still processing a paste. Try sending another announce. */
143 cliprdr_send_native_format_announce(last_formats,
144 last_formats_length);
145 break;
146 case CLIPRDR_DATA_RESPONSE:
147 ui_clip_request_failed();
148 break;
149 default:
150 DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type));
151 }
152
153 return;
154 }
155
156 switch (type)
157 {
158 case CLIPRDR_CONNECT:
159 ui_clip_sync();
160 break;
161 case CLIPRDR_FORMAT_ANNOUNCE:
162 ui_clip_format_announce(data, length);
163 cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
164 return;
165 case CLIPRDR_FORMAT_ACK:
166 break;
167 case CLIPRDR_DATA_REQUEST:
168 in_uint32_le(s, format);
169 ui_clip_request_data(format);
170 break;
171 case CLIPRDR_DATA_RESPONSE:
172 ui_clip_handle_data(data, length);
173 break;
174 case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */
175 break;
176 default:
177 unimpl("CLIPRDR packet type %d\n", type);
178 }
179}
180
181void
182cliprdr_set_mode(const char *optarg)
183{
184 ui_clip_set_mode(optarg);
185}
186
187RD_BOOL
188cliprdr_init(void)
189{
190 cliprdr_channel =
191 channel_register("cliprdr",
192 CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
193 CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
194 cliprdr_process);
195 return (cliprdr_channel != NULL);
196}
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