~ubuntu-branches/ubuntu/quantal/freerdp/quantal

« back to all changes in this revision

Viewing changes to channels/rdpdr/printer/printer_main.c

  • Committer: Bazaar Package Importer
  • Author(s): Otavio Salvador
  • Date: 2010-06-23 21:39:09 UTC
  • Revision ID: james.westby@ubuntu.com-20100623213909-bb9pvvv03913tdv6
Tags: upstream-0.7.1
ImportĀ upstreamĀ versionĀ 0.7.1

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- c-basic-offset: 8 -*-
 
2
   FreeRDP: A Remote Desktop Protocol client.
 
3
   Redirected Printer Device Service
 
4
 
 
5
   Copyright (C) Marc-Andre Moreau <marcandre.moreau@gmail.com> 2010
 
6
   Copyright (C) Vic Lee <llyzs@163.com> 2010
 
7
 
 
8
   This program is free software; you can redistribute it and/or modify
 
9
   it under the terms of the GNU General Public License as published by
 
10
   the Free Software Foundation; either version 2 of the License, or
 
11
   (at your option) any later version.
 
12
 
 
13
   This program is distributed in the hope that it will be useful,
 
14
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
15
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
16
   GNU General Public License for more details.
 
17
 
 
18
   You should have received a copy of the GNU General Public License
 
19
   along with this program; if not, write to the Free Software
 
20
   Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
 
21
*/
 
22
 
 
23
#include <stdio.h>
 
24
#include <stdlib.h>
 
25
#include <string.h>
 
26
#include <sys/stat.h>
 
27
#include "rdpdr_constants.h"
 
28
#include "rdpdr_types.h"
 
29
#include "devman.h"
 
30
#include "printer_main.h"
 
31
 
 
32
static char *
 
33
printer_get_filename(const char * name)
 
34
{
 
35
        char * home;
 
36
        char * filename;
 
37
        struct stat st;
 
38
 
 
39
        home = getenv("HOME");
 
40
        if (home == NULL)
 
41
                return NULL;
 
42
 
 
43
        filename = (char *) malloc(strlen(home) + strlen("/.freerdp/printer_") + strlen(name) + 1);
 
44
        sprintf(filename, "%s/.freerdp", home);
 
45
        if (stat(filename, &st) != 0)
 
46
        {
 
47
                mkdir(filename, 0700);
 
48
                LLOGLN(0, ("printer_get_filename: created %s", filename));
 
49
        }
 
50
        strcat(filename, "/printer_");
 
51
        strcat(filename, name);
 
52
        return filename;
 
53
}
 
54
 
 
55
static void
 
56
printer_save_data(const char * name, const char * data, int data_len)
 
57
{
 
58
        char * filename;
 
59
        FILE * fp;
 
60
        int len;
 
61
 
 
62
        filename = printer_get_filename(name);
 
63
        fp = fopen(filename, "w+b");
 
64
        if (fp == NULL)
 
65
        {
 
66
                LLOGLN(0, ("printer_save_data: create %s failed.", filename));
 
67
        }
 
68
        else
 
69
        {
 
70
                len = (int) fwrite(data, 1, data_len, fp);
 
71
                if (len < data_len)
 
72
                {
 
73
                        LLOGLN(0, ("printer_save_data: error writing %d bytes.", len));
 
74
                }
 
75
                fclose(fp);
 
76
        }
 
77
        free(filename);
 
78
}
 
79
 
 
80
static char *
 
81
printer_get_data(const char * name, int * len)
 
82
{
 
83
        char * buf;
 
84
        char * filename;
 
85
        FILE * fp;
 
86
        int i;
 
87
 
 
88
        filename = printer_get_filename(name);
 
89
        fp = fopen(filename, "rb");
 
90
        if (fp == NULL)
 
91
        {
 
92
                *len = 0;
 
93
                buf = NULL;
 
94
        }
 
95
        else
 
96
        {
 
97
                fseek(fp, 0, SEEK_END);
 
98
                *len = (int) ftell(fp);
 
99
                fseek(fp, 0, SEEK_SET);
 
100
                buf = (char *) malloc(*len);
 
101
                memset(buf, 0, *len);
 
102
                i = fread(buf, 1, *len, fp);
 
103
        }
 
104
        free(filename);
 
105
        return buf;
 
106
}
 
107
 
 
108
static uint32
 
109
printer_process_update_printer_event(SERVICE * srv, const char * data, int data_len)
 
