diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c index 93ce11e6..9919c0e9 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.c @@ -139,37 +139,20 @@ static void guac_rdpdr_send_client_capability(guac_rdpdrPlugin* rdpdr) { static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdrPlugin* rdpdr) { + int i; wStream* output_stream = Stream_New(NULL, 256); /* Write header */ Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE); Stream_Write_UINT16(output_stream, PAKID_CORE_DEVICELIST_ANNOUNCE); - /* Only one device for now */ - Stream_Write_UINT32(output_stream, 1); - - /* TODO: Actually register proper device with devices array */ - /* TODO: Init devices-registered count */ - - /* Printer header */ - guac_client_log_info(rdpdr->client, "Sending printer"); - Stream_Write_UINT32(output_stream, RDPDR_DTYP_PRINT); - Stream_Write_UINT32(output_stream, GUAC_PRINTER_DEVICE_ID); - Stream_Write(output_stream, "PRN1\0\0\0\0", 8); /* DOS name */ - - /* Printer data */ - Stream_Write_UINT32(output_stream, 24 + GUAC_PRINTER_DRIVER_LENGTH + GUAC_PRINTER_NAME_LENGTH); - Stream_Write_UINT32(output_stream, - RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER - | RDPDR_PRINTER_ANNOUNCE_FLAG_NETWORKPRINTER); - Stream_Write_UINT32(output_stream, 0); /* reserved - must be 0 */ - Stream_Write_UINT32(output_stream, 0); /* PnPName length (PnPName is ultimately ignored) */ - Stream_Write_UINT32(output_stream, GUAC_PRINTER_DRIVER_LENGTH); /* DriverName length */ - Stream_Write_UINT32(output_stream, GUAC_PRINTER_NAME_LENGTH); /* PrinterName length */ - Stream_Write_UINT32(output_stream, 0); /* CachedFields length */ - - Stream_Write(output_stream, GUAC_PRINTER_DRIVER, GUAC_PRINTER_DRIVER_LENGTH); - Stream_Write(output_stream, GUAC_PRINTER_NAME, GUAC_PRINTER_NAME_LENGTH); + /* List devices */ + Stream_Write_UINT32(output_stream, rdpdr->devices_registered); + for (i=0; idevices_registered; i++) { + guac_rdpdr_device* device = &(rdpdr->devices[i]); + device->announce_handler(device, output_stream, i); + guac_client_log_info(rdpdr->client, "Registered device %i", i); + } svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream); guac_client_log_info(rdpdr->client, "All supported devices sent."); @@ -219,13 +202,13 @@ void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_str code = ntstatus & 0x0000FFFF; /* Log error / information */ - if (device_id == GUAC_PRINTER_DEVICE_ID) { + if (device_id >= 0 && device_id < rdpdr->devices_registered) { if (severity == 0x0) - guac_client_log_info(rdpdr->client, "Printer connected successfully"); + guac_client_log_info(rdpdr->client, "Device %i connected successfully"); else - guac_client_log_error(rdpdr->client, "Problem connecting printer: " + guac_client_log_error(rdpdr->client, "Problem connecting device %i: " "severity=0x%x, c=0x%x, n=0x%x, facility=0x%x, code=0x%x", severity, c, n, facility, code); diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h index cc317799..8d2890f9 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_messages.h @@ -83,11 +83,6 @@ */ #define GUAC_OS_TYPE (*((uint32_t*) "GUAC")) -/** - * Arbitray 32-bit unique integer representing the printer device. - */ -#define GUAC_PRINTER_DEVICE_ID (*((uint32_t*) "GPR1")) - /** * Name of the printer driver that should be used on the server. */ diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c index cd523697..6fc477ac 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_printer.c @@ -290,6 +290,31 @@ void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device, } +static void guac_rdpdr_device_printer_announce_handler(guac_rdpdr_device* device, + wStream* output_stream, int device_id) { + + /* Printer header */ + guac_client_log_info(device->rdpdr->client, "Sending printer"); + Stream_Write_UINT32(output_stream, RDPDR_DTYP_PRINT); + Stream_Write_UINT32(output_stream, device_id); + Stream_Write(output_stream, "PRN1\0\0\0\0", 8); /* DOS name */ + + /* Printer data */ + Stream_Write_UINT32(output_stream, 24 + GUAC_PRINTER_DRIVER_LENGTH + GUAC_PRINTER_NAME_LENGTH); + Stream_Write_UINT32(output_stream, + RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER + | RDPDR_PRINTER_ANNOUNCE_FLAG_NETWORKPRINTER); + Stream_Write_UINT32(output_stream, 0); /* reserved - must be 0 */ + Stream_Write_UINT32(output_stream, 0); /* PnPName length (PnPName is ultimately ignored) */ + Stream_Write_UINT32(output_stream, GUAC_PRINTER_DRIVER_LENGTH); /* DriverName length */ + Stream_Write_UINT32(output_stream, GUAC_PRINTER_NAME_LENGTH); /* PrinterName length */ + Stream_Write_UINT32(output_stream, 0); /* CachedFields length */ + + Stream_Write(output_stream, GUAC_PRINTER_DRIVER, GUAC_PRINTER_DRIVER_LENGTH); + Stream_Write(output_stream, GUAC_PRINTER_NAME, GUAC_PRINTER_NAME_LENGTH); + +} + static void guac_rdpdr_device_printer_iorequest_handler(guac_rdpdr_device* device, wStream* input_stream, int file_id, int completion_id, int major_func, int minor_func) { @@ -331,6 +356,7 @@ void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr) { /* Init device */ device->rdpdr = rdpdr; + device->announce_handler = guac_rdpdr_device_printer_announce_handler; device->iorequest_handler = guac_rdpdr_device_printer_iorequest_handler; device->free_handler = guac_rdpdr_device_printer_free_handler; diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c index e7297b1c..ede4edc8 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.c +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_service.c @@ -97,6 +97,9 @@ void guac_rdpdr_process_connect(rdpSvcPlugin* plugin) { /* Init plugin */ rdpdr->client = client; + /* For now, always register the printer */ + guac_rdpdr_register_printer(rdpdr); + /* Log that printing, etc. has been loaded */ guac_client_log_info(client, "guacdr connected."); diff --git a/src/protocols/rdp/guac_rdpdr/rdpdr_service.h b/src/protocols/rdp/guac_rdpdr/rdpdr_service.h index 5c6cc2f2..b999441e 100644 --- a/src/protocols/rdp/guac_rdpdr/rdpdr_service.h +++ b/src/protocols/rdp/guac_rdpdr/rdpdr_service.h @@ -51,6 +51,13 @@ typedef struct guac_rdpdrPlugin guac_rdpdrPlugin; typedef struct guac_rdpdr_device guac_rdpdr_device; +/** + * Handler for client device list announce. Each implementing device must write + * its announcement header and data to the given output stream. + */ +typedef void guac_rdpdr_device_announce_handler(guac_rdpdr_device* device, wStream* output_stream, + int device_id); + /** * Handler for device I/O requests. */ @@ -77,6 +84,12 @@ struct guac_rdpdr_device { */ const char* device_name; + /** + * Handler which will be called when the RDPDR plugin is forming the client + * device announce list. + */ + guac_rdpdr_device_announce_handler* announce_handler; + /** * Handler which should be called for every I/O request received. */