libfreerdp-core: added GCC client data blocks

This commit is contained in:
Marc-André Moreau 2011-07-05 18:26:12 -04:00
parent 14e45b940c
commit f8fa387fae
9 changed files with 267 additions and 25 deletions

View File

@ -81,7 +81,7 @@ void test_transport(void)
CU_ASSERT(r == True);
stream = stream_new(sizeof(test_x224_req));
stream_write_buffer(stream, test_x224_req, sizeof(test_x224_req));
stream_write(stream, test_x224_req, sizeof(test_x224_req));
r = transport_send(transport, stream);
CU_ASSERT(r == 0);

View File

@ -20,8 +20,8 @@
#ifndef __FREERDP_H
#define __FREERDP_H
#include "settings.h"
#include "types/ui.h"
#include "settings.h"
#include "extension.h"
#define FREERDP_INTERFACE_VERSION 4

View File

@ -20,10 +20,12 @@
#ifndef __RDP_SETTINGS_H
#define __RDP_SETTINGS_H
#include <freerdp/freerdp.h>
struct rdp_chan
{
char name[8]; /* ui sets */
int flags; /* ui sets */
int options; /* ui sets */
int chan_id; /* core sets */
void * handle; /* just for ui */
};
@ -45,8 +47,25 @@ struct rdp_monitor
struct rdp_settings
{
int width;
int height;
uint16 width;
uint16 height;
uint32 rdp_version;
uint16 color_depth;
uint32 kbd_layout;
uint32 kbd_type;
uint32 kbd_subtype;
uint32 kbd_fn_keys;
uint32 selected_protocol;
uint32 session_id;
int console_session;
int num_channels;
struct rdp_chan channels[16];
int num_monitors;
struct rdp_monitor monitors[16];
char hostname[16];
char server[64];
char domain[16];
@ -55,26 +74,19 @@ struct rdp_settings
char directory[256];
char username[256];
int tcp_port_rdp;
int keyboard_layout;
int keyboard_type;
int keyboard_subtype;
int keyboard_functionkeys;
char xkb_layout[32];
char xkb_variant[32];
int performance_flags;
int encryption;
int tls_security;
int nla_security;
int rdp_security;
int encryption;
int rdp_version;
int remote_app;
char app_name[64];
int console_session;
int server_depth;
int bitmap_cache;
int bitmap_cache_persist_enable;
int bitmap_cache_precache;
int bitmap_compression;
int performanceflags;
int desktop_save;
int polygon_ellipse_orders;
int autologin;
@ -87,12 +99,8 @@ struct rdp_settings
int rfx_flags;
int ui_decode_flags;
int use_frame_ack;
int num_channels;
int software_gdi;
struct rdp_chan channels[16];
struct rdp_ext_set extensions[16];
int num_monitors;
struct rdp_monitor monitors[16];
};
#endif /* __RDP_SETTINGS_H */

View File

@ -44,4 +44,12 @@ typedef signed long long sint64;
typedef int boolean;
#ifndef MIN
#define MIN(x,y) (((x) < (y)) ? (x) : (y))
#endif
#ifndef MAX
#define MAX(x,y) (((x) > (y)) ? (x) : (y))
#endif
#endif

View File

@ -21,6 +21,7 @@
#ifndef __STREAM_UTILS_H
#define __STREAM_UTILS_H
#include <string.h>
#include <freerdp/types/base.h>
struct _STREAM
@ -93,10 +94,14 @@ stream_extend(STREAM * stream);
*_s->ptr++ = ((_v) >> 40) & 0xFF; \
*_s->ptr++ = ((_v) >> 48) & 0xFF; \
*_s->ptr++ = ((_v) >> 56) & 0xFF; } while (0)
#define stream_write_buffer(_s, _b, _n) do { \
#define stream_write(_s, _b, _n) do { \
memcpy(_s->ptr, (_b), (_n)); \
_s->ptr += (_n); \
} while (0)
#define stream_write_padding(_s, _n) do { \
memset(_s->ptr, '\0', (_n)); \
_s->ptr += (_n); \
} while (0)
#define stream_peek_uint8(_s, _v) do { _v = *_s->ptr; } while (0)
#define stream_peek_uint16(_s, _v) do { _v = \

View File

@ -134,6 +134,21 @@ gcc_write_create_conference_request(STREAM* s, STREAM* user_data)
per_write_octet_string(s, user_data->buffer, stream_get_length(user_data), 0); /* array of client data blocks */
}
/**
* Write a user data header (TS_UD_HEADER).\n
* @msdn{cc240509}
* @param s stream
* @param type data block type
* @param length data block length
*/
void
gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length)
{
stream_write_uint16(s, type); /* type */
stream_write_uint16(s, length); /* length */
}
/**
* Write a client core data block (TS_UD_CS_CORE).\n
* @msdn{cc240510}
@ -144,7 +159,61 @@ gcc_write_create_conference_request(STREAM* s, STREAM* user_data)
void
gcc_write_client_core_data(STREAM* s, rdpSettings *settings)
{
uint32 version;
uint16 highColorDepth;
uint16 supportedColorDepths;
uint16 earlyCapabilityFlags;
uint8 connectionType;
gcc_write_user_data_header(s, CS_CORE, 216);
version = settings->rdp_version >= 5 ? RDP_VERSION_5_PLUS : RDP_VERSION_4;
stream_write_uint32(s, version); /* version */
stream_write_uint16(s, settings->width); /* desktopWidth */
stream_write_uint16(s, settings->height); /* desktopHeight */
stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* colorDepth, ignored because of postBeta2ColorDepth */
stream_write_uint16(s, RNS_UD_SAS_DEL); /* SASSequence (Secure Access Sequence) */
stream_write_uint32(s, settings->kbd_layout); /* keyboardLayout */
stream_write_uint32(s, 2600); /* clientBuild */
stream_write_padding(s, 32); /* clientName */
stream_write_uint32(s, settings->kbd_type); /* keyboardType */
stream_write_uint32(s, settings->kbd_subtype); /* keyboardSubType */
stream_write_uint32(s, settings->kbd_fn_keys); /* keyboardFunctionKey */
stream_write_padding(s, 64); /* imeFileName */
stream_write_uint16(s, RNS_UD_COLOR_8BPP); /* postBeta2ColorDepth */
stream_write_uint16(s, 1); /* clientProductID */
stream_write_uint16(s, 0); /* serialNumber (should be initialized to 0) */
highColorDepth = MIN(settings->color_depth, 24);
supportedColorDepths = RNS_UD_32BPP_SUPPORT | RNS_UD_24BPP_SUPPORT | RNS_UD_16BPP_SUPPORT | RNS_UD_15BPP_SUPPORT;
stream_write_uint16(s, highColorDepth); /* highColorDepth */
stream_write_uint16(s, supportedColorDepths); /* supportedColorDepths */
connectionType = 0;
earlyCapabilityFlags = RNS_UD_CS_SUPPORT_ERRINFO_PDU;
if (settings->performance_flags == PERF_FLAG_NONE)
{
earlyCapabilityFlags |= RNS_UD_CS_VALID_CONNECTION_TYPE;
connectionType = CONNECTION_TYPE_LAN;
}
if (settings->color_depth == 32)
earlyCapabilityFlags |= RNS_UD_CS_WANT_32BPP_SESSION;
stream_write_uint16(s, earlyCapabilityFlags); /* earlyCapabilityFlags */
stream_write_padding(s, 64); /* clientDigProductId (64 bytes) */
stream_write_uint8(s, connectionType); /* connectionType */
stream_write_uint8(s, 0); /* pad1octet */
stream_write_uint32(s, settings->selected_protocol); /* serverSelectedProtocol */
}
/**
@ -157,7 +226,23 @@ gcc_write_client_core_data(STREAM* s, rdpSettings *settings)
void
gcc_write_client_security_data(STREAM* s, rdpSettings *settings)
{
uint16 encryptionMethods;
gcc_write_user_data_header(s, CS_SECURITY, 12);
encryptionMethods = ENCRYPTION_40BIT_FLAG | ENCRYPTION_128BIT_FLAG;
if (settings->encryption)
{
stream_write_uint32(s, encryptionMethods); /* encryptionMethods */
stream_write_uint32(s, 0); /* extEncryptionMethods */
}
else
{
/* French locale, disable encryption */
stream_write_uint32(s, 0); /* encryptionMethods */
stream_write_uint32(s, encryptionMethods); /* extEncryptionMethods */
}
}
/**
@ -170,7 +255,24 @@ gcc_write_client_security_data(STREAM* s, rdpSettings *settings)
void
gcc_write_client_network_data(STREAM* s, rdpSettings *settings)
{
int i;
uint16 length;
if (settings->num_channels > 0)
{
length = settings->num_channels * 12 + 8;
gcc_write_user_data_header(s, CS_NET, length);
stream_write_uint32(s, settings->num_channels); /* channelCount */
/* channelDefArray */
for (i = 0; i < settings->num_channels; i++)
{
/* CHANNEL_DEF */
stream_write(s, settings->channels[i].name, 8); /* name (8 bytes) */
stream_write_uint32(s, settings->channels[i].options); /* options (4 bytes) */
}
}
}
/**
@ -183,7 +285,18 @@ gcc_write_client_network_data(STREAM* s, rdpSettings *settings)
void
gcc_write_client_cluster_data(STREAM* s, rdpSettings *settings)
{
uint32 flags;
uint32 redirectedSessionID;
gcc_write_user_data_header(s, CS_CLUSTER, 12);
flags = REDIRECTION_SUPPORTED | REDIRECTION_VERSION4;
if (settings->console_session || settings->session_id)
flags |= REDIRECTED_SESSIONID_FIELD_VALID;
stream_write_uint32(s, flags); /* flags */
stream_write_uint32(s, settings->session_id); /* redirectedSessionID */
}
/**
@ -196,5 +309,31 @@ gcc_write_client_cluster_data(STREAM* s, rdpSettings *settings)
void
gcc_write_client_monitor_data(STREAM* s, rdpSettings *settings)
{
int i;
uint16 length;
uint32 left, top, right, bottom, flags;
if (settings->num_monitors > 1)
{
length = (20 * settings->num_monitors) + 12;
gcc_write_user_data_header(s, CS_MONITOR, length);
stream_write_uint32(s, 0); /* flags */
stream_write_uint32(s, settings->num_monitors); /* monitorCount */
for (i = 0; i < settings->num_monitors; i++)
{
left = settings->monitors[i].x;
top = settings->monitors[i].y;
right = settings->monitors[i].x + settings->monitors[i].width - 1;
bottom = settings->monitors[i].y + settings->monitors[i].height - 1;
flags = settings->monitors[i].is_primary ? MONITOR_PRIMARY : 0;
stream_write_uint32(s, left); /* left */
stream_write_uint32(s, top); /* top */
stream_write_uint32(s, right); /* right */
stream_write_uint32(s, bottom); /* bottom */
stream_write_uint32(s, flags); /* flags */
}
}
}

