1
/* -*- c-basic-offset: 8 -*-
2
FreeRDP: A Remote Desktop Protocol client.
3
Redirected Printer Device Service
5
Copyright (C) Marc-Andre Moreau <marcandre.moreau@gmail.com> 2010
6
Copyright (C) Vic Lee <llyzs@163.com> 2010
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.
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.
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.
27
#include "rdpdr_constants.h"
28
#include "rdpdr_types.h"
30
#include "printer_main.h"
33
printer_get_filename(const char * name)
39
home = getenv("HOME");
43
filename = (char *) malloc(strlen(home) + strlen("/.freerdp/printer_") + strlen(name) + 1);
44
sprintf(filename, "%s/.freerdp", home);
45
if (stat(filename, &st) != 0)
47
mkdir(filename, 0700);
48
LLOGLN(0, ("printer_get_filename: created %s", filename));
50
strcat(filename, "/printer_");
51
strcat(filename, name);
56
printer_save_data(const char * name, const char * data, int data_len)
62
filename = printer_get_filename(name);
63
fp = fopen(filename, "w+b");
66
LLOGLN(0, ("printer_save_data: create %s failed.", filename));
70
len = (int) fwrite(data, 1, data_len, fp);
73
LLOGLN(0, ("printer_save_data: error writing %d bytes.", len));
81
printer_get_data(const char * name, int * len)
88
filename = printer_get_filename(name);
89
fp = fopen(filename, "rb");
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);
109
printer_process_update_printer_event(SERVICE * srv, const char * data, int data_len)
111
uint32 printerNameLen;
113
uint32 configDataLen;
116
printerNameLen = GET_UINT32(data, 0);
117
configDataLen = GET_UINT32(data, 4);
119
if (printerNameLen + configDataLen + 8 > data_len)
121
LLOGLN(0, ("printer_process_update_printer_event: expect %d+%d+8 got %d",
122
printerNameLen, configDataLen, data_len));
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);
137
printer_process_delete_printer_event(SERVICE * srv, const char * data, int data_len)
139
uint32 printerNameLen;
144
printerNameLen = GET_UINT32(data, 0);
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);
151
filename = printer_get_filename(printerName);
153
LLOGLN(0, ("printer_process_delete_printer_event: %s deleted", filename));
161
printer_process_cache_data(SERVICE * srv, const char * data, int data_len)
165
eventID = GET_UINT32(data, 0);
168
case RDPDR_ADD_PRINTER_EVENT:
169
LLOGLN(0, ("RDPDR_ADD_PRINTER_EVENT"));
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);
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);
182
case RDPDR_RENAME_PRINTER_EVENT:
183
LLOGLN(0, ("RDPDR_RENAME_PRINTER_EVENT"));
187
LLOGLN(0, ("RDPDR printer unsupported eventID %i", eventID));
194
printer_process_data(SERVICE * srv, int type, const char * data, int data_len)
198
case PAKID_PRN_CACHE_DATA:
199
LLOGLN(10, ("PAKID_PRN_CACHE_DATA"));
200
printer_process_cache_data(srv, data, data_len);
204
LLOGLN(0, ("RDPDR printer component, packetID: 0x%02X", type));
211
printer_register_service(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints)
215
srv = pEntryPoints->pDevmanRegisterService(pDevman);
217
srv->create = printer_hw_create;
218
srv->close = printer_hw_close;
220
srv->write = printer_hw_write;
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;
236
printer_register(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints, SERVICE * srv,
237
const char * name, const char * driver, int is_default, int * port)
248
LLOGLN(0, ("printer_register: %s (default=%d)", name, is_default));
252
/* This is a generic PostScript printer driver developed by MS, so it should be good in most cases */
253
driver = "MS Publisher Imagesetter";
256
snprintf(buf, sizeof(buf) - 1, "PRN%d", *port);
258
dev = pEntryPoints->pDevmanRegisterDevice(pDevman, srv, buf);
259
dev->info = printer_hw_new(name);
261
cache_data = printer_get_data(name, &cache_data_len);
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);
267
/*flags = RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT;*/
270
flags |= RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER;
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 */
277
len = set_wstr(&dev->data[offset], size - offset, (char *) driver, strlen(driver) + 1);
278
SET_UINT32 (dev->data, 12, len); /* DriverNameLen */
280
len = set_wstr(&dev->data[offset], size - offset, (char *) name, strlen(name) + 1);
281
SET_UINT32 (dev->data, 16, len); /* PrintNameLen */
285
memcpy(&dev->data[offset], cache_data, cache_data_len);
286
offset += cache_data_len;
290
dev->data_len = offset;
296
printer_free(DEVICE * dev)
298
printer_hw_free(dev->info);
308
DeviceServiceEntry(PDEVMAN pDevman, PDEVMAN_ENTRY_POINTS pEntryPoints)
310
SERVICE * srv = NULL;
311
RD_PLUGIN_DATA * data;
314
data = (RD_PLUGIN_DATA *) pEntryPoints->pExtendedData;
315
while (data && data->size > 0)
317
if (strcmp((char*)data->data[0], "printer") == 0)
320
srv = printer_register_service(pDevman, pEntryPoints);
322
if (data->data[1] == NULL)
323
printer_hw_register_auto(pDevman, pEntryPoints, srv, &port);
325
printer_register(pDevman, pEntryPoints, srv, data->data[1], data->data[2], (port == 1), &port);
328
data = (RD_PLUGIN_DATA *) (((void *) data) + data->size);