Merge 1.0.0 changes back to master.
This commit is contained in:
commit
35237a4f88
@ -29,6 +29,7 @@
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/unicode.h>
|
||||
|
||||
#ifdef ENABLE_WINPR
|
||||
#include <winpr/stream.h>
|
||||
@ -36,21 +37,6 @@
|
||||
#include "compat/winpr-stream.h"
|
||||
#endif
|
||||
|
||||
static void guac_rdpdr_device_fs_announce_handler(guac_rdpdr_device* device,
|
||||
wStream* output_stream, int device_id) {
|
||||
|
||||
/* Filesystem header */
|
||||
guac_client_log(device->rdpdr->client, GUAC_LOG_INFO, "Sending filesystem");
|
||||
Stream_Write_UINT32(output_stream, RDPDR_DTYP_FILESYSTEM);
|
||||
Stream_Write_UINT32(output_stream, device_id);
|
||||
Stream_Write(output_stream, "GUAC\0\0\0\0", 8); /* DOS name */
|
||||
|
||||
/* Filesystem data */
|
||||
Stream_Write_UINT32(output_stream, GUAC_FILESYSTEM_NAME_LENGTH);
|
||||
Stream_Write(output_stream, GUAC_FILESYSTEM_NAME, GUAC_FILESYSTEM_NAME_LENGTH);
|
||||
|
||||
}
|
||||
|
||||
static void guac_rdpdr_device_fs_iorequest_handler(guac_rdpdr_device* device,
|
||||
wStream* input_stream, int file_id, int completion_id, int major_func, int minor_func) {
|
||||
|
||||
@ -128,6 +114,9 @@ static void guac_rdpdr_device_fs_iorequest_handler(guac_rdpdr_device* device,
|
||||
}
|
||||
|
||||
static void guac_rdpdr_device_fs_free_handler(guac_rdpdr_device* device) {
|
||||
|
||||
Stream_Free(device->device_announce, 1);
|
||||
|
||||
}
|
||||
|
||||
void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr) {
|
||||
@ -143,9 +132,21 @@ void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr) {
|
||||
device->rdpdr = rdpdr;
|
||||
device->device_id = id;
|
||||
device->device_name = "Guacamole Filesystem";
|
||||
int device_name_len = guac_utf8_strlen(device->device_name);
|
||||
device->device_type = RDPDR_DTYP_FILESYSTEM;
|
||||
device->dos_name = "GUACFS\0\0";
|
||||
|
||||
/* Set up the device announcement */
|
||||
device->device_announce_len = 20 + device_name_len;
|
||||
device->device_announce = Stream_New(NULL, device->device_announce_len);
|
||||
Stream_Write_UINT32(device->device_announce, device->device_type);
|
||||
Stream_Write_UINT32(device->device_announce, device->device_id);
|
||||
Stream_Write(device->device_announce, device->dos_name, 8);
|
||||
Stream_Write_UINT32(device->device_announce, device_name_len);
|
||||
Stream_Write(device->device_announce, device->device_name, device_name_len);
|
||||
|
||||
|
||||
/* Set handlers */
|
||||
device->announce_handler = guac_rdpdr_device_fs_announce_handler;
|
||||
device->iorequest_handler = guac_rdpdr_device_fs_iorequest_handler;
|
||||
device->free_handler = guac_rdpdr_device_fs_free_handler;
|
||||
|
||||
|
@ -22,9 +22,11 @@
|
||||
#include "rdp.h"
|
||||
#include "rdpdr_messages.h"
|
||||
#include "rdpdr_service.h"
|
||||
#include "unicode.h"
|
||||
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/unicode.h>
|
||||
|
||||
#ifdef ENABLE_WINPR
|
||||
#include <winpr/stream.h>
|
||||
@ -122,20 +124,29 @@ 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);
|
||||
/* Calculate number of bytes needed for the stream */
|
||||
int streamBytes = 16;
|
||||
for (int i=0; i < rdpdr->devices_registered; i++)
|
||||
streamBytes += rdpdr->devices[i].device_announce_len;
|
||||
|
||||
/* Allocate the stream */
|
||||
wStream* output_stream = Stream_New(NULL, streamBytes);
|
||||
|
||||
/* Write header */
|
||||
Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
|
||||
Stream_Write_UINT16(output_stream, PAKID_CORE_DEVICELIST_ANNOUNCE);
|
||||
|
||||
/* List devices */
|
||||
/* Get the stream for each of the devices. */
|
||||
Stream_Write_UINT32(output_stream, rdpdr->devices_registered);
|
||||
for (i=0; i<rdpdr->devices_registered; i++) {
|
||||
guac_rdpdr_device* device = &(rdpdr->devices[i]);
|
||||
device->announce_handler(device, output_stream, i);
|
||||
for (int i=0; i<rdpdr->devices_registered; i++) {
|
||||
|
||||
Stream_Write(output_stream,
|
||||
Stream_Buffer(rdpdr->devices[i].device_announce),
|
||||
rdpdr->devices[i].device_announce_len);
|
||||
|
||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Registered device %i (%s)",
|
||||
device->device_id, device->device_name);
|
||||
rdpdr->devices[i].device_id, rdpdr->devices[i].device_name);
|
||||
|
||||
}
|
||||
|
||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
||||
@ -273,4 +284,3 @@ void guac_rdpdr_process_prn_cache_data(guac_rdpdrPlugin* rdpdr, wStream* input_s
|
||||
void guac_rdpdr_process_prn_using_xps(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Printer unexpectedly switched to XPS mode");
|
||||
}
|
||||
|
||||
|
@ -76,12 +76,6 @@
|
||||
#define GUAC_PRINTER_DRIVER "M\0S\0 \0P\0u\0b\0l\0i\0s\0h\0e\0r\0 \0I\0m\0a\0g\0e\0s\0e\0t\0t\0e\0r\0\0\0"
|
||||
#define GUAC_PRINTER_DRIVER_LENGTH 50
|
||||
|
||||
/**
|
||||
* Name of the printer itself.
|
||||
*/
|
||||
#define GUAC_PRINTER_NAME "G\0u\0a\0c\0a\0m\0o\0l\0e\0\0\0"
|
||||
#define GUAC_PRINTER_NAME_LENGTH 20
|
||||
|
||||
/**
|
||||
* Name of the filesystem.
|
||||
*/
|
||||
|
@ -25,12 +25,14 @@
|
||||
#include "rdp.h"
|
||||
#include "rdp_print_job.h"
|
||||
#include "rdp_status.h"
|
||||
#include "unicode.h"
|
||||
|
||||
#include <freerdp/utils/svc_plugin.h>
|
||||
#include <guacamole/client.h>
|
||||
#include <guacamole/protocol.h>
|
||||
#include <guacamole/socket.h>
|
||||
#include <guacamole/stream.h>
|
||||
#include <guacamole/unicode.h>
|
||||
#include <guacamole/user.h>
|
||||
|
||||
#ifdef ENABLE_WINPR
|
||||
@ -131,31 +133,6 @@ 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(device->rdpdr->client, GUAC_LOG_INFO, "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) {
|
||||
|
||||
@ -187,10 +164,12 @@ static void guac_rdpdr_device_printer_iorequest_handler(guac_rdpdr_device* devic
|
||||
}
|
||||
|
||||
static void guac_rdpdr_device_printer_free_handler(guac_rdpdr_device* device) {
|
||||
/* Do nothing */
|
||||
|
||||
Stream_Free(device->device_announce, 1);
|
||||
|
||||
}
|
||||
|
||||
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr) {
|
||||
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr, char* printer_name) {
|
||||
|
||||
int id = rdpdr->devices_registered++;
|
||||
|
||||
@ -200,10 +179,42 @@ void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr) {
|
||||
/* Init device */
|
||||
device->rdpdr = rdpdr;
|
||||
device->device_id = id;
|
||||
device->device_name = "Guacamole Printer";
|
||||
device->device_name = printer_name;
|
||||
int device_name_len = guac_utf8_strlen(device->device_name);
|
||||
device->device_type = RDPDR_DTYP_PRINT;
|
||||
device->dos_name = "PRN1\0\0\0\0";
|
||||
|
||||
/* Set up device announce stream */
|
||||
int prt_name_len = (device_name_len + 1) * 2;
|
||||
device->device_announce_len = 44 + prt_name_len
|
||||
+ GUAC_PRINTER_DRIVER_LENGTH;
|
||||
device->device_announce = Stream_New(NULL, device->device_announce_len);
|
||||
|
||||
/* Write common information. */
|
||||
Stream_Write_UINT32(device->device_announce, device->device_type);
|
||||
Stream_Write_UINT32(device->device_announce, device->device_id);
|
||||
Stream_Write(device->device_announce, device->dos_name, 8);
|
||||
|
||||
/* DeviceDataLength */
|
||||
Stream_Write_UINT32(device->device_announce, 24 + prt_name_len + GUAC_PRINTER_DRIVER_LENGTH);
|
||||
|
||||
/* Begin printer-specific information */
|
||||
Stream_Write_UINT32(device->device_announce,
|
||||
RDPDR_PRINTER_ANNOUNCE_FLAG_DEFAULTPRINTER
|
||||
| RDPDR_PRINTER_ANNOUNCE_FLAG_NETWORKPRINTER); /* Printer flags */
|
||||
Stream_Write_UINT32(device->device_announce, 0); /* Reserved - must be 0. */
|
||||
Stream_Write_UINT32(device->device_announce, 0); /* PnPName Length - ignored. */
|
||||
Stream_Write_UINT32(device->device_announce, GUAC_PRINTER_DRIVER_LENGTH);
|
||||
Stream_Write_UINT32(device->device_announce, prt_name_len);
|
||||
Stream_Write_UINT32(device->device_announce, 0); /* CachedFields length. */
|
||||
|
||||
Stream_Write(device->device_announce, GUAC_PRINTER_DRIVER, GUAC_PRINTER_DRIVER_LENGTH);
|
||||
guac_rdp_utf8_to_utf16((const unsigned char*) device->device_name,
|
||||
device_name_len + 1, (char*) Stream_Pointer(device->device_announce),
|
||||
prt_name_len);
|
||||
Stream_Seek(device->device_announce, prt_name_len);
|
||||
|
||||
/* Set handlers */
|
||||
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;
|
||||
|
||||
|
@ -34,8 +34,15 @@
|
||||
/**
|
||||
* Registers a new printer device within the RDPDR plugin. This must be done
|
||||
* before RDPDR connection finishes.
|
||||
*
|
||||
* @param rdpdr
|
||||
* The RDP device redirection plugin where the device is registered.
|
||||
*
|
||||
* @param printer_name
|
||||
* The name of the printer that will be registered with the RDP
|
||||
* connection and passed through to the server.
|
||||
*/
|
||||
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr);
|
||||
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr, char* printer_name);
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -96,7 +96,7 @@ void guac_rdpdr_process_connect(rdpSvcPlugin* plugin) {
|
||||
|
||||
/* Register printer if enabled */
|
||||
if (rdp_client->settings->printing_enabled)
|
||||
guac_rdpdr_register_printer(rdpdr);
|
||||
guac_rdpdr_register_printer(rdpdr, rdp_client->settings->printer_name);
|
||||
|
||||
/* Register drive if enabled */
|
||||
if (rdp_client->settings->drive_enabled)
|
||||
|
@ -74,15 +74,30 @@ struct guac_rdpdr_device {
|
||||
int device_id;
|
||||
|
||||
/**
|
||||
* An arbitrary device name, used for logging purposes only.
|
||||
* Device name, used for logging and for passthrough to the
|
||||
* server.
|
||||
*/
|
||||
const char* device_name;
|
||||
|
||||
/**
|
||||
* Handler which will be called when the RDPDR plugin is forming the client
|
||||
* device announce list.
|
||||
* The type of RDPDR device that this represents.
|
||||
*/
|
||||
guac_rdpdr_device_announce_handler* announce_handler;
|
||||
uint32_t device_type;
|
||||
|
||||
/**
|
||||
* The DOS name of the device. Max 8 bytes, including terminator.
|
||||
*/
|
||||
const char *dos_name;
|
||||
|
||||
/**
|
||||
* The stream that stores the RDPDR device announcement for this device.
|
||||
*/
|
||||
wStream* device_announce;
|
||||
|
||||
/**
|
||||
* The length of the device_announce wStream.
|
||||
*/
|
||||
int device_announce_len;
|
||||
|
||||
/**
|
||||
* Handler which should be called for every I/O request received.
|
||||
@ -90,7 +105,7 @@ struct guac_rdpdr_device {
|
||||
guac_rdpdr_device_iorequest_handler* iorequest_handler;
|
||||
|
||||
/**
|
||||
* Handlel which should be called when the device is being free'd.
|
||||
* Handler which should be called when the device is being freed.
|
||||
*/
|
||||
guac_rdpdr_device_free_handler* free_handler;
|
||||
|
||||
@ -154,7 +169,7 @@ void guac_rdpdr_process_terminate(rdpSvcPlugin* plugin);
|
||||
void guac_rdpdr_process_event(rdpSvcPlugin* plugin, wMessage* event);
|
||||
|
||||
/**
|
||||
* Creates a new stream which contains the ommon DR_DEVICE_IOCOMPLETION header
|
||||
* Creates a new stream which contains the common DR_DEVICE_IOCOMPLETION header
|
||||
* used for virtually all responses.
|
||||
*/
|
||||
wStream* guac_rdpdr_new_io_completion(guac_rdpdr_device* device,
|
||||
|
@ -52,6 +52,7 @@ const char* GUAC_RDP_CLIENT_ARGS[] = {
|
||||
"color-depth",
|
||||
"disable-audio",
|
||||
"enable-printing",
|
||||
"printer-name",
|
||||
"enable-drive",
|
||||
"drive-path",
|
||||
"create-drive-path",
|
||||
@ -187,6 +188,11 @@ enum RDP_ARGS_IDX {
|
||||
*/
|
||||
IDX_ENABLE_PRINTING,
|
||||
|
||||
/**
|
||||
* The name of the printer that will be passed through to the RDP server.
|
||||
*/
|
||||
IDX_PRINTER_NAME,
|
||||
|
||||
/**
|
||||
* "true" if the virtual drive should be enabled, "false" or blank
|
||||
* otherwise.
|
||||
@ -794,6 +800,11 @@ guac_rdp_settings* guac_rdp_parse_args(guac_user* user,
|
||||
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_ENABLE_PRINTING, 0);
|
||||
|
||||
/* Name of redirected printer */
|
||||
settings->printer_name =
|
||||
guac_user_parse_args_string(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
IDX_PRINTER_NAME, "Guacamole Printer");
|
||||
|
||||
/* Drive enable/disable */
|
||||
settings->drive_enabled =
|
||||
guac_user_parse_args_boolean(user, GUAC_RDP_CLIENT_ARGS, argv,
|
||||
@ -990,6 +1001,7 @@ void guac_rdp_settings_free(guac_rdp_settings* settings) {
|
||||
free(settings->remote_app_args);
|
||||
free(settings->remote_app_dir);
|
||||
free(settings->username);
|
||||
free(settings->printer_name);
|
||||
|
||||
/* Free channel name array */
|
||||
if (settings->svc_names != NULL) {
|
||||
|
@ -177,6 +177,11 @@ typedef struct guac_rdp_settings {
|
||||
*/
|
||||
int printing_enabled;
|
||||
|
||||
/**
|
||||
* Name of the redirected printer.
|
||||
*/
|
||||
char* printer_name;
|
||||
|
||||
/**
|
||||
* Whether the virtual drive is enabled.
|
||||
*/
|
||||
|
Loading…
Reference in New Issue
Block a user