VirtualBox

source: vbox/trunk/src/VBox/RDP/client/printercache.c@ 40654

Last change on this file since 40654 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: 7.4 KB
Line 
1/* -*- c-basic-offset: 8 -*-
2 rdesktop: A Remote Desktop Protocol client.
3 Entrypoint and utility functions
4 Copyright (C) Matthew Chapman <matthewc.unsw.edu.au> 1999-2008
5 Copyright (C) Jeroen Meijer <jeroen@oldambt7.com> 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/* According to the W2K RDP Printer Redirection WhitePaper, a data
31 * blob is sent to the client after the configuration of the printer
32 * is changed at the server.
33 *
34 * This data blob is saved to the registry. The client returns this
35 * data blob in a new session with the printer announce data.
36 * The data is not interpreted by the client.
37 */
38
39#include <sys/stat.h>
40#include <sys/types.h>
41#include <errno.h>
42#include <fcntl.h>
43#include <unistd.h>
44#include <string.h>
45#include "rdesktop.h"
46
47static RD_BOOL
48printercache_mkdir(char *base, char *printer)
49{
50 char *path;
51
52 path = (char *) xmalloc(strlen(base) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) + 1);
53
54 sprintf(path, "%s/.rdesktop", base);
55 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
56 {
57 perror(path);
58 xfree(path);
59 return False;
60 }
61
62 strcat(path, "/rdpdr");
63 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
64 {
65 perror(path);
66 xfree(path);
67 return False;
68 }
69
70 strcat(path, "/");
71 strcat(path, printer);
72 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
73 {
74 perror(path);
75 xfree(path);
76 return False;
77 }
78
79 xfree(path);
80 return True;
81}
82
83static RD_BOOL
84printercache_unlink_blob(char *printer)
85{
86 char *path;
87 char *home;
88
89 if (printer == NULL)
90 return False;
91
92 home = getenv("HOME");
93 if (home == NULL)
94 return False;
95
96 path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) +
97 sizeof("/AutoPrinterCacheData") + 1);
98
99 sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer);
100
101 if (unlink(path) < 0)
102 {
103 xfree(path);
104 return False;
105 }
106
107 sprintf(path, "%s/.rdesktop/rdpdr/%s", home, printer);
108
109 if (rmdir(path) < 0)
110 {
111 xfree(path);
112 return False;
113 }
114
115 xfree(path);
116 return True;
117}
118
119
120static RD_BOOL
121printercache_rename_blob(char *printer, char *new_printer)
122{
123 char *printer_path;
124 char *new_printer_path;
125 int printer_maxlen;
126
127 char *home;
128
129 if (printer == NULL)
130 return False;
131
132 home = getenv("HOME");
133 if (home == NULL)
134 return False;
135
136 printer_maxlen =
137 (strlen(printer) >
138 strlen(new_printer) ? strlen(printer) : strlen(new_printer)) + strlen(home) +
139 sizeof("/.rdesktop/rdpdr/") + 1;
140
141 printer_path = (char *) xmalloc(printer_maxlen);
142 new_printer_path = (char *) xmalloc(printer_maxlen);
143
144 sprintf(printer_path, "%s/.rdesktop/rdpdr/%s", home, printer);
145 sprintf(new_printer_path, "%s/.rdesktop/rdpdr/%s", home, new_printer);
146
147 printf("%s,%s\n", printer_path, new_printer_path);
148 if (rename(printer_path, new_printer_path) < 0)
149 {
150 xfree(printer_path);
151 xfree(new_printer_path);
152 return False;
153 }
154
155 xfree(printer_path);
156 xfree(new_printer_path);
157 return True;
158}
159
160
161int
162printercache_load_blob(char *printer_name, uint8 ** data)
163{
164 char *home, *path;
165 struct stat st;
166 int fd, length;
167
168 if (printer_name == NULL)
169 return 0;
170
171 *data = NULL;
172
173 home = getenv("HOME");
174 if (home == NULL)
175 return 0;
176
177 path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) +
178 sizeof("/AutoPrinterCacheData") + 1);
179 sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name);
180
181 fd = open(path, O_RDONLY);
182 if (fd == -1)
183 {
184 xfree(path);
185 return 0;
186 }
187
188 if (fstat(fd, &st))
189 {
190 xfree(path);
191 return 0;
192 }
193
194 *data = (uint8 *) xmalloc(st.st_size);
195 length = read(fd, *data, st.st_size);
196 close(fd);
197 xfree(path);
198 return length;
199}
200
201static void
202printercache_save_blob(char *printer_name, uint8 * data, uint32 length)
203{
204 char *home, *path;
205 int fd;
206
207 if (printer_name == NULL)
208 return;
209
210 home = getenv("HOME");
211 if (home == NULL)
212 return;
213
214 if (!printercache_mkdir(home, printer_name))
215 return;
216
217 path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) +
218 sizeof("/AutoPrinterCacheData") + 1);
219 sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name);
220
221 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
222 if (fd == -1)
223 {
224 perror(path);
225 xfree(path);
226 return;
227 }
228
229 if (write(fd, data, length) != length)
230 {
231 perror(path);
232 unlink(path);
233 }
234
235 close(fd);
236 xfree(path);
237}
238
239void
240printercache_process(STREAM s)
241{
242 uint32 type, printer_length, driver_length, printer_unicode_length, blob_length;
243 char device_name[9], printer[256], driver[256];
244
245 in_uint32_le(s, type);
246 switch (type)
247 {
248 case 4: /* rename item */
249 in_uint8(s, printer_length);
250 in_uint8s(s, 0x3); /* padding */
251 in_uint8(s, driver_length);
252 in_uint8s(s, 0x3); /* padding */
253
254 /* NOTE - 'driver' doesn't contain driver, it contains the new printer name */
255
256 rdp_in_unistr(s, printer, sizeof(printer), printer_length);
257 rdp_in_unistr(s, driver, sizeof(driver), driver_length);
258
259 printercache_rename_blob(printer, driver);
260 break;
261
262 case 3: /* delete item */
263 in_uint8(s, printer_unicode_length);
264 in_uint8s(s, 0x3); /* padding */
265 rdp_in_unistr(s, printer, sizeof(printer), printer_unicode_length);
266 printercache_unlink_blob(printer);
267 break;
268
269 case 2: /* save printer data */
270 in_uint32_le(s, printer_unicode_length);
271 in_uint32_le(s, blob_length);
272
273 if (printer_unicode_length < 2 * 255)
274 {
275 rdp_in_unistr(s, printer, sizeof(printer), printer_unicode_length);
276 printercache_save_blob(printer, s->p, blob_length);
277 }
278 break;
279
280 case 1: /* save device data */
281 in_uint8a(s, device_name, 5); /* get LPTx/COMx name */
282
283 /* need to fetch this data so that we can get the length of the packet to store. */
284 in_uint8s(s, 0x2); /* ??? */
285 in_uint8s(s, 0x2) /* pad?? */
286 in_uint32_be(s, driver_length);
287 in_uint32_be(s, printer_length);
288 in_uint8s(s, 0x7) /* pad?? */
289 /* next is driver in unicode */
290 /* next is printer in unicode */
291 /* TODO: figure out how to use this information when reconnecting */
292 /* actually - all we need to store is the driver and printer */
293 /* and figure out what the first word is. */
294 /* rewind stream so that we can save this blob */
295 /* length is driver_length + printer_length + 19 */
296 /* rewind stream */
297 s->p = s->p - 19;
298
299 printercache_save_blob(device_name, s->p,
300 driver_length + printer_length + 19);
301 break;
302 default:
303
304 unimpl("RDPDR Printer Cache Packet Type: %d\n", type);
305 break;
306 }
307}
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