VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.3/cliprdr.c@ 55121

Last change on this file since 55121 was 55121, checked in by vboxsync, 10 years ago

rdesktop 1.8.3 unmodified

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 4.9 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#include "rdesktop.h"
22
23#define CLIPRDR_CONNECT 1
24#define CLIPRDR_FORMAT_ANNOUNCE 2
25#define CLIPRDR_FORMAT_ACK 3
26#define CLIPRDR_DATA_REQUEST 4
27#define CLIPRDR_DATA_RESPONSE 5
28
29#define CLIPRDR_REQUEST 0
30#define CLIPRDR_RESPONSE 1
31#define CLIPRDR_ERROR 2
32
33static VCHANNEL *cliprdr_channel;
34
35static uint8 *last_formats = NULL;
36static uint32 last_formats_length = 0;
37
38static void
39cliprdr_send_packet(uint16 type, uint16 status, uint8 * data, uint32 length)
40{
41 STREAM s;
42
43 DEBUG_CLIPBOARD(("CLIPRDR send: type=%d, status=%d, length=%d\n", type, status, length));
44
45 s = channel_init(cliprdr_channel, length + 12);
46 out_uint16_le(s, type);
47 out_uint16_le(s, status);
48 out_uint32_le(s, length);
49 out_uint8p(s, data, length);
50 out_uint32(s, 0); /* pad? */
51 s_mark_end(s);
52 channel_send(s, cliprdr_channel);
53}
54
55/* Helper which announces our readiness to supply clipboard data
56 in a single format (such as CF_TEXT) to the RDP side.
57 To announce more than one format at a time, use
58 cliprdr_send_native_format_announce.
59 */
60void
61cliprdr_send_simple_native_format_announce(uint32 format)
62{
63 uint8 buffer[36];
64
65 DEBUG_CLIPBOARD(("cliprdr_send_simple_native_format_announce\n"));
66
67 buf_out_uint32(buffer, format);
68 memset(buffer + 4, 0, sizeof(buffer) - 4); /* description */
69 cliprdr_send_native_format_announce(buffer, sizeof(buffer));
70}
71
72/* Announces our readiness to supply clipboard data in multiple
73 formats, each denoted by a 36-byte format descriptor of
74 [ uint32 format + 32-byte description ].
75 */
76void
77cliprdr_send_native_format_announce(uint8 * formats_data, uint32 formats_data_length)
78{
79 DEBUG_CLIPBOARD(("cliprdr_send_native_format_announce\n"));
80
81 cliprdr_send_packet(CLIPRDR_FORMAT_ANNOUNCE, CLIPRDR_REQUEST, formats_data,
82 formats_data_length);
83
84 if (formats_data != last_formats)
85 {
86 if (last_formats)
87 xfree(last_formats);
88
89 last_formats = xmalloc(formats_data_length);
90 memcpy(last_formats, formats_data, formats_data_length);
91 last_formats_length = formats_data_length;
92 }
93}
94
95void
96cliprdr_send_data_request(uint32 format)
97{
98 uint8 buffer[4];
99
100 DEBUG_CLIPBOARD(("cliprdr_send_data_request\n"));
101 buf_out_uint32(buffer, format);
102 cliprdr_send_packet(CLIPRDR_DATA_REQUEST, CLIPRDR_REQUEST, buffer, sizeof(buffer));
103}
104
105void
106cliprdr_send_data(uint8 * data, uint32 length)
107{
108 DEBUG_CLIPBOARD(("cliprdr_send_data\n"));
109 cliprdr_send_packet(CLIPRDR_DATA_RESPONSE, CLIPRDR_RESPONSE, data, length);
110}
111
112static void
113cliprdr_process(STREAM s)
114{
115 uint16 type, status;
116 uint32 length, format;
117 uint8 *data;
118
119 in_uint16_le(s, type);
120 in_uint16_le(s, status);
121 in_uint32_le(s, length);
122 data = s->p;
123
124 DEBUG_CLIPBOARD(("CLIPRDR recv: type=%d, status=%d, length=%d\n", type, status, length));
125
126 if (status == CLIPRDR_ERROR)
127 {
128 switch (type)
129 {
130 case CLIPRDR_FORMAT_ACK:
131 /* FIXME: We seem to get this when we send an announce while the server is
132 still processing a paste. Try sending another announce. */
133 cliprdr_send_native_format_announce(last_formats,
134 last_formats_length);
135 break;
136 case CLIPRDR_DATA_RESPONSE:
137 ui_clip_request_failed();
138 break;
139 default:
140 DEBUG_CLIPBOARD(("CLIPRDR error (type=%d)\n", type));
141 }
142
143 return;
144 }
145
146 switch (type)
147 {
148 case CLIPRDR_CONNECT:
149 ui_clip_sync();
150 break;
151 case CLIPRDR_FORMAT_ANNOUNCE:
152 ui_clip_format_announce(data, length);
153 cliprdr_send_packet(CLIPRDR_FORMAT_ACK, CLIPRDR_RESPONSE, NULL, 0);
154 return;
155 case CLIPRDR_FORMAT_ACK:
156 break;
157 case CLIPRDR_DATA_REQUEST:
158 in_uint32_le(s, format);
159 ui_clip_request_data(format);
160 break;
161 case CLIPRDR_DATA_RESPONSE:
162 ui_clip_handle_data(data, length);
163 break;
164 case 7: /* TODO: W2K3 SP1 sends this on connect with a value of 1 */
165 break;
166 default:
167 unimpl("CLIPRDR packet type %d\n", type);
168 }
169}
170
171void
172cliprdr_set_mode(const char *optarg)
173{
174 ui_clip_set_mode(optarg);
175}
176
177RD_BOOL
178cliprdr_init(void)
179{
180 cliprdr_channel =
181 channel_register("cliprdr",
182 CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP |
183 CHANNEL_OPTION_COMPRESS_RDP | CHANNEL_OPTION_SHOW_PROTOCOL,
184 cliprdr_process);
185 return (cliprdr_channel != NULL);
186}
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