ReactOS 0.4.16-dev-258-g81860b4
printercache.c
Go to the documentation of this file.
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
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 along
18 * with this program; if not, write to the Free Software Foundation, Inc.,
19 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
20 */
21
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.
25 *
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.
29 */
30
31#include <sys/stat.h>
32#include <sys/types.h>
33#include <errno.h>
34#include <fcntl.h>
35#include <unistd.h>
36#include <string.h>
37#include "rdesktop.h"
38
39static BOOL
40printercache_mkdir(char *base, char *printer)
41{
42 char *path;
43
44 path = (char *) xmalloc(strlen(base) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) + 1);
45
46 sprintf(path, "%s/.rdesktop", base);
47 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
48 {
49 perror(path);
50 xfree(path);
51 return False;
52 }
53
54 strcat(path, "/rdpdr");
55 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
56 {
57 perror(path);
58 xfree(path);
59 return False;
60 }
61
62 strcat(path, "/");
63 strcat(path, printer);
64 if ((mkdir(path, 0700) == -1) && errno != EEXIST)
65 {
66 perror(path);
67 xfree(path);
68 return False;
69 }
70
71 xfree(path);
72 return True;
73}
74
75static BOOL
77{
78 char *path;
79 char *home;
80
81 if (printer == NULL)
82 return False;
83
84 home = getenv("HOME");
85 if (home == NULL)
86 return False;
87
88 path = (char *) xmalloc(strlen(home) + sizeof("/.rdesktop/rdpdr/") + strlen(printer) +
89 sizeof("/AutoPrinterCacheData") + 1);
90
91 sprintf(path, "%s/.rdesktop/rdpdr/%s/AutoPrinterCacheData", home, printer);
92
93 if (unlink(path) < 0)
94 {
95 xfree(path);
96 return False;
97 }
98
99 sprintf(path, "%s/.rdesktop/rdpdr/%s", home, printer);
100
101 if (rmdir(path) < 0)
102 {
103 xfree(path);
104 return False;
105 }
106
107 xfree(path);
108 return True;
109}
110
111
112static BOOL
113printercache_rename_blob(char *printer, char *new_printer)
114{
115 char *printer_path;
116 char *new_printer_path;
117 int printer_maxlen;
118
119 char *home;
120
121 if (printer == NULL)
122 return False;
123
124 home = getenv("HOME");
125 if (home == NULL)
126 return False;
127
128 printer_maxlen =
129 (strlen(printer) >
130 strlen(new_printer) ? strlen(printer) : strlen(new_printer)) + strlen(home) +
131 sizeof("/.rdesktop/rdpdr/") + 1;
132
133 printer_path = (char *) xmalloc(printer_maxlen);
134 new_printer_path = (char *) xmalloc(printer_maxlen);
135
136 sprintf(printer_path, "%s/.rdesktop/rdpdr/%s", home, printer);
137 sprintf(new_printer_path, "%s/.rdesktop/rdpdr/%s", home, new_printer);
138
139 printf("%s,%s\n", printer_path, new_printer_path);
140 if (rename(printer_path, new_printer_path) < 0)
141 {
142 xfree(printer_path);
143 xfree(new_printer_path);
144 return False;
145 }
146
147 xfree(printer_path);
148 xfree(new_printer_path);
149 return True;
150}
151
152
153int
154printercache_load_blob(char *printer_name, uint8 ** data)
155{
156 char *home, *path;
157 struct stat st;
158 int fd, length;
159
160 if (printer_name == NULL)
161 return 0;
162
163 *data = NULL;
164
165 home = getenv("HOME");
166 if (home == NULL)
167 return 0;
168
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);
172
173 fd = open(path, O_RDONLY);
174 if (fd == -1)
175 {
176 xfree(path);
177 return 0;
178 }
179
180 if (fstat(fd, &st))
181 {
182 xfree(path);
183 close(fd);
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
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
234{
235 uint32 type, printer_length, driver_length, printer_unicode_length, blob_length;
236 char device_name[9], printer[256], driver[256];
237
239 switch (type)
240 {
241 case 4: /* rename item */
242 in_uint8(s, printer_length);
243 in_uint8s(s, 0x3); /* padding */
244 in_uint8(s, driver_length);
245 in_uint8s(s, 0x3); /* padding */
246
247 /* NOTE - 'driver' doesn't contain driver, it contains the new printer name */
248
249 rdp_in_unistr(This, s, printer, printer_length);
250 rdp_in_unistr(This, s, driver, driver_length);
251
253 break;
254
255 case 3: /* delete item */
256 in_uint8(s, printer_unicode_length);
257 in_uint8s(s, 0x3); /* padding */
258 printer_length = rdp_in_unistr(This, s, printer, printer_unicode_length);
260 break;
261
262 case 2: /* save printer data */
263 in_uint32_le(s, printer_unicode_length);
264 in_uint32_le(s, blob_length);
265
266 if (printer_unicode_length < 2 * 255)
267 {
268 rdp_in_unistr(This, s, printer, printer_unicode_length);
269 printercache_save_blob(printer, s->p, blob_length);
270 }
271 break;
272
273 case 1: /* save device data */
274 in_uint8a(s, device_name, 5); /* get LPTx/COMx name */
275
276 /* need to fetch this data so that we can get the length of the packet to store. */
277 in_uint8s(s, 0x2); /* ??? */
278 in_uint8s(s, 0x2) /* pad?? */
279 in_uint32_be(s, driver_length);
280 in_uint32_be(s, printer_length);
281 in_uint8s(s, 0x7) /* pad?? */
282 /* next is driver in unicode */
283 /* next is printer in unicode */
284 /* TODO: figure out how to use this information when reconnecting */
285 /* actually - all we need to store is the driver and printer */
286 /* and figure out what the first word is. */
287 /* rewind stream so that we can save this blob */
288 /* length is driver_length + printer_length + 19 */
289 /* rewind stream */
290 s->p = s->p - 19;
291
293 driver_length + printer_length + 19);
294 break;
295 default:
296
297 unimpl("RDPDR Printer Cache Packet Type: %d\n", type);
298 break;
299 }
300}
#define EEXIST
Definition: acclib.h:88
char * strcat(char *DstString, const char *SrcString)
Definition: utclib.c:568
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
#define O_WRONLY
Definition: acwin.h:111
#define O_CREAT
Definition: acwin.h:110
#define mkdir
Definition: acwin.h:101
#define read
Definition: acwin.h:96
#define O_RDONLY
Definition: acwin.h:108
#define open
Definition: acwin.h:95
#define close
Definition: acwin.h:98
#define fstat
Definition: acwin.h:100
#define write
Definition: acwin.h:97
#define O_TRUNC
Definition: acwin.h:112
#define in_uint32_be(s, v)
Definition: parse.h:76
#define in_uint8a(s, v, n)
Definition: parse.h:90
#define in_uint8s(s, n)
Definition: parse.h:91
#define in_uint8(s, v)
Definition: parse.h:88
#define in_uint32_le(s, v)
Definition: parse.h:56
void xfree(void *mem)
Definition: uimain.c:758
void rdp_in_unistr(STREAM s, int in_len, char **string, uint32 *str_size)
Definition: rdp.c:265
void unimpl(char *format,...)
Definition: uimain.c:801
void * xmalloc(int size)
Definition: uimain.c:747
unsigned int uint32
Definition: types.h:32
#define False
Definition: types.h:25
#define True
Definition: types.h:24
unsigned char uint8
Definition: types.h:28
#define NULL
Definition: types.h:112
static const WCHAR device_name[]
Definition: btrfs.c:60
unsigned int BOOL
Definition: ntddk_ex.h:94
#define printf
Definition: freeldr.h:97
GLuint GLuint GLsizei GLenum type
Definition: gl.h:1545
GLdouble s
Definition: gl.h:2039
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
_CRTIMP void __cdecl perror(_In_opt_z_ const char *_ErrMsg)
_Check_return_ char *__cdecl getenv(_In_z_ const char *_VarName)
#define unlink
Definition: syshdrs.h:54
#define sprintf(buf, format,...)
Definition: sprintf.c:55
struct @1677::@1678 driver
#define rmdir
Definition: syshdrs.h:70
static BOOL printercache_rename_blob(char *printer, char *new_printer)
Definition: printercache.c:113
int printercache_load_blob(char *printer_name, uint8 **data)
Definition: printercache.c:154
void printercache_process(RDPCLIENT *This, STREAM s)
Definition: printercache.c:233
static BOOL printercache_mkdir(char *base, char *printer)
Definition: printercache.c:40
static void printercache_save_blob(char *printer_name, uint8 *data, uint32 length)
Definition: printercache.c:195
static BOOL printercache_unlink_blob(char *printer)
Definition: printercache.c:76
#define errno
Definition: errno.h:18
_Check_return_ int __cdecl rename(_In_z_ const char *_OldFilename, _In_z_ const char *_NewFilename)
static int fd
Definition: io.c:51
Definition: tftpd.h:38
Definition: stat.h:55
_off_t st_size
Definition: stat.h:63
Definition: parse.h:23