GUACAMOLE-249: Migrate RDPDR support to FreeRDP 2.0.0 plugin API.
This commit is contained in:
parent
68710a6702
commit
ee4d91ea98
@ -132,9 +132,9 @@ libguac_client_rdp_la_LIBADD = \
|
|||||||
|
|
||||||
freerdp_LTLIBRARIES = \
|
freerdp_LTLIBRARIES = \
|
||||||
libguacai-client.la \
|
libguacai-client.la \
|
||||||
|
libguacdr-client.la \
|
||||||
libguacsnd-client.la \
|
libguacsnd-client.la \
|
||||||
libguacsvc-client.la
|
libguacsvc-client.la
|
||||||
# libguacdr-client.la
|
|
||||||
|
|
||||||
freerdpdir = ${libdir}/freerdp2
|
freerdpdir = ${libdir}/freerdp2
|
||||||
|
|
||||||
@ -142,35 +142,35 @@ freerdpdir = ${libdir}/freerdp2
|
|||||||
# RDPDR
|
# RDPDR
|
||||||
#
|
#
|
||||||
|
|
||||||
#libguacdr_client_la_SOURCES = \
|
libguacdr_client_la_SOURCES = \
|
||||||
# guac_rdpdr/rdpdr_fs_messages.c \
|
guac_rdpdr/rdpdr_fs_messages.c \
|
||||||
# guac_rdpdr/rdpdr_fs_messages_dir_info.c \
|
guac_rdpdr/rdpdr_fs_messages_dir_info.c \
|
||||||
# guac_rdpdr/rdpdr_fs_messages_file_info.c \
|
guac_rdpdr/rdpdr_fs_messages_file_info.c \
|
||||||
# guac_rdpdr/rdpdr_fs_messages_vol_info.c \
|
guac_rdpdr/rdpdr_fs_messages_vol_info.c \
|
||||||
# guac_rdpdr/rdpdr_fs_service.c \
|
guac_rdpdr/rdpdr_fs_service.c \
|
||||||
# guac_rdpdr/rdpdr_messages.c \
|
guac_rdpdr/rdpdr_messages.c \
|
||||||
# guac_rdpdr/rdpdr_printer.c \
|
guac_rdpdr/rdpdr_printer.c \
|
||||||
# guac_rdpdr/rdpdr_service.c \
|
guac_rdpdr/rdpdr_service.c \
|
||||||
# rdp_fs.c \
|
rdp_fs.c \
|
||||||
# rdp_print_job.c \
|
rdp_print_job.c \
|
||||||
# rdp_stream.c \
|
rdp_stream.c \
|
||||||
# unicode.c
|
unicode.c
|
||||||
#
|
|
||||||
#libguacdr_client_la_CFLAGS = \
|
libguacdr_client_la_CFLAGS = \
|
||||||
# -Werror -Wall -Iinclude \
|
-Werror -Wall -Iinclude \
|
||||||
# @COMMON_INCLUDE@ \
|
@COMMON_INCLUDE@ \
|
||||||
# @COMMON_SSH_INCLUDE@ \
|
@COMMON_SSH_INCLUDE@ \
|
||||||
# @LIBGUAC_INCLUDE@ \
|
@LIBGUAC_INCLUDE@ \
|
||||||
# @RDP_CFLAGS@
|
@RDP_CFLAGS@
|
||||||
#
|
|
||||||
#libguacdr_client_la_LDFLAGS = \
|
libguacdr_client_la_LDFLAGS = \
|
||||||
# -module -avoid-version -shared \
|
-module -avoid-version -shared \
|
||||||
# @PTHREAD_LIBS@ \
|
@PTHREAD_LIBS@ \
|
||||||
# @RDP_LIBS@
|
@RDP_LIBS@
|
||||||
#
|
|
||||||
#libguacdr_client_la_LIBADD = \
|
libguacdr_client_la_LIBADD = \
|
||||||
# @COMMON_LTLIB@ \
|
@COMMON_LTLIB@ \
|
||||||
# @LIBGUAC_LTLIB@
|
@LIBGUAC_LTLIB@
|
||||||
|
|
||||||
#
|
#
|
||||||
# Audio Input
|
# Audio Input
|
||||||
|
@ -29,7 +29,6 @@
|
|||||||
#include "rdp_status.h"
|
#include "rdp_status.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
#include <winpr/wtypes.h>
|
#include <winpr/wtypes.h>
|
||||||
@ -110,7 +109,9 @@ void guac_rdpdr_fs_process_create(guac_rdpdr_device* device,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -158,7 +159,9 @@ void guac_rdpdr_fs_process_read(guac_rdpdr_device* device,
|
|||||||
Stream_Write(output_stream, buffer, bytes_read); /* ReadData */
|
Stream_Write(output_stream, buffer, bytes_read); /* ReadData */
|
||||||
}
|
}
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
free(buffer);
|
free(buffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -201,7 +204,9 @@ void guac_rdpdr_fs_process_write(guac_rdpdr_device* device,
|
|||||||
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
||||||
}
|
}
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -234,7 +239,9 @@ void guac_rdpdr_fs_process_close(guac_rdpdr_device* device,
|
|||||||
STATUS_SUCCESS, 4);
|
STATUS_SUCCESS, 4);
|
||||||
Stream_Write(output_stream, "\0\0\0\0", 4); /* Padding */
|
Stream_Write(output_stream, "\0\0\0\0", 4); /* Padding */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -322,7 +329,9 @@ void guac_rdpdr_fs_process_set_volume_info(guac_rdpdr_device* device,
|
|||||||
"%s: [file_id=%i] Set volume info not supported",
|
"%s: [file_id=%i] Set volume info not supported",
|
||||||
__func__, file_id);
|
__func__, file_id);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -385,7 +394,9 @@ void guac_rdpdr_fs_process_device_control(guac_rdpdr_device* device,
|
|||||||
/* No content for now */
|
/* No content for now */
|
||||||
Stream_Write_UINT32(output_stream, 0);
|
Stream_Write_UINT32(output_stream, 0);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -501,7 +512,9 @@ void guac_rdpdr_fs_process_query_directory(guac_rdpdr_device* device, wStream* i
|
|||||||
Stream_Write_UINT32(output_stream, 0); /* Length */
|
Stream_Write_UINT32(output_stream, 0); /* Length */
|
||||||
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -517,7 +530,9 @@ void guac_rdpdr_fs_process_lock_control(guac_rdpdr_device* device, wStream* inpu
|
|||||||
|
|
||||||
Stream_Zero(output_stream, 5); /* Padding */
|
Stream_Zero(output_stream, 5); /* Padding */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "rdp_status.h"
|
#include "rdp_status.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <guacamole/unicode.h>
|
#include <guacamole/unicode.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
|
|
||||||
@ -72,7 +71,9 @@ void guac_rdpdr_fs_process_query_directory_info(guac_rdpdr_device* device,
|
|||||||
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
||||||
Stream_Write(output_stream, "\0\0", 2);
|
Stream_Write(output_stream, "\0\0", 2);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -119,7 +120,9 @@ void guac_rdpdr_fs_process_query_full_directory_info(guac_rdpdr_device* device,
|
|||||||
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
||||||
Stream_Write(output_stream, "\0\0", 2);
|
Stream_Write(output_stream, "\0\0", 2);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +173,9 @@ void guac_rdpdr_fs_process_query_both_directory_info(guac_rdpdr_device* device,
|
|||||||
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
||||||
Stream_Write(output_stream, "\0\0", 2);
|
Stream_Write(output_stream, "\0\0", 2);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -208,7 +213,9 @@ void guac_rdpdr_fs_process_query_names_info(guac_rdpdr_device* device,
|
|||||||
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
Stream_Write(output_stream, utf16_entry_name, utf16_length); /* FileName */
|
||||||
Stream_Write(output_stream, "\0\0", 2);
|
Stream_Write(output_stream, "\0\0", 2);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "rdp_status.h"
|
#include "rdp_status.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
#include <winpr/wtypes.h>
|
#include <winpr/wtypes.h>
|
||||||
|
|
||||||
@ -59,7 +58,9 @@ void guac_rdpdr_fs_process_query_basic_info(guac_rdpdr_device* device, wStream*
|
|||||||
|
|
||||||
/* Reserved field must not be sent */
|
/* Reserved field must not be sent */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -94,7 +95,9 @@ void guac_rdpdr_fs_process_query_standard_info(guac_rdpdr_device* device, wStrea
|
|||||||
|
|
||||||
/* Reserved field must not be sent */
|
/* Reserved field must not be sent */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,7 +125,9 @@ void guac_rdpdr_fs_process_query_attribute_tag_info(guac_rdpdr_device* device,
|
|||||||
|
|
||||||
/* Reserved field must not be sent */
|
/* Reserved field must not be sent */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -179,7 +184,9 @@ void guac_rdpdr_fs_process_set_rename_info(guac_rdpdr_device* device,
|
|||||||
}
|
}
|
||||||
|
|
||||||
Stream_Write_UINT32(output_stream, length);
|
Stream_Write_UINT32(output_stream, length);
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -207,7 +214,9 @@ void guac_rdpdr_fs_process_set_allocation_info(guac_rdpdr_device* device,
|
|||||||
completion_id, STATUS_SUCCESS, 4);
|
completion_id, STATUS_SUCCESS, 4);
|
||||||
|
|
||||||
Stream_Write_UINT32(output_stream, length);
|
Stream_Write_UINT32(output_stream, length);
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -231,7 +240,9 @@ void guac_rdpdr_fs_process_set_disposition_info(guac_rdpdr_device* device,
|
|||||||
|
|
||||||
Stream_Write_UINT32(output_stream, length);
|
Stream_Write_UINT32(output_stream, length);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -259,7 +270,9 @@ void guac_rdpdr_fs_process_set_end_of_file_info(guac_rdpdr_device* device,
|
|||||||
completion_id, STATUS_SUCCESS, 4);
|
completion_id, STATUS_SUCCESS, 4);
|
||||||
|
|
||||||
Stream_Write_UINT32(output_stream, length);
|
Stream_Write_UINT32(output_stream, length);
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +289,9 @@ void guac_rdpdr_fs_process_set_basic_info(guac_rdpdr_device* device,
|
|||||||
"%s: [file_id=%i] IGNORED",
|
"%s: [file_id=%i] IGNORED",
|
||||||
__func__, file_id);
|
__func__, file_id);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "rdp_fs.h"
|
#include "rdp_fs.h"
|
||||||
#include "rdp_status.h"
|
#include "rdp_status.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <guacamole/unicode.h>
|
#include <guacamole/unicode.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
#include <winpr/wtypes.h>
|
#include <winpr/wtypes.h>
|
||||||
@ -47,7 +46,9 @@ void guac_rdpdr_fs_process_query_volume_info(guac_rdpdr_device* device,
|
|||||||
/* Reserved field must not be sent */
|
/* Reserved field must not be sent */
|
||||||
Stream_Write(output_stream, GUAC_FILESYSTEM_LABEL, GUAC_FILESYSTEM_LABEL_LENGTH);
|
Stream_Write(output_stream, GUAC_FILESYSTEM_LABEL, GUAC_FILESYSTEM_LABEL_LENGTH);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +71,9 @@ void guac_rdpdr_fs_process_query_size_info(guac_rdpdr_device* device, wStream* i
|
|||||||
Stream_Write_UINT32(output_stream, 1); /* SectorsPerAllocationUnit */
|
Stream_Write_UINT32(output_stream, 1); /* SectorsPerAllocationUnit */
|
||||||
Stream_Write_UINT32(output_stream, info.block_size); /* BytesPerSector */
|
Stream_Write_UINT32(output_stream, info.block_size); /* BytesPerSector */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -88,7 +91,9 @@ void guac_rdpdr_fs_process_query_device_info(guac_rdpdr_device* device, wStream*
|
|||||||
Stream_Write_UINT32(output_stream, FILE_DEVICE_DISK); /* DeviceType */
|
Stream_Write_UINT32(output_stream, FILE_DEVICE_DISK); /* DeviceType */
|
||||||
Stream_Write_UINT32(output_stream, 0); /* Characteristics */
|
Stream_Write_UINT32(output_stream, 0); /* Characteristics */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,7 +118,9 @@ void guac_rdpdr_fs_process_query_attribute_info(guac_rdpdr_device* device, wStre
|
|||||||
Stream_Write_UINT32(output_stream, name_len);
|
Stream_Write_UINT32(output_stream, name_len);
|
||||||
Stream_Write(output_stream, device->device_name, name_len);
|
Stream_Write(output_stream, device->device_name, name_len);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -137,7 +144,9 @@ void guac_rdpdr_fs_process_query_full_size_info(guac_rdpdr_device* device, wStre
|
|||||||
Stream_Write_UINT32(output_stream, 1); /* SectorsPerAllocationUnit */
|
Stream_Write_UINT32(output_stream, 1); /* SectorsPerAllocationUnit */
|
||||||
Stream_Write_UINT32(output_stream, info.block_size); /* BytesPerSector */
|
Stream_Write_UINT32(output_stream, info.block_size); /* BytesPerSector */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,7 +25,6 @@
|
|||||||
#include "rdpdr_messages.h"
|
#include "rdpdr_messages.h"
|
||||||
#include "rdpdr_service.h"
|
#include "rdpdr_service.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/protocol.h>
|
#include <guacamole/protocol.h>
|
||||||
#include <guacamole/socket.h>
|
#include <guacamole/socket.h>
|
||||||
@ -114,7 +113,7 @@ static void guac_rdpdr_device_fs_free_handler(guac_rdpdr_device* device) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr, char* drive_name) {
|
void guac_rdpdr_register_fs(guac_rdpdr* rdpdr, char* drive_name) {
|
||||||
|
|
||||||
guac_client* client = rdpdr->client;
|
guac_client* client = rdpdr->client;
|
||||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
|
@ -48,7 +48,7 @@
|
|||||||
* @param drive_name
|
* @param drive_name
|
||||||
* The name of the redirected drive to display in the RDP connection.
|
* The name of the redirected drive to display in the RDP connection.
|
||||||
*/
|
*/
|
||||||
void guac_rdpdr_register_fs(guac_rdpdrPlugin* rdpdr, char* drive_name);
|
void guac_rdpdr_register_fs(guac_rdpdr* rdpdr, char* drive_name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -24,7 +24,6 @@
|
|||||||
#include "rdpdr_service.h"
|
#include "rdpdr_service.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/unicode.h>
|
#include <guacamole/unicode.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
@ -32,7 +31,7 @@
|
|||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
static void guac_rdpdr_send_client_announce_reply(guac_rdpdrPlugin* rdpdr,
|
static void guac_rdpdr_send_client_announce_reply(guac_rdpdr* rdpdr,
|
||||||
unsigned int major, unsigned int minor, unsigned int client_id) {
|
unsigned int major, unsigned int minor, unsigned int client_id) {
|
||||||
|
|
||||||
wStream* output_stream = Stream_New(NULL, 12);
|
wStream* output_stream = Stream_New(NULL, 12);
|
||||||
@ -46,11 +45,13 @@ static void guac_rdpdr_send_client_announce_reply(guac_rdpdrPlugin* rdpdr,
|
|||||||
Stream_Write_UINT16(output_stream, minor);
|
Stream_Write_UINT16(output_stream, minor);
|
||||||
Stream_Write_UINT32(output_stream, client_id);
|
Stream_Write_UINT32(output_stream, client_id);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle,
|
||||||
|
rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void guac_rdpdr_send_client_name_request(guac_rdpdrPlugin* rdpdr, const char* name) {
|
static void guac_rdpdr_send_client_name_request(guac_rdpdr* rdpdr, const char* name) {
|
||||||
|
|
||||||
int name_bytes = strlen(name) + 1;
|
int name_bytes = strlen(name) + 1;
|
||||||
wStream* output_stream = Stream_New(NULL, 16 + name_bytes);
|
wStream* output_stream = Stream_New(NULL, 16 + name_bytes);
|
||||||
@ -65,11 +66,13 @@ static void guac_rdpdr_send_client_name_request(guac_rdpdrPlugin* rdpdr, const c
|
|||||||
Stream_Write_UINT32(output_stream, name_bytes);
|
Stream_Write_UINT32(output_stream, name_bytes);
|
||||||
Stream_Write(output_stream, name, name_bytes);
|
Stream_Write(output_stream, name, name_bytes);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle,
|
||||||
|
rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void guac_rdpdr_send_client_capability(guac_rdpdrPlugin* rdpdr) {
|
static void guac_rdpdr_send_client_capability(guac_rdpdr* rdpdr) {
|
||||||
|
|
||||||
wStream* output_stream = Stream_New(NULL, 256);
|
wStream* output_stream = Stream_New(NULL, 256);
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Sending capabilities...");
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Sending capabilities...");
|
||||||
@ -112,12 +115,14 @@ static void guac_rdpdr_send_client_capability(guac_rdpdrPlugin* rdpdr) {
|
|||||||
Stream_Write_UINT16(output_stream, 8);
|
Stream_Write_UINT16(output_stream, 8);
|
||||||
Stream_Write_UINT32(output_stream, DRIVE_CAPABILITY_VERSION_02);
|
Stream_Write_UINT32(output_stream, DRIVE_CAPABILITY_VERSION_02);
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle,
|
||||||
|
rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Capabilities sent.");
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Capabilities sent.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdrPlugin* rdpdr) {
|
static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdr* rdpdr) {
|
||||||
|
|
||||||
/* Calculate number of bytes needed for the stream */
|
/* Calculate number of bytes needed for the stream */
|
||||||
int streamBytes = 16;
|
int streamBytes = 16;
|
||||||
@ -144,12 +149,14 @@ static void guac_rdpdr_send_client_device_list_announce_request(guac_rdpdrPlugin
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) rdpdr, output_stream);
|
rdpdr->entry_points.pVirtualChannelWriteEx(rdpdr->init_handle,
|
||||||
|
rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "All supported devices sent.");
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "All supported devices sent.");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr,
|
void guac_rdpdr_process_server_announce(guac_rdpdr* rdpdr,
|
||||||
wStream* input_stream) {
|
wStream* input_stream) {
|
||||||
|
|
||||||
unsigned int major, minor, client_id;
|
unsigned int major, minor, client_id;
|
||||||
@ -172,11 +179,11 @@ void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_clientid_confirm(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
void guac_rdpdr_process_clientid_confirm(guac_rdpdr* rdpdr, wStream* input_stream) {
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Client ID confirmed");
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Client ID confirmed");
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
void guac_rdpdr_process_device_reply(guac_rdpdr* rdpdr, wStream* input_stream) {
|
||||||
|
|
||||||
unsigned int device_id, ntstatus;
|
unsigned int device_id, ntstatus;
|
||||||
int severity, c, n, facility, code;
|
int severity, c, n, facility, code;
|
||||||
@ -210,7 +217,7 @@ 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_rdpdr* rdpdr, wStream* input_stream) {
|
||||||
|
|
||||||
int device_id, file_id, completion_id, major_func, minor_func;
|
int device_id, file_id, completion_id, major_func, minor_func;
|
||||||
|
|
||||||
@ -236,7 +243,7 @@ void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
void guac_rdpdr_process_server_capability(guac_rdpdr* rdpdr, wStream* input_stream) {
|
||||||
|
|
||||||
int count;
|
int count;
|
||||||
int i;
|
int i;
|
||||||
@ -265,17 +272,17 @@ void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* inpu
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_user_loggedon(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
void guac_rdpdr_process_user_loggedon(guac_rdpdr* rdpdr, wStream* input_stream) {
|
||||||
|
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "User logged on");
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "User logged on");
|
||||||
guac_rdpdr_send_client_device_list_announce_request(rdpdr);
|
guac_rdpdr_send_client_device_list_announce_request(rdpdr);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_prn_cache_data(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
void guac_rdpdr_process_prn_cache_data(guac_rdpdr* rdpdr, wStream* input_stream) {
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring printer cached configuration data");
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Ignoring printer cached configuration data");
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_process_prn_using_xps(guac_rdpdrPlugin* rdpdr, wStream* input_stream) {
|
void guac_rdpdr_process_prn_using_xps(guac_rdpdr* rdpdr, wStream* input_stream) {
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Printer unexpectedly switched to XPS mode");
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Printer unexpectedly switched to XPS mode");
|
||||||
}
|
}
|
||||||
|
@ -204,14 +204,14 @@
|
|||||||
* Message handlers.
|
* Message handlers.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void guac_rdpdr_process_server_announce(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_server_announce(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
void guac_rdpdr_process_clientid_confirm(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_clientid_confirm(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
void guac_rdpdr_process_device_reply(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_device_reply(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
void guac_rdpdr_process_device_iorequest(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_device_iorequest(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
void guac_rdpdr_process_server_capability(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_server_capability(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
void guac_rdpdr_process_user_loggedon(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_user_loggedon(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
void guac_rdpdr_process_prn_cache_data(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_prn_cache_data(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
void guac_rdpdr_process_prn_using_xps(guac_rdpdrPlugin* rdpdr, wStream* input_stream);
|
void guac_rdpdr_process_prn_using_xps(guac_rdpdr* rdpdr, wStream* input_stream);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -27,7 +27,6 @@
|
|||||||
#include "rdp_status.h"
|
#include "rdp_status.h"
|
||||||
#include "unicode.h"
|
#include "unicode.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/protocol.h>
|
#include <guacamole/protocol.h>
|
||||||
#include <guacamole/socket.h>
|
#include <guacamole/socket.h>
|
||||||
@ -61,7 +60,9 @@ void guac_rdpdr_process_print_job_create(guac_rdpdr_device* device,
|
|||||||
completion_id, STATUS_SUCCESS, 4);
|
completion_id, STATUS_SUCCESS, 4);
|
||||||
|
|
||||||
Stream_Write_UINT32(output_stream, 0); /* fileId */
|
Stream_Write_UINT32(output_stream, 0); /* fileId */
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -100,7 +101,9 @@ void guac_rdpdr_process_print_job_write(guac_rdpdr_device* device,
|
|||||||
Stream_Write_UINT32(output_stream, length);
|
Stream_Write_UINT32(output_stream, length);
|
||||||
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
Stream_Write_UINT8(output_stream, 0); /* Padding */
|
||||||
|
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +124,9 @@ void guac_rdpdr_process_print_job_close(guac_rdpdr_device* device,
|
|||||||
completion_id, STATUS_SUCCESS, 4);
|
completion_id, STATUS_SUCCESS, 4);
|
||||||
|
|
||||||
Stream_Write_UINT32(output_stream, 0); /* Padding */
|
Stream_Write_UINT32(output_stream, 0); /* Padding */
|
||||||
svc_plugin_send((rdpSvcPlugin*) device->rdpdr, output_stream);
|
device->rdpdr->entry_points.pVirtualChannelWriteEx(device->rdpdr->init_handle,
|
||||||
|
device->rdpdr->open_handle, Stream_Buffer(output_stream),
|
||||||
|
Stream_GetPosition(output_stream), output_stream);
|
||||||
|
|
||||||
/* Log end of print job */
|
/* Log end of print job */
|
||||||
guac_client_log(client, GUAC_LOG_INFO, "Print job closed");
|
guac_client_log(client, GUAC_LOG_INFO, "Print job closed");
|
||||||
@ -164,7 +169,7 @@ static void guac_rdpdr_device_printer_free_handler(guac_rdpdr_device* device) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr, char* printer_name) {
|
void guac_rdpdr_register_printer(guac_rdpdr* rdpdr, char* printer_name) {
|
||||||
|
|
||||||
int id = rdpdr->devices_registered++;
|
int id = rdpdr->devices_registered++;
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@
|
|||||||
* The name of the printer that will be registered with the RDP
|
* The name of the printer that will be registered with the RDP
|
||||||
* connection and passed through to the server.
|
* connection and passed through to the server.
|
||||||
*/
|
*/
|
||||||
void guac_rdpdr_register_printer(guac_rdpdrPlugin* rdpdr, char* printer_name);
|
void guac_rdpdr_register_printer(guac_rdpdr* rdpdr, char* printer_name);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -32,7 +32,6 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
|
|
||||||
#include <freerdp/constants.h>
|
#include <freerdp/constants.h>
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <guacamole/protocol.h>
|
#include <guacamole/protocol.h>
|
||||||
#include <guacamole/socket.h>
|
#include <guacamole/socket.h>
|
||||||
@ -40,92 +39,19 @@
|
|||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Entry point for RDPDR virtual channel.
|
* Processes data received along the RDPDR channel via a
|
||||||
|
* CHANNEL_EVENT_DATA_RECEIVED event, forwarding the data along an established,
|
||||||
|
* outbound pipe stream to the Guacamole client.
|
||||||
|
*
|
||||||
|
* @param rdpdr
|
||||||
|
* The guac_rdpdr structure representing the RDPDR channel.
|
||||||
|
*
|
||||||
|
* @param input_stream
|
||||||
|
* The data that was received.
|
||||||
*/
|
*/
|
||||||
int VirtualChannelEntry(PCHANNEL_ENTRY_POINTS pEntryPoints) {
|
static void guac_rdpdr_process_receive(guac_rdpdr* rdpdr,
|
||||||
|
|
||||||
/* Allocate plugin */
|
|
||||||
guac_rdpdrPlugin* rdpdr =
|
|
||||||
(guac_rdpdrPlugin*) calloc(1, sizeof(guac_rdpdrPlugin));
|
|
||||||
|
|
||||||
/* Init channel def */
|
|
||||||
strcpy(rdpdr->plugin.channel_def.name, "rdpdr");
|
|
||||||
rdpdr->plugin.channel_def.options =
|
|
||||||
CHANNEL_OPTION_INITIALIZED | CHANNEL_OPTION_ENCRYPT_RDP | CHANNEL_OPTION_COMPRESS_RDP;
|
|
||||||
|
|
||||||
/* Set callbacks */
|
|
||||||
rdpdr->plugin.connect_callback = guac_rdpdr_process_connect;
|
|
||||||
rdpdr->plugin.receive_callback = guac_rdpdr_process_receive;
|
|
||||||
rdpdr->plugin.event_callback = guac_rdpdr_process_event;
|
|
||||||
rdpdr->plugin.terminate_callback = guac_rdpdr_process_terminate;
|
|
||||||
|
|
||||||
/* Finish init */
|
|
||||||
svc_plugin_init((rdpSvcPlugin*) rdpdr, pEntryPoints);
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Service Handlers
|
|
||||||
*/
|
|
||||||
|
|
||||||
void guac_rdpdr_process_connect(rdpSvcPlugin* plugin) {
|
|
||||||
|
|
||||||
/* Get RDPDR plugin */
|
|
||||||
guac_rdpdrPlugin* rdpdr = (guac_rdpdrPlugin*) plugin;
|
|
||||||
|
|
||||||
/* Get client from plugin parameters */
|
|
||||||
guac_client* client = (guac_client*)
|
|
||||||
plugin->channel_entry_points.pExtendedData;
|
|
||||||
|
|
||||||
/* NULL out pExtendedData so we don't lose our guac_client due to an
|
|
||||||
* automatic free() within libfreerdp */
|
|
||||||
plugin->channel_entry_points.pExtendedData = NULL;
|
|
||||||
|
|
||||||
/* Get data from client */
|
|
||||||
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
|
||||||
|
|
||||||
/* Init plugin */
|
|
||||||
rdpdr->client = client;
|
|
||||||
rdpdr->devices_registered = 0;
|
|
||||||
|
|
||||||
/* Register printer if enabled */
|
|
||||||
if (rdp_client->settings->printing_enabled)
|
|
||||||
guac_rdpdr_register_printer(rdpdr, rdp_client->settings->printer_name);
|
|
||||||
|
|
||||||
/* Register drive if enabled */
|
|
||||||
if (rdp_client->settings->drive_enabled)
|
|
||||||
guac_rdpdr_register_fs(rdpdr, rdp_client->settings->drive_name);
|
|
||||||
|
|
||||||
/* Log that printing, etc. has been loaded */
|
|
||||||
guac_client_log(client, GUAC_LOG_INFO, "guacdr connected.");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void guac_rdpdr_process_terminate(rdpSvcPlugin* plugin) {
|
|
||||||
|
|
||||||
guac_rdpdrPlugin* rdpdr = (guac_rdpdrPlugin*) plugin;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i=0; i<rdpdr->devices_registered; i++) {
|
|
||||||
guac_rdpdr_device* device = &(rdpdr->devices[i]);
|
|
||||||
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Unloading device %i (%s)",
|
|
||||||
device->device_id, device->device_name);
|
|
||||||
device->free_handler(device);
|
|
||||||
}
|
|
||||||
|
|
||||||
free(plugin);
|
|
||||||
}
|
|
||||||
|
|
||||||
void guac_rdpdr_process_event(rdpSvcPlugin* plugin, wMessage* event) {
|
|
||||||
freerdp_event_free(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
void guac_rdpdr_process_receive(rdpSvcPlugin* plugin,
|
|
||||||
wStream* input_stream) {
|
wStream* input_stream) {
|
||||||
|
|
||||||
guac_rdpdrPlugin* rdpdr = (guac_rdpdrPlugin*) plugin;
|
|
||||||
|
|
||||||
int component;
|
int component;
|
||||||
int packet_id;
|
int packet_id;
|
||||||
|
|
||||||
@ -306,3 +232,269 @@ void guac_rdpdr_start_download(guac_rdpdr_device* device, char* path) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler for events which deal with data transmitted over the RDPDR
|
||||||
|
* channel. This specific implementation of the event handler currently
|
||||||
|
* handles only the CHANNEL_EVENT_DATA_RECEIVED event, delegating actual
|
||||||
|
* handling of that event to guac_rdpdr_process_receive().
|
||||||
|
*
|
||||||
|
* The FreeRDP requirements for this function follow those of the
|
||||||
|
* VirtualChannelOpenEventEx callback defined within Microsoft's RDP API:
|
||||||
|
*
|
||||||
|
* https://docs.microsoft.com/en-us/previous-versions/windows/embedded/aa514754%28v%3dmsdn.10%29
|
||||||
|
*
|
||||||
|
* @param user_param
|
||||||
|
* The pointer to arbitrary data originally passed via the first parameter
|
||||||
|
* of the pVirtualChannelInitEx() function call when the associated channel
|
||||||
|
* was initialized. The pVirtualChannelInitEx() function is exposed within
|
||||||
|
* the channel entry points structure.
|
||||||
|
*
|
||||||
|
* @param open_handle
|
||||||
|
* The handle which identifies the channel itself, typically referred to
|
||||||
|
* within the FreeRDP source as OpenHandle.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* An integer representing the event that should be handled. This will be
|
||||||
|
* either CHANNEL_EVENT_DATA_RECEIVED, CHANNEL_EVENT_WRITE_CANCELLED, or
|
||||||
|
* CHANNEL_EVENT_WRITE_COMPLETE.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* The data received, for CHANNEL_EVENT_DATA_RECEIVED events, and the value
|
||||||
|
* passed as user data to pVirtualChannelWriteEx() for
|
||||||
|
* CHANNEL_EVENT_WRITE_* events (note that user data for
|
||||||
|
* pVirtualChannelWriteEx() as implemented by FreeRDP MUST either be NULL
|
||||||
|
* or a wStream containing the data written).
|
||||||
|
*
|
||||||
|
* @param data_length
|
||||||
|
* The number of bytes of event-specific data.
|
||||||
|
*
|
||||||
|
* @param total_length
|
||||||
|
* The total number of bytes written to the RDP server in a single write
|
||||||
|
* operation.
|
||||||
|
*
|
||||||
|
* NOTE: The meaning of total_length is unclear. The above description was
|
||||||
|
* written mainly through referencing the documentation in MSDN. Real-world
|
||||||
|
* use will need to be consulted, likely within the FreeRDP source, before
|
||||||
|
* this value can be reliably used. The current implementation of this
|
||||||
|
* handler ignores this parameter.
|
||||||
|
*
|
||||||
|
* @param data_flags
|
||||||
|
* The result of a bitwise OR of the CHANNEL_FLAG_* flags which apply to
|
||||||
|
* the data received. This value is relevant only to
|
||||||
|
* CHANNEL_EVENT_DATA_RECEIVED events. Valid flags are CHANNEL_FLAG_FIRST,
|
||||||
|
* CHANNEL_FLAG_LAST, and CHANNEL_FLAG_ONLY. The flag CHANNEL_FLAG_MIDDLE
|
||||||
|
* is not itself a flag, but the absence of both CHANNEL_FLAG_FIRST and
|
||||||
|
* CHANNEL_FLAG_LAST.
|
||||||
|
*/
|
||||||
|
static VOID guac_rdpdr_handle_open_event(LPVOID user_param,
|
||||||
|
DWORD open_handle, UINT event, LPVOID data, UINT32 data_length,
|
||||||
|
UINT32 total_length, UINT32 data_flags) {
|
||||||
|
|
||||||
|
/* Ignore all events except for received data */
|
||||||
|
if (event != CHANNEL_EVENT_DATA_RECEIVED)
|
||||||
|
return;
|
||||||
|
|
||||||
|
guac_rdpdr* rdpdr = (guac_rdpdr*) user_param;
|
||||||
|
|
||||||
|
/* Validate relevant handle matches that of the RDPDR channel */
|
||||||
|
if (open_handle != rdpdr->open_handle) {
|
||||||
|
guac_client_log(rdpdr->client, GUAC_LOG_WARNING, "%i bytes of data "
|
||||||
|
"received from within the remote desktop session for the "
|
||||||
|
"RDPDR channel are being dropped because the relevant open "
|
||||||
|
"handle (0x%X) does not match the open handle of RDPDR "
|
||||||
|
"(0x%X).", data_length, rdpdr->channel_def.name, open_handle,
|
||||||
|
rdpdr->open_handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
wStream* input_stream = Stream_New(data, data_length);
|
||||||
|
guac_rdpdr_process_receive(rdpdr, input_stream);
|
||||||
|
Stream_Free(input_stream, FALSE);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a CHANNEL_EVENT_CONNECTED event, completing the
|
||||||
|
* connection/initialization process of the RDPDR channel.
|
||||||
|
*
|
||||||
|
* @param rdpdr
|
||||||
|
* The guac_rdpdr structure representing the RDPDR channel.
|
||||||
|
*/
|
||||||
|
static void guac_rdpdr_process_connect(guac_rdpdr* rdpdr) {
|
||||||
|
|
||||||
|
/* Get data from client */
|
||||||
|
guac_client* client = rdpdr->client;
|
||||||
|
guac_rdp_client* rdp_client = (guac_rdp_client*) client->data;
|
||||||
|
|
||||||
|
/* Open FreeRDP side of connected channel */
|
||||||
|
UINT32 open_status =
|
||||||
|
rdpdr->entry_points.pVirtualChannelOpenEx(rdpdr->init_handle,
|
||||||
|
&rdpdr->open_handle, rdpdr->channel_def.name,
|
||||||
|
guac_rdpdr_handle_open_event);
|
||||||
|
|
||||||
|
/* Warn if the channel cannot be opened after all */
|
||||||
|
if (open_status != CHANNEL_RC_OK) {
|
||||||
|
guac_client_log(client, GUAC_LOG_WARNING, "RDPDR channel could not be "
|
||||||
|
"opened: %s (error %i)", WTSErrorToString(open_status),
|
||||||
|
open_status);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Register printer if enabled */
|
||||||
|
if (rdp_client->settings->printing_enabled)
|
||||||
|
guac_rdpdr_register_printer(rdpdr, rdp_client->settings->printer_name);
|
||||||
|
|
||||||
|
/* Register drive if enabled */
|
||||||
|
if (rdp_client->settings->drive_enabled)
|
||||||
|
guac_rdpdr_register_fs(rdpdr, rdp_client->settings->drive_name);
|
||||||
|
|
||||||
|
/* Log that printing, etc. has been loaded */
|
||||||
|
guac_client_log(client, GUAC_LOG_INFO, "RDPDR channel connected.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Processes a CHANNEL_EVENT_TERMINATED event, freeing all resources associated
|
||||||
|
* with the RDPDR channel.
|
||||||
|
*
|
||||||
|
* @param rdpdr
|
||||||
|
* The guac_rdpdr structure representing the RDPDR channel.
|
||||||
|
*/
|
||||||
|
static void guac_rdpdr_process_terminate(guac_rdpdr* rdpdr) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i=0; i<rdpdr->devices_registered; i++) {
|
||||||
|
guac_rdpdr_device* device = &(rdpdr->devices[i]);
|
||||||
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "Unloading device %i (%s)",
|
||||||
|
device->device_id, device->device_name);
|
||||||
|
device->free_handler(device);
|
||||||
|
}
|
||||||
|
|
||||||
|
guac_client_log(rdpdr->client, GUAC_LOG_INFO, "RDPDR channel disconnected.");
|
||||||
|
free(rdpdr);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Event handler for events which deal with the overall lifecycle of the RDPDR
|
||||||
|
* channel. This specific implementation of the event handler currently
|
||||||
|
* handles only CHANNEL_EVENT_CONNECTED and CHANNEL_EVENT_TERMINATED events,
|
||||||
|
* delegating actual handling of those events to guac_rdpdr_process_connect()
|
||||||
|
* and guac_rdpdr_process_terminate() respectively.
|
||||||
|
*
|
||||||
|
* The FreeRDP requirements for this function follow those of the
|
||||||
|
* VirtualChannelInitEventEx callback defined within Microsoft's RDP API:
|
||||||
|
*
|
||||||
|
* https://docs.microsoft.com/en-us/previous-versions/windows/embedded/aa514727%28v%3dmsdn.10%29
|
||||||
|
*
|
||||||
|
* @param user_param
|
||||||
|
* The pointer to arbitrary data originally passed via the first parameter
|
||||||
|
* of the pVirtualChannelInitEx() function call when the associated channel
|
||||||
|
* was initialized. The pVirtualChannelInitEx() function is exposed within
|
||||||
|
* the channel entry points structure.
|
||||||
|
*
|
||||||
|
* @param init_handle
|
||||||
|
* The handle which identifies the client connection, typically referred to
|
||||||
|
* within the FreeRDP source as pInitHandle.
|
||||||
|
*
|
||||||
|
* @param event
|
||||||
|
* An integer representing the event that should be handled. This will be
|
||||||
|
* either CHANNEL_EVENT_CONNECTED, CHANNEL_EVENT_DISCONNECTED,
|
||||||
|
* CHANNEL_EVENT_INITIALIZED, CHANNEL_EVENT_TERMINATED, or
|
||||||
|
* CHANNEL_EVENT_V1_CONNECTED.
|
||||||
|
*
|
||||||
|
* @param data
|
||||||
|
* NULL in all cases except the CHANNEL_EVENT_CONNECTED event, in which
|
||||||
|
* case this is a null-terminated string containing the name of the server.
|
||||||
|
*
|
||||||
|
* @param data_length
|
||||||
|
* The number of bytes of data, if any.
|
||||||
|
*/
|
||||||
|
static VOID guac_rdpdr_handle_init_event(LPVOID user_param,
|
||||||
|
LPVOID init_handle, UINT event, LPVOID data, UINT data_length) {
|
||||||
|
|
||||||
|
guac_rdpdr* rdpdr = (guac_rdpdr*) user_param;
|
||||||
|
|
||||||
|
/* Validate relevant handle matches that of the RDPDR channel */
|
||||||
|
if (init_handle != rdpdr->init_handle) {
|
||||||
|
guac_client_log(rdpdr->client, GUAC_LOG_WARNING, "An init event "
|
||||||
|
"(#%i) for the RDPDR channel has been dropped because the "
|
||||||
|
"relevant init handle (0x%X) does not match the init handle "
|
||||||
|
"of the RDPDR channel (0x%X).", event, init_handle,
|
||||||
|
rdpdr->init_handle);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (event) {
|
||||||
|
|
||||||
|
/* The RDPDR channel has been connected */
|
||||||
|
case CHANNEL_EVENT_CONNECTED:
|
||||||
|
guac_rdpdr_process_connect(rdpdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
/* The RDPDR channel has disconnected and now must be cleaned up */
|
||||||
|
case CHANNEL_EVENT_TERMINATED:
|
||||||
|
guac_rdpdr_process_terminate(rdpdr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Entry point for FreeRDP plugins. This function is automatically invoked when
|
||||||
|
* the plugin is loaded.
|
||||||
|
*
|
||||||
|
* @param entry_points
|
||||||
|
* Functions and data specific to the FreeRDP side of the virtual channel
|
||||||
|
* and plugin. This structure must be copied within implementation-specific
|
||||||
|
* storage such that the functions it references can be invoked when
|
||||||
|
* needed.
|
||||||
|
*
|
||||||
|
* @param init_handle
|
||||||
|
* The handle which identifies the client connection, typically referred to
|
||||||
|
* within the FreeRDP source as pInitHandle. This handle is also provided
|
||||||
|
* to the channel init event handler. The handle must eventually be used
|
||||||
|
* within the channel open event handler to obtain a handle to the channel
|
||||||
|
* itself.
|
||||||
|
*
|
||||||
|
* @return
|
||||||
|
* TRUE if the plugin has initialized successfully, FALSE otherwise.
|
||||||
|
*/
|
||||||
|
BOOL VirtualChannelEntryEx(PCHANNEL_ENTRY_POINTS entry_points,
|
||||||
|
PVOID init_handle) {
|
||||||
|
|
||||||
|
CHANNEL_ENTRY_POINTS_FREERDP_EX* entry_points_ex =
|
||||||
|
(CHANNEL_ENTRY_POINTS_FREERDP_EX*) entry_points;
|
||||||
|
|
||||||
|
/* Allocate plugin */
|
||||||
|
guac_rdpdr* rdpdr = (guac_rdpdr*) calloc(1, sizeof(guac_rdpdr));
|
||||||
|
|
||||||
|
/* Init channel def */
|
||||||
|
strcpy(rdpdr->channel_def.name, "rdpdr");
|
||||||
|
rdpdr->channel_def.options = CHANNEL_OPTION_INITIALIZED
|
||||||
|
| CHANNEL_OPTION_ENCRYPT_RDP
|
||||||
|
| CHANNEL_OPTION_COMPRESS_RDP;
|
||||||
|
|
||||||
|
/* Maintain reference to associated guac_client */
|
||||||
|
rdpdr->client = (guac_client*) entry_points_ex->pExtendedData;
|
||||||
|
|
||||||
|
/* No devices are connected initially */
|
||||||
|
rdpdr->devices_registered = 0;
|
||||||
|
|
||||||
|
/* Copy FreeRDP data into RDPSND structure for future reference */
|
||||||
|
rdpdr->entry_points = *entry_points_ex;
|
||||||
|
rdpdr->init_handle = init_handle;
|
||||||
|
|
||||||
|
/* Complete initialization */
|
||||||
|
if (rdpdr->entry_points.pVirtualChannelInitEx(rdpdr, rdpdr, init_handle,
|
||||||
|
&rdpdr->channel_def, 1, VIRTUAL_CHANNEL_VERSION_WIN2000,
|
||||||
|
guac_rdpdr_handle_init_event) != CHANNEL_RC_OK) {
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -23,16 +23,17 @@
|
|||||||
|
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
|
|
||||||
#include <freerdp/utils/svc_plugin.h>
|
#include <freerdp/svc.h>
|
||||||
#include <guacamole/client.h>
|
#include <guacamole/client.h>
|
||||||
#include <winpr/stream.h>
|
#include <winpr/stream.h>
|
||||||
|
#include <winpr/wtsapi.h>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The maximum number of bytes to allow for a device read.
|
* The maximum number of bytes to allow for a device read.
|
||||||
*/
|
*/
|
||||||
#define GUAC_RDP_MAX_READ_BUFFER 4194304
|
#define GUAC_RDP_MAX_READ_BUFFER 4194304
|
||||||
|
|
||||||
typedef struct guac_rdpdrPlugin guac_rdpdrPlugin;
|
typedef struct guac_rdpdr guac_rdpdr;
|
||||||
typedef struct guac_rdpdr_device guac_rdpdr_device;
|
typedef struct guac_rdpdr_device guac_rdpdr_device;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -61,7 +62,7 @@ struct guac_rdpdr_device {
|
|||||||
/**
|
/**
|
||||||
* The RDPDR plugin owning this device.
|
* The RDPDR plugin owning this device.
|
||||||
*/
|
*/
|
||||||
guac_rdpdrPlugin* rdpdr;
|
guac_rdpdr* rdpdr;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The ID assigned to this device by the RDPDR plugin.
|
* The ID assigned to this device by the RDPDR plugin.
|
||||||
@ -115,20 +116,45 @@ struct guac_rdpdr_device {
|
|||||||
* Structure representing the current state of the Guacamole RDPDR plugin for
|
* Structure representing the current state of the Guacamole RDPDR plugin for
|
||||||
* FreeRDP.
|
* FreeRDP.
|
||||||
*/
|
*/
|
||||||
struct guac_rdpdrPlugin {
|
struct guac_rdpdr {
|
||||||
|
|
||||||
/**
|
|
||||||
* The FreeRDP parts of this plugin. This absolutely MUST be first.
|
|
||||||
* FreeRDP depends on accessing this structure as if it were an instance
|
|
||||||
* of rdpSvcPlugin.
|
|
||||||
*/
|
|
||||||
rdpSvcPlugin plugin;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Reference to the client owning this instance of the RDPDR plugin.
|
* Reference to the client owning this instance of the RDPDR plugin.
|
||||||
*/
|
*/
|
||||||
guac_client* client;
|
guac_client* client;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The definition of this virtual channel (RDPDR).
|
||||||
|
*/
|
||||||
|
CHANNEL_DEF channel_def;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Functions and data specific to the FreeRDP side of the virtual channel
|
||||||
|
* and plugin.
|
||||||
|
*/
|
||||||
|
CHANNEL_ENTRY_POINTS_FREERDP_EX entry_points;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle which identifies the client connection, typically referred to
|
||||||
|
* within the FreeRDP source as pInitHandle. This handle is provided to the
|
||||||
|
* channel entry point and the channel init event handler. The handle must
|
||||||
|
* eventually be used within the channel open event handler to obtain a
|
||||||
|
* handle to the channel itself.
|
||||||
|
*/
|
||||||
|
PVOID init_handle;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handle which identifies the channel itself, typically referred to within
|
||||||
|
* the FreeRDP source as OpenHandle. This handle is obtained through a call
|
||||||
|
* to entry_points.pVirtualChannelOpenEx() in response to receiving a
|
||||||
|
* CHANNEL_EVENT_CONNECTED event via the init event handler.
|
||||||
|
*
|
||||||
|
* Data is received in CHANNEL_EVENT_DATA_RECEIVED events via the open
|
||||||
|
* event handler, and data is written through calls to
|
||||||
|
* entry_points.pVirtualChannelWriteEx().
|
||||||
|
*/
|
||||||
|
DWORD open_handle;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The number of devices registered within the devices array.
|
* The number of devices registered within the devices array.
|
||||||
*/
|
*/
|
||||||
@ -141,28 +167,6 @@ struct guac_rdpdrPlugin {
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler called when this plugin is loaded by FreeRDP.
|
|
||||||
*/
|
|
||||||
void guac_rdpdr_process_connect(rdpSvcPlugin* plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler called when this plugin receives data along its designated channel.
|
|
||||||
*/
|
|
||||||
void guac_rdpdr_process_receive(rdpSvcPlugin* plugin,
|
|
||||||
wStream* input_stream);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler called when this plugin is being unloaded.
|
|
||||||
*/
|
|
||||||
void guac_rdpdr_process_terminate(rdpSvcPlugin* plugin);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handler called when this plugin receives an event. For the sake of RDPDR,
|
|
||||||
* all events will be ignored and simply free'd.
|
|
||||||
*/
|
|
||||||
void guac_rdpdr_process_event(rdpSvcPlugin* plugin, wMessage* event);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates a new stream which contains the common DR_DEVICE_IOCOMPLETION header
|
* Creates a new stream which contains the common DR_DEVICE_IOCOMPLETION header
|
||||||
* used for virtually all responses.
|
* used for virtually all responses.
|
||||||
|
Loading…
Reference in New Issue
Block a user