1 /* -*- c-basic-offset: 8 -*-
2 * rdesktop: A Remote Desktop Protocol client.
3 * Entrypoint and utility functions
4 * Copyright (C) Matthew Chapman 1999-2005
5 * Copyright (C) Jeroen Meijer 2003
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.
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.
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.
22 /* According to the W2K RDP Printer Redirection WhitePaper, a data
23 * blob is sent to the client after the configuration of the printer
24 * is changed at the server.
26 * This data blob is saved to the registry. The client returns this
27 * data blob in a new session with the printer announce data.
28 * The data is not interpreted by the client.
32 #include <sys/types.h>
40 printercache_mkdir(char *base
, char *printer
)
44 path
= (char *) xmalloc(strlen(base
) + sizeof("/.rdesktop/rdpdr/") + strlen(printer
) + 1);
46 sprintf(path
, "%s/.rdesktop", base
);
47 if ((mkdir(path
, 0700) == -1) && errno
!= EEXIST
)
54 strcat(path
, "/rdpdr");
55 if ((mkdir(path
, 0700) == -1) && errno
!= EEXIST
)
63 strcat(path
, printer
);
64 if ((mkdir(path
, 0700) == -1) && errno
!= EEXIST
)
76 printercache_unlink_blob(char *printer
)
84 home
= getenv("HOME");
88 path
= (char *) xmalloc(strlen(home
) + sizeof("/.rdesktop/rdpdr/") + strlen(printer
) +
89 sizeof("/AutoPrinterCacheData") + 1);
91 sprintf(path
, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home
, printer
);
99 sprintf(path
, "%s/.rdesktop/rdpdr/%s", home
, printer
);
113 printercache_rename_blob(char *printer
, char *new_printer
)
116 char *new_printer_path
;
124 home
= getenv("HOME");
130 strlen(new_printer
) ? strlen(printer
) : strlen(new_printer
)) + strlen(home
) +
131 sizeof("/.rdesktop/rdpdr/") + 1;
133 printer_path
= (char *) xmalloc(printer_maxlen
);
134 new_printer_path
= (char *) xmalloc(printer_maxlen
);
136 sprintf(printer_path
, "%s/.rdesktop/rdpdr/%s", home
, printer
);
137 sprintf(new_printer_path
, "%s/.rdesktop/rdpdr/%s", home
, new_printer
);
139 printf("%s,%s\n", printer_path
, new_printer_path
);
140 if (rename(printer_path
, new_printer_path
) < 0)
143 xfree(new_printer_path
);
148 xfree(new_printer_path
);
154 printercache_load_blob(char *printer_name
, uint8
** data
)
160 if (printer_name
== NULL
)
165 home
= getenv("HOME");
169 path
= (char *) xmalloc(strlen(home
) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name
) +
170 sizeof("/AutoPrinterCacheData") + 1);
171 sprintf(path
, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home
, printer_name
);
173 fd
= open(path
, O_RDONLY
);
186 *data
= (uint8
*) xmalloc(st
.st_size
);
187 length
= read(fd
, *data
, st
.st_size
);
194 printercache_save_blob(char *printer_name
, uint8
* data
, uint32 length
)
199 if (printer_name
== NULL
)
202 home
= getenv("HOME");
206 if (!printercache_mkdir(home
, printer_name
))
209 path
= (char *) xmalloc(strlen(home
) + sizeof("/.rdesktop/rdpdr/") + strlen(printer_name
) +
210 sizeof("/AutoPrinterCacheData") + 1);
211 sprintf(path
, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home
, printer_name
);
213 fd
= open(path
, O_WRONLY
| O_CREAT
| O_TRUNC
, 0600);
221 if (write(fd
, data
, length
) != length
)
232 printercache_process(RDPCLIENT
* This
, STREAM s
)
234 uint32 type
, printer_length
, driver_length
, printer_unicode_length
, blob_length
;
235 char device_name
[9], printer
[256], driver
[256];
237 in_uint32_le(s
, type
);
240 case 4: /* rename item */
241 in_uint8(s
, printer_length
);
242 in_uint8s(s
, 0x3); /* padding */
243 in_uint8(s
, driver_length
);
244 in_uint8s(s
, 0x3); /* padding */
246 /* NOTE - 'driver' doesn't contain driver, it contains the new printer name */
248 rdp_in_unistr(This
, s
, printer
, printer_length
);
249 rdp_in_unistr(This
, s
, driver
, driver_length
);
251 printercache_rename_blob(printer
, driver
);
254 case 3: /* delete item */
255 in_uint8(s
, printer_unicode_length
);
256 in_uint8s(s
, 0x3); /* padding */
257 printer_length
= rdp_in_unistr(This
, s
, printer
, printer_unicode_length
);
258 printercache_unlink_blob(printer
);
261 case 2: /* save printer data */
262 in_uint32_le(s
, printer_unicode_length
);
263 in_uint32_le(s
, blob_length
);
265 if (printer_unicode_length
< 2 * 255)
267 rdp_in_unistr(This
, s
, printer
, printer_unicode_length
);
268 printercache_save_blob(printer
, s
->p
, blob_length
);
272 case 1: /* save device data */
273 in_uint8a(s
, device_name
, 5); /* get LPTx/COMx name */
275 /* need to fetch this data so that we can get the length of the packet to store. */
276 in_uint8s(s
, 0x2); /* ??? */
277 in_uint8s(s
, 0x2) /* pad?? */
278 in_uint32_be(s
, driver_length
);
279 in_uint32_be(s
, printer_length
);
280 in_uint8s(s
, 0x7) /* pad?? */
281 /* next is driver in unicode */
282 /* next is printer in unicode */
283 /* TODO: figure out how to use this information when reconnecting */
284 /* actually - all we need to store is the driver and printer */
285 /* and figure out what the first word is. */
286 /* rewind stream so that we can save this blob */
287 /* length is driver_length + printer_length + 19 */
291 printercache_save_blob(device_name
, s
->p
,
292 driver_length
+ printer_length
+ 19);
296 unimpl("RDPDR Printer Cache Packet Type: %d\n", type
);