Initial migration to dynamic device registration.
This commit is contained in:
parent
7661f465e5
commit
1138df74be
@ -148,6 +148,9 @@ static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdrPlugin
|
|||||||
/* Only one device for now */
|
/* Only one device for now */
|
||||||
Stream_Write_UINT32(output_stream, 1);
|
Stream_Write_UINT32(output_stream, 1);
|
||||||
|
|
||||||
|
/* TODO: Actually register proper device with devices array */
|
||||||
|
/* TODO: Init devices-registered count */
|
||||||
|
|
||||||
/* Printer header */
|
/* Printer header */
|
||||||
guac_client_log_info(rdpdr->client, "Sending printer");
|
guac_client_log_info(rdpdr->client, "Sending printer");
|
||||||
Stream_Write_UINT32(output_stream, RDPDR_DTYP_PRINT);
|
Stream_Write_UINT32(output_stream, RDPDR_DTYP_PRINT);
|
||||||
@ -235,41 +238,22 @@ void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_str
|
|||||||
|
|
||||||
void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
||||||
|
|
||||||
int device_id, completion_id, major_func, minor_func;
|
int device_id, file_id, completion_id, major_func, minor_func;
|
||||||
|
|
||||||
/* Read header */
|
/* Read header */
|
||||||
Stream_Read_UINT32(input_stream, device_id);
|
Stream_Read_UINT32(input_stream, device_id);
|
||||||
Stream_Seek(input_stream, 4); /* file_id - currently skipped (not used in printer) */
|
Stream_Read_UINT32(input_stream, file_id);
|
||||||
Stream_Read_UINT32(input_stream, completion_id);
|
Stream_Read_UINT32(input_stream, completion_id);
|
||||||
Stream_Read_UINT32(input_stream, major_func);
|
Stream_Read_UINT32(input_stream, major_func);
|
||||||
Stream_Read_UINT32(input_stream, minor_func);
|
Stream_Read_UINT32(input_stream, minor_func);
|
||||||
|
|
||||||
/* If printer, run printer handlers */
|
/* If printer, run printer handlers */
|
||||||
if (device_id == GUAC_PRINTER_DEVICE_ID) {
|
if (device_id >= 0 && device_id < rdpdr->devices_registered) {
|
||||||
|
|
||||||
switch (major_func) {
|
/* Call handler on device */
|
||||||
|
guac_rdpdr_device* device = &(rdpdr->devices[device_id]);
|
||||||
/* Print job create */
|
device->iorequest_handler(device, input_stream,
|
||||||
case IRP_MJ_CREATE:
|
file_id, completion_id, major_func, minor_func);
|
||||||
guac_rdpdr_process_print_job_create(rdpdr, input_stream, completion_id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Printer job write */
|
|
||||||
case IRP_MJ_WRITE:
|
|
||||||
guac_rdpdr_process_print_job_write(rdpdr, input_stream, completion_id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Printer job close */
|
|
||||||
case IRP_MJ_CLOSE:
|
|
||||||
guac_rdpdr_process_print_job_close(rdpdr, input_stream, completion_id);
|
|
||||||
break;
|
|
||||||
|
|
||||||
/* Log unknown */
|
|
||||||
default:
|
|
||||||
guac_client_log_error(rdpdr->client, "Unknown printer I/O request function: 0x%x/0x%x",
|
|
||||||
major_func, minor_func);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -35,25 +35,28 @@ char* const guac_rdpdr_pdf_filter_command[] = {
|
|||||||
|
|
||||||
static void* guac_rdpdr_print_filter_output_thread(void* data) {
|
static void* guac_rdpdr_print_filter_output_thread(void* data) {
|
||||||
|
|
||||||
guac_rdpdrPlugin* rdpdr = (guac_rdpdrPlugin*) data;
|
guac_rdpdr_device* device = (guac_rdpdr_device*) data;
|
||||||
|
guac_rdpdr_printer_data* printer_data = (guac_rdpdr_printer_data*) device->data;
|
||||||
|
|
||||||
int length;
|
int length;
|
||||||
char buffer[8192];
|
char buffer[8192];
|
||||||
|
|
||||||
/* Write all output as blobs */
|
/* Write all output as blobs */
|
||||||
while ((length = read(rdpdr->printer_output, buffer, sizeof(buffer))) > 0)
|
while ((length = read(printer_data->printer_output, buffer, sizeof(buffer))) > 0)
|
||||||
guac_protocol_send_blob(rdpdr->client->socket,
|
guac_protocol_send_blob(device->rdpdr->client->socket,
|
||||||
GUAC_RDPDR_PRINTER_BLOB, buffer, length);
|
GUAC_RDPDR_PRINTER_BLOB, buffer, length);
|
||||||
|
|
||||||
/* Log any error */
|
/* Log any error */
|
||||||
if (length < 0)
|
if (length < 0)
|
||||||
guac_client_log_error(rdpdr->client, "Error reading from filter: %s", strerror(errno));
|
guac_client_log_error(device->rdpdr->client, "Error reading from filter: %s", strerror(errno));
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int guac_rdpdr_create_print_process(guac_rdpdrPlugin* rdpdr) {
|
static int guac_rdpdr_create_print_process(guac_rdpdr_device* device) {
|
||||||
|
|
||||||
|
guac_rdpdr_printer_data* printer_data = (guac_rdpdr_printer_data*) device->data;
|
||||||
|
|
||||||
int child_pid;
|
int child_pid;
|
||||||
int stdin_pipe[2];
|
int stdin_pipe[2];
|
||||||
@ -61,25 +64,27 @@ static int guac_rdpdr_create_print_process(guac_rdpdrPlugin* rdpdr) {
|
|||||||
|
|
||||||
/* Create STDIN pipe */
|
/* Create STDIN pipe */
|
||||||
if (pipe(stdin_pipe)) {
|
if (pipe(stdin_pipe)) {
|
||||||
guac_client_log_error(rdpdr->client, "Unable to create STDIN pipe for PDF filter process: %s", strerror(errno));
|
guac_client_log_error(device->rdpdr->client,
|
||||||
|
"Unable to create STDIN pipe for PDF filter process: %s", strerror(errno));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Create STDOUT pipe */
|
/* Create STDOUT pipe */
|
||||||
if (pipe(stdout_pipe)) {
|
if (pipe(stdout_pipe)) {
|
||||||
guac_client_log_error(rdpdr->client, "Unable to create STDIN pipe for PDF filter process: %s", strerror(errno));
|
guac_client_log_error(device->rdpdr->client,
|
||||||
|
"Unable to create STDIN pipe for PDF filter process: %s", strerror(errno));
|
||||||
close(stdin_pipe[0]);
|
close(stdin_pipe[0]);
|
||||||
close(stdin_pipe[1]);
|
close(stdin_pipe[1]);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Store our side of stdin/stdout */
|
/* Store our side of stdin/stdout */
|
||||||
rdpdr->printer_input = stdin_pipe[1];
|
printer_data->printer_input = stdin_pipe[1];
|
||||||
rdpdr->printer_output = stdout_pipe[0];
|
printer_data->printer_output = stdout_pipe[0];
|
||||||
|
|
||||||
/* Start output thread */
|
/* Start output thread */
|
||||||
if (pthread_create(&(rdpdr->printer_output_thread), NULL, guac_rdpdr_print_filter_output_thread, rdpdr)) {
|
if (pthread_create(&(printer_data->printer_output_thread), NULL, guac_rdpdr_print_filter_output_thread, device)) {
|
||||||
guac_client_log_error(rdpdr->client, "Unable to fork PDF filter process");
|
guac_client_log_error(device->rdpdr->client, "Unable to fork PDF filter process");
|
||||||
close(stdin_pipe[0]);
|
close(stdin_pipe[0]);
|
||||||
close(stdin_pipe[1]);
|
close(stdin_pipe[1]);
|
||||||
close(stdout_pipe[0]);
|
close(stdout_pipe[0]);
|
||||||
@ -92,7 +97,8 @@ static int guac_rdpdr_create_print_process(guac_rdpdrPlugin* rdpdr) {
|
|||||||
|
|
||||||
/* Log fork errors */
|
/* Log fork errors */
|
||||||
if (child_pid == -1) {
|
if (child_pid == -1) {
|
||||||
guac_client_log_error(rdpdr->client, "Unable to fork PDF filter process: %s", strerror(errno));
|
guac_client_log_error(device->rdpdr->client,
|
||||||
|
"Unable to fork PDF filter process: %s", strerror(errno));
|
||||||
close(stdin_pipe[0]);
|
close(stdin_pipe[0]);
|
||||||
close(stdin_pipe[1]);
|
close(stdin_pipe[1]);
|
||||||
close(stdout_pipe[0]);
|
close(stdout_pipe[0]);
|
||||||
@ -112,11 +118,11 @@ static int guac_rdpdr_create_print_process(guac_rdpdrPlugin* rdpdr) {
|
|||||||
dup2(stdout_pipe[1], STDOUT_FILENO);
|
dup2(stdout_pipe[1], STDOUT_FILENO);
|
||||||
|
|
||||||
/* Run PDF filter */
|
/* Run PDF filter */
|
||||||
guac_client_log_info(rdpdr->client, "Running %s", guac_rdpdr_pdf_filter_command[0]);
|
guac_client_log_info(device->rdpdr->client, "Running %s", guac_rdpdr_pdf_filter_command[0]);
|
||||||
if (execvp(guac_rdpdr_pdf_filter_command[0], guac_rdpdr_pdf_filter_command) < 0)
|
if (execvp(guac_rdpdr_pdf_filter_command[0], guac_rdpdr_pdf_filter_command) < 0)
|
||||||
guac_client_log_error(rdpdr->client, "Unable to execute PDF filter command: %s", strerror(errno));
|
guac_client_log_error(device->rdpdr->client, "Unable to execute PDF filter command: %s", strerror(errno));
|
||||||
else
|
else
|
||||||
guac_client_log_error(rdpdr->client, "Unable to execute PDF filter command, but no error given");
|
guac_client_log_error(device->rdpdr->client, "Unable to execute PDF filter command, but no error given");
|
||||||
|
|
||||||
/* Terminate child process */
|
/* Terminate child process */
|
||||||
exit(1);
|
exit(1);
|
||||||
@ -124,7 +130,7 @@ static int guac_rdpdr_create_print_process(guac_rdpdrPlugin* rdpdr) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Log fork success */
|
/* Log fork success */
|
||||||
guac_client_log_info(rdpdr->client, "Created PDF filter process PID=%i", child_pid);
|
guac_client_log_info(device->rdpdr->client, "Created PDF filter process PID=%i", child_pid);
|
||||||
|
|
||||||
/* Close unneeded ends of pipe */
|
/* Close unneeded ends of pipe */
|
||||||
close(stdin_pipe[0]);
|
close(stdin_pipe[0]);
|
||||||
@ -133,12 +139,14 @@ static int guac_rdpdr_create_print_process(guac_rdpdrPlugin* rdpdr) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_print_job_create(guac_rdpdrPlugin* rdpdr, wStream* input_stream, int completion_id) {
|
void guac_rdpdr_process_print_job_create(guac_rdpdr_device* device,
|
||||||
|
wStream* input_stream, int completion_id) {
|
||||||
|
|
||||||
|
guac_rdpdr_printer_data* printer_data = (guac_rdpdr_printer_data*) device->data;
|
||||||
wStream* output_stream = Stream_New(NULL, 24);
|
wStream* output_stream = Stream_New(NULL, 24);
|
||||||
|
|
||||||
/* No bytes received yet */
|
/* No bytes received yet */
|
||||||
rdpdr->bytes_received = 0;
|
printer_data->bytes_received = 0;
|
||||||
|
|
||||||
/* Write header */
|
/* Write header */
|
||||||
Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
|
Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
|
||||||
@ -150,12 +158,14 @@ void guac_rdpdr_process_print_job_create(guac_rdpdrPlugin* rdpdr, wStream* input
|
|||||||
Stream_Write_UINT32(output_stream, 0); /* Success */
|
Stream_Write_UINT32(output_stream, 0); /* Success */
|
||||||
Stream_Write_UINT32(output_stream, 0); /* fileId */
|
Stream_Write_UINT32(output_stream, 0); /* fileId */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_print_job_write(guac_rdpdrPlugin* rdpdr, wStream* input_stream, int completion_id) {
|
void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device,
|
||||||
|
wStream* input_stream, int completion_id) {
|
||||||
|
|
||||||
|
guac_rdpdr_printer_data* printer_data = (guac_rdpdr_printer_data*) device->data;
|
||||||
int status=0, length;
|
int status=0, length;
|
||||||
unsigned char* buffer;
|
unsigned char* buffer;
|
||||||
|
|
||||||
@ -167,7 +177,7 @@ void guac_rdpdr_process_print_job_write(guac_rdpdrPlugin* rdpdr, wStream* input_
|
|||||||
buffer = Stream_Pointer(input_stream);
|
buffer = Stream_Pointer(input_stream);
|
||||||
|
|
||||||
/* Create print job, if not yet created */
|
/* Create print job, if not yet created */
|
||||||
if (rdpdr->bytes_received == 0) {
|
if (printer_data->bytes_received == 0) {
|
||||||
|
|
||||||
char filename[1024] = "guacamole-print.pdf";
|
char filename[1024] = "guacamole-print.pdf";
|
||||||
unsigned char* search = buffer;
|
unsigned char* search = buffer;
|
||||||
@ -207,27 +217,27 @@ void guac_rdpdr_process_print_job_write(guac_rdpdrPlugin* rdpdr, wStream* input_
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Begin file */
|
/* Begin file */
|
||||||
guac_client_log_info(rdpdr->client, "Print job created");
|
guac_client_log_info(device->rdpdr->client, "Print job created");
|
||||||
guac_protocol_send_file(rdpdr->client->socket,
|
guac_protocol_send_file(device->rdpdr->client->socket,
|
||||||
GUAC_RDPDR_PRINTER_BLOB, "application/pdf", filename);
|
GUAC_RDPDR_PRINTER_BLOB, "application/pdf", filename);
|
||||||
|
|
||||||
/* Start print process */
|
/* Start print process */
|
||||||
if (guac_rdpdr_create_print_process(rdpdr) != 0) {
|
if (guac_rdpdr_create_print_process(device) != 0) {
|
||||||
status = 0x80000010;
|
status = 0x80000010;
|
||||||
length = 0;
|
length = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
rdpdr->bytes_received += length;
|
printer_data->bytes_received += length;
|
||||||
|
|
||||||
/* If not yet failed, write received data */
|
/* If not yet failed, write received data */
|
||||||
if (status == 0) {
|
if (status == 0) {
|
||||||
|
|
||||||
/* Write data to printer, translate output for RDP */
|
/* Write data to printer, translate output for RDP */
|
||||||
length = write(rdpdr->printer_input, buffer, length);
|
length = write(printer_data->printer_input, buffer, length);
|
||||||
if (length == -1) {
|
if (length == -1) {
|
||||||
guac_client_log_error(rdpdr->client, "Error writing to printer: %s", strerror(errno));
|
guac_client_log_error(device->rdpdr->client, "Error writing to printer: %s", strerror(errno));
|
||||||
status = 0x80000010;
|
status = 0x80000010;
|
||||||
length = 0;
|
length = 0;
|
||||||
}
|
}
|
||||||
@ -245,24 +255,26 @@ void guac_rdpdr_process_print_job_write(guac_rdpdrPlugin* rdpdr, wStream* input_
|
|||||||
Stream_Write_UINT32(output_stream, length);
|
Stream_Write_UINT32(output_stream, length);
|
||||||
Stream_Write_UINT8(output_stream, 0); /* padding (stated as optional in spec, but requests fail without) */
|
Stream_Write_UINT8(output_stream, 0); /* padding (stated as optional in spec, but requests fail without) */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_print_job_close(guac_rdpdrPlugin* rdpdr, wStream* input_stream, int completion_id) {
|
void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device,
|
||||||
|
wStream* input_stream, int completion_id) {
|
||||||
|
|
||||||
|
guac_rdpdr_printer_data* printer_data = (guac_rdpdr_printer_data*) device->data;
|
||||||
wStream* output_stream = Stream_New(NULL, 24);
|
wStream* output_stream = Stream_New(NULL, 24);
|
||||||
|
|
||||||
/* Close input and wait for output thread to finish */
|
/* Close input and wait for output thread to finish */
|
||||||
close(rdpdr->printer_input);
|
close(printer_data->printer_input);
|
||||||
pthread_join(rdpdr->printer_output_thread, NULL);
|
pthread_join(printer_data->printer_output_thread, NULL);
|
||||||
|
|
||||||
/* Close file descriptors */
|
/* Close file descriptors */
|
||||||
close(rdpdr->printer_output);
|
close(printer_data->printer_output);
|
||||||
|
|
||||||
/* Close file */
|
/* Close file */
|
||||||
guac_client_log_info(rdpdr->client, "Print job closed");
|
guac_client_log_info(device->rdpdr->client, "Print job closed");
|
||||||
guac_protocol_send_end(rdpdr->client->socket, GUAC_RDPDR_PRINTER_BLOB);
|
guac_protocol_send_end(device->rdpdr->client->socket, GUAC_RDPDR_PRINTER_BLOB);
|
||||||
|
|
||||||
/* Write header */
|
/* Write header */
|
||||||
Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
|
Stream_Write_UINT16(output_stream, RDPDR_CTYP_CORE);
|
||||||
@ -274,7 +286,56 @@ void guac_rdpdr_process_print_job_close(guac_rdpdrPlugin* rdpdr, wStream* input_
|
|||||||
Stream_Write_UINT32(output_stream, 0); /* NTSTATUS - success */
|
Stream_Write_UINT32(output_stream, 0); /* NTSTATUS - success */
|
||||||
Stream_Write_UINT32(output_stream, 0); /* padding*/
|
Stream_Write_UINT32(output_stream, 0); /* padding*/
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
|
||||||
|
switch (major_func) {
|
||||||
|
|
||||||
|
/* Print job create */
|
||||||
|
case IRP_MJ_CREATE:
|
||||||
|
guac_rdpdr_process_print_job_create(device, input_stream, completion_id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Printer job write */
|
||||||
|
case IRP_MJ_WRITE:
|
||||||
|
guac_rdpdr_process_print_job_write(device, input_stream, completion_id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Printer job close */
|
||||||
|
case IRP_MJ_CLOSE:
|
||||||
|
guac_rdpdr_process_print_job_close(device, input_stream, completion_id);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* Log unknown */
|
||||||
|
default:
|
||||||
|
guac_client_log_error(device->rdpdr->client,
|
||||||
|
"Unknown printer I/O request function: 0x%x/0x%x",
|
||||||
|
major_func, minor_func);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
static void guac_rdpdr_device_printer_free_handler(guac_rdpdr_device* device) {
|
||||||
|
free(device->data);
|
||||||
|
}
|
||||||
|
|
||||||
|
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr) {
|
||||||
|
|
||||||
|
/* Get new device */
|
||||||
|
guac_rdpdr_device* device = &(rdpdr->devices[rdpdr->devices_registered++]);
|
||||||
|
|
||||||
|
/* Init device */
|
||||||
|
device->rdpdr = rdpdr;
|
||||||
|
device->iorequest_handler = guac_rdpdr_device_printer_iorequest_handler;
|
||||||
|
device->free_handler = guac_rdpdr_device_printer_free_handler;
|
||||||
|
|
||||||
|
/* Init data */
|
||||||
|
device->data = malloc(sizeof(guac_rdpdr_printer_data));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,13 +51,40 @@
|
|||||||
*/
|
*/
|
||||||
#define GUAC_RDPDR_PRINTER_BLOB 0
|
#define GUAC_RDPDR_PRINTER_BLOB 0
|
||||||
|
|
||||||
/*
|
/**
|
||||||
* Message handlers.
|
* Data specific to an instance of the printer device.
|
||||||
*/
|
*/
|
||||||
|
typedef struct guac_rdpdr_printer_data {
|
||||||
|
|
||||||
void guac_rdpdr_process_print_job_create(guac_rdpdrPlugin* rdpdr, wStream* input_stream, int completion_id);
|
/**
|
||||||
void guac_rdpdr_process_print_job_write(guac_rdpdrPlugin* rdpdr, wStream* input_stream, int completion_id);
|
* File descriptor that should be written to when sending documents to the
|
||||||
void guac_rdpdr_process_print_job_close(guac_rdpdrPlugin* rdpdr, wStream* input_stream, int completion_id);
|
* printer.
|
||||||
|
*/
|
||||||
|
int printer_input;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* File descriptor that should be read from when receiving output from the
|
||||||
|
* printer.
|
||||||
|
*/
|
||||||
|
int printer_output;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Thread which transfers data from the printer to the Guacamole client.
|
||||||
|
*/
|
||||||
|
pthread_t printer_output_thread;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of bytes received in the current print job.
|
||||||
|
*/
|
||||||
|
int bytes_received;
|
||||||
|
|
||||||
|
} guac_rdpdr_printer_data;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Registers a new printer device within the RDPDR plugin. This must be done
|
||||||
|
* before RDPDR connection finishes.
|
||||||
|
*/
|
||||||
|
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The command to run when filtering postscript to produce PDF. This must be
|
* The command to run when filtering postscript to produce PDF. This must be
|
||||||
|
@ -48,11 +48,58 @@
|
|||||||
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
|
|
||||||
|
typedef struct guac_rdpdrPlugin guac_rdpdrPlugin;
|
||||||
|
typedef struct guac_rdpdr_device guac_rdpdr_device;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for device I/O requests.
|
||||||
|
*/
|
||||||
|
typedef void guac_rdpdr_device_iorequest_handler(guac_rdpdr_device* device,
|
||||||
|
wStream* input_stream, int file_id, int completion_id, int major_func, int minor_func);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler for cleaning up the dynamically-allocated portions of a device.
|
||||||
|
*/
|
||||||
|
typedef void guac_rdpdr_device_free_handler(guac_rdpdr_device* device);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arbitrary device forwarded over the RDPDR channel.
|
||||||
|
*/
|
||||||
|
struct guac_rdpdr_device {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The RDPDR plugin owning this device.
|
||||||
|
*/
|
||||||
|
guac_rdpdrPlugin* rdpdr;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An arbitrary device name, used for logging purposes only.
|
||||||
|
*/
|
||||||
|
const char* device_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handler which should be called for every I/O request received.
|
||||||
|
*/
|
||||||
|
guac_rdpdr_device_iorequest_handler* iorequest_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handlel which should be called when the device is being free'd.
|
||||||
|
*/
|
||||||
|
guac_rdpdr_device_free_handler* free_handler;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Arbitrary data, used internally by the handlers for this device.
|
||||||
|
*/
|
||||||
|
void* data;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Structure representing the current state of the Guacamole RDPDR plugin for
|
* Structure representing the current state of the Guacamole RDPDR plugin for
|
||||||
* FreeRDP.
|
* FreeRDP.
|
||||||
*/
|
*/
|
||||||
typedef struct guac_rdpdrPlugin {
|
struct guac_rdpdrPlugin {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The FreeRDP parts of this plugin. This absolutely MUST be first.
|
* The FreeRDP parts of this plugin. This absolutely MUST be first.
|
||||||
@ -67,28 +114,16 @@ typedef struct guac_rdpdrPlugin {
|
|||||||
guac_client* client;
|
guac_client* client;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File descriptor that should be written to when sending documents to the
|
* The number of devices registered within the devices array.
|
||||||
* printer.
|
|
||||||
*/
|
*/
|
||||||
int printer_input;
|
int devices_registered;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* File descriptor that should be read from when receiving output from the
|
* Array of registered devices.
|
||||||
* printer.
|
|
||||||
*/
|
*/
|
||||||
int printer_output;
|
guac_rdpdr_device devices[8];
|
||||||
|
|
||||||
/**
|
};
|
||||||
* Thread which transfers data from the printer to the Guacamole client.
|
|
||||||
*/
|
|
||||||
pthread_t printer_output_thread;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* The number of bytes received in the current print job.
|
|
||||||
*/
|
|
||||||
int bytes_received;
|
|
||||||
|
|
||||||
} guac_rdpdrPlugin;
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user