mirror of
https://github.com/FreeRDP/FreeRDP.git
synced 2025-06-03 00:00:20 +00:00
hardend display channel
This commit is contained in:
parent
e5d5cd3c94
commit
dca53c132c
@ -3,6 +3,8 @@
|
|||||||
* Display Update Virtual Channel Extension
|
* Display Update Virtual Channel Extension
|
||||||
*
|
*
|
||||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||||
|
* Copyright 2015 Thincast Technologies GmbH
|
||||||
|
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -33,6 +35,7 @@
|
|||||||
#include <winpr/sysinfo.h>
|
#include <winpr/sysinfo.h>
|
||||||
#include <winpr/cmdline.h>
|
#include <winpr/cmdline.h>
|
||||||
#include <winpr/collections.h>
|
#include <winpr/collections.h>
|
||||||
|
#include <winpr/win32error.h>
|
||||||
|
|
||||||
#include <freerdp/addin.h>
|
#include <freerdp/addin.h>
|
||||||
|
|
||||||
@ -71,9 +74,9 @@ struct _DISP_PLUGIN
|
|||||||
};
|
};
|
||||||
typedef struct _DISP_PLUGIN DISP_PLUGIN;
|
typedef struct _DISP_PLUGIN DISP_PLUGIN;
|
||||||
|
|
||||||
int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
WIN32ERROR disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
||||||
{
|
{
|
||||||
int status;
|
WIN32ERROR status;
|
||||||
wStream* s;
|
wStream* s;
|
||||||
UINT32 type;
|
UINT32 type;
|
||||||
UINT32 index;
|
UINT32 index;
|
||||||
@ -91,6 +94,12 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback
|
|||||||
|
|
||||||
s = Stream_New(NULL, length);
|
s = Stream_New(NULL, length);
|
||||||
|
|
||||||
|
if(!s)
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "Stream_New failed!");
|
||||||
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
Stream_Write_UINT32(s, type); /* Type (4 bytes) */
|
Stream_Write_UINT32(s, type); /* Type (4 bytes) */
|
||||||
Stream_Write_UINT32(s, length); /* Length (4 bytes) */
|
Stream_Write_UINT32(s, length); /* Length (4 bytes) */
|
||||||
|
|
||||||
@ -154,14 +163,17 @@ int disp_send_display_control_monitor_layout_pdu(DISP_CHANNEL_CALLBACK* callback
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
WIN32ERROR disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
||||||
{
|
{
|
||||||
DISP_PLUGIN* disp;
|
DISP_PLUGIN* disp;
|
||||||
|
|
||||||
disp = (DISP_PLUGIN*) callback->plugin;
|
disp = (DISP_PLUGIN*) callback->plugin;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 12)
|
if (Stream_GetRemainingLength(s) < 12)
|
||||||
return -1;
|
{
|
||||||
|
WLog_ERR(TAG, "not enought remaining data");
|
||||||
|
return ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */
|
Stream_Read_UINT32(s, disp->MaxNumMonitors); /* MaxNumMonitors (4 bytes) */
|
||||||
Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */
|
Stream_Read_UINT32(s, disp->MaxMonitorAreaFactorA); /* MaxMonitorAreaFactorA (4 bytes) */
|
||||||
@ -169,16 +181,19 @@ int disp_recv_display_control_caps_pdu(DISP_CHANNEL_CALLBACK* callback, wStream*
|
|||||||
//WLog_ERR(TAG, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d",
|
//WLog_ERR(TAG, "DisplayControlCapsPdu: MaxNumMonitors: %d MaxMonitorWidth: %d MaxMonitorHeight: %d",
|
||||||
// disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight);
|
// disp->MaxNumMonitors, disp->MaxMonitorWidth, disp->MaxMonitorHeight);
|
||||||
|
|
||||||
return 0;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
WIN32ERROR disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
||||||
{
|
{
|
||||||
UINT32 type;
|
UINT32 type;
|
||||||
UINT32 length;
|
UINT32 length;
|
||||||
|
|
||||||
if (Stream_GetRemainingLength(s) < 8)
|
if (Stream_GetRemainingLength(s) < 8)
|
||||||
return -1;
|
{
|
||||||
|
WLog_ERR(TAG, "not enought remaining data");
|
||||||
|
return ERROR_INVALID_DATA;
|
||||||
|
}
|
||||||
|
|
||||||
Stream_Read_UINT32(s, type); /* Type (4 bytes) */
|
Stream_Read_UINT32(s, type); /* Type (4 bytes) */
|
||||||
Stream_Read_UINT32(s, length); /* Length (4 bytes) */
|
Stream_Read_UINT32(s, length); /* Length (4 bytes) */
|
||||||
@ -188,36 +203,28 @@ int disp_recv_pdu(DISP_CHANNEL_CALLBACK* callback, wStream* s)
|
|||||||
switch (type)
|
switch (type)
|
||||||
{
|
{
|
||||||
case DISPLAY_CONTROL_PDU_TYPE_CAPS:
|
case DISPLAY_CONTROL_PDU_TYPE_CAPS:
|
||||||
disp_recv_display_control_caps_pdu(callback, s);
|
return disp_recv_display_control_caps_pdu(callback, s);
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
WLog_ERR(TAG, "Type %d not recognized!", type);
|
||||||
|
return ERROR_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int disp_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data)
|
static WIN32ERROR disp_on_data_received(IWTSVirtualChannelCallback* pChannelCallback, wStream *data)
|
||||||
{
|
|
||||||
int status = 0;
|
|
||||||
DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback;
|
|
||||||
|
|
||||||
status = disp_recv_pdu(callback, data);
|
|
||||||
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int disp_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
|
||||||
{
|
{
|
||||||
DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback;
|
DISP_CHANNEL_CALLBACK* callback = (DISP_CHANNEL_CALLBACK*) pChannelCallback;
|
||||||
|
|
||||||
free(callback);
|
return disp_recv_pdu(callback, data);
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
|
static WIN32ERROR disp_on_close(IWTSVirtualChannelCallback* pChannelCallback)
|
||||||
|
{
|
||||||
|
free(pChannelCallback);
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
static WIN32ERROR disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallback,
|
||||||
IWTSVirtualChannel* pChannel, BYTE* Data, int* pbAccept,
|
IWTSVirtualChannel* pChannel, BYTE* Data, int* pbAccept,
|
||||||
IWTSVirtualChannelCallback** ppCallback)
|
IWTSVirtualChannelCallback** ppCallback)
|
||||||
{
|
{
|
||||||
@ -227,7 +234,10 @@ static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac
|
|||||||
callback = (DISP_CHANNEL_CALLBACK*) calloc(1, sizeof(DISP_CHANNEL_CALLBACK));
|
callback = (DISP_CHANNEL_CALLBACK*) calloc(1, sizeof(DISP_CHANNEL_CALLBACK));
|
||||||
|
|
||||||
if (!callback)
|
if (!callback)
|
||||||
return -1;
|
{
|
||||||
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
callback->iface.OnDataReceived = disp_on_data_received;
|
callback->iface.OnDataReceived = disp_on_data_received;
|
||||||
callback->iface.OnClose = disp_on_close;
|
callback->iface.OnClose = disp_on_close;
|
||||||
@ -238,18 +248,21 @@ static int disp_on_new_channel_connection(IWTSListenerCallback* pListenerCallbac
|
|||||||
|
|
||||||
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
*ppCallback = (IWTSVirtualChannelCallback*) callback;
|
||||||
|
|
||||||
return 0;
|
return CHANNEL_RC_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
static WIN32ERROR disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager* pChannelMgr)
|
||||||
{
|
{
|
||||||
int status;
|
WIN32ERROR status;
|
||||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
|
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
|
||||||
|
|
||||||
disp->listener_callback = (DISP_LISTENER_CALLBACK*) calloc(1, sizeof(DISP_LISTENER_CALLBACK));
|
disp->listener_callback = (DISP_LISTENER_CALLBACK*) calloc(1, sizeof(DISP_LISTENER_CALLBACK));
|
||||||
|
|
||||||
if (!disp->listener_callback)
|
if (!disp->listener_callback)
|
||||||
return -1;
|
{
|
||||||
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
disp->listener_callback->iface.OnNewChannelConnection = disp_on_new_channel_connection;
|
disp->listener_callback->iface.OnNewChannelConnection = disp_on_new_channel_connection;
|
||||||
disp->listener_callback->plugin = pPlugin;
|
disp->listener_callback->plugin = pPlugin;
|
||||||
@ -263,36 +276,31 @@ static int disp_plugin_initialize(IWTSPlugin* pPlugin, IWTSVirtualChannelManager
|
|||||||
return status;
|
return status;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int disp_plugin_terminated(IWTSPlugin* pPlugin)
|
static WIN32ERROR disp_plugin_terminated(IWTSPlugin* pPlugin)
|
||||||
{
|
{
|
||||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) pPlugin;
|
free(pPlugin);
|
||||||
|
return CHANNEL_RC_OK;
|
||||||
free(disp);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Channel Client Interface
|
* Channel Client Interface
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
WIN32ERROR disp_send_monitor_layout(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors)
|
||||||
{
|
{
|
||||||
DISP_PLUGIN* disp = (DISP_PLUGIN*) context->handle;
|
DISP_PLUGIN* disp = (DISP_PLUGIN*) context->handle;
|
||||||
DISP_CHANNEL_CALLBACK* callback = disp->listener_callback->channel_callback;
|
DISP_CHANNEL_CALLBACK* callback = disp->listener_callback->channel_callback;
|
||||||
|
|
||||||
disp_send_display_control_monitor_layout_pdu(callback, NumMonitors, Monitors);
|
return disp_send_display_control_monitor_layout_pdu(callback, NumMonitors, Monitors);
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef STATIC_CHANNELS
|
#ifdef STATIC_CHANNELS
|
||||||
#define DVCPluginEntry disp_DVCPluginEntry
|
#define DVCPluginEntry disp_DVCPluginEntry
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
WIN32ERROR DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
||||||
{
|
{
|
||||||
int error = 0;
|
WIN32ERROR error = CHANNEL_RC_OK;
|
||||||
DISP_PLUGIN* disp;
|
DISP_PLUGIN* disp;
|
||||||
DispClientContext* context;
|
DispClientContext* context;
|
||||||
|
|
||||||
@ -303,7 +311,10 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
|||||||
disp = (DISP_PLUGIN*) calloc(1, sizeof(DISP_PLUGIN));
|
disp = (DISP_PLUGIN*) calloc(1, sizeof(DISP_PLUGIN));
|
||||||
|
|
||||||
if (!disp)
|
if (!disp)
|
||||||
return -1;
|
{
|
||||||
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
disp->iface.Initialize = disp_plugin_initialize;
|
disp->iface.Initialize = disp_plugin_initialize;
|
||||||
disp->iface.Connected = NULL;
|
disp->iface.Connected = NULL;
|
||||||
@ -314,8 +325,9 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
|||||||
|
|
||||||
if (!context)
|
if (!context)
|
||||||
{
|
{
|
||||||
|
WLog_ERR(TAG, "calloc failed!");
|
||||||
free(disp);
|
free(disp);
|
||||||
return -1;
|
return CHANNEL_RC_NO_MEMORY;
|
||||||
}
|
}
|
||||||
|
|
||||||
context->handle = (void*) disp;
|
context->handle = (void*) disp;
|
||||||
@ -330,6 +342,11 @@ int DVCPluginEntry(IDRDYNVC_ENTRY_POINTS* pEntryPoints)
|
|||||||
|
|
||||||
error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp);
|
error = pEntryPoints->RegisterPlugin(pEntryPoints, "disp", (IWTSPlugin*) disp);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
WLog_ERR(TAG, "could not get disp Plugin.");
|
||||||
|
return CHANNEL_RC_BAD_CHANNEL;
|
||||||
|
}
|
||||||
|
|
||||||
return error;
|
return error;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
* Display Update Virtual Channel Extension
|
* Display Update Virtual Channel Extension
|
||||||
*
|
*
|
||||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||||
|
* Copyright 2015 Thincast Technologies GmbH
|
||||||
|
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -34,5 +36,7 @@
|
|||||||
#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000005
|
#define DISPLAY_CONTROL_PDU_TYPE_CAPS 0x00000005
|
||||||
#define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
#define DISPLAY_CONTROL_PDU_TYPE_MONITOR_LAYOUT 0x00000002
|
||||||
|
|
||||||
|
#define TAG CHANNELS_TAG("disp.client")
|
||||||
|
|
||||||
#endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */
|
#endif /* FREERDP_CHANNEL_DISP_CLIENT_MAIN_H */
|
||||||
|
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
* Display Update Virtual Channel Extension
|
* Display Update Virtual Channel Extension
|
||||||
*
|
*
|
||||||
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
* Copyright 2013 Marc-Andre Moreau <marcandre.moreau@gmail.com>
|
||||||
|
* Copyright 2015 Thincast Technologies GmbH
|
||||||
|
* Copyright 2015 DI (FH) Martin Haimberger <martin.haimberger@thincast.com>
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@ -50,7 +52,7 @@ typedef struct _DISPLAY_CONTROL_MONITOR_LAYOUT DISPLAY_CONTROL_MONITOR_LAYOUT;
|
|||||||
|
|
||||||
typedef struct _disp_client_context DispClientContext;
|
typedef struct _disp_client_context DispClientContext;
|
||||||
|
|
||||||
typedef int (*pcDispSendMonitorLayout)(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors);
|
typedef WIN32ERROR (*pcDispSendMonitorLayout)(DispClientContext* context, UINT32 NumMonitors, DISPLAY_CONTROL_MONITOR_LAYOUT* Monitors);
|
||||||
|
|
||||||
struct _disp_client_context
|
struct _disp_client_context
|
||||||
{
|
{
|
||||||
|
Loading…
Reference in New Issue
Block a user