VirtualBox

source: vbox/trunk/src/VBox/RDP/client-1.8.3/printercache.c@ 72086

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

rdesktop 1.8.3 modified for VBox

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
File size: 7.6 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 <[email protected]> 2003-2008
6 Copyright (C) Henrik Andersson <[email protected]> 2013
7
8
9 This program is free software: you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation, either version 3 of the License, or
12 (at your option) any later version.
13
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
18
19 You should have received a copy of the GNU General Public License
20 along with this program. If not, see <http://www.gnu.org/licenses/>.
21*/
22
23/*
24 * Oracle GPL Disclaimer: For the avoidance of doubt, except that if any license choice
25 * other than GPL or LGPL is available it will apply instead, Oracle elects to use only
26 * the General Public License version 2 (GPLv2) at this time for any software where
27 * a choice of GPL license versions is made available with the language indicating
28 * that GPLv2 or any later version may be used, or where a choice of which version
29 * of the GPL is applied is otherwise unspecified.
30 */
31
32/* According to the W2K RDP Printer Redirection WhitePaper, a data
33 * blob is sent to the client after the configuration of the printer
34 * is changed at the server.
35 *
36 * This data blob is saved to the registry. The client returns this
37 * data blob in a new session with the printer announce data.
38 * The data is not interpreted by the client.
39 */
40
41#include <sys/stat.h>
42#include <sys/types.h>
43#include <errno.h>
44#include <fcntl.h>
45#include <unistd.h>
46#include <string.h>
47#include "rdesktop.h"
48
49static RD_BOOL
50printercache_mkdir(char *base, char *printer)
51{
52 char *path;
53
54 path = (char *) xmalloc(strlen(base) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) + 1);
55
56 sprintf(path, "%s/.rdesktop", base);
57 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
58 {
59 perror(path);
60 xfree(path);
61 return False;
62 }
63
64 strcat(path, "/rdpdr");
65 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
66 {
67 perror(path);
68 xfree(path);
69 return False;
70 }
71
72 strcat(path, "/");
73 strcat(path, printer);
74 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
75 {
76 perror(path);
77 xfree(path);
78 return False;
79 }
80
81 xfree(path);
82 return True;
83}
84
85static RD_BOOL
86printercache_unlink_blob(char *printer)
87{
88 char *path;
89 char *home;
90
91 if (printer == NULL)
92 return False;
93
94 home = getenv("HOME");
95 if (home == NULL)
96 return False;
97
98 path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) +
99 sizeof("/AutoPrinterCacheData") + 1);
100
101 sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer);
102
103 if (unlink(path) < 0)
104 {
105 xfree(path);
106 return False;
107 }
108
109 sprintf(path, "%s/.rdesktop/rdpdr/%s", home, printer);
110
111 if (rmdir(path) < 0)
112 {
113 xfree(path);
114 return False;
115 }
116
117 xfree(path);
118 return True;
119}
120
121
122static RD_BOOL
123printercache_rename_blob(char *printer, char *new_printer)
124{
125 char *printer_path;
126 char *new_printer_path;
127 int printer_maxlen;
128
129 char *home;
130
131 if (printer == NULL)
132 return False;
133
134 home = getenv("HOME");
135 if (home == NULL)
136 return False;
137
138 printer_maxlen =
139 (strlen(printer) >
140 strlen(new_printer) ? strlen(printer) : strlen(new_printer)) + strlen(home) +
141 sizeof("/.rdesktop/rdpdr/") + 1;
142
143 printer_path = (char *) xmalloc(printer_maxlen);
144 new_printer_path = (char *) xmalloc(printer_maxlen);
145
146 sprintf(printer_path, "%s/.rdesktop/rdpdr/%s", home, printer);
147 sprintf(new_printer_path, "%s/.rdesktop/rdpdr/%s", home, new_printer);
148
149 printf("%s,%s\n", printer_path, new_printer_path);
150 if (rename(printer_path, new_printer_path) < 0)
151 {
152 xfree(printer_path);
153 xfree(new_printer_path);
154 return False;
155 }
156
157 xfree(printer_path);
158 xfree(new_printer_path);
159 return True;
160}
161
162
163int
164printercache_load_blob(char *printer_name, uint8 ** data)
165{
166 char *home, *path;
167 struct stat st;
168 int fd, length;
169
170 if (printer_name == NULL)
171 return 0;
172
173 *data = NULL;
174
175 home = getenv("HOME");
176 if (home == NULL)
177 return 0;
178
179 path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) +
180 sizeof("/AutoPrinterCacheData") + 1);
181 sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name);
182
183 fd = open(path, O_RDONLY);
184 if (fd == -1)
185 {
186 xfree(path);
187 return 0;
188 }
189
190 if (fstat(fd, &st))
191 {
192 xfree(path);
193 return 0;
194 }
195
196 *data = (uint8 *) xmalloc(st.st_size);
197 length = read(fd, *data, st.st_size);
198 close(fd);
199 xfree(path);
200 return length;
201}
202
203static void
204printercache_save_blob(char *printer_name, uint8 * data, uint32 length)
205{
206 char *home, *path;
207 int fd;
208
209 if (printer_name == NULL)
210 return;
211
212 home = getenv("HOME");
213 if (home == NULL)
214 return;
215
216 if (!printercache_mkdir(home, printer_name))
217 return;
218
219 path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name) +
220 sizeof("/AutoPrinterCacheData") + 1);
221 sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer_name);
222
223 fd = open(path, O_WRONLY | O_CREAT | O_TRUNC, 0600);
224 if (fd == -1)
225 {
226 perror(path);
227 xfree(path);
228 return;
229 }
230
231 if (write(fd, data, length) != length)
232 {
233 perror(path);
234 unlink(path);
235 }
236
237 close(fd);
238 xfree(path);
239}
240
241void
242printercache_process(STREAM s)
243{
244 uint32 type, printer_length, driver_length, printer_unicode_length, blob_length;
245 char device_name[9], *printer, *driver;
246
247 printer = driver = NULL;
248
249 in_uint32_le(s, type);
250 switch (type)
251 {
252 case 4: /* rename item */
253 in_uint8(s, printer_length);
254 in_uint8s(s, 0x3); /* padding */
255 in_uint8(s, driver_length);
256 in_uint8s(s, 0x3); /* padding */
257
258 /* NOTE - 'driver' doesn't contain driver, it contains the new printer name */
259
260 rdp_in_unistr(s, printer_length, &printer, &printer_length);
261 rdp_in_unistr(s, driver_length, &driver, &driver_length);
262
263 if (printer != NULL && driver != NULL)
264 printercache_rename_blob(printer, driver);
265
266 free(printer);
267 free(driver);
268 break;
269
270 case 3: /* delete item */
271 in_uint8(s, printer_unicode_length);
272 in_uint8s(s, 0x3); /* padding */
273 rdp_in_unistr(s, printer_unicode_length, &printer, &printer_unicode_length);
274 if (printer)
275 printercache_unlink_blob(printer);
276 free(printer);
277 break;
278
279 case 2: /* save printer data */
280 in_uint32_le(s, printer_unicode_length);
281 in_uint32_le(s, blob_length);
282
283 if (printer_unicode_length < 2 * 255)
284 {
285 rdp_in_unistr(s, printer_unicode_length, &printer,
286 &printer_unicode_length);
287 if (printer)
288 printercache_save_blob(printer, s->p, blob_length);
289 free(printer);
290 }
291 break;
292
293 case 1: /* save device data */
294 in_uint8a(s, device_name, 5); /* get LPTx/COMx name */
295
296 /* need to fetch this data so that we can get the length of the packet to store. */
297 in_uint8s(s, 0x2); /* ??? */
298 in_uint8s(s, 0x2) /* pad?? */
299 in_uint32_be(s, driver_length);
300 in_uint32_be(s, printer_length);
301 in_uint8s(s, 0x7) /* pad?? */
302 /* next is driver in unicode */
303 /* next is printer in unicode */
304 /* TODO: figure out how to use this information when reconnecting */
305 /* actually - all we need to store is the driver and printer */
306 /* and figure out what the first word is. */
307 /* rewind stream so that we can save this blob */
308 /* length is driver_length + printer_length + 19 */
309 /* rewind stream */
310 s->p = s->p - 19;
311
312 printercache_save_blob(device_name, s->p,
313 driver_length + printer_length + 19);
314 break;
315 default:
316
317 unimpl("RDPDR Printer Cache Packet Type: %d\n", type);
318 break;
319 }
320}
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