VirtualBox

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

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