VirtualBox

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

最後變更 在這個檔案從55121是 55121,由 vboxsync 提交於 10 年 前

rdesktop 1.8.3 unmodified

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

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette