~ubuntu-branches/ubuntu/wily/freerdp/wily-proposed

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): Martin Pitt, Jeremy Bicha, Jean-Louis Dupond, Martin Pitt
  • Date: 2012-01-31 10:02:14 UTC
  • mfrom: (1.1.6)
  • Revision ID: package-import@ubuntu.com-20120131100214-jaok3uwvni7sqxth
Tags: 1.0.0-0git1
Upload current Debian packaging git to get this rolling for precise.

[ Jeremy Bicha ]
* New upstream release. Closes: #647498.
* Updated symbols and bumped soname
* debian/control:
  - Added new build dependencies
  - Bump Standards-Version to 3.9.2
* debian/source/format: Set to 3.0 (quilt)
* debian/rules: Turn on strict symbols checking
* debian/watch: Watch github

[ Jean-Louis Dupond ]
* debian/control: Updated homepage
* debian/copyright: Reflect upstream switch to the Apache license

[ Martin Pitt ]
* debian/libfreerdp0.symbols: Fix version number, should
  be 1.0~beta5, not 1.0-beta5.
* debian/control: Add libavcodec-dev build dependency, upstream build system
  checks for that. Thanks Jean-Louis Dupond!

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
 
 
 
1
/**
 
2
 * FreeRDP: A Remote Desktop Protocol client.
 
3
 * Print Virtual Channel
 
4
 *
 
5
 * Copyright 2010-2011 Vic Lee
 
6
 *
 
7
 * Licensed under the Apache License, Version 2.0 (the "License");
 
8
 * you may not use this file except in compliance with the License.
 
9
 * You may obtain a copy of the License at
 
10
 *
 
11
 *     http://www.apache.org/licenses/LICENSE-2.0
 
12
 *
 
13
 * Unless required by applicable law or agreed to in writing, software
 
14
 * distributed under the License is distributed on an "AS IS" BASIS,
 
15
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
16
 * See the License for the specific language governing permissions and
 
17
 * limitations under the License.
 
18
 */
 
19
 
 
20
#include "config.h"
23
21
#include <stdio.h>
24
22
#include <stdlib.h>
25
23
#include <string.h>
26
 
#include <sys/stat.h>
 
24
#include <freerdp/utils/stream.h>
 
25
#include <freerdp/utils/unicode.h>
 
26
#include <freerdp/utils/memory.h>
 
27
#include <freerdp/utils/thread.h>
 
28
#include <freerdp/utils/svc_plugin.h>
 
29
 
27
30
#include "rdpdr_constants.h"
28
31
#include "rdpdr_types.h"
29
 
#include "devman.h"
 
32
 
 
33
#ifdef CUPS_FOUND
 
34
#include "printer_cups.h"
 
35
#endif
 
36
 
30
37
#include "printer_main.h"
31
38
 
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;
 
39
typedef struct _PRINTER_DEVICE PRINTER_DEVICE;
 
40
struct _PRINTER_DEVICE
 
41
{
 
42
        DEVICE device;
 
43
 
 
44
        rdpPrinter* printer;
 
45
 
 
46
        LIST* irp_list;
 
47
        freerdp_thread* thread;
 
48
};
 
49
 
 
50
static void printer_process_irp_create(PRINTER_DEVICE* printer_dev, IRP* irp)
 
51
{
 
52
        rdpPrintJob* printjob = NULL;
 
53
 
 
54
        if (printer_dev->printer != NULL)
 
55
                printjob = printer_dev->printer->CreatePrintJob(printer_dev->printer, irp->devman->id_sequence++);
 
56
 
 
57
        if (printjob != NULL)
 
58
        {
 
59
                stream_write_uint32(irp->output, printjob->id); /* FileId */
 
60
 
 
61
                DEBUG_SVC("printjob id: %d", printjob->id);
 
62
        }
 
63
        else
 
64
        {
 
65
                stream_write_uint32(irp->output, 0); /* FileId */
 
66
                irp->IoStatus = STATUS_PRINT_QUEUE_FULL;
 
67
 
 
68
                DEBUG_WARN("error creating print job.");
 
69
        }
 
70
 
 
71
        irp->Complete(irp);
 
72
}
 
73
 
 
74
static void printer_process_irp_close(PRINTER_DEVICE* printer_dev, IRP* irp)
 
75
{
 
76
        rdpPrintJob* printjob = NULL;
 
77
 
 
78
        if (printer_dev->printer != NULL)
 
79
                printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId);
 
80
 
 
81
        if (printjob == NULL)
 
82
        {
 
83
                irp->IoStatus = STATUS_UNSUCCESSFUL;
 
84
 
 
85
                DEBUG_WARN("printjob id %d not found.", irp->FileId);
 
86
        }
 
87
        else
 
88
        {
 
89
                printjob->Close(printjob);
 
90
 
 
91
                DEBUG_SVC("printjob id %d closed.", irp->FileId);
 
92
        }
 
93
 
 
94
        stream_write_zero(irp->output, 4); /* Padding(4) */
 
95
 
 
96
        irp->Complete(irp);
 
97
}
 
98
 
 
99
static void printer_process_irp_write(PRINTER_DEVICE* printer_dev, IRP* irp)
 
100
{
 
101
        rdpPrintJob* printjob = NULL;
 
102
        uint32 Length;
 
103
        uint64 Offset;
 
104
 
 
105
        stream_read_uint32(irp->input, Length);
 
106
        stream_read_uint64(irp->input, Offset);
 
107
        stream_seek(irp->input, 20); /* Padding */
 
108
 
 
109
        if (printer_dev->printer != NULL)
 
110
                printjob = printer_dev->printer->FindPrintJob(printer_dev->printer, irp->FileId);
 
111
 
 
112
        if (printjob == NULL)
 
113
        {
 
114
                irp->IoStatus = STATUS_UNSUCCESSFUL;
 
115
                Length = 0;
 
116
 
 
117
                DEBUG_WARN("printjob id %d not found.", irp->FileId);
 
118
        }
 
119
        else
 
120
        {
 
121
                printjob->Write(printjob, stream_get_tail(irp->input), Length);
 
122
 
 
123
                DEBUG_SVC("printjob id %d written %d bytes.", irp->FileId, Length);
 
124
        }
 
125
 
 
126
        stream_write_uint32(irp->output, Length);
 
127
        stream_write_uint8(irp->output, 0); /* Padding */
 
128
 
 
129
        irp->Complete(irp);
 
130
}
 
131
 
 
132
static void printer_process_irp(PRINTER_DEVICE* printer_dev, IRP* irp)
 
133
{
 
134
        switch (irp->MajorFunction)
 
135
        {
 
136
                case IRP_MJ_CREATE:
 
137
                        printer_process_irp_create(printer_dev, irp);
 
138
                        break;
 
139
 
 
140
                case IRP_MJ_CLOSE:
 
141
                        printer_process_irp_close(printer_dev, irp);
 
142
                        break;
 
143
 
 
144
                case IRP_MJ_WRITE:
 
145
                        printer_process_irp_write(printer_dev, irp);
 
146
                        break;
 
147
 
 
148
                default:
 
149
                        DEBUG_WARN("MajorFunction 0x%X not supported", irp->MajorFunction);
 
150
                        irp->IoStatus = STATUS_NOT_SUPPORTED;
 
151
                        irp->Complete(irp);
 
152
                        break;
 
153
        }
 
154
}
 
155
 
 
156
static void printer_process_irp_list(PRINTER_DEVICE* printer_dev)
 
157
{
 
158
        IRP* irp;
 
159
 
 
160
        while (1)
 
161
        {
 
162
                if (freerdp_thread_is_stopped(printer_dev->thread))
 
163
                        break;
 
164
 
 
165
                freerdp_thread_lock(printer_dev->thread);
 
166
                irp = (IRP*)list_dequeue(printer_dev->irp_list);
 
167
                freerdp_thread_unlock(printer_dev->thread);
 
168
 
 
169
                if (irp == NULL)
 
170
                        break;
 
171
 
 
172
                printer_process_irp(printer_dev, irp);
 
173
        }
 
174
}
 
175
 
 
176
static void* printer_thread_func(void* arg)
 
177
{
 
178
        PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)arg;
 
179
 
 
180
        while (1)
 
181
        {
 
182
                freerdp_thread_wait(printer_dev->thread);
 
183
 
 
184
                if (freerdp_thread_is_stopped(printer_dev->thread))
 
185
                        break;
 
186
 
 
187
                freerdp_thread_reset(printer_dev->thread);
 
188
                printer_process_irp_list(printer_dev);
 
189
        }
 
190
 
 
191
        freerdp_thread_quit(printer_dev->thread);
 
192
 
 
193
        return NULL;
 
194
}
 
195
 
 
196
static void printer_irp_request(DEVICE* device, IRP* irp)
 
197
{
 
198
        PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)device;
 
199
 
 
200
        freerdp_thread_lock(printer_dev->thread);
 
201
        list_enqueue(printer_dev->irp_list, irp);
 
202
        freerdp_thread_unlock(printer_dev->thread);
 
203
 
 
204
        freerdp_thread_signal(printer_dev->thread);
 
205
}
 
206
 
 
207
static void printer_free(DEVICE* device)
 
208
{
 
209
        PRINTER_DEVICE* printer_dev = (PRINTER_DEVICE*)device;
 
210
        IRP* irp;
 
211
 
 
212
        freerdp_thread_stop(printer_dev->thread);
 
213
        freerdp_thread_free(printer_dev->thread);
 
214
        
 
215
        while ((irp = (IRP*)list_dequeue(printer_dev->irp_list)) != NULL)
 
216
                irp->Discard(irp);
 
217
        list_free(printer_dev->irp_list);
 
218
 
 
219
        if (printer_dev->printer)
 
220
                printer_dev->printer->Free(printer_dev->printer);
 
221
 
 
222
        xfree(printer_dev->device.name);
 
223
 
 
224
        xfree(printer_dev);
 
225
}
 
226
 
 
227
void printer_register(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints, rdpPrinter* printer)
 
228
{
 
229
        PRINTER_DEVICE* printer_dev;
 
230
        char* port;
 
231
        UNICONV* uniconv;
 
232
        uint32 Flags;
 
233
        size_t DriverNameLen;
 
234
        char* DriverName;
 
235
        size_t PrintNameLen;
 
236
        char* PrintName;
 
237
        uint32 CachedFieldsLen;
 
238
        uint8* CachedPrinterConfigData;
 
239
 
 
240
        port = xmalloc(10);
 
241
        snprintf(port, 10, "PRN%d", printer->id);
 
242
 
 
243
        printer_dev = xnew(PRINTER_DEVICE);
 
244
 
 
245
        printer_dev->device.type = RDPDR_DTYP_PRINT;
 
246
        printer_dev->device.name = port;
 
247
        printer_dev->device.IRPRequest = printer_irp_request;
 
248
        printer_dev->device.Free = printer_free;
 
249
 
 
250
        printer_dev->printer = printer;
 
251
 
 
252
        CachedFieldsLen = 0;
 
253
        CachedPrinterConfigData = NULL;
 
254
 
 
255
        DEBUG_SVC("Printer %s registered", printer->name);
 
256
 
 
257
        Flags = 0;
 
258
        if (printer->is_default)
 
259
                Flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER;
 
260
 
 
261
        uniconv = freerdp_uniconv_new();
 
262
        DriverName = freerdp_uniconv_out(uniconv, printer->driver, &DriverNameLen);
 
263
        PrintName = freerdp_uniconv_out(uniconv, printer->name, &PrintNameLen);
 
264
        freerdp_uniconv_free(uniconv);
 
265
 
 
266
        printer_dev->device.data = stream_new(28 + DriverNameLen + PrintNameLen + CachedFieldsLen);
 
267
 
 
268
        stream_write_uint32(printer_dev->device.data, Flags);
 
269
        stream_write_uint32(printer_dev->device.data, 0); /* CodePage, reserved */
 
270
        stream_write_uint32(printer_dev->device.data, 0); /* PnPNameLen */
 
271
        stream_write_uint32(printer_dev->device.data, DriverNameLen + 2);
 
272
        stream_write_uint32(printer_dev->device.data, PrintNameLen + 2);
 
273
        stream_write_uint32(printer_dev->device.data, CachedFieldsLen);
 
274
        stream_write(printer_dev->device.data, DriverName, DriverNameLen);
 
275
        stream_write_uint16(printer_dev->device.data, 0);
 
276
        stream_write(printer_dev->device.data, PrintName, PrintNameLen);
 
277
        stream_write_uint16(printer_dev->device.data, 0);
 
278
        if (CachedFieldsLen > 0)
 
279
        {
 
280
                stream_write(printer_dev->device.data, CachedPrinterConfigData, CachedFieldsLen);
 
281
        }
 
282
 
 
283
        xfree(DriverName);
 
284
        xfree(PrintName);
 
285
 
 
286
        printer_dev->irp_list = list_new();
 
287
        printer_dev->thread = freerdp_thread_new();
 
288
 
 
289
        pEntryPoints->RegisterDevice(pEntryPoints->devman, (DEVICE*)printer_dev);
 
290
 
 
291
        freerdp_thread_start(printer_dev->thread, printer_thread_func, printer_dev);
 
292
}
 
293
 
 
294
int DeviceServiceEntry(PDEVICE_SERVICE_ENTRY_POINTS pEntryPoints)
 
295
{
 
296
        rdpPrinterDriver* driver = NULL;
 
297
        rdpPrinter** printers;
 
298
        rdpPrinter* printer;
86
299
        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));
 
300
        char* name;
 
301
        char* driver_name;
 
302
 
 
303
#ifdef CUPS_FOUND
 
304
        driver = printer_cups_get_driver();
 
305
#endif
 
306
        if (driver == NULL)
 
307
        {
 
308
                DEBUG_WARN("no driver.");
123
309
                return 1;
124
310
        }
125
 
        size = printerNameLen * 3 / 2 + 2;
126
 
        printerName = (char *) malloc(size);
127
 
        memset(printerName, 0, size);
128
 
        freerdp_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
 
        freerdp_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
 
        srv->get_event = NULL;
232
 
        srv->file_descriptor = NULL;
233
 
        srv->get_timeouts = NULL;
234
 
 
235
 
        return srv;
236
 
}
237
 
 
238
 
int
239
 
printer_register(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints, SERVICE * srv,
240
 
        const char * name, const char * driver, int is_default, int * port)
241
 
{
242
 
        DEVICE * dev;
243
 
        char buf[8];
244
 
        uint32 flags;
245
 
        int size;
246
 
        int offset;
247
 
        int len;
248
 
        char * cache_data;
249
 
        int cache_data_len;
250
 
 
251
 
        LLOGLN(0, ("printer_register: %s (default=%d)", name, is_default));
252
 
 
253
 
        if (driver == NULL)
254
 
        {
255
 
                /* This is a generic PostScript printer driver developed by MS, so it should be good in most cases */
256
 
                driver = "MS Publisher Imagesetter";
257
 
        }
258
 
 
259
 
        snprintf(buf, sizeof(buf) - 1, "PRN%d", *port);
260
 
        *port += 1;
261
 
        dev = pEntryPoints->pDevmanRegisterDevice(pDevman, srv, buf);
262
 
        dev->info = printer_hw_new(name);
263
 
 
264
 
        cache_data = printer_get_data(name, &cache_data_len);
265
 
 
266
 
        size = 24 + 4 + (strlen(name) + 1) * 2 + (strlen(driver) + 1) * 2 + cache_data_len;
267
 
        dev->data = malloc(size);
268
 
        memset(dev->data, 0, size);
269
 
 
270
 
        /*flags = RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT;*/
271
 
        flags = 0;
272
 
        if (is_default)
273
 
                flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER;
274
 
 
275
 
        SET_UINT32 (dev->data, 0, flags); /* Flags */
276
 
        SET_UINT32 (dev->data, 4, 0); /* CodePage, reserved */
277
 
        SET_UINT32 (dev->data, 8, 0); /* PnPNameLen */
278
 
        SET_UINT32 (dev->data, 20, cache_data_len); /* CachedFieldsLen */
279
 
        offset = 24;
280
 
        len = freerdp_set_wstr(&dev->data[offset], size - offset, (char *) driver, strlen(driver) + 1);
281
 
        SET_UINT32 (dev->data, 12, len); /* DriverNameLen */
282
 
        offset += len;
283
 
        len = freerdp_set_wstr(&dev->data[offset], size - offset, (char *) name, strlen(name) + 1);
284
 
        SET_UINT32 (dev->data, 16, len); /* PrintNameLen */
285
 
        offset += len;
286
 
        if (cache_data)
287
 
        {
288
 
                memcpy(&dev->data[offset], cache_data, cache_data_len);
289
 
                offset += cache_data_len;
290
 
                free(cache_data);
291
 
        }
292
 
 
293
 
        dev->data_len = offset;
294
 
 
295
 
        return 0;
296
 
}
297
 
 
298
 
uint32
299
 
printer_free(DEVICE * dev)
300
 
{
301
 
        printer_hw_free(dev->info);
302
 
        if (dev->data)
303
 
        {
304
 
                free(dev->data);
305
 
                dev->data = NULL;
306
 
        }
307
 
        return 0;
308
 
}
309
 
 
310
 
int
311
 
DeviceServiceEntry(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints)
312
 
{
313
 
        SERVICE * srv = NULL;
314
 
        RD_PLUGIN_DATA * data;
315
 
        int port = 1;
316
 
 
317
 
        data = (RD_PLUGIN_DATA *) pEntryPoints->pExtendedData;
318
 
        while (data && data->size > 0)
319
 
        {
320
 
                if (strcmp((char*)data->data[0], "printer") == 0)
321
 
                {
322
 
                        if (srv == NULL)
323
 
                                srv = printer_register_service(pDevman, pEntryPoints);
324
 
 
325
 
                        if (data->data[1] == NULL)
326
 
                                printer_hw_register_auto(pDevman, pEntryPoints, srv, &port);
327
 
                        else
328
 
                                printer_register(pDevman, pEntryPoints, srv, data->data[1], data->data[2], (port == 1), &port);
329
 
                        break;
330
 
                }
331
 
                data = (RD_PLUGIN_DATA *) (((void *) data) + data->size);
332
 
        }
333
 
 
334
 
        return 1;
 
311
 
 
312
        name = (char*)pEntryPoints->plugin_data->data[1];
 
313
        driver_name = (char*)pEntryPoints->plugin_data->data[2];
 
314
 
 
315
        if (name && name[0])
 
316
        {
 
317
                printer = driver->GetPrinter(driver, name);
 
318
                if (printer == NULL)
 
319
                {
 
320
                        DEBUG_WARN("printer %s not found.", name);
 
321
                        return 1;
 
322
                }
 
323
                if (driver_name && driver_name[0])
 
324
                        printer->driver = driver_name;
 
325
 
 
326
                printer_register(pEntryPoints, printer);
 
327
        }
 
328
        else
 
329
        {
 
330
                printers = driver->EnumPrinters(driver);
 
331
                for (i = 0; printers[i]; i++)
 
332
                {
 
333
                        printer = printers[i];
 
334
                        printer_register(pEntryPoints, printer);
 
335
                }
 
336
                xfree(printers);
 
337
        }
 
338
 
 
339
        return 0;
335
340
}