| /* |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| */ |
| |
| #ifndef GUAC_RDP_CHANNELS_COMMON_SVC_H |
| #define GUAC_RDP_CHANNELS_COMMON_SVC_H |
| |
| #include "config.h" |
| |
| #include <freerdp/svc.h> |
| #include <guacamole/client.h> |
| #include <guacamole/stream.h> |
| #include <winpr/stream.h> |
| #include <winpr/wtsapi.h> |
| #include <winpr/wtypes.h> |
| |
| /** |
| * The maximum number of bytes to allow within each channel name, including |
| * null terminator. |
| */ |
| #define GUAC_RDP_SVC_MAX_LENGTH 8 |
| |
| /** |
| * The maximum number of bytes that the RDP server will be allowed to send |
| * within any single write operation, regardless of the number of chunks that |
| * write is split into. Bytes beyond this limit may be dropped. |
| */ |
| #define GUAC_SVC_MAX_ASSEMBLED_LENGTH 1048576 |
| |
| /** |
| * Structure describing a static virtual channel, and the corresponding |
| * Guacamole pipes and FreeRDP resources. |
| */ |
| typedef struct guac_rdp_common_svc guac_rdp_common_svc; |
| |
| /** |
| * Handler which is invoked when a CHANNEL_EVENT_CONNECTED event has been |
| * processed and the connection/initialization process of the SVC is now |
| * complete. |
| * |
| * @param svc |
| * The guac_rdp_common_svc structure representing the SVC that is now |
| * connected. |
| */ |
| typedef void guac_rdp_common_svc_connect_handler(guac_rdp_common_svc* svc); |
| |
| /** |
| * Handler which is invoked when a logical block of data has been received |
| * along an SVC, having been reassembled from a series of |
| * CHANNEL_EVENT_DATA_RECEIVED events. |
| * |
| * @param svc |
| * The guac_rdp_common_svc structure representing the SVC that received the |
| * data. |
| * |
| * @param input_stream |
| * The reassembled block of data that was received. |
| */ |
| typedef void guac_rdp_common_svc_receive_handler(guac_rdp_common_svc* svc, wStream* input_stream); |
| |
| /** |
| * Handler which is invoked when a CHANNEL_EVENT_TERMINATED event has been |
| * processed and all resources associated with the SVC must now be freed. |
| * |
| * @param svc |
| * The guac_rdp_common_svc structure representing the SVC that has been |
| * terminated. |
| */ |
| typedef void guac_rdp_common_svc_terminate_handler(guac_rdp_common_svc* svc); |
| |
| struct guac_rdp_common_svc { |
| |
| /** |
| * Reference to the client owning this static channel. |
| */ |
| guac_client* client; |
| |
| /** |
| * The name of the static virtual channel, as specified to |
| * guac_rdp_common_svc_load_plugin(). This value is stored and defined |
| * internally by the CHANNEL_DEF. |
| */ |
| const char* name; |
| |
| /** |
| * Arbitrary channel-specific data which may be assigned and referenced by |
| * channel implementations leveraging the "guac-common-svc" plugin. |
| */ |
| void* data; |
| |
| /** |
| * Handler which is invoked when handling a CHANNEL_EVENT_CONNECTED event. |
| */ |
| guac_rdp_common_svc_connect_handler* _connect_handler; |
| |
| /** |
| * Handler which is invoked when all chunks of data for a single logical |
| * block have been received via CHANNEL_EVENT_DATA_RECEIVED events and |
| * reassembled. |
| */ |
| guac_rdp_common_svc_receive_handler* _receive_handler; |
| |
| /** |
| * Handler which is invokved when the SVC has been disconnected and is |
| * about to be freed. |
| */ |
| guac_rdp_common_svc_terminate_handler* _terminate_handler; |
| |
| /** |
| * The definition of this static virtual channel, including its name. |
| */ |
| 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; |
| |
| /** |
| * All data that has been received thus far from the current RDP server |
| * write operation. Data received along virtual channels is sent in chunks |
| * (typically 1600 bytes), and thus must be gradually reassembled as it is |
| * received. |
| */ |
| wStream* _input_stream; |
| |
| }; |
| |
| /** |
| * Initializes arbitrary static virtual channel (SVC) support for RDP, loading |
| * a new instance of Guacamole's arbitrary SVC plugin for FreeRDP ("guacsvc") |
| * supporting the channel having the given name. Data sent from within the RDP |
| * session using this channel will be sent along an identically-named pipe |
| * stream to the Guacamole client, and data sent along a pipe stream having the |
| * same name will be written to the SVC and received within the RDP session. If |
| * failures occur while loading the plugin, messages noting the specifics of |
| * those failures will be logged, and support for the given channel will not be |
| * functional. |
| * |
| * This MUST be called within the PreConnect callback of the freerdp instance |
| * for static virtual channel support to be loaded. |
| * |
| * @param context |
| * The rdpContext associated with the FreeRDP side of the RDP connection. |
| * |
| * @param name |
| * The name of the SVC which should be handled by the new instance of the |
| * plugin. |
| * |
| * @param channel_options |
| * Bitwise OR of any of the several CHANNEL_OPTION_* flags. Regardless of |
| * whether specified here, the CHANNEL_OPTION_INTIALIZED and |
| * CHANNEL_OPTION_ENCRYPT_RDP flags will automatically be set. |
| * |
| * @param connect_handler |
| * The function to invoke when the SVC has been connected. |
| * |
| * @param receive_handler |
| * The function to invoke when the SVC has received a logical block of |
| * data, reassembled from perhaps several smaller chunks of data. |
| * |
| * @param terminate_handler |
| * The function to invoke when the SVC has been disconnected and is about |
| * to be freed. |
| * |
| * @return |
| * Zero if the plugin was loaded successfully, non-zero if the plugin could |
| * not be loaded. |
| */ |
| int guac_rdp_common_svc_load_plugin(rdpContext* context, |
| char* name, ULONG channel_options, |
| guac_rdp_common_svc_connect_handler* connect_handler, |
| guac_rdp_common_svc_receive_handler* receive_handler, |
| guac_rdp_common_svc_terminate_handler* terminate_handler); |
| |
| /** |
| * Writes the given data to the virtual channel such that it can be received |
| * within the RDP session. The given data MUST be dynamically allocated, as the |
| * write operation may be queued and the actual write may not occur until |
| * later. The provided wStream and the buffer it points to will be |
| * automatically freed after the write occurs. |
| * |
| * @param svc |
| * The static virtual channel to write data to. |
| * |
| * @param output_stream |
| * The data to write, which MUST be dynamically allocated. |
| */ |
| void guac_rdp_common_svc_write(guac_rdp_common_svc* svc, |
| wStream* output_stream); |
| |
| #endif |
| |