110
{
 
111
        uint32 printerNameLen;
 
112
        char * printerName;
 
113
        uint32 configDataLen;
 
114
        uint32 size;
 
115
 
 
116
        printerNameLen = GET_UINT32(data, 0);
 
117
        configDataLen = GET_UINT32(data, 4);
 
118
 
 
119
        if (printerNameLen + configDataLen + 8 > data_len)
 
120
        {
 
121
                LLOGLN(0, ("printer_process_update_printer_event: expect %d+%d+8 got %d",
 
122
                        printerNameLen, configDataLen, data_len));
 
123
                return 1;
 
124
        }
 
125
        size = printerNameLen * 3 / 2 + 2;
 
126
        printerName = (char *) malloc(size);
 
127
        memset(printerName, 0, size);
 
128
        get_wstr(printerName, size, (char *)(data + 8), printerNameLen);
 
129
        LLOGLN(10, ("printer_process_update_printer_event: %s %d", printerName, configDataLen));
 
130
        printer_save_data(printerName, data + 8 + printerNameLen, configDataLen);
 
131
        free(printerName);
 
132
 
 
133
        return 0;
 
134
}
 
135
 
 
136
static uint32
 
137
printer_process_delete_printer_event(SERVICE * srv, const char * data, int data_len)
 
138
{
 
139
        uint32 printerNameLen;
 
140
        char * printerName;
 
141
        uint32 size;
 
142
        char * filename;
 
143
 
 
144
        printerNameLen = GET_UINT32(data, 0);
 
145
 
 
146
        size = printerNameLen * 3 / 2 + 2;
 
147
        printerName = (char *) malloc(size);
 
148
        memset(printerName, 0, size);
 
149
        get_wstr(printerName, size, (char *)(data + 4), printerNameLen);
 
150
 
 
151
        filename = printer_get_filename(printerName);
 
152
        remove(filename);
 
153
        LLOGLN(0, ("printer_process_delete_printer_event: %s deleted", filename));
 
154
        free(filename);
 
155
        free(printerName);
 
156
 
 
157
        return 0;
 
158
}
 
159
 
 
160
static uint32
 
161
printer_process_cache_data(SERVICE * srv, const char * data, int data_len)
 
162
{
 
163
        uint32 eventID;
 
164
 
 
165
        eventID = GET_UINT32(data, 0);
 
166
        switch (eventID)
 
167
        {
 
168
                case RDPDR_ADD_PRINTER_EVENT:
 
169
                        LLOGLN(0, ("RDPDR_ADD_PRINTER_EVENT"));
 
170
                        break;
 
171
 
 
172
                case RDPDR_UPDATE_PRINTER_EVENT:
 
173
                        LLOGLN(10, ("RDPDR_UPDATE_PRINTER_EVENT"));
 
174
                        printer_process_update_printer_event(srv, &data[4], data_len - 4);
 
175
                        break;
 
176
 
 
177
                case RDPDR_DELETE_PRINTER_EVENT:
 
178
                        LLOGLN(10, ("RDPDR_DELETE_PRINTER_EVENT"));
 
179
                        printer_process_delete_printer_event(srv, &data[4], data_len - 4);
 
180
                        break;
 
181
 
 
182
                case RDPDR_RENAME_PRINTER_EVENT:
 
183
                        LLOGLN(0, ("RDPDR_RENAME_PRINTER_EVENT"));
 
184
                        break;
 
185
 
 
186
                default:
 
187
                        LLOGLN(0, ("RDPDR printer unsupported eventID %i", eventID));
 
188
                        break;
 
189
        }
 
190
        return 0;
 
191
}
 
192
 
 
193
static uint32
 
194
printer_process_data(SERVICE * srv, int type, const char * data, int data_len)
 
195
{
 
196
        switch (type)
 
197
        {
 
198
                case PAKID_PRN_CACHE_DATA:
 
199
                        LLOGLN(10, ("PAKID_PRN_CACHE_DATA"));
 
200
                        printer_process_cache_data(srv, data, data_len);
 
201
                        break;
 
202
 
 
203
                default:
 
204
                        LLOGLN(0, ("RDPDR printer component, packetID: 0x%02X", type));
 
205
                        break;
 
206
        }
 
207
        return 0;
 
208
}
 
209
 
 
210
static SERVICE * 
 
211
printer_register_service(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints)
 
212
{
 
213
        SERVICE * srv;
 
214
 
 
215
        srv = pEntryPoints->pDevmanRegisterService(pDevman);
 
216
 
 
217
        srv->create = printer_hw_create;
 
218
        srv->close = printer_hw_close;
 
219
        srv->read = NULL;
 
220
        srv->write = printer_hw_write;
 
221
        srv->control = NULL;
 
222
        srv->query_volume_info = NULL;
 
223
        srv->query_info = NULL;
 
224
        srv->set_info = NULL;
 
225
        srv->query_directory = NULL;
 
226
        srv->notify_change_directory = NULL;
 
227
        srv->lock_control = NULL;
 
228
        srv->free = printer_free;
 
229
        srv->process_data = printer_process_data;
 
230
        srv->type = RDPDR_DTYP_PRINT;
 
231
 
 
232
        return srv;
 
233
}
 
234
 
 
235
int
 
236
printer_register(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints, SERVICE * srv,
 
237
        const char * name, const char * driver, int is_default, int * port)
 
238
{
 
239
        DEVICE * dev;
 
240
        char buf[8];
 
241
        uint32 flags;
 
242
        int size;
 
243
        int offset;
 
244
        int len;
 
245
        char * cache_data;
 
246
        int cache_data_len;
 
247
 
 
248
        LLOGLN(0, ("printer_register: %s (default=%d)", name, is_default));
 
249
 
 
250
        if (driver == NULL)
 
251
        {
 
252
                /* This is a generic PostScript printer driver developed by MS, so it should be good in most cases */
 
253
                driver = "MS Publisher Imagesetter";
 
254
        }
 
255
 
 
256
        snprintf(buf, sizeof(buf) - 1, "PRN%d", *port);
 
257
        *port += 1;
 
258
        dev = pEntryPoints->pDevmanRegisterDevice(pDevman, srv, buf);
 
259
        dev->info = printer_hw_new(name);
 
260
 
 
261
        cache_data = printer_get_data(name, &cache_data_len);
 
262
 
 
263
        size = 24 + 4 + (strlen(name) + 1) * 2 + (strlen(driver) + 1) * 2 + cache_data_len;
 
264
        dev->data = malloc(size);
 
265
        memset(dev->data, 0, size);
 
266
 
 
267
        /*flags = RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT;*/
 
268
        flags = 0;
 
269
        if (is_default)
 
270
                flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER;
 
271
 
 
272
        SET_UINT32 (dev->data, 0, flags); /* Flags */
 
273
        SET_UINT32 (dev->data, 4, 0); /* CodePage, reserved */
 
274
        SET_UINT32 (dev->data, 8, 0); /* PnPNameLen */
 
275
        SET_UINT32 (dev->data, 20, cache_data_len); /* CachedFieldsLen */
 
276
        offset = 24;
 
277
        len = set_wstr(&dev->data[offset], size - offset, (char *) driver, strlen(driver) + 1);
 
278
        SET_UINT32 (dev->data, 12, len); /* DriverNameLen */
 
279
        offset += len;
 
280
        len = set_wstr(&dev->data[offset], size - offset, (char *) name, strlen(name) + 1);
 
281
        SET_UINT32 (dev->data, 16, len); /* PrintNameLen */
 
282
        offset += len;
 
283
        if (cache_data)
 
284
        {
 
285
                memcpy(&dev->data[offset], cache_data, cache_data_len);
 
286
                offset += cache_data_len;
 
287
                free(cache_data);
 
288
        }
 
289
 
 
290
        dev->data_len = offset;
 
291
 
 
292
        return 0;
 
293
}
 
294
 
 
295
uint32
 
296
printer_free(DEVICE * dev)
 
297
{
 
298
        printer_hw_free(dev->info);
 
299
        if (dev->data)
 
300
        {
 
301
                free(dev->data);
 
302
                dev->data = NULL;
 
303
        }
 
304
        return 0;
 
305
}
 
306
 
 
307
int
 
308
DeviceServiceEntry(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints)
 
309
{
 
310
        SERVICE * srv = NULL;
 
311
        RD_PLUGIN_DATA * data;
 
312
        int port = 1;
 
313
 
 
314
        data = (RD_PLUGIN_DATA *) pEntryPoints->pExtendedData;
 
315
        while (data && data->size > 0)
 
316
        {
 
317
                if (strcmp((char*)data->data[0], "printer") == 0)
 
318
                {
 
319
                        if (srv == NULL)
 
320
                                srv = printer_register_service(pDevman, pEntryPoints);
 
321
 
 
322
                        if (data->data[1] == NULL)
 
323
                                printer_hw_register_auto(pDevman, pEntryPoints, srv, &port);
 
324
                        else
 
325
                                printer_register(pDevman, pEntryPoints, srv, data->data[1], data->data[2], (port == 1), &port);
 
326
                        break;
 
327
                }
 
328
                data = (RD_PLUGIN_DATA *) (((void *) data) + data->size);
 
329
        }
 
330
 
 
331
        return 1;
 
332
}