Actually read print job data.

This commit is contained in:
Michael Jumper 2013-06-22 17:43:05 -07:00
parent c07eb9c063
commit 06ef43bd2c
7 changed files with 193 additions and 19 deletions

View File

@ -67,10 +67,12 @@ guac_rdpsnd_la_SOURCES = \
guac_rdpdr_la_SOURCES = \
guac_rdpdr/rdpdr_messages.c \
guac_rdpdr/rdpdr_printer.c \
guac_rdpdr/rdpdr_service.c
noinst_HEADERS = \
guac_rdpdr/rdpdr_messages.h \
guac_rdpdr/rdpdr_printer.h \
guac_rdpdr/rdpdr_service.h \
guac_rdpsnd/rdpsnd_messages.h \
guac_rdpsnd/rdpsnd_service.h \

View File

@ -48,6 +48,7 @@
#include "rdpdr_service.h"
#include "rdpdr_messages.h"
#include "rdpdr_printer.h"
#include "client.h"
@ -229,15 +230,46 @@ void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, STREAM* input_stre
void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, STREAM* input_stream) {
/* STUB */
guac_client_log_info(rdpdr->client, "STUB: device_iorequest");
int device_id, completion_id, major_func, minor_func;
}
/* Read header */
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, completion_id);
stream_read_uint32(input_stream, major_func);
stream_read_uint32(input_stream, minor_func);
void guac_rdpdr_process_device_iocompletion(guac_rdpdrPlugin* rdpdr, STREAM* input_stream) {
/* If printer, run printer handlers */
if (device_id == GUAC_PRINTER_DEVICE_ID) {
/* STUB */
guac_client_log_info(rdpdr->client, "STUB: device_iocompletion");
switch (major_func) {
/* Print job create */
case IRP_MJ_CREATE:
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);
}
}
else
guac_client_log_error(rdpdr->client, "Unknown device ID: 0x%08x", device_id);
}
@ -278,16 +310,10 @@ void guac_rdpdr_process_user_loggedon(guac_rdpdrPlugin* rdpdr, STREAM* input_str
}
void guac_rdpdr_process_prn_cache_data(guac_rdpdrPlugin* rdpdr, STREAM* input_stream) {
/* STUB */
guac_client_log_info(rdpdr->client, "STUB: prn_cache_data");
guac_client_log_info(rdpdr->client, "Ignoring printer cached configuration data");
}
void guac_rdpdr_process_prn_using_xps(guac_rdpdrPlugin* rdpdr, STREAM* input_stream) {
/* STUB */
guac_client_log_info(rdpdr->client, "STUB: prn_using_xps");
guac_client_log_info(rdpdr->client, "Printer unexpectedly switched to XPS mode");
}

View File

@ -38,6 +38,8 @@
#ifndef __GUAC_RDPDR_MESSAGES_H
#define __GUAC_RDPDR_MESSAGES_H
#include "rdpdr_service.h"
/**
* Identifies the "core" component of RDPDR as the destination of the received
* packet.
@ -158,6 +160,25 @@
#define RDPDR_PRINTER_ANNOUNCE_FLAG_TSPRINTER 0x00000008
#define RDPDR_PRINTER_ANNOUNCE_FLAG_XPSFORMAT 0x00000010
/*
* I/O requests.
*/
#define IRP_MJ_CREATE 0x00000000
#define IRP_MJ_CLOSE 0x00000002
#define IRP_MJ_READ 0x00000003
#define IRP_MJ_WRITE 0x00000004
#define IRP_MJ_DEVICE_CONTROL 0x0000000E
#define IRP_MJ_QUERY_VOLUME_INFORMATION 0x0000000A
#define IRP_MJ_SET_VOLUME_INFORMATION 0x0000000B
#define IRP_MJ_QUERY_INFORMATION 0x00000005
#define IRP_MJ_SET_INFORMATION 0x00000006
#define IRP_MJ_DIRECTORY_CONTROL 0x0000000C
#define IRP_MJ_LOCK_CONTROL 0x00000011
#define IRP_MN_QUERY_DIRECTORY 0x00000001
#define IRP_MN_NOTIFY_CHANGE_DIRECTORY 0x00000002
/*
* Message handlers.
*/
@ -166,7 +187,6 @@ void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr, STREAM* input_s
void guac_rdpdr_process_clientid_confirm(guac_rdpdrPlugin* rdpdr, STREAM* input_stream);
void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, STREAM* input_stream);
void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, STREAM* input_stream);
void guac_rdpdr_process_device_iocompletion(guac_rdpdrPlugin* rdpdr, STREAM* input_stream);
void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, STREAM* input_stream);
void guac_rdpdr_process_user_loggedon(guac_rdpdrPlugin* rdpdr, STREAM* input_stream);
void guac_rdpdr_process_prn_cache_data(guac_rdpdrPlugin* rdpdr, STREAM* input_stream);

View File

@ -0,0 +1,75 @@
#include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h>
#include "rdpdr_messages.h"
#include "rdpdr_service.h"
void guac_rdpdr_process_print_job_create(guac_rdpdrPlugin* rdpdr, STREAM* input_stream, int completion_id) {
STREAM* output_stream = stream_new(24);
guac_client_log_info(rdpdr->client, "Print job created");
/* Write header */
stream_write_uint16(output_stream, RDPDR_CTYP_CORE);
stream_write_uint16(output_stream, PAKID_CORE_DEVICE_IOCOMPLETION);
/* Write content */
stream_write_uint32(output_stream, GUAC_PRINTER_DEVICE_ID);
stream_write_uint32(output_stream, completion_id);
stream_write_uint32(output_stream, 0); /* NTSTATUS - success */
stream_write_uint32(output_stream, 0); /* fileId */
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
}
void guac_rdpdr_process_print_job_write(guac_rdpdrPlugin* rdpdr, STREAM* input_stream, int completion_id) {
int length;
STREAM* output_stream = stream_new(24);
stream_read_uint32(input_stream, length);
stream_seek(input_stream, 8); /* Offset */
stream_seek(input_stream, 20); /* Padding */
/* TODO: Here, read data */
guac_client_log_info(rdpdr->client, "Data received: %i bytes", length);
/* Write header */
stream_write_uint16(output_stream, RDPDR_CTYP_CORE);
stream_write_uint16(output_stream, PAKID_CORE_DEVICE_IOCOMPLETION);
/* Write content */
stream_write_uint32(output_stream, GUAC_PRINTER_DEVICE_ID);
stream_write_uint32(output_stream, completion_id);
stream_write_uint32(output_stream, 0); /* NTSTATUS - success */
stream_write_uint32(output_stream, length);
stream_write_uint8(output_stream, 0); /* padding (stated as optional in spec, but requests fail without) */
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
}
void guac_rdpdr_process_print_job_close(guac_rdpdrPlugin* rdpdr, STREAM* input_stream, int completion_id) {
STREAM* output_stream = stream_new(24);
guac_client_log_info(rdpdr->client, "Print job closed");
/* Write header */
stream_write_uint16(output_stream, RDPDR_CTYP_CORE);
stream_write_uint16(output_stream, PAKID_CORE_DEVICE_IOCOMPLETION);
/* Write content */
stream_write_uint32(output_stream, GUAC_PRINTER_DEVICE_ID);
stream_write_uint32(output_stream, completion_id);
stream_write_uint32(output_stream, 0); /* NTSTATUS - success */
stream_write_uint32(output_stream, 0); /* padding*/
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
}

View File

@ -0,0 +1,53 @@
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
* http://www.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is libguac-client-rdp.
*
* The Initial Developer of the Original Code is
* Michael Jumper.
* Portions created by the Initial Developer are Copyright (C) 2011
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef __GUAC_RDPDR_PRINTER_H
#define __GUAC_RDPDR_PRINTER_H
#include <freerdp/utils/stream.h>
#include <freerdp/utils/svc_plugin.h>
/*
* Message handlers.
*/
void guac_rdpdr_process_print_job_create(guac_rdpdrPlugin* rdpdr, STREAM* input_stream, int completion_id);
void guac_rdpdr_process_print_job_write(guac_rdpdrPlugin* rdpdr, STREAM* input_stream, int completion_id);
void guac_rdpdr_process_print_job_close(guac_rdpdrPlugin* rdpdr, STREAM* input_stream, int completion_id);
#endif

View File

@ -119,10 +119,6 @@ void guac_rdpdr_process_receive(rdpSvcPlugin* plugin,
guac_rdpdr_process_device_iorequest(rdpdr, input_stream);
break;
case PAKID_CORE_DEVICE_IOCOMPLETION:
guac_rdpdr_process_device_iocompletion(rdpdr, input_stream);
break;
case PAKID_CORE_SERVER_CAPABILITY:
guac_rdpdr_process_server_capability(rdpdr, input_stream);
break;

View File

@ -38,6 +38,8 @@
#ifndef __GUAC_RDPDR_SERVICE_H
#define __GUAC_RDPDR_SERVICE_H
#include <guacamole/client.h>
/**
* Structure representing the current state of the Guacamole RDPDR plugin for
* FreeRDP.