View File

@ -25,9 +25,91 @@
#include <freerdp/freerdp.h>
#include <freerdp/utils/stream.h>
/* Client to Server (CS) data blocks */
#define CS_CORE 0xC001
#define CS_SECURITY 0xC002
#define CS_NET 0xC003
#define CS_CLUSTER 0xC004
#define CS_MONITOR 0xC005
/* Server to Client (SC) data blocks */
#define SC_CORE 0x0C01
#define SC_SECURITY 0x0C02
#define SC_NET 0x0C03
/* RDP version */
#define RDP_VERSION_4 0x00080001
#define RDP_VERSION_5_PLUS 0x00080004
/* Color depth */
#define RNS_UD_COLOR_4BPP 0xCA00
#define RNS_UD_COLOR_8BPP 0xCA01
#define RNS_UD_COLOR_16BPP_555 0xCA02
#define RNS_UD_COLOR_16BPP_565 0xCA03
#define RNS_UD_COLOR_24BPP 0xCA04
/* Secure Access Sequence */
#define RNS_UD_SAS_DEL 0xAA03
/* Supported Color Depths */
#define RNS_UD_24BPP_SUPPORT 0x0001
#define RNS_UD_16BPP_SUPPORT 0x0002
#define RNS_UD_15BPP_SUPPORT 0x0004
#define RNS_UD_32BPP_SUPPORT 0x0008
/* Early Capability Flags */
#define RNS_UD_CS_SUPPORT_ERRINFO_PDU 0x0001
#define RNS_UD_CS_WANT_32BPP_SESSION 0x0002
#define RNS_UD_CS_SUPPORT_STATUSINFO_PDU 0x0004
#define RNS_UD_CS_STRONG_ASYMMETRIC_KEYS 0x0008
#define RNS_UD_CS_VALID_CONNECTION_TYPE 0x0020
#define RNS_UD_CS_SUPPORT_MONITOR_LAYOUT_PDU 0x0040
/* Performance Flags */
#define PERF_FLAG_NONE 0x00000000
#define PERF_DISABLE_WALLPAPER 0x00000001
#define PERF_DISABLE_FULLWINDOWDRAG 0x00000002
#define PERF_DISABLE_MENUANIMATIONS 0x00000004
#define PERF_DISABLE_THEMING 0x00000008
#define PERF_RESERVED1 0x00000010
#define PERF_DISABLE_CURSOR_SHADOW 0x00000020
#define PERF_DISABLE_CURSORSETTINGS 0x00000040
#define PERF_ENABLE_FONT_SMOOTHING 0x00000080
#define PERF_ENABLE_DESKTOP_COMPOSITION 0x00000100
/* Connection Types */
#define CONNECTION_TYPE_MODEM 0x01
#define CONNECTION_TYPE_BROADBAND_LOW 0x02
#define CONNECTION_TYPE_SATELLITE 0x03
#define CONNECTION_TYPE_BROADBAND_HIGH 0x04
#define CONNECTION_TYPE_WAN 0x05
#define CONNECTION_TYPE_LAN 0x06
/* Encryption Methods */
#define ENCRYPTION_40BIT_FLAG 0x00000001
#define ENCRYPTION_128BIT_FLAG 0x00000002
#define ENCRYPTION_56BIT_FLAG 0x00000008
#define ENCRYPTION_FIPS_FLAG 0x00000010
/* Cluster Information Flags */
#define REDIRECTION_SUPPORTED 0x00000001
#define REDIRECTED_SESSIONID_FIELD_VALID 0x00000002
#define REDIRECTED_SMARTCARD 0x00000040
#define REDIRECTION_VERSION1 0x00
#define REDIRECTION_VERSION2 0x01
#define REDIRECTION_VERSION3 0x02
#define REDIRECTION_VERSION4 0x03
#define REDIRECTION_VERSION5 0x04
/* Monitor Flags */
#define MONITOR_PRIMARY 0x00000001
void
gcc_write_create_conference_request(STREAM* s, STREAM* user_data);
void
gcc_write_user_data_header(STREAM* s, uint16 type, uint16 length);
void
gcc_write_client_core_data(STREAM* s, rdpSettings *settings);
void

View File

@ -257,8 +257,8 @@ void nego_send_negotiation_request(rdpNego *nego)
if (nego->cookie)
{
int cookie_length = strlen(nego->cookie);
stream_write_buffer(s, "Cookie: mstshash=", 17);
stream_write_buffer(s, nego->cookie, cookie_length);
stream_write(s, "Cookie: mstshash=", 17);
stream_write(s, nego->cookie, cookie_length);
stream_write_uint8(s, 0x0D); /* CR */
stream_write_uint8(s, 0x0A); /* LF */
length += cookie_length + 19;
@ -266,7 +266,7 @@ void nego_send_negotiation_request(rdpNego *nego)
else if (nego->routing_token)
{
int routing_token_length = strlen(nego->routing_token);
stream_write_buffer(s, nego->routing_token, routing_token_length);
stream_write(s, nego->routing_token, routing_token_length);
length += routing_token_length;
}

View File

@ -1117,7 +1117,7 @@ gdi_init(rdpInst * inst, uint32 flags)
gdi->width = inst->settings->width;
gdi->height = inst->settings->height;
gdi->srcBpp = inst->settings->server_depth;
gdi->srcBpp = inst->settings->color_depth;
/* default internal buffer format */
gdi->dstBpp = 